cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L151 USB - What actually switches PA11/PA12 from GPIO to USB?

jcwren
Associate
Posted on August 20, 2012 at 20:06

I have a design that was switched from an STM32F103ZDT6 to a STM32L151ZDT6. On the 'F103, the USB functioned perfectly, but on the 'L151, I'm having trouble getting it going. 

Looking at all the various source in the STM32_USB-FS-Device_Lib_V3.4.0 files, NOWHERE does it ever set GPIO_AF_USB to configure PA11/PA12 from GPIO to USB. As near as I can tell, it appears that this may happen as soon as the RCC_APB1ENR_USBEN bit is set in RCC_APB1ENR.

Is this actually the case? If so, I cannot find ANY references in the documentation that GPIO_AF_USB in the GPIOx_AFR registers, along with GPIO_Mode_AF and the various pull-up/pull-down bits do not need to be set for the USB peripheral.

If this is the case, why does GPIO_AF_USB in the GPIOx_AFR registers even exist?

--jc

#stm32l151-usb-pa11-pa12
11 REPLIES 11
Posted on August 20, 2012 at 20:52

A cursory review of the manual, and the code, suggest the pins are not being set up.

The default reset values for MODER and AFRH do not route USB.

For the AF mux to work the GPIOA clock will need to be enabled, the pins configured to AF, and the AF mux set to 10 (GPIO_AF_USB)
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
gafsos
Associate II
Posted on August 21, 2012 at 00:27

In  STM32L products no need to put PA11/PA12 data lines as “AF�?

Other, sould be set

I have a design that was switched from an STM32F103ZDT6 to a STM32L151ZDT6. On the 'F103, the USB functioned perfectly, but on the 'L151, I'm having trouble getting it going. 

Looking at all the various source in the STM32_USB-FS-Device_Lib_V3.4.0 files, NOWHERE does it ever set GPIO_AF_USB to configure PA11/PA12 from GPIO to USB. As near as I can tell, it appears that this may happen as soon as the RCC_APB1ENR_USBEN bit is set in RCC_APB1ENR.

Is this actually the case? If so, I cannot find ANY references in the documentation that GPIO_AF_USB in the GPIOx_AFR registers, along with GPIO_Mode_AF and the various pull-up/pull-down bits do not need to be set for the USB peripheral.

If this is the case, why does GPIO_AF_USB in the GPIOx_AFR registers even exist?

--jc
jcwren
Associate
Posted on August 21, 2012 at 17:43

That's as I would believe, which makes me wonder how ANY of the USB example code would run on a 'L1xx part.

Everything is set up as I would expect it should be (and considering all my other peripherals work fine: SPI w/ DMA, I2C w/ DMA, USARTs, PWM, general GPIO, interrupts, etc). 

The AF mux is set, alternate functions selected, AHB and APBs enabled, I have a 12MHz HSE with an 8x PLL and /3 PLLDIV (system clock checked on MCO pin, 32MHz), so there's a 48MHz clock available to the USB SEI. I have an external USB 1.5K pull-up left over from the 'F103 design, and when I enable it or the built-in 1.5K pull-up, the DP line barely moves off of ground. It's like the I/O pins are driving low, and staying that way. 

This may seem like a silly question, but has anyone actually ever SEEN a 'L151 designed that implemented USB? 'cause it's about to be ''Call the FAE time''.

arnaud239955
Associate II
Posted on October 04, 2015 at 16:01

Hello All,

I have exactly this problem on the STM32L151CC.

I need to make my device sleeping in STOP mode. To reduce the power consumption I turn the GPIO clock off and I set the GPIO in analog mode. I works perfect (a few uA consumption), but leaving the stop mode on interrupt, I am not able to turn the USB PA11 & PA12 pins back to USB mode. I suppose also that the MUX of alternate functions is not properly set, but I have not found in documentation how to set AF_USB on the mux on L151CC.

My code executed on stop mode exit (in the interrupt handler):

  /* GPIO Ports Clock Enable */

  __GPIOC_CLK_ENABLE();

  __GPIOH_CLK_ENABLE();

  __GPIOA_CLK_ENABLE();

  __GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PA11 */

  GPIO_InitStruct.Pin = GPIO_PIN_11;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA12 */

  GPIO_InitStruct.Pin = GPIO_PIN_12;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Any advice is welcome.

Best regards

Zirco

Posted on October 04, 2015 at 16:16

What happens if you don't meddle with the analogue settings for PA11/PA12?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arnaud239955
Associate II
Posted on October 04, 2015 at 17:01

Thanks Clive1, I have followed your idea and tested two different implementations:

1/ I exclude the whole GPIOA port from analog mode : The  USB works correctly but in stop mode the current is 400 uA : It 40 times what I need to achieve (10 uA is my target)

2/ I exclude only GPIOA 11 and 12 from analog setup : The leak current in stop mode is 100 uA but curiously the USB is sometimes unreliable (I have to investigate)

Anyway, the current consumption is not appropriate to my application. I really need to turn off the USB pins in analog mode and turn them back to USB to achieve the consumption target. Any idea ?

Thanks a lot

Zirco

arnaud239955
Associate II
Posted on October 04, 2015 at 18:31

I did also the following code (see below), but without success. The USB pins are stuck in Analog mode. Impossible (?) to turn them back to USB.

