К1921ВГ015 RTC timer IRQ

32-разрядные микроконтроллеры разработки АО "НИИЭТ"

Модераторы: ea, dav, bkolbov, Alis, pip, _sva_

bukvy
Сообщения: 16
Зарегистрирован: 02 сен 2025, 19:01
Предприятие: ООО НПФ Вымпел

К1921ВГ015 RTC timer IRQ

Сообщение bukvy »

Добрый день. Слепил проект из rtc_events и uart_dma. Почему-то при инициализации таймера RTC он сразу же уходит в SLEEP ( по кнопке WAKEUP0 пробуждается только чтобы выполнить прерывание и опять засыпает) До основного цикла while не доходт. Причем после этого приходится полностью память стирать утилитой erase_flash. Если убираю RTC_Init, то работает, кроме RTC_IRQHandler ,ну и естественно ни на events1s ни на WakeUP0 не реагирует. Вот куски кода main, rtc_ini, rtc_irq_handler,wakeup_init

int main(void)
{
periph_init();
TMR32_init(SystemCoreClock>>4);
InterruptEnable();
memset(UBUFF,0,UBUFF_SIZE); //Очистка буфера UBUFF
led_shift = LED0_MSK;
WakeUp_init();// Разрешаем прерывание от кнопки WakeUP0
RTC_Event_1S_init(); // Разрешаем односекундное событие
RTC_init();
// PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6; //PMURTC->RTC_TIME = count

while(1)
{
uint8_t get1char=retarget_get_char();
retarget_put_char(get1char);
if(get1char == 0x32){
PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 20; //Устанавливаем пробуждение через 20 секунд
printf("GOTO sleep\n");
// SelectPowerMode(0x32);
__asm("NOP");
printf("out from sleep\n");


}
}

return 0;
}

//==============================================
void RTC_init()
{

// AntiTamper_init(); // Разрешаем AntiTamper
// enable global IRQ for RTC
PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler);
PLIC_SetPriority (IsrVect_IRQ_PMURTC, 0x1);
PLIC_IntEnable (Plic_Mach_Target, IsrVect_IRQ_PMURTC);
PMURTC->PMU_IRQEVT = 1;
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
RTC_SetCounter_(timer); //Записать новое значение счетчика
}

//============================================================
void RTC_IRQHandler()
{
uint32_t tmp_history;
tmp_history = PMURTC->RTC_HISTORY;
GPIOA->DATAOUTTGL = LED6_MSK;

// Проверяем события WakeUp
if(tmp_history & RTC_EVENT_WAKEUP){
printf("\nWakeUp ON: ");
if(tmp_history & PMURTC_RTC_HISTORY_WAKE0_Msk) { PMURTC->RTC_HISTORY_bit.WAKE0 = 0; printf("WakeUp0, ");}
if(tmp_history & PMURTC_RTC_HISTORY_WAKE1_Msk) { PMURTC->RTC_HISTORY_bit.WAKE1 = 0; printf("WakeUp1, ");}
if(tmp_history & PMURTC_RTC_HISTORY_WAKE2_Msk) { PMURTC->RTC_HISTORY_bit.WAKE2 = 0; printf("WakeUp2, ");}
}

if(tmp_history & PMURTC_RTC_HISTORY_TIMEALARM_Msk){
printf("\nWakeUp ON: ");
printf("TimeAlarm,\n ");
// PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6;
}


// Проверяем событие односекундного таймера
if (PMURTC->PMU_WK3STAT_bit.CLK1S){
PMURTC->PMU_WK3STAT_bit.CLK1S = 1; // Сбрасываем событие односекундного таймера
printf("\nEvent 1S\n");
}

PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
PMURTC->PMU_IRQEVT = 1;
printf("out of wakeup interrupt\n") ;
PMURTC->RTC_HISTORY=0; // Room420 added as recomendation
}

//=================================================
void WakeUp_init()
{
//Настраиваем уровни активных сигналов, подключенных к WAKEUP
PMURTC->RTC_WAKECFG_bit.WAKEPOL = 0;// was 0x7; // Устанавливаем полярность для WAKEUP0 - WAKEUP2 низкий уровень
PMURTC->RTC_WAKECFG_bit.WAKEEN = 0x1; // Разрешаем событие WAKEUP0 - WAKEUP2
PMURTC->RTC_HISTORY = 0x0; // СБрасываем регистр событий
}
RabidRabbit
Сообщения: 139
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: К1921ВГ015 RTC timer IRQ

Сообщение RabidRabbit »

