Contiki 2.6

ds1629.c

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 }