(defvar *rtc-port* 0)

(defun bcd-to-dec (x)
   "(bcd-to-dec x)
Convert the BCD-encoded number x to a decimal value."
   (+
      (* 10 (ash x -4))
      (logand x #xf)))

(defun dec-to-bcd (x)
  "(dec-to-bcd x)
Converts the decimal value to a BCD-encoded number.
Number must be in the range 0 to 99."
  (+
    (ash (floor x 10) 4)
    (logand (rem x 10) #xf)))

(defun rtc-p ()
  "(rtc-p)
Returns t if the RTC is connected."
  (with-i2c (str *rtc-port* #x68)
	    (streamp str)))

(defun rtc-set (h m s)
 "(rtc-set hr min sec)
Set the time on a DS3231 RTC. Times are in BCD, so use
the appropriate reader macro, e.g. (rtc-set #x12 #x34 #x00)
for 12:34:00."
  (let ((h (dec-to-bcd h))
	(m (dec-to-bcd m))
	(s (dec-to-bcd s)))
    (with-i2c (str *rtc-port* #x68)
	      (write-byte 0 str)
	      (write-byte s str)
	      (write-byte m str)
	      (write-byte h str))))

(defun rtc-get ()
  (with-i2c (str *rtc-port* #x68)
    (write-byte 0 str)
    (restart-i2c str 3)
    (mapcar bcd-to-dec
      (reverse
        (list
          (read-byte str)
          (read-byte str)
          (read-byte str))))))

(defun rtc-now ()
 "(rtc-now)
Set the time using the RTC."
  (apply now (rtc-get)))

(defun now-rtc ()
  "(now-rtc)
Sets the RTC time using the now function."
  (apply rtc-set (now)))
