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

  • I am quite confident that softdevice is only checking for interrupts being enabled and their priority for protected peripherals.And I think softdevice is not checking anything with app PPI channels except that it makes sure that when app use sd_ppi_*** api it will mask away channel number to the numbers not restricted. I am still confused of what it means by "the program is stuck at PPI channel initialization". I just verified on SDK8.0 S110 softdevice that it does not matter if you initalize PPI channel 0 before or after softdevice_enable it works just fine.

  • You made me go test it. If I load the softdevice but leave it unprotected (ffffffff in CLENR0) then initialising the softdevice with sd_softdevice_enable() doesn't change anything in the MPU PERR0 to protect peripherals and I can access anything. If, however, the softdevice is 'protected' when loaded, ie CLENR0 is 0x18000, the SD init does mark a number of the peripherals as region 0, which would mean accessing them from user code would hardfault. I just tested accessing one, it hardfaulted.

    However .. PPI isn't one of them, at least not with SD 8.x. Did that change? I remember seeing posts about accessing PPI directly under the SD hardfaulting before, I'll go find one later. That makes me wonder what version of the 110 the OP is using and whether it's 'protected' or not. I think 'stuck' must mean 'in an error handler' and I can't think of another reason accessing PPI would error.

  • I am thinking of questions like this one

    devzone.nordicsemi.com/.../

    where it was stated that the PPI was protected when the softdevice was in use and direct access would hardfault. That was back at S110v6 which is quite a long time ago and that may not be the case any more.

    If the OP is using a recent softdevice, especially if it's being loaded without being protected, then I have no idea why he's having the issue.

  • RK, you asked,

    PPI isn't one of them, at least not with SD 8.x. Did that change?

    Yes, you are right, this has changed in SD 8.x. Protecting it did not serve the main intentions, if the app wants to access protected peripherals they can use PPI channels accessible to the applications to manipulate protected pheripheral behaviour. I think this will be addressed in next generation chips.

  • Yes RK,

    PPI is not protected anymore from SD 8.x, as protecting it does not serve the protection it needs. App can anyways program PPI unrestricted channels to manipulate restricted peripheral behaviour using sd_ppi_*** API. This issue is probably addressed in nRF52 chips. I am guessing that the debugger isn't giving the exact point of where the error occurs probably due to optimisation being too high. I would try again by compiling again with no optimizations and trace again.

    Updated 01.06.2015

    Softdevice and the peripherals used by it are not protected by default, I think this has changed with SDK8.0. Softdevice does not write to UICR.CLENR0. When initializing the softdevice, it first checks CLENR0, and if it is clean (0XFFFFFFFF) then it will not protect any peripherals. In that case it is upto applications to be careful with what peripherals they are using. RK, you have already made this observation and I can confirm that you were right. If we want the peripherals to be protected, we need to write to CLENR0 register before initializing the softdevice. Something I learned from you today :)

Related