2014-01-25 12:34 PM
Hi,
I am trying to sample some data using DMA and the internal ADC and send the same data , still using DMA to an external DAC using the SPI Internface, through an optoisolation barrier. It all works great, I need 1MS/s and this is not a problem. Still I need to qualify the data using a NSS line and TI Mode works fine, but the lack of wait states makes my task hard. The NSS is released on the 14th byte and re-issued on the 15th. Most of the DACs (I have been using DAC8311 for a while) need some time between the sync signal and the new data, so the NSS line needs to be inactive for a while between the subsequent data. I could not find any suitable DAC. Is the interface not suitable for such a task or am I missing something? Thanks Fabio2014-01-26 8:51 AM
You might want to use timer-triggered DMA.
JW2014-01-26 9:36 AM
Thanks for your suggestion,
If I understand you properly, you suggest to qualify the data via software in an IRS. I think this will not work because of the enormous amount of interrupts (@1MS/s I'll get 1 Interrupt every us). I either need DACs that support continuos mode, or I need to make somehow the transfer discontinuos to let the DAC have the necessary settling time or either build external glue logic (please noooo.....) Fabio2014-01-26 2:39 PM
No, what Jan is suggesting is that you pace the SPI DMA with a timer driven request instead of an SPI-TXE one.
That said the STM32 SPI implementation is going to be totally useless driving NSS in a useful way.2014-01-26 2:42 PM
What about a DAC using an I2S data stream?
2014-01-26 11:34 PM
> No, what Jan is suggesting is that you pace the SPI DMA with a timer driven request instead of an SPI-TXE one.
That is. The DMA transfer source/target does not necessarily needs to involve the trigger source, so you can trigger it from a timer (i.e. use stream/channel ''assigned to'' the timer) but set the SPI DR as transfer target. It's not obvious at the first reading, I guess. Of course, the timing has to be set right, and possible latency of the DMA transfer has to be taken into account. > That said the STM32 SPI implementation is going to be totally useless driving NSS in a useful way. Clive, Fabio above said he is OK with the TI mode. Alternatively, the same timer's compare could be used to generate a select signal, perhaps. > I2S That sounds like an interesting option, too, a bit less flexible perhaps, as the ''wait'' would be fixed to the same time as the transfer lasts - but it is up to Fabio to judge whether this fits his needs. JW2014-01-29 12:48 AM
2014-01-31 7:30 AM
So,
i decided to go for a timer triggered DMA transfer but I can't get it running... :( Well this is what I do, TMR3 is configured in PWM mode, works RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); RCC_TIMCLKPresConfig(RCC_TIMPrescActivated); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 150; TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 40000000) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 5; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); TIM_Cmd(TIM3, ENABLE ); than I try to start DMA1 Stream 2 channel5 to get a DMA triggered everytime the timer overflows RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); DMA_DeInit(DMA1_Stream2); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_5; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI4->DR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uwADC3ConvertedVoltage; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, DISABLE); DMA_Init(DMA1_Stream2, &DMA_InitStructure); DMA_Cmd(DMA1_Stream2, ENABLE); TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE); Can't get it running....2014-02-02 6:14 AM
I fixed the issue,
it was trivial, as usual :(( DMA1 is not connected to APB2 and thus cannot trigger SPI4 transfers. I was trying to use the free pins on the 429discovery and didn't care much. Now TMR1 Ch3, pin PC8 is free, DMA2 on APB2 works. DMA sampling 1MS/s and sendind out SPI4, 500kS/s is not a problem. I send the data back and forth through an optoisolation barrier for kW level current control. Fabio2014-07-20 3:49 AM
Hi Fabio!
Thank you for this nice post. How did you configure the SPI? Do you require any additional code to start the transfer?Thank you for your answers,BlazWe’re moving the ST Community to a new platform to give you a better and more reliable community experience.