This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

cc2540 interrupt routine implementation

Other Parts Discussed in Thread: CC2540, CC2541

Hi TI's experts,

I have a peripheral device that sets an interrupt to a GPIO on the cc2540.

I need some help on setting the interrupt routine on the cc2540.

From what I understand, I need to create a task (create task ID, task init routine, define and add to OSAL init) as well as writing the event processing routine itself which is the actual routine needs to be executed.

This is all task related stuff... I need help understand and implement how the interrupt on the gpio is setting / calling the event.

Thanks in advance,

  • hi Omri,

    have a look at the code in hal_key.c. reading that really helped me a lot.

    a short summary:

    • you need to setup your GPIO as input, select the triggering edge and enable the IRQs for the given port
    • implement an IRQ-handler for the vector of your port (see end of hal_key.c, copy the handler from hal_key.c for best results as the called macros are important)
    • if you want to process the IRQ-event in the main-task instead of the IRQ-handler raise an event by calling osal_set_event()
    • don't forget to clear the IRQ-pending flags in the handler

    hope that helps

    Andre

  • Thanks for the help,

    Can you point me to the handler you've mentioned in hal_key.c and the important macro?

  • sorry, but did you even look at the file?

    1. open Components\hal\target\CC2540EB\hal_key.c in a text editor
    2. grab the scrollbar and drag it to the lowest possible position
    3. voila, behold the HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR ) in all it's beauty including the macros called by this IRQ handler

    </sarcasm>

  • Hi Andre, 
    I have my interrupt working but I'd like it to set a timer that will count 5 minutes and then put it into PM3. I don't understand how to accomplish what you said here: 
    • if you want to process the IRQ-event in the main-task instead of the IRQ-handler raise an event by calling osal_set_event()
    Am I calling osal_set_event() in the ISR or how do we get the subroutine to operate out of the main so I can use an osal_timer_startEx?
    Would really appreciate help here soon, I have been stuck on this for too long and need to get this accomplished.
    Thank you.
  • Hi William,

    it is exactly as you said:

    • I raise an event in the ISR by calling osal_set_event()
    • then I handle the event in the event-llop of the main-task
    • at the end of the event-handler i start a timer by calling osal_timer_startEx
    • if the timer expires i re-enter battery-power-mode

    HTH

    Andre

  • Hi,

            I am new to CC2540 and BLE so please help me.

    I am also trying to do something similar, I am trying to raise an Interrupt when there is a change from High to low in pulse and Low to High in the pulse, I have set the GPIO as input, selected the trigerring edge and Enabled the IRQ for the given port

    I am using HAL_ISR_FUNCTION(halKeyPort0Isr, P0INT_VECTOR) and the P0INT_VECTOR is the Interrupt Vector for the Port0 ( #define  P0INT_VECTOR   VECT( 13, 0x6B )   /*  Port 0 Inputs */) , so if I write my code in the HAL_ISR_FUNCTION will it execute when the Interrupt on the GPIO pin happen?

    And also please anyone clear me, the ISR should written only in halkey.c or it can e written anywhere else

    And, if I have to write more than one Interrupt Service Routine how do I do it ?

    Thank you.

    Regards,

    -Rakesh

  • Hi Rakesh,

    1. if I write my code in the HAL_ISR_FUNCTION will it execute when the Interrupt on the GPIO pin happen?

    Yes

    2. the ISR should written only in halkey.c or it can e written anywhere else?

    It can be anywhere but I suggest you keep it in hal_key.c

    3.  if I have to write more than one Interrupt Service Routine how do I do it ?

    Don't understand your question well. Would you specify your question?

  • Thanks Chen for replying,

    I will try to explain in detail what I am try to do:

     I have three sensor connected to P0.4 , P0.6 and P0.7 respectively, I have used PICTL bit register to generate an Interrupt during the raising edge and falling edge of the input pins, and I am recording the Time of Interrupt

    The time of Interrupt between these pins is very less and also two sensor or three sensors together(total of six interrupts maximum at any point of time) might generate an interrupt at the same time.

    So what I want to know is

    1. If I am using HAL_ISR_FUNCTION a single ISR Routine, if two Interrupts happen at time how will it handle ?

    2. I want to handle Interrupts from Different Ports differently using different ISR Routines meaning when P0.4 generates and Interrupt I want an ISR to handle this event and if the P0.6 generates interrupt I want a different ISR to handle the event..

    3. In the condition like multiple Interrupts happen at the same time which are ways I can handle It?

    4. And if I want to set the P0IFG register for both Rising Edge and Falling Edge (i.e I want the Interrupt to happen at Rising Edge of the Input and also at Falling Edge of the Input on the Same Input Pin) is it possile ? If possible how do I go about it ?


    Thanking you.

    Regareds,

    Rakesh

  • Hi, 

    OSAL can handle interrupts at time, so no need to worry about it.

    1. HAL_ISR_FUNCTION handles one interrupt only. But you can modify it. When interrupt occurred you can check all interrupt flags and call relative ISR. I mean lets say if 2 interrupts occur together than two bits will be set. You can call interrupt routine one by one. Don't forget to clear bit once ISR is served.

    2. You can write different function which calls ISR of different pin, I mean you can have 3 functions each function handling interrupt for single port only. 

    Example for port 0. 

    #pragma vector = P0INT_VECTOR  

    __interrupt  void p0_ISR(void){

    ......//Your code for port 0.

    }.

    you can write same for port 1 and 2.

    vector = P1INT_VECTOR  for port 1 and  P2INT_VECTOR for port 2. 

    3. In above function you can take for loop and check for interrupt flags. If lets say flag is set for pin 1 and pin2, First call ISR to handle interrupt of pin1 and then pin 2. You need to also clear flag manually after calling ISR.

    4. In a way it's possible. You can't have both mode set at a time. Lets say if interrupt occur in sequence as follow:

    R F R F R F R F.  (R = Rising edge, F= Falling edge). 

    Then you can initially set interrupt mode to rising edge. When interrupt occurs, change mode to falling edge in ISR, Again next time change mode to Rising edge in ISR. Thus you can have both mode on single pin. But you can't have both mode at same time. 

  • Hi All ,

    I interfaced KXCJ9-1008 accelerometer sensor to cc2541 Port0 pin2 (i.e P0.2 pin) and I want to generate interrupt with this pin and also I want to use that interupt to wakeup the cc2541 chip .

    My question is how to generate interrupt using sensors ? what are the Interrupt and port configuration i need to do to wakeup the cc2541?

    Ans as per documents cc2541 has 0.5uA current consumption when it is in PM3 mode , the KXCJ9-1008 accelerometer needs 10uA when it is in low power mode , So is it possible to wakeup cc2541 using accelerometer ?
  • You can refer to SW1 (use P0.1) in hal_key.c which shows you how to implement interrupt to wakeup CC254x.
  • Hi ,

    I implemented GPIO interrupt uisng KXTJ9-1007 Acceleriometer ( my cc2541 is interfaced KXTJ9-1007 at P0.2 pin) , I configure ISR routine cc2541 side and configuered KXTJ9-1007 Interrupt source registers ( Enabled IEN ,IEA bits in INT_CTRL_REG1 register DRDYE bit in CTRL_REG1 register) , the accelerometer generating interrupt but after reading INT_REL register the interrupts are not clearing ( still STATUS register and INT_SOURCE1 registers are not coming back to 0x00) , still these registers are showing interrupt is presented .

    Can any one help out here how can I clear the interrupt at accelerometer ???
    or
    Am I doing anything wrong in configuring the registers ?

    Thanks