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.