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.

Accelerometer Interrupt on CC2540

Other Parts Discussed in Thread: CC2540, CC2541

Hi everyone!

Did anybody can set an external interrupt on the PORT1? I want to set the Motion Detection Mode on the CMA3000 accelerometer. I've read its datasheet and i've set the following registers:

CTRL = 0x38 ------------> CTRL: [G_RANGE | INT_LEV | MD_EXIT | I2C_DIS | MODE (3:1) | INT_DIS]

MDTHR = 0x0E ---------> 571 + 286 +143 = 1000 mg (I want to set the threshold in 1G, is that correct?)

MDFFTMR = 0x30 -----> 200ms + 1/10s = 300 ms (I want to set the detection time in 300ms, is that correct?)

 

My current code to configure the accelerometer and port interrupt is the following: 

void acc1Init(void){

  uint8 readValue;

  /* Clear flag and enable P1 interrupts */   

  P1IFG = 0;

  P1IF = 0;

  IEN2 = 0x10;

  P1IEN |= BV(7);

  accWriteReg(CTRL, RANGE_2G | I2C_DIS | MODE_400HZ_MEAS | INT_EN);

  WAIT_1_3US(80);

  do{

      accReadReg(STATUS, &readValue);

      WAIT_1_3US(80);

  }while(readValue & 0x08);  

 

And my ISR:

HAL_ISR_FUNCTION( accFFDPort1Isr, P1INT_VECTOR ){

  HAL_ENTER_ISR();

    if (P1IFG){

// More code...

    }

  P1IFG = 0;

  P1IF = 0;

  HAL_EXIT_ISR();

}

But my problem is that the accelerometer never interrupts and besides the whole system starts working wrong. Any help? Thanks in advance...

Best regards...

 

Martin R 

  • Sorry, in the part when i set the CTRL register the correct lines are the following:

    accWriteReg(CTRL, RANGE_8G | I2C_DIS | MODE_10HZ_MD | MDET | INT_EN);

    accWriteReg(MDTHR , 0x0E);

    accWriteReg(MDFFTMR , 0x30);

    I'm not sure that the interrupt configuration on the port 1 is correct. Is correct?

    Thanks...

  • I am trying the same thing that you are testing and I have used the oscilloscope to see the behaviour of the INT line (pin P1_7 on the CC2540) and this pin is always low, although the accelerometer is giving data to the CC2540. I don't undersand this behaviour as I think interrupts are activated in the accelerometer configuration:

    accWriteReg(CTRL, RANGE_8G | INT_ACTIVE_LOW | MODE_40HZ_MEAS | INT_EN); // I am using measurement mode 8g, 40Hz with interrupts.

    My purpouse is that each time that the accelerometer (suposed at a frequency of 40hz) has data, it interrupts the cpu and the cpu acquires the data. One of the problems I am facing is that I don't understand how the callbacks functions work. I am looking at the example of a key press interrupt, but I don't understand how the Onboard_keyCallback works() function works. Is it really necessary to use callbacks in order to use interruptions? I have seen that the OnBoard_KeyCallback function is used by the function "HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);". In addition I have seen that in the function "OnBoard_KeyCallback()" there is a call to the function "OnBoard_KeyCallback()" through the function HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback), what sounds recurrent and strange at the same time. I get lost with this, can somebody explain how it works? Thanks!

    /*********************************************************************
     * @fn      OnBoard_KeyCallback
     *
     * @brief   Callback service for keys
     *
     * @param   keys  - keys that were pressed
     *          state - shifted
     *
     * @return  void
     *********************************************************************/
    void OnBoard_KeyCallback ( uint8 keys, uint8 state )
    {
      uint8 shift;
      (void)state;

      // shift key (S1) is used to generate key interrupt
      // applications should not use S1 when key interrupt is enabled
      shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);

      if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )
      {
        // Process SW1 here
        if ( keys & HAL_KEY_SW_1 )  // Switch 1
        {
        }
        // Process SW2 here
        if ( keys & HAL_KEY_SW_2 )  // Switch 2
        {
        }
        // Process SW3 here
        if ( keys & HAL_KEY_SW_3 )  // Switch 3
        {
        }
        // Process SW4 here
        if ( keys & HAL_KEY_SW_4 )  // Switch 4
        {
        }
        // Process SW5 here
        if ( keys & HAL_KEY_SW_5 )  // Switch 5
        {
        }
        // Process SW6 here
        if ( keys & HAL_KEY_SW_6 )  // Switch 6
        {
        }
      }
     
      /* If any key is currently pressed down and interrupt
         is still enabled, disable interrupt and switch to polling */
      if( keys != 0 )
      {
        if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
        {
          OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
          HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
        }
      }
      /* If no key is currently pressed down and interrupt
         is disabled, enable interrupt and turn off polling */
      else
      {
        if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
        {
          OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
          HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
        }
      }
    }

     

  • Hi Martin and Victor,

     

    In your posts, I haven't seen any configurations for the GPIO.

    For your purpose the according pins on P1 should be configured as

    inputs, with internal pull-down and the interrupts triggered on rising

    edge. (section 7 in user's guide).

     

    Br,

    Igor

  • Dear Igor, first of all thanks for your answer it has helped me a lot!

    I have done this in the file cma3000d.c:

    #ifdef REV_1_0
        P1DIR |= 0x04; //P1_2 CS as output
        P1DIR &= ~0x80; //(configure P1_7) as INT
    #elif (defined REV_0_6)
        P1DIR |= 0x80; //P1_7 CS as output 
    #endif

    After that change the interrupt line is working in the oscilloscope. But the CPU is still not able to see interrupts from the accelerometer. I think that the problem I have is related to the callback functions. Please could you explain how do callbacks work in the CC2540 or where I can have information about it? Do I need a callback for the accelerometer? How to define it and in what file to do it?

    Thanks again for the reply!

     

     

     

  • HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )

    {

      if ((p0 & BV(1)) || p0 & BV(6))

      {

        halProcessKeyInterrupt();

      }

    ...

    }

     

    This is from hal_key.c regarding Port0. As you can see, you can distinguish which pin of port0 is giving the interrupt. I've modified the code in order to simplify it. Is this what are you searching for?

  • Hi Victor,

     

    As Kazola have mention in his post (by giving you an example), you have to implement an ISR

    for the port (pin) to catch incoming interrupts from the ACC.

    Look at the first post (Martin's) for an example of HAL_ISR_FUNCTION.

    Once you have implemented the ISR, use breakpoints just to see whether the CPU catches ACC

    interrupts. Once it works, you can place some sort of set_event() inside this ISR.

     

    Hope this helps,

    Igor

  • Dear Igor and Kazola,

    I am making some progress in the project in part thanks to your help, so if you don't mind I will continue asking doubts... I am following the key interrupt example and I think the key example is a bit more complicated that what I am trying to do. I have seen that this example uses the function:

    osal_set_event(Hal_TaskID, HAL_KEY_EVENT);

    To set an event once the interrupt is received. In the keyfob demo de the accelerometer is working without interruptions, but doing polling and in order to set and event the function used is in this form:

    osal_set_event(keyfobapp_TaskID, ACCEL_READ_EVT);

    The main diference is the TaskID used. The key interrupt uses the Hal_TaskID to set an event and the keyfob demo the keyfobapp_TaskID to set an event in the accelerometer. Which one should I use to set and event after the interrupt for the accelerometer?

    In order to answer the question maybe you should know that I have created the files hal_acc.c and hal_acc.h in the drivers section and there I have implemented the ISR routine and other functions. In this way I follow the same structure as the key example.

    Thanks again for your help

     

  • Hi Victor,

     

    The application with OnBoard_KeyCallbac() function is the one you should use the TaskID for osal_set_event().

    I'm just not familiar with the application you are using, however, if your application named as "myApp", in the ISR

    you should write the following:

    osal_set_event(myApp_TaskID, ACCEL_INT_EVT);

    where ACCEL_INT_EVENT is known name to hal_acc.c and myApp.c.

    In that way, the ISR invokes an event in your application (myApp), further in the event you should do some sort of

    processing.

    So lets summerise it all:

    1. You should add an osal_set_event(myApp_TaskID, ACCEL_INT_EVT); in your ISR.
    2. You should implement the ACCEL_INT_EVT (based on some sort of example) in myApp.

    Br,

    Igor.

  • just in order to help in my explanation, this is my hal_acc.c file:

     

    #include "hal_mcu.h"
    #include "hal_defs.h"
    #include "hal_types.h"
    #include "hal_drivers.h"
    #include "hal_adc.h"
    #include "hal_acc.h"
    #include "osal.h"
    #include "hal_acc_by_victor.h"


    #if (defined HAL_ACC) && (HAL_ACC == TRUE)

    /**************************************************************************************************
     *                                              MACROS
     **************************************************************************************************/

    /**************************************************************************************************
     *                                            CONSTANTS
     **************************************************************************************************/

    /* CPU port interrupt */
    #define HAL_ACC_CPU_PORT_1_IF P1IF

    /* ACC INT is at P1.7.0 */
    #define HAL_ACC_INT_PORT   P1
    #define HAL_ACC_INT_BIT    BV(7)
    #define HAL_ACC_INT_SEL    P1SEL
    #define HAL_ACC_INT_DIR    P1DIR

    #define HAL_ACC_INT_IEN      IEN1  /* CPU interrupt mask register */
    #define HAL_ACC_INT_ICTL     P1IEN /* Port Interrupt Control register */
    #define HAL_ACC_INT_ICTLBIT  BV(7) /* P1IEN - P1.7 enable/disable bit */
    #define HAL_ACC_INT_IENBIT   BV(5) /* Mask bit for all of Port_0 */
    #define HAL_ACC_INT_PXIFG    P1IFG /* Interrupt flag at source */

    #define HAL_ACC_INT_EDGEBIT  BV(0)

    /**************************************************************************************************
     *                                        GLOBAL VARIABLES
     **************************************************************************************************/
    static halAccCBack_t pHalAccProcessFunction;
    static uint8 HalAccConfigured;
    bool Hal_AccIntEnable;            /* interrupt enable/disable flag */

    /**************************************************************************************************
     *                                        FUNCTIONS - API
     **************************************************************************************************/


    /**************************************************************************************************
     * @fn      HalAccInit
     *
     * @brief   Initilize Acc Service
     *
     * @param   none
     *
     * @return  None
     **************************************************************************************************/
    void HalAccInit( void )
    {
      HAL_ACC_INT_SEL &= ~(HAL_ACC_INT_BIT);    /* Set pin function to GPIO */
      HAL_ACC_INT_DIR &= ~(HAL_ACC_INT_BIT);    /* Set pin direction to Input */

      /* Initialize callback function */
      pHalAccProcessFunction  = NULL;

      /* Start with acc is not configured */
      HalAccConfigured = FALSE;
    }


    /**************************************************************************************************
     * @fn      HalAccConfig
     *
     * @brief   Configure the Acc serivce
     *
     * @param   interruptEnable - TRUE/FALSE, enable/disable interrupt
     *          cback - pointer to the CallBack function
     *
     * @return  None
     **************************************************************************************************/
    void HalAccConfig (bool interruptEnable, halAccCBack_t cback)
    {
      /* Enable/Disable Interrupt or */
      Hal_AccIntEnable = interruptEnable;

      /* Register the callback fucntion */
      pHalAccProcessFunction = cback;

      /* Determine if interrupt is enable or not */
      if (Hal_AccIntEnable)
      {
        /* Rising/Falling edge configuratinn */
        PICTL |= HAL_ACC_INT_EDGEBIT;   /* Set the edge bit to set falling edge to give int */

        HAL_ACC_INT_ICTL |= HAL_ACC_INT_ICTLBIT; /* enable interrupt generation at port */
        HAL_ACC_INT_IEN |= HAL_ACC_INT_IENBIT;   /* enable CPU interrupt */
        HAL_ACC_INT_PXIFG = ~(HAL_ACC_INT_BIT); /* Clear any pending interrupt */
       
        /* Do this only after the hal_acc is configured - to work with sleep stuff */
        if (HalAccConfigured == TRUE)
        {
          osal_stop_timerEx( accfobapp_TaskID, ACCEL_READ_EVT);  /* Cancel Accelerometer polling if active */
        }
      }
      else    /* Interrupts NOT enabled */
      {
        HAL_ACC_INT_ICTL &= ~(HAL_ACC_INT_ICTLBIT); /* don't generate interrupt */
        HAL_ACC_INT_IEN &= ~(HAL_ACC_INT_IENBIT);   /* Clear interrupt enable bit */
       
        osal_set_event(accfobapp_TaskID, ACCEL_READ_EVT);  //Start Polling   
      }

      /* Acc now is configured */
      HalAccConfigured = TRUE;
    }

    /**************************************************************************************************
     * @fn      halProcessAccInterrupt
     *
     * @brief   Checks to see if it's a valid Acc interrupt, saves interrupt driven Acc states for
     *          processing by HalKeyRead(), and debounces accs by scheduling HalKeyRead() 25ms later.
     *
     * @param
     *
     * @return
     **************************************************************************************************/
    void halProcessAccInterrupt (void)
    {
      bool valid=FALSE;

    #if defined ( CC2540_MINIDK )
      if( HAL_ACC_INT_PXIFG & HAL_ACC_INT_BIT) /* Interrupt Flag has been set by SW1 */
      {
        HAL_ACC_INT_PXIFG = ~(HAL_ACC_INT_BIT); /* Clear Interrupt Flag */
        valid = TRUE;
      }
    #endif
      if (valid)
      {
        osal_set_event(accfobapp_TaskID, ACCEL_READ_EVT);
      }
    }

    /***************************************************************************************************
     *                                    INTERRUPT SERVICE ROUTINE
     ***************************************************************************************************/

    /**************************************************************************************************
     * @fn      halKeyPort0Isr
     *
     * @brief   Port0 ISR
     *
     * @param
     *
     * @return
     **************************************************************************************************/
    HAL_ISR_FUNCTION( halKeyPort1Isr, P1INT_VECTOR )
    {
      if (HAL_ACC_INT_PXIFG & HAL_ACC_INT_BIT)
      {
        halProcessAccInterrupt();
      }

      /*
        Clear the CPU interrupt flag for Port_1
        PxIFG has to be cleared before PxIF
      */
      HAL_ACC_INT_PXIFG = 0;
      HAL_ACC_CPU_PORT_1_IF = 0;
    }

    #endif /* HAL_ACC */

     

     

  • Hi Victor,

    this is explained in the Software Developer's Guide.

    Each layer has its own taskID. This is an extract of osal_simpleBLEPeripheral.c, from the application SimpleBLEPeripheral.

     

    // The order in this table must be identical to the task initialization calls below in osalInitTask.

    const pTaskEventHandlerFn tasksArr[] =

    {

      LL_ProcessEvent,                                                  // task 0

      Hal_ProcessEvent,                                                 // task 1

      HCI_ProcessEvent,                                                 // task 2

    ...  L2CAP_ProcessEvent,                                               // task 4

      GAP_ProcessEvent,                                                 // task 5

      GATT_ProcessEvent,                                                // task 6

    ...

      GATTServApp_ProcessEvent,                                         // task 10

      SimpleBLEPeripheral_ProcessEvent                                  // task 11

    };


    const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );

    uint16 *tasksEvents;


    /*********************************************************************

     * @fn      osalInitTasks

     * @brief   This function invokes the initialization function for each task.

     * @param   void

     * @return  none

     */

    void osalInitTasks( void )

    {

      uint8 taskID = 0;

      tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

      osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

      LL_Init( taskID++ );

      Hal_Init( taskID++ );  /* Hal Task */

      HCI_Init( taskID++ );   /* HCI Task */

    ...

      L2CAP_Init( taskID++ );   /* L2CAP Task */

      GAP_Init( taskID++ );   /* GAP Task */

      GATT_Init( taskID++ );   /* GATT Task */

      GAPRole_Init( taskID++ );   /* Profiles */

    ...

      /* Application */

      SimpleBLEPeripheral_Init( taskID );

    }

    As you can see, by incrementing the taskID value, each entity receives its own and unic taskID. You have to send the event where you want it to be received. If it is sent to the simpleBLEPeripheral layer taskID, it is going to be processed in SimpleBLEPeripheral_ProcessEvent. Please note by the comments you can even "cheat" and send the event to a raw directly coded taskID, I mean:
    osal_set_event(0x0B, 0x0004)               //- this sends the event 0x0004 to the taskID 0x0B
    But this is obviously not a right coding style, even if it is useful for debug & test purposes.
  • Hi everyone!

    I tell you that i could solve my problem with the interrupt on port 1 (P1_7) with the following port setting:

    (...)

    #if defined ( ACC1_400HZ_FALL )

      P1DIR |= 0x47; // port 1 pins (P1.0-P1.2, P1.6) as output, P1.7 as input

      /* Clear flag and enable P1 interrupts */   

      PICTL = 0x00;

      P1IEN = 0x80;

      IEN2 |= BV(4);

      P1IFG = 0;

      P1IF = 0;

    #else

    (...)

    Then, the interrupt service routine is:

    HAL_ISR_FUNCTION( accFFDPort1Isr, P1INT_VECTOR ){

        HAL_ENTER_ISR();

        uint8 ffd;   

        if (P1IFG){

          ffd = acc1ReadINTStatus();

          HalLedOnOff (HAL_LED_2, HAL_LED_MODE_BLINK);

          osal_start_timerEx( myApp_TaskID, STOP_FFD_EVT, 1000);

          P1IFG = 0;

          P1IF = 0;

        }

        HAL_EXIT_ISR();

    }


    Then i had another problem with accelerometer settings, i had to write the accelerometer's registers inside a do-while structure, like:

    (...)

     do{

       accWriteReg(FFTHR, 0x08);

       WAIT_1_3US(80);

       accReadReg(FFTHR, &readValue);

       WAIT_1_3US(80);

     }while(readValue != 0x08);

    (...)


    Because with a simple write sentence, the register is not written correctly.

    But, now i have another problem, that is with FFTHR register of accelerometer.

    Its datasheet says:

    "When enabled, the Free-Fall Detection (FFD) will monitor the measured acceleration in the X, Y and Z directions. If all measured XYZ acceleration values stay within the TL longer than time TFF (Figure 5 below), the FFD will generate an interrupt to the INT-pin. TL can be controlled by FFTHR [6:0] and TFF by FFTMR [3:0] bits."

    FFTHR[5:0]

    Free fall detection threshold level absolute value. See detailed bit level weighting in Table below.

    Bit level description in [mg] for free fall detection threshold of CMA3000-D01.

    RANGE | G_RANGE |   B5   |   B4   |   B3   |   B2   |   B1   |   B0   |

     2g        |        1        |  143   |   71   |    36   |   18   |     x    |    x    |    [mg]

    -------------------------------------------------------------------------------------------------

     8g        |        0        |    x    |    x     |  571  |   286  |   143  |   71   |

    ------------------------------------------------------------------------------------------------


    So, i set this register FFTHR = 0x08 ---> 571mg

    But when i try to set the threshold in 1g with FFTHR = 0x0F (571+286+143+71), the threshold is 71mg instead of 1g.

    Why? Any help?


    Thanks in advance...  

  • Hi Martin,

    As you have been able to solve the interrupt problem, I would like to ask you where (in what file?) have you put each part of the code your are talking about? I am using the keyfobdemo_app as a base for my code.

    Have you created a new file called hal_acc.c in order to implement a new driver for the accelerometer and there you have put the ISR and the part of the code you mention first?

    Or you have not created a new file and you have put the ISR and that code in the file cma3000d.c?

    Thanks for the answer

     

  • You could put ISR code in several places. depends on the structure of your code. I put my ISR inside my main task (for example: SimpleBLEPeripheral.c, at the end). Besides, the interrupt port setting you could put where you set all other ports (In my case in the same file).

    I hope I've helped you, regards...

    P/D: someone has been able to set FFTHR in 1g of threshold? 

     

    Best regards,
    Martin R 

  • Dear friends,

    I just want to inform you that finally I have managed to use accelerometer with interrupts. Now, I am acquiring data each time the accelerometer interrupts the CPU, so thanks to all of you Martin, Igor and kazola.

    Martin I don't understand what you mean when you say "been able to set FFTHR in 1g of threshold". If you follow the table 7 of the datasheet I understand that if you activate B3, B2 and B1 (571mg+286mg+143mg), you will get 1g (only in 8g mode). The FFTHR register should be set with "0x0E". I think this is working in my case, why do you think you have been able to set the FFTHR register in 1g? Can you explain what is the problem?

     

    Best Regards,

    Victor

  • Congratulations,

    so why don't you post the code and / or the procedure here and / or even create a wiki entry?

  • Hi Victor! I'm glad you've solved!

    When i said if someone could set FFTHR in 1G of threshold. I meant if someone could set FFTHR register properly, and the accelerometer behave according to the configuration. Because when i tried to set the threshold in 1g with FFTHR = 0x0E (571+286+143), the threshold really was set in 143mg instead of 1g. However when i read this register its value is 0x0E, but the accelerometer behave like if this register would had set in 143mg. It's understood the problem? 

    Best regards!


    Martin

  • Hi all,

    Here is the code that has worked for me. I am using a modified version of the keyfobdemo (version 1.0). I have also tried version 1.1 of the keyfobdemo and it is not working yet... (I don't know why). Meanwhile, the code that is working is:

    --------------------------------------

    In the file keyfobdemo.c:

    --------------------------------------

     

    /********** CONSTANTS TO CREATE INTERRUPTS ON CPU FOR THE ACC **************/

    /* CPU port interrupt for accelerometer configuration */
    #define HAL_ACC_CPU_PORT_1_IF P1IF

    /* Configuration variables for accelerometer Interrupt at port P1.7 */
    #define HAL_ACC_INT_PORT   P1
    #define HAL_ACC_INT_BIT    BV(7)    /*Port 1 INT bit, in this case P1.7 */
    #define HAL_ACC_INT_SEL    P1SEL
    #define HAL_ACC_INT_DIR    P1DIR

    #define HAL_ACC_INT_IEN      IEN2  /* CPU interrupt mask register IEN2 (CPU Interrupt Enable 2, contains Port 1. Pag.43)*/
    #define HAL_ACC_INT_ICTL     P1IEN /* Port Interrupt Control register - Port P1.7 to P1.0 interrupt enable*/
    #define HAL_ACC_INT_ICTLBIT  BV(7) /* P1IEN - P1.7 enable/disable bit */
    #define HAL_ACC_INT_IENBIT   BV(4) /* Mask bit for all of Port_1 */
    #define HAL_ACC_INT_PXIFG    P1IFG /* Port 1, inputs 7 to 0 interrupt status flags (IFG). When an input port pin has an interrupt request pending, the corresponding flag bit is set.*/

    #define HAL_ACC_INT_EDGEBIT  BV(2) /* PICTL.P1ICONH (PICTL bit 2) port 1 inpus 7 to 4. Selects interrupt request condition. */
                                       /* 0 = Rising edge on input gives interrupt | 1 = Falling edge on input gives interrupt */

    void KeyFobApp_Init( uint8 task_id )
    {

    ...

    // For keyfob board set GPIO pins into a power-optimized state
      // Note that there is still some leakage current from the buzzer,
      // accelerometer, LEDs, and buttons on the PCB.
     
      P0SEL = 0; // Configure Port 0 as GPIO
      P1SEL = 0x40; // Configure Port 1 as GPIO, except P1.6 for peripheral function for buzzer
      P2SEL = 0; // Configure Port 2 as GPIO

      P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
                    // all others (P0.2-P0.7) as output
      P1DIR = 0x7F; // All port 1 pins (P1.0-P1.6) as output, except P1.7
      P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
     
      P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
      P1 = 0x00;   // All pins on port 1 to low
      P2 = 0;   // All pins on port 2 to low 

    ...

       // Setup a delayed profile startup
      osal_start_timerEx( keyfobapp_TaskID, KEYFOB_START_DEVICE_EVT, STARTDELAY );
    }

    uint16 KeyFobApp_ProcessEvent( uint8 task_id, uint16 events )
    {
      ...

      if ( events & KEYFOB_START_DEVICE_EVT )
      {
        // Start the Device
        VOID GAPRole_StartDevice( &keyFob_PeripheralCBs );
       
        // Start the Accelerometer Profile
        accInit();
          
        /*
          Clear the CPU interrupt flag for Port_1
          PxIFG has to be cleared before PxIF
        */
        HAL_ACC_INT_PXIFG = ~(HAL_ACC_INT_BIT); /* Clear Interrupt Flag */
        HAL_ACC_INT_PXIFG = 0;
        HAL_ACC_CPU_PORT_1_IF = 0;
       
        // Activate accelerometer interrupts
        PICTL |= HAL_ACC_INT_EDGEBIT;   /* Set the edge bit to set falling edge to give int, int will be set when int port chanhes from high to low */
        HAL_ACC_INT_ICTL |= HAL_ACC_INT_ICTLBIT; /* enable interrupt generation at port 1 (pag.88 P1IEN datasheet)*/
        HAL_ACC_INT_IEN |= HAL_ACC_INT_IENBIT;   /* enable CPU interrupt */
        HAL_ACC_INT_PXIFG = ~(HAL_ACC_INT_BIT); /* Clear any pending interrupt in port 1, to detect new ones */
       
        return ( events ^ KEYFOB_START_DEVICE_EVT );

      }

    if ( events & ACCEL_READ_EVT )
      {
        accelRead();
           
        return (events ^ ACCEL_READ_EVT);
      }

    }

    /***************************************************************************************************
     *                                    INTERRUPT SERVICE ROUTINE
     ***************************************************************************************************/

    /**************************************************************************************************
     * @fn      halAccPort1Isr
     *
     * @brief   Port1 ISR
     *
     * @param
     *
     * @return
     **************************************************************************************************/
    HAL_ISR_FUNCTION( halAccPort1Isr, P1INT_VECTOR )
    {
      bool valid=FALSE;
     
      if (HAL_ACC_INT_PXIFG & HAL_ACC_INT_BIT)
      {
          HAL_ACC_INT_PXIFG = ~(HAL_ACC_INT_BIT); /* Clear Interrupt Flag */
          valid = TRUE;
      }
     
      if (valid)
      {
          //osal_set_event(keyfobapp_TaskID, ACCEL_READ_EVT);
      }

      /*
        Clear the CPU interrupt flag for Port_1
        PxIFG has to be cleared before PxIF
      */
      HAL_ACC_INT_PXIFG = 0;
      HAL_ACC_CPU_PORT_1_IF = 0;
    }


    /*********************************************************************
    *********************************************************************/

     

    --------------------------------------

    In the file cma3000d.c:

    --------------------------------------

    void accInit(void)
    {
        //*** Setup USART 0 SPI at alternate location 2 ***

        // USART 0 at alternate location 2
        PERCFG |= 0x01;
        // Peripheral function on SCK, MISO and MOSI (P1_3-5)
        P1SEL |= 0x38;
        // Configure CS (P1_7/P1_2) as output
    #ifdef REV_1_0
        P1DIR |= 0x04;    //P1_2 CS as output
        P1DIR &= ~0x80;   //(configure P1_7) as INT
        //P1DIR |= 0x47;      // port 1 pins (P1.0-P1.2, P1.6) as output, P1.7 as input
    #elif (defined REV_0_6)
        P1DIR |= 0x80;    //P1_7 CS as output
    #endif
        CS = CS_DISABLED;

        //*** Setup the SPI interface ***
        // SPI master mode
        U0CSR = 0x00;
        // Negative clock polarity, Phase: data out on CPOL -> CPOL-inv
        //                                 data in on CPOL-inv -> CPOL
        // MSB first
        U0GCR = 0x20;
        // SCK frequency = 480.5kHz (max 500kHz)
        U0GCR |= 0x0D;
        U0BAUD = 0xEC;

        uint8 readValue;
       
        //External reset sequence
        accWriteReg(RSTR, 0x02);
        WAIT_1_3US(80);
        accWriteReg(RSTR, 0x0A);
        WAIT_1_3US(80);
        accWriteReg(RSTR, 0x04);
        WAIT_1_3US(80);
       
        do{
            accReadReg(STATUS, &readValue);
            WAIT_1_3US(80);
        }while(~readValue & 0x08);
       
        //Mode configuration
        accWriteReg(CTRL, RANGE_8G | INT_ACTIVE_LOW | I2C_DIS | MODE_400HZ_FALL);
        WAIT_1_3US(80);
        do{
            accReadReg(STATUS, &readValue);
            WAIT_1_3US(80);
        }while(readValue & 0x08);
     
        //Free falling window time (set configuration time)
        accWriteReg(MDFFTMR, 0x0F);
        WAIT_1_3US(80);
        do{
            accReadReg(STATUS, &readValue);
            WAIT_1_3US(80);
        }while(readValue & 0x80);  

        accWriteReg(FFTHR, 0x06);
        WAIT_1_3US(80);
        do{
            accReadReg(STATUS, &readValue);
            WAIT_1_3US(80);
        }while(readValue & 0x80);
       
    }

  • From what I can tell there are some missing defines.  And this is in the first few line segments.   KEYFOB_START_DEVICE_EVT  isn't defined in the upper code.... This could pose a problem unless I can just make up may own ..... doens't seem right!   Is there an include file that pairs this information?

  • 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