00001 /* 00002 Copyright 2005, Freie Universitaet Berlin. All rights reserved. 00003 00004 These sources were developed at the Freie Universität Berlin, Computer 00005 Systems and Telematics group. 00006 00007 Redistribution and use in source and binary forms, with or without 00008 modification, are permitted provided that the following conditions are 00009 met: 00010 00011 - Redistributions of source code must retain the above copyright 00012 notice, this list of conditions and the following disclaimer. 00013 00014 - Redistributions in binary form must reproduce the above copyright 00015 notice, this list of conditions and the following disclaimer in the 00016 documentation and/or other materials provided with the distribution. 00017 00018 - Neither the name of Freie Universitaet Berlin (FUB) nor the names of its 00019 contributors may be used to endorse or promote products derived from 00020 this software without specific prior written permission. 00021 00022 This software is provided by FUB and the contributors on an "as is" 00023 basis, without any representations or warranties of any kind, express 00024 or implied including, but not limited to, representations or 00025 warranties of non-infringement, merchantability or fitness for a 00026 particular purpose. In no event shall FUB or contributors be liable 00027 for any direct, indirect, incidental, special, exemplary, or 00028 consequential damages (including, but not limited to, procurement of 00029 substitute goods or services; loss of use, data, or profits; or 00030 business interruption) however caused and on any theory of liability, 00031 whether in contract, strict liability, or tort (including negligence 00032 or otherwise) arising in any way out of the use of this software, even 00033 if advised of the possibility of such damage. 00034 00035 This implementation was developed by the CST group at the FUB. 00036 00037 For documentation and questions please use the web site 00038 http://scatterweb.mi.fu-berlin.de and the mailinglist 00039 scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). 00040 Berlin, 2005 00041 */ 00042 00043 /** 00044 * Part of the source code from ScatterWeb 2.2 (ScatterWeb.{Data,System}.c) 00045 * released by Freie Universitaet Berlin has been reworked and 00046 * reformatted to fit the Contiki ESB port. 00047 */ 00048 00049 #include "contiki-conf.h" 00050 #include "dev/ds1629.h" 00051 #include <io.h> 00052 00053 #define SDA_HIGH (P5OUT |= 0x01) /* RTC data line high */ 00054 #define SDA_LOW (P5OUT &= 0xFE) /* RTC data line low */ 00055 #define SCL_HIGH (P5OUT |= 0x02) /* RTC clock line high */ 00056 #define SCL_LOW (P5OUT &= 0xFD) /* RTC clock line low */ 00057 #define BUS_READ 0x9F 00058 #define BUS_WRITE 0x9E 00059 #define ACC_CSR 0xAC /* Access Configuration/Control Register */ 00060 #define ACC_CLOCK 0xC0 /* Access Clock Register */ 00061 #define ACC_CLOCK_ALARM 0xC7 /* Access Clock Alarm Register */ 00062 #define ACC_TH 0xA1 /* Access Thermostat Setpoint High */ 00063 #define ACC_TL 0xA2 /* Access Thermostat Setpoint Low */ 00064 #define ACC_CSRAM 0x17 /* Access Clock 32 byte SRAM */ 00065 #define ACC_RT 0xAA /* Access Read Temperatur Register */ 00066 #define CSR_OS1 (0x80) 00067 #define CSR_OS0 (0x40) 00068 #define CSR_A1 (0x20) 00069 #define CSR_A0 (0x10) 00070 #define CSR_CNV (0x04) 00071 #define CSR_POL (0x02) 00072 #define CSR_1SH (0x01) 00073 #define CSR_DEFAULT (CSR_OS1 + CSR_OS0 + CSR_A1 + CSR_CNV + CSR_1SH + CSR_POL) 00074 00075 /** 00076 * Temperature type (built on a signed int). It's a signed (twos complement) 00077 * fixed point value with 8 bits before comma and 7 bits after. So Bit 15 is 00078 * sign, Bit14-7 is before comma and Bit 6-0 after comma. 00079 * 00080 * @since 2.0 00081 */ 00082 typedef union { unsigned int u; signed int s; } temp_t; 00083 00084 /*--------------------------------------------------------------------------*/ 00085 /* Puts the start condition on bus. */ 00086 static void 00087 cl_start(void) 00088 { 00089 P5DIR |= 0x03; /* ensure: P50(SDA), P51(SCL) output */ 00090 SCL_LOW; _NOP(); _NOP(); 00091 SDA_HIGH; _NOP(); _NOP(); 00092 SCL_HIGH; _NOP(); _NOP(); 00093 SDA_LOW; _NOP(); _NOP(); 00094 SCL_LOW; _NOP(); _NOP(); 00095 } 00096 /*--------------------------------------------------------------------------*/ 00097 /* Puts the stop condition on bus. */ 00098 static void 00099 cl_stop() 00100 { 00101 SCL_LOW; _NOP(); _NOP(); 00102 SDA_LOW; _NOP(); _NOP(); 00103 SCL_HIGH; _NOP(); _NOP(); 00104 SDA_HIGH; _NOP(); _NOP(); 00105 SCL_LOW; _NOP(); _NOP(); 00106 P5DIR &= ~0x03; 00107 } 00108 /*--------------------------------------------------------------------------*/ 00109 /* Writes a byte on the bus, returns the acknowledge bit. */ 00110 static u16_t 00111 cl_writeOnBus(u8_t byte) 00112 { 00113 u16_t i, ack; 00114 for(i=0;i<8;i++) { 00115 if(byte & 0x80) SDA_HIGH; else SDA_LOW; 00116 SCL_HIGH; 00117 byte = byte << 1; _NOP(); 00118 SCL_LOW; _NOP(); 00119 } 00120 /* check ack */ 00121 P5DIR &= 0xFE; /* P50(SDA) input */ 00122 SCL_HIGH; 00123 if(P5IN & 0x01) ack = 0; else ack = 1; /* test if ack=0, else error */ 00124 _NOP(); 00125 SCL_LOW; 00126 P5DIR |= 0x01; /* P50(SDA) output */ 00127 return ack; 00128 } 00129 /*--------------------------------------------------------------------------*/ 00130 static u8_t 00131 cl_readFromBus(u16_t ack) 00132 { 00133 u16_t i; 00134 u8_t byte = 0; 00135 P5DIR &= 0xFE; /* P50(SDA) input */ 00136 for(i=0;i<8;i++) { 00137 byte = byte << 1; 00138 SCL_HIGH; 00139 if(P5IN & 0x01) byte |= 0x01; else byte &= 0xFE; 00140 SCL_LOW; 00141 } 00142 P5DIR |= 0x01; /* P50(SDA) output */ 00143 if(ack) SDA_LOW; else SDA_HIGH; 00144 SCL_HIGH; 00145 SCL_LOW; 00146 return byte; 00147 } 00148 /*--------------------------------------------------------------------------*/ 00149 static u16_t 00150 getReg16bit(u8_t acc, u16_t bitmask) 00151 { 00152 u16_t config = 0; 00153 do cl_start(); 00154 while(!cl_writeOnBus(BUS_WRITE)); 00155 cl_writeOnBus(acc); 00156 cl_start(); 00157 cl_writeOnBus(BUS_READ); 00158 config = cl_readFromBus(1); 00159 config = config << 8; 00160 config += cl_readFromBus(0); 00161 cl_stop(); 00162 config &= bitmask; 00163 _NOP(); 00164 _NOP(); 00165 return config; 00166 } 00167 /*--------------------------------------------------------------------------*/ 00168 /* Only first 8 bit of Configuration Status Register can be set */ 00169 static void 00170 setCSReg(u8_t setting) 00171 { 00172 do cl_start(); 00173 while(!cl_writeOnBus(BUS_WRITE)); 00174 cl_writeOnBus(ACC_CSR); 00175 cl_writeOnBus(setting); 00176 cl_stop(); 00177 _NOP(); 00178 _NOP(); 00179 _NOP(); 00180 _NOP(); 00181 } 00182 /*--------------------------------------------------------------------------*/ 00183 static void 00184 System_startConversion(void) 00185 { 00186 do cl_start(); /* do start until BUS_WRITE is acked */ 00187 while(!cl_writeOnBus(BUS_WRITE)); /* control byte */ 00188 cl_writeOnBus(0xEE); /* start conversion */ 00189 cl_stop(); 00190 } 00191 /*--------------------------------------------------------------------------*/ 00192 /* RTC initialization. Initializes RTC with ::CSR_DEFAULT. */ 00193 static void 00194 initClock(void) 00195 { 00196 u8_t csr = getReg16bit(ACC_CSR,0xFF00) >> 8; 00197 if(csr!=CSR_DEFAULT) setCSReg(CSR_DEFAULT); /* if desired config isnt in clock => set it */ 00198 /* IMPORTANT: Ensure quartz is generating 32768 Hz */ 00199 /* (sometimes CH bit gets set when clock is read while reset) */ 00200 do cl_start(); /* Do start until BUS_WRITE is acked. */ 00201 while(!cl_writeOnBus(BUS_WRITE)); /* Send control byte */ 00202 cl_writeOnBus(ACC_CLOCK); /* Send command byte ::ACC_CLOCK. */ 00203 cl_writeOnBus(0x00); /* Send starting address 0x00. */ 00204 cl_writeOnBus(0x00); /* Set CH to 0, tseconds and seconds will also be reset! */ 00205 cl_stop(); /* Stop condition. */ 00206 } 00207 /*--------------------------------------------------------------------------*/ 00208 void 00209 ds1629_init() 00210 { 00211 initClock(); 00212 } 00213 /*--------------------------------------------------------------------------*/ 00214 void 00215 ds1629_start() 00216 { 00217 System_startConversion(); 00218 } 00219 /*--------------------------------------------------------------------------*/ 00220 signed int 00221 ds1629_temperature() 00222 { 00223 temp_t temperature; 00224 00225 ds1629_start(); 00226 00227 temperature.u = getReg16bit(ACC_RT,0xFFFF); 00228 return temperature.s; 00229 }