Не это?
9. Ошибка формирования односекундного сигнала CLK1S
Описание
При разрешении прерывания по односекундному сигналу CLK1S прерывание PMURTC
возникает непрерывно и его невозможно сбросить.
bukvy
Сообщения: 16
Зарегистрирован: 02 сен 2025, 19:01
Предприятие: ООО НПФ Вымпел

Re: К1921ВГ015 RTC timer IRQ

Сообщение bukvy »

Если запрещаю RTC_Event_1s тоже не работает. Хотя в каком-то релизе у меня работало это прерывание раз в секунду. Плохо, что почему-то он затирает кажется SERVEN и приходится делать flasherase каждый раз после запуска. Очень трудоемкая отладка получается.
bukvy
Сообщения: 16
Зарегистрирован: 02 сен 2025, 19:01
Предприятие: ООО НПФ Вымпел

Re: К1921ВГ015 RTC timer IRQ

Сообщение bukvy »

Стоит только разрешить прерывание жирным выделил важные моменты:
void RTC_init()
{

// AntiTamper_init(); // Разрешаем AntiTamper
// enable global IRQ for RTC
PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler);
PLIC_SetPriority (IsrVect_IRQ_PMURTC, 0x1);
PLIC_IntEnable (Plic_Mach_Target, IsrVect_IRQ_PMURTC);
// PMURTC->PMU_IRQEVT = 1;
// PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
RTC_SetCounter_(timer); //Записать новое значение счетчика
}
Сразу после запуска срабатывает это прерывание
void RTC_IRQHandler()
{
uint32_t tmp_history;
tmp_history = PMURTC->RTC_HISTORY;
GPIOA->DATAOUTTGL = LED6_MSK;
// Проверяем события AntiTamper
if(tmp_history & RTC_EVENT_ANTITAMPER){
printf("\nAntiTamper ALARM ON: ");
if(tmp_history & PMURTC_RTC_HISTORY_TAMPER0_Msk) { PMURTC->RTC_HISTORY_bit.TAMPER0 = 0; printf("AT_IN0, ");}
if(tmp_history & PMURTC_RTC_HISTORY_TAMPER1_Msk) { PMURTC->RTC_HISTORY_bit.TAMPER1 = 0; printf("AT_IN1, ");}
if(tmp_history & PMURTC_RTC_HISTORY_TAMPER2_Msk) { PMURTC->RTC_HISTORY_bit.TAMPER2 = 0; printf("AT_IN2, ");}
}
// Проверяем события WakeUp
if(tmp_history & RTC_EVENT_WAKEUP){
printf("\nWakeUp ON: ");
if(tmp_history & PMURTC_RTC_HISTORY_WAKE0_Msk) { PMURTC->RTC_HISTORY_bit.WAKE0 = 0; printf("WakeUp0, ");}
if(tmp_history & PMURTC_RTC_HISTORY_WAKE1_Msk) { PMURTC->RTC_HISTORY_bit.WAKE1 = 0; printf("WakeUp1, ");}
if(tmp_history & PMURTC_RTC_HISTORY_WAKE2_Msk) { PMURTC->RTC_HISTORY_bit.WAKE2 = 0; printf("WakeUp2, ");}
}

if(tmp_history & PMURTC_RTC_HISTORY_TIMEALARM_Msk){
printf("\nWakeUp ON: ");
printf("TimeAlarm,\n ");
// PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6;
}


// Проверяем событие односекундного таймера
if (PMURTC->PMU_WK3STAT_bit.CLK1S){
PMURTC->PMU_WK3STAT_bit.CLK1S = 1; // Сбрасываем событие односекундного таймера
printf("\nEvent 1S\n");
}

PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
PMURTC->PMU_IRQEVT = 1;
printf("out of wakeup interrupt\n") ;
PMURTC->RTC_HISTORY=0; // Room420 added as recomendation
}


Выводится на терминал:
- A.3, RX - A.2) DMA

WakeUp ON: TimeAlarm,

И почему-то работа контроллера прекращается со стиранием SERVEN. Приходится flasherase делать.
RabidRabbit
Сообщения: 139
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: К1921ВГ015 RTC timer IRQ

Сообщение RabidRabbit »

А если вот это

Код: Выделить всё

// PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6;
раскомментировать?
bukvy
Сообщения: 16
Зарегистрирован: 02 сен 2025, 19:01
Предприятие: ООО НПФ Вымпел

Re: К1921ВГ015 RTC timer IRQ

Сообщение bukvy »

