firmware - TiboLGH/solextronic GitHub Wiki
Le firmware est concu pour tourner sur un Atmel ATMega328 (sur une carte Arduino Nano v3). Il est écrit en C et compile avec avr-gcc et la avr-libc.
Neanmoins, la plupart du code specifique à l'AVR est regroupé dans le fichier platform.c. Utiliser un autre MCU doit se limiter a une réadaptation de ce fichier + changement des headers.
Le firmware est compose de plusieurs taches :
- une tache de fond basse priorité
- une tache de mesure du signal PMH et de génération des signaux d'allumage et d'injection à l'aide des modules capture/compare des timers hardware.
- une tache périodique (1ms) : pseudo-RTC, trigger des conversions analogique-numerique.
Tache de fond Cette tache implémente :
- gestion de l'EEPROM
- gestion des commandes USB/RS232
- calcul des timings d'allumage et d'injection
- Dans un 2e temps : gestion de la face avant LCD/boutons
Tache "PMH" Cette tache se base sur un timer hardware (Timer 1) et est cadencée sur le top PMH. Une rotation moteur se déroule de la façon suivante :
- au top PMH, l'interruption INT0 est déclenchée : le contenu du timer 1 est capturé (et permet de calculer le régime courant). C'est le début du cycle. Attention, depuis la version 0.2, le contenu du timer n'est pas remis à 0: tous les timings sont en relatif.
- les registres output compare A (allumage) et B (injection) sont chargés avec les valeurs permettant de déclencher l'allumage et le début d'injection. Ces valeurs sont calculées en tache de fond. Note : ces calculs sont assez rapides pour tenir dans un cycle moteur.
- quand le timer 1 atteint une des valeurs des OC, la pin correspondante change d'état et une interruption est déclenchée : dans cette interruption, le registre OC correspondant est rechargé avec la valeur de fin d'evenement (durée d'injection ou d'allumage).
- le cycle reprends au prochain top PMH.
Le timer 1 a une granularité de 4µs et un overflow de 262ms (~230 tr/min). On considère le moteur "calé" si on ne reçoit pas de top PMH pour un cycle complet .
Tache périodique (1ms) Cette tache se base sur un timer hardware (Timer 2) réglé pour déclencher une interruption chaque ms.
- Mise à jour des timers software
- Mise à jour de la pseudo-RTC (tous les 100msec)
- Déclenchement des conversions analogique/numérique (tous les 10msec)
- Déclenchement des cycles allumage/injection dans les modes de tests.
Autres taches
- Emission/reception des caracteres sur l'USART sur interruption.
Il y a 6 fichiers principaux :
main.c
- Initialisation
- Tache de fond (incluant calcul de l'injection et l'allumage)
command.c/.h
- Interpretation des commandes RS232
helper.c/.h
- Regroupe les functions d'interpolation, de conversions...
- A la fois executé par le firmware et la simulation.
platform.c/.h
- Interface USART
- Gestion EEPROM
- Service de timer software
- interface I²C
- interface ADC
- interface PWM
- Gestion des timings allumage/injection
common.h
- Définitions des structures communes
- Version
varDef.h
- Mapping de l'EEPROM
- Mapping de l'état interne en RAM
- Ce fichier est également utilisé par la simulation
frontPanel.c/.h
- Gestion de l'écran LCD et des bouttons accessibles
- Gestion des menus du LCD
- Gestion de la couleur du rétroéclairage poour donner l'état global
Cette section décrit les ressources matérielles utilisées dans le microcontroleur.
- Horloge principale a 16MHz
- RS232 : 57600, 8bits, pas de parité
- Timer 0 (8 bits) : génération PWM pour le controle de l'injecteur
- Timer 1 (16 bits): Mesure RPM et generation des signaux allumage et injection
- Timer 2 (8 bits) : horloge 1ms pour la pseudo RTC et les timers software
TODO
ADC Utilisation ADC1 Temperature 1, culasse
Le facteur de conversion est de 10mV/°ADC2 Temperature 2, admission
Le facteur de conversion est de 10mV/°ADC3 Papillon ADC6 Capteur de pression/debit
TDBADC7 Niveau batterie
Le facteur de conversion est x3
Le scheduler de conversion réponds aux critères suivants :
- 1 seule fonction doit etre capable d'accéder à l'ADC
- certaines conversions se font en tache de fond sans timing precis (temperatures, batterie)
- la mesure de la position du papillon se fait sur un timer 10ms + timestamp pour calculer la vitesse de variation. Le gestionnaire d'ADC fait le calcul de la vitesse de variation.
- la mesure de la pression se fait de facon synchrone avec le top PMH (avec un angle d'avance reglable)
Le scheduler de mesure doit :
- faire les mesures basse priorité en permanence
- maintenir un timer 10ms pour faire la mesure papillon qui passe en priorité juste apres la mesure en cours
- en cas de demande de mesure de pression, on arrete la mesure en cours pour faire la mesure pression ASAP.
2 choix d'implementation avec priorité au 1 :
- Fonctionnement sur interruption : la FSM scheduler est rythmée par les interruptions de fin de conversion et la requete de mesure immédiate
- Le scheduler est appelé regulierement dans la loop principale
Interface:
-
Entrées
- AdcFSM() : implémentation de la FSM. L'état interne est réévalué à chaque appel (polling ou int)
- AdcPressureMeasure() : déclenche une mesure de pression ASAP. Appel non bloquant, la mesure est disponible avant le prochain cycle
-
Sorties :
- Résultats de conversions dans la structure gState mise à jour à chaque conversion
Les commandes RS232 sont basees sur le protocole de Megasquirt décrit dans la page Commandes. Les variables accessibles sont définies dans varDef.h :
- eData : parametres accessibles en écriture et stockées en EEPROM (+ image en RAM)
- gState : variables internes accessibles en lecture et stockées en RAM
Le pilotage des boutons externes et du LCD se fait à travers un module Adafruit (http://www.adafruit.com/product/714). Il comporte 5 boutons, un LCD 2 lignes/16 caractères et un rétroéclairage 8 couleurs le tout piloté par I2C.
Le driver est inspiré du code Adafruit modifié pour fonctionner en C pur sans les libs Arduino et largement allégé. Il fonctionne en 4 couches :
- la communication I2C bas niveau
- le pilotage du composant IO expander
- le pilotage du LCD et des boutons
- la mécanique des menus
Les menus sont pilotés par 5 boutons : up/down, +/- et OK. On change de menu avec up/down, on change de réglage avec +/-. Le bouton OK permet de valider un choix.
Dans le mode normal, le bouton OK permet d'indiquer le début d'un tour.
Les menus sont les suivants (simulation LCD par l'applet du site Avtanski):
Normal : en alternance
En cas de problème, le fond devient rouge :
Etats des entrées : Valeurs ADC brutes:
En appuyant sur + ou -, valeurs converties:
Ajustement allumage en °
Ajustement injection : temps d'injection en µs
Ajustement injection : début d'injection on °
Autodignostic (TODO)
Chrono (TODO)
Pour le debug, on peut afficher des messages ou déclencher un assert :