Contiki 2.6
|
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.h" 00050 #include "dev/ds1629.h" 00051 00052 #define SDA_HIGH (P5OUT |= 0x01) /* RTC data line high */ 00053 #define SDA_LOW (P5OUT &= 0xFE) /* RTC data line low */ 00054 #define SCL_HIGH (P5OUT |= 0x02) /* RTC clock line high */ 00055 #define SCL_LOW (P5OUT &= 0xFD) /* RTC clock line low */ 00056 #define BUS_READ 0x9F 00057 #define BUS_WRITE 0x9E 00058 #define ACC_CSR 0xAC /* Access Configuration/Control Register */ 00059 #define ACC_CLOCK 0xC0 /* Access Clock Register */ 00060 #define ACC_CLOCK_ALARM 0xC7 /* Access Clock Alarm Register */ 00061 #define ACC_TH 0xA1 /* Access Thermostat Setpoint High */ 00062 #define ACC_TL 0xA2 /* Access Thermostat Setpoint Low */ 00063 #define ACC_CSRAM 0x17 /* Access Clock 32 byte SRAM */ 00064 #define ACC_RT 0xAA /* Access Read Temperatur Register */ 00065 #define CSR_OS1 (0x80) 00066 #define CSR_OS0 (0x40) 00067 #define CSR_A1 (0x20) 00068 #define CSR_A0 (0x10) 00069 #define CSR_CNV (0x04) 00070 #define CSR_POL (0x02) 00071 #define CSR_1SH (0x01) 00072 #define CSR_DEFAULT (CSR_OS1 + CSR_OS0 + CSR_A1 + CSR_CNV + CSR_1SH + CSR_POL) 00073 00074 /** 00075 * Temperature type (built on a signed int). It's a signed (twos complement) 00076 * fixed point value with 8 bits before comma and 7 bits after. So Bit 15 is 00077 * sign, Bit14-7 is before comma and Bit 6-0 after comma. 00078 * 00079 * @since 2.0 00080 */ 00081 typedef union { unsigned int u; signed int s; } temp_t; 00082 00083 /*--------------------------------------------------------------------------*/ 00084 /* Puts the start condition on bus. */ 00085 static void 00086 cl_start(void) 00087 { 00088 P5DIR |= 0x03; /* ensure: P50(SDA), P51(SCL) output */ 00089 SCL_LOW; _NOP(); _NOP(); 00090 SDA_HIGH; _NOP(); _NOP(); 00091 SCL_HIGH; _NOP(); _NOP(); 00092 SDA_LOW; _NOP(); _NOP(); 00093 SCL_LOW; _NOP(); _NOP(); 00094 } 00095 /*--------------------------------------------------------------------------*/ 00096 /* Puts the stop condition on bus. */ 00097 static void 00098 cl_stop() 00099 { 00100 SCL_LOW; _NOP(); _NOP(); 00101 SDA_LOW; _NOP(); _NOP(); 00102 SCL_HIGH; _NOP(); _NOP(); 00103 SDA_HIGH; _NOP(); _NOP(); 00104 SCL_LOW; _NOP(); _NOP(); 00105 P5DIR &= ~0x03; 00106 } 00107 /*--------------------------------------------------------------------------*/ 00108 /* Writes a byte on the bus, returns the acknowledge bit. */ 00109 static uint16_t 00110 cl_writeOnBus(uint8_t byte) 00111 { 00112 uint16_t i, ack; 00113 for(i=0;i<8;i++) { 00114 if(byte & 0x80) SDA_HIGH; else SDA_LOW; 00115 SCL_HIGH; 00116 byte = byte << 1; _NOP(); 00117 SCL_LOW; _NOP(); 00118 } 00119 /* check ack */ 00120 P5DIR &= 0xFE; /* P50(SDA) input */ 00121 SCL_HIGH; 00122 if(P5IN & 0x01) ack = 0; else ack = 1; /* test if ack=0, else error */ 00123 _NOP(); 00124 SCL_LOW; 00125 P5DIR |= 0x01; /* P50(SDA) output */ 00126 return ack; 00127 } 00128 /*--------------------------------------------------------------------------*/ 00129 static uint8_t 00130 cl_readFromBus(uint16_t ack) 00131 { 00132 uint16_t i; 00133 uint8_t byte = 0; 00134 P5DIR &= 0xFE; /* P50(SDA) input */ 00135 for(i=0;i<8;i++) { 00136 byte = byte << 1; 00137 SCL_HIGH; 00138 if(P5IN & 0x01) byte |= 0x01; else byte &= 0xFE; 00139 SCL_LOW; 00140 } 00141 P5DIR |= 0x01; /* P50(SDA) output */ 00142 if(ack) SDA_LOW; else SDA_HIGH; 00143 SCL_HIGH; 00144 SCL_LOW; 00145 return byte; 00146 } 00147 /*--------------------------------------------------------------------------*/ 00148 static uint16_t 00149 getReg16bit(uint8_t acc, uint16_t bitmask) 00150 { 00151 uint16_t config = 0; 00152 do cl_start(); 00153 while(!cl_writeOnBus(BUS_WRITE)); 00154 cl_writeOnBus(acc); 00155 cl_start(); 00156 cl_writeOnBus(BUS_READ); 00157 config = cl_readFromBus(1); 00158 config = config << 8; 00159 config += cl_readFromBus(0); 00160 cl_stop(); 00161 config &= bitmask; 00162 _NOP(); 00163 _NOP(); 00164 return config; 00165 } 00166 /*--------------------------------------------------------------------------*/ 00167 /* Only first 8 bit of Configuration Status Register can be set */ 00168 static void 00169 setCSReg(uint8_t setting) 00170 { 00171 do cl_start(); 00172 while(!cl_writeOnBus(BUS_WRITE)); 00173 cl_writeOnBus(ACC_CSR); 00174 cl_writeOnBus(setting); 00175 cl_stop(); 00176 _NOP(); 00177 _NOP(); 00178 _NOP(); 00179 _NOP(); 00180 } 00181 /*--------------------------------------------------------------------------*/ 00182 static void 00183 System_startConversion(void) 00184 { 00185 do cl_start(); /* do start until BUS_WRITE is acked */ 00186 while(!cl_writeOnBus(BUS_WRITE)); /* control byte */ 00187 cl_writeOnBus(0xEE); /* start conversion */ 00188 cl_stop(); 00189 } 00190 /*--------------------------------------------------------------------------*/ 00191 /* RTC initialization. Initializes RTC with ::CSR_DEFAULT. */ 00192 static void 00193 initClock(void) 00194 { 00195 uint8_t csr = getReg16bit(ACC_CSR,0xFF00) >> 8; 00196 if(csr!=CSR_DEFAULT) setCSReg(CSR_DEFAULT); /* if desired config isnt in clock => set it */ 00197 /* IMPORTANT: Ensure quartz is generating 32768 Hz */ 00198 /* (sometimes CH bit gets set when clock is read while reset) */ 00199 do cl_start(); /* Do start until BUS_WRITE is acked. */ 00200 while(!cl_writeOnBus(BUS_WRITE)); /* Send control byte */ 00201 cl_writeOnBus(ACC_CLOCK); /* Send command byte ::ACC_CLOCK. */ 00202 cl_writeOnBus(0x00); /* Send starting address 0x00. */ 00203 cl_writeOnBus(0x00); /* Set CH to 0, tseconds and seconds will also be reset! */ 00204 cl_stop(); /* Stop condition. */ 00205 } 00206 /*--------------------------------------------------------------------------*/ 00207 void 00208 ds1629_init() 00209 { 00210 initClock(); 00211 } 00212 /*--------------------------------------------------------------------------*/ 00213 void 00214 ds1629_start() 00215 { 00216 System_startConversion(); 00217 } 00218 /*--------------------------------------------------------------------------*/ 00219 signed int 00220 ds1629_temperature() 00221 { 00222 temp_t temperature; 00223 00224 ds1629_start(); 00225 00226 temperature.u = getReg16bit(ACC_RT,0xFFFF); 00227 return temperature.s; 00228 }