Столкнулся с такой проблемой.
Настроил COMP2 на внешние выводы (PA2/PA3) и COMP2_OUT yна PA7 для контроля.
Разрешены прерывания по возрастающему фронту
Если микроконтроллер в run mode, то прерывания работают как задумано. Если перейти в STOP, то прерывания почти не работают. Что проявляется следующим образом - иногда рандомно может произойти прерывание которое пробудит выводит микроконтроллер из STOP режима.
Вход в стоп реализован так:
#pragma inline=forced
void enterInSTOPMode(void){
HAL_SuspendTick();
uint32_t primask = __get_PRIMASK();
__disable_irq();
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_ConfigAfterStop();
HAL_ResumeTick();
__set_PRIMASK(primask);
}
Настройка компаратора сгенерирована cube
void MX_COMP2_Init(void)
{
/* USER CODE BEGIN COMP2_Init 0 */
/* USER CODE END COMP2_Init 0 */
/* USER CODE BEGIN COMP2_Init 1 */
/* USER CODE END COMP2_Init 1 */
hcomp2.Instance = COMP2;
hcomp2.Init.InvertingInput = COMP_INPUT_MINUS_IO1;
hcomp2.Init.NonInvertingInput = COMP_INPUT_PLUS_IO1;
hcomp2.Init.LPTIMConnection = COMP_LPTIMCONNECTION_DISABLED;
hcomp2.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED;
hcomp2.Init.Mode = COMP_POWERMODE_MEDIUMSPEED;
hcomp2.Init.WindowMode = COMP_WINDOWMODE_DISABLE;
hcomp2.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING;
if (HAL_COMP_Init(&hcomp2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN COMP2_Init 2 */
/* USER CODE END COMP2_Init 2 */
}
Прерывания разрешены
void HAL_COMP_MspInit(COMP_HandleTypeDef* compHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(compHandle->Instance==COMP2)
{
/* USER CODE BEGIN COMP2_MspInit 0 */
/* USER CODE END COMP2_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**COMP2 GPIO Configuration
PA2 ------> COMP2_INM
PA3 ------> COMP2_INP
PA7 ------> COMP2_OUT
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_COMP2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* COMP2 interrupt Init */
HAL_NVIC_SetPriority(ADC1_COMP_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_COMP_IRQn);
}
}
Пока микроконтроллер находится в STOP состоянии, на выходе компаратора ничего не происходит, наблюдаю осциллографом. Как только происходит выход из режима стоп, можно даже остановиться в точке останова сразу за командой HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI) (те. еще до включения прерываний и настройки нормального тактирования) то компаратор сразу же начинает работать и на выходе компаратора сигнал правильный.
Есть еще одно интересное наблюдение, если включить RTC и не использовать макрос __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU), то компаратор работает в режиме сна. Если использовать __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU) то перестает работать вне зависимости включен RTC или нет.
Проблема была обнаружена случайно, так как в девайсе всегда использовался RTC, но по ошибке не очищался флаг __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU)
before entering in this function, it is important to ensure that the WUF
* wakeup flag is cleared. To perform this action, it is possible to call the
* following macro : __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU)
Т.е. по сути дела попытка исправить этот недостаток ломает работу компаратора.
Был сделан отдельный чистый проект, где есть только компаратор comp2 и режим STOP. Проблема полностью воспроизводиться, т.е. компаратор не может разбудить микроконтроллер из STOP режима. Железо тоже менялось, и даже взято из готового продукта, который работает 5 лет.
Ломаю голову уже 7-й день. Не могу понять где искать ошибку.