cancel
Showing results for 
Search instead for 
Did you mean: 

Remote wakeup on STM32F0

pretoriandave
Associate

Trying to implement a composite HID device on STM32F042 (or maybe STM32F072 as both Flash and RAM usage seem insane), starting from the MX mouse middleware. After much scratching around it's finally working as a mouse and keyboard and I now need to add remote wakeup from a few buttons. Unfortunately the middleware has no support for it, nor any hints as to how to implement it. There are a number of posts on here in a similar vain but none really provide any solutions.

I'm experienced with HID implementations on much simpler 8-bit devices (Cypress) of the 'bare metal' variety and am finding using other people's muddleware very hard going. Not a spelling mistake, by the way.

I have so far managed to get the f/w to wake up on the press of a single button by adding a bit of code to

HAL_PCD_SuspendCallback...

{

/* Inform USB library that core enters in suspend Mode. */

USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);

/* Enter in STOP mode. */

/* USER CODE BEGIN 2 */

if (hpcd->Init.low_power_enable)

{

  HAL_GPIO_WritePin(GPIOB,LED_1_Pin,0);                            //turn off LED to save power (new)

  SYSCFG->EXTICR[2] |= (SYSCFG_EXTICR2_EXTI6_PA);    //enable EXTI lines (new)

  EXTI->IMR |= (EXTI_IMR_MR6);                                              //Configure corresponding IMR register bits (new)

  EXTI->FTSR |= (EXTI_FTSR_TR6);                                          //and make them falling edge triggered (new)

  NVIC_SetPriority(EXTI4_15_IRQn,0);                                        //Set to low priority (new)

  NVIC_EnableIRQ(EXTI4_15_IRQn);                                           //turn on interrupt on lines 4 and above (new)

  /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */

  SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); //and finally go to sleep

}

/* USER CODE END 2 */

}

 

Then in HAL_PCD_ResumeCallback I've included....

NVIC_DisableIRQ(EXTI4_15_IRQn);

in case the wakeup is due to bus activity, otherwise the interrupt would stay enabled in this event.

 

Finally, I've created an ISR for the relevant EXTI lines to handle the button press while suspended....

void EXTI4_15_IRQHandler(void)

{

  NVIC_DisableIRQ(EXTI4_15_IRQn);                                          //Turn off interrupt on lines 4 and above

  NVIC_ClearPendingIRQ(EXTI4_15_IRQn);                                //Clear the interrupt flag.

 

  HAL_PCD_ActivateRemoteWakeup(&hpcd_USB_FS);             //Now do wakeup signalling for 10ms

  HAL_Delay(10);

  HAL_PCD_DeActivateRemoteWakeup(&hpcd_USB_FS);

}

 

 

Then in HAL_PCD_ResumeCallback I've included....

NVIC_DisableIRQ(EXTI4_15_IRQn);

in case the wakeup is due to bus activity, otherwise the interrupt would stay enabled in this event.

 

Finally, I've created an ISR for the relevant EXTI lines to handle the button press while suspended....

void EXTI4_15_IRQHandler(void)

{

  NVIC_DisableIRQ(EXTI4_15_IRQn);                                          //Turn off interrupt on lines 4 and above

  NVIC_ClearPendingIRQ(EXTI4_15_IRQn);                                //Clear the interrupt flag.



  HAL_PCD_ActivateRemoteWakeup(&hpcd_USB_FS);             //Now do wakeup signalling for 10ms

  HAL_Delay(10);

  HAL_PCD_DeActivateRemoteWakeup(&hpcd_USB_FS);

}

The result is a piece of code that does wake up the host on button press but does not then respond to any Control pipe activity. I'm guessing there's more to be done in the IRQHandler - maybe USBD_LL_Resume, or perhaps something needs to be done to re-enable clocks after the deep sleep?

 

Any insight would be greatly appreciated. Thanks community



1 REPLY 1
Andrew Neil
Evangelist III

Please use this button to properly post source code:

AndrewNeil_0-1709218952222.png