Comment écrire sur la mémoire flash SPI?

9

Je travaille sur une application audio où au lieu de stocker des données audio sur une carte SD ( Waveshield sur Arduino), je les stocke sur un circuit intégré de mémoire flash SPI et je roule ma propre carte avec MCU, DAC et ampli.

J'utilise un Winbond W25Q80BVSSIG .

Je suis assez familier avec la programmation de l'AVR à l'aide de l' AVRISP mkII ou de l' USBTiny , l'écriture de données sur flash est-elle effectuée avec le même programmeur? Je n'ai rien trouvé lors de la recherche de programmeurs de mémoire flash SPI spécifiquement.

Cette question fait suite à celle-ci .

JYelton
la source
Je ne sais pas s'il existe un programmeur qui peut spécifiquement le faire facilement pour vous, à partir d'un PC ou quelque chose, mais s'il y a un CPLD impliqué dans votre circuit, vous pouvez le configurer pour écrire des données dans la mémoire flash.
deed02392
Je pense que les modules flash spi sont conçus depuis quelques jours pour stocker le firmware / bios que le processeur utilise dans la plupart des PC. Pas pour un périphérique de stockage robuste.
vaisseau de maréchal

Réponses:

12

Si vous cherchez simplement un moyen de programmer le flash Winbond SPI avec des données "préchargées" que votre microcontrôleur lirait pour l'utiliser lorsqu'il est en cours d'exécution, alors ce que vous voudrez étudier, c'est un programmeur qui peut faire de la programmation en circuit de la puce Flash SPI. Cela est également connu sous le nom de programmation système (ISP).

Un choix est le programmeur de DediProg. Cet appareil connecté par USB peut programmer en circuit si vous concevez correctement votre carte. Ils vendent même un clip adaptateur qui peut se fixer dans le package SOW-16 sans avoir à concevoir dans un en-tête de programmation séparé sur votre carte. DediProg propose des bulletins d'informations sur les applications pour vous aider à concevoir correctement un circuit. La stratégie principale de la conception consiste à trouver un moyen simple d'isoler les pilotes d'interface SPI de votre système MCU afin qu'ils n'interfèrent pas avec les pilotes du module de programmation SPI. La façon la plus simple de le faire est de placer des résistances en série dans les lignes pilotées par le MCU entre le MCU et le flash SPI. Le programmeur se connecterait du côté flash SPI des résistances série. D'autres méthodes pourraient inclure l'ajout d'un MUX ou de commutateurs analogiques dans les lignes d'interface pilotées. Un schéma encore plus intelligent consiste à ajouter un "

entrez la description de l'image ici

Un deuxième choix à considérer est également le programmeur USB d'ASIX . Le Presto est capable de faire différents types d'appareils SPI et I 2 C, y compris les appareils Flash SPI. J'ai l'un de ces appareils spécifiquement pour la programmation des microcontrôleurs Atmel et divers types de périphériques Flash SPI. C'est une solution plus rentable que l'unité ci-dessus mais pas tout à fait aussi flexible. Leur appareil plus cher appelé Forte est capable de faire plus de choses car il a plus de broches d'interface cible.

entrez la description de l'image ici

Parfois, il peut être avantageux de pouvoir connecter un programmeur à une carte cible sans avoir à ajouter un en-tête de programmation. Une bonne solution pour cela est de placer un petit ensemble de tampons dans une empreinte spéciale définie par une société appelée TagConnect . Ils fabriquent et vendent une série de câbles de programmation à connexion rapide qui ont des broches pogo qui engagent l'empreinte spéciale sur la carte. Il existe des versions 6 broches, 10 broches et 14 broches du câble disponibles pour convenir à une gamme d'applications. Le coût des câbles est très raisonnable.

entrez la description de l'image ici

Michael Karas
la source
C'est très utile. Je prévois de programmer la mémoire flash avant de la souder au PCB final. Jusqu'à présent, j'ai fait cela pour les MCU et cela a bien fonctionné. Je ne sais pas si fournir des broches ISP sur le PCB est une bonne idée ou non, car elles ne sont pas censées être reprogrammées une fois terminées.
JYelton
1
@JYelton - D'après mon expérience, c'est une bonne idée de planifier un FAI pour plusieurs raisons. Les ECO (Engineering Change Orders) sont une réalité du cycle de production. Quelqu'un ou quelque chose exigera un changement dans le contenu Flash une fois que vous serez en production. Les puces Flash sont parfois sensibles à des perturbations sonores inattendues dans le circuit et finissent par compromettre leur contenu. Une autre raison de prévoir un FAI.
Michael Karas
1
Existe-t-il un en-tête "standard" compatible avec la plupart de ces programmeurs au moins via des câbles adaptateurs fournis? J'ai vu des en-têtes de broches 2x4 et 2x5 avec un tas de brochages différents Voir également flashrom.org/Supported_hardware
kert
Chacun a sa propre idée du raisonnable. Les câbles Tag-connect coûtent entre 35 $ et 40 $.
markrages
1
@markrages - Mais pour un laboratoire de développement ou une station de programmation d'usine donné, vous n'avez besoin d'acheter qu'un seul câble. Vous n'en avez pas besoin pour chaque produit. De plus, ces câbles sont beaucoup moins chers que d'essayer de faire rouler votre propre fixation pogo-pin pour permettre à un FAI sans connecteur.
Michael Karas
8

