1 /*
2 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3 * Copyright (c) 2014 Intel Corporation.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <iostream>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <stdexcept>
29
30 #include "maxds3231m.h"
31
32 using namespace upm;
33
MAXDS3231M(int bus,int devAddr)34 MAXDS3231M::MAXDS3231M (int bus, int devAddr) : m_i2Ctx(bus) {
35 m_name = "MAXDS3231M";
36
37 m_i2cAddr = devAddr;
38 m_bus = bus;
39
40 mraa::Result ret = m_i2Ctx.address(m_i2cAddr);
41 if (ret != mraa::SUCCESS) {
42 throw std::invalid_argument(std::string(__FUNCTION__) +
43 ": m_i2Ctx.address() failed");
44 }
45 }
46
47 void
setDate(Time3231 & time)48 MAXDS3231M::setDate (Time3231 &time) {
49 uint8_t *data = (uint8_t *)&time;
50
51 i2cWriteReg_N (TIME_CAL_ADDR, 7, data);
52 }
53
54 bool
getDate(Time3231 & time)55 MAXDS3231M::getDate (Time3231 &time) {
56 uint8_t buffer[7];
57
58 // We need 7 bytes of data.
59 if (i2cReadReg_N (TIME_CAL_ADDR, 7, buffer) > 6) {
60 uint8_t century = (buffer[5] & 0x80) >> 7;
61
62 time.second = BCDtoDEC(buffer[0]);
63 time.minute = BCDtoDEC(buffer[1]);
64 time.hour = BCDtoDEC(buffer[2]);
65 time.day = BCDtoDEC(buffer[4]);
66 time.month = BCDtoDEC(buffer[5] & 0x1F);
67 time.year = (century == 1) ? 2000 + BCDtoDEC(buffer[6]) : 1900 + BCDtoDEC(buffer[6]);
68 time.weekDay = BCDtoDEC(buffer[3]);
69
70 return true;
71 }
72
73 return false;
74 }
75
76 uint16_t
getTemperature()77 MAXDS3231M::getTemperature () {
78 uint8_t buffer[2];
79 uint8_t msb = 0;
80 uint8_t lsb = 0;
81
82 i2cReadReg_N (TEMPERATURE_ADDR, 2, buffer);
83 msb = buffer[0];
84 lsb = buffer[1] >> 6;
85
86 if ((msb & 0x80) != 0)
87 msb |= ~((1 << 8) - 1); // if negative get two's complement
88
89 return 0.25 * lsb + msb;
90 }
91
92 /*
93 * **************
94 * private area
95 * **************
96 */
97 uint16_t
i2cReadReg_N(int reg,unsigned int len,uint8_t * buffer)98 MAXDS3231M::i2cReadReg_N (int reg, unsigned int len, uint8_t * buffer) {
99 int readByte = 0;
100
101 m_i2Ctx.address(m_i2cAddr);
102 m_i2Ctx.writeByte(reg);
103
104 m_i2Ctx.address(m_i2cAddr);
105 readByte = m_i2Ctx.read(buffer, len);
106 return readByte;
107 }
108
109 mraa::Result
i2cWriteReg_N(uint8_t reg,unsigned int len,uint8_t * buffer)110 MAXDS3231M::i2cWriteReg_N (uint8_t reg, unsigned int len, uint8_t * buffer) {
111 mraa::Result error = mraa::SUCCESS;
112
113 error = m_i2Ctx.address (m_i2cAddr);
114 error = m_i2Ctx.write (buffer, len);
115
116 return error;
117 }
118
119 uint8_t
DECtoBSD(uint8_t data)120 MAXDS3231M::DECtoBSD(uint8_t data) {
121 return ((data / 10 * 16) + (data % 10));
122 }
123
124 uint8_t
BCDtoDEC(uint8_t data)125 MAXDS3231M::BCDtoDEC(uint8_t data) {
126 return ((data / 16 * 10) + (data % 16));
127 }
128