Problèmes et corrections de la RTC DS1302 sur carte ACME Fox
Dans un précédent billet j'ai détaillé la mise en oeuvre d'une RTC à base de DS1302 pour la carte ACME Fox. Constatant une dérive d'horloge assez importante, j'ai décidé de revoir la chose. Un quartz c'est fragile et il y a un petit problème dans le code du support DS1302 dans le noyau...
La dérive d'horloge vient du montage lui-même. Il faut faire très attention avec les quartz et respecter les conseils donnés dans la datasheet :

Ground plane is the key ! Sinon le quartz fait un peu... antenne et ne tient pas la route. J'ai donc bien blindé la chose et cela devrait mieux se passer (le temps nous le dira puisque la dérive est de quelques dixièmes de seconde par jour seulement).
Mais durant les expérimentations, le DS1302 ne fonctionnait pas toujours. Certes, il pouvait stocker la date mais l'horloge elle-même ne fonctionnait pas. Étrange. La datasheet apporte la réponse :
«CLOCK HALT FLAG : it 7 of the seconds register is defined as the clock halt (CH) flag. When this bit is set to logic 1, the clock oscillator s stopped and the DS1302 is placed into a low-power standby mode with a current drain of less than 100nA. When his bit is written to logic 0, the clock will start. The initial power-on state is not defined.»
En bon français, le bit 7 du registre des secondes est le drapeau CH qui, à 1, arrête l'horloge. Pire encore, l'état à la mise sous tension du composant est indéfini ! Un petit coup d'oeil dans le code (os/linux-2.6-tag--devboard-R2_01-1/arch/cris/arch-v10/drivers/ds1302.c) et, surprise, pas une seule ligne ne s'assure que ce drapeau est bien à zéro.
On ajoute donc :
/* LEFINNOIS */
printk(KERN_INFO "%s: HC enable.\n", ds1302_name);
out_byte(0x81);
lefinnois = in_byte();
ds1302_wenable();
out_byte(0x80);
out_byte(lefinnois & 0x7F);
ds1302_wdisable();
out_byte(0x81);
if((res = in_byte()) && 0x80) {
printk(KERN_INFO "%s: HC enable OK.\n", ds1302_name);
}
printk(KERN_INFO "%s: HC enable done.\n", ds1302_name);
/* /LEFINNOIS */
Dans la fonction ds1302_probe(void). Effectivement au démarrage on retrouve :
ds1302: RTC found. ds1302: SDA, SCL, RST on PB0, PB1, GENIO2 ds1302: HC enable. ds1302: HC enable OK. ds1302: HC enable done.