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 
00062 #include <cfg/os.h>
00063 #include <dev/twif.h>
00064 #include <sys/event.h>
00065 #include <sys/timer.h>
00066 
00067 #include <stdlib.h>
00068 #include <string.h>
00069 
00070 #include <dev/ds1307rtc.h>
00071 
00072 #ifndef I2C_SLA_RTC
00073 #define I2C_SLA_RTC     0x68    // 7 bit address!
00074 #endif
00075 
00076 
00086 int DS1307RtcReadRegs(u_char reg, u_char *buff, size_t cnt)
00087 {
00088     int rc = -1;
00089     u_char wbuf[1];
00090 
00091     wbuf[0] = reg;
00092     if (TwMasterTransact(I2C_SLA_RTC, wbuf, 1, buff, cnt, NUT_WAIT_INFINITE) == cnt) {
00093         rc = 0;
00094     }
00095     return rc;
00096 }
00097 
00107 int DS1307RtcWrite(CONST u_char *buff, size_t cnt)
00108 {
00109     int rc;
00110 
00111     rc = TwMasterTransact(I2C_SLA_RTC, buff, cnt, 0, 0, NUT_WAIT_INFINITE);
00112     return rc;
00113 }
00114 
00123 int DS1307RtcGetClock(struct _tm *tm)
00124 {
00125     int rc;
00126     u_char data[7];
00127 
00128     if ((rc = DS1307RtcReadRegs(0x00, data, 7)) == 0) {
00129         tm->tm_sec  = BCD2BIN(data[0]);
00130         tm->tm_min  = BCD2BIN(data[1]);
00131         tm->tm_hour = BCD2BIN(data[2] & 0x3F);
00132         tm->tm_mday = BCD2BIN(data[4]);
00133         tm->tm_mon  = BCD2BIN(data[5]) - 1;
00134         tm->tm_year = BCD2BIN(data[6]) + 100;
00135         tm->tm_wday = data[3] - 1;
00136     }
00137     return rc;
00138 }
00139 
00148 int DS1307RtcSetClock(CONST struct _tm *tm)
00149 {
00150     u_char data[8];
00151 
00152     memset(data, 0, sizeof(data));
00153     if (tm) {
00154         data[0] = 0x00;     // adress 0
00155         data[1] = BIN2BCD(tm->tm_sec);
00156         data[2] = BIN2BCD(tm->tm_min);
00157         data[3] = BIN2BCD(tm->tm_hour) & 0x3f; // 24 hour mode
00158         data[5] = BIN2BCD(tm->tm_mday);
00159         data[6] = BIN2BCD(tm->tm_mon + 1);
00160         data[7] = BIN2BCD(tm->tm_year - 100);
00161         data[4] = tm->tm_wday + 1;
00162     }
00163     return DS1307RtcWrite(data, 8);
00164 }
00165 
00175 int DS1307RamRead(u_char addr, u_char *buff, size_t cnt)
00176 {
00177     int rc = -1;
00178 
00179     // Range check
00180     if ((addr>=0x08) && (addr<=0x3F)) {
00181         rc = DS1307RtcReadRegs(addr, buff, cnt);
00182     }
00183 
00184     return rc;
00185 }
00186 
00196 int DS1307RamWrite(u_char addr, CONST void *buff, size_t len)
00197 {
00198     int rc = 0;
00199     u_char *wbuf;
00200     CONST u_char *wp = buff;
00201 
00202     /* Allocate and set a TWI write buffer. */
00203     if ((wbuf = malloc(len + 1)) == 0) {
00204         rc = -1;
00205     } else {
00206         wbuf[0] = addr;
00207         memcpy(wbuf + 1, wp, len);
00208 
00209         /* Send the write buffer. */
00210         rc = TwMasterTransact(I2C_SLA_RTC, wbuf, len + 1, 0, 0, NUT_WAIT_INFINITE);
00211 
00212         /* Release the buffer. */
00213         free(wbuf);
00214     }
00215 
00216     return rc;
00217 }
00218 
00225 int DS1307Init(void)
00226 {
00227     int rc;
00228     u_char data;
00229     u_char buff[2];
00230 
00231     if ((rc = TwInit(0)) == 0 ) {
00232         // Enable Oszillator
00233         if ((rc = DS1307RtcReadRegs(0x00, &data, 1)) == 0) {
00234             buff[0] = 0x00;
00235             buff[1] = data & 0x7F; //0b01111111;
00236             rc = DS1307RtcWrite(buff, 2);
00237         }
00238 
00239         // Enable 24h Mode
00240         if ((rc = DS1307RtcReadRegs(0x02, &data, 1)) == 0) {
00241             buff[0] = 0x02;
00242             buff[1] = data & 0xBF; //0b10111111;
00243             rc = DS1307RtcWrite(buff, 2);
00244         }
00245     }
00246     return rc;
00247 }
00248 
00249 NUTRTC rtcDs1307 = {
00250     DS1307Init,         
00251     DS1307RtcGetClock,  
00252     DS1307RtcSetClock,  
00253     NULL,               
00254     NULL,               
00255     NULL,               
00256     NULL                
00257 };

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/