Désolé d’avoir mis mon grain de sel.
Voila un bout de code (DU CONCRET) de l’un de mes projets. Toute le présentation est cassée mais normalement, je ne laisse pas un truc qui ne soit pas aligné si je peux (je suis trop maniaque). Les 72/80 caractères, j’essaye mais je ne sais pas toujours comment m’en sortir ; le but étant simplement d’éviter des lignes de 4m de long. On y trouve du bon et du pas bon (bcp de fautes d’orthographe je pense), mais l’idée générale est là.
/*--------------------------------------------------------------------------*/
/* */
/* Logiciel embarqué de la carte XXXXX */
/* */
/*--------------------------------------------------------------------------*/
/** \file Max6955.c
\brief <B> Module contenant les fonctions de gestion du Max6955
</B>
Ce module contient les fonctions de gestion du composant Max6955
(Led Display Driver).
<TT> produit..:
\n version..: 00
\n auteur...: Fr. JONCOURT
</TT>
*/
/*-------------------------------- Librairies ------------------------------*/
#include "XXXXX.h"
/*------------------- Declarations des variables locales -------------------*/
static TMax6955Reg Max6955Reg; ///< Registres de controle du Max6955
/*------------------- Affectation des segments du Lexan --------------------*/
// Tableau de croisement entre les digits du Max6955 et les digits softs utilisés
// dans le module affichage.c
static const U8 CODE affiCrossedTable[NB_SS_PHY][3] =
{ // CENTAINES DIZAINES UNITES
{ REG_DIGIT_0_P0P1, REG_DIGIT_1_P0P1, REG_DIGIT_2_P0P1 }, // SS_I_INFO
{ REG_DIGIT_0A_P0P1, REG_DIGIT_1A_P0P1, REG_DIGIT_2A_P0P1 }, // SS_I_REGU_LO
{ REG_DIGIT_3A_P0P1, REG_DIGIT_4A_P0P1, REG_DIGIT_5A_P0P1 } // SS_I_REGU_HI
};
// Tableau de croisement entre les voyants du Max6955 et ceux utilisée dans
// le module affichage.c
static const U8 CODE ledsCrossedTable[LED_I_ALL][2] =
{
// REGISTRE POSITION
{ REG_DIGIT_4_P0P1, 0x40 }, // LED_I_MODE_1
{ REG_DIGIT_4_P0P1, 0x20 }, // LED_I_MODE_2
{ REG_DIGIT_4_P0P1, 0x10 }, // LED_I_MODE_3
{ REG_DIGIT_4_P0P1, 0x08 }, // LED_I_MODE_4
{ REG_DIGIT_4_P0P1, 0x04 }, // LED_I_MODE_5
{ REG_DIGIT_3_P0P1, 0x10 }, // LED_I_READY_HI
{ REG_DIGIT_4_P0P1, 0x40 }, // LED_I_READY_LO
{ REG_DIGIT_5_P0P1, 0x80 }, // LED_I_REGUL_HI
{ REG_DIGIT_5_P0P1, 0x40 }, // LED_I_REGUL_LO
{ REG_DIGIT_3_P0P1, 0x04 }, // LED_I_PEDALE
{ REG_DIGIT_3_P0P1, 0x02 }, // LED_I_VENTILO
{ REG_DIGIT_3_P0P1, 0x01 }, // LED_I_FORWARD
{ REG_DIGIT_5_P0P1, 0x20 }, // LED_I_REARM
{ REG_DIGIT_4_P0P1, 0x02 }, // LED_I_MARCHE1
{ REG_DIGIT_4_P0P1, 0x02 } // LED_I_MARCHE2
};
#define REGISTRE 0x00
#define POSITION 0x01
/****************************************************************************/
/** <B> Charger la configuration actuelle dans le Max6955.
</B>
Cette fonction permet d'initialiser les registres du MAX6955 avec la
configuration presente. dans la structure de controle.
*/
static void load_config (
U8 slaveAddress) ///< Adresse du slave avec qui communiquer
{
Max6955Write(slaveAddress, REG_DECODE_MODE,
sizeof(TConfigReg),
(U8*)&Max6955Reg.configReg);
Max6955Write(slaveAddress, REG_KEY_A_PRESSED,
sizeof(Max6955Reg.configReg.digitType),
&Max6955Reg.configReg.digitType);
}
/****************************************************************************/
/** <B> Attends que le MAX6955 soit prêt
</B>
Cette fonction locale attend pendant 10ms maximum que le MAX6955 réponde à
son adresse sur le bus. Ce temps correspond au temps maximum d'écriture d'une
donnée dans le MAX6955.
\return OUI si EEPROM prête à recevoir des instructions.
NON si EEPROM ne répond plus.
*/
static max6955_ready(
U8 slaveAddress) ///< Adresse du slave avec qui communiquer
{
U8 tim; /* compte-rendu de la fonction */
// Attendre pendant 10ms que le MAX6955 soit pret
for (tim=40 ; tim != 0 ; tim--)
{
// Sortir si adresse du max6955 est prise en compte
I2cStart();
if (I2cWrite(0xC0 | (slaveAddress << 1) | WR_MAX6955))
break;
mDelayMs(10);
}
// Retourner le compte rendu
return (tim != 0) ? OUI : NON;
}
/****************************************************************************/
/** <B> Initialiser le MAX6955
</B>
Cette fonction permet d'initialiser la structure de controle du MAX6955.
*/
void Max6955Init (void)
{
U8 ix; ///< Variable temporaire pour l'initialisation des digits
// Initialiser le bus I2C - déjà fait
// I2cInit();
// Mettre en place la configuration du MAX6955
Max6955Reg.configReg.decodeMode = 0x00; // Enlever le decode mode
Max6955Reg.configReg.globalIntensity = 0x0E; // Positionner l'intensite globale au minimum
Max6955Reg.configReg.scanLimit = 0x06; // Scanner sur 7 digits
Max6955Reg.configReg.controlRegister = 0x09; // Mettre le driver en mode normal avec blinking mode enabled
Max6955Reg.configReg.gpioData = 0x05; // Valeur par defaut (non utilisee)
Max6955Reg.configReg.portConfiguration = 0x40; // Scanner KEY_A et KEY_B pour les touches
Max6955Reg.configReg.digitType = 0x00; // Mode 16 ou 7 segments pour les digits 0 à 7
// Eteindre toutes les leds
Max6955Reg.reloadDigit = 0xFF;
for (ix = 0 ; ix < sizeof(Max6955Reg.digit) ; ix++)
{
Max6955Reg.digit[ix] = 0x00;
Max6955Reg.blink[ix] = 0x00;
}
// Mettre à jour la configuration
load_config(SLAVE_ADDRESS);
// Mettre à jour les données
Max6955Update();
}
/****************************************************************************/
/** <B> Ecrire une plage de donnees dans les registres du Max6955
</B>
Cette fonction ecrit une plage de donnees dans un des registres du Max6955,
en fonction de la cde passée en paramètre et de l'adresse de l'esclave.
return OUI si l'ecriture c'est bien passee
NON
*/
U8 Max6955Write (
U8 slaveAddress, ///< Adresse du slave avec qui communiquer
U8 reg, ///< Registre à charger
U8 taille, ///< la taille des donnees en octets a ecrire
U8 *donnee) ///< Pointeur sur la donnee
{
U8 correct; ///< Détection d'une erreur
// Attendre que le max6955 soit pret
if (!max6955_ready(slaveAddress))
return NON;
// Envoyer la commande
if (!I2cWrite(reg))
return NON;
/* Tant que tous les octets n'ont pas été écrits, */
correct = OUI;
while (taille-- != 0)
{
if (correct)
correct = I2cWrite(*donnee++);
else
break;
}
// Envoyer l'octet de STOP
I2cStop();
return correct;
}
[…]
Et voila une fonction beaucoup trop longue car je suis loin d’être tout blanc, mais j’essaye :
/****************************************************************************/
/** <B> Met la structure de controle du MAX6955 a jour
</B>
Cette fonction permet de mettre a jour la structure de controle du MAX6955,
en fonction de l'affichage en cours.
*/
void Max6955UpdateReg(
U8 mode, ///< Mode d'affichage a prendre en compte
U8 identifiant) ///< Id(specifique au mode) a mettre a jour
{
U8 col; ///< Variable temporaire
U8 ix; ///< Digit du driver a mettre a jour
U8 idVirtuel; ///< Identifiant de l'afficheur virtuel au premier plan
U16 position; ///< Position de la led en cours de mise a jour
U8 segment; ///< Segment du bargraphe en cours de mise a jour
switch (mode)
{
case MODE_AFFICHEURS :
// Obtenir l'identifiant de l'afficheur virtuel au premier plan pour le
// 7 segments selectionne
for (ix=0x00 ; ix<SS_V_MAX ; ix++)
{
if ((tabAffi[identifiant].mode >> ix) == 0x01)
{
idVirtuel = ix;
break;
}
}
// Parcourir toutes les colonnes (unites, dizaines, centaines) de
// l'afficheur virtuel en cours
for (col=CENTAINES ; col<=UNITES ; col++)
{
// Obtenir le digit du MAX6955 associe au digit "soft"
ix = affiCrossedTable[identifiant][col] - REG_DIGIT_0_P0P1;
// Mettre en evidence une demande de rechargement du driver pour
// le digit specifie
Max6955Reg.reloadDigit |= (1<<ix);
// Mettre a jour la structure de controle du Max6955
Max6955Reg.digit[ix] = tabAffi[identifiant].affiVirtuel[idVirtuel][col];
if (tabAffi[identifiant].affiClign[idVirtuel][col])
Max6955Reg.blink[ix] &= ~Max6955Reg.digit[ix];
else
Max6955Reg.blink[ix] = Max6955Reg.digit[ix];
}
break;
case MODE_LEDS :
// Obtenir le digit du MAX6955 associe au digit "soft"
ix = ledsCrossedTable[identifiant][REGISTRE] - REG_DIGIT_0_P0P1;
position = ledsCrossedTable[identifiant][POSITION];
// Mettre en evidence une demande de rechargement du driver pour
// le digit specifie
Max6955Reg.reloadDigit |= (1<<ix);
// Mettre a jour la structure de controle du Max6955
Max6955Reg.digit[ix] &= ~position;
Max6955Reg.blink[ix] &= ~position;
if (tabLeds.etat & (1<<identifiant))
Max6955Reg.digit[ix] |= position;
if ( (tabLeds.blink ^ tabLeds.etat) & (1<<identifiant) )
Max6955Reg.blink[ix] |= position;
break;
case MODE_BARGRAPHE :
// Parcourir tous les segments disponibles pour le bargraphe en cours
for (segment=0 ; segment<tabBg[identifiant].niveau ; segment++ )
{
// Obtenir le digit du MAX6955 associe au digit "soft"
ix = bgCrossedTable[identifiant][segment][REGISTRE] - REG_DIGIT_0_P0P1;
position = bgCrossedTable[identifiant][segment][POSITION];
// Mettre en evidence une demande de rechargement du driver pour
// le digit specifie
Max6955Reg.reloadDigit |= (1<<ix);
// Mettre a jour la structure de controle du Max6955
Max6955Reg.digit[ix] &= ~position;
Max6955Reg.blink[ix] &= ~position;
if (tabBg[identifiant].etat & (1 << segment))
Max6955Reg.digit[ix] |= position;
if ( (tabBg[identifiant].clignotement ^ tabBg[identifiant].etat) & (1 << segment) )
Max6955Reg.blink[ix] |= position;
}
break;
}
}
J’ai encore beaucoup de choses à faire pour m’améliorer que ce soit au niveau algo, méthodes, clarté mais je teste et je vois ce que cela donne et ce que les autres en pense. Cela fait maintenant un peu moins de 2 ans et demi que je travaille, et du soft j’en fait 75% du temps autrement je fais les cartes qui vont avec. Du coup, avoir quelque chose de propre, de réutilisable et de maintenable s’impose.
Une demande de modification de soft tombe, alors que je suis sur un autre projet, ou le client appelle et veut savoir pourquoi le soft fait cela mais il reste en ligne.
Pas de commentaire et incompréhensible => trop de temps à retrouver ses petits => BIP !