Skip to content

Commit 5e0ac65

Browse files
committed
Upgrade to v0.92
1 parent 5f8c8d7 commit 5e0ac65

File tree

6 files changed

+630
-65
lines changed

6 files changed

+630
-65
lines changed

drivers/rtc/isl12022m/isl12022m.c

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
/**************************************************************************/
2+
/*!
3+
@file isl12022m.c
4+
@author K. Townsend (microBuilder.eu)
5+
6+
@brief Drivers for the ISL12022M RTC
7+
8+
@section DESCRIPTION
9+
10+
The ISL12022M is an I2C RTC with 128 bytes battery-backed up SRAM.
11+
12+
@section LICENSE
13+
14+
Software License Agreement (BSD License)
15+
16+
Copyright (c) 2010, microBuilder SARL
17+
All rights reserved.
18+
19+
Redistribution and use in source and binary forms, with or without
20+
modification, are permitted provided that the following conditions are met:
21+
1. Redistributions of source code must retain the above copyright
22+
notice, this list of conditions and the following disclaimer.
23+
2. Redistributions in binary form must reproduce the above copyright
24+
notice, this list of conditions and the following disclaimer in the
25+
documentation and/or other materials provided with the distribution.
26+
3. Neither the name of the copyright holders nor the
27+
names of its contributors may be used to endorse or promote products
28+
derived from this software without specific prior written permission.
29+
30+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
31+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
34+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40+
*/
41+
/**************************************************************************/
42+
#include "isl12022m.h"
43+
#include "core/systick/systick.h"
44+
45+
extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
46+
extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
47+
extern volatile uint32_t I2CReadLength, I2CWriteLength;
48+
49+
uint32_t i;
50+
uint8_t monthday[12]={31,28,31,30,31,30,31,31,30,31,30,31};
51+
52+
static bool _isl12022mInitialised = false;
53+
54+
/**************************************************************************/
55+
/*!
56+
@brief Standard decimal to binary coded decimal
57+
*/
58+
/**************************************************************************/
59+
uint8_t isl12022mDecToBCD(uint8_t val)
60+
{
61+
return ( (val/10*16) + (val%10) );
62+
}
63+
64+
/**************************************************************************/
65+
/*!
66+
@brief Binary coded decimal to standard decimal
67+
*/
68+
/**************************************************************************/
69+
uint8_t isl12022mBCDToDec(uint8_t val)
70+
{
71+
return ( (val/16*10) + (val%16) );
72+
}
73+
74+
/**************************************************************************/
75+
/*!
76+
@brief Writes an 8 bit value
77+
*/
78+
/**************************************************************************/
79+
isl12022mError_t isl12022mWrite8 (uint8_t address, uint8_t reg, uint32_t value)
80+
{
81+
// Clear write buffers
82+
for ( i = 0; i < I2C_BUFSIZE; i++ )
83+
{
84+
I2CMasterBuffer[i] = 0x00;
85+
}
86+
87+
I2CWriteLength = 3;
88+
I2CReadLength = 0;
89+
I2CMasterBuffer[0] = address;
90+
I2CMasterBuffer[1] = reg; // Command register
91+
I2CMasterBuffer[2] = (value & 0xFF); // Value to write
92+
i2cEngine();
93+
return ISL12022M_ERROR_OK;
94+
}
95+
96+
/**************************************************************************/
97+
/*!
98+
@brief Reads x bytes into a buffer
99+
*/
100+
/**************************************************************************/
101+
isl12022mError_t isl12022mReadBuffer(uint8_t address, uint8_t reg, uint8_t *buffer, uint32_t len)
102+
{
103+
if (len > I2C_BUFSIZE)
104+
return ISL12022M_ERROR_I2C_BUFFEROVERFLOW;
105+
106+
// Clear write buffers
107+
for ( i = 0; i < I2C_BUFSIZE; i++ )
108+
{
109+
I2CMasterBuffer[i] = 0x00;
110+
}
111+
112+
I2CWriteLength = 2;
113+
I2CReadLength = len;
114+
I2CMasterBuffer[0] = address;
115+
I2CMasterBuffer[1] = reg; // Command register
116+
// Append address w/read bit
117+
I2CMasterBuffer[2] = address | ISL12022M_READBIT;
118+
i2cEngine();
119+
120+
// Push response into buffer
121+
for ( i = 0; i < len; i++ )
122+
{
123+
buffer[i] = I2CSlaveBuffer[i];
124+
}
125+
126+
return ISL12022M_ERROR_OK;
127+
}
128+
129+
/**************************************************************************/
130+
/*!
131+
@brief Initialises the I2C block
132+
*/
133+
/**************************************************************************/
134+
isl12022mError_t isl12022mInit(void)
135+
{
136+
isl12022mError_t error = ISL12022M_ERROR_OK;
137+
uint8_t buffer[1];
138+
139+
// Initialise I2C
140+
if (i2cInit(I2CMASTER) == false)
141+
{
142+
return ISL12022M_ERROR_I2C_INIT; /* Fatal error */
143+
}
144+
145+
// Make sure write is enabled on the ISL12202M (factory default = disabled)
146+
error = isl12022mReadBuffer(ISL12022M_RTC_ADDRESS, ISL12022M_REG_CSR_INT, buffer, sizeof(buffer));
147+
if (!error)
148+
{
149+
if (!(buffer[0] & ISL12022M_INT_WRITEENABLE))
150+
{
151+
// Write is not enabled on the RTC ... enable it now
152+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_CSR_INT, buffer[0] | ISL12022M_INT_WRITEENABLE);
153+
}
154+
_isl12022mInitialised = true;
155+
}
156+
157+
return error;
158+
}
159+
160+
/**************************************************************************/
161+
/*!
162+
@brief Gets the current date/time from the RTC
163+
164+
@section EXAMPLE
165+
166+
@code
167+
#include "drivers/rtc/isl12022m.h"
168+
...
169+
isl12022mInit();
170+
171+
// Set the time to 12 June 2011 @ 11:59:30
172+
isl12022mSetTime(0, 11, 6, 12, 11, 59, 30);
173+
174+
// Wait 5 seconds
175+
systickDelay(5000);
176+
177+
// Display the current time
178+
isl12022mTime_t time;
179+
isl12022mGetTime(&time);
180+
printf("DW:%d, Y:%d, M:%d, D:%d, H:%d, M:%d, S:%d\r\n",
181+
time.dayofweek,
182+
time.year,
183+
time.month,
184+
time.day,
185+
time.hour,
186+
time.minute,
187+
time.second);
188+
@endcode
189+
*/
190+
/**************************************************************************/
191+
isl12022mError_t isl12022mGetTime(isl12022mTime_t *time)
192+
{
193+
isl12022mError_t error = ISL12022M_ERROR_OK;
194+
uint8_t buffer[9];
195+
196+
if (!_isl12022mInitialised)
197+
{
198+
error = isl12022mInit();
199+
if (error) return error;
200+
}
201+
202+
// Read 9 bytes at once into buffer
203+
error = isl12022mReadBuffer(ISL12022M_RTC_ADDRESS,
204+
ISL12022M_REG_RTC_SC,
205+
buffer, sizeof(buffer));
206+
207+
if (!error)
208+
{
209+
// Check status register
210+
if (buffer[7] & (ISL12022M_STATUS_LOWBATT85 | ISL12022M_STATUS_LOWBATT75))
211+
{
212+
// Set low battery flag to indicate that the RTC value may not be accurate
213+
error = ISL12022M_ERROR_RTC_LOWBATT;
214+
}
215+
216+
time->second = isl12022mBCDToDec(buffer[0]);
217+
time->minute = isl12022mBCDToDec(buffer[1]);
218+
time->hour = buffer[2] & 0x1F; // 0x3F;
219+
time->day = buffer[3] & 0x3F;
220+
time->month = buffer[4] & 0x1F;
221+
time->year = buffer[5];
222+
time->dayofweek = buffer[6] & 0x07;
223+
time->status = buffer[7];
224+
time->interrupt = buffer[8];
225+
}
226+
227+
return error;
228+
}
229+
230+
/**************************************************************************/
231+
/*!
232+
@brief Sets the current date/time from the RTC
233+
234+
@section EXAMPLE
235+
236+
@code
237+
#include "drivers/rtc/isl12022m.h"
238+
...
239+
isl12022mInit();
240+
241+
// Set the time to 12 June 2011 @ 11:59:30
242+
isl12022mSetTime(0, 11, 6, 12, 11, 59, 30);
243+
244+
// Wait 5 seconds
245+
systickDelay(5000);
246+
247+
// Display the current time
248+
isl12022mTime_t time;
249+
isl12022mGetTime(&time);
250+
printf("DW:%d, Y:%d, M:%d, D:%d, H:%d, M:%d, S:%d\r\n",
251+
time.dayofweek,
252+
time.year,
253+
time.month,
254+
time.day,
255+
time.hour,
256+
time.minute,
257+
time.second);
258+
@endcode
259+
*/
260+
/**************************************************************************/
261+
isl12022mError_t isl12022mSetTime(uint8_t dayofweek, uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
262+
{
263+
isl12022mError_t error = ISL12022M_ERROR_OK;
264+
265+
if (!_isl12022mInitialised)
266+
{
267+
error = isl12022mInit();
268+
if (error) return error;
269+
}
270+
271+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_SC, isl12022mDecToBCD(second));
272+
if (error) return error;
273+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_MN, isl12022mDecToBCD(minute));
274+
if (error) return error;
275+
// Always append military flag to hour (24 hour only)
276+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_HR, hour & 0x3F) | ISL12022M_HR_MILITARY;
277+
if (error) return error;
278+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_DT, day & 0x3F);
279+
if (error) return error;
280+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_MO, month & 0x1F);
281+
if (error) return error;
282+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_YR, year);
283+
if (error) return error;
284+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_RTC_DW, dayofweek & 0x07);
285+
if (error) return error;
286+
287+
return error;
288+
}
289+
290+
/**************************************************************************/
291+
/*!
292+
@brief Reads the current temperature from the ISL12022
293+
294+
@section EXAMPLE
295+
296+
@code
297+
#include "drivers/rtc/isl12022m.h"
298+
...
299+
isl12022mInit();
300+
301+
uint32_t temperature;
302+
isl12022mGetTemp(&temperature);
303+
printf("Temperature: %u C\r\n", temperature);
304+
305+
@endcode
306+
*/
307+
/**************************************************************************/
308+
isl12022mError_t isl12022mGetTemp(uint8_t *celsius)
309+
{
310+
isl12022mError_t error = ISL12022M_ERROR_OK;
311+
uint8_t buffer[2];
312+
uint32_t temp;
313+
314+
if (!_isl12022mInitialised)
315+
{
316+
error = isl12022mInit();
317+
if (error) return error;
318+
}
319+
320+
// Enable temperature sensing if required
321+
error = isl12022mReadBuffer(ISL12022M_RTC_ADDRESS, ISL12022M_REG_CSR_BETA, buffer, 1);
322+
if (!error)
323+
{
324+
if (!(buffer[0] & ISL12022M_BETA_TEMPENABLE))
325+
{
326+
// Temp sensor is not enabled ... enable it now
327+
error = isl12022mWrite8(ISL12022M_RTC_ADDRESS, ISL12022M_REG_CSR_BETA, buffer[0] | ISL12022M_BETA_TEMPENABLE);
328+
if (error)
329+
return error;
330+
}
331+
}
332+
333+
// Wait 100ms for conversion to complete
334+
systickDelay(100);
335+
// Read low and high temp bytes (0x28 and 0x29)
336+
error = isl12022mReadBuffer(ISL12022M_RTC_ADDRESS, ISL12022M_REG_TEMP_TKOL, buffer, 2);
337+
if (error)
338+
return error;
339+
// Convert value to degrees celsius (value/2 - 273 = degrees C)
340+
temp = ((buffer[0]) | (buffer[1] << 8)) / 2 - 273;
341+
*celsius = (uint8_t)temp & 0xFF;
342+
343+
return error;
344+
}

0 commit comments

Comments
 (0)