SPI xfer using DMA: How to transmit again?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2012-08-16 7:58 PM
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));- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 2:14 AM
Hi Mendes,
Does anyone give you an answer? I'm looking for the same thing for the STM32F30xx. Thanks, Regards- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 3:25 AM
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 4:13 AM
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 4:33 AM
Thanks for answer, i did made all of steps excluding one ( DMA_LISR and DMA_HISR) ), will see if this changes anything
UpdateDMA2->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 ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 5:05 AM
> DMA2->LIFCR = 0;
> DMA2->HIFCR = 0;
Read the RM - what does it say about LIFCR/HIFCR?
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 5:31 AM
ok, my problem, clearing means 0 for me, but it should be 1. i should pay more attention
DMA2->LIFCR = 0xF7D0F7D; DMA2->HIFCR = 0xF7D0F7D;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 5:41 AM
OK, so did it help?
JW- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2014-11-13 5:50 AM
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