#include "Includes.h" //#define printf(...) (0) /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ extern void Init_rtc(rtc_t *rtc) { uint32_t VAL; if(rtc == (rtc_t*)0) return; VAL = ((rtc->day)<<17) | ((rtc->hour)<<12) | ((rtc->minute)<<6) | (rtc->second); __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x20002); __write_hw_reg32(CPR_AOCLKEN_GRCTL, 0x20002); __write_hw_reg32(RTC_ICR, 0x00); __write_hw_reg32(RTC_CLR, VAL); __write_hw_reg32(RTC_WLR, rtc->week); __write_hw_reg32(RTC_RAW_LIMIT, 32000);//32768 __write_hw_reg32(RTC_SECOND_LIMIT, 60); __write_hw_reg32(RTC_MINUTE_LIMIT, 60); __write_hw_reg32(RTC_HOUR_LIMIT, 24); VAL = 0x100; if(rtc->interrupt != 0) { VAL |= (rtc->interrupt); NVIC_EnableIRQ(RTC_IRQn); } __write_hw_reg32(RTC_ICR, VAL); //- 使能RTC开始工作 } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ extern void rtc_Current_VAL(rtc_t *rtc) { uint32_t VAL; __read_hw_reg32(RTC_CCVR, VAL); rtc->day = (VAL >> 17) & 0x7FFF; rtc->hour = (VAL >> 12) & 0x1F; rtc->minute = (VAL >> 6)& 0x3F; rtc->second = VAL & 0x3F; __read_hw_reg32(RTC_WVR, VAL); rtc->week = VAL & 0x07; } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ extern void rtc_Alarm_Init(uint32_t no, rtc_t * rtc) { uint8_t TAB[3] = {RTC_INT_T1, RTC_INT_T2, RTC_INT_T3}; uint32_t VAL; no = no - 1; VAL = ((rtc->hour)<<12) | ((rtc->minute)<<6) | (rtc->second); //VAL |= 1<<((rtc->week)+17); VAL |= rtc->week_alarm; __write_hw_reg32(RTC_CMR_X(no), VAL); __read_hw_reg32(RTC_ICR, VAL); VAL |= TAB[no]; __write_hw_reg32(RTC_ICR, VAL); //- 使能定时匹配中 NVIC_EnableIRQ(RTC_IRQn);//使能RTC中断 } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ extern void Init_rtc_gpio(uint32_t num,uint32_t level) { uint32_t val; __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x20002); __write_hw_reg32(CPR_AOCLKEN_GRCTL, 0x20002); __write_hw_reg32(PWRKEY_CTRL0, level);/*gpio0-31(1:low,0:high)*/ __write_hw_reg32(PWRKEY_CTRL1, num);/*gpio0-31(0:disable,1:enable)*/ __write_hw_reg32(PWRKEY_CTRL2, 0x80000000);/*bit31:enable inter,bit1:inter raw*/ NVIC_EnableIRQ(RTC_IRQn); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ extern void RTC_Handler(void) { /*rtc pclk must be opened here after deep sleep wakeup*/ __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL, 0x20002); uint32_t stat; /*bit0:day , bit1:hour , bit2:min , bit3:sec , bit4:t2 , bit5:t1 , bit6:t3 intr*/ __read_hw_reg32(RTC_ISR, stat); if(stat != 0) { __write_hw_reg32(RTC_EOI, stat);//clear intr if(stat&0x1)//day intr { printf("rtc day intr\n"); } if(stat&0x2)//hour intr { printf("rtc hour intr\n"); } if(stat&0x4)//min intr { printf("rtc min intr\n"); } if(stat&0x8)//sec intr { printf("rtc sec intr\n"); } if(stat&0x70)//alarm intr { printf("rtc alarm t2/t1/t3 intr\n"); rtc_t rtc={0}; Init_rtc(&rtc); rtc.second=rtc.second+2; rtc.week_alarm=0xFE0000; rtc_Alarm_Init(1,&rtc); } } /*ao_timer intr*/ __read_hw_reg32(AO_ALL_INTR, stat); if(stat&0x20)//ao_timer intr { *AO_TIMER_CTL |=0x10000; printf("ao_timer intr\n"); } /*rtc_gpio inter*/ __read_hw_reg32(PWRKEY_CTRL2, stat); if(stat&0x02) /*power key gpio wakeup*/ { printf("rtc_gpio intr\n"); //__write_hw_reg32(PWRKEY_CTRL2, 0x00000000); //__write_hw_reg32(PWRKEY_CTRL2, 0x80000000); } } /*************************The following is the calibration of rc32k************************************/ static AO_TIMER_CTL_T* ao_timer_ctl = (AO_TIMER_CTL_T*)AO_TIMER_CTL; static void LPO_RTM_SET(uint16_t val) { *((volatile unsigned *)0x40002084)=0x1fff4000|val; //*((volatile unsigned *)0x40002084)=0x1fff4000|0x22C0; //printf("LPO_RTM:%08x\n",*((volatile unsigned *)0x40002084)); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ static uint8_t calib_step(uint32_t _cycle_32k,uint32_t *FREQ_VAL) { uint32_t tsd; ao_timer_ctl->AO_TIMER_VALUE = _cycle_32k;//32 cycle == 1ms ao_timer_ctl->AO_TIMER_EN = 0; ao_timer_ctl->AO_TIMER_CLR = 0; //中断使用在timer 使能之前 ao_timer_ctl->FREQ_TIMER_EN = 1; do{ __read_hw_reg32(AO_ALL_INTR, tsd); }while((tsd&0x20)==0); __read_hw_reg32(FREQ_TIMER_VAL, *FREQ_VAL);// ao_timer_ctl->AO_TIMER_CLR = 1; // rtc 必须清理中断 ao_timer_ctl->FREQ_TIMER_EN = 0; if(*FREQ_VAL==COUNT_16M) return 0; return ((*FREQ_VAL _32K_STAND_HZ) { mid=mid-((uint32_t)(((float)(frac-_32K_STAND_HZ))/GEARS_HZ)); } else if(frac < _32K_STAND_HZ) { mid=mid+((uint32_t)(((float)(_32K_STAND_HZ-frac))/GEARS_HZ)); } LPO_RTM_SET(mid); } printf("@@LPO_RTM_SET:0x%08x\n",mid); } /**********************************calibration rc32k end********************************************/ void test_rtc(void) { /*rc32k calib*/ calib_init(); rc32k_calib(3); #if 0 gpio_mux_ctl(1,0);gpio_fun_inter(1,0);gpio_fun_sel(1,0);gpio_direction_input(1,1); gpio_mux_ctl(4,0);gpio_fun_inter(4,0);gpio_fun_sel(4,0);gpio_direction_input(4,0); Init_rtc_gpio(0x00000012,0x00000010);/*1:low,0:high*/ while(1); #endif #if 0 rtc_t rtc={0}; Init_rtc(&rtc); rtc.second=rtc.second+5; //设定闹钟时间5S后 rtc.week_alarm=0xFE0000; //设置闹钟星期几有效,周一到周日都有效 rtc_Alarm_Init(1,&rtc); //设置闹钟--5s后唤醒 while(1); #endif #if 1 rtc_t rtc={ .day = 16, .hour = 10, .minute= 14, .second= 00, .week = 5, .interrupt = RTC_INT_SEC }; Init_rtc(&rtc); while(1) { for(int i=0;i<0x455000;i++); rtc_Current_VAL(&rtc); printf("%d-%d %d:%d:%d\n",rtc.day,rtc.week,rtc.hour,rtc.minute,rtc.second); } #endif }