Go Down

Topic: Winbond SPI Flash library (Read 24896 times) previous topic - next topic

Marzogh

Just pushed through a big update to v2.0.0.

- BIG update in terms of speed. Sped up all functions atleast 25x
- Compatible with ATTiny85
- All Read/Write/Erase functions can now take either (page number & offset) or (address) as arguments (Except readPage())
- getAddress() can now return either a 32-bit address or a page number & offset.

As always, you can find this version on Github here -->SPIFlash Library for Arduino v2.0.0 A ZIP file is also attached to the first post on this thread. :)

Marzogh

Just pushed through an update to v2.1.0

- The library now supports the Arduino Due!
- Lots more optimizations + even better ATTiny85 support

As always, you can find this version on Github here -->SPIFlash Library for Arduino v2.1.0 A ZIP file is also attached to the first post on this thread. :)

P.S. jtewell : This might be the version you are looking for!

Stephan_Duino

Help please! I am trying to get the W25Q80BV Winbond 1Mbyte Spi Flash DIP chip to work with the Arduino Due, but it gets stuck in function flash.begin.
I am using example programms fron Marzogh/SPIFlash V2.1.1 with Arduino V1.6.5 with an Arduino due.
The examples compile fine and upload to the Due board fine but all I see is
"Initialising Flash memory………."
Nothing else is written to the screen. Further investigation shows it get stuck in flash.begin();
I have wired the chip to the Due as follows:
Chip pin 1 -> Due pin 10 (Chip Select)
Chip pin 2 -> Due pin MISO (108) (SPI Pins)
Chip pin 3 -> Vcc 3.3V
Chip pin 4 -> GND (Common GND for chip and Due)
Chip pin 5 -> Due pin MOSI (109) (SPI Pins)
Chip pin 6 -> Due pin SCK (110) (SPI Pins)
Chip pin 7 -> Vcc 3.3V
Chip pin 8 -> Vcc 3.3V
Any help will be much appreciated.

Marzogh

#18
Oct 28, 2015, 01:42 am Last Edit: Oct 28, 2015, 03:04 am by Marzogh
That is unexpected. v2.1.1 was a bug fix release for the powerUp & powerDown functions so I didn't realise I'd broken Due support. Thanks for the heads up - I'll test and get back to you with a fix shortly, however, for the time being, using v2.1.0 should solve the problem.

Update:

I've just tested my Due with v2.1.1 and the only issue I have with it is that powerDown() returns a false negative (This is being fixed in the upcoming v2.2.0). Everything else is functioning properly and returns the following:

Code: [Select]
Initialising Flash memory..........


----------------------------------------------------------------------------------------------------------------------------------
                                                           Get ID                                                                 
----------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------
Manufacturer ID: efh
Memory Type: 13h
Capacity: 4014h
JEDEC ID: ef4014h
----------------------------------------------------------------------------------------------------------------------------------
                                                          Write Data                                                             
----------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------
Data Written || Data Read || Result
----------------------------------------------------------------------------------------------------------------------------------
35 || 35 || Pass
-110 || -110 || Pass
4520 || 4520 || Pass
-1250 || -1250 || Pass
876532 || 876532 || Pass
-10959 || -10959 || Pass
3.1415 || 3.1415 || Pass
123 Test !@# || 123 Test !@# || Pass

Struct data written successfully
31325, 4.84, 880932, 1, 5
Saved!
Local values set to 0
After reading
31325, 4.84, 880932, 1, 5

Values from 0 to 255 have been written to the page 484
These values have been read back from page 484
Reading page (01e4)
000,001,002,003,004,005,006,007,008,009,010,011,012,013,014,015,
016,017,018,019,020,021,022,023,024,025,026,027,028,029,030,031,
032,033,034,035,036,037,038,039,040,041,042,043,044,045,046,047,
048,049,050,051,052,053,054,055,056,057,058,059,060,061,062,063,
064,065,066,067,068,069,070,071,072,073,074,075,076,077,078,079,
080,081,082,083,084,085,086,087,088,089,090,091,092,093,094,095,
096,097,098,099,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,


