2014-12-01 01:49 PM
I'm stuck on TIM triggered DMA to SPI.
My DMA Code configuration is as follow: void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Blank DMA Configuration */ DMA_DeInit(DMA1_Channel1); /* Using the default values at Startup */ DMA_StructInit(&DMA_InitStructure); /*Changes from the default values */ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(SPI2->DR); // Address of peripheral the DMA must map to => SPI2 Data Register DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) TTxBuffer; // Variable to which received data will be stored DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Direction of transfer Memory to Peripheral =Destinatary DMA_InitStructure.DMA_BufferSize = 32; // BufferSize DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // We don't want to change the SPI2 Data register DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // We increment Memory DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // We define Peripheral Data Size as Byte DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // We define Memory Data Size as Byte DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // Circular Mode define DMA_InitStructure.DMA_Priority = DMA_Priority_High; // High Priority DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Memory to Memory Disable /* Initialize the DMA */ DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable the DMA transfer half and complete interrupt */ DMA_ITConfig(DMA1_Channel1, DMA_IT_HT, ENABLE); // Half Transfer Interrupt Enable DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // Full transfer Interrupt Enable /* Enable the DMA TIM Triggered */ TIM_DMACmd(TIM2, TIM_DMA_Trigger, ENABLE); TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE); /* Enable DMA1 Channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); } Looking at DMA_CCR1 gives me 0x2AB7 which is ok. Looking at the SPI2_DR I found no value ; i.e. 0 Franck2014-12-01 03:54 PM
I have TIM+DMA working on a number of STM32 platforms.
I think you have an STM32F3, but it's really important that you create free standing questions, and post complete code examples that compiles. Check to see if the DMA is throwing any error conditions/states. Check the TIM with an external pin. Check if memory-to-memory mode is required for DMAx != APBx Check if SPI->DR needs to be 16 or 32-bit wide The value read from SPI->DR will NOT reflect data written to SPI->DR, it's not memory, it doesn't work like that.2014-12-02 02:08 AM
Hi Clive,
I have TIM+DMA working on a number of STM32 platforms. Great! That's mean it does work and my code has some mistake in. I think you have an STM32F3: I used a STM32F302 on a Nucleo evaluation board Complete Code attached Check to see if the DMA is throwing any error conditions/states. No error from what I'm able to see. Check the TIM with an external pin. That's ok. TIM2_CH3 on PA9 given a 8MHz signal. Check if memory-to-memory mode is required for DMAx != APBx memory- to-memory only on DMA2 but STM32F302 as none and possesses only DMA1 Check if SPI->DR needs to be 16 or 32-bit wide RM0365 says that SPI is 4-bit to 16-bit data size selection. I2S is 16-bit or 32-bit data frame. The value read from SPI->DR will NOT reflect data written to SPI->DR, it's not memory, it doesn't work like that. Isn't the SPI2_DR the SPI data register? I expected to find in that 16-bit register the data received. Thanks again for your help. I appreciate ________________ Attachments : main.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I168&d=%2Fa%2F0X0000000bib%2FMiHFneeDc0SMZdfjw8fHf2PUuufxKu9Nq74mv_oVAPY&asPdf=false2014-12-02 04:21 AM
Confused, you're triggering at 8 MHz, what's your SPI clocking at? 64 MHz?
Correct, reading SPI->DR will show data received, not data transmitted. DMA2 doing memory-to-memory is an F2/F4 issue, I haven't looked at your F3 part.2014-12-02 05:13 AM
SPI clocking upt o 30MHz. So effectively I change my clocking TIM2 to 20x less (1.5MHz)!!
/* Compute the value to be set in ARR regiter to generate signal frequency at f(SPI)/20=30MHz/20 *//* SPI up to 30MHz */
TimerPeriod = (SystemCoreClock / 1500000); I changed also TIM1 to 8x less as used for LDAC of external DAC. /* Compute the value to be set in ARR register to generate signal frequency at F(TIM2)/8=1,5MHz/8 */
TimerPeriod = (SystemCoreClock / 187500); TIM1 and TIM2 ok on pin PA9 and PC0. But still nothing on the SPI pin at pin PB15 (MOSI). How can I be sure that the DMA as being triggered by the TIM2? Flag? Would it be possible to trig the DMA with the Timer, and send 4x32bits on the SPI without any interrupt in between each 32 bit?
2014-12-02 05:33 AM
New code attached!
________________ Attachments : main.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0xa&d=%2Fa%2F0X0000000biZ%2FOMzbpF0DPYyeRs45tzVHYxe_4oIBF2g_Dfp.1PQvV_o&asPdf=false2014-12-02 05:55 AM
Can it be that I have speed pb?
If I send only one 32 bit word I received the figure attached ________________ Attachments : Screen_2014-12-02_02-54-53.jpeg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I15A&d=%2Fa%2F0X0000000biY%2F.MWEeTj2cDQbaRt0rznAFnNIv_J9oXdch2xXgkvx6rM&asPdf=false2014-12-02 06:04 AM
Well if you want the bits back-to-back why use the timer at all? The SPI can use DMA on the TXE flag.
For the TIM+DMA to be viable the trigger rate needs to be below the shift/word rate of the SPI, otherwise you'll keep stomping on the SPI->DR register before it shifts out. To confirm the DMA pace, you'd use the TC and/or HT interrupts to toggle a GPIO and then scope the frequency of that. ie 100 transfers should occur at 100 periods of the timer.2014-12-02 07:01 AM
Well if you want the bits back-to-back why use the timer at all? The SPI can use DMA on the TXE flag.
I know, but I would like to stream 4x32-bit data to an external DAC, with no sweat for the processor; so direct mode.For the TIM+DMA to be viable the trigger rate needs to be below the shift/word rate of the SPI, otherwise you'll keep stomping on the SPI->DR register before it shifts out. Ok.To confirm the DMA pace, you'd use the TC and/or HT interrupts to toggle a GPIO and then scope the frequency of that. ie 100 transfers should occur at 100 periods of the timer. Ok. I'll go hunting....2014-12-02 07:06 AM
Clive,
Where can I find an application note like AN4031 but for the STM32F302? Not able to find same kind of ST document for that µP.