58 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Common Lisp
		
	
	
	
			
		
		
	
	
			58 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Common Lisp
		
	
	
	
| (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)))
 |