Have you tried running Diagnostic.ino - included in the examples after uncommenting #define RUNDIAGNOSTIC from the top of SPIFlash.cpp? (Make sure you save SPIFlash.cpp before you recompile and upload Diagnostics.ino) If you have, what errors did it print to your serial?

Can you post a photo of your wiring?

Also, if all fails have you tried using a different chip? I have previously found the chip returns 'busy' if the breadboard connections are not properly made or if the chip is faulty and not responding.

Stephan_Duino

Thankyou for this reply. I am working on this today. I will use another chip just in case and will send you a photo and let you know how I get on.
I have noticed some people use lots of resistors and a 0.1uf capcitor between VCC and GND but I simply connect direct and use the Due's 3.3V for VCC. (Trust my connections above are OK for the Due) Excelent Library you have. I am sure I had something simple wrong the first time I tried it.

Stephan_Duino

It works :) Many thanks for your help. Much appreciated. Excellent library, especially as you support the Arduino Due which needs the SPI memory more than most.

I have attached a photo of my setup but it is hard to see. The wiring is as stated above and now the examples are working. Perhaps I had a duff chip as I have not knowingly made any changes other than swap the chip out.

Thanks again Stephan

Marzogh

Hi Stephan,

I'm glad it works and that you find the library useful. Connecting a 0.1uF cap across VCC and GND is totally up to whether you think you need to minimize any noise on your power bus. I haven't had the need for one yet. :)

Also, if you choose to use the powerDown() mode for low power while using v2.1.1, I'd recommend that you  refer to Issue 15 (on Github).

Good luck with whatever you project is and thanks for the photo. The connections look ok and as you said, it might have just been a bad chip.

Cheers!

Hoek

Been writing a similar driver for the spansion S25FL132K and similar chips which will have Due and Teensy support as I use a small common library for the low level pin setting. After reading the documentation this library should work for the other chips if single mode is chosen.

I've also implemented it primarily as QSPI but normal SPI mode should work. As the guts of it had QSPI in mind it bitbangs the data too and from the slave device.

Seems the QSPI is quite new as didn't find any other libraries using it.





Marzogh

#23
Nov 03, 2015, 03:00 am Last Edit: Nov 03, 2015, 03:01 am by Marzogh
I've never looked at those chips before. They'd be an useful addition to the library. :) My plan's to add support for ATMEL's flash chips sometime in the future and support for Spansion's flash chips would make it more widely useful.

I've never seen QSPI being used in any other libraries either. The Winbond Chips support DSPI and QSPI. Its something I'd like to integrate into the library if I can.

P.S. Is your code on Github? I'd love to get a look at it if that's ok :)

chucktodd

I've never looked at those chips before. They'd be an useful addition to the library. :) My plan's to add support for ATMEL's flash chips sometime in the future and support for Spansion's flash chips would make it more widely useful.

I've never seen QSPI being used in any other libraries either. The Winbond Chips support DSPI and QSPI. Its something I'd like to integrate into the library if I can.

P.S. Is your code on Github? I'd love to get a look at it if that's ok :)
But,
   The whole point of DSPI and QSPI is speed.  Bit banging QSPI uses more resources (4bit databus + SCK + SS). And it is slower.  Using software to build the nibbles, output them, stimulate the Clock, cannot be twice as fast as 4mhz one bit SPI?  A single byte SPI at 4mhz takes 32 clock cycles, how many op codes are executed to emulate QSPI?

I realize the SPI.h code is not interrupt driven, I wrote a version that does the transfers in a background interrupt setting.  As long as I code the foreground code to politely handle atomic access to the SPI hardware I can do two things at once.  If I were to used a bit banged QSPI function I believe it would slow down my code.

What benefit do you receive using QSPI?

Chuck.
Currently building mega http server 90% done, the Last 10% is killing me.

Hoek

I've never looked at those chips before. They'd be an useful addition to the library. :) My plan's to add support for ATMEL's flash chips sometime in the future and support for Spansion's flash chips would make it more widely useful.

I've never seen QSPI being used in any other libraries either. The Winbond Chips support DSPI and QSPI. Its something I'd like to integrate into the library if I can.

P.S. Is your code on Github? I'd love to get a look at it if that's ok :)
Sorry for the long delay in answering. I've only just started testing the library as the breakout boards took so long to arrive "fast aussie delivery". Anyway got the normal serial stuff to work finally. Got the guts working, setting and reading status, read byte(s), verify byte(s), write buffer to location, page dump function for debugging.

