Kas
The macro looks to be incorrect - as you point out it can't set an input once it has been an output, but it is also is necessary to clear the corresponding bit in the GPIOx_PIDR register to be able to read anything other than a zero.
Below are the macros that I use (from the uTasker project):
#define _CONFIG_PORT_OUTPUT(ref, pins, chars) GPIO##ref##_PIDR &= ~(pins); fnConnectGPIO(PORT##ref, pins, chars); GPIO##ref##_PDDR |= (pins)
#define _CONFIG_PORT_INPUT(ref, pins, chars) GPIO##ref##_PIDR &= ~(pins); fnConnectGPIO(PORT##ref, pins, chars); GPIO##ref##_PDDR &= ~(pins)
#define _CONFIG_DRIVE_PORT_OUTPUT_VALUE(ref, pins, value, chars) GPIO##ref##_PIDR &= ~(pins); GPIO##ref##_PDOR = ((GPIO##ref##_PDOR & ~(pins)) | (value)); GPIO##ref##_PDDR |= (pins);
These allow multiple bits to be configured at the same time and also the output state to be defined when setting an output. The fnConnetGPIO() part is optional (and I haven't shown its code here) but it allows pull-ups to be defined on inputs and drive strengths to be defined on outputs, which are set the same for each of the pins reference in the call.
What is a bit strange about the KE and KEA devices is that the ports are in fact basically the same as those in K and KL parts - they use the same 32 bit registers to control them but they are named as if they were 8 bit registers. (One 32 bit register packs in 4 of the 8 bit ports).
I suspect that this is a naming conventon that has its roots in older 8 bit devices but it does make for some compatibility complications due to the naming:
- if there were two ports A an B then everything would be simple
- having 8 pseudo 8 bit ports packed into the 2 real 32 bit ports makes referencing unnecessarily complicated
With a few tricks one can live with it but it doesn't keep things as simple as they could have been....
Regards
Mark
http://www.utasker.com/kinetis.html