Un po 'tardi alla discussione, ma per chiunque lo legga dopo una ricerca ....
Una cosa che non ho visto menzionato, che è assolutamente fondamentale durante la programmazione dei chip SPI Flash è il controllo del pin Chip Select (CS_). Il pin Chip Select viene utilizzato per punteggiare i comandi su SPI Flash. In particolare, una transizione da CS_ high a CS_ low deve precedere immediatamente l'emissione di qualsiasi codice op di operazione di scrittura (WREN, BE, SE, PP). Se c'è attività tra la transizione CS_ (cioè dopo che CS_ è diventato basso) e prima che il codice operativo di scrittura venga trasmesso, il codice operativo di scrittura verrà generalmente ignorato.
Inoltre, ciò che non è comunemente spiegato nei fogli dati SPI Flash, poiché è una parte intrinseca del protocollo SPI, che è anche fondamentale, è che per ogni byte che si trasmette sul bus SPI, si riceve un byte in cambio. Inoltre, non è possibile ricevere byte, a meno che non si trasmetta un byte.
In genere, il Master SPI che l'utente sta comandando ha un Buffer di trasmissione, che invia i byte sulla linea MOSI del bus SPI e un Buffer di ricezione, che riceve byte dalla linea MISO del bus SPI.
Affinché i dati vengano visualizzati nel buffer di ricezione, alcuni dati devono essere stati inviati al buffer di trasmissione. Allo stesso modo, ogni volta che si inviano dati dal buffer di trasmissione, i dati verranno visualizzati nel buffer di ricezione.
Se non si è attenti al bilanciamento delle scritture di trasmissione e delle letture di ricezione, non si saprà cosa aspettarsi nel buffer di ricezione. Se l'overflow del buffer di ricezione, i dati vengono generalmente versati e persi.
Pertanto, quando si invia un comando di lettura, che è un codice operativo a un byte e tre byte di indirizzo, si riceveranno innanzitutto quattro byte di "immondizia" nel buffer di ricezione principale SPI. Questi quattro byte di immondizia corrispondono al codice operativo e a tre byte di indirizzo. Mentre vengono trasmessi, Flash non sa ancora cosa leggere, quindi restituisce solo quattro parole di immondizia.
Dopo che queste quattro parole di immondizia vengono restituite, al fine di ottenere qualsiasi altra cosa nel buffer di ricezione, è necessario trasmettere una quantità di dati pari alla quantità che si desidera leggere. Dopo il codice operativo e l'indirizzo, non importa ciò che si trasmette, è solo un riempimento per inviare il DAta di lettura dal flash SPI al buffer di ricezione.
Se non hai tenuto traccia delle prime quattro parole spazzatura restituite, potresti pensare che una o più di esse facciano parte dei dati di lettura restituiti.
Quindi, per sapere cosa stai effettivamente ricevendo dal buffer di ricezione, è importante conoscere la dimensione del buffer, sapere come è vuoto o pieno (di solito c'è un bit di stato del registro per segnalarlo) e tenere traccia di come molte cose che hai trasmesso e quanto hai ricevuto.
Prima di avviare qualsiasi operazione SPI Flash, è consigliabile "svuotare" il FIFO di ricezione. Ciò significa controllare lo stato del buffer di ricezione e svuotarlo (di solito eseguito eseguendo una 'lettura' del buffer di ricezione) se non è già vuoto. Di solito, svuotare (leggere) un buffer di ricezione già vuoto non fa male.
Le seguenti informazioni sono disponibili dai diagrammi di temporizzazione nei fogli di dati di SPI Flash, ma a volte le persone trascurano i bit. Tutti i comandi e i dati vengono inviati al flash SPI utilizzando il bus SPI. La sequenza per leggere un Flash SPI è:
1) Start with CS_ high.
2) Bring CS_ low.
3) Issue "Read" op code to SPI Flash.
4) Issue three address bytes to SPI Flash.
5) "Receive" four garbage words in Receive Buffer.
6) Transmit as many arbitrary bytes (don't cares) as you wish to receive.
Number of transmitted bytes after address equals size of desired read.
7) Receive read data in the Receive Buffer.
8) When you've read the desired amount of data, set CS_ high to end the Read command.
If you skip this step, any additional transmissions will be interpreted as
request for more data from (a continuation of) this Read.
Si noti che i passaggi 6 e 7 devono essere intercalati e ripetuti a seconda della dimensione della lettura e della dimensione dei buffer di ricezione e trasmissione. Se si trasmette un numero maggiore di parole in una volta sola, rispetto a quanto può contenere il buffer di ricezione, si riverseranno alcuni dati.
Per preformare un programma Page Program o Write, eseguire questi passaggi. Dimensione pagina (in genere 256 byte) e Dimensione settore (in genere 64 KB) e i limiti associati sono proprietà dell'SPI Flash in uso. Queste informazioni dovrebbero essere nel foglio dati per Flash. Ometterò i dettagli del bilanciamento dei buffer di trasmissione e ricezione.
1) Start with CS_ high.
2) Change CS_ to low.
3) Transmit the Write Enable (WREN) op code.
4) Switch CS_ to high for at least one SPI Bus clock cycle. This may be tens or
hundreds of host clock cycles. All write operations do not start until CS_ goes high.
The preceding two notes apply to all the following 'CS_ to high' steps.
5) Switch CS_ to low.
6) Gadfly loop: Transmit the 'Read from Status Register' (RDSR) op code and
one more byte. Receive two bytes. First byte is garbage. Second byte is status.
Check status byte. If 'Write in Progress' (WIP) bit is set, repeat loop.
(NOTE: May also check 'Write Enable Latch' bit is set (WEL) after WIP is clear.)
7) Switch CS_ to high.
8) Switch CS_ to low.
9) Transmit Sector Erase (SE) or Bulk Erase (BE) op code. If sending SE, then follow
it with three byte address.
10) Switch CS_ to high.
11) Switch CS_ to low.
12) Gadfly loop: Spin on WIP in Status Register as above in step 6. WEL will
be unset at end.
13) Switch CS_ to high.
14) Switch CS_ to low.
15) Transmit Write Enable op code (again).
16) Switch CS_ to high.
17) Switch CS_ to low.
18) Gadfly loop: Wait on WIP bit in Status Register to clear. (WEL will be set.)
19) Transmit Page Program (PP = Write) op code followed by three address bytes.
20) Transmit up to Page Size (typically 256 bytes) of data to write. (You may allow
Receive data to simply spill over during this operation, unless your host hardware
has a problem with that.)
21) Switch CS_ to high.
22) SWitch CS_ to low.
23) Gadfly loop: Spin on WIP in the Status Register.
24) Drain Receive FIFO so that it's ready for the next user.
25) Optional: Repeat steps 13 to 24 as needed to write additional pages or
page segments.
Infine, se il tuo indirizzo di scrittura non si trova su un limite di pagina (in genere un multiplo di 256 byte) e scrivi dati sufficienti per attraversare il limite di pagina seguente, i dati che devono attraversare il limite verranno scritti all'inizio della pagina in cui l'indirizzo del tuo programma cade. Quindi, se si tenta di scrivere tre byte per l'indirizzo 0x0FE. I primi due byte verranno scritti su 0x0fe e 0x0ff. Il terzo byte verrà scritto all'indirizzo 0x000.
Se si trasmette un numero di byte di dati maggiore di una dimensione di pagina, i byte iniziali verranno eliminati e solo i byte finali 256 (o dimensioni di pagina) verranno utilizzati per programmare la pagina.
Come sempre, non è responsabile per le conseguenze di eventuali errori, errori di battitura, sviste o disordini di cui sopra, né nel modo in cui lo utilizzi.