cancel
Showing results for 
Search instead for 
Did you mean: 

SPI xfer using DMA: How to transmit again?

Asantos
Senior
Posted on August 17, 2012 at 04:58

 The code below transmits 8 bytes from a sram buffer to SP1 using DMA.

 for(i=0;i<8;i++) SPI_MASTER_Buffer_Tx[i] = i+1;

  

  /* SPI_MASTER configuration ------------------------------------------------*/

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

  SPI_InitStructure.SPI_CRCPolynomial = CRCPolynomial;

  SPI_Init(SPI1, &SPI_InitStructure);

  SPI_Cmd(SPI1, ENABLE);

  /* SPI_MASTER_Rx_DMA_Channel configuration ---------------------------------*/

  DMA_DeInit(DMA1_Channel3);  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI_MASTER_DR_Base;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI_MASTER_Buffer_Tx;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

  DMA_InitStructure.DMA_BufferSize = 8;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_Low;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel3, &DMA_InitStructure);

   /* Enable DMA channels */

  DMA_Cmd(DMA1_Channel3, ENABLE);

  /* Enable SPI_MASTER DMA Tx request */

  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);

  /* Transfer complete */

  while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));

   

 

How to transmit the buffer again? I tried it with the code below with no success.

  

      DMA_ClearFlag(DMA1_FLAG_TC3);

      DMA_Cmd(DMA1_Channel3, ENABLE);

      SPI_I2S_DMACmd(SPI_MASTER, SPI_I2S_DMAReq_Tx, ENABLE);

      while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));

8 REPLIES 8
franck2
Associate II
Posted on November 13, 2014 at 11:14

Hi Mendes,

Does anyone give you an answer? I'm looking for the same thing for the STM32F30xx.

Thanks,

Regards

megahercas6
Senior
Posted on November 13, 2014 at 12:25

I am having same problem. it should just be re-enable dma stream, but it does not work. if you find solution, please post it here, same apply for me.

You can use Circular buffer, but it can create problems at high speed ( note receiver must have lower spi prescaller setting (use at least 2-4x) to get data

Posted on November 13, 2014 at 13:13

To re-enable DMA after a stopped or finished or failed transfer, you need to do several things:

all the stream dedicated bits set in the status register (DMA_LISR and DMA_HISR) from the previous data block DMA transfer should be cleared before the stream can be re-enabled

- set the total number of data items to be transferred in the DMA_SxNDTR register

- activate the stream by setting the EN bit in the DMA_SxCR register

You of course may reinitialize the control register and the FIFO control register and the source and destination address registers, but not necessarily - these retain their previous values (i.e. even if addresses are set to increment, they restart from the same point where they started originally, they don't ''continue where left'').

I don't speak the ''library'' goobledygook, so it's up to you to translate it to that, if desired.

JW

megahercas6
Senior
Posted on November 13, 2014 at 13:33

Thanks for answer, i did made all of steps excluding one ( DMA_LISR and DMA_HISR) ), will see if this changes anything

Update

DMA2->LIFCR = 0;
DMA2->HIFCR = 0;
DMA2->LISR = 0; // it's only read, if i comment this, same happens, no data at spi
DMA2->HISR = 0;// it's only read, if i comment this, same happens, no data at spi
DMA2_Stream3->NDTR = 12;
DMA2_Stream2->NDTR = 12;
DMA_Cmd(DMA2_Stream3,ENABLE);
DMA_Cmd(DMA2_Stream2,ENABLE);

nothing, i get no SPI clock, any ideas why ?
Posted on November 13, 2014 at 14:05

> DMA2->LIFCR = 0;
> DMA2->HIFCR = 0;

Read the RM - what does it say about LIFCR/HIFCR? JW
megahercas6
Senior
Posted on November 13, 2014 at 14:31

ok, my problem, clearing means 0 for me, but it should be 1. i should pay more attention

DMA2->LIFCR = 0xF7D0F7D;

DMA2->HIFCR = 0xF7D0F7D;

Posted on November 13, 2014 at 14:41

OK, so did it help?

JW
megahercas6
Senior
Posted on November 13, 2014 at 14:50

Yes, it does work, thank you very much.

I hope some time in near future problem like this will be history, since i have to learn so much, as in previous threads, i try to read RM, but sometimes it does not help, or to be more correct, i don't know where to read