2014-11-13 04:32 AM
Hi everybody,
I'm a beginner with STM32F30x µP. I'd like to made a DMA transfers from SRAM to an external DAC via SPI communication. Is it possible? Can I even configure a timer (TIMx) to generate a PWM signal or One Pulse Mode signal on TIMx_CHx and use it as DMA trigger and also as NSS signal input to latch the SPI data transfers to my external DAC? Thanks for your advice on that point. Regards, Franck2014-11-13 06:20 AM
Not exactly,
you could generate data stream, with CLK and MOSI, but you will not be able to toggle CS pin to make it work, or at least this is what i know, i never had luck with hard_cs on stm32 but i can give you code for internal SRAM to internal DAC, triggered by timer, it does work for me,2014-11-13 07:13 AM
Hi Linas,
I need a DAC resolution of 12bit ILN +/-1LSB for my application. The STM32F30x internal DAC is really bad. On page 109 of DM00093333(STM32F302x6/x8) the electrical specifications of DAC are given. ILN given for a 12-bit input code of ±4 max LSB with note3: ''Data based on characterization results, not tested in production''. So as far I can't use the internal DAC! That's why I select an external one (AD5628 -Octal 12 bits SPI voltage output). Also reference manual RM0365 DM00094349 gives at pg159 the summary of DMA1 request for each channel. (STM32F302 I am working with, uses only DMA1 which have 7 configurable channels). I've attached also a timer comparison table. It shows for my application which timer I can use. Why can't I used TIM2 to generate a PWM signal on TIM2_CH2 for example and use it as DMA trigger and also as NSS signal input to latch the SPI data transfers? ________________ Attachments : Timer_Feature_comparison.xlsx : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyhm&d=%2Fa%2F0X0000000bkd%2F5nLl3z88vP1_4CdRV0dtiATqh07A3II9MRvK5eoCEqc&asPdf=false2014-11-13 07:37 AM
> Why can't I used TIM2 to generate a PWM signal on TIM2_CH2 for example and use it as DMA trigger and also as NSS signal input to latch the SPI data transfers?
IMO you can. Why don't you simply try? I personally would divide the problem: first, learn to set up the timer, then leran to set up SPI with ''manual'' ''filling'' of data register, then learn to set up the DMA. There will be some latency between TIM2_CH2 event and start of SPI transmission, and this latency will have some jitter dependent on load on the DMA controller and involved buses, so count on this and don't try to make a too tight timing of the NSS signal. JW2014-11-13 08:22 AM
Hi Jan,
IMO you can. Why don't you simply try? By the way i will try ;0))) Thanks for your advices. Franck2014-11-13 11:16 AM
I try to make this program work from on my STM32F429i devkit. So far i don't know how to trigger dma with Timer.
however, i could give you program that will generate high duty cycle PWM, and inside low period it i will generate TIM1_CC_IRQHandler interrupt program, that could transfer one 16b halfword to spi, with software CS. But i guess this is not what you are trying to achieve2014-11-14 01:07 AM
Hi Linas,
I read in the DM00068049_Description of STM32F30xx-STM32F31xx Standard Peripheral Library about the following DMA/TIM instruction on page 186: Function Name void DMA_Init ( DMA_Channel_TypeDef * DMAy_Channelx, DMA_InitTypeDef * DMA_InitStruct)Function Description Initializes the DMAy Channelx according to the specified parameters in the DMA_InitStruct. Parameters :
2014-11-14 02:43 AM
Hi Linas,
Can you please send me your code example? Thanks a lot. Franck2014-11-19 06:16 AM
Hi Linas,
I'm still working hard on DMA to extarnal DAC through SPI communication on STM32F302. In one of your email you said you can provide me with a program able to generate high duty cycle PWM, and inside low period it i will generate TIM1_CC_IRQHandler interrupt program, that could transfer one 16b halfword to spi, with software CS. Can you please share it attached it? Thanks a lot. Best regards, Franck2014-11-19 09:04 AM
uint32_t adc_pointer = 0;
void TIM1_CC_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)
{
ToDo
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
}
}
void TIM_Config_Update(void)
{
TIM_TimeBaseStructure.TIM_Period = period;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_Pulse = ccr;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
}
void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* GPIOA Configuration: Channel 1, 2, 3, 4 and Channel 1N as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = period;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = ccr;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; ;//TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;//TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
you can use this for CS, but you have to figure out how to trigger dma via timer. i did same configuration with update, but it was not successful