📄 rtc.c
字号:
* * Return values : * --------------- * * 'OK'(=0) * * ************************************************************************/static INT32 RTC_write( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_RTC_calendar *p_param ); /* INOUT: current RTC value *//************************************************************************ * Implementation : Public functions ************************************************************************//************************************************************************ * * RTC_install * Description : * ------------- * * Installs the RTC device drivers services in the IO system * at the reserved device slot, found in the 'sys_dev.h' file, * which defines all major device numbers. * * Note: * This service is the only public declared interface function; all * provided device driver services are static declared, but this * function installs the function pointers in the io-system to * enable the provided public driver services. * * Parameters : * ------------ * * None * * Return values : * --------------- * * 'OK'(=0) * 'ERROR_IO_ILLEGAL_MAJOR': Illegal major device number * 'ERROR_IO_NO_SPACE': Device slot already allocated * ************************************************************************/INT32 RTC_install( void ){ /* pre-initialize local variables and install device services */ IO_install( SYS_MAJOR_RTC, /* major device number */ (t_io_service) RTC_init, /* 'init' service */ NULL, /* 'open' service N/A */ NULL, /* 'close' service N/A */ (t_io_service) RTC_read, /* 'read' service */ (t_io_service) RTC_write, /* 'write' service */ NULL ) ; /* 'ctrl' service N/A */ /* call our own 'init' service */ return IO_init( SYS_MAJOR_RTC, 0, NULL);}/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * RTC_init * Description : * ------------- * This service initializes the RTC driver. * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, not used * 'p_param', INOUT, not used * * * Return values : * --------------- * * 'OK'(=0) * * * ************************************************************************/static INT32 RTC_init( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ void *p_param ) /* INOUT: device parameter block */{ bool start12; UINT8 hour; /* Get addresses of ADR and DAT registers */ SYSCON_read( SYSCON_BOARD_RTC_ADDR_ID, &rtcaddr, sizeof(rtcaddr) ); SYSCON_read( SYSCON_BOARD_RTC_DATA_ID, &rtcdata, sizeof(rtcdata) ); /* Get register size */ SYSCON_read( SYSCON_BOARD_RTC_REG_SIZE_ID, &size, sizeof(UINT8) ); rtcaddr = KSEG1( rtcaddr ); rtcdata = KSEG1( rtcdata ); /* initialize RTC, * Register B: * - 'disable update, temporary' * - 'binary mode' * - 'daylight saving on' * - 24 hr mode * * If RTC is in 12 hr mode, update time. */ SETREG( rtcaddr, RTC_REGB_OFS ); start12 = (REGFIELD( GETREG(rtcdata), RTC_REGB_HF ) == RTC_REGB_HF_12) ? TRUE : FALSE; SETREG( rtcdata, RTC_REGB_SET_BIT | (RTC_REGB_DM_BIN << RTC_REGB_DM_SHF) | RTC_REGB_DSE_BIT | (RTC_REGB_HF_24 << RTC_REGB_HF_SHF) ); if( start12) { /* force 24h format */ SETREG( rtcaddr, RTC_HOUR_OFS ); hour = GETREG( rtcdata ); if (hour == 12) hour = 0; if (hour == 0x8c) hour = 12; if (hour & 0x80) hour = (hour & 0xf) + 12; SETREG( rtcdata, hour ); } /* Register A */ SETREG( rtcaddr, RTC_REGA_OFS ); SETREG( rtcdata, (RTC_REGA_DCS_NORMAL << RTC_REGA_DCS_SHF) | (RTC_REGA_RSB_NONE << RTC_REGA_RSB_SHF) ); /* re-enable update */ SETREG( rtcaddr, RTC_REGB_OFS ); SETREG( rtcdata, GETREG(rtcdata) & ~RTC_REGB_SET_BIT ); return( OK );}/************************************************************************ * * RTC_read * Description : * ------------- * This service reads the current value of the Real Time Clock. * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, minor device number for multi device drivers * 'p_param', INOUT, RTC variable of type, t_RTC_calendar. * * * Return values : * --------------- * * 'OK'(=0) * * ************************************************************************/static INT32 RTC_read( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_RTC_calendar *p_param ) /* INOUT: current RTC value */{ UINT8 data; UINT32 cp0_ie; /* Read RTC value. * * When the UIP bit is set, the clock will not tick for at least * 244 us. * We need to perform the read operations before that happens. * This should not be a problem unless an interrupt occurs. * So, we disable interrupts and poll the UIP bit until it is set. * Then we read the data and restore the interrupt enable bit. */ cp0_ie = sys_disable_int(); do { SETREG( rtcaddr, RTC_REGA_OFS ); data = GETREG( rtcdata ); } while( data & RTC_REGA_UIP_MSK ); SETREG( rtcaddr, RTC_SEC_OFS ); p_param->second = GETREG( rtcdata ); SETREG( rtcaddr, RTC_MIN_OFS ); p_param->minute = GETREG( rtcdata ); SETREG( rtcaddr, RTC_HOUR_OFS ); p_param->hour = GETREG( rtcdata ); SETREG( rtcaddr, RTC_DAYOFWEEK_OFS ); /* CE:0-6 RTC:1-7 */ p_param->dayofweek = GETREG( rtcdata ); SETREG( rtcaddr, RTC_DAYOFMONTH_OFS ); p_param->dayofmonth = GETREG( rtcdata ); SETREG( rtcaddr, RTC_MONTH_OFS ); p_param->month = GETREG( rtcdata ); /* We assume no century register, but instead assume: * Year ranges: 0<=y<=69: 2000-2069. 70<=y<=255: 1970-2155. * Future generations, please forgive us. */ p_param->year = 1900; SETREG( rtcaddr, RTC_YEAR_OFS ); p_param->year += GETREG( rtcdata ); if (p_param->year < 1970) p_param->year += 100; /* Reenable interrupts in case interrupts were enabled */ if( cp0_ie ) sys_enable_int(); return( OK );}/************************************************************************ * * RTC_write * Description : * ------------- * This service sets the current value of the Real Time Clock. * * * Parameters : * ------------ * * 'major', IN, major device number * 'minor', IN, minor device number for multi device drivers * 'p_param', INOUT, RTC variable of type, t_RTC_calendar. * * * Return values : * --------------- * * 'OK'(=0) * * ************************************************************************/static INT32 RTC_write( UINT32 major, /* IN: major device number */ UINT32 minor, /* IN: minor device number */ t_RTC_calendar *p_param ) /* INOUT: current RTC value */{ /* Set RTC value */ /* disable register update during setting of RTC value */ SETREG( rtcaddr, RTC_REGB_OFS ); SETREG( rtcdata, GETREG(rtcdata) | RTC_REGB_SET_BIT ); SETREG( rtcaddr, RTC_SEC_OFS ); SETREG( rtcdata, p_param->second ); SETREG( rtcaddr, RTC_MIN_OFS ); SETREG( rtcdata, p_param->minute ); SETREG( rtcaddr, RTC_HOUR_OFS ); SETREG( rtcdata, p_param->hour ); SETREG( rtcaddr, RTC_DAYOFWEEK_OFS ); /* CE:0-6 RTC:1-7 */ SETREG( rtcdata, p_param->dayofweek ); SETREG( rtcaddr, RTC_DAYOFMONTH_OFS ); SETREG( rtcdata, p_param->dayofmonth ); SETREG( rtcaddr, RTC_MONTH_OFS ); SETREG( rtcdata, p_param->month ); SETREG( rtcaddr, RTC_YEAR_OFS ); SETREG( rtcdata, p_param->year % 100 ); /* re-enable update */ SETREG( rtcaddr, RTC_REGB_OFS ); SETREG( rtcdata, GETREG(rtcdata) & ~RTC_REGB_SET_BIT ); return( OK );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -