\ 2006-07-25 EW adv2_i2c_rtc.fs \ pcf8583: \ addr \ 0x00 control register 3: mask_flag \ 0x01 sec/100.bcd \ 0x02 sec.bcd \ 0x03 min.bcd \ 0x04 7: 0=24h clock, 6: am/pm flag \ 5-0: hour.bcd \ 0x05 7-6: year%4 5-0: day.bcd \ 0x06 7-5: weekdays unless maskbit, \ 4-0: month.bcd \ eeprom: \ 0x10,0x11 full year, not BCD : bcd>dec ( n.bcd -- n.dec ) $ff and dup 4 rshift 10 * \ extract high nibble as 10s swap $0f and \ extract low nibble as 1s + \ add ; : dec>bcd ( n.dec -- n.bcd ) &100 mod \ 99 is largest for 8 bit bcd &10 /mod 4 lshift + $ff and \ truncate to 8 bit ; : get.rtc $01 \ start address 1 i2c_addr_rtc NB>i2c \ send > rtc 6 i2c_addr_rtc NBi2c \ send > rtc 2 i2c_addr_rtc NBbcd >R \ sec/100.bcd dec>bcd >R \ sec.bcd dec>bcd >R \ min.bcd dec>bcd >R \ hour.bcd \ year%4<<6 | hour.bcd dec>bcd 2 pick $03 and 6 lshift + >R dec>bcd \ month.bcd R> R> R> R> R> ; : set.rtc ( year ... sec/100.bcd -- ) format.rtc $80 $00 \ stop rtc 8 i2c_addr_rtc NB>i2c \ send all args \ start rtc $08 $00 2 i2c_addr_rtc NB>i2c \ year is still on stack dup $00ff and \ low byte swap 8 rshift $00ff and \ high byte swap \ low byte first $10 \ start addr 3 i2c_addr_rtc NB>i2c \ send > rtc ; : clock-init ( -- ) get.rtc year ! bcd>dec month ! bcd>dec day ! bcd>dec hour ! bcd>dec min ! bcd>dec sec ! drop \ bcd>dec 10 * msec ! ;