Hi,
I have an application where I often need to reconfigure pins from analog inputs to outputs (and eventually back to analog inputs again). It works as expected on one of the pins I tried it with, but not on any other pin. This inconsistency really has me stumped. Why does it work in one case and not others?
I created a simplified example that recreates this problem on the LM4F232H5QD (rev A1) eval board using Stellarisware (rev 9453):
| #include "inc/hw_adc.h" #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "inc/hw_sysctl.h" #include "inc/hw_types.h" #include "driverlib/adc.h" #include "driverlib/gpio.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" /******************************************************************************* * GPIO peripheral addresses *******************************************************************************/ const unsigned long gpioPeripherals[] = { SYSCTL_PERIPH_GPIOA, SYSCTL_PERIPH_GPIOB, SYSCTL_PERIPH_GPIOC, SYSCTL_PERIPH_GPIOD, SYSCTL_PERIPH_GPIOE, SYSCTL_PERIPH_GPIOF, SYSCTL_PERIPH_GPIOG, SYSCTL_PERIPH_GPIOH, SYSCTL_PERIPH_GPIOJ, SYSCTL_PERIPH_GPIOK, SYSCTL_PERIPH_GPIOL, SYSCTL_PERIPH_GPIOM, SYSCTL_PERIPH_GPION, SYSCTL_PERIPH_GPIOP, SYSCTL_PERIPH_GPIOQ, SYSCTL_PERIPH_GPIOR, SYSCTL_PERIPH_GPIOS }; /******************************************************************************* * Ports, pins, adc channels *******************************************************************************/ typedef struct { unsigned long port; unsigned char pin; unsigned long adcChannel; } _reconfigurePins; const _reconfigurePins reconfigurePins[] = { GPIO_PORTK_BASE, GPIO_PIN_1, ADC_CTL_CH17, GPIO_PORTD_BASE, GPIO_PIN_5, ADC_CTL_CH6, GPIO_PORTD_BASE, GPIO_PIN_6, ADC_CTL_CH5, GPIO_PORTK_BASE, GPIO_PIN_3, ADC_CTL_CH19, GPIO_PORTK_BASE, GPIO_PIN_2, ADC_CTL_CH18, }; #define NUMBER_OF_PINS sizeof(reconfigurePins) / sizeof(_reconfigurePins) void main(void) { unsigned long pinType; unsigned long strength; MAP_SysCtlClockSet( SYSCTL_OSC_MAIN | *Configure system clock to 50MHz */ SYSCTL_USE_PLL | /* using 200 MHz PLL */ SYSCTL_SYSDIV_4 | /* divided by four */ SYSCTL_XTAL_16MHZ ); /* clocked from 16MHz external crystal */ unsigned int i, ports; // //Enable all GPIO peripherals // ports = sizeof(gpioPeripherals) / sizeof(unsigned long); /*Get the number of gpio peripherals */ for (i = 0; i < ports; i++) /*For all GPIO peripherals */ { if( MAP_SysCtlPeripheralPresent(gpioPeripherals[i])) /*If peripheral is present on this part */ { MAP_SysCtlPeripheralEnable(gpioPeripherals[i]); /*Enable the peripheral */ } } // //Configure pins as analog inputs // for (i = 0; i < NUMBER_OF_PINS; i++) { MAP_GPIOPinTypeADC(reconfigurePins[i].port, reconfigurePins[i].pin); } // //All pins are successfully configured as analog inputs here // for (i = 0; i < NUMBER_OF_PINS; i++) { MAP_GPIOPadConfigGet( /*Get pin configuration */ reconfigurePins[i].port, /*Pin base address */ reconfigurePins[i].pin, /*Pin */ &strength, /*Location to store pin strength */ &pinType); /*Location to store pin type */ } // //Reconfigure pins as outputs // for (i = 0; i < NUMBER_OF_PINS; i++) { MAP_GPIOPinTypeGPIOOutput( /*Reconfigure pin as output */ reconfigurePins[i].port, reconfigurePins[i].pin); } // //Only PK1 successfully reconfigures as an output //Changing the location of PK1 in the array results in the same behavior // for (i = 0; i < NUMBER_OF_PINS; i++) { MAP_GPIOPadConfigGet( /*Get pin configuration */ reconfigurePins[i].port, /*Pin base address */ reconfigurePins[i].pin, /*Pin */ &strength, /*Location to store pin strength */ &pinType); /*Location to store pin type */ } for(;;); } |