SPI DMA problems #16455
Replies: 2 comments 2 replies
-
Ok, I think I've worked out the problem here. I think my use of the standard After deleting all the python objects instantiated from the Testing this theory a bit further, I tried creating and deleting the It is a little surprising that the rx_dma = rp2.DMA(5) # Use DMA channel 5 in order to avoid these kind of conflicts. |
Beta Was this translation helpful? Give feedback.
-
A couple of queries (from a non-expert) tx_config = tx_dma.pack_ctrl(
size = 0, # 8-bit transfers
inc_read = False, # always read tx_data
inc_write = False, # always write to SPI1_SSPDR
treq_sel = DREQ_SPI1_TX # pace transfers according to when byte is sent on SPI bus
) Shouldn't There may be a race condition here: def write_spi():
cs_1.value(0) # Low enable chip select
tx_dma.active(1) # Send address bytes to SPI controller
cs_1.value(1) # Stop transaction If |
Beta Was this translation helpful? Give feedback.
-
Intention
So I have been trying to see whether I could use the new DMA micropython module to interface a MAX31865 SPI RTD sensing chip to a Pico 2, in such a way that I can periodically read temperature values from the chip and write them to a memory buffer, all with essentially no intervention with the main processor.
Code
After a fair bit of reading of the RP2350 datasheet, I was able to come up with the following code:
which I was very happy to see would result in the appropriate temperature (resistance, actually) value appearing in
rx_data
.Problem
The only problem is, after the first transaction, attempting to restart
rx_dma
fails, with0x00
bytes being written torx_data
,and I am unable to re-activate the receive DMA channel (or, when it is activated, it immediately thinks it has received 4
0x00
bytes and stops?)Funnily enough, I found that if I used the Micropython
SPI
module to perform the same SPI read at this point e.gthen
rx_dma
andtx_dma
go back to their original state and I am successfully able to callonce again. However, if I call
write_spi()
again, the DMA channels go back to the 'unresponsive state' and I'm back at square one.The issue?
Having looked at the C code in
ports/rp2/machine_spi.c
(specificallymachine_spi_transfer()
), it's unclear to me what I'm doing different which is preventing me from restarting the DMA channel. I can see that the Pico SDK functiondma_channel_wait_for_finish_blocking()
is called at the end ofmachine_spi_transfer()
, however as far as I can tell, all that does is prevent the read address being accessed while the DMA transfer is taking place.My hunch, having read the RP2350 datasheet, was that this might have something to do with IRQs being generated by the SPI controller which are cleared when the
read
andwrite
functions of the standardSPI
module are used.Investigating the status registers for the SPI 1 controller whilst it was in its 'working state', I noticed that the following two registers:
SSPSR (Status register)
SSPRIS (Raw interrupt status register)
had different values when in the 'unresponsive state':
I wasn't sure if this is the reason I'm not able to reactivate the DMA channels - because the SSPRXINTR/SSPRTINTR interrupts remain asserted? The thing is, I'm not sure how to de-assert them; writing
0x3
to the interrupt clear register,SSPICR
, doesn't seem to do anything.I should note that both DMA channels are set to
irq_quiet=True
- the default setting in therp2.DMA
module.Beta Was this translation helpful? Give feedback.
All reactions