Ce qui m'a fait aller voir comment le RP2040 pourrait traiter le problème du Manchester ou de la réception du feedback MFX.
Sur esp32, RMT transmet donc des symboles Rx à la CPU. Puis cette dernière doit ensuite les valider et les convertir en bits: un travail pour la CPU. Ensuite seulement, la CPU commencera à traiter les bits... A de petits débits et avec des messages courts, ça doit être un travail raisonnable pour la CPU de l'esp32.
Le RP2040 a une sorte d'assembleur et jusqu'à 8 machines à états sur les IO, qui déchargent la CPU. Le RP2350 a jusqu'à 12 machines à états. C'est spécifique à ces CPU Raspberry.
Ce code pour RP2040 semble partir du principe qu'il n'existe que deux symboles possibles, 10 ou 01. Ca exclue les erreurs de symboles, les erreurs de transmission... Au lieu de pousser des symboles dans une FIFO, le code pousse les bits décodés dans la FIFO. Ce qui soulage alors la CPU, elle n'a plus qu'à traiter ensuite les données reçues:
https://github.com/raspberrypi/pico-examples/blob/master/pio/manchester_encoding/manchester_encoding.pio.program manchester_rx
; Assumes line is idle low, first bit is 0
; One bit is 12 cycles
; a '0' is encoded as 10
; a '1' is encoded as 01
;
; Both the IN base and the JMP pin mapping must be pointed at the GPIO used for RX.
; Autopush must be enabled.
; Before enabling the SM, it should be placed in a 'wait 1, pin` state, so that
; it will not start sampling until the initial line idle state ends.
start_of_0: ; We are 0.25 bits into a 0 - signal is high
wait 0 pin 0 ; Wait for the 1->0 transition - at this point we are 0.5 into the bit
in y, 1 [8] ; Emit a 0, sleep 3/4 of a bit
jmp pin start_of_0 ; If signal is 1 again, it's another 0 bit, otherwise it's a 1
.wrap_target
start_of_1: ; We are 0.25 bits into a 1 - signal is 1
wait 1 pin 0 ; Wait for the 0->1 transition - at this point we are 0.5 into the bit
in x, 1 [8] ; Emit a 1, sleep 3/4 of a bit
jmp pin start_of_0 ; If signal is 0 again, it's another 1 bit otherwise it's a 0
.wrap
% c-sdk {
static inline void manchester_rx_program_init(PIO pio, uint sm, uint offset, uint pin, float div) {
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
pio_gpio_init(pio, pin);
pio_sm_config c = manchester_rx_program_get_default_config(offset);
sm_config_set_in_pins(&c, pin); // for WAIT
sm_config_set_jmp_pin(&c, pin); // for JMP
sm_config_set_in_shift(&c, true, true, 32);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
// X and Y are set to 0 and 1, to conveniently emit these to ISR/FIFO.
pio_sm_exec(pio, sm, pio_encode_set(pio_x, 1));
pio_sm_exec(pio, sm, pio_encode_set(pio_y, 0));
// Assume line is idle low, and first transmitted bit is 0. Put SM in a
// wait state before enabling. RX will begin once the first 0 symbol is
// detected.
pio_sm_exec(pio, sm, pio_encode_wait_pin(1, 0) | pio_encode_delay(2));
pio_sm_set_enabled(pio, sm, true);
}
%}Vu comment fonctionnent ces PIO du RP2040 on pourrait même imaginer plus simple que avec Manchester, avec juste clock et data RDS:
- détecter la clock, une première transition, la présence d'une porteuse
- ou détecter un premier bit à zéro
- le préambule MFX, ce sont des bits à zéro
- attendre le start bit, un bit à 1, s'il en suit un
- après un start bit, ne faire le shift in que de la data et de la checksum
Après réception, la CPU d'un RP2040 n'aurait alors plus qu'à vérifier la checksum de la data reçue. Pour très peu de travail à réaliser par cette CPU.
Cerise sur le gâteau, pour des transferts plus volumineux, ou par gros bursts, alors que la FIFO PIO du 2040 a une taille limitée de 32 bits, il doit être possible de transférer son contenu via la DMA. J'en retiendrais simplement que RMT vs PIO/DMA, ce ne seront pas les mêmes applications.
https://github.com/raspberrypi/pico-examples/blob/master/pio/logic_analyser/logic_analyser.cEntre l'esp, mfx, le 2040 et tout le reste, ça fini par devenir un océan sans fond. JMP, on en apprend plus dans la datasheet du 2040. X et Y dans ces instructions, c'est quoi?
https://files.seeedstudio.com/wiki/XIAO-RP2040/res/rp2040_datasheet.pdf