Nut/OS  4.10.3
API Reference
ds1307rtc.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 by egnite Software GmbH and Christian Welzel.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00022  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * For additional information see http://www.ethernut.de/
00032  *
00033  */
00034 
00065 #include <cfg/os.h>
00066 #include <dev/twif.h>
00067 #include <sys/event.h>
00068 #include <sys/timer.h>
00069 
00070 #include <stdlib.h>
00071 #include <string.h>
00072 
00073 #include <dev/ds1307rtc.h>
00074 
00075 #ifndef I2C_SLA_RTC
00076 #define I2C_SLA_RTC     0x68    // 7 bit address!
00077 #endif
00078 
00079 
00089 int DS1307RtcReadRegs(uint8_t reg, uint8_t *buff, size_t cnt)
00090 {
00091     int rc = -1;
00092     uint8_t wbuf[1];
00093 
00094     wbuf[0] = reg;
00095     if (TwMasterTransact(I2C_SLA_RTC, wbuf, 1, buff, cnt, NUT_WAIT_INFINITE) == cnt) {
00096         rc = 0;
00097     }
00098     return rc;
00099 }
00100 
00110 int DS1307RtcWrite(CONST uint8_t *buff, size_t cnt)
00111 {
00112     int rc;
00113 
00114     rc = TwMasterTransact(I2C_SLA_RTC, buff, cnt, 0, 0, NUT_WAIT_INFINITE);
00115     return rc;
00116 }
00117 
00126 int DS1307RtcGetClock(struct _tm *tm)
00127 {
00128     int rc;
00129     uint8_t data[7];
00130 
00131     if ((rc = DS1307RtcReadRegs(0x00, data, 7)) == 0) {
00132         tm->tm_sec  = BCD2BIN(data[0]);
00133         tm->tm_min  = BCD2BIN(data[1]);
00134         tm->tm_hour = BCD2BIN(data[2] & 0x3F);
00135         tm->tm_mday = BCD2BIN(data[4]);
00136         tm->tm_mon  = BCD2BIN(data[5]) - 1;
00137         tm->tm_year = BCD2BIN(data[6]) + 100;
00138         tm->tm_wday = data[3] - 1;
00139     }
00140     return rc;
00141 }
00142 
00151 int DS1307RtcSetClock(CONST struct _tm *tm)
00152 {
00153     uint8_t data[8];
00154 
00155     memset(data, 0, sizeof(data));
00156     if (tm) {
00157         data[0] = 0x00;     // adress 0
00158         data[1] = BIN2BCD(tm->tm_sec);
00159         data[2] = BIN2BCD(tm->tm_min);
00160         data[3] = BIN2BCD(tm->tm_hour) & 0x3f; // 24 hour mode
00161         data[5] = BIN2BCD(tm->tm_mday);
00162         data[6] = BIN2BCD(tm->tm_mon + 1);
00163         data[7] = BIN2BCD(tm->tm_year - 100);
00164         data[4] = tm->tm_wday + 1;
00165     }
00166     return DS1307RtcWrite(data, 8);
00167 }
00168 
00178 int DS1307RamRead(uint8_t addr, uint8_t *buff, size_t cnt)
00179 {
00180     int rc = -1;
00181 
00182     // Range check
00183     if ((addr>=0x08) && (addr<=0x3F)) {
00184         rc = DS1307RtcReadRegs(addr, buff, cnt);
00185     }
00186 
00187     return rc;
00188 }
00189 
00199 int DS1307RamWrite(uint8_t addr, CONST void *buff, size_t len)
00200 {
00201     int rc = 0;
00202     uint8_t *wbuf;
00203     CONST uint8_t *wp = buff;
00204 
00205     /* Allocate and set a TWI write buffer. */
00206     if ((wbuf = malloc(len + 1)) == 0) {
00207         rc = -1;
00208     } else {
00209         wbuf[0] = addr;
00210         memcpy(wbuf + 1, wp, len);
00211 
00212         /* Send the write buffer. */
00213         rc = TwMasterTransact(I2C_SLA_RTC, wbuf, len + 1, 0, 0, NUT_WAIT_INFINITE);
00214 
00215         /* Release the buffer. */
00216         free(wbuf);
00217     }
00218 
00219     return rc;
00220 }
00221 
00228 int DS1307Init(void)
00229 {
00230     int rc;
00231     uint8_t data;
00232     uint8_t buff[2];
00233 
00234     if ((rc = TwInit(0)) == 0 ) {
00235         // Enable Oszillator
00236         if ((rc = DS1307RtcReadRegs(0x00, &data, 1)) == 0) {
00237             buff[0] = 0x00;
00238             buff[1] = data & 0x7F; //0b01111111;
00239             rc = DS1307RtcWrite(buff, 2);
00240         }
00241 
00242         // Enable 24h Mode
00243         if ((rc = DS1307RtcReadRegs(0x02, &data, 1)) == 0) {
00244             buff[0] = 0x02;
00245             buff[1] = data & 0xBF; //0b10111111;
00246             rc = DS1307RtcWrite(buff, 2);
00247         }
00248     }
00249     return rc;
00250 }
00251 
00252 NUTRTC rtcDs1307 = {
00253     DS1307Init,         
00254     DS1307RtcGetClock,  
00255     DS1307RtcSetClock,  
00256     NULL,               
00257     NULL,               
00258     NULL,               
00259     NULL                
00260 };