GPIO.h input/output configuration correct ?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GPIO.h input/output configuration correct ?

Jump to solution
2,297 Views
kaslewis
Contributor III

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

0 Kudos
Reply
1 Solution
1,810 Views
mjbcswitzerland
Specialist V

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

View solution in original post

0 Kudos
Reply
4 Replies
1,811 Views
mjbcswitzerland
Specialist V

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

0 Kudos
Reply
1,810 Views
kaslewis
Contributor III

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

0 Kudos
Reply
1,810 Views
yasuhikokoumoto
Senior Contributor I

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.

1,810 Views
kaslewis
Contributor III

Thank you for confirming my thoughts

Kas

0 Kudos
Reply