cancel
Showing results for 
Search instead for 
Did you mean: 

USB: how to manage disconnect and re-connect the cable

bruzzim
Associate II
Posted on December 01, 2014 at 09:48

Hello all,

my application is based on stm32l152, I use StdPeriph_Driver and STM32_USB-FS-Device_Driver.

USB transfer works fine until I disconnect usb cable. After disconnecting the firmware stuck running just interrupt drivers, the main stops suddenly.

After reconnecting cable main program get to work but the usb PC connection is cannot be estabilished. 

What operations should I do just after removing usb cable in order to make everything works?

Kind regards

2 REPLIES 2
bruzzim
Associate II
Posted on December 01, 2014 at 11:31

I want to detail a little bit more my application. I have two states: 

- low speed, low power, MSI clocked (64KHz clock)

- high speed (when USB cable is connected to PC)

these are the functions I use to switch speed:

void SYSCLKConfig_SLOW(void)

{

  if (IsFast)

  {

    Usb_Disable();

    Flash_Sleep();

    XRAM_Sleep();    

    Spi_Disable(); // spengo il consumo da MISO di SPI1 e SPI2

    

    // disabilito il systick 

    SysTick_Disable();

    

    /* Disable Prefetch Buffer */

    FLASH_PrefetchBufferCmd(DISABLE);

  

    /* Disable 64-bit access */

    FLASH_ReadAccess64Cmd(DISABLE);

  

    /* Enable the PWR APB1 Clock */

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

    

    /* Select the Voltage Range 2 (1.5V) */

    PWR_VoltageScalingConfig(PWR_VoltageScaling_Range2);

    

    /* Wait Until the Voltage Regulator is ready */

    while(PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET)

      {

      }

          

    /* HCLK = SYSCLK/2 = ~32KHz */

    RCC_HCLKConfig(RCC_SYSCLK_Div2);

  

    /* PCLK2 = HCLK */

    RCC_PCLK2Config(RCC_HCLK_Div1);

  

    /* PCLK1 = HCLK */

    RCC_PCLK1Config(RCC_HCLK_Div1);

  

    RCC_MSICmd(ENABLE);

  

    RCC_WaitForMSIStartUp();

  

    /* Set MSI clock range to 65.536KHz */

    RCC_MSIRangeConfig(RCC_MSIRange_0);

    

    /* Select MSI as system clock source */

    RCC_SYSCLKConfig(RCC_SYSCLKSource_MSI);

  

    /* Wait till PLL is used as system clock source */

    while (RCC_GetSYSCLKSource() != 0x00)

      {} 

  

    /* Flash 0 wait state */

    FLASH_SetLatency(FLASH_Latency_0);

  

    // disable PLL  

    //RCC_PLLCmd(DISABLE);

  

    // disable HSE Clock

    RCC_HSEConfig(RCC_HSE_OFF);

    

    /* Enter RUN LP Mode */

    PWR_EnterLowPowerRunMode(ENABLE);

  

    /* Wait until the system enters RUN LP and the Regulator is in LP mode */

    while(PWR_GetFlagStatus(PWR_FLAG_REGLP) == RESET)

      {

      }

  

    SystemCoreClockUpdate();

    /* SysTick end of count event each 10ms

    RCC_GetClocksFreq(&RCC_Clocks);

    SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

    */

    /* SysTick end of count event each SYSTICK_PERIOD ms */

    SysTick_Config((SystemCoreClock / 1000) * SYSTICK_PERIOD);

  

#ifndef __DEBUG_LOCAL_ON

    Usart_Local_Disable();

#endif

  //  while(1);

 

    IsFast = 0;

  }

}

void SYSCLKConfig_USB(void)

{

  if (IsFast == CLOCK_SPEED_USB) return;

  // disabilito il systick 

  SysTick_Disable();

  

  /* Enable the PWR APB1 Clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  /* Exit the RUN LP Mode */

  PWR_EnterLowPowerRunMode(DISABLE);

  

  /* Wait until the system exits RUN LP and the Regulator is in main mode */

  while(PWR_GetFlagStatus(PWR_FLAG_REGLP) != RESET)

    {

    }   

  RCC_HSEConfig(RCC_HSE_ON);

  RCC_WaitForHSEStartUp(); // okkio gestire il caso di clock non funzionante

  // Flash access

  FLASH_ReadAccess64Cmd(ENABLE);

  FLASH_SetLatency(FLASH_Latency_1);

  FLASH_PrefetchBufferCmd(ENABLE);

  // HCLK = SYSCLK 

  RCC_HCLKConfig(RCC_SYSCLK_Div1);

  // VOS 1.8

  PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1);

  while(PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) {}

    /* HCLK = SYSCLK /1*/

    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

  

    /* PCLK2 = HCLK /1*/

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

    

    /* PCLK1 = HCLK /1*/

    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

    

    /*  PLL configuration */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |

                                        RCC_CFGR_PLLDIV));

    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL12 | RCC_CFGR_PLLDIV3);

    /* Enable PLL */

    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */

    while((RCC->CR & RCC_CR_PLLRDY) == 0)

    {

    }

        

    /* Select PLL as system clock source */

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;

    /* Wait till PLL is used as system clock source */

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)

    {

    }

  SystemCoreClockUpdate();

  /* SysTick end of count event each 10 ms

  RCC_GetClocksFreq(&RCC_Clocks);

  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

  */

  /* SysTick end of count event each SYSTICK_PERIOD ms */

  SysTick_Config((SystemCoreClock / 1000) * SYSTICK_PERIOD);

  Spi_Enable(); // riabilito MISO di SPI1 e SPI2

  

  Usb_Init();

  IsFast = CLOCK_SPEED_USB;

}

 

bruzzim
Associate II
Posted on December 01, 2014 at 14:57

I see that as soon as I remove USB cable, the main program keeps working but the RTC second interrupt (RTC_WKUP_IRQHandler) is no more executed.