/* * sht20.c * * Created on: Jan 19, 2023 * Author: Wenxue */ #include #include #include "isl1208.h" /*+--------------------------------------+ *| RTC Chipset ISL1208 Register | *+--------------------------------------+*/ /* rtc section */ #define ISL1208_REG_SC 0x00 #define ISL1208_REG_MN 0x01 #define ISL1208_REG_HR 0x02 #define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */ #define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */ #define ISL1208_REG_DT 0x03 #define ISL1208_REG_MO 0x04 #define ISL1208_REG_YR 0x05 #define ISL1208_REG_DW 0x06 #define ISL1208_RTC_SECTION_LEN 7 /* RTC Section register */ #define REGS_RTC_SR_LEN 8 /* RTC Section and status register */ /* control/status section */ #define ISL1208_REG_SR 0x07 #define ISL1208_REG_SR_ARST (1<<7) /* auto reset */ #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ #define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */ #define ISL1208_REG_SR_EVT (1<<3) /* event */ #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ #define ISL1208_REG_SR_BAT (1<<1) /* battery */ #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ #define ISL1208_REG_INT 0x08 #define ISL1208_REG_INT_ALME (1<<6) /* alarm enable */ #define ISL1208_REG_INT_IM (1<<7) /* interrupt/alarm mode */ #define ISL1219_REG_EV 0x09 #define ISL1219_REG_EV_EVEN (1<<4) /* event detection enable */ #define ISL1219_REG_EV_EVIENB (1<<7) /* event in pull-up disable */ #define ISL1208_REG_ATR 0x0a #define ISL1208_REG_DTR 0x0b /* alarm section */ #define ISL1208_REG_SCA 0x0c #define ISL1208_REG_MNA 0x0d #define ISL1208_REG_HRA 0x0e #define ISL1208_REG_DTA 0x0f #define ISL1208_REG_MOA 0x10 #define ISL1208_REG_DWA 0x11 #define ISL1208_ALARM_SECTION_LEN 6 /* user section */ #define ISL1208_REG_USR1 0x12 #define ISL1208_REG_USR2 0x13 #define ISL1208_USR_SECTION_LEN 2 #define ISL1208_REGS_MAX 0x13 const char *weekday[7]={"Sun.","Mon.","Tue.","Wed.","Thu.","Fri.","Sat." }; #define CONFIG_RTC_DEBUG #ifdef CONFIG_RTC_DEBUG #define rtc_print(format,args...) printf(format, ##args) #else #define rtc_print(format,args...) do{} while(0) #endif #ifdef CONFIG_RTC_DEBUG __attribute__((unused)) static void dump_buf(const char *prompt, uint8_t *buf, uint32_t size) { int i; if(!buf) return ; if(prompt) printf("%s\r\n", prompt); for(i=0; i> 4) * 10) #define bin2bcd(x) ((((x) / 10) << 4) + (x) % 10) int set_rtc_time(rtc_time_t tm) { int rv; uint8_t regs[ISL1208_RTC_SECTION_LEN] = { 0, }; uint8_t sr; regs[ISL1208_REG_SC] = bin2bcd(tm.tm_sec); regs[ISL1208_REG_MN] = bin2bcd(tm.tm_min); regs[ISL1208_REG_HR] = bin2bcd(tm.tm_hour) | ISL1208_REG_HR_MIL; regs[ISL1208_REG_DT] = bin2bcd(tm.tm_mday); regs[ISL1208_REG_MO] = bin2bcd(tm.tm_mon); regs[ISL1208_REG_YR] = bin2bcd(tm.tm_year - 2000); //regs[ISL1208_REG_DW] = bin2bcd(tm.tm_wday & 7); if( i2c_init(ISL1208_I2CBUS, ISL1208_CHIPADDR) ) { rtc_print("ISL1208: Initial I2C bus failure!\r\n"); return -2; } rv = isl1208_i2c_read_regs(ISL1208_REG_SR, &sr, 1); if( rv < 0 ) { rtc_print("ISL1208: read Status Register failure, rv=%d!\r\n", rv); rv = -3; goto OUT; } sr |= ISL1208_REG_SR_WRTC; rv = isl1208_i2c_write_regs(ISL1208_REG_SR, &sr, 1); if( rv < 0 ) { rtc_print("ISL1208: Set Status Register WRTC failure, rv=%d!\r\n", rv); rv = -4; goto OUT; } rv=isl1208_i2c_write_regs(ISL1208_REG_SC, regs, ISL1208_RTC_SECTION_LEN); if(rv < 0 ) { rtc_print("ISL1208: Set RTC section registeres failure, rv=%d!\r\n", rv); rv = -5; goto OUT; } sr &= (~ISL1208_REG_SR_WRTC); rv = isl1208_i2c_write_regs(ISL1208_REG_SR, &sr, 1); if( rv < 0 ) { rtc_print("ISL1208: Clear Status Register WRTC failure, rv=%d!\r\n", rv); rv = -6; goto OUT; } OUT: i2c_term(ISL1208_I2CBUS); return rv; } int get_rtc_time(rtc_time_t *tm) { int rv = 0; uint8_t regs[REGS_RTC_SR_LEN] = { 0, }; if( !tm ) { rtc_print("ISL1208: Invalid input arugments!\r\n"); return -1; } if( i2c_init(ISL1208_I2CBUS, ISL1208_CHIPADDR) ) { rtc_print("ISL1208: Initial I2C bus failure!\r\n"); return -2; } rv = isl1208_i2c_read_regs(ISL1208_REG_SC, regs, REGS_RTC_SR_LEN); if (rv < 0) { rtc_print("ISL1208: read RTC_SECTION and SR registeres failure, rv=%d!\r\n", rv); rv = -3; goto OUT; } if( regs[ISL1208_REG_SR] & ISL1208_REG_SR_RTCF ) { rtc_print("ISL1208: Initialize RTC time after power failure!\r\n"); rv = -4; goto OUT; } tm->tm_sec = bcd2bin(regs[ISL1208_REG_SC]); tm->tm_min = bcd2bin(regs[ISL1208_REG_MN]); { const uint8_t _hr = regs[ISL1208_REG_HR]; if (_hr & ISL1208_REG_HR_MIL) /* 24H */ { tm->tm_hour = bcd2bin(_hr & 0x3f); } else /* 12H */ { tm->tm_hour = bcd2bin(_hr & 0x1f); if (_hr & ISL1208_REG_HR_PM) tm->tm_hour += 12; } } tm->tm_mday = bcd2bin(regs[ISL1208_REG_DT]); tm->tm_mon = bcd2bin(regs[ISL1208_REG_MO]); tm->tm_year = bcd2bin(regs[ISL1208_REG_YR]) + 2000; tm->tm_wday = bcd2bin(regs[ISL1208_REG_DW]); OUT: i2c_term(ISL1208_I2CBUS); return rv; } void print_rtc_time(void) { rtc_time_t tm; if( get_rtc_time(&tm) < 0 ) return ; printf("%04d-%02d-%02d %02d:%02d:%02d %s\r\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, weekday[tm.tm_wday]); }