cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 - STM32CubeMX Configured - SPI Slave DMA Problems - Really Slow Init & Odd Behaviors

Matt Roybal
Associate II
Posted on January 31, 2018 at 02:48

Hello, I have a separate MCU acting as the SPI Master, sending data in multiples of 64 bytes (anywhere from 1x 64 byte group, to 10x 64 byte groups) - all during a single transaction. So NSS goes low, 64 bytes to 640 bytes transfer (small delay between the groups of 64 bytes), NSS goes high. This is running at 4MHz and I verified this piece is working correctly via Oscilloscope. This data is coming over twice per second. The slave also has data to exchange back to the MCU, but I have not got that far yet so its all zeros for now.

For the SPI slave, I am using a STM32F103 that I configured using STM32CubeMX - clock running at 64MHz. These are the settings I made for the SPI slave in CubeMX:

  • Mode: Full-Duplex Slave
  • Hardware NSS Input Signal
  • Prescaler (for Baud Rate) = 4 -> This gives 16.0 MBits/s Baud Rate
  • I created both DMAs under 'DMA Settings' for 'Peripheral To Memory' and 'Memory To Peripheral', set both Priority to 'Very High'

This is what my main loop looks like:

while(true)

{

     if(spiReady)

     {

          spiReady = false;

          InitSPISlave(&hspi1);

     }

}

Here is the 'InitSPISlave':

const short MAX_DEVICES_TRACKED = 10;

uint8_t txData[MAX_DEVICES_TRACKED * 64];

uint8_t rxData[MAX_DEVICES_TRACKED * 64];

void InitSPISlave( SPI_HandleTypeDef *spiHandler )

{

     HAL_SPI_TransmitReceive_DMA(spiHandler, txData, rxData, sizeof(txData));

}

And here is the interrupt callback handler (I am only displaying the first two 64 byte chunks for now):

void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)

{

     SPISlaveTransferComplete();

     spiReady = true;

}

void SPISlaveTransferComplete( void )

{

     printf('SP1 Data Received: ');

     for(int i = 0; i < 64; i++)

     {

          printf('%lx ', (long)rxData[i]);

     }

     printf('\n');

     printf('SP1 Data Received: ');

     for(int i = 64; i < 128; i++)

     {

          printf('%lx ', (long)rxData[i]);

     }

     printf('\n \n');

     memset(rxData, 0, sizeof(rxData));

}

I am experiencing 2 main problems:

  1. In approximately 1 in 10 SPI transfers, I am missing the first 64 byte chunk. On the Master side, I tried creating a long delay between setting NSS low and between the data transfer starting... this made no difference. This is odd because its always the full 64 bytes... its never a portion of it.
  2. The bigger problem I am experiencing, is that if I set '

    MAX_DEVICES_TRACKED' to 2 for instance, I get all of the SPI transfers and dump them to the screen (with the occasional first 64 bytes missing). If I start increasing the 'MAX_DEVICES_TRACKED' to 5, 10, 20, etc.It creates huge delays and I miss most of the other SPI transfers coming from the Master. At 20, it takes several seconds to re-initialize the SPI and begin a transfer. I timed all of the functions using HAL_GetTicks and nothing is taking that long.... so I don't know why this is happening?

I am using the SWO pin, J-link, and 'SEGGER J-Link SWO Viewer' to display the 'printf's.

Something else I have tried... I reset the clock settings back to stock, running everything at 8MHz, and I get the exact same delays here. This was my reasoning to up the clock speed to 64MHz (which I verified via oscilloscope by setting PA8 to MCC and I could see the clock cycle.) but this had no effect on the delay I am experiencing.

Thanks for taking a look and any help/advice is greatly appreciated!

0 REPLIES 0