How to read GPIO direction using HAL?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-06-12 12:18 AM
Hello world,
I'm developing a FW for STM32F107VCT6 which can change GPIO direction programmatically: there is a terminal command which can switch individually 7 pins* mapped on different ports between GPIO_MODE_OUTPUT_PP \ GPIO_MODE_INPUT.
I'm wondering if is there a way to read GPIO direction using STM32 HAL the same way I use HAL_GPIO_ReadPin for the status.
Since the code is completely written pointing the resources with an header file which defines are used to feed HAL drivers calls, I don't want to write just for this code which dive down to GPIOx_CRL/H MODEx pins....is there a more straightforward way?
Thanks
*: Pin listed below
#define EXP6_Pin GPIO_PIN_8
#define EXP6_GPIO_Port GPIOB
#define EXP5_Pin GPIO_PIN_9
#define EXP5_GPIO_Port GPIOB
#define EXP4_Pin GPIO_PIN_10
#define EXP4_GPIO_Port GPIOC
#define EXP3_Pin GPIO_PIN_11
#define EXP3_GPIO_Port GPIOC
#define EXP2_Pin GPIO_PIN_5
#define EXP2_GPIO_Port GPIOA
#define EXP1_Pin GPIO_PIN_6
#define EXP1_GPIO_Port GPIOA
#define EXP0_Pin GPIO_PIN_7
#define EXP0_GPIO_Port GPIOA
Solved! Go to Solution.
- Labels:
-
GPIO-EXTI
-
STM32F1 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-06-13 1:41 AM
Uhm, thanks for the answer. After about half an hour of very hard coding I solved the way below.
I don't like that manual define of EXPx_Dir (where I extract the MODE values) in particular I don'ìt like the fact that can't be derived from the .ioc automatically generated code in a straightforward way, i could spare some time to use EXPx_Pin and EXPx_GPIO_Port to displace automatically the EXPx_Dir read but the reuse of that code is not to high to justify the effort.
Thanks for your support,
LG
.H:
...
#define EXP6_Pin GPIO_PIN_8
#define EXP6_GPIO_Port GPIOB
#define EXP5_Pin GPIO_PIN_9
#define EXP5_GPIO_Port GPIOB
#define EXP4_Pin GPIO_PIN_10
#define EXP4_GPIO_Port GPIOC
#define EXP3_Pin GPIO_PIN_11
#define EXP3_GPIO_Port GPIOC
#define EXP2_Pin GPIO_PIN_5
#define EXP2_GPIO_Port GPIOA
#define EXP1_Pin GPIO_PIN_6
#define EXP1_GPIO_Port GPIOA
#define EXP0_Pin GPIO_PIN_7
#define EXP0_GPIO_Port GPIOA
...
#define EXP0_Dir (GPIOA->CRL>>28) & 0b11 //GPIOA.7
#define EXP1_Dir (GPIOA->CRL>>24) & 0b11 //GPIOA.6
#define EXP2_Dir (GPIOA->CRL>>20) & 0b11 //GPIOA.5
#define EXP3_Dir (GPIOC->CRH>>12) & 0b11 //GPIOC.11
#define EXP4_Dir (GPIOC->CRH>>8) & 0b11 //GPIOC.10
#define EXP5_Dir (GPIOB->CRH>>4) & 0b11 //GPIOB.9
#define EXP6_Dir (GPIOB->CRH) & 0b11 //GPIOB.8
...
.C:
...
struct expbus_struct{
GPIO_TypeDef* port[7];
uint16_t pin[7];
uint8_t dir[7];
} expbus = {{EXP0_GPIO_Port,EXP1_GPIO_Port,EXP2_GPIO_Port,EXP3_GPIO_Port,EXP4_GPIO_Port,EXP5_GPIO_Port,EXP6_GPIO_Port},{EXP0_Pin,EXP1_Pin,EXP2_Pin,EXP3_Pin,EXP4_Pin,EXP5_Pin,EXP6_Pin}};
...
char expr (uint8_t ch){
uint8_t dir=0, val=0;
switch(ch){
case 0:
if (EXP0_Dir) dir=1;
break;
case 1:
if (EXP1_Dir) dir=1;
break;
case 2:
if (EXP2_Dir) dir=1;
break;
case 3:
if (EXP3_Dir) dir=1;
break;
case 4:
if (EXP4_Dir) dir=1;
break;
case 5:
if (EXP5_Dir) dir=1;
break;
case 6:
if (EXP6_Dir) dir=1;
break;
}
if(HAL_GPIO_ReadPin(expbus.port[ch],expbus.pin[ch])==GPIO_PIN_SET) val=1;
if (dir && val) return 'H'; //out hi
else if (dir && !val) return 'L'; //out lo
else if (!dir && !val) return '0'; //in lo
else return '1'; //in hi (default)
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-06-12 3:11 AM
Welcome, @Luca Gallucci, to the community!
Well, compared to reading a GPIO, querying the current data flow direction occurs rather rarely. However, it should be easy to query via GPIO->CTL or GPIO->CTH and branch accordingly, even for several pins at the same time.
Regards
/Peter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-06-12 4:56 PM
> is there a more straightforward way?
A global variable which keeps track of how the pins have been defined, perhaps. STM32Cube doesn't really support changing pin functionality so it's not surprising there isn't an appropriate HAL call.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2023-06-13 1:41 AM
Uhm, thanks for the answer. After about half an hour of very hard coding I solved the way below.
I don't like that manual define of EXPx_Dir (where I extract the MODE values) in particular I don'ìt like the fact that can't be derived from the .ioc automatically generated code in a straightforward way, i could spare some time to use EXPx_Pin and EXPx_GPIO_Port to displace automatically the EXPx_Dir read but the reuse of that code is not to high to justify the effort.
Thanks for your support,
LG
.H:
...
#define EXP6_Pin GPIO_PIN_8
#define EXP6_GPIO_Port GPIOB
#define EXP5_Pin GPIO_PIN_9
#define EXP5_GPIO_Port GPIOB
#define EXP4_Pin GPIO_PIN_10
#define EXP4_GPIO_Port GPIOC
#define EXP3_Pin GPIO_PIN_11
#define EXP3_GPIO_Port GPIOC
#define EXP2_Pin GPIO_PIN_5
#define EXP2_GPIO_Port GPIOA
#define EXP1_Pin GPIO_PIN_6
#define EXP1_GPIO_Port GPIOA
#define EXP0_Pin GPIO_PIN_7
#define EXP0_GPIO_Port GPIOA
...
#define EXP0_Dir (GPIOA->CRL>>28) & 0b11 //GPIOA.7
#define EXP1_Dir (GPIOA->CRL>>24) & 0b11 //GPIOA.6
#define EXP2_Dir (GPIOA->CRL>>20) & 0b11 //GPIOA.5
#define EXP3_Dir (GPIOC->CRH>>12) & 0b11 //GPIOC.11
#define EXP4_Dir (GPIOC->CRH>>8) & 0b11 //GPIOC.10
#define EXP5_Dir (GPIOB->CRH>>4) & 0b11 //GPIOB.9
#define EXP6_Dir (GPIOB->CRH) & 0b11 //GPIOB.8
...
.C:
...
struct expbus_struct{
GPIO_TypeDef* port[7];
uint16_t pin[7];
uint8_t dir[7];
} expbus = {{EXP0_GPIO_Port,EXP1_GPIO_Port,EXP2_GPIO_Port,EXP3_GPIO_Port,EXP4_GPIO_Port,EXP5_GPIO_Port,EXP6_GPIO_Port},{EXP0_Pin,EXP1_Pin,EXP2_Pin,EXP3_Pin,EXP4_Pin,EXP5_Pin,EXP6_Pin}};
...
char expr (uint8_t ch){
uint8_t dir=0, val=0;
switch(ch){
case 0:
if (EXP0_Dir) dir=1;
break;
case 1:
if (EXP1_Dir) dir=1;
break;
case 2:
if (EXP2_Dir) dir=1;
break;
case 3:
if (EXP3_Dir) dir=1;
break;
case 4:
if (EXP4_Dir) dir=1;
break;
case 5:
if (EXP5_Dir) dir=1;
break;
case 6:
if (EXP6_Dir) dir=1;
break;
}
if(HAL_GPIO_ReadPin(expbus.port[ch],expbus.pin[ch])==GPIO_PIN_SET) val=1;
if (dir && val) return 'H'; //out hi
else if (dir && !val) return 'L'; //out lo
else if (!dir && !val) return '0'; //in lo
else return '1'; //in hi (default)
}
