tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/pcf8563/pcf8563.go (about) 1 // Package pcf8563 implements a driver for the PCF8563 CMOS Real-Time Clock (RTC) 2 // 3 // Datasheet: https://www.nxp.com/docs/en/data-sheet/PCF8563.pdf 4 // 5 6 package pcf8563 7 8 import ( 9 "time" 10 11 "tinygo.org/x/drivers" 12 ) 13 14 // Device wraps an I2C connection to a PCF8563 device. 15 type Device struct { 16 bus drivers.I2C 17 Address uint16 18 } 19 20 // New creates a new PCF8563 connection. I2C bus must be already configured. 21 func New(i2c drivers.I2C) Device { 22 return Device{ 23 bus: i2c, 24 Address: PCF8563_ADDR, 25 } 26 } 27 28 // Reset resets the `control and status registers`. When this method is 29 // called, it writes `0x00` to the `control and status registers`. This will 30 // cause `Alarm` and `Timer` to become Inactive. Please refer to the datasheet 31 // for details. 32 func (d *Device) Reset() (err error) { 33 return d.bus.Tx(d.Address, []byte{0x00, 0x00, 0x00}, nil) 34 } 35 36 // SetTime sets the time and date 37 func (d *Device) SetTime(t time.Time) error { 38 var buf [9]byte 39 buf[0] = 0x02 40 buf[1] = decToBcd(t.Second()) 41 buf[2] = decToBcd(t.Minute()) 42 buf[3] = decToBcd(t.Hour()) 43 buf[4] = decToBcd(t.Day()) 44 buf[5] = decToBcd(int(t.Weekday() + 1)) 45 buf[6] = decToBcd(int(t.Month())) 46 buf[7] = decToBcd(t.Year() - 2000) 47 err := d.bus.Tx(d.Address, buf[:], nil) 48 return err 49 } 50 51 // ReadTime returns the date and time 52 func (d *Device) ReadTime() (time.Time, error) { 53 var buf [9]byte 54 err := d.bus.Tx(d.Address, []byte{0x00}, buf[:]) 55 if err != nil { 56 return time.Time{}, err 57 } 58 59 seconds := bcdToDec(buf[2] & 0x7F) 60 minute := bcdToDec(buf[3] % 0x7F) 61 hour := bcdToDec(buf[4] & 0x3F) 62 day := bcdToDec(buf[5] & 0x3F) 63 month := time.Month(bcdToDec(buf[7] & 0x0F)) 64 year := int(bcdToDec(buf[8])) + 2000 65 66 t := time.Date(year, month, day, hour, minute, seconds, 0, time.UTC) 67 return t, nil 68 } 69 70 // SetAlarm sets the alarm 71 func (d *Device) SetAlarm(t time.Time) error { 72 var buf [5]byte 73 buf[0] = 0x09 74 buf[1] = RTC_ALARM_ENABLE | decToBcd(t.Minute()) 75 buf[2] = RTC_ALARM_ENABLE | decToBcd(t.Hour()) 76 buf[3] = RTC_ALARM_ENABLE | decToBcd(t.Day()) 77 buf[4] = RTC_ALARM_DISABLE 78 err := d.bus.Tx(d.Address, buf[:], nil) 79 if err != nil { 80 return err 81 } 82 83 // enable alarm 84 buf[0] = 0x01 85 err = d.bus.Tx(d.Address, buf[:1], buf[1:]) 86 if err != nil { 87 return err 88 } 89 90 buf[1] |= RTC_CTRL_AF 91 err = d.bus.Tx(d.Address, buf[:2], nil) 92 return err 93 } 94 95 // ClearAlarm disables alarm. 96 func (d *Device) ClearAlarm() error { 97 var buf [2]byte 98 buf[0] = 0x01 99 err := d.bus.Tx(d.Address, buf[:1], buf[1:]) 100 if err != nil { 101 return err 102 } 103 104 buf[1] &= ^uint8(RTC_CTRL_AF) 105 err = d.bus.Tx(d.Address, buf[:], nil) 106 return err 107 } 108 109 // EnableAlarmInterrupt enables alarm interrupt. When triggered, INT pin (3) 110 // goes low. 111 func (d *Device) EnableAlarmInterrupt() error { 112 var buf [2]byte 113 buf[0] = 0x01 114 err := d.bus.Tx(d.Address, buf[:1], buf[1:]) 115 if err != nil { 116 return err 117 } 118 119 buf[1] |= RTC_CTRL_AIE 120 err = d.bus.Tx(d.Address, buf[:], nil) 121 return err 122 } 123 124 // DisableAlarmInterrupt disable alarm interrupt. 125 func (d *Device) DisableAlarmInterrupt() error { 126 var buf [2]byte 127 buf[0] = 0x01 128 err := d.bus.Tx(d.Address, buf[:1], buf[1:]) 129 if err != nil { 130 return err 131 } 132 133 buf[1] &= ^uint8(RTC_CTRL_AIE) 134 err = d.bus.Tx(d.Address, buf[:], nil) 135 return err 136 } 137 138 // AlarmTriggered returns whether or not an Alarm has been triggered. 139 func (d *Device) AlarmTriggered() bool { 140 var buf [1]byte 141 buf[0] = 0x01 142 err := d.bus.Tx(d.Address, buf[:], buf[:]) 143 if err != nil { 144 return false 145 } 146 return (buf[0] & RTC_CTRL_AF) != 0 147 } 148 149 // SetTimer sets timer. The available durations are 1 to 127 seconds. If any 150 // other value is specified, it will be truncated. 151 func (d *Device) SetTimer(dur time.Duration) error { 152 var buf [3]byte 153 154 sec := dur / time.Second 155 if sec > 127 { 156 sec = 127 157 } 158 159 // Treat as sec timer. 160 buf[0] = 0x0E 161 buf[1] = RTC_TIMER_1S 162 buf[2] = byte(sec) 163 err := d.bus.Tx(d.Address, buf[:], nil) 164 if err != nil { 165 return err 166 } 167 168 // enable alarm 169 buf[0] = 0x01 170 err = d.bus.Tx(d.Address, buf[:1], buf[1:]) 171 if err != nil { 172 return err 173 } 174 175 buf[1] |= RTC_CTRL_TF 176 err = d.bus.Tx(d.Address, buf[:2], nil) 177 return err 178 } 179 180 // ClearTimer disables timer. 181 func (d *Device) ClearTimer() error { 182 var buf [2]byte 183 buf[0] = 0x01 184 err := d.bus.Tx(d.Address, buf[:1], buf[1:]) 185 if err != nil { 186 return err 187 } 188 189 buf[1] &= ^uint8(RTC_CTRL_TF) 190 err = d.bus.Tx(d.Address, buf[:], nil) 191 return err 192 } 193 194 // EnableTimerInterrupt enables timer interrupt. When triggered, INT pin (3) 195 // goes low. 196 func (d *Device) EnableTimerInterrupt() error { 197 var buf [2]byte 198 buf[0] = 0x01 199 err := d.bus.Tx(d.Address, buf[:1], buf[1:]) 200 if err != nil { 201 return err 202 } 203 204 buf[1] |= RTC_CTRL_TIE 205 err = d.bus.Tx(d.Address, buf[:], nil) 206 return err 207 } 208 209 // DisableTimerInterrupt disable timer interrupt. 210 func (d *Device) DisableTimerInterrupt() error { 211 var buf [2]byte 212 buf[0] = 0x01 213 err := d.bus.Tx(d.Address, buf[:1], buf[1:]) 214 if err != nil { 215 return err 216 } 217 218 buf[1] &= ^uint8(RTC_CTRL_TIE) 219 err = d.bus.Tx(d.Address, buf[:], nil) 220 return err 221 } 222 223 // TimerTriggered returns whether or not an Alarm has been triggered. 224 func (d *Device) TimerTriggered() bool { 225 var buf [1]byte 226 buf[0] = 0x01 227 err := d.bus.Tx(d.Address, buf[:], buf[:]) 228 if err != nil { 229 return false 230 } 231 return (buf[0] & RTC_CTRL_TF) != 0 232 } 233 234 // SetOscillatorFrequency sets output oscillator frequency 235 // Available modes: RTC_COT_DISABLE, RTC_COT_32KHZ, RTC_COT_1KHZ, 236 // RTC_COT_32Hz, RTC_COT_1HZ. 237 func (d *Device) SetOscillatorFrequency(sqw uint8) error { 238 var buf [2]byte 239 buf[0] = 0x0D 240 buf[1] = sqw 241 return d.bus.Tx(d.Address, buf[:], nil) 242 } 243 244 // decToBcd converts int to BCD 245 func decToBcd(dec int) uint8 { 246 return uint8(dec + 6*(dec/10)) 247 } 248 249 // bcdToDec converts BCD to int 250 func bcdToDec(bcd uint8) int { 251 return int(bcd - 6*(bcd>>4)) 252 }