cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7: why some specific GPIO pins don't work?

Wowa
Associate III

Hello everyone,

I'm using USART3 on F746, but only RX/TX pins which are mapped to pins PD8/PD9.

Besides that, I want to configure general output to pins PD10/PD11 (to control LEDs), but they don't work when I try to control them. I looked up the AF mapping for the chip and can see that these pins fall into "USART pin domain" (PD10 = USART3_CK, PD11 = USART3_CTS). Can this prevent me from using them as GPIO_MODE_OUTPUT_PP? Is this documented in any paper? Because I didn't find any such limitations in reference/datasheet and thought that I might program those independently.

Thanks!

Vladimir

1 ACCEPTED SOLUTION

Accepted Solutions

Couldn't confirm.

Tried on a 'F746 DISCO. Enabled GPIOD in RCC, set MODER to 0x1a0000 (i.e. PD10 to Out, PD9 and PD8 to AF), set AFR[1] to 0x777 (i.e. all three pins to USART3). Enabled USART3 in RCC, set CR2.CLKEN and CR1.TE/RE/UE. As expected, wiggling bit 10 of GPIOD.ODR was reflected by bit 10 of GPIOD.IDR (PD10 is not exposed on the Disco, unfortunately), regardless of the AFR[1] setting.

Please post the readout of GPIOD registers with the modification; try to revert the modification, make sure that reproduces the problem and post then that readout of GPIOD registers, too.

@Mike_ST,

can you please clarify your comment.​ 

Thanks,

JW

View solution in original post

9 REPLIES 9
Mike_ST
ST Employee

>> Can this prevent me from using them as GPIO_MODE_OUTPUT_PP?

No, just make sure to enable clock on GPIOD and set alternate value to 0 for PD10/PD11.

@Mike_ST​ ,

> set alternate value to 0

What is "alternate value" and why would it have to be 0?

JW

Wowa,

read out and check content of relevant GPIO registers.

Is this your own board? Are *all* VDD and VSS/GND connected? If this is some of the devboards (Nucleo, Disco, Eval), are all jumpers/solder bridges to these pins disconnected?

JW

UPD: I found a bug in my code later, so it turned out that there is no need in any modifications in HAL_GPIO_Init() function. Explained this in the other post below.

---------------------------------------------------------------

Thank you, that was it!

For those who might get into this too: the matter is that HAL_GPIO_Init() function sets AFR registers only if GPIO_Init->Mode == GPIO_MODE_AF_... . But it does not reset them if you ask it to set up non-AF mode!

So, I just added to this part of HAL_GPIO_Init():

/*--------------------- GPIO Mode Configuration ------------------------*/
      /* In case of Alternate function mode selection */
      if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
      {
        /* Check the Alternate function parameter */
        assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
        
        /* Configure Alternate function mapped with the current IO */
        temp = GPIOx->AFR[position >> 3];
        temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;
        temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4));
        GPIOx->AFR[position >> 3] = temp;
      }

an 'else' section to make it:

/*--------------------- GPIO Mode Configuration ------------------------*/
      /* In case of Alternate function mode selection */
      if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
      {
        /* Check the Alternate function parameter */
        assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
        
        /* Configure Alternate function mapped with the current IO */
        temp = GPIOx->AFR[position >> 3];
        temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;
        temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4));
        GPIOx->AFR[position >> 3] = temp;
      } else {
        /* !!! No AF required - set Alternate function for current IO to 0 !!! */
        temp = GPIOx->AFR[position >> 3];
        temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;
        GPIOx->AFR[position >> 3] = temp;
      }

I got it solved, at least the LED is now on.

Yes, it's our self-developed board, all those are connected, seems that the reason was really in AFR regs, see my post above. Thank you for your reply!

This does not make sense - as long as the respective MODER bits are set to Out, the AF ought to be ignored.

If this is not the case, it's a hardware bug.

Can you please read out the GPIOD registers before the modification and after it?

Thanks,

JW

Wowa
Associate III

I just gave out the board to a colleague, but will try this tomorrow. Still, the LED is working. I checked errata on this chip today, there are no GPIO issues there. Interestingly...

Couldn't confirm.

Tried on a 'F746 DISCO. Enabled GPIOD in RCC, set MODER to 0x1a0000 (i.e. PD10 to Out, PD9 and PD8 to AF), set AFR[1] to 0x777 (i.e. all three pins to USART3). Enabled USART3 in RCC, set CR2.CLKEN and CR1.TE/RE/UE. As expected, wiggling bit 10 of GPIOD.ODR was reflected by bit 10 of GPIOD.IDR (PD10 is not exposed on the Disco, unfortunately), regardless of the AFR[1] setting.

Please post the readout of GPIOD registers with the modification; try to revert the modification, make sure that reproduces the problem and post then that readout of GPIOD registers, too.

@Mike_ST,

can you please clarify your comment.​ 

Thanks,

JW

Thank you for your efforts to help me with this! Today I tried to reproduce it, but didn't succeed as well. You were right, it works without modification either. I rolled back to the code that didn't work and finally found out the real reason for that failure. It happened so that besides my modification to HAL_GPIO_Init() there was another code change made at the same moment. And the glitch that caused problem was trivial misuse of logical OR (||) instead of binary one (|) trying to set two bits of one port at once (like this:  GPIO_InitStruct.Pin = nLedD_Pin || nLedR_Pin;). So it was totally my fault from the very beginning, sorry for bothering!