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.

CC2640 GPIO Input



I'm having trouble with what would seemingly be a simple task.

I have customized my own board.c/board.h files to fit my specific needs.

I am able to successfully write to and change the value of a GPIO pin that is configured as an output, but unsuccessful when attempting to read the value of a GPIO pin that is configured as an Input.

Any suggestions on what I could be missing, I have done everything in the PIN.h file examples as well as looked over the SWRU393 Guide. 

Board.h

/*TAMPER SWITCH PINS*/
#define REED_SWITCH_STATUS					IOID_3
#define REED_SWITCH_ENABLE					IOID_2
/*LIGHT SENSOR PINS*/
#define LIGHT_SENSOR_ENABLE					IOID_7
#define LIGHT_SENSOR_STATUS					IOID_8
/*BATTERY VOLTAGE PINS*/
#define BATTERY_READ_ENABLE					IOID_13
#define BATTERY_VOLTAGE_READ				IOID_14
/*DEBUG UART*/
#define UART_DEBUG_RX						IOID_1
#define UART_DEBUG_TX						IOID_0

Board.c

PIN_Config BoardGpioInitTable[] = {

	REED_SWITCH_ENABLE 	| PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,
	REED_SWITCH_STATUS	| PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,

	/*LIGHT SENSOR PINS*/
	LIGHT_SENSOR_ENABLE	| PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,
    LIGHT_SENSOR_STATUS	| PIN_INPUT_EN | PIN_NOPULL | PIN_HYSTERESIS,

	PIN_TERMINATE
};

SimpleBLE Peripheral

// eTag pin handle
PIN_Handle hEtagPins;
PIN_State  EtagPins;  

hEtagPins = PIN_open(&EtagPins, BoardGpioInitTable); 


 //Tamper Switch Logic
    PIN_setOutputValue(hEtagPins, REED_SWITCH_ENABLE, 0);
    PIN_setOutputValue(hEtagPins, LIGHT_SENSOR_ENABLE, 0);
    // Sleep for 100ms
    Task_sleep(100000/10);
    //Get Input of Tamper
    reedSwitchStatus = PIN_getInputValue(REED_SWITCH_STATUS);
    lightSensorStatus = PIN_getInputValue(LIGHT_SENSOR_STATUS);
    reedSwitchStatus = PIN_getInputValue(REED_SWITCH_STATUS);
    if(reedSwitchStatus)
    {
    	Task_sleep(10000/10);
    }
    else
    {
    	Task_sleep(10000/10);
    }

  }

Thanks in advance for any help.

 

  • Any suggestions on why PIN_setOutputValue() would work properly, but not PIN_getInputValue() ?

    Thanks,

    Peyton

  • Hello Peyton,
    Did you run PIN_init first? If so which pin table did you use for it't argument (pin table)?
    Where in the SimpleBLEPeripheral code are you running this?
  • In main.c I am running -> PIN_init(BoardGpioInitTable);

    The point in the code where I am trying to read the and set the pins is in SimpleBLEPeripheral_performPeriodicTask(void) which is called every 5 seconds.
  • Are there anymore suggestions on things I should look into in order to properly read GPIO Input.

    Thanks.
  • I can't help with suggestions why getInputValue() doesn't work, but have you considered going the Interrupt route? i.e.

    PIN_registerIntCb(hEtagPins, yourCallbackFunction);

    Just a thought. You could react to GPIO events there and post a semaphore if you have to do a lot of work.

  • I was having exactly the same issue. 

    I just found that I can read the input value with PIN_NOPULL setting. 

    In fact I found that the input was stuck high with PIN_PULLUP and stuck low with PIN_PULLDOWN... 

    I did not check further in the documentation, but can anybody confirm this behavior ? and explain what is the purpose of the pull up and pull down settings ? 

    Note that I tested the same behavior in DIO 13 and 14

  • Hello Peyton,

    I tried your code (reading input from DIO25 instead of DIO8) successfully on SimpleBLEPeripheral (2.1) both with PIN_NOPULL and PIN_PULLUP.

    • What level do your read?
    • What kind of source voltage do you apply to the pin?
    • Have you mounted any external pull-up or pull-down?

  • Hey Eirik,

    I am reading a HIGH Input when debugging regardless of the voltage level (HIGH = 2.8V, LOW =  GND) at the input of the DIO3 pin. There are no external pull-up or pull-downs. I am also getting the same results when using the SaBLE-x Dev Board and tying the pin to GND still reads a HIGH input.

    The problem is that whenever I am using functions that do not require that handle it can not find the pin and return the corresponding value.

    For example calling the below value function where hEtagPins is required returns the correct value.

    PIN_setOutputValue(hEtagPins, LIGHT_SENSOR_ENABLE, 0);

    But, Calling PIN_getOutputValue(LIGHT_SENSOR_ENABLE) always returns 1;

     

    This is also the case for:

    PIN_getInputValue(REED_SWITCH_STATUS);

     

     

  • Hi Peyton,

    First of all, please check that the pin handle (hEtagPins) are not NULL. The "handle" architecture the pin driver uses is to ensure a client of a set of pins owns these and only that client can modify pin settings and outputs. Our peripheral drivers will for example run PIN_open on the set of pins the peripheral is using to ensure nothing else can modify these pins.
    If you provide an invalid handle then simply PIN_NO_ACCESS is returned.

    Also note the difference in PIN_getOutputValue and PIN_getInputValue. Getting the output value means reading which value the output buffer (if enabled as output) is trying to drive the pin to. PIN_getInputValue will return the actual value on the input read in by the input buffer (if input is enabled).

    Regards,
    Svend
  • Hi Svend,

    Thanks and yes, I was just showing both instances of getOuputValue and getInputValue b/c both were not working and both did not include the pin handle when calling the function.

    Also, I was using the cJTAG setup for my debugging so I was never able to see the return values as it would not allow me to set break points there.

    It seems my problem was not the functions themselves or the initialization but it was in the compiler settings that I had initially that was not aware of. My optimizations settings were optimizing the code out where I was reading the pin values and I was not aware of that b/c it was still allowing me to set break points there.

    To answer Sylvain:

    The purpose of the PULL-UP/PULL-DOWN settings are to allow the programmer to more easily incorporate external circuitry/sensor with the microcontroller. The use of pull-down/pull-up will just depend on whether or not you have a normally high, or normally grounded circuitry for reading the value of a binary sensor output such as a switch.

    If you have a normally open switch that floats when open, but is grounded when closed, you will use internal pull-up setting for example.

  • Hello Peyton,

    In that case you should see, in the dissambly window, that the breakpoints are not actually placed in the desired location.

    You can simply remove optimization on the SimpleBLEPeripheral_performPeriodicTask by adding the following pragma define:

    #pragma optimize=none
    static void SimpleBLEPeripheral_performPeriodicTask(void)