This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Question for NVIC_EnabeIRQ

Hi,

I'm trying to implement a device including a PWM counter and a high resolution timer working with softdevice stack 110. Per the examples I got from this site, I'm using the TIMER1 in TIMER mode for the high resolution timer, TIMER2 in counter mode with LPCOMP for the PWM counter. The timer and the PWM counter can work well separately without S110 stack, but when I tried to integrate them together, I got some issues. By searching the forum, I can't find some clue for them:

  1. If the ble_stack_init is called before the counter initialization, which the PPI channel[0] is used in the counter, the program is stuck at channel[0] initialization. But this issue goes away if PPI is initialized before ble_stack_init is called. Is there any dependency between them?

  2. The timer_init is called before ble_stack_init either, and defined as below:

    NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Counter Mode NRF_TIMER1->PRESCALER = 6; //Set prescaler. Higher number gives slower timer. Prescaler = 0 gives 16MHz timer NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set counter to 16 bit resolution NRF_TIMER1->CC[0] = TIMER_MS_TO_TICK(1); //Set value for TIMER compare register 0

    // Enable interrupt on Timer, set CC[0] to compare match events NRF_TIMER1->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos); NVIC_EnableIRQ(TIMER1_IRQn);

But when the ble_stack_init is called, the system reboots. I added some logs, and found that this issue was caused by the call NVIC_EnableIRQ(TIMER1_IRQn). With below line, there is no reboot happened again:

NVIC_SetPriority(TIMER1_IRQn, 1);

Is this setting compulsory if the timer is set as TIMER mode working with S110 stack?

  1. The 3rd question is some like above question, I'm trying to use LPCOMP + TIMER2 to implement a PWM counter as the example shown, but when I call NVIC_EnableIRQ(LPCOMP_IRQn), the system reboots at ble_stack_init(). And the call NVIC_SetPriority(TIMER1_IRQn, 1); does't help, even I set the priority as 3. The code is shown as below:

    static void LPCOMP_init(void) { /* Enable interrupt on LPCOMP CROSS event */ NRF_LPCOMP->INTENSET = LPCOMP_INTENSET_CROSS_Msk;

         /* Configure LPCOMP - set input source to AVDD*4/8 */
         NRF_LPCOMP->REFSEL |= (LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling << LPCOMP_REFSEL_REFSEL_Pos);
         /* Configure LPCOMP - set reference input source to AIN pin 6, i.e. P0.5 */
         NRF_LPCOMP->PSEL |= (COUNTER_PULSE_INPUT << LPCOMP_PSEL_PSEL_Pos);
         
         /* Enable and start the low power comparator */
         NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled;      
    
         NVIC_SetPriority(CP_TIMER_IRQ, 1);
         NVIC_EnableIRQ(LPCOMP_IRQn);  
    

    }

Could anyone please help me on these issues? Any feedback will be appreciated.

Thanks & Regards, Stanley

    1. Section 11.2 of the softdevice spec - you only have App High and App Low interrupt priorities available for your app, that's 1 and 3 (APP_IRQ_PRIORITY_LOW, APP_IRQ_PRIORITY_HIGH). And don't use '1' and '3', use the defines for compatibility.

    2. Why would setting the TIMER1 IRQ priority help with your use of the LPCOMP interrupt? Set the LPCOMP IRQ priority.

  • Thanks RK.

    What's a shame, I have been working on this typo for more than one hour...

    BTW, do you have comment on why PPI has to be initialized before BLE stack?

    Thanks & Regards, Stanley

  • I didn't have a comment about the PPI because I don't know what you meant by 'the program is stuck'. Programs don't 'stick', the processor is somewhere doing something, where is it and what is it doing? My guess is that it's in the hardfault handler because the PPI is a restricted peripheral when the softdevice is enabled so accessing it causes an exception. Have a look at all the functions starting sd_ppi_ ... you probably want to be using those.

  • Like RK mentioned, PPI is restricted peripheral when softdevice is used. Your program is most probably asserted into hardfault when you called sd_softdevice_enable at which point softdevice checks for all its reserved peripheral configuration. read 11.5 Programmable Peripheral Interconnect (PPI) in S110 SDS

  • Other way around I think. If he sets up the PPI channel first then calls sd_softdevice_enable() then it's fine, however if he calls sd_softdevice_enable() and then tries to do PPI->CHANNEL.. at that point he 'gets stuck' which I assume means ends up in the hardfault handler. It's at the PPI->CHANNEL code it all goes wrong, not at sd_softdevice_enable(), according to the orginal post at least.

    My assumption is that the softdevice initialisation sets PPI as a Region 0 peripheral and so attempting to access after that from user code is what causes the hardfault. If he sets up beforehand since he's not using a channel the softdevice uses, the init of the softdevice is fine.

Related