Hi,
It seems that the new GPIOTiva implementation does not allow pin grouping, only single pins can be defined. Is this correct? If so please bring back the old GPIO driver! It would seem the complexity has been reduced at the cost of flexibility.
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.
Hi,
It seems that the new GPIOTiva implementation does not allow pin grouping, only single pins can be defined. Is this correct? If so please bring back the old GPIO driver! It would seem the complexity has been reduced at the cost of flexibility.
Hi Chris,
According to the development team, the 'pin grouping' feature (ie. writing several pins at once by specifying several pins in the bitmask) was an unintended side-effect in the former implementation of the GPIO driver. This functionality is not supported and there is no plan to do so at this point in time. If you absolutely need this feature you can continue to use and maintain the older implementation by copying its source files into your own project.
Best regards,
Vincent
Hi Vincent,
I've stepped through the code and most of it seems to handle pin groups very well. It seems strange that the prototype for GPIO_write()/GPIO_read() uses "int"s, eg
Shouldn't these take/return "bool" if pin grouping isn't allowed.
Anyway, with a small fix we can re-add pin grouping (which is a major advantage of using the arm chips, since they use address mapping to mask each bit in a port).
unsigned int GPIO_read(unsigned int index)
{
unsigned int value;
PinConfig *config = (PinConfig *) &GPIOTiva_config.pinConfigs[index];
Assert_isTrue(initCalled && index < GPIOTiva_config.numberOfPinConfigs, NULL);
value = GPIOPinRead(getGpioBaseAddr(config->port), config->pin);
Log_print3(Diags_USER1, "GPIO: port 0x%x, pin 0x%x read 0x%x", config->port, config->pin, value);
return value & config->pin; //((value & config->pin) ? 1 : 0); <---- CHANGE THIS LINE
}
void GPIO_write(unsigned int index, unsigned int value)
{
unsigned int key;
uint32_t output;
PinConfig *config = (PinConfig *) &GPIOTiva_config.pinConfigs[index];
Assert_isTrue(initCalled && index < GPIOTiva_config.numberOfPinConfigs, NULL);
Assert_isTrue((GPIOTiva_config.pinConfigs[index] & GPIO_CFG_INPUT) == GPIO_CFG_OUTPUT, NULL);
key = Hwi_disable();
/* Clear output from pinConfig */
GPIOTiva_config.pinConfigs[index] &= ~GPIO_CFG_OUT_HIGH;
if (value) {
output = value; //config->pin; <------ CHANGE THIS LINE
/* Set the pinConfig output bit to high */
GPIOTiva_config.pinConfigs[index] |= GPIO_CFG_OUT_HIGH;
}
else {
output = value;
}
GPIOPinWrite(getGpioBaseAddr(config->port), config->pin, output);
Hwi_restore(key);
Log_print3(Diags_USER1, "GPIO: port 0x%x, pin 0x%x wrote 0x%x", config->port, config->pin, value);
}
And in your EK_TM4C1294XL.c
GPIO_PinConfig gpioPinConfigs[] = {
/* Pin grouping */
GPIOTiva_PM_4 | GPIOTiva_PM_5 |GPIOTiva_PM_6 |GPIOTiva_PM_7 |GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
};
You can either change the source code and recompile or create your own GPIO_writeGroup() function in your own local file. But when I did this I had to copy several types/structures/vars from GPIOTiva.c since they were either static or locally defined, eg
#include <stdbool.h>
#include <xdc/runtime/Assert.h>
#include <xdc/runtime/Diags.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Log.h>
#include <ti/sysbios/family/arm/m3/Hwi.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOTiva.h>
#include <driverlib/gpio.h>
#include <inc/hw_memmap.h>
/* Boolean to confirm that GPIO_init() has been called */
static volatile bool initCalled = true; // <---- THIS NEED TO BE true TO AVOID ASSERTS, OR REMOVE THE ASSERT FROM YOUR CODE
extern const GPIOTiva_Config GPIOTiva_config;
/* Device specific interpretation of the GPIO_PinConfig content */
typedef struct PinConfig {
uint8_t pin;
uint8_t port;
uint16_t config;
} PinConfig;
/* Returns the GPIO port base address */
#define getGpioBaseAddr(port) (gpioBaseAddresses[port])
/* Table of port base addresses. */
static const uint32_t gpioBaseAddresses[] = {
GPIO_PORTA_BASE, GPIO_PORTB_BASE, GPIO_PORTC_BASE,
GPIO_PORTD_BASE, GPIO_PORTE_BASE, GPIO_PORTF_BASE,
GPIO_PORTG_BASE, GPIO_PORTH_BASE, GPIO_PORTJ_BASE,
GPIO_PORTK_BASE, GPIO_PORTL_BASE, GPIO_PORTM_BASE,
GPIO_PORTN_BASE, GPIO_PORTR_BASE, GPIO_PORTS_BASE,
GPIO_PORTT_BASE, GPIO_PORTP_BASE, GPIO_PORTQ_BASE
};
void GPIO_writeGroup(unsigned int index, unsigned int value)
{ ...}
unsigned int GPIO_readGroup(unsigned int index)
{...}
Its a shame TI decided to remove pin grouping by failing to code two lines of code correctly ;-(
The rest of the GPIO functions (eg GPIO_init(), GPIO_setConfig() ) all work with pin grouping.
The only problem you will have is the ability of the GPIO driver to remember your actual pin values when you enter deep sleep since the driver only stores a single bit to indicate the value the pin should be restored to when it wakes up.
I hope this helps other people.
cheers
Chris