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.
2023-06-13 01: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)
}
2023-06-12 03: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
2023-06-12 04: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.
2023-06-13 01: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)
}