MicroPython Driver for DS1302

DS1302 Driver Code for micro:bit

Download as zip file

'''
 DS1302 Real Time Clock Driver
 for the BBC micro:bit

 Original author: shaoziyang
 Date: 2018.2
 http://www.micropython.org.cn

 Extended by fredscave.com
 DATE: 2024.9
'''
from microbit import *
from micropython import const

REG_SEC    = const(0x80)
REG_MIN    = const(0x82)
REG_HR     = const(0x84)
REG_DAY    = const(0x86)
REG_MON    = const(0x88)
REG_WDAY   = const(0x8A)
REG_YR     = const(0x8C)
REG_WP     = const(0x8E)
# REG_CTRL = const(0x90)
REG_RAM    = const(0xC0)

class DS1302:
    def __init__(self, CLK=pin13, DAT=pin14, CS=pin15):
        self.CLK = CLK
        self.DAT = DAT
        self.CS  = CS

    def DecToHex(self, dat):
        return (dat//10) * 16 + (dat%10)

    def HexToDec(self, dat):
        return (dat//16) * 10 + (dat%16)

    def write_byte(self, dat):
        for i in range(8):
            self.DAT.write_digital((dat >> i) & 1)
            self.CLK.write_digital(1)
            self.CLK.write_digital(0)

    def read_byte(self):
        d = 0
        for i in range(8):
            d = d | (self.DAT.read_digital() << i)
            self.CLK.write_digital(1)
            self.CLK.write_digital(0)
        return d

    def getReg(self, reg):
        self.CS.write_digital(1)
        self.write_byte(reg)
        t = self.read_byte()
        self.CS.write_digital(0)
        return t

    def setReg(self, reg, dat):
        self.CS.write_digital(1)
        self.write_byte(reg)
        self.write_byte(dat)
        self.CS.write_digital(0)

    def wr(self, reg, dat):
        self.setReg(REG_WP, 0)
        self.setReg(reg, dat)
        self.setReg(REG_WP, 0x80)

    def start(self):
        t = self.getReg(REG_SEC + 1)
        self.wr(REG_SEC, t & 0x7f)

    def stop(self):
        t = self.getReg(REG_SEC + 1)
        self.wr(REG_SEC, t | 0x80)

    def Sec(self, sec = None):
        if sec == None:
            return self.HexToDec(self.getReg(REG_SEC+1))%60
        else:
            self.wr(REG_SEC, self.DecToHex(sec%60))

    def Mins(self, mins = None):
        if mins == None:
            return self.HexToDec(self.getReg(REG_MIN+1))
        else:
            self.wr(REG_MIN, self.DecToHex(mins%60))

    def Hr(self, hr = None):
        if hr == None:
            return self.HexToDec(self.getReg(REG_HR+1))
        else:
            self.wr(REG_HR, self.DecToHex(hr%24))

    def Wday(self, wday = None):
        if wday == None:
            return self.HexToDec(self.getReg(REG_WDAY+1))
        else:
            self.wr(REG_WDAY, self.DecToHex(wday%8))

    def Day(self, day = None):
        if day == None:
            return self.HexToDec(self.getReg(REG_DAY+1))
        else:
            self.wr(REG_DAY, self.DecToHex(day%32))

    def Mon(self, mon = None):
        if mon == None:
            return self.HexToDec(self.getReg(REG_MON+1))
        else:
            self.wr(REG_MON, self.DecToHex(mon%13))

    def Yr(self, yr = None):
        if yr == None:
            return self.HexToDec(self.getReg(REG_YR+1)) + 2000
        else:
            self.wr(REG_YR, self.DecToHex(yr%100))

    def DateTime(self, dat = None):
        if dat == None:
            return [self.Yr(),
                    self.Mon(),
                    self.Day(),
                    self.Wday(),
                    self.Hr(),
                    self.Mins(),
                    self.Sec()]
        else:
            self.Yr(dat[0])
            self.Mon(dat[1])
            self.Day(dat[2])
            self.Wday(dat[3])
            self.Hr(dat[4])
            self.Mins(dat[5])
            self.Sec(dat[6])

    def Time(self, h=None, m=None, s=None):
        if (h==None) and (m==None) and (s==None):
            str_sec = "%02d" % self.Sec()
            str_min = "%02d" % self.Mins()
            str_hr = "%02d" % self.Hr()
            return str_hr + ':' + str_min + ':' + str_sec
        if (s != None):
            self.Sec(s)
        if (m != None):
            self.Mins(m)
        if (h != None):
            self.Hr(h)

    def Date(self, y=None, m=None, d=None, fmt=1):
        # fmt = 1; YMD
        # fmt = 2; DMY
        # fmt = 3; MDY
        if (y==None) and (m==None) and (d==None):
            str_day = "%02d" % self.Day()
            str_mon = "%02d" % self.Mon()
            str_yr = "%04d" % self.Yr()
            if fmt == 1:
                return str_yr + '-' + str_mon + '-' + str_day
            if fmt == 2:
                return str_day + '-' + str_mon + '-' + str_yr
            if fmt == 3:
                return str_mon + '-' + str_day + '-' + str_yr
            return None
        if (d != None):
            self.Day(d)
        if (m != None):
            self.Mon(m)
        if (y != None):
            self.Yr(y)

    def Ram(self, reg, dat = None):
        if dat == None:
            return self.getReg(REG_RAM + 1 + (reg%31)*2)
        else:
            self.wr(REG_RAM + (reg%31)*2, dat)