cancel
Showing results for 
Search instead for 
Did you mean: 

How to read multiple GPIO simultaneously? [solved]

ced seg
Associate II

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);

 }

...

1 ACCEPTED SOLUTION

Accepted Solutions
S.Ma
Principal

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...

View solution in original post

4 REPLIES 4

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

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...

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
Associate II

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.