Je parie que vous pourriez le faire avec un Bus Pirate sans passer par votre MCU ... qui vous permet d'effectuer des interactions série quelque peu arbitraires directement sur une puce en utilisant la communication SPI, I2C ou UART. Cela pourrait prendre un peu de travail pour le "script", mais cela vous permettrait probablement de faire le travail.

J'ai également vu des outils spécialisés pour charger directement les EEPROM sur I2C, mais pas flash et pas SPI spécifiquement.

vicatcu
la source
Je commence à me demander si ma sélection de flash SPI est bonne, étant donné à quel point (apparemment) les méthodes sont obscures pour écrire sur les choses foudroyantes.
JYelton
1
Cela nécessiterait des scripts sérieux, mais une bonne idée de toute façon. Un peu compliqué à mon goût. Vous devriez peut-être envisager une carte SD? Ensuite, il vous suffit de vous soucier de la lecture, d'écrire dessus avec un ordinateur
chwi
Le prototype actuel utilise un Arduino et Waveshield (qui a un lecteur de carte SD). Je veux m'éloigner de la carte SD car je pense que le coût sera moindre (pas de lecteur et de carte) et aussi plus inviolable.
JYelton
7

Je n'ai jamais entendu parler d'autres outils qui parlent directement de SPI à une telle puce, et je pense que c'est impossible car "toutes" les puces nécessitent des appels différents pour différentes opérations.

La puce a besoin d'appels SPI pour l'écriture, la lecture, le changement de secteur, la taille des données, etc. Sous le chapitre 7.2 Instructions de la fiche technique, vous pouvez voir toutes les commandes SPI que vous pouvez lui envoyer. Par conséquent, comme toutes les mémoires flash externes n'ont pas le même jeu d'instructions, vous devez écrire une application personnalisée pour celle-ci.

EDIT: En tant que suivi, je recommanderais vraiment l'une des mémoires flash SPI d'Atmels, car la plupart d'entre elles ont déjà écrit du code ouvert disponible pour elles. En regardant cet article d' AVRFreaks , vous obtiendrez le code de certaines puces flash série Atmels AT45xxxx.

chwi
la source
Si je vous comprends bien, devrais-je écrire un programme pour mon MCU qui écrit ensuite les données dans la mémoire flash? Le problème est que le MCU a moins de mémoire que le flash externe, donc je suis un peu à perte.
JYelton
Oui. Vous pouvez envoyer des données de la ligne série de votre ordinateur avec UART que vous écrivez sur le flash. En outre, vous pouvez écrire plusieurs programmes pour le MCU, en programmant le flash quelques blocs à la fois. Cela peut prendre un peu de temps mais cela fonctionne car le flash externe ne sera pas effacé tant que vous gardez une trace des changements de secteurs correctement
chwi
2
Ceci est la bonne réponse. Vous aurez donc besoin d'un programme sur votre PC pour télécharger des morceaux sur le MCU qui les écrit ensuite sur flash. Cela aide s'il y a une vérification d'erreur et que vous n'avez pas besoin d'écrire un nouveau programme sur le PC; donc je vous suggère de trouver du code pour XMODEM ou similaire.
pjc50
@ pjc50 ... pas si vite pour déclarer la 'bonne réponse' :)
vicatcu
En fait, de nombreux programmeurs peuvent programmer des mémoires flash; et l'un des schémas de programmation courants utilisés avec les micros atmel est assez proche de SPI pour commencer.
Chris Stratton
4

J'ai acheté un programmateur " FlashCAT " chez Embedded Computers pour environ 30 $ US. Il était étonnamment facile de se connecter au PC via USB et d'écrire des fichiers dans la mémoire flash Winbond. Les méthodes et les programmeurs dans les autres réponses sont probablement tout aussi bons, certains plus chers ou DIY, mais c'est un moyen simple et bon marché qui correspond à ce que je cherchais.

Voici une photo de la configuration:

Programmation avec FlashCAT