I can set quad mode enable (QE) and it sets the correct bit however the quad read function is returning rubbish from my test page which simply has the values 0-255 on the page. I've looked at the datasheet a zillion times, rechecked pin connections but at best the 1st 10 are correct then it goes all bad. I want to eventually put this on github, but when at least the quad mode is working. If it was working, the speed is about 2.5x faster than serial mode. However, it could be faster if the 4 data pins were sequential on the same port and they were all read/set as a single operation.

At the moment I want it just to work... then I'll optimize it and add a few options.

My code at the moment is just a single .ino file with everything in it for testing. If you want a copy pm me and I'll email a copy.

Also found the following link useful http://www.corelis.com/education/SPI_Tutorial.htm as talks about quad speed SPI. It mentions io1, io2 and io3 need to be tristated (high impedance) from what I could figure this means their pinmode should be "input". I have a feeling this is the cause of the problem.


A_Solis

I have recently started using the Spiflash library and need some help with the getAdress() section.   I read the .cpp file and a bit confused on how it works in terms of practical application. 

If I have 5 strings 
s1="one",
s2= "two",....
...
..
s5 = "five"

 and if I want to write them in consecutive order ,so that s1 is on page 0,section 0 , s2 will be on page 0,section (s1.length +1).... or the next available address after the end of string s1. How can I utilize the getAddress() function to indicate the next address?  I may be using it out of context but any help to get me started would be appreciated. 

Thanks in advance. 

Adam

Marzogh

Hi Adam,

My apologies for the delay in getting back to you - I am not usually very active on the forums.

Coming to your issue, I'd recommend you update your version of SPIFlash to the latest version - 2.2.0. It has an example called 'getAddressEx.ino' which should walk you through the process. The latest version also simplifies the getAddress() function when it comes to Strings.

If it still doesn't work, feel free to let me know here - I'll keep an eye on this thread for your reply. :)

Cheers,

Praj

Marzogh

Just pushed through an update to v2.2.0

- When #RUNDIAGNOSTIC is uncommented, the _troubleshoot() function is now optimised for different µCs
- Added the ability to check if the address has been previously written to before initiating a write operation.
- Added a sizeofStr() function to get sizes of String objects, to use with the getAddress() function
- Fixed a bug with getAddress()
- Added the ability get the chip's name via getChipName() (Refer to Diagnostics.ino to see how it can be used)
- Diagnostics.ino has been made more and efficient and provides a cleaner Serial output
- Added getAddressEx.ino to examples show how getAdress() works.

As always, you can find this version on Github here --> SPIFlash Library for Arduino v2.2.0
A ZIP file is also attached to the first post on this thread. :)

@Chuck, I have barely scratched the surface of QSPI or DSPI and as I have a functioning library for a chip that supports both those protocols, I'm curious to see how I can make it work on an Atmega328. My interest is purely academic - unless a miracle happens and bitbanging QSPI turns out to be faster than hardware SPI :P.

@Hoek, I'm quite curious about how far you've gotten it working. Will PM you now :) Thanks for the link as well! :)

A_Solis

Thanks for the Reply:

I found what I was looking for by the example posted below.  I will store coordinates from a gps module and just needed single increments of the address block versus using the (page,offset) method.  Just helps to keep the code clean. 

... The following will successively write to the memory chip and all I would need to do is keep track of which element was last written to. 



 //globals


uint32_t addy =0x0000;
uinit8_t cnt=0;


// This will count to 0x3eb ...(decimal 1000) and the counter will increment by 1 and reset at 250: repeats 4 times


 for (addy = 0x0000; addy <= 0x3eb; addy+=0x1) {
 
  flash.writeByte(addy, cnt, true);
  if(cnt==250){
    cnt=0;
  }
  else  cnt++;
}

for (addy= 0x0000; addy <= 0x3eb; addy+=0x1) {
  Serial.println();
  Serial.println(flash.readByte(addy, false));
}




The SPI library you have made is amazing... I will update to the latest version and look forward to utilizing the last known memory allocation to make things easier. 


Go Up