2020-05-03 06:12 AM
Hello,
I'm not able to enable MR under-drive mode in my STM32F779NI chip.
The exact problem is UDRDY is not getting set -> Line number 39 to 43.
Below is the code snippet. Any suggestion would be very helpful. Thanks in advance.
int main(void)
{
/* Add your application code here */
__IO uint32_t tmpreg;
/* Enable clock for toggle LED */
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOIEN);
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOIEN);
/* Enable clock for switch input (EXTI) */
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
/* Enable clock for SYSCFG that connects switch to EXTI */
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);
/* Enable clock for PWR module */
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);
/* Configure toggle LED */
GPIOI->MODER |= GPIO_MODER_MODER15_0;
GPIOI->PUPDR |= GPIO_PUPDR_PUPDR15_0;
GPIOI->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR15;
GPIOI->BSRR= GPIO_BSRR_BS15; // Reset
/* Configure switch input */
GPIOC->PUPDR = 0;
GPIOC->MODER = 0;
SYSCFG->EXTICR[3] = 0x20;
EXTI->IMR = 0x2000;
EXTI->EMR = 0;
EXTI->RTSR = 0x2000;
NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 0));
NVIC_EnableIRQ(EXTI15_10_IRQn);
SET_BIT(PWR->CR1, PWR_CR1_MRUDS);
PWR->CR1 |= PWR_CR1_UDEN;
while( ! ((READ_BIT(PWR->CSR1, PWR_CSR1_UDRDY)) == PWR_CSR1_UDRDY ) );
/* Infinite loop */
while (1)
{
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* Ensure that all instructions done before entering SLEEP mode */
__DSB();
__ISB();
/* Request Wait For Interrupt */
__WFI();
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
}
}
Regards,
Bivin
Solved! Go to Solution.
2020-05-03 06:41 AM
It looks like UDRDY bits get set only when the CPU enters stop mode. You can check for and clear them after it wakes back up.
2020-05-03 06:41 AM
It looks like UDRDY bits get set only when the CPU enters stop mode. You can check for and clear them after it wakes back up.
2020-05-03 06:53 AM
Sorry. I overlooked this information. Thanks a lot ! :)
Regards
Bivin
2020-05-03 06:55 AM
But the HAL library for PWRex itself has a check wait loop for this flag field . But luckily with a timeout :grinning_face: .
HAL_StatusTypeDef HAL_PWREx_EnterUnderDriveSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
{
uint32_t tempreg = 0;
uint32_t tickstart = 0;
/* Check the parameters */
assert_param(IS_PWR_REGULATOR_UNDERDRIVE(Regulator));
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
/* Enable Power ctrl clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* Enable the Under-drive Mode ---------------------------------------------*/
/* Clear Under-drive flag */
__HAL_PWR_CLEAR_ODRUDR_FLAG();
/* Enable the Under-drive */
__HAL_PWR_UNDERDRIVE_ENABLE();
/* Get tick */
tickstart = HAL_GetTick();
/* Wait for UnderDrive mode is ready */
while(__HAL_PWR_GET_FLAG(PWR_FLAG_UDRDY))
{
if((HAL_GetTick() - tickstart ) > PWR_UDERDRIVE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
/* Select the regulator state in STOP mode ---------------------------------*/
tempreg = PWR->CR1;
/* Clear PDDS, LPDS, MRLUDS and LPLUDS bits */
tempreg &= (uint32_t)~(PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_LPUDS | PWR_CR1_MRUDS);
/* Set LPDS, MRLUDS and LPLUDS bits according to PWR_Regulator value */
tempreg |= Regulator;
/* Store the new value */
PWR->CR1 = tempreg;
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* Select STOP mode entry --------------------------------------------------*/
if(STOPEntry == PWR_SLEEPENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
}
else
{
/* Request Wait For Event */
__WFE();
}
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
return HAL_OK;
}