2017-05-04 03:41 AM
Hi,
I am occasionally loosing a byte on SPI reads from an external ADC and would appreciate any suggestions about how to investigate further.
Summary: I have a FreeRTOS based application running on the STM32F769I Eval board. Periodically the application reads data from an external ADC (AD7606) connected via SPI. Data reads from the ADC are using DMA. Very occasionally (~one cluster in every 250000 transfers) I lose a byte in the middle of a number of successive transfers. The missing data is visibleon the bus an external SPI Analyser. The SPI Error interrupt never triggers.
Details:
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 7; hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;On Bus: 0x24 0x06 0x24 0x0F
0x24
0x23
0x24 0x12 0x24 0x14 0x23 0xFA 0x24 0x06 0x24 0x10Received: 0x24 0x06 0x24 0x0F0x23
0x24 0x12 0x24 0x14 0x23 0xFA 0x24 0x06 0x24 0x10 0x24Thanks in advance for any suggestions.
Jonathan
#dma #spi #stm32f7 #freertos Note: this post was migrated and contained many threaded conversations, some content may be missing.2017-05-09 12:30 PM
I have continued to investigate this and have modified theSTM32F769I-DiscoverySPI_FullDuplex_ComDMA example to run on the
STM32F769I Eval board and read data from my external ADC. I am using the same SPI and DMA configuration as my full application it appears to be 100% reliable.
This suggests to me that the problem is some sort of interaction between components in my full application. The application isn't terribly complicated at the moment and is only using the following peripherals:
Full speed USB port
TIM6
SPI1 & DMA
GPIO
SDRAM
Whilst the ADC is running there isn't anyTX/RX activity on the USB port.
I have used Seggers SystemView application to visualise the activity of the system and I haven't been able to spot anything different in the system behaviour during the conversion that fails vs the ones which are fine.
I am wondering is something similar to this
https://community.st.com/thread/39114-reading-rtc-registers-stops-dma-transfer-on-stm32l051
is happening (I realise it is a very different part).Any suggestions as to the cause would be appreciated.
Thanks!
2017-05-09 05:32 PM
Is 16-bit mode more robust?
At 16 bytes per transfer, would Internal SRAM make more sense? Even if you move the data to SDRAM later via the cache/write-buffers.
Monitoring via the debugger is likely more invasive than you think, and more likely to cause bus conflicts and stalls. Avoid.
Getting this kind of byte loss with DMA is disturbing, perhaps you can convince an ST FAE to review this behaviour with you. If it were my problem I'd probably get an FPGA to spoof the ADC with an LFSR generating a known/predictable sequence so the STM32 side software could detect and trap the failure.
I don't think the RTC issue is the same, there you have a massive disparity in peripheral speeds and the stalling of bus resources for very significant amounts of time. ie like the accidents you'd have with a Zamboni on the motorway/freeway.
2017-05-09 06:17 PM
> Monitoring via the debugger is likely more invasive than you think, and more likely to cause bus conflicts and stalls. Avoid.
More importantly, reading the SPI [data] register by the debuging gadget causes [Rx] flag loss.
I'd also ask whether the DMA is circular, or the SPI is stopped/started (maybe it's in the given code, I don't speak the 'libraries' gobbledygook), and whether the data loss occurs on the 16-byte chunk boundaries.
JW
2017-05-10 08:25 AM
Interesting comments and suggestions.
Firstly I am not monitoring the SPI registers with the debugger so we can rule out that.
My test system is feeding known voltages into the 8 ADC inputs and I have traps set in the application to trigger when the captured inputs go outside of some tight bounds around the expected values.
I have today tried changing the DMA RX buffer from SDRAM to internal memory (aligned on a 4 byte boundary). I also tried changing from 8 bit mode to 16 bit mode. After these changes it does appear to be more robust but eventually I had a similar problem occur, but this time I 'lost' 4 bytes.
2017-05-10 10:04 AM
I'd also ask whether the DMA is circular, or the SPI is stopped/started (maybe it's in the given code, I don't speak the 'libraries' gobbledygook), and whether the data loss occurs on the 16-byte chunk boundaries.
2017-05-10 10:16 AM
Also,
If it were my problem I'd probably get an FPGA to spoof the ADC with an LFSR generating a known/predictable sequence so the STM32 side software could detect and trap the failure.
is a great point. You might have missing more data than you think.
JW
2017-05-10 11:49 AM
Hi,
Sorry I missed this question earlier. The DMA isn't circular and the SPI is started and stopped by the HAL layer around each transaction. The I don't believe that the failure always occurs on a 16 byte boundary, but will need to re run the system to check.
It is a good idea about using a controllable SPI Slave to generate a known pattern. I will try and set that up tomorrow..
2017-05-11 12:48 AM
I don't know if this fits your problem, but I have had similar kind of problem: STM32F0 as SPI slave 'lost' bytes (I mean random 0x00 bytes injected into the data stream). After a while I spotted a comment in the HAL file 'stm32f0xx_hal_spi.c'
Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes,
the following table resume the max SPI frequency reached with data size 8bits/16bits: +-----------------------------------------------------------------------------------------+ | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | | Process | Tranfert mode |--------------------|--------------------|--------------------| | | | Master | Slave | Master | Slave | Master | Slave | |=========================================================================================| | T | Polling | Fcpu/32 | Fcpu/32 | NA | NA | NA | NA | | X |----------------|----------|---------|----------|---------|----------|---------| | / | Interrupt | Fcpu/32 | Fcpu/32 | NA | NA | NA | NA | | R |----------------|----------|---------|----------|---------|----------|---------| | X | DMA | Fcpu/32 | Fcpu/16 | NA | NA | NA | NA | |=========|================|==========|=========|==========|=========|==========|=========| | | Polling | Fcpu/32 | Fcpu/16 | Fcpu/16 | Fcpu/16 | Fcpu/16 | Fcpu/16 | | |----------------|----------|---------|----------|---------|----------|---------| | R | Interrupt | Fcpu/16 | Fcpu/16 | Fcpu/16 | Fcpu/16 | Fcpu/16 | Fcpu/16 | | X |----------------|----------|---------|----------|---------|----------|---------| | | DMA | Fcpu/4 | Fcpu/8 | Fcpu/4 | Fcpu/4 | Fcpu/8 | Fcpu/16 | |=========|================|==========|=========|==========|=========|==========|=========| | | Polling | Fcpu/16 | Fcpu/16 | NA | NA | Fcpu/16 | Fcpu/16 | | |----------------|----------|---------|----------|---------|----------|---------| | T | Interrupt | Fcpu/32 | Fcpu/16 | NA | NA | Fcpu/16 | Fcpu/16 | | X |----------------|----------|---------|----------|---------|----------|---------| | | DMA | Fcpu/2 | Fcpu/16 | NA | NA | Fcpu/8 | Fcpu/16 | +-----------------------------------------------------------------------------------------+ @note The max SPI frequency depend on SPI data size (4bits, 5bits,..., 8bits,...15bits, 16bits), SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).Being max SPI clock = 1/32* FCPU is shocking: a 48MHz MCU (fully armored with DMA, cache system etc) can do only 1.5Mbps transfer?
2017-05-15 07:31 AM
Any progress on this?