void MX_GPIO_Init_Enter_Stop(void)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */

  __GPIOC_CLK_ENABLE();

  __GPIOH_CLK_ENABLE();

  __GPIOA_CLK_ENABLE();

  __GPIOB_CLK_ENABLE();

  /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */

    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 |

    GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |

    GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;

    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG ;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_All;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /*Configure GPIO pin : PC13 */

    GPIO_InitStruct.Pin = GPIO_PIN_13;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /*Configure GPIO pin : PA2 */

    GPIO_InitStruct.Pin = GPIO_PIN_2;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

    GPIO_InitStruct.Pull = GPIO_PULLDOWN;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /*Configure GPIO pin : PB5 */

    GPIO_InitStruct.Pin = GPIO_PIN_5;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* GPIO Ports Clock Disable */

    __GPIOC_CLK_DISABLE();

    __GPIOH_CLK_DISABLE();

    __GPIOA_CLK_DISABLE();

    __GPIOB_CLK_DISABLE();

}

void MX_GPIO_Init_Exit_Stop(void) {

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */

  __GPIOC_CLK_ENABLE();

  __GPIOH_CLK_ENABLE();

  __GPIOA_CLK_ENABLE();

  __GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PA11 */

  GPIO_InitStruct.Pin = GPIO_PIN_11;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  GPIO_InitStruct.Alternate = 10;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* Configure GPIO pin : PA12 */

  GPIO_InitStruct.Pin = GPIO_PIN_12;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  GPIO_InitStruct.Alternate = 10;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

The lack of information in the documentation is strange as JC mentioned above in the post...

Any idea ?

Thanks

Zirco

arnaud239955
Associate II
Posted on October 04, 2015 at 20:01

In my post (10/4/2015 5:01 PM) I said that I needed investigation on the case 2. In fact the USB communication doesn't work even the internal logic is activated. I did one additional test : I just set in analog mode the PA0 pin. The result is that USB communication is jeopardized by setting only one PIN of GPIOA in analog mode. Here is my code :

GPIO_InitStruct.Pin = GPIO_PIN_0;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

GPIO_InitStruct.Mode = GPIO_MODE_ANALOG ;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

It is really strange that setting only one PIN in analog mode on GPIOA kills all USB communications on pin PA11 and PA12. Is it normal ?

Thanks

Zirco

arnaud239955
Associate II
Posted on October 07, 2015 at 21:59

Hello All,

Here is the outcome of the story. I had some bugs in my code that led me to various false interpretations. Now, here is the code that works (current is around 50 uA with RTC and various pin listening events). I am happy with this solution. Any suggestion to improve is welcome.

Zirco

      /*** Start the procedure to switch to STOP mode ***/

      /* De-initialize the USB device */

      USBD_DeInit(&hUsbDeviceFS);

      /* Switch GPIO in Analog low current and stop GPIO clock */

      MX_GPIO_Init_Enter_Stop(); // See below

      /* Switch to ultra low power */

      HAL_PWREx_EnableUltraLowPower();

      HAL_PWREx_EnableFastWakeUp();

      /* Enter stop mode */

      HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

      /* Exit ultra low power */

      HAL_PWREx_DisableUltraLowPower();

// Executed at application startup

void

MX_GPIO_Init (void)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */

  __GPIOC_CLK_ENABLE()

  ;

  __GPIOH_CLK_ENABLE()

  ;

  __GPIOA_CLK_ENABLE()

  ;

  __GPIOB_CLK_ENABLE()

  ;

  /*Configure GPIO pin : PC13 */

  GPIO_InitStruct.Pin = GPIO_PIN_13;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init (GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PA2 */

  GPIO_InitStruct.Pin = GPIO_PIN_2;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLDOWN;

  HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PB5 */

  GPIO_InitStruct.Pin = GPIO_PIN_5;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init (GPIOB, &GPIO_InitStruct);

  /* EXTI interrupt init*/

  HAL_NVIC_SetPriority (EXTI2_IRQn, 5, 1);

  HAL_NVIC_EnableIRQ (EXTI2_IRQn);

  HAL_NVIC_SetPriority (EXTI15_10_IRQn, 5, 0);

  HAL_NVIC_EnableIRQ (EXTI15_10_IRQn);

  HAL_NVIC_SetPriority (EXTI9_5_IRQn, 5, 0);

  HAL_NVIC_EnableIRQ (EXTI9_5_IRQn);

}

/* USER CODE BEGIN 2 */

// Executed just before entry in Stop mode

void

MX_GPIO_Init_Enter_Stop (void)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */

  __GPIOC_CLK_ENABLE();

  __GPIOH_CLK_ENABLE();

  __GPIOA_CLK_ENABLE();

  __GPIOB_CLK_ENABLE();

  /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */

  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4

     | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9

     | GPIO_PIN_10 ;

  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

  HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_All & ~GPIO_PIN_3;

  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

  HAL_GPIO_Init (GPIOB, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_All & ~GPIO_PIN_14 & ~GPIO_PIN_15;

  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

  HAL_GPIO_Init (GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PC13 */

  GPIO_InitStruct.Pin = GPIO_PIN_13;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init (GPIOC, &GPIO_InitStruct);

  /* Configure GPIO pin : PA2 */

  GPIO_InitStruct.Pin = GPIO_PIN_2;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLDOWN;

  HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PB5 */

  GPIO_InitStruct.Pin = GPIO_PIN_5;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init (GPIOB, &GPIO_InitStruct);

  /* GPIO Ports Clock Disable */

  __GPIOC_CLK_DISABLE();

  __GPIOH_CLK_DISABLE();

  __GPIOA_CLK_DISABLE();

  __GPIOB_CLK_DISABLE();

}