Un peu tard pour la discussion, mais pour tous ceux qui le lisent après une recherche ...
Une chose que je n'ai pas vue mentionnée, qui est absolument critique lors de la programmation de puces Flash SPI, est le contrôle de la broche Chip Select (CS_). La broche de sélection de puce est utilisée pour ponctuer les commandes du SPI Flash. En particulier, une transition de CS_ high à CS_ low doit précéder immédiatement l'émission de tout code d'opération d'opération d'écriture (WREN, BE, SE, PP). S'il y a une activité entre la transition CS_ (c'est-à-dire après que CS_ a baissé) et avant la transmission du code d'opération d'écriture, le code d'opération d'écriture sera généralement ignoré.
De plus, ce qui n'est pas souvent expliqué dans les fiches techniques SPI Flash, car il fait partie inhérente du protocole SPI, ce qui est également critique, c'est que pour chaque octet que l'on transmet sur le bus SPI, on reçoit un octet en retour. De même, on ne peut recevoir aucun octet, à moins de transmettre un octet.
En règle générale, le maître SPI que l'utilisateur commande dispose d'un tampon de transmission, qui envoie des octets sur la ligne MOSI du bus SPI et d'un tampon de réception, qui reçoit des octets de la ligne MISO du bus SPI.
Pour que des données apparaissent dans le tampon de réception, certaines données doivent avoir été envoyées dans le tampon de transmission. De même, chaque fois que l'on envoie des données hors du tampon de transmission, les données apparaissent dans le tampon de réception.
Si l'on ne fait pas attention à l'équilibre entre les écritures de transmission et les lectures de réception, on ne saura pas à quoi s'attendre dans le tampon de réception. En cas de débordement du tampon de réception, les données sont généralement simplement renversées et perdues.
Ainsi, lorsque l'on envoie une commande de lecture, qui est un code op à un octet et trois octets d'adresse, on reçoit d'abord quatre octets de "déchets" dans le tampon de réception maître SPI. Ces quatre octets de déchets correspondent au code op et aux trois octets d'adresse. Pendant leur transmission, le Flash ne sait pas encore quoi lire, il ne renvoie donc que quatre mots de poubelle.
Après que ces quatre mots de déchets sont retournés, afin d'obtenir autre chose dans le tampon de réception, vous devez transmettre une quantité de données égale à la quantité que vous souhaitez lire. Après le code op et l'adresse, peu importe ce que vous transmettez, il suffit de pousser le Read DAta du flash SPI vers le tampon de réception.
Si vous n'avez pas suivi attentivement ces quatre premiers mots poubelles retournés, vous pourriez penser qu'un ou plusieurs d'entre eux font partie de vos données de lecture retournées.
Donc, afin de savoir ce que vous obtenez réellement du tampon de réception, il est important de connaître la taille de votre tampon, de savoir comment il est vide ou plein (il y a généralement un bit d'état d'enregistrement pour le signaler) et garder une trace de la façon dont beaucoup de choses que vous avez transmises et combien vous avez reçues.
Avant de commencer une opération Flash SPI, il est conseillé de "vider" la FIFO de réception. Cela signifie vérifier l'état du tampon de réception et le vider (généralement en effectuant une «lecture» du tampon de réception) s'il n'est pas déjà vide. Habituellement, vider (lire) un tampon de réception déjà vide ne fait aucun mal.
Les informations suivantes sont disponibles à partir des chronogrammes dans les fiches techniques des flashes SPI, mais parfois les gens oublient les bits. Toutes les commandes et données sont envoyées au flash SPI à l'aide du bus SPI. La séquence de lecture d'un SPI Flash est la suivante:
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.
Notez que les étapes 6 et 7 doivent être entrelacées et répétées en fonction de la taille de la lecture et de la taille de vos tampons de réception et de transmission. Si vous transmettez un plus grand nombre de mots d'un coup, que votre tampon de réception ne peut contenir, vous renverserez des données.
Pour exécuter un programme de page ou une commande d'écriture, procédez comme suit. La taille de la page (généralement 256 octets) et la taille du secteur (généralement 64 Ko) et les limites associées sont les propriétés du SPI Flash que vous utilisez. Ces informations devraient figurer dans la fiche technique du Flash. Je vais omettre les détails de l'équilibrage des tampons de transmission et de réception.
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.
Enfin, si votre adresse d'écriture n'est pas sur une limite de page (généralement un multiple de 256 octets) et que vous écrivez suffisamment de données pour franchir la limite de page suivante, les données qui doivent franchir la limite seront écrites au début de la page dans laquelle votre adresse de programme tombe. Donc, si vous essayez d'écrire trois octets pour l'adresse 0x0FE. Les deux premiers octets seront écrits dans 0x0fe et 0x0ff. Le troisième octet sera écrit à l'adresse 0x000.
Si vous transmettez un nombre d'octets de données supérieur à une taille de page, les octets de début seront supprimés et seuls les 256 derniers octets (ou taille de page) seront utilisés pour programmer la page.
Comme toujours, nous ne sommes pas responsables des conséquences d'erreurs, fautes de frappe, oublis ou dérangement dans ce qui précède, ni dans la façon dont vous les utilisez.