cancel
Showing results for 
Search instead for 
Did you mean: 

Timer triggered SPI transfer with data size beyond 64k bytes

diverger
Senior

Hi,

With GPDMA standard mode, I implemented timer triggered SPI DMA transfer. But the 'Size' argument of the 'HAL_SPI_TransmitReceive_DMA()' is 'unit16_t', this means it can only transfer 64k bytes once. Are there any method to transfer beyond this value using DMA?

Thanks.

4 REPLIES 4
Bob S
Principal

If your total transfer size is always a multiple of 2, you can change the SPI config to 16-bit data instead of 8-bit.  Then you get 64K 16-bit words, or 128K bytes per call.

Or just use the transfer complete callback to start a 2nd (or 3rd) transfer of the next chunk of data.

Hi,

It seems there are something not clear now.

  1. For the SPI transfer APIs without '_DMA' suffix, they all accept an 16-bit 'Size', which mean the 'number of' transfers. That means they are counted in 'transfers', but not bytes. I think I can enlarge the size of one single transfer to 'halfword', 'word', to increase the total bytes it can transfer.
  2. For the APIs with '_DMA' suffix, the 'Size' is multiplied by the 'SPI_DATASIZE' in bytes, then passed to the DMA's CBR1 register (the BNDT[15:0]) field. This is the final cause of the 64k bytes limitation.

So, I think the question now is how to break the 64k bytes limitation of GPDMA. Right?

 

Thanks.

I remember a decade ago I write my own code for Atmel's SAM3X uCPU, that supports DMA Link List mode.  No driver from IC makers at that time. I see similar situation here, DMA has feature LList but spi_dma_transfer has no reference in HAL.  Probaly, it's quite possible to create two lists and link them in circle, at least I see dma_hal has some references to LList type definition structure

Hi,

After changing to linked-list DMA, the code enter into hard fault exception when run the code below (in the SPI xfr APIs):

 

  /* Packing mode management is enabled by the DMA settings */
  if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmatx->Init.SrcDataWidth !=  DMA_SRC_DATAWIDTH_WORD) && \
       (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \
      ((hspi->Init.DataSize > SPI_DATASIZE_8BIT)  && (hspi->hdmatx->Init.SrcDataWidth ==  DMA_SRC_DATAWIDTH_BYTE)))
  {
    /* Restriction the DMA data received is not allowed in this mode */
    __HAL_UNLOCK(hspi);
    return HAL_ERROR;
  }

 

And when tracing the code, it seems the 'hspi->hdmatx' is a NULL pointer, this is weird.