Circular DMA does not circle for ADC (STM32L1xx)
I'm trying to use the ADC on an STM32L1xx to read a single channel with a sample rate based on TIM2. I plan to use a double-buffering scheme, so I want to set it up to DMA into a buffer with half-complete and fully-complete interrupts. I think I have this working for the first pass, but it appears not to circle. In other words, when I enable everything, I get a 1/2 transfer interrupt, and a transfer complete interrupt, but no more. The buffer appears to have been written to, and while it is a bit hard to tell, I don't think the buffer is being written to more than once. I see no overflow bits set. Any ideas? Here is the initialization code:
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR); // Set DMA channel Peripheral base address to ADC Data register DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buffer; // Set DMA channel Memeory base addr to ADC_ConvertedValueBuff address DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // Set DMA channel direction to peripheral to memory DMA_InitStructure.DMA_BufferSize = bufLength*2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Disable DMA channel Peripheral address auto increment DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // Enable Memory increment DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// set Peripheral data size to 16bit DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // set Memeory data size to 16bit DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Disable memory to memory option DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Setup NVIC for DMA channel 1 interrupt request */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_Init( GPIOA, &GPIO_InitStructure); /* Enable ADC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div1; ADC_CommonInit(&ADC_CommonInitStructure); /* Initialize the ADC1 by using its init structure */ ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // Set conversion resolution to 12bit ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Disable Continuous conversion ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // Use same trigger as D/A-timer 2 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // Set conversion data alignement to right ADC_InitStructure.ADC_NbrOfConversion = 1; // Only one conversion per trigger ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_16Cycles); /* Enable DMA1 Channel1 */ DMA_ITConfig(DMA1_Channel1, DMA_IT_HT | DMA_IT_TC, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); /* Enable DMA for ADC */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC Channel2 */ ADC_Cmd(ADC1, ENABLE); #stm32l-adc-dma