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.

RTOS/CC2650: TI-RTOS PIN driver, re-configure pin at run time

Part Number: CC2650

Tool/software: TI-RTOS

Hi TI E2E Community,

I've been working with a CC2650 and a temperature sensor DHT11 to understand better how the PIN driver works and the TI-RTOS in general. After a couple hours of coding, I got it working, though I have the feeling that it could've been done better. Let me explain, to read successfully a DHT11 sensor you have to initialize one pin as an output to send a low start signal for 18 ms, then change the pin configuration to input to read the sensor's data. I found to different ways of achieving this using the PIN driver, in the following code they are presented as /* Method 1 */ and /* Method 2 */ in the readSensor function.

/* PIN configuration table */
PIN_Config gpioTable[] =
{
	/* Outputs */
	DHT11 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
	/* End of table */
	PIN_TERMINATE
};

uint8_t readSensor(uint8_t* temperature, uint8_t* humidity)
{
	/* Allocate collection of pins */
	gpioHandle = PIN_open(&gpioState, gpioTable);
	if (!gpioHandle) System_abort("Error allocating pin\n");

	/* Buffer to receive */
 	uint8_t bytes[DHT11_NUM_BYTES];
	uint8_t i = 0, j = 0;

	/* Empty buffer */
	for (i = 0; i < DHT11_NUM_BYTES; i++) bytes[i] = 0;

	/* Request sample */
	PIN_setOutputValue(gpioHandle, DHT11, LOW);
	/* Sleep for 18 ms */
	Task_sleep(18000 / Clock_tickPeriod);

	/* Method 1 */
	/* PIN_setOutputEnable(gpioHandle, DHT11, 0);
	PIN_setConfig(gpioHandle, (PIN_INPUT_EN | PIN_NOPULL), (DHT11 | PIN_INPUT_EN | PIN_NOPULL)); */
/* Method 2 */ PIN_remove(gpioHandle, DHT11); PIN_add(gpioHandle, (DHT11 | PIN_INPUT_EN | PIN_NOPULL)); /* Skip the following pulses */ if (skipPulse(HIGH)) return DHT11_ERROR_TIMEOUT; if (skipPulse(LOW)) return DHT11_ERROR_TIMEOUT; if (skipPulse(HIGH)) return DHT11_ERROR_TIMEOUT; /* Read output - 40 bits => 5 bytes or timeout */ UInt32 lastTick = 0, width = 0; for (i = 0; i < DHT11_NUM_BYTES; i++) { for (j = 0; j < 8; j++) { if (skipPulse(LOW)) return DHT11_ERROR_TIMEOUT; lastTick = Clock_getTicks(); if (skipPulse(HIGH)) return DHT11_ERROR_TIMEOUT; /* calculate width of last HIGH pulse */ width = (Clock_getTicks() - lastTick) * Clock_tickPeriod; /* shift in the data, msb first if width > threshold */ bytes[i] |= ((width > DHT11_THRESHOLD) << (7 - j)); } } /* the checksum will overflow automatically */ uint8_t checkSum = 0; for (i = 0; i < (DHT11_NUM_BYTES - 1); i++) checkSum += bytes[i]; if (checkSum != bytes[4]) return DHT11_ERROR_CHECKSUM; *humidity = bytes[0]; *temperature = bytes[2]; /* Deallocate pins to return to the default configuration */ PIN_close(gpioHandle); return DHT11_OK; }

int main(void)
{
    /* Power manager initialization */
    Power_init();

    /* PIN module initialization */
    if (PIN_init(gpioTable) != PIN_SUCCESS) System_abort("Error initializing gpioTable\n");

    /* Start BIOS */
    BIOS_start();

    return (0);
}

In terms of PIN configuration, the process goes as follows:

1. Use PIN_open to allocate pins based on the gpioTable

2.  Choose either method 1 or 2 to change pin configuration from output to input

3. Use PIN_close deallocate pins and return to the default configuration (the one provided by gpioTable since the PIN module was initialized with it)

The issue:

  • Method 1: By using PIN_setConfig we are adding not re-configuring. This means that after using this PIN_setConfig to add PIN_INPUT_EN to my DHT11 pin, it was still having PIN_GPIO_OUTPUT_EN set from previous configuration. This cause me troubles since the DHT11 was still outputting a 'LOW' level from a previous call. To solve this problem I had to disable the output manually with  PIN_setOutputEnable.
  • Method 2: This one is the one that I liked the most since it is pretty straightforward and clearer. By adding an removing a PIN there is no need to use PIN_setOutputEnable to diasble the output, although, I don't know how efficient would be constantly adding and removing a pin.

I was wondering if there isn't any method similar to PIN_setConfig in the sense that adds new configurations but resets previous ones. In other words, something that actually re-configures the pin. I looked for PIN_reConfig(), but I didn´t find anything.