Question on interrupt process in nRF52840

I want to confirm these questions,hope someone can give me some explaination.

1) RADIO has it's own kernal which is some kind of MCU.

I have looked through some doc on BLE chips, most of them are dual kernal:one for layers higher,and one for RADIO phy, is nRF52840 same?

2) Interrupt process structure.

I did not find much info on this subject in datasheet(S140_SDS_v2.1.pdf):

"6.1.8 Interrupts"

"the peripheral with ID=4 is connected to interrupt number 4 in the nested vectored interrupt controller(NVIC)."--NVIC preseted.

"6.8 EGU — Event generator unit"

"or to handle a peripheral's interrupt service routine (ISR) execution at a lower priority for some of its events"

"Up to 16 separate event flags per interrupt for multiplexing"

All just mention,no so much details.I believe the whole structure is powerful.

The most important thing for me is:

Can I keep some interrupt not interrupted by other interrupt, or not delay too long.

For example,I want to receive the IR signal(PWM,40K/50K),interrupts from them should not delayed too long,and I want to send IR signal too.Thery are executed through interrupt handler.

It should be OK if RADIO has its own kernal,not rely on the same kernal to process.

3) Can I directly use interrupt handler instead of events?

4) Can I freely set priorities for each interrput?

Thank you.   

Parents
  • Hi,

    I have looked through some doc on BLE chips, most of them are dual kernal:one for layers higher,and one for RADIO phy, is nRF52840 same?

    The nRF52840 (and all other nRF52 series devices) is a singel core device.

    The rest of the qustions are specific to the SoftDevice, which is used in the nRF5 SDK. I will attempt to answer them, but I would strongly advice that you use the nRF Connect SDK for new products. Please see nRF Connect SDK and nRF5 SDK statement.

    Can I keep some interrupt not interrupted by other interrupt, or not delay too long.

    Yes. However, the highest priority interrupt should be reserved for the SoftDevice. See Interrupt model and processor availability in the S140 SoftDevice specification for details on this.

    3) Can I directly use interrupt handler instead of events?

    Events from the SoftDevice are a form of software interrupts. For other interrupt sources, you can use them as you would on any other device.

    4) Can I freely set priorities for each interrput?

    Yes, but make sure you reseve the highest interrupts for the SoftDevice, as mentionned earlier. In practice, I recomend you use the defines in the SDK such as APP_IRQ_PRIORITY_HIGHEST, as defined in components/libraries/util/app_util_platform.h to make sure you pick priorities that does not conflict with the SoftDevice.

  • Einar:

    I have read Interrupt model and processor availability 

    To tell the truth, I'm not clear with model very much,I'm still doubt on the possibility on my case:

    I need to send 32 bits through IR with PWM.

    PWM Freq = 40K

    bit 1 : 600us PWM + 300us space/silence

    bit 0 : 300us PWM + 300us space/silence

    preamble : 1200us PWM + 300us space/silence

    The solution I adoped using normal ARM MCU:

    1) use timer_A to output 40K PWM;

    2) use timer_B to control the output time(1200us/600us/300us) and switch on/off PWM output;

    3) the timer ticks computed before send, and timer_B interrupt handler will load the ticks and switch on/off PWM.

    Acoodring to Bluetooth Low Energy central connection processor usage

    21us =< tISR(0) <= 200us

    I am sure the IR packet will be broken if ISR(0) triggered during it's sending period.

    There are 2 options for me:

    1) bypass with PPI + DMA + ??

    I have thought about it, but did not figure it out.

    It looks like impossible to solve it only by event.

    2) detect the interruption.
    If the timer_B interrupt was interrupted,cancel current send,retry later(how to confirm no higher interrupt is processing?)

    Same problem when receiving IR signal,but not so serious,maybe we can use PPI to solve it.

    I use timer to measure the time between rise and down level on pin,maybe we can use PPI + DMA to store result to memory,and process the data in any interrupt triggered by DMA.

    How about your opinions?

  • Hi,

    Another alternative coudl be to have the whole sequence in RAM, as the PWM peripheral can output sequences from RAM. If it is easier to do it in software and it does not take too long compared to the Bluetooth acticity, an option can be to use the radio timeslot API. With this, you can get a duration of time where you are guaranteed to not be interrupted by the SoftDevice.

    PS: I would like to re-iterate that using the SoftDevice and nRF5 SDK for new products is not recomended. The nRF Connect SDK is the SDK that we support going forward.

  • Hi,

    Thank you for reply.

    "I would like to re-iterate that using the SoftDevice and nRF5 SDK for new products is not recomended. The nRF Connect SDK is the SDK that we support going forward."

    -->This is for price sensitive application,and it is simple,nRF5 SDK is enough.

    "If it is easier to do it in software and it does not take too long compared to the Bluetooth acticity, an option can be to use the radio timeslot API"

    -->If 20 central connections reached, I think the timeslot maybe is not so much(though I do not think about it yet), the time to send a IR packet will be about 1.2ms + 450us/bit * 32bit = 15.6ms.

    "Another alternative coudl be to have the whole sequence in RAM, as the PWM peripheral can output sequences from RAM. "

    -->I hope I can do like this,but,as I said before,I don't figure it out.

    Could you explain how to realize it?

    The work flow will looks like this:

    typedef struct{
    	uint16_t tick;
    	bool     PWM_ON;
    }IR_bit_t;
    IR_bit_t ir_data[33];//preamble + 32 bits
    uint16_t current_ir_data_index = 0;
    
    void send_ir_data(IR_bit_t* data,uint16_t* idx){
    	if(*idx >= 33) return;
    	
    	timer_B.ticks = (*(data+*idx)).tick;
    	if((*(data+*idx)).PWM_ON)
    		timer_A.start;
    	else{
    		timer_A.stop;
    		Pin_PWM.level = LOW;
    	}	
    	
    	(*idx)++;
    }

    I know I can use DMA to transfer the ticks to timer_B register,but I don't know how to switch the PWM ON/OFF.

    I have no experience on using PPI + GPIOE + EVENT + ...

    So,till now,I have no idea to solve it.

Reply
  • Hi,

    Thank you for reply.

    "I would like to re-iterate that using the SoftDevice and nRF5 SDK for new products is not recomended. The nRF Connect SDK is the SDK that we support going forward."

    -->This is for price sensitive application,and it is simple,nRF5 SDK is enough.

    "If it is easier to do it in software and it does not take too long compared to the Bluetooth acticity, an option can be to use the radio timeslot API"

    -->If 20 central connections reached, I think the timeslot maybe is not so much(though I do not think about it yet), the time to send a IR packet will be about 1.2ms + 450us/bit * 32bit = 15.6ms.

    "Another alternative coudl be to have the whole sequence in RAM, as the PWM peripheral can output sequences from RAM. "

    -->I hope I can do like this,but,as I said before,I don't figure it out.

    Could you explain how to realize it?

    The work flow will looks like this:

    typedef struct{
    	uint16_t tick;
    	bool     PWM_ON;
    }IR_bit_t;
    IR_bit_t ir_data[33];//preamble + 32 bits
    uint16_t current_ir_data_index = 0;
    
    void send_ir_data(IR_bit_t* data,uint16_t* idx){
    	if(*idx >= 33) return;
    	
    	timer_B.ticks = (*(data+*idx)).tick;
    	if((*(data+*idx)).PWM_ON)
    		timer_A.start;
    	else{
    		timer_A.stop;
    		Pin_PWM.level = LOW;
    	}	
    	
    	(*idx)++;
    }

    I know I can use DMA to transfer the ticks to timer_B register,but I don't know how to switch the PWM ON/OFF.

    I have no experience on using PPI + GPIOE + EVENT + ...

    So,till now,I have no idea to solve it.

Children
  • Hi,

    OldXiao said:
    -->This is for price sensitive application,and it is simple,nRF5 SDK is enough.

    You can use the same old low const devices with nRF Connect SDK, and it is suitable for small devices as well as larger. That said, using the nRF5 SDK is possible, just be aware that it has not been updated for a long time and you should not expect any updates going forward either.

    OldXiao said:
    Could you explain how to realize it?

    I dot not have any IR examples, but PWM sequences are demonstrated in the PWM driver sample (there very short sequences are used, but the principel is the same with longer sequences).

  • OK,I will try to use connect SDK later.

    And,sorry,I mixed the application,for gateway, no IR send & receive function.

    Only BLE peripherals have IR functions,and for peripherals, the connection count is very few,so timeslot is long enough.

    But,from technical view,it will be perfect if I can use peripheral instead of CPU to finish the job.

    Just forget IR function,it is PWM application.

    What the difference is: 

    All examples just need to update the compare values when time is up.

    In my case,I need not only update the compare values,but also need switch on/off PWM.

    The output looks like this(Pulse width modulation):

    preamble                                             1                                               0                                      1             ...

    PWM_1200us  SPACE_300us   PWM_600us  SPACE_300us PWM_300us  SPACE_300us PWM_600us  SPACE_300us   ...

    _-_-_-_-_-_-_-_-_-  [space]_-_-_-_-_-_-[space]_-_-_-[space] _-_-_-_-_-_-       

     

    Need 2 timers to finish the job at least: 1 outputs PWM, 1 control the interval.

    The problem is the PWM output is not continuous,we need to switch it once per bit.

    I don't figure out the way without interrupt handler.

    Anyway,this is my application problem,not chip or SDK technical problem,you can just ignore it.

  • I get the way, I limited my thought before. "switch" is to change the value of register at last,it is same with changing compare values.

    Maybe I need use 3 DMA channels.

    The data array:

    tick:            1200  300  600  300 300  300 ...

    pwmOnOff: 1        0      1      0     1      0    ...

    pinLevel:     0        0      0      0     0      0    ...

    After switched off PWM,we need make sure the pinLevel is low,so set it low every time.

    tick -> timer_B               -> DMA.channel_B

    pwmOnOff  -> timer_A  ->  DMA.channel_A

    pinLevel  -> pin_out      ->  DMA.channel_C

    trigger flow:

    pin_out = low

    timer_B.cv = 1200

    timer_A.en = 1

    timer_B.en = 1 ---->Int                                                                        ----->Int

                                         -> DMA.channel_B move 300 to timer_B.cv             ->repeat

                                         -> DMA.channel_A move 0 to timer_A.en

                                         -> DMA.channel_C move 0 to pinLevel

    It should work,I will study the hardware drivers.

    Thank you for help.

  • Just read the introduction of PPI 如何理解nRF5芯片外设PPI - Nordic Semiconductor中文官网.

    Thing will get simpler.

    Maybe I can do like this:

    timerA: pwm
    timerB: control interval
    pinPWM=P0.11: pin to output PWM
    DMA_CHn: load compare value to timerB

    timerB interrupt(event)
         ->(task)DMA_CHn load cv to timerB
         ->(task)PPI_CH[0].TASK_toggle_timerA(event)
                         ->(task)PPI_CH[1].TASK_CLR_pinPWM(event)
                                               ->(task)GPIOTE.TASK_CLR_pinPWM

    1)timerB timeout event trigger a)DMA to load new compare value to timerB; b)switch PWM(tmerA) output;

    2)switch PWM output will be the event to trigger clear pinPWM;

    3)clear pinPWM will trigger the action to clr pinPWM port.

Related