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/CC2650MODA: Fast GPIO toggle

Part Number: CC2650MODA
Other Parts Discussed in Thread: CC2650

Tool/software: Code Composer Studio

I am having a strange problem with CC2650MODA GPIO. I am using "simple_np_cc2650bp_app" project as my base project and adding my application functionality. One of the requirement I have is to generate fast IO to emulate 1-Wire protocol over a GPIO. I tried multiple different ways to generate minimum GPIO time I need starting with timer, using TI PIN driver, using direct PINCC26XX drivers and also writing to HWREG directly. But for some reason I am not able to get time period to few microseconds. System clock frequency is 48MHz and system tick is at 10usec.

For example as shown in code snippet below I am toggling GPIO (where ONE_PIN is DIO14 on CC2650MODA) without any other code or task sleep. But as you can see in the logic analyzer snippet I am getting 0.125us for transition from 0 to 1 but for transition from 1 to 0 it takes 31.31us. This is something I am not able to understand and I need help with asap.

I have tried disabling system tick timer using "Clock_tickStop()" before this code block and starting system tick timer again with "Clock_tickStart()". But it didn't made any difference. Actually project has only one active task, so task switching should not be an issue. The fastest frequency I can toggle with (0.125us + 31.31us) is close to 32KHz frequency. Is this the clock rate for I/O Control module because of which I can not toggle any faster?

To comply with the protocol I need to have at least 15us time period reliably.

/* Code Snippet */

    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 0;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 1;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 0;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 1;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 0;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 1;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 0;
    HWREGB(GPIO_BASE+GPIO_O_DOUT3_0+ONE_PIN) = 1;

  • Try to refer to to do micro second delay.

  • Hello Pritesh,

    Is pull configured on the IO? That might explain the difference in rise and fall times.

    BTW, It also might be possible for you to implement this interface in the sensor controller if it makes sense.

  • Thanks Chen for sharing the article. I will try it out.

  • Hi Eirik,

    The current configuration for the IO is open drain with no pull. I need IO to be open drain to connect device to 1-wire network. Out of curiosity I did tryout push-pull configuration but with same result. It seems some thing in the IO controller is blocking calls.

    Ultimately I do want to implement this in sensor controller but doesn't sensor controller use/share the same IO controller module on the SOC?

  • Hi Eirik,

    Any update on the issue? Were TI engineers able to replicate the issue that I am having? I really need to know if this is a limitation of CC2650MODA and in that case we have to replace CC2650MODA with an alternative.

  • Hello Pritesh,

    Can you show me how you configured the pin?

    What is the value of ONE_PIN?

  • Hi Eirik,

    Below is the parts of the code that assigns PIN ID and get a handle for the ONE_PIN. In the process, I actually figured out where additional execution block is happening in my application. One of the requirement for the protocol is to able to generate a negative falling interrupt when master assert the line and produce delays base on timer as compared to waits. The edge triggered call back with just timer stop/start calls is blocking task for 32us. Even with  call back routine empty, I measured task block of 20us. Is there a way I can reduce call back routine delay? Without GPIO enabled for negative edge trigger I am getting delays of 0.125us for both high to low and low to high transitions.

    /* Board Specific header file */
    #define Board_BP_ONE_WIRE              Board_BP_Pin_J2_12
    
    /* One Wire */
    #define Board_ONE_WIRE                 Board_BP_ONE_WIRE
    
    /* Application Task File */
    #define ONE_PIN			       Board_ONE_WIRE
    
    
    // Define pins used by one wire slave as open drain input/output
    const PIN_Config aOwPin[] = {
        ONE_PIN     | PIN_INPUT_EN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_NOPULL | PIN_OPENDRAIN | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    PIN_State  hOwPinState;
    PIN_Handle  hOwPin;
    
    void edgeTriggerCallback(PIN_Handle handle, PIN_Id pinId) {
        //one_falledge_flag = 1;
        //timer1_stop();
        //timer1_start();
    }
    
    // Get handle to One Wire Pin
    hOwPin = PIN_open(&hOwPinState, aOwPin);
    if (!hOwPin) {
      // Handle allocation error
    }
    // Edge trigger
    PIN_registerIntCb(hOwPin,  edgeTriggerCallback);
    PIN_setInterrupt(hOwPin,  PIN_ID(ONE_PIN)| PIN_IRQ_NEGEDGE);

  • Hi Eirik,

    Should edge trigger interrupt callback take 20us to enter after an edge occurs on the IO? Or is there something I am missing?

  • Hi Eiric,

    The interrupt latency of about 20us is really affecting to generate the protocol I need. Is there a solution that TI engineers can provide to reduce interrupt latency?

  • Hello Pritesh,

    Should not the CC2650 be the master?

    You might be able to make a solution with sensor controller by keeping the module in active mode (to avoid latency due to power up from standby). There is also a small Single-Wire Handshake in the Sensor Controller Studio Help Viewer for General-purpose digital open-drain pins (drive low).

    For the PIN driver interrupt latency the first entry after the HWI dispatcher will be the PIN_hwi in PINCC26XX.c that will post a swi (PIN_swi) that calls the callback interrupt function. This might consume quite a bit of clock cycles as it will iterate through the pinHandleTable. So you might be able to modify the PIN_hwi  at your own risk. In that case copy the driver files in to your project and modify. remember the HWI triggers for all pins with interrupt enabled.