mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-12-23 01:29:33 +00:00
230 lines
7.5 KiB
C
230 lines
7.5 KiB
C
|
/*
|
|||
|
Copyright 2005, Freie Universitaet Berlin. All rights reserved.
|
|||
|
|
|||
|
These sources were developed at the Freie Universit<EFBFBD>t Berlin, Computer
|
|||
|
Systems and Telematics group.
|
|||
|
|
|||
|
Redistribution and use in source and binary forms, with or without
|
|||
|
modification, are permitted provided that the following conditions are
|
|||
|
met:
|
|||
|
|
|||
|
- Redistributions of source code must retain the above copyright
|
|||
|
notice, this list of conditions and the following disclaimer.
|
|||
|
|
|||
|
- Redistributions in binary form must reproduce the above copyright
|
|||
|
notice, this list of conditions and the following disclaimer in the
|
|||
|
documentation and/or other materials provided with the distribution.
|
|||
|
|
|||
|
- Neither the name of Freie Universitaet Berlin (FUB) nor the names of its
|
|||
|
contributors may be used to endorse or promote products derived from
|
|||
|
this software without specific prior written permission.
|
|||
|
|
|||
|
This software is provided by FUB and the contributors on an "as is"
|
|||
|
basis, without any representations or warranties of any kind, express
|
|||
|
or implied including, but not limited to, representations or
|
|||
|
warranties of non-infringement, merchantability or fitness for a
|
|||
|
particular purpose. In no event shall FUB or contributors be liable
|
|||
|
for any direct, indirect, incidental, special, exemplary, or
|
|||
|
consequential damages (including, but not limited to, procurement of
|
|||
|
substitute goods or services; loss of use, data, or profits; or
|
|||
|
business interruption) however caused and on any theory of liability,
|
|||
|
whether in contract, strict liability, or tort (including negligence
|
|||
|
or otherwise) arising in any way out of the use of this software, even
|
|||
|
if advised of the possibility of such damage.
|
|||
|
|
|||
|
This implementation was developed by the CST group at the FUB.
|
|||
|
|
|||
|
For documentation and questions please use the web site
|
|||
|
http://scatterweb.mi.fu-berlin.de and the mailinglist
|
|||
|
scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website).
|
|||
|
Berlin, 2005
|
|||
|
*/
|
|||
|
|
|||
|
/**
|
|||
|
* Part of the source code from ScatterWeb 2.2 (ScatterWeb.{Data,System}.c)
|
|||
|
* released by Freie Universitaet Berlin has been reworked and
|
|||
|
* reformatted to fit the Contiki ESB port.
|
|||
|
*/
|
|||
|
|
|||
|
#include "contiki-conf.h"
|
|||
|
#include "dev/ds1629.h"
|
|||
|
#include <io.h>
|
|||
|
|
|||
|
#define SDA_HIGH (P5OUT |= 0x01) /* RTC data line high */
|
|||
|
#define SDA_LOW (P5OUT &= 0xFE) /* RTC data line low */
|
|||
|
#define SCL_HIGH (P5OUT |= 0x02) /* RTC clock line high */
|
|||
|
#define SCL_LOW (P5OUT &= 0xFD) /* RTC clock line low */
|
|||
|
#define BUS_READ 0x9F
|
|||
|
#define BUS_WRITE 0x9E
|
|||
|
#define ACC_CSR 0xAC /* Access Configuration/Control Register */
|
|||
|
#define ACC_CLOCK 0xC0 /* Access Clock Register */
|
|||
|
#define ACC_CLOCK_ALARM 0xC7 /* Access Clock Alarm Register */
|
|||
|
#define ACC_TH 0xA1 /* Access Thermostat Setpoint High */
|
|||
|
#define ACC_TL 0xA2 /* Access Thermostat Setpoint Low */
|
|||
|
#define ACC_CSRAM 0x17 /* Access Clock 32 byte SRAM */
|
|||
|
#define ACC_RT 0xAA /* Access Read Temperatur Register */
|
|||
|
#define CSR_OS1 (0x80)
|
|||
|
#define CSR_OS0 (0x40)
|
|||
|
#define CSR_A1 (0x20)
|
|||
|
#define CSR_A0 (0x10)
|
|||
|
#define CSR_CNV (0x04)
|
|||
|
#define CSR_POL (0x02)
|
|||
|
#define CSR_1SH (0x01)
|
|||
|
#define CSR_DEFAULT (CSR_OS1 + CSR_OS0 + CSR_A1 + CSR_CNV + CSR_1SH + CSR_POL)
|
|||
|
|
|||
|
/**
|
|||
|
* Temperature type (built on a signed int). It's a signed (twos complement)
|
|||
|
* fixed point value with 8 bits before comma and 7 bits after. So Bit 15 is
|
|||
|
* sign, Bit14-7 is before comma and Bit 6-0 after comma.
|
|||
|
*
|
|||
|
* @since 2.0
|
|||
|
*/
|
|||
|
typedef union { unsigned int u; signed int s; } temp_t;
|
|||
|
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
/* Puts the start condition on bus. */
|
|||
|
static void
|
|||
|
cl_start(void)
|
|||
|
{
|
|||
|
P5DIR |= 0x03; /* ensure: P50(SDA), P51(SCL) output */
|
|||
|
SCL_LOW; _NOP(); _NOP();
|
|||
|
SDA_HIGH; _NOP(); _NOP();
|
|||
|
SCL_HIGH; _NOP(); _NOP();
|
|||
|
SDA_LOW; _NOP(); _NOP();
|
|||
|
SCL_LOW; _NOP(); _NOP();
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
/* Puts the stop condition on bus. */
|
|||
|
static void
|
|||
|
cl_stop()
|
|||
|
{
|
|||
|
SCL_LOW; _NOP(); _NOP();
|
|||
|
SDA_LOW; _NOP(); _NOP();
|
|||
|
SCL_HIGH; _NOP(); _NOP();
|
|||
|
SDA_HIGH; _NOP(); _NOP();
|
|||
|
SCL_LOW; _NOP(); _NOP();
|
|||
|
P5DIR &= ~0x03;
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
/* Writes a byte on the bus, returns the acknowledge bit. */
|
|||
|
static u16_t
|
|||
|
cl_writeOnBus(u8_t byte)
|
|||
|
{
|
|||
|
u16_t i, ack;
|
|||
|
for(i=0;i<8;i++) {
|
|||
|
if(byte & 0x80) SDA_HIGH; else SDA_LOW;
|
|||
|
SCL_HIGH;
|
|||
|
byte = byte << 1; _NOP();
|
|||
|
SCL_LOW; _NOP();
|
|||
|
}
|
|||
|
/* check ack */
|
|||
|
P5DIR &= 0xFE; /* P50(SDA) input */
|
|||
|
SCL_HIGH;
|
|||
|
if(P5IN & 0x01) ack = 0; else ack = 1; /* test if ack=0, else error */
|
|||
|
_NOP();
|
|||
|
SCL_LOW;
|
|||
|
P5DIR |= 0x01; /* P50(SDA) output */
|
|||
|
return ack;
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
static u8_t
|
|||
|
cl_readFromBus(u16_t ack)
|
|||
|
{
|
|||
|
u16_t i;
|
|||
|
u8_t byte = 0;
|
|||
|
P5DIR &= 0xFE; /* P50(SDA) input */
|
|||
|
for(i=0;i<8;i++) {
|
|||
|
byte = byte << 1;
|
|||
|
SCL_HIGH;
|
|||
|
if(P5IN & 0x01) byte |= 0x01; else byte &= 0xFE;
|
|||
|
SCL_LOW;
|
|||
|
}
|
|||
|
P5DIR |= 0x01; /* P50(SDA) output */
|
|||
|
if(ack) SDA_LOW; else SDA_HIGH;
|
|||
|
SCL_HIGH;
|
|||
|
SCL_LOW;
|
|||
|
return byte;
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
static u16_t
|
|||
|
getReg16bit(u8_t acc, u16_t bitmask)
|
|||
|
{
|
|||
|
u16_t config = 0;
|
|||
|
do cl_start();
|
|||
|
while(!cl_writeOnBus(BUS_WRITE));
|
|||
|
cl_writeOnBus(acc);
|
|||
|
cl_start();
|
|||
|
cl_writeOnBus(BUS_READ);
|
|||
|
config = cl_readFromBus(1);
|
|||
|
config = config << 8;
|
|||
|
config += cl_readFromBus(0);
|
|||
|
cl_stop();
|
|||
|
config &= bitmask;
|
|||
|
_NOP();
|
|||
|
_NOP();
|
|||
|
return config;
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
/* Only first 8 bit of Configuration Status Register can be set */
|
|||
|
static void
|
|||
|
setCSReg(u8_t setting)
|
|||
|
{
|
|||
|
do cl_start();
|
|||
|
while(!cl_writeOnBus(BUS_WRITE));
|
|||
|
cl_writeOnBus(ACC_CSR);
|
|||
|
cl_writeOnBus(setting);
|
|||
|
cl_stop();
|
|||
|
_NOP();
|
|||
|
_NOP();
|
|||
|
_NOP();
|
|||
|
_NOP();
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
static void
|
|||
|
System_startConversion(void)
|
|||
|
{
|
|||
|
do cl_start(); /* do start until BUS_WRITE is acked */
|
|||
|
while(!cl_writeOnBus(BUS_WRITE)); /* control byte */
|
|||
|
cl_writeOnBus(0xEE); /* start conversion */
|
|||
|
cl_stop();
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
/* RTC initialization. Initializes RTC with ::CSR_DEFAULT. */
|
|||
|
static void
|
|||
|
initClock(void)
|
|||
|
{
|
|||
|
u8_t csr = getReg16bit(ACC_CSR,0xFF00) >> 8;
|
|||
|
if(csr!=CSR_DEFAULT) setCSReg(CSR_DEFAULT); /* if desired config isnt in clock => set it */
|
|||
|
/* IMPORTANT: Ensure quartz is generating 32768 Hz */
|
|||
|
/* (sometimes CH bit gets set when clock is read while reset) */
|
|||
|
do cl_start(); /* Do start until BUS_WRITE is acked. */
|
|||
|
while(!cl_writeOnBus(BUS_WRITE)); /* Send control byte */
|
|||
|
cl_writeOnBus(ACC_CLOCK); /* Send command byte ::ACC_CLOCK. */
|
|||
|
cl_writeOnBus(0x00); /* Send starting address 0x00. */
|
|||
|
cl_writeOnBus(0x00); /* Set CH to 0, tseconds and seconds will also be reset! */
|
|||
|
cl_stop(); /* Stop condition. */
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
void
|
|||
|
ds1629_init()
|
|||
|
{
|
|||
|
initClock();
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
void
|
|||
|
ds1629_start()
|
|||
|
{
|
|||
|
System_startConversion();
|
|||
|
}
|
|||
|
/*--------------------------------------------------------------------------*/
|
|||
|
signed int
|
|||
|
ds1629_temperature()
|
|||
|
{
|
|||
|
temp_t temperature;
|
|||
|
|
|||
|
ds1629_start();
|
|||
|
|
|||
|
temperature.u = getReg16bit(ACC_RT,0xFFFF);
|
|||
|
return temperature.s;
|
|||
|
}
|