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.

CC3200 GPIO initial state

Other Parts Discussed in Thread: CC3200

I've been doing some testing on the GPIO pins and found some very odd behaviour. On any micro I've used in the past, the GPIO data registers are buffered. So you can write a value to the data register, then set the data direction, and guarantee that you won't drive the wrong value to the pin momentarily. It appears that this doesn't work on the CC3200.

//configure GPIO pin as output, high, pushpull
MAP_PinTypeGPIO(PIN_01, PIN_MODE_0, false);
MAP_GPIODirModeSet(GPIOA1_BASE, 1 << 2, GPIO_DIR_MODE_OUT);
GPIO_IF_Set(10, GPIOA1_BASE, 1<<2, 1);

works - the pin is driven high.

//configure GPIO pin as output, high, pushpull
MAP_PinTypeGPIO(PIN_01, PIN_MODE_0, false);

GPIO_IF_Set(10, GPIOA1_BASE, 1<<2, 1);

MAP_GPIODirModeSet(GPIOA1_BASE, 1 << 2, GPIO_DIR_MODE_OUT);

Does not work. The pin is driven low. This is not good. The pin in question is a data line, that won't (gracefully) tolerate being driven low.

Then it got weirder. I added a hardware pullup to ensure that at least the pin would be high during boot, and ran the above code again. The pin did not go low when the direction was set to output. 

It appears that the data register is retaining the read value! If the pin is externally pulled high when the direction is set to output, the pin will drive high. If it's pulled low, it will start driving low. If I'm correct, that's madness.

In my case, it fortunately seems to work out - the pullup holds it high, and then I want it to keep driving high. But I can imagine a whole range of scenarios where the pin is floating or unknown, but absolutely must not be driven to a random value. Please tell me I'm wrong.

  • Iain,

    I'll check and get back by early next week.

    -/Praneet
  • Any updates on this?

  • how's that week looking?

  • Well, there is only one GPIODATA register, used for both output and input. So, when you configure the GPIO as input it gets used as input register. In your second case (copied below), the 2nd statement is not right.. At this point, the GPIO by default could be input!! So, the proper procedure is to 'set the direction of the GPIO and then write the desired output to the DATA register. Else, as you noted the input will be retained in the DATA register and drives the output, when the GPIO is configured as output. Please refer to the "Initialization and Configuration" steps in section 5.4 of the CC3200 Technical reference manual. As, you noted use external (or internal) pull up/downs if you want to keep the line at a level (high or low).....

    //configure GPIO pin as output, high, pushpull

    MAP_PinTypeGPIO(PIN_01, PIN_MODE_0, false);
    GPIO_IF_Set(10, GPIOA1_BASE, 1<<2, 1);
    MAP_GPIODirModeSet(GPIOA1_BASE, 1 << 2, GPIO_DIR_MODE_OUT);
  • Yeah, that appears to be how it works. It should not be how it works, though. Yes, there's only one data register, but typically it is tied to separate input and output buffers, controlled by the data direction register. Writes to the data register address go into the output buffer, whether the direction is input or output, and when the pin is made an output the buffer is tied to the pin. It prevents exactly the uncertainty I'm describing. 

    For example, the S08 family is extremely common. The top of page 76 of its datasheet illustrates the concept clearly, and explains why and how you should use it.

  • Iain,

    Apologies for the delayed response.

    On CC3200, we don't have a separate input and output buffers. Please follow the initialization and configurations steps mentioned by Hari in his above post. Also, add a 2.7K or stronger pull-up or pull-down to ensure that the state of the line is maintained during power on reset - Without this, the line can get pulled by internal pulls momentarily causing a glitch (which lasts upto 15ms)

    -/Praneet