void rtc_set_alarm(int h, int m) { unsigned char buf[4] = {0}; int i, rv; /* clear alarm interrupt */ rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, buf); buf[0] &= RTC_AF; pp_i2c_send(RTC_ADDR, RTC_CTRL2, buf[0]); /* prepare new alarm */ if( m >= 0 ) buf[0] = DEC2BCD(m); else /* ignore minutes comparison query */ buf[0] = RTC_AE; if( h >= 0 ) buf[1] = DEC2BCD(h); else /* ignore hours comparison query */ buf[1] = RTC_AE; /* ignore day and wday */ buf[2] = RTC_AE; buf[3] = RTC_AE; /* write new alarm */ for(i = 0; i < 4; i++) pp_i2c_send(RTC_ADDR, RTC_ALARM_MINUTES + i, buf[i]); /* note: alarm is not enabled at the point */ }
void rtc_init(void) { unsigned char tmp; int rv; /* initialize Control 1 register */ tmp = 0; pp_i2c_send(RTC_ADDR, RTC_CTRL1, tmp); /* read value of the Control 2 register - we'll need it to preserve alarm and timer interrupt assertion flags */ rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); /* preserve alarm and timer interrupt flags */ tmp &= (RTC_TF | RTC_AF | RTC_TIE | RTC_AIE); pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); }
bool rtc_check_alarm_started(bool release_alarm) { static bool alarm_state, run_before = false; unsigned char tmp=0; bool started; int rv=0; if (run_before) { started = alarm_state; alarm_state &= ~release_alarm; } else { /* read Control 2 register which contains alarm flag */ rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); alarm_state = started = ( (tmp & RTC_AF) && (tmp & RTC_AIE) ); if(release_alarm && started) { rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); /* clear alarm interrupt enable and alarm flag */ tmp &= ~(RTC_AF | RTC_AIE); pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); } run_before = true; rtc_lock_alarm_clear = false; } return started; }
int pcf50605_write_multiple(int address, const unsigned char* buf, int count) { int i; i2c_lock(); for (i = 0; i < count; i++) pp_i2c_send(0x8, address + i, buf[i]); i2c_unlock(); return 0; }
void rtc_enable_alarm(bool enable) { unsigned char tmp=0; int rv=0; if(enable) { /* enable alarm interrupt */ rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); tmp |= RTC_AIE; tmp &= ~RTC_AF; pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); } else { /* disable alarm interrupt */ if(rtc_lock_alarm_clear) /* lock disabling alarm before it was checked whether or not the unit was started by RTC alarm */ return; rv = i2c_readbytes(RTC_ADDR, RTC_CTRL2, 1, &tmp); tmp &= ~(RTC_AIE | RTC_AF); pp_i2c_send(RTC_ADDR, RTC_CTRL2, tmp); } }
int rtc_write_datetime(const struct tm *tm) { unsigned int i; unsigned char buf[7]; buf[0] = tm->tm_sec; buf[1] = tm->tm_min; buf[2] = tm->tm_hour; buf[3] = tm->tm_mday; buf[4] = tm->tm_wday; buf[5] = tm->tm_mon + 1; buf[6] = tm->tm_year - 100; for (i = 0; i < sizeof(buf); i++) pp_i2c_send(RTC_ADDR, 0x02 + i, DEC2BCD(buf[i])); return 1; }
int pcf50605_write(int address, unsigned char val) { pp_i2c_send(0x8, address, val); return 0; }