К1921ВГ015 RTC timer IRQ
Модераторы: ea, dav, bkolbov, Alis, pip, _sva_
К1921ВГ015 RTC timer IRQ
Добрый день. Слепил проект из 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; // СБрасываем регистр событий
}
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
- Сообщения: 136
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
Re: К1921ВГ015 RTC timer IRQ
Не это?
9. Ошибка формирования односекундного сигнала CLK1S
Описание
При разрешении прерывания по односекундному сигналу CLK1S прерывание PMURTC
возникает непрерывно и его невозможно сбросить.
Re: К1921ВГ015 RTC timer IRQ
Если запрещаю RTC_Event_1s тоже не работает. Хотя в каком-то релизе у меня работало это прерывание раз в секунду. Плохо, что почему-то он затирает кажется SERVEN и приходится делать flasherase каждый раз после запуска. Очень трудоемкая отладка получается.
Re: К1921ВГ015 RTC timer IRQ
Стоит только разрешить прерывание жирным выделил важные моменты:
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 делать.
▒
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
- Сообщения: 136
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
Re: К1921ВГ015 RTC timer IRQ
А если вот это
раскомментировать?
Код: Выделить всё
// PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6;Re: К1921ВГ015 RTC timer IRQ
Это пробовал.
Вот после этой строчки виснет(Жирынм выделил). Причем я установил время перед этим, чтобы 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
ПОчему?
Вот после этой строчки виснет(Жирынм выделил). Причем я установил время перед этим, чтобы 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
ПОчему?
Re: К1921ВГ015 RTC timer IRQ
Кажется понял причину, почему вызывается прерывание по 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");
}
Но не понял почему счетчики не выставляются как я их высталяю.
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
- Сообщения: 136
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
Re: К1921ВГ015 RTC timer IRQ
Учитывайте, что:
если в итоге таймер Вам таки нужен.
Далее, сброс состояния прерывания в обработчике попробуйте всё же сделать черезПри первом включении питания, в связи с тем, что по умолчанию установлен бит
ALARMEN регистра RTC_CFG1, и регистры RTC_TIME и RTC_ALARM имеют
одинаковое нулевое значение, возникает событие ALARM.
Код: Выделить всё
PMURTC->RTC_ALARM = PMURTC->RTC_TIME + 6;Re: К1921ВГ015 RTC timer IRQ
Спасибо, но и это учел. Очень странное что-то приосходит. Как только устанавливаю ALARMEN
PMURTC->RTC_CFG1 |= PMURTC_RTC_CFG1_ALARMRST_Msk;
Даже еще не разрешил прерывания от alarm
и гарантированно RTC_TIME > RTC_ALRM
Сразу же зависает контроллер со стиранием SERVEN.
Вот тут вроде все предусмотрено :
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
- Сообщения: 136
- Зарегистрирован: 10 июн 2025, 12:11
- Предприятие: HomeWork
Re: К1921ВГ015 RTC timer IRQ
Попробую поковыряться.
Что настораживает: значение после сброса для регистра PMURTC->RTC_CFG1 заявлено как 0xad0a0117, его я вижу под отладчиком, но это значение никак не "бьётся" с описанием этого регистра в РП.
Что настораживает: значение после сброса для регистра PMURTC->RTC_CFG1 заявлено как 0xad0a0117, его я вижу под отладчиком, но это значение никак не "бьётся" с описанием этого регистра в РП.
