ds3231.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. // Copyright 2021 IOsetting <iosetting(at)outlook.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "ds3231.h"
  15. __XDATA uint8_t buff[7];
  16. uint8_t DS3231_Write(uint8_t reg, uint8_t dat)
  17. {
  18. return I2C_Write(DS3231_I2C_ADDR, reg, &dat, 1);
  19. }
  20. uint8_t DS3231_Hex2Bcd(uint8_t hex)
  21. {
  22. return (hex % 10) + ((hex / 10) << 4);
  23. }
  24. uint8_t DS3231_Bcd2Hex(uint8_t bcd)
  25. {
  26. return (bcd >> 4) * 10 + (bcd & 0x0F);
  27. }
  28. uint8_t DS3231_GetStatus(void)
  29. {
  30. I2C_Read(DS3231_I2C_ADDR, DS3231_REG_STATUS, buff, 1);
  31. return buff[0];
  32. }
  33. uint8_t DS3231_GetTime(uint8_t *t)
  34. {
  35. uint8_t res;
  36. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_SECOND, buff, 7);
  37. if (res != HAL_OK)
  38. {
  39. return res;
  40. }
  41. t[0] = DS3231_Bcd2Hex(buff[6]) + ((buff[5] >> 7) & 0x01) * 100; // year
  42. t[1] = DS3231_Bcd2Hex(buff[5] & 0x1F); // month
  43. t[2] = DS3231_Bcd2Hex(buff[3]); // week
  44. t[3] = DS3231_Bcd2Hex(buff[4]); // date
  45. t[7] = (buff[2] >> 6) & 0x01; // 12h/24h
  46. t[8] = (buff[2] >> 5) & 0x01; // am/pm
  47. if (t[7] == DS3231_FORMAT_12H)
  48. {
  49. t[4] = DS3231_Bcd2Hex(buff[2] & 0x1F); // hour
  50. }
  51. else
  52. {
  53. t[4] = DS3231_Bcd2Hex(buff[2] & 0x3F); // hour
  54. }
  55. t[5] = DS3231_Bcd2Hex(buff[1]); // minute
  56. t[6] = DS3231_Bcd2Hex(buff[0]); // second
  57. return HAL_OK;
  58. }
  59. /**
  60. uint8_t year;
  61. uint8_t month;
  62. uint8_t week;
  63. uint8_t date;
  64. uint8_t hour;
  65. uint8_t minute;
  66. uint8_t second;
  67. DS3231_HourFormat_t format;
  68. DS3231_AmPm_t am_pm;
  69. */
  70. uint8_t DS3231_SetTime(uint8_t *t)
  71. {
  72. uint8_t res, reg;
  73. // Time validation
  74. if (t[0] > 200) t[0] = 200; // year
  75. if (t[1] == 0) t[1] = 1; // month
  76. else if (t[1] > 12) t[1] = 12;
  77. if (t[2] == 0) t[2] = 1; // week
  78. else if (t[2] > 7) t[2] = 7;
  79. if (t[3] == 0) t[3] = 1; // date
  80. else if (t[3] > 31) t[3] = 31;
  81. if (t[7] == DS3231_FORMAT_12H)
  82. {
  83. if (t[4] > 12) t[4] = 12; // hour
  84. }
  85. else if (t[7] == DS3231_FORMAT_24H)
  86. {
  87. if (t[4] > 23) t[4] = 23; // hour
  88. }
  89. if (t[5] > 59) t[5] = 59; // minute
  90. if (t[6] > 59) t[6] = 59; // second
  91. res = DS3231_Write(DS3231_REG_SECOND, DS3231_Hex2Bcd(t[6]));
  92. if (res != HAL_OK) return res;
  93. res = DS3231_Write(DS3231_REG_MINUTE, DS3231_Hex2Bcd(t[5]));
  94. if (res != HAL_OK) return res;
  95. if (t[7] == DS3231_FORMAT_12H)
  96. {
  97. reg = (uint8_t)((1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));
  98. }
  99. else
  100. {
  101. reg = (0 << 6) | DS3231_Hex2Bcd(t[4]);
  102. }
  103. res = DS3231_Write(DS3231_REG_HOUR, reg);
  104. if (res != HAL_OK) return res;
  105. res = DS3231_Write(DS3231_REG_WEEK, DS3231_Hex2Bcd(t[2]));
  106. if (res != HAL_OK) return res;
  107. res = DS3231_Write(DS3231_REG_DATE, DS3231_Hex2Bcd(t[3]));
  108. if (res != HAL_OK) return res;
  109. if (t[0] >= 100)
  110. {
  111. res = DS3231_Write(DS3231_REG_MONTH, DS3231_Hex2Bcd(t[1]) | (1 << 7));
  112. if (res != HAL_OK) return res;
  113. return DS3231_Write(DS3231_REG_YEAR, DS3231_Hex2Bcd(t[0] - 100));
  114. }
  115. else
  116. {
  117. res = DS3231_Write(DS3231_REG_MONTH, DS3231_Hex2Bcd(t[1]));
  118. if (res != HAL_OK) return res;
  119. return DS3231_Write(DS3231_REG_YEAR, DS3231_Hex2Bcd(t[0]));
  120. }
  121. }
  122. uint8_t DS3231_GetPin(DS3231_PinType_t *pin)
  123. {
  124. uint8_t res;
  125. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
  126. if (res != HAL_OK) return res;
  127. *pin = (DS3231_PinType_t)((buff[0] >> 2) & 0x01);
  128. return HAL_OK;
  129. }
  130. uint8_t DS3231_SetPin(DS3231_PinType_t *pin)
  131. {
  132. uint8_t res;
  133. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
  134. if (res != HAL_OK) return res;
  135. buff[0] &= ~(1 << 2);
  136. buff[0] |= (*pin) << 2;
  137. return DS3231_Write(DS3231_REG_CONTROL, buff[0]);
  138. }
  139. uint8_t ds3231_GetSquareOutputState(HAL_State_t *state)
  140. {
  141. uint8_t res;
  142. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
  143. if (res != HAL_OK) return res;
  144. *state = (HAL_State_t)((buff[0] >> 6) & 0x01);
  145. return HAL_OK;
  146. }
  147. uint8_t DS3231_SetSquareOutputState(HAL_State_t state)
  148. {
  149. uint8_t res;
  150. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
  151. if (res != HAL_OK) return res;
  152. buff[0] &= ~(1 << 6);
  153. buff[0] |= state << 6;
  154. return DS3231_Write(DS3231_REG_CONTROL, buff[0]);
  155. }
  156. uint8_t DS3231_GetAlarmInterrupt(DS3231_Alarm_t alarm, HAL_State_t *state)
  157. {
  158. uint8_t res;
  159. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
  160. if (res != HAL_OK) return res;
  161. *state = (HAL_State_t)((buff[0] >> alarm) & 0x01);
  162. return HAL_OK;
  163. }
  164. uint8_t DS3231_SetAlarmInterrupt(DS3231_Alarm_t alarm, HAL_State_t state)
  165. {
  166. uint8_t res;
  167. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
  168. if (res != HAL_OK) return res;
  169. buff[0] &= ~(1 << alarm);
  170. buff[0] |= state << alarm;
  171. return DS3231_Write(DS3231_REG_CONTROL, buff[0]);
  172. }
  173. uint8_t DS3231_GetAlarm1(uint8_t *t, DS3231_Alarm1Mode_t *mode)
  174. {
  175. uint8_t res;
  176. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_ALARM1_SECOND, buff, 4);
  177. if (res != HAL_OK) return res;
  178. t[0] = 0; // year
  179. t[1] = 0; // month
  180. if (((buff[3] >> 6) & 0x01) != 0) // if week
  181. {
  182. t[2] = DS3231_Bcd2Hex(buff[3] & 0x0F); // week
  183. t[3] = 0; // date
  184. }
  185. else // if date
  186. {
  187. t[2] = 0; // week
  188. t[3] = DS3231_Bcd2Hex(buff[3] & 0x3F); // date
  189. }
  190. t[8] = ((buff[2] >> 5) & 0x01); // am/pm
  191. t[7] = ((buff[2] >> 6) & 0x01); // 12h/24h
  192. if (t[7] == DS3231_FORMAT_12H)
  193. {
  194. t[4] = DS3231_Bcd2Hex(buff[2]&0x1F);
  195. }
  196. else
  197. {
  198. t[4] = DS3231_Bcd2Hex(buff[2]&0x3F);
  199. }
  200. t[5] = DS3231_Bcd2Hex(buff[1] & 0x7F);
  201. t[6] = DS3231_Bcd2Hex(buff[0] & 0x7F);
  202. *mode = (DS3231_Alarm1Mode_t)(
  203. ((buff[0]>>7)&0x01)<<0 |
  204. ((buff[1]>>7)&0x01)<<1 |
  205. ((buff[2]>>7)&0x01)<<2 |
  206. ((buff[3]>>7)&0x01)<<3 |
  207. ((buff[3]>>6)&0x01)<<4
  208. );
  209. return HAL_OK;
  210. }
  211. uint8_t DS3231_SetAlarm1(uint8_t *t, DS3231_Alarm1Mode_t mode)
  212. {
  213. uint8_t res;
  214. uint8_t reg;
  215. res = DS3231_Write(DS3231_REG_ALARM1_SECOND, DS3231_Hex2Bcd(t[6]) | ((mode & 0x01) << 7));
  216. if (res != HAL_OK) return res;
  217. res = DS3231_Write(DS3231_REG_ALARM1_MINUTE, DS3231_Hex2Bcd(t[5]) | (((mode >> 1) & 0x01) << 7));
  218. if (res != HAL_OK) return res;
  219. if (t[7] == DS3231_FORMAT_12H)
  220. {
  221. reg = (uint8_t)((((mode >> 2) & 0x01) << 7) | (1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));
  222. }
  223. else
  224. {
  225. reg = (((mode >> 2) & 0x01) << 7) | DS3231_Hex2Bcd(t[4]);
  226. }
  227. res = DS3231_Write(DS3231_REG_ALARM1_HOUR, reg);
  228. if (res != HAL_OK) return res;
  229. if (mode >= DS3231_ALARM1_MODE_WEEK_HOUR_MINUTE_SECOND_MATCH)
  230. {
  231. reg = (((mode >> 3) & 0x01) << 7) | (1 << 6) | DS3231_Hex2Bcd(t[2]);
  232. }
  233. else
  234. {
  235. reg = (((mode >> 3) & 0x01) << 7) | DS3231_Hex2Bcd(t[3]);
  236. }
  237. return DS3231_Write(DS3231_REG_ALARM1_WEEK, reg);
  238. }
  239. uint8_t DS3231_GetAlarm2(uint8_t *t, DS3231_Alarm2Mode_t *mode)
  240. {
  241. uint8_t res;
  242. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_ALARM2_MINUTE, buff, 3);
  243. if (res != HAL_OK) return res;
  244. t[0] = 0; // year
  245. t[1] = 0; // month
  246. if (((buff[2] >> 6) & 0x01) != 0) // if week
  247. {
  248. t[2] = DS3231_Bcd2Hex(buff[2] & 0x0F);
  249. t[3] = 0;
  250. }
  251. else // if date
  252. {
  253. t[2] = 0;
  254. t[3] = DS3231_Bcd2Hex(buff[2] & 0x3F);
  255. }
  256. t[8] = ((buff[1] >> 5) & 0x01); // am/pm
  257. t[7] = ((buff[1] >> 6) & 0x01); // 12h/24h
  258. if (t[7] == DS3231_FORMAT_12H)
  259. {
  260. t[4] = DS3231_Bcd2Hex(buff[1]&0x1F);
  261. }
  262. else
  263. {
  264. t[4] = DS3231_Bcd2Hex(buff[1]&0x3F);
  265. }
  266. t[5] = DS3231_Bcd2Hex(buff[0] & 0x7F);
  267. t[6] = 0;
  268. *mode = (DS3231_Alarm2Mode_t)(
  269. ((buff[0]>>7)&0x01)<<0 |
  270. ((buff[1]>>7)&0x01)<<1 |
  271. ((buff[2]>>7)&0x01)<<2 |
  272. ((buff[2]>>6)&0x01)<<4
  273. );
  274. return HAL_OK;
  275. }
  276. uint8_t DS3231_SetAlarm2(uint8_t *t, DS3231_Alarm2Mode_t mode)
  277. {
  278. uint8_t res;
  279. uint8_t reg;
  280. res = DS3231_Write(DS3231_REG_ALARM2_MINUTE, DS3231_Hex2Bcd(t[5]) | (((mode >> 0) & 0x01) << 7));
  281. if (res != HAL_OK) return res;
  282. if (t[7] == DS3231_FORMAT_12H)
  283. {
  284. reg = (uint8_t)((((mode >> 1) & 0x01) << 7) | (1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));
  285. }
  286. else
  287. {
  288. reg = (((mode >> 1) & 0x01) << 7) | DS3231_Hex2Bcd(t[4]);
  289. }
  290. res = DS3231_Write(DS3231_REG_ALARM2_HOUR, reg);
  291. if (res != HAL_OK) return res;
  292. if (mode >= DS3231_ALARM2_MODE_WEEK_HOUR_MINUTE_MATCH)
  293. {
  294. reg = (((mode >> 2) & 0x01) << 7) | (1 << 6) | DS3231_Hex2Bcd(t[2]);
  295. }
  296. else
  297. {
  298. reg = (((mode >> 2) & 0x01) << 7) | DS3231_Hex2Bcd(t[3]);
  299. }
  300. return DS3231_Write(DS3231_REG_ALARM2_WEEK, reg);
  301. }
  302. uint8_t DS3231_ClearAlarm(DS3231_Alarm_t alarm)
  303. {
  304. uint8_t res;
  305. res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_STATUS, buff, 1);
  306. if (res != HAL_OK) return res;
  307. buff[0] &= ~(1 << alarm);
  308. return DS3231_Write(DS3231_REG_STATUS, buff[0]);
  309. }