Skip to content

hal: microchip: pic32c: fix the SG/GC no-parity USART frame format - #76

Open
TheArkadiuszGrzelka wants to merge 1 commit into
zephyrproject-rtos:masterfrom
ArivEmb:sercom-sg-gc-no-parity-form
Open

hal: microchip: pic32c: fix the SG/GC no-parity USART frame format#76
TheArkadiuszGrzelka wants to merge 1 commit into
zephyrproject-rtos:masterfrom
ArivEmb:sercom-sg-gc-no-parity-form

Conversation

@TheArkadiuszGrzelka

Copy link
Copy Markdown

The SG/GC SERCOM mapping header points the no-parity frame format at the with-parity encoding, so every UART in the family runs an 11-bit frame while reporting 8N1; host-to-device traffic desynchronises on the second character of a burst and the board is unusable as a console under load.

Why this one, and what it deletes here

include/pic32cm_sg_gc_fixups.h in the pic32cm-gc00 workspace carries the
same correction as an #undef/#define pair, force-included into every
build. That block goes away the moment this merges - it is the entire
reason the fixups header exists for USART.

Consumer

hal_microchip merges a change once the Zephyr-side pull request that needs
it is green (nandojve on #38, stated twice). The consumer here is the board
pull request for pic32cm_gc00_cpro, which gives the board a console over
SERCOM0: without this fix that console is an 11-bit frame claiming 8N1.
Open the two as a pair, cross-linked, and expect this one to merge second.

Measured

With the correction in place - as the workspace's fixups header applies it
today - a SERCOM UART node configured parity = "none" carried 163239 bytes of
CRC-checked SMP traffic to a host opened at 8N1, in 31.1 s at 115200 baud, with
no framing or checksum failure. A transmitter emitting the 11-bit
with-parity frame while the receiver expects 10 bits does not survive that.

What a reviewer will ask

Why the with-parity mapping stays as it is: because it is correct. FORM=1
is the with-parity encoding, and only the no-parity name was pointed at it.

sercom_pic32cm_sg_gc.h maps both frame formats onto the same pack macro:

    #define SERCOM_USART_CTRLA_FORM_USART_FRAME_WITH_PARITY \
            SERCOM_USART_CTRLA_FORM_USARTP
    #define SERCOM_USART_CTRLA_FORM_USART_FRAME_NO_PARITY \
            SERCOM_USART_CTRLA_FORM_USARTP

Both resolve to FORM=1, "USART frame with parity", so uart_mchp_sercom_g1.c
writes the with-parity encoding on its parity = "none" path. Every UART in
the family then sends and expects an 11-bit frame while reporting 8N1.

Device to host survives it, which is what hides the defect: the host reads
the eight data bits and samples the parity bit where it expects the stop
bit, and the tty layer discards that as a framing error, so a console
banner comes through clean. Host to device desynchronises on the second
character of any back-to-back burst - the receiver takes the next frame's
start bit as its parity bit and then finds a data bit where the stop bit
should be. Sixteen 'a' (0x61) sent back to back echo as alternating 0x61
and 0x58; the same link typed one character at a time is flawless.

FORM_USART is the no-parity encoding, value 0. Confirmed by reading CTRLA
off a running PIC32CM5112GC00100 with an overlay asking for parity = "none":
FORM read back as 1.

Signed-off-by: Arkadiusz Grzelka <devitwise@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant