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.

CCS/CC2640R2F: GPTimerCC26XX with GPT_MODE_EDGE_COUNT

Part Number: CC2640R2F
Other Parts Discussed in Thread: SYSBIOS

Tool/software: Code Composer Studio

Hi,

We are trying to implement pulse counter for rotary encoder with GPTimerCC26XX.h.

timerCallback is working, when we use timerParams.mode = GPT_MODE_EDGE_TIME, but not with GPT_MODE_EDGE_COUNT.

Could anyone explain why it does not work?

void timerCallback(GPTimerCC26XX_Handle handle,
                   GPTimerCC26XX_IntMask interruptMask) {
  Log_info0("interrupt");
}

PIN_Config GptPinInitTable[] = {
  PIN_ID(Board_ENCODER) | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS, 
PIN_TERMINATE }; static void ProjectZero_init(void) { ... GPTimerCC26XX_Params timerParams; GPTimerCC26XX_Handle hTimer; GPTimerCC26XX_Params_init(&timerParams); timerParams.mode = GPT_MODE_EDGE_COUNT; timerParams.width = GPT_CONFIG_16BIT; hTimer = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0A, &timerParams); // Register interrupt when capture happens GPTimerCC26XX_registerInterrupt(hTimer, timerCallback, GPT_INT_CAPTURE); // Open pin handle and route pin to timer timerPinHandle = PIN_open(&timerPinState, GptPinInitTable); GPTimerCC26XX_PinMux pinMux = GPTimerCC26XX_getPinMux(hTimer); PINCC26XX_setMux(timerPinHandle, PIN_ID(Board_ENCODER), pinMux); GPTimerCC26XX_setCaptureEdge(hTimer, GPTimerCC26XX_BOTH_EDGES); GPTimerCC26XX_setLoadValue(hTimer, 0x0000); GPTimerCC26XX_setMatchValue(hTimer, 0x0010); GPTimerCC26XX_start(hTimer); }

  • I found out, that someone had a similar problem:

    https://e2e.ti.com/support/tools/ccs/f/81/t/801871

    And I also read Timers section from CC13x0, CC26x0 SimpleLink™ Wireless MCU Technical Reference Manual

    Now my edge counter started to work, but I still don't understand, why I need to set load value to 0xFFFF. If I set it to 0x0000 it does not work. 

    Now I have same problem as him, that I need to reset load value. I tried using GPTimerCC26XX_setLoadValue(hTimer, 0xFFFF) but it did not have any effect.

    And GPTimerCC26XX.h says, that if I need high accuracy, I need to setDepencency: 

    #include <ti/sysbios/family/arm/cc26xx/Power.h>
    #include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
    Power_setDependency(XOSC_HF);

    It seems, this code does not work with simplelink SDK 3.10.00.15. How it should be implemented with this SDK?

  • And now I found out, that someone had also solved, how to reset GPTimer value register:

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/538/t/722625

    #define GPT_0_OFFSET 0
    GPTimerCC26XX_Handle hTimer;
    
    void timerCallback(GPTimerCC26XX_Handle handle,
                       GPTimerCC26XX_IntMask interruptMask) {
      uint32_t edgeCount = GPTimerCC26XX_getValue(handle);
      Log_info1("callback %u", edgeCount);
    }
    
    PIN_Config gptPinInitTable[] = {
      Board_ENCODER | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,   
      PIN_TERMINATE
    };
    
    static void ProjectZero_init(void)
    {
    
      ...
    
      GPTimerCC26XX_Params timerParams;
      GPTimerCC26XX_Handle hTimer;
      GPTimerCC26XX_Params_init(&timerParams);
      timerParams.mode = GPT_MODE_EDGE_COUNT;
      timerParams.width = GPT_CONFIG_16BIT;
      timerParams.direction = GPTimerCC26XX_DIRECTION_UP;
      
      hTimer = GPTimerCC26XX_open(CC2640R2_LAUNCHXL_GPTIMER0A, &timerParams);
      
      // Register interrupt when capture happens
      // GPT_MODE_EDGE_COUNT seems to trigger GPT_INT_CAPTURE_MATCH interrupts
      GPTimerCC26XX_registerInterrupt(hTimer, timerCallback, GPT_INT_CAPTURE_MATCH);
      
      // Open pin handle and route pin to timer
      timerPinHandle = PIN_open(&timerPinState, gptPinInitTable);
      GPTimerCC26XX_PinMux pinMux = GPTimerCC26XX_getPinMux(hTimer);
      PINCC26XX_setMux(timerPinHandle, PIN_ID(Board_ENCODER), pinMux);
      GPTimerCC26XX_setCaptureEdge(hTimer, GPTimerCC26XX_BOTH_EDGES);
    
      // When counting in upwads direction LoadValue needs to be at least as 
      // large as matchValue for interrupts to work.
      GPTimerCC26XX_setLoadValue(hTimer, 0xFFFF); 
      GPTimerCC26XX_setMatchValue(hTimer, 1000);
      
      GPTimerCC26XX_start(hTimer);
    }
    
    static void user_handleButtonPress(button_state_t *pState) {
      switch (pState->pinId) {
        case Board_PIN_BUTTON0:
            if (pState->state) { // button pressed
              uint32_t edgeCount = GPTimerCC26XX_getValue(hTimer);
              Log_info1("button pressed %u", edgeCount);
            } else { // button released
              uint32_t edgeCount = GPTimerCC26XX_getValue(hTimer);
              Log_info1("button released %u", edgeCount);
    
              //-------------------------------------------------------------
              // Reset GPTimer0 value register
              //-------------------------------------------------------------
              HWREG(hTimer->hwAttrs->baseAddr + GPT_0_OFFSET + GPT_O_TAV) = 0;
    
            }
        break;
      }
    }

  • Hi Toni,

    I'm glad you were able to resolve your issue. Thanks for sharing!

    BR,

    Alexis