2014-04-01 4:50 PM
Hello,
Me again with basic questions. I am still trying to acquire from a bank of ADCs. 8 SAR ADCs in parallel on my stm32f429i-disco. From previous forum posts, and my own attempts, it appears I cannot use the HSI clock directly by putting it out on MCO1 and reading its transitions. So I am trying to learn how to use TIM1 and a peripheral-to-memory DMA. Since it's TIM1, I'll use DMA2. Because of the ADCs I have, a full read takes 16 cycles of the clock I send them (call it SCLK): - 4 leading zeros - 8 bits of data - 4 trailing zeros I generate the SCLK from the TIM1 and put it out on PA8:RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//Fill the TIM_TimeBaseInitStruct with the desired parameters
// TIM_TimeBaseInitTypeDef base;
TIM_TimeBaseStructInit(&TIM1_Settings);
TIM1_Settings.TIM_Prescaler = 0;
TIM1_Settings.TIM_CounterMode = TIM_CounterMode_Up;
TIM1_Settings.TIM_Period = 5; //AutoReload value in the TIM1->ARR register
TIM1_Settings.TIM_ClockDivision = 0;
//configure the Time Base unit with the corresponding configuration
TIM_TimeBaseInit(TIM1, &TIM1_Settings);
/* Channel 1 output configuration */
TIM_OCInitTypeDef OCbase;
TIM_OCStructInit(&OCbase);
OCbase.TIM_OCMode = TIM_OCMode_PWM2;
OCbase.TIM_OutputState = TIM_OutputState_Enable;
OCbase.TIM_Pulse = 2;
OCbase.TIM_OCPolarity = TIM_OCPolarity_Low;
OCbase.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OC1Init(TIM1, &OCbase);
//Enable TIM1 output on pin PA8
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
/* Very much needed. Enable Preload register on CCR1. */
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
//Enable Timer
 TIM_Cmd(TIM1, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);//before assigning CS=0, we need to wait for the SCLK to be high, for synch reasons
while(SCLK==0);
CS_TO_LOW;
TIM1->RCR = 3; //Set the repetition value to skip 4 leading zeros
TIM1->DIER |= TIM_IT_Update; //enable update interrupt
while((TIM1->SR & TIM_IT_Update) == 0); //wait until update flag2014-04-01 5:25 PM
By the way, this is my DMA config code
//USE registers from DMA2 and DMA2_Stream5, channel 6
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_Channel = DMA_Channel_6;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)GPIOA;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dataBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1; //or ACQUISITION_BUFFER_SIZE
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //do not increase the peripheral address
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Increase the target memory address
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
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_Init(DMA2_Stream5, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream5, ENABLE);2014-04-01 5:43 PM
Pretty much stuck with DMA2 based on the mem-to-mem requirement of &GPIO->IDR
If it where me I'd just burst in the entire 16 byte run, and be done. Perhaps you can diagram the connectivity (schematic), and the waveforms (timing diagram) you need to generate?2014-04-01 6:19 PM
If it where me I'd just burst in the entire 16 byte run, and be done.
How would I go about doing that, exactly? Settings wise I mean. Would this work:TIM1->RCR = 0;
TIM1->DIER |= TIM_IT_Update | 0x0100; 
while((DMA2->HISR&0x0800)==0); //wait for transfer complete
TIM1->DIER &= ~TIM_IT_Update; //disable update interruptDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;2014-04-01 7:05 PM
Here are my current DMA init settings:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_6;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)GPIOA;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dataBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 16; //or ACQUISITION_BUFFER_SIZE //or number of bytes each shot
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //do not increase the peripheral address
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Increase the target memory address
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream5, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream5, ENABLE);while(SCLK==0);
CS_TO_LOW;
TIM1->RCR = 0; //repetition counter = 0
TIM1->DIER |= TIM_IT_Update | 0x0100;
while((DMA2->HISR & 0x0800) == 0);//wait for DMA transfer complete (all 16 bits)
TIM1->DIER &= ~TIM_IT_Update;
CS_TO_HIGH;