Hi,
for my app, I need to discard some SPI frames. As I understand SPI+DMA, all frames have to be the same size, the buffer size depending on the frames size. I have some variable length frames that have to be discarded (they are useless). They are easily recognizable with their first byte, and thay are smaller than legit ones.
I solved the problem this way (it works fine) :
- an interrupt on the falling edge of the /CS pin
- an interrupt vector that tests for the buffer's first byte :
- if the first byte is not "legit" -> reset SPI : the whole sequence from setModule() to
spi_rx_dma_enable(), dettaching and reattaching the DMA interrupt. I tried to remove some
functions with no success
- if the first byte is legit, fine, return !
It could take too long (who knows...), so I could miss the next frame from time to time.
Sounds a bit like crap. Doesn't it ? Or as Dave Jones would say : if it looks like..., if it smells like..., it is !
Searching the headers, I didn't find anything that looks like reset or restart. dma_clear_isr_bits() has not the expected effect (it has no effect, but it's only DMA...). It's not enough. Looking for something more brutal, but smarter than what I did.
Is there somethingthat just resets the SPI transfer (and DMA), keeping all the parameters alone ?
(Community Core)
(obviously)
SPI/DMA Filtering frames on the fly
-
- Posts: 505
- Joined: Fri Dec 27, 2019 4:53 pm
- Location: Munich, Germany
- Contact:
Re: SPI/DMA Filtering frames on the fly
I think you should try , this should avoid any further data reception.
Code: Select all
spi_rx_dma_disable()
Re: SPI/DMA Filtering frames on the fly
Code: Select all
spi_rx_dma_disable()
Code: Select all
spi_rx_dma_enable()
Finally, the simplest (and fastest ?) I could do :
Code: Select all
void ISR_NSS_1() // RISING
{
volatile uint8_t* p = SPI_1_Rx_Buffer;
// keep pages only : 0x10 0x00 0xBn (0 <= n < 8)
if (*p++ != 0x10 || *p++ !=0x00 || *p++ & 0xF0 != 0xB0 || *p & 0x0F > 7)
{
dma_disable(SPI_1_DMA, SPI_1_RX_CH);
dma_tube_cfg(SPI_1_DMA, SPI_1_RX_CH, &SPI_1_DMA_RxTubeCfg);
dma_enable(SPI_1_DMA, SPI_1_RX_CH);
}
}