cancel
Showing results for 
Search instead for 
Did you mean: 

How to read GPIO direction using HAL?

Spaghetto
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions
Spaghetto
Associate III

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

View solution in original post

3 REPLIES 3
Peter BENSCH
ST Employee

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

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".
Spaghetto
Associate III

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