Skip to main content
ced seg
Associate
June 12, 2019
Solved

How to read multiple GPIO simultaneously? [solved]

  • June 12, 2019
  • 4 replies
  • 7354 views

Hi guys,

Is it possible to read multiple gpio simultaneously? See part of my code below.

Thanks

while (1)

 {

 if ( (HAL_GPIO_ReadPin(IN_1_GPIO_Port, IN_1_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_2_GPIO_Port, IN_2_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_3_GPIO_Port, IN_3_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_4_GPIO_Port, IN_4_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_5_GPIO_Port, IN_5_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_6_GPIO_Port, IN_6_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_7_GPIO_Port, IN_7_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_8_GPIO_Port, IN_8_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_9_GPIO_Port, IN_9_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_10_GPIO_Port, IN_10_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_11_GPIO_Port, IN_11_Pin) == GPIO_PIN_SET)

 || (HAL_GPIO_ReadPin(IN_12_GPIO_Port, IN_12_Pin) == GPIO_PIN_SET))

 {

 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);

 }

 else

 {

 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);

 }

...

This topic has been closed for replies.
Best answer by S.Ma

Don't do like this. It will be very inefficient and possiblly generate more code to execute than needed.

GPIO registers are 16 bit wide, so PA0..PA15 bits are packed in a single register you can read in 1 shot.

GPIO input register is volatile, it changes over time from external events. take a snapshot, read the register once, put in a local variable then bit mask.

Don't re-rename things, you will make understanding of your code more indirect in a dialect code only you will understand.

Make your code intuitive with minimum dependency.

Digging the code, say you want to check if PA0, PA2, PA5, PA9 any one of these pin to be high level:

if(GPIO->IDR & 0b1000100101)
 {
 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
 }
 else
 {
 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
 } 

If the pins are from differnet ports, group them by port name. There maybe a HAL function to wrap read IDR, don't remember...

4 replies

Tesla DeLorean
Guru
June 12, 2019

uint16_t foo = GPIOD->IDR; // bit 0 thru 15 reflect PD0 thru PD15

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
S.Ma
S.MaBest answer
Principal
June 12, 2019

Don't do like this. It will be very inefficient and possiblly generate more code to execute than needed.

GPIO registers are 16 bit wide, so PA0..PA15 bits are packed in a single register you can read in 1 shot.

GPIO input register is volatile, it changes over time from external events. take a snapshot, read the register once, put in a local variable then bit mask.

Don't re-rename things, you will make understanding of your code more indirect in a dialect code only you will understand.

Make your code intuitive with minimum dependency.

Digging the code, say you want to check if PA0, PA2, PA5, PA9 any one of these pin to be high level:

if(GPIO->IDR & 0b1000100101)
 {
 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
 }
 else
 {
 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
 } 

If the pins are from differnet ports, group them by port name. There maybe a HAL function to wrap read IDR, don't remember...

waclawek.jan
Super User
June 12, 2019

In the particular case if you want to check if any pin of a set of pins of the same port is nonzero, you can use

if (HAL_GPIO_ReadPin(THE_COMMON_GPIO_Port, IN_1_Pin | IN_2_Pin | IN_3_Pin | IN_4_Pin) == GPIO_PIN_SET) { 
 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 1);
 } else {
 HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, 0);
 }

although it is not intended by Cube/HAL authors, and I wouldn't recommend this usage.

It will even pass the IS_GPIO_PIN() assertion, given how sloppily is it written.

JW

ced seg
ced segAuthor
Associate
June 13, 2019

Hi guys,

Thank you all for your help. Your solution makes sense, and works perfectly.

Just to understand why it doesn't work like i thought at first, is it specific to HAL library or my first idea, reading multiple GPIO, was a terrible behaviour (poor code optimisation, etc.)?

Thanks again,

CS.