AnsweredAssumed Answered

STM32F030 DMA interrupt not working

Question asked by Conover.John on Oct 9, 2016
Latest reply on Oct 10, 2016 by Clive One
Hi,
     We have a design using an STM32F030 and we have three analog channels attached to the ADC. We are currently not using a timer to start the conversions(doing it manually.) The problem is that I initially set up a DMA interrupt but it never fired. I then set up a ADC interrupt on the end of sequence. The ADC interrupt fires after all three channels have been converted but we do not see the DMA interrupt fire. The data is DMA'ed into the DMA buffer, just no interrupt. What have I mis-configured?

Thanks,
     John C.

int main(void)
{
    /* GPIOA-C Periph clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    /* Enable SYSCFG clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    /* DMA1 clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);

    // Configure the PortA(PA) analog input pins
    GPIO_InitStructure.GPIO_Pin        = CADCELL | LINE | CURRENT;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_OType     = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed     = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_InitStruct.ADC_Resolution            = ADC_Resolution_10b;
    ADC_InitStruct.ADC_ScanDirection        = ADC_ScanDirection_Upward;

    /* Initialize ADC */
    ADC_Init(ADC1, &ADC_InitStruct);

    /* Enable ADC */
    ADC_GetCalibrationFactor(ADC1);
    ADC_ITConfig(ADC1 ,ADC_IT_EOSEQ, ENABLE);
    NVIC_EnableIRQ(ADC1_IRQn); /* (7) */
    NVIC_SetPriority(ADC1_IRQn,0); /* (8) */
    ADC_DMACmd(ADC1, ENABLE);
    ADC_Cmd(ADC1, ENABLE);

    //Wait for ADC to be ready
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));

    //Set ADC conversion channel sample time
    ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_28_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_28_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_4, ADC_SampleTime_28_5Cycles);

    DMA_InitTypeDef   DMA_InitStructure;

    /* DMA1 Channel1 Config */
    DMA_DeInit(DMA1_Channel1);
    //DMA_InitStructure.DMA_PeripheralBaseAddr    = (uint32_t)ADC1_DR_Address;
    DMA_InitStructure.DMA_PeripheralBaseAddr    = (uint32_t)&(ADC1->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr        = (uint32_t)dmaBuff;
    DMA_InitStructure.DMA_DIR            = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize        = 3;
    DMA_InitStructure.DMA_PeripheralInc        = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc            = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize        = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode            = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority            = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M            = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    /* DMA1 Channel1 enable */
    DMA_Cmd(DMA1_Channel1, ENABLE);

    NVIC_EnableIRQ(DMA1_Channel1_IRQn);
    NVIC_SetPriority(DMA1_Channel1_IRQn,0);


    while (1)
    {
        // Start conversion on ADC1
        ADC_StartOfConversion(ADC1);

            //Wait for DMA to complete
            while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));

            //Clear DMA flag
            DMA_ClearFlag(DMA1_FLAG_TC1);
    }
}



void ADC1_COMP_IRQHandler(void)
{
      if (ADC1->ISR & ADC_ISR_EOSEQ)  /* Check the end of sequence bit */
      {
          dmaHead++;
          dmaHead &= (MAX_DMA_XFERS-1);
          DMA1_Channel1->CMAR    = (uint32_t)&dmaBuff[dmaHead][0];
          ADC1->ISR |= ADC_ISR_EOSEQ;
      }
      if ((ADC1->ISR & ADC_ISR_OVR) != 0)  /* Check OVR has triggered the IT */
      {
        GPIOC->BSRR = (1<<8); /* Switch on orange led to report a resume of the conversion  */
        GPIOC->BSRR = (1<<(9+16)); /* Switch off green led to report it is due to overrun  */
        ADC1->ISR |= ADC_ISR_OVR; /* Clear the pending bit */
        ADC1->CR |= ADC_CR_ADSTP; /* Stop the sequence conversion */
      }
      else
      {
        //error |= ERROR_UNEXPECTED_ADC_IT; /* Report unexpected ADC interrupt occurrence */
      }
}

void DMA1_Channel1_IRQHandler(void)
{
      if ((DMA1->ISR & DMA_ISR_TCIF1) != 0) /* Test if transfer completed on DMA channel 1 */
      {

      }

}

 

Outcomes