I was looking in the GPIO.h file for the KEA family and I saw the below code to set input/output for the ports, but something does not look correct to me.
#define CONFIG_PIN_AS_GPIO(port,register_number,mode) XCONFIG_PIN_AS_GPIO(port,register_number,mode)
#define XCONFIG_PIN_AS_GPIO(port,register_number,mode) (mode == 0) ? (GPIO##port##_PDDR |= 0 << register_number) : (GPIO##port##_PDDR |= 1 << register_number)
The first option in the conditional statement (second line) looks incorrect. If the port was previously set as an output (mode = 1) and then you try set the port as an input, you would be doing 1 | 0 which we know is equal to 1 -> output. Should the correct code not be
#define XCONFIG_PIN_AS_GPIO(port,register_number,mode) (mode == 0) ? (GPIO##port##_PDDR &= ~(1 << register_number)) : (GPIO##port##_PDDR |= 1 << register_number)
please let me know if I am understanding this incorrectly or if this really is an issue.
Thanks
Kas
解決済! 解決策の投稿を見る。
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
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
Looking through the other macros there appears to be other issues. As a general rule simple code like this I try not use other peoples code without checking it first and if possible I write the code myself so as not to be bitten by someone elses bad code.
Thank you for confirming my thoughts
Kas
Hi Kas,
I agree you. However, I'm not responsible for the issue and cannot confirm it because I'm not a Freescale person.
Best regards,
Yasuhiko Koumoto.
Thank you for confirming my thoughts
Kas