fonctions communes pour stm32

Introduction

Le microprocesseur stm32f1 et, sans doute, les autres variantes possèdent des fonctionnalités internes réutilisables d'un projet à l'autre. Plutôt que de se répéter dans chaque description de projet, cette page se propose de les regrouper pour ensuite y faire référence.

Voici la liste de ces fonctionnalités:

Périphérique de calcul CRC

Les codes CRC (Cyclic Redundancy Check) permettent de vérifier l'intégrité d'un bloc de donnée, par exemple le code de votre programme installé dans la mémoire flash. En effet, certains évenements de la vie courante comme les orages et les coupures de courant, ont tendance à perturber ces petits processeurs allant parfois jusqu'à modifier le programme en mémoire. Un calcul CRC peut se faire entièremnt en logiciel. Avec le stm32 on peut le faire plus simplement en utilisant le périphérique interne.

Pour ce faire, voir le code dans stmcrc.c et il faut;

L'appel à la fonction se fait avec le code suivant, le programme mkcrc fait la même chose;

      uint32_t sz = (uint32_t) &_data_loadaddr -
         (uint32_t) &vector_table +
         (uint32_t) &_edata - (uint32_t) &_data + 4;
      uint32_t crc = crc_run( (uint32_t) &vector_table, sz, NULL);
      printf( "CRC 0x%X\n", crc );

Périphérique RTC.

Le stm32 fournit un périphérique RTC (Real Time Clock) permettant de maintenir l'heure pendant la coupure de l'alimentation principale à condition d'être alimentée sur la pin VBAT par une pile ou batterie de 3 V comme cr2032 ou 2 piles de 1.5 V.

Pour l'utiliser, voir le code dans rtc.c et ;

Attention la lecture de RTC_CNT se fait en 2 fois, il peut donc y avoir une incrémentation entre les 2 lectures, mais la fonction rtc_read() en tient compte !.

Pour mesurer la fréquence du quartz de 32768 Hz divisée par 64 sur la pin PC13, pour éventuellement faire une correction, on positionne à 1 le bit CCO du registre BKP_RTCCR et on programme le gpio PC13 en mode sortie et en fonction alternée. Voir Application note AN2604.

La calibration consiste à entrer dans les bits CAL[6:0] du registre BKP_RTCCR le nombre de cycles d'horloge par millions supprimés sur l'ntrée du RTC.

Périphériques usart1 et usart3.

L'usart1 doit en principe être cablé. Il est nécessaire pour le flashage de la mémoire à partir du bootloader en rom. On peut aussi l'utiliser en module de communication de l'application avec le pc.

Les usarts sont utilisés en interruption avec un buffer circulaire en entrée et en sortie. L'application y accède avec les fonctions cbuf_write(tx_cbuf, c), cbuf_read(rx_cbuf).

Les fonctions usarts sont implémentées dans des fichiers séparés, en effet les fonctions d'initialisations et d'interruptions sont différentes. Ceci permet d'embarquer uniquement le fichier dont on a besoin.

Les usart1 et usart3 sont implémentés dans usart1.c et usart3.c.

Périphérique USB et cdcacm.

Le processeur possède une interface USB device utilisée par le module cdcacm qui fournit 2 canaux de communication entre le processeur et le pc. Ces canaux s'utilisent comme une liaison série.

Lorsque le module est activé sur le micro et que le cable USB est branché, 2 nouveaux devices /dev/ttyACM0 et /dev/ttyACM1 apparaissent du coté pc. Ils peuvent être utilisés par un terminal ou une application indépendemment de /dev/ttyS0.

Du coté processeur, cdcacm communique avec l'application à travers des buffers circulaires comme pour l'usart. C'est alors le rôle de l'application de gérer et de connecter ces endpoints, comme utiliser un cnnal en console, ou faire un convertisseur usb-série.

Périphérique i2c2.

Le module i2c2.c fournit une implémentation des fonctions i2c maitre et esclave en utilisant l'interface i2c2 du stm32f1.

User hardfault handler.

Ce module User hardfault handler implémenté dans stmdbg.c, c'est le module dont on n'a pas normalement besoin. Il peut arriver, parce que l'on a mal écrit son code (il faut bien trouver une raison !), que le processeur ne sache pas exécuter le code généré par le compilateur. Il se produit alors une exception plus prioritaire que l'interruption la plus prioritaire, résultant en un code figé et plus rien ne se passe parce que le handler par défault est une boucle infinie.

Le User hardfault handler va remplacer le handler par défault et fournir quelques informations sur les causes du problème avec printf. Mais comme les usarts ne fonctionnent plus à cause des priorités des interruptions, il faut se créer une fonction putc qui utilise l'usart en mode bloquant usart_send_blocking.

Pour la mise en oeuvre, il suffit d'embarquer le module stmdbg.c et compiler avec l'option -DUSE_USER_HARDFAULT.

L'information importante que l'on peut retirer, c'est la valeur de l'adresse contenue dans le PC (program counter) au moment ou l'exception se produit. La comparaison de cette adresse avec les adresses de votre code permet de déterminer l'endroit ou cela se produit. Le contenu du registre LR donne l'adresse de retour de la dernière fonction appelée. voir la page de Frank's Random.

Références