Le programmeur FlashCAT est à gauche, connecté à USB. Il exécute le micrologiciel de programmation SPI (par opposition à JTAG) et alimente la mémoire flash. La puissance fournie est sélectionnable (3,3 V ou 5 V) avec un cavalier.

J'ai une prise SOIC to DIP sur la planche à pain pour faciliter la programmation de plusieurs puces. (Vous pouvez également voir un autre IC de mémoire flash sur la maquette.)

Logiciel FlashCAT

Je n'ai pas encore converti mon fichier audio au format binaire approprié, mais j'ai écrit un fichier WAV de 211 Ko juste pour tester, illustré ci-dessus. Je l'ai ensuite relu et enregistré en tant que nouveau fichier, renommé en .wav et il joue correctement sur le PC.

L'étape suivante consistera à encoder correctement le fichier et à écrire le logiciel AVR pour lire les données et les envoyer via un DAC.

Avertissement: je ne suis pas affilié à Embedded Computers, je suis juste un client qui a choisi quelque chose de peu coûteux et partage des informations sur l'expérience avec le produit.

JYelton
la source
4

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.

Jeff Walther
la source
"Avant de commencer une opération SPI Flash, c'est une bonne idée de" vider "le 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 ne l'est pas. déjà vide. Habituellement, vider (lire) un tampon de réception déjà vide ne fait aucun mal. " quelles mesures dois-je prendre pour lire l'état du tampon de réception et vider le tampon de réception?
3

Contrairement à certaines des déclarations ici, bien qu'il existe des SPI SPI originales, il existe également des instructions standard utilisées par une grande variété de SPI PROM, y compris celle que vous avez choisie.

Comme vicatcu l'a déjà mentionné, il existe de bons câbles «bit-bash» qui peuvent directement programmer SPI. En ce qui concerne le signal, SPI ressemble beaucoup à JTAG, donc tout type de câble bit-bash devrait pouvoir être utilisé à condition que l'interface soit open source. Le protocole interne du flash est assez simple.

Nous utilisons le grand frère de la partie que vous regardez pour démarrer nos cartes FPGA (256M - 2G). L'adressage a un octet supplémentaire pour gérer le volume de stockage, mais sinon les commandes sont fondamentalement identiques.

Le type de PROM que vous utilisez doit être effacé par secteur, puis programmé par page. La lecture est beaucoup plus rapide que l'écriture (dans le cas de ceux que nous utilisons, la programmation peut prendre une demi-heure, mais la lecture de la PROM entière prend moins d'une seconde à 108 MHz).

Maintenant, pour les commandes: il y a bien plus de commandes disponibles dans ces appareils qu'il n'en faut pour les programmer. En fait, vous n'avez besoin que des éléments suivants:

  • RDID (lire ID) - juste pour vérifier la PROM et la signalisation avant de faire quoi que ce soit de plus complexe.
  • WREN (autorisation d'écriture) - nécessaire avant chaque écriture.
  • PP (0x02 - programme de page) - nécessaire pour programmer une page.
  • SE (0x20 - effacement de secteur) - renvoie les bits du secteur à «1».
  • RDSR (0x05 - registre d'état de lecture) - nécessaire pour surveiller le cycle d'effacement / écriture.
  • FREAD (0x0B - lecture rapide) - lire les données PROM et vérifier l'écriture.

Si vous souhaitez plus d'informations, consultez les notes de réponse sur la programmation SPI pour les FPGA Xilinx sur leur site Web (http://www.xilinx.com). Ils implémentent un sous-ensemble réduit de commandes afin que leurs FPGA puissent démarrer à partir de ces périphériques.

J'ai conçu mon propre programmeur pour ce faire sur la base de ce que j'ai à disposition et j'ai écrit un script de programmeur en Python, mais vous pouvez faire la même chose en utilisant un câble. Dans votre cas, j'envisagerais sérieusement de tout faire indirectement via le MCU, comme le suggère Michael Karas. Vous n'avez pas besoin de programmer la PROM entière à partir du MCU en une seule fois - vous pouvez le faire par secteur.

Jxj
la source
2

Vous devriez être en mesure de réaffecter l'USBtiny pour programmer une mémoire flash au lieu d'un MCU cible si vous êtes à l'aise de changer sa programmation. Cependant, il peut ne pas y avoir suffisamment de mémoire pour le rendre suffisamment polyvalent pour programmer à la fois le MCU et le flash.

Quelque part, j'ai une carte d'un projet qui a à la fois un flash ATTINY et un SPI, et utilise comme Arduino comme un "programmeur" facilement disponible. Une légère modification de l'esquisse du FAI est utilisée pour programmer le MCU avec avrdude, puis un utilitaire personnalisé envoie une séquence qui place l'esquisse dans un mode spécial et écrit des blocs de données sur le flash SPI.

Chris Stratton
la source