This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Difficulty debugging ISR issue.

I am using the MCBSTM32 evaluation board. I started with the "blinky" project.

I wanted to change it so that I could DMA a block of data from the ADC to memory. OK, I did that and it worked fine.

Next, I wanted to get an interrupt when the specified number of transfers had happened. I modified DMA1_Channel1_IRQHandler in stm32f10x_it.c to toggle a LED and set a flag when it happens. I also set the TCIE bit in DMA_CCR1

Being unfamiliar with the interrupt handler for this processor I looked at the code in STM32_Init.c for inspiration. In there I found that the initialization routines used the following:

 NVIC->Enable[n] |= (1 << ( <Position > & 0x1F));


Where n is the 32 bit array element where the bit is in and Position represents the bit position in that element.

With that in mind, and finding no initilization for DMA interrupt, I implemented the following in my code immediately after I enable the DMA chanel:

NVIC->Enable[0] |= (1 << (DMAChannel1_IRQChannel & 0x1F));


Where DMAChannel1_IRQChannel is 0x0B and being the position is less than 32, it should go into the first array element.

Needless to say it does not work. I put a break point on the interrupt and it never breaks. It seems to fault, but gets to an area of code I do not recognise. It is in STM32f10x.s and is the point highlighted in the following:


<snip>

EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
USBWakeUp_IRQHandler

                B       . 

                ENDP


                ALIGN


; User Initial Stack & Heap

                IF      :DEF:__MICROLIB

<snip>

Any help or pointers would be appreciated.

Parents Reply Children
  • Yes, actually I did so don't give up!!

    It ends up that in the stm32f10x_it.c and stm32f10x_it.h files I used the names of the interrupts did not match those in STM32F10x.s! (So much for consistency in programming). Anyway, I finally figured out that this is the default point the program ends up at for an unhandled interrupt.

    Here is some code that might help you along. It is for the MCBSTM32 and is just a snip of the initialization and interrupt handler. It has been awhile since I touched this code, so I must state that I can't guarantee that it actually works anymore. It should hopefully gets you going down the right path. Enjoy!

    #define DATA_BUFF_SIZE 128
    
    typedef struct
    {
            bool done;
            unsigned short data[DATA_BUFF_SIZE];
    }DATA_BUFF;
    
    #define DMA_INT_ENABLE 0x00000002
    
    void DMAChannel1_IRQHandler(void)
    {
            DMA_Channel1->CCR   &=  ~DMA_INT_ENABLE;
        data_buff.done = TRUE;
            GPIOB->ODR ^= (GPIOB->ODR & 0xFFFF00FF) | 0x200;
    }
    
    void adc_Init (void)
    {
    //  GPIOA->CRL &= ~0x0000000F;                    // set PIN1 as analog input (see stm32_Init.c)
    
      RCC->AHBENR |= (1<<0);                          // enable periperal clock for DMA
    
            // Setup interrupt for DMA.
      DMA_Channel1->CMAR  = (u32)data_buff.data; // set channel1 memory address
      DMA_Channel1->CPAR  = (u32)&(ADC1->DR);       // set channel1 peripheral address
      DMA_Channel1->CNDTR = DATA_BUFF_SIZE;                      // transmit data buff size.
      DMA_Channel1->CCR   = 0x000025A0;               // configure DMA channel
      DMA_Channel1->CCR   |=  DMA_INT_ENABLE;
    
    //  DMA_Channel1->CCR   = 0x00002520;               // configure DMA channel
    
    //  DMA_Channel1->CCR   = 0x00002AA2;             // configure DMA channel:
                                                                                                    //              Transfer Complete interrupt Enabled,
                                                                                                    //              read from peripheral,
                                                                                                    //              curcular mode (auto reload),
                                                                                                    //              no peripheral increment,
                                                                                                    //              memory increment,
                                                                                                    //              32 bit perpherial and menory size,
                                                                                                    //              high priority level
                                                                                                    //              no memory to memory mode
    
      DMA_Channel1->CCR  |= (1 << 0);               // DMA Channel 1 enable
    
            // Enable interrupt
      NVIC->Enable[0] |= (1 << (DMAChannel1_IRQChannel & 0x1F)); // enable interrupt
    
      RCC->APB2ENR |= (1<<9);                         // enable periperal clock for ADC1
    
      ADC1->SQR1 &= ~0x00F00000;                      // only one conversion
    
      ADC1->SMPR2 &= 0x00000038;                      // clear bits 3..5 (channel1)
      ADC1->SMPR2 |= 0x00000028;                      // set sample time (55,5 cycles)
    
      ADC1->SQR3  &= 0x0000001F;                      // clear bits 0..4
      ADC1->SQR3  |= 0x00000001;                      // set rank
    
      ADC1->CR1   =  0x00000100;                      // use independant mode, SCAN mode
    
      ADC1->CR2   =  0x00000101;                      // use data align right, single conversion
                                                      // EXTSEL = Timer 1 CC1 event
                                                      // enable ADC, DMA mode, external Trigger
      ADC1->CR2  |=  0x00500000;                                   // start conversion
    
    }