SPIv3 issues
Posted: Sat Jan 04, 2020 4:22 am
When porting my application to STM32H7, I found that SPI did not work correctly.
I'll just list the things I addressed, and I will attach a patch later:
- I found that the DMEIF interrupt was occasionally being triggered. Since DMEIF is only triggered on a peripheral-to-memory transfer where the MINC bit is cleared, this interrupt can only happen on the transfer to dummyrx. So, it should be ignored, rather than causing the DMA_ERROR_HOOK to be called. (Why have the dummy variables in the first place? This SPI peripheral supports operation in simplex mode.)
- IFCR is being set to 0xFFFFFFFFU in order to clear flags. Documentation states that reserved bits in this register are not to be changed from their reset value, so this should be 0xFF8.
- I use a software-controlled slave select. I am not certain the register configuration is correct for that. I changed the register settings as follows: Clear the SSOE bit, set the SSM bit, set the SSI bit (unsure if necessary, the table embedded in fig. 616 in the reference manual seems to imply so). I am not sure if the ChibiOS driver is intended to support this mode of operation or if it is intended to only support hardware-controlled slave select.
- When debugging, I found that if I put a breakpoint after dmaStreamEnable and before the CSTART bit is set in spi_lld_send, it causes spiSend to get stuck waiting for the interrupt and never return. Changing the order so that CSTART is set prior to dma setup fixes this. I am unsure why this happens - perhaps the SPI peripheral does not like bytes being inserted in the txfifo prior to CSTART being set.
- The CSUSP (suspend request) bit was being set in the dma rx interrupt. Since the SUSPC (suspend clear) bit in the IFCR is only set in spi_lld_start, the driver works for the first transaction or two, and then gets stuck.
I'll just list the things I addressed, and I will attach a patch later:
- I found that the DMEIF interrupt was occasionally being triggered. Since DMEIF is only triggered on a peripheral-to-memory transfer where the MINC bit is cleared, this interrupt can only happen on the transfer to dummyrx. So, it should be ignored, rather than causing the DMA_ERROR_HOOK to be called. (Why have the dummy variables in the first place? This SPI peripheral supports operation in simplex mode.)
- IFCR is being set to 0xFFFFFFFFU in order to clear flags. Documentation states that reserved bits in this register are not to be changed from their reset value, so this should be 0xFF8.
- I use a software-controlled slave select. I am not certain the register configuration is correct for that. I changed the register settings as follows: Clear the SSOE bit, set the SSM bit, set the SSI bit (unsure if necessary, the table embedded in fig. 616 in the reference manual seems to imply so). I am not sure if the ChibiOS driver is intended to support this mode of operation or if it is intended to only support hardware-controlled slave select.
- When debugging, I found that if I put a breakpoint after dmaStreamEnable and before the CSTART bit is set in spi_lld_send, it causes spiSend to get stuck waiting for the interrupt and never return. Changing the order so that CSTART is set prior to dma setup fixes this. I am unsure why this happens - perhaps the SPI peripheral does not like bytes being inserted in the txfifo prior to CSTART being set.
- The CSUSP (suspend request) bit was being set in the dma rx interrupt. Since the SUSPC (suspend clear) bit in the IFCR is only set in spi_lld_start, the driver works for the first transaction or two, and then gets stuck.