Skip to main content
Visitor II
August 10, 2019
Question

STM32H7 PVD not interrupting

  • August 10, 2019
  • 9 replies
  • 3166 views

Hi,

I want to get the PVD on a STM32H743 running in order to write some data to the flash, which did not work for whatever reason. So, as a first step, I tried to implement an interrupt which just pulls a GPIO-pin high and check it with an oscilloscope. I configured "PVD Level 6" (2.85V) and "External Interrupt Mode with Rising Edge Trigger Detection" in CubeMX, and implemented HAL_PWR_PVDCallback() with a GPIO_Write. However, when I disconnect the power supply, the pin is not being pulled high. The duration in which the power drops from 2.85V to 1.6V is approx. 10ms, which I guess should be plenty of time to process the interrupt. I can fire the interrupt with a software trigger (SWIER1) on EXTI line 16 successfully, which tells me that the EXTI interrupt is working in principle. I also checked that PVDE in PWR_CR1 is enabled, as well as the PLS bits for the threshold.

The following code was generated by CubeMX in stm32h7xx_hal_msp.c:

void HAL_MspInit(void)
{
 /* USER CODE BEGIN MspInit 0 */
 
 /* USER CODE END MspInit 0 */
 PWR_PVDTypeDef sConfigPVD = {0};
 
 __HAL_RCC_SYSCFG_CLK_ENABLE();
 
 /* System interrupt init*/
 /* PendSV_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
 
 /* Peripheral interrupt init */
 /* PVD_AVD_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(PVD_AVD_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(PVD_AVD_IRQn);
 
 /** PVD Configuration 
 */
 sConfigPVD.PVDLevel = PWR_PVDLEVEL_7;
 sConfigPVD.Mode = PWR_PVD_MODE_IT_RISING;
 HAL_PWR_ConfigPVD(&sConfigPVD);
 /** Enable the PVD Output 
 */
 HAL_PWR_EnablePVD();
 
 /* USER CODE BEGIN MspInit 1 */
 
 /* USER CODE END MspInit 1 */
}

Unfortunately I can't change the supply voltage other than disconnecting it, which makes it hard to check the registers at the time PVD is supposed to detect the power drop.

Is there anything I missed or misunderstood?

    This topic has been closed for replies.

    9 replies

    Visitor II
    April 10, 2021

    Hi,

    did you resolve?

    I have the same problem running an STM32F429NI board.

    I'm trying the same code as above (I'm also calling __HAL_RCC_PWR_CLK_ENABLE prior to set PVD registers).

    No matter what, the interrupt is not triggering (in the ISR I'm driving a GPIO to high level, but I'm not able to see it changing the status). As MaxMax, I can fire the interrupt with a software trigger (SWIER1) on EXTI line 16 successfully, which tells me that the EXTI interrupt is working in principle.

    VDD and VDDA are on the same power bus, and it takes approximately 4.2ms to drop from 3V to 1.8V (I'm running 160Mhz clock, so 4ms should be enough to move a GPIO).

    0693W000008zBS0QAM.pngAny clue?

    Super User
    April 10, 2021

    Read out and check/post content of PWR_CR.

    Running a trivial program, which after setup does nothing but in a loop checks PWR_CSR.PVDO and e.g. outputs its value to a pin, should also indicate whether this flag gets active upon power going down.

    You may also try disconnect the power supply and use a regulated power supply to try to set the lower voltage level deliberately.

    Do you use Brownout Detection (i.e. what's the value of FLASH_OPTCR.BOR_LEV)?

    JW

    Visitor II
    April 11, 2021

    Hi, thanks for the support and the advices.

    So, here is my full code.

    int main(void)
    {
     uint32_t registers[4];
     PWR_PVDTypeDef config = { 0 };
     GPIO_InitTypeDef init = { 0 };
     RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
     RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
     
     __HAL_RCC_GPIOH_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_SYSCFG_CLK_ENABLE();
     __HAL_RCC_PWR_CLK_ENABLE();
     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
     __HAL_FLASH_DATA_CACHE_ENABLE();
     __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
     
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
     RCC_OscInitStruct.PLL.PLLM = 8;
     RCC_OscInitStruct.PLL.PLLN = 160;
     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
     RCC_OscInitStruct.PLL.PLLQ = 4;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
     
     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
     |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
     
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
     {
     Error_Handler();
     }
     
     memset (&config, 0x00, sizeof (config));
     
     config.Mode = PWR_PVD_MODE_IT_RISING_FALLING;
     config.PVDLevel = PWR_CR_PLS_LEV7;
     
     HAL_PWR_ConfigPVD (&config);
     
     HAL_PWR_EnablePVD ();
     
     HAL_NVIC_SetPriority (PVD_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ (PVD_IRQn);
     
     SystemClock_Config();
     
     init.Pin = GPIO_PIN_12;
     init.Mode = GPIO_MODE_OUTPUT_PP;
     init.Pull = GPIO_NOPULL;
     init.Speed = GPIO_SPEED_FREQ_LOW;
     
     HAL_GPIO_Init(GPIOA, &init);
     
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
     
     __enable_irq();
     
     registers[0] = PWR->CR;
     registers[1] = EXTI->IMR;
     registers[2] = EXTI->FTSR;
     registers[3] = EXTI->RTSR;
     
     (void) registers;
     
     while (1)
     {
     if (PWR->CSR & PWR_CSR_PVDO)
     {
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
     }
     else
     {
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
     }
     }
    }

    1) contents of PWR_CR and EXTI registers seems correct.

    0693W000008zC6UQAU.png0693W000008zC8zQAE.png0693W000008zC9JQAU.png2) I'm checking PVDO output using GPIO but it's not moving. Flag never gets active;

    3) Brownout is disabled

    0693W000008zCAMQA2.png 

    4) my last chance, trying to bypass switching power circuit of the board and using a regulated power supply directly connected to VDD/VDDA. I'll give it a try, but I think I will not resolve.

    Visitor II
    April 12, 2021

    I've tried also using regulated power supply (3v3). It seems that CPU is resetting almost immediatly as voltage drop down to 3V: shouldn't be 1V8?

    I'll try an EVB, maybe it's an hardware problem of my board.

    Visitor II
    April 12, 2021

    With NUCLEO F429ZI seems to work. I think I should investigate on my board.

    Super User
    April 12, 2021

    OK, please let us know of your findings.

    JW

    Visitor II
    April 12, 2021

    My bad,

    I've just realized that on the board, on the MCU_RESET line there is a LM809M3-3.08 chip that is resetting my MCU @ 3.08V : )3

    Super User
    April 12, 2021

    Thanks for coming back with the solution.

    Please select your post as Best so that the thread can be marked as solved.

    JW

    Graduate II
    November 6, 2024

    Is there any tutorial on PVD? I looked for one but I could not find. I am using a STM32H7. I enabled PVD on the .ioc file.

     

    eduardo_reis_0-1730930655549.png

     

    Then, on the initialization, I do this:

     

     PWR_PVDTypeDef pvd_config{PWR_PVDLEVEL_6, PWR_PVD_MODE_IT_FALLING};
     HAL_PWR_ConfigPVD(&pvd_config);
     HAL_PWR_EnablePVD();

     

    And I defined this on main.c

     

    void HAL_PWR_PVDCallback(){
     // some code here.
    }

     

    But, the interrupt callback is not being called. Is there someone that could help on this?