Bonsoir
Ca semble en effet la construction adéquate.
Je pèche en revanche sur ce que je "connais" et ce qui me "manque".
Ce qui "est connu":
La Lib d AIKO utilise le mode de capture du timer en charge du traitement du signal DCC en mode "Frequency measurement" avec un déclanchement sur "event".
Chaque "détection" d'un front montant ou descendant introduit une interruption. Une bascule s'opère entre la "montée et la descente via (EVENTCTRL ^= EDGE) Lors de celle ci et de façon automatique liée à cette implémentation la valeur du compteur du timer TIMERx.CNT est transférée dans le registre TIMERx.CCMP.
On effectue alors une "moulinette" en ayant mis à l échelle des timings avec la vitesse du CPU pour déterminer si on a un "demi 0" , un "demi 1" et bien aussi si on ne "serait pas" dans le cadre d un intervalle de timing de type RAILCOM CUTOUT ( typique 29us (intervalle de 26us à 32us selon les tolérances en vigueur de cette même norme) On a l'idée de vérifier les entrées des PIN DCC venant des deux pôles de la voie. ( 1 serait il suffisant?) ( utilisation de la commande PORTx.IN & "bytes" == "valeur*") (* celle du mask_combo évoquée dans mes précédents messages)
Si pas dans le cutout on assemble ensuite les "1" et les "0" après diagnostic de leur conformité pour constituer les messages DCC. ( ou pas! et alors "reset"!)
Pour RAILCOM on sait donc identifier le cas ou on est dans un CUTOUT:
on a un intervalle de détection conforme ET les entrées des pins DCC sont à "0" puisque il n y a pas de tension dans la voie ( sur les deux rails) ( les valeurs sont plutôt à 1 mais l'absence de tension est un état "0" = OFF) Comme le HARD inverse cette logique on cherchera alors à trouver une valeur 1 sur la lecture des pins
A tout moment on à alors les valeurs TIMERx.CNT et TIMERx.CCMP à dispo qui peuvent être exploitées. puisqu'il il n y aura pas d autre interruption (normalement) avant la reprise des trames DCC post cutout ( donc retour de tension et nouvelle mesure de temps entre 2 fronts de directions opposées) ( dans le cas contraire bye bye railcom et on rebascule en mode "nominal" de traitement des 0 et 1)
Dans mon "analyse" si j ai ces conditions de remplies je "déclenche" seulement le timer du railcom( TIMERy) et je vais avec celui ci voir si je suis dans les intervalles d émission des canaux 1 et 2 ( si on a active RAILCOM via le bon bit du CV29 et préciser ce que l on émet à l aide des bits du CV28 ( canal 1 et ou canal 2)). Je peux rester dans l ISR générée par le signal DCC.( j ene vois pas comment faire le start du timer RC autrement en mode "periodic interupt")
Donc si je ne suis pas dans l erreur on ajoute le temps écoulé sur le TIMERx à la valeur CNT du TIMERy utilisé pour la mesure de temps RAILCOM. ( le CCMP0 que tu indiquais avoir mis en mémoire)
Ce timer peut alors être simplement mis en mode "Periodic interrupt" dont on s arrangera pour ne jamais atteindre le seuil haut ou seulement à la fin du temps équivalent au max du timing cutout ( les fameuses 488us après le temps de référence T0 amorcé sur le TIMERx et incrémentés ici en sus à l origine du démarrage de ce TIMERy dédié à railcom.)
Dans le cas d une éventuelle ISR du timer Railcom on aurait alors STOP du timer RC, flag railcom = false, reset de la valeur CNT.
Lors des plages ad hoc (75us 177us) on émet manuellement les "2 bytes du CH1" une tempo puis ceux (les 3 bytes) du CH2 (de 193 à 454us) (CH2 dont il reste à construire aussi la création des contenus)
Ce que je n identifie pas c est "comment"/ "pourquoi" on établirait sur le "front montant"(oui c est le point de depart) l'interruption de démarrage du TIMERy pour RC de façon systématique quitte à faire un reset lors d un front descendant reçu sur le TIMERx si c est dans la plage ouverte et dans les conditions du cutout...
Il faudrait alors une condition qui fasse que uniquement sur les fronts montant on d'éclanche le compteur TIMERy pour RAILCOM depuis l'interruption générée sur le traitement du signal DCC.( et "reset sur les front descendants)
Certes on s éviterait ainsi les passages de valeur(s) multiples inter timer comme j en avais l idée initialement... whynot!
En quittant l ISR on arrêterait aussi du coup le TIMERy du railcom qui serait en même temps réinitialisé ( TIMERy.CNT =0, TIMERy.CCMP= (valeur a maxima pour 488us), (bitClear(TIMERy.CTRLA,0) pour arreter le timer y.
Le code "NIPPON" formule l usage d envoi des messages sur le CH1 ( senduart(data)) et construit pour cela le paramétrage "complet" de l'uart.
Je ne suis pas du tout familier avec l UART et ses mécanismes mais l'inspiration "est là"
Je pense qu'une petite classe complémentaire RAILCOM_UART va devoir faire son apparition...
Tout laisser dans l ISR parait presque "trivial" des lors que tout est construit "à la main". ( on contourne ainsi l émission sur TX DANS l ISR, ce qui est naturellement impossible avec la lib serial et les bons timings.)
L'autre solution alternative qui me vient en tête serait de rendre prioritaire les interruptions pour émettre les messages RAILCOM sans interruption extérieure dans les conditions requises avant de revenir à un niveau standard. C'est peut être un peu capillotracté et moins judicieux? /ou combinable) ou devenu inutile!... Sauf selon l effet contraire que toute nouvelle interruption sur le signal DCC viendrait obligatoirement faire un reset de "l encours", ce qui, si on est en émission railcom des bytes des CH1 ou 2 et en priorité LVL1 incompatible… On va donc oublier cette fausse bonne idée pour le moment.
Questions: quant tu parles de UART0.TXDATA tu veux parler de UART0.TXDATAL ?
Si j ai bien compris, ce registre contient précisément le Byte a envoyer donc si on n'a pas fini son émission complètement il ne faut pas le rafraichir par son successeur? ( supposition)
donc la close
if (USART0.TXDATA & DREIF) serait (plutôt) à mettre entre chaque refresh des valeurs ds le registre TXDATAL pour émission. Une fois le byte envoyé refresh etc
Ou alors on stocke les valeurs à envoyer successivement dans un "POOL des BYTES RAILCOM A EMMETTRE" et on avance dans ce pool au fur et à mesure que chaque byte est envoyé un par un. Et ce pool est rafraichi périodiquement si valeurs dynamiques (ou pas si valeurs statiques ex l adresse ne change pas alors que la vitesse elle évolue plus régulièrement)...
A voir donc...
Laurent
Rm: pour ceux qui suivent ce fil et notre échange, ne soyez pas "timide" pour poser vos questions ou apporter votre pierre à l'édifice.