ds1302.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * ds1302.c:
  3. * Real Time clock
  4. *
  5. * Copyright (c) 2013 Gordon Henderson.
  6. ***********************************************************************
  7. * This file is part of wiringPi:
  8. * https://projects.drogon.net/raspberry-pi/wiringpi/
  9. *
  10. * wiringPi is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Lesser General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * wiringPi is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public License
  21. * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <stdint.h>
  27. #include <stdarg.h>
  28. #include <wiringPi.h>
  29. #include "ds1302.h"
  30. // Register defines
  31. #define RTC_SECS 0
  32. #define RTC_MINS 1
  33. #define RTC_HOURS 2
  34. #define RTC_DATE 3
  35. #define RTC_MONTH 4
  36. #define RTC_DAY 5
  37. #define RTC_YEAR 6
  38. #define RTC_WP 7
  39. #define RTC_TC 8
  40. #define RTC_BM 31
  41. // Locals
  42. static int dPin, cPin, sPin ;
  43. /*
  44. * dsShiftIn:
  45. * Shift a number in from the chip, LSB first. Note that the data is
  46. * sampled on the trailing edge of the last clock, so it's valid immediately.
  47. *********************************************************************************
  48. */
  49. static unsigned int dsShiftIn (void)
  50. {
  51. uint8_t value = 0 ;
  52. int i ;
  53. pinMode (dPin, INPUT) ; delayMicroseconds (1) ;
  54. for (i = 0 ; i < 8 ; ++i)
  55. {
  56. value |= (digitalRead (dPin) << i) ;
  57. digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ;
  58. digitalWrite (cPin, LOW) ; delayMicroseconds (1) ;
  59. }
  60. return value;
  61. }
  62. /*
  63. * dsShiftOut:
  64. * A normal LSB-first shift-out, just slowed down a bit - the Pi is
  65. * a bit faster than the chip can handle.
  66. *********************************************************************************
  67. */
  68. static void dsShiftOut (unsigned int data)
  69. {
  70. int i ;
  71. pinMode (dPin, OUTPUT) ;
  72. for (i = 0 ; i < 8 ; ++i)
  73. {
  74. digitalWrite (dPin, data & (1 << i)) ; delayMicroseconds (1) ;
  75. digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ;
  76. digitalWrite (cPin, LOW) ; delayMicroseconds (1) ;
  77. }
  78. }
  79. /*
  80. * ds1302regRead: ds1302regWrite:
  81. * Read/Write a value to an RTC Register or RAM location on the chip
  82. *********************************************************************************
  83. */
  84. static unsigned int ds1302regRead (const int reg)
  85. {
  86. unsigned int data ;
  87. digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
  88. dsShiftOut (reg) ;
  89. data = dsShiftIn () ;
  90. digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
  91. return data ;
  92. }
  93. static void ds1302regWrite (const int reg, const unsigned int data)
  94. {
  95. digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
  96. dsShiftOut (reg) ;
  97. dsShiftOut (data) ;
  98. digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
  99. }
  100. /*
  101. * ds1302rtcWrite: ds1302rtcRead:
  102. * Writes/Reads the data to/from the RTC register
  103. *********************************************************************************
  104. */
  105. unsigned int ds1302rtcRead (const int reg)
  106. {
  107. return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ;
  108. }
  109. void ds1302rtcWrite (int reg, unsigned int data)
  110. {
  111. ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ;
  112. }
  113. /*
  114. * ds1302ramWrite: ds1302ramRead:
  115. * Writes/Reads the data to/from the RTC register
  116. *********************************************************************************
  117. */
  118. unsigned int ds1302ramRead (const int addr)
  119. {
  120. return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ;
  121. }
  122. void ds1302ramWrite (const int addr, const unsigned int data)
  123. {
  124. ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ;
  125. }
  126. /*
  127. * ds1302clockRead:
  128. * Read all 8 bytes of the clock in a single operation
  129. *********************************************************************************
  130. */
  131. void ds1302clockRead (int clockData [8])
  132. {
  133. int i ;
  134. unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ;
  135. digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
  136. dsShiftOut (regVal) ;
  137. for (i = 0 ; i < 8 ; ++i)
  138. clockData [i] = dsShiftIn () ;
  139. digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
  140. }
  141. /*
  142. * ds1302clockWrite:
  143. * Write all 8 bytes of the clock in a single operation
  144. *********************************************************************************
  145. */
  146. void ds1302clockWrite (const int clockData [8])
  147. {
  148. int i ;
  149. unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ;
  150. digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
  151. dsShiftOut (regVal) ;
  152. for (i = 0 ; i < 8 ; ++i)
  153. dsShiftOut (clockData [i]) ;
  154. digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
  155. }
  156. /*
  157. * ds1302trickleCharge:
  158. * Set the bits on the trickle charger.
  159. * Probably best left alone...
  160. *********************************************************************************
  161. */
  162. void ds1302trickleCharge (const int diodes, const int resistors)
  163. {
  164. if (diodes + resistors == 0)
  165. ds1302rtcWrite (RTC_TC, 0x5C) ; // Disabled
  166. else
  167. ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ;
  168. }
  169. /*
  170. * ds1302setup:
  171. * Initialise the chip & remember the pins we're using
  172. *********************************************************************************
  173. */
  174. void ds1302setup (const int clockPin, const int dataPin, const int csPin)
  175. {
  176. dPin = dataPin ;
  177. cPin = clockPin ;
  178. sPin = csPin ;
  179. digitalWrite (dPin, LOW) ;
  180. digitalWrite (cPin, LOW) ;
  181. digitalWrite (sPin, LOW) ;
  182. pinMode (dPin, OUTPUT) ;
  183. pinMode (cPin, OUTPUT) ;
  184. pinMode (sPin, OUTPUT) ;
  185. ds1302rtcWrite (RTC_WP, 0) ; // Remove write-protect
  186. }