PIO UART how to join them in MicroPython [solved]

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
User avatar
Grumpy_Mike
Posts: 8
Joined: Sun Feb 14, 2021 8:04 pm

PIO UART how to join them in MicroPython [solved]

Post by Grumpy_Mike » Sun Feb 14, 2021 8:12 pm

I want to join the TX and RX FIFO buffers together, using a PIO UART

According to the rp2040 data sheet this is done by:-

Code: Select all

sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX)
But this is in C, does anyone know the python for this?

I asked this on the Raspberry Pi forum and the bottom line was:-
I guess it wouldn't as one would normally be interacting through the official MicroPython API, so it's mostly unimportant how it's done under the hood and that's in the MicroPython team's domain rather than RPT's.
Which I felt was a bit of a let down.
Thanks
Last edited by Grumpy_Mike on Mon Feb 15, 2021 12:47 pm, edited 1 time in total.

User avatar
jimmo
Posts: 2244
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: PIO UART how to join them in MicroPython

Post by jimmo » Mon Feb 15, 2021 1:53 am

Grumpy_Mike wrote:
Sun Feb 14, 2021 8:12 pm
But this is in C, does anyone know the python for this?
MicroPython doesn't provide an API for this (yet).

It seems like this would be relatively straightforward to add to rp2_state_machine_init_helper (in ports/rp2/rp2_pio.c). Perhaps worth raising an issue at github.com/micropython/micropython.

It's almost certainly possible to use machine.mem32 to set the PIO shiftctrl register directly from Python (replicating exactly what the C API does).
Grumpy_Mike wrote:
Sun Feb 14, 2021 8:12 pm
Which I felt was a bit of a let down.
I'm not quite sure I follow... can you elaborate? (This does entirely seem like a limitation of the MicroPython port that we don't provide access to this feature).

User avatar
Grumpy_Mike
Posts: 8
Joined: Sun Feb 14, 2021 8:04 pm

Re: PIO UART how to join them in MicroPython

Post by Grumpy_Mike » Mon Feb 15, 2021 9:35 am

Thanks for the reply.
I'm not quite sure I follow... can you elaborate?
It just seemed to me that the buck was being passed over to you.
It's almost certainly possible to use machine.mem32 to set the PIO shiftctrl register directly from Python
It appears that is the answer. I got an answer on the RP forum from someone suggesting the same thing and eventually I made it work without errors.

Code: Select all

from machine import mem32
PIO_base = [ 0x50200000, 0x50300000 ]
SM_SHIFTCTRL= [ 0x0d0, 0x0e8, 0x100, 0x118]

PIO_FIFO_JOIN_TX = 1
PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS = 0x40000000
PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS =  0x80000000
PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB = 30
# then after I defined my UART in the variable 'port' I added

#join TX and RX FIFOs gogether to make 8 deep
reg = mem32[PIO_base[0] + 0] # state machine number
reg = (reg & ~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS)) | (PIO_FIFO_JOIN_TX << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB)
mem32[PIO_base[0] + 0] = reg
Now this worked and didn't stop the code running, but then it didn't overflow before, maybe due to the baudrate being so high and microPython being so slow ( relatively speaking ) that I was not throwing values at them fast enough to overwhelm a buffer of four.

So I need to slow the baud rate down and to check that buffer didn't overflow using the buffer status register which I haven't done yet. I will update the post when I have.
Thanks again I appreciate your input.

User avatar
Grumpy_Mike
Posts: 8
Joined: Sun Feb 14, 2021 8:04 pm

Re: PIO UART how to join them in MicroPython [solved]

Post by Grumpy_Mike » Mon Feb 15, 2021 12:46 pm

Ok this has now been proved to work:-

Code: Select all

from machine import mem32
PIO_base = [ 0x50200000, 0x50300000 ]
SM_SHIFTCTRL= [ 0x0d0, 0x0e8, 0x100, 0x118]

PIO_FIFO_JOIN_TX = 1
PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS = 0x40000000
PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS =  0x80000000
PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB = 30
# then after I defined my UART in the variable 'port' I added

#join TX and RX FIFOs gogether to make 8 deep
reg = mem32[PIO_base[0] + SM_SHIFTCTRL[0]]
reg = (reg & ~(PIO_SM0_SHIFTCTRL_FJOIN_TX_BITS | PIO_SM0_SHIFTCTRL_FJOIN_RX_BITS)) | (PIO_FIFO_JOIN_TX << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB)
mem32[PIO_base[0] + SM_SHIFTCTRL[0]] = reg
You can check this with the calls to the FIFO level register, which shows you how full the TX register is.

Code: Select all

    #print("Flevel register", hex(mem32[PIO_base[0] + 0xC]))
Before joining you see 4 and after joining you see 7, depending on the speed of the serial data.

Post Reply