Это пробовал.
Вот после этой строчки виснет(Жирынм выделил). Причем я установил время перед этим, чтобы ALARM < time
{

// AntiTamper_init(); // Разрешаем AntiTamper
// enable global IRQ for RTC
PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler);
RTC_SetCounter_(timer); //Записать новое значение счетчика
PLIC_SetPriority (IsrVect_IRQ_PMURTC, 0x1);
PLIC_IntEnable (Plic_Mach_Target, IsrVect_IRQ_PMURTC);
PMURTC->PMU_IRQEVT = 1;
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk; <- После выполнения этой строчки виснет.
__asm("NOP");

Если закомментировать эту строчку внутри прерывания
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
то получается бесконечные вызовы прерыввания с маской PMURTC_RTC_HISTORY_TIMEALARM_Msk (time=alarm).
Но как это возможно, я же выставляю time > alarm заведомо.
Если снимаю комментарий внутри прерывания (void RTC_IRQHandler()). то после сброса этого флага сразу зависает со стиранием
SERVEN
ПОчему?
bukvy
Сообщения: 16
Зарегистрирован: 02 сен 2025, 19:01
Предприятие: ООО НПФ Вымпел

Re: К1921ВГ015 RTC timer IRQ

Сообщение bukvy »

Кажется понял причину, почему вызывается прерывание по time=alarm
Но не понял почему счетчики не выставляются как я их высталяю.

void RTC_init()
{

// AntiTamper_init(); // Разрешаем AntiTamper
// enable global IRQ for RTC
uint32_t count2;
uint32_t count3;
PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler);

Высатавляем счетчик : timer =1384850400+14400
RTC_SetCounter_(timer); //Записать новое значение счетчика
PLIC_SetPriority (IsrVect_IRQ_PMURTC, 0x1);

Проверим счетчики:
count2= PMURTC->RTC_TIME; count2=1
count3= PMURTC->RTC_ALARM; count3=1

Почему ???


PLIC_IntEnable (Plic_Mach_Target, IsrVect_IRQ_PMURTC);
PMURTC->PMU_IRQEVT = 1;
// PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
__asm("NOP");
__asm("NOP");
__asm("NOP");
}
RabidRabbit
Сообщения: 139
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: К1921ВГ015 RTC timer IRQ

Сообщение RabidRabbit »

Учитывайте, что:
При первом включении питания, в связи с тем, что по умолчанию установлен бит
ALARMEN регистра RTC_CFG1, и регистры RTC_TIME и RTC_ALARM имеют
одинаковое нулевое значение, возникает событие ALARM.
Далее, сброс состояния прерывания в обработчике попробуйте всё же сделать через

Код: Выделить всё

PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6;
если в итоге таймер Вам таки нужен.
bukvy
Сообщения: 16
Зарегистрирован: 02 сен 2025, 19:01
Предприятие: ООО НПФ Вымпел

Re: К1921ВГ015 RTC timer IRQ

Сообщение bukvy »

Спасибо, но и это учел. Очень странное что-то приосходит. Как только устанавливаю ALARMEN
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
Даже еще не разрешил прерывания от alarm
и гарантированно RTC_TIME > RTC_ALRM

Сразу же зависает контроллер со стиранием SERVEN.

Вот тут вроде все предусмотрено :

Код: Выделить всё

void RTC_init()
{

	// enable global IRQ for RTC
	PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_PMURTC, RTC_IRQHandler);  // Адрес обработчким
    RTC_SetCounter_(timer);             //Записать новое значение счетчика
	PLIC_SetPriority   (IsrVect_IRQ_PMURTC, 0x1);
	PMURTC->RTC_TIME=100;
	count2= PMURTC->RTC_TIME;
	count3= PMURTC->RTC_ALARM;

    PMURTC->PMU_IRQEVT = 1;    // Сбросил флаг прерывания
    while(count2 == count3){    // Ждем наверняка, что time > alarm
	__asm("NOP");
	__asm("NOP");
	__asm("NOP");
	count2= PMURTC->RTC_TIME;
	count3= PMURTC->RTC_ALARM;

}
// все норамльно приходим сюда
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;  // Дальше не идет здесь зависает намертво
	PLIC_IntEnable     (Plic_Mach_Target, IsrVect_IRQ_PMURTC);
}
RabidRabbit
Сообщения: 139
Зарегистрирован: 10 июн 2025, 12:11
Предприятие: HomeWork

Re: К1921ВГ015 RTC timer IRQ

Сообщение RabidRabbit »

Попробую поковыряться.
Что настораживает: значение после сброса для регистра PMURTC->RTC_CFG1 заявлено как 0xad0a0117, его я вижу под отладчиком, но это значение никак не "бьётся" с описанием этого регистра в РП.
Ответить

Вернуться в «32-разрядные микроконтроллеры»