📄 ds1629.c
字号:
/*Copyright 2005, Freie Universitaet Berlin. All rights reserved.These sources were developed at the Freie Universit鋞 Berlin, ComputerSystems and Telematics group.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions aremet:- Redistributions of source code must retain the above copyrightnotice, this list of conditions and the following disclaimer.- Redistributions in binary form must reproduce the above copyrightnotice, this list of conditions and the following disclaimer in thedocumentation and/or other materials provided with the distribution.- Neither the name of Freie Universitaet Berlin (FUB) nor the names of itscontributors may be used to endorse or promote products derived fromthis 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, expressor implied including, but not limited to, representations orwarranties of non-infringement, merchantability or fitness for aparticular purpose. In no event shall FUB or contributors be liablefor any direct, indirect, incidental, special, exemplary, orconsequential damages (including, but not limited to, procurement ofsubstitute goods or services; loss of use, data, or profits; orbusiness interruption) however caused and on any theory of liability,whether in contract, strict liability, or tort (including negligenceor otherwise) arising in any way out of the use of this software, evenif 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 sitehttp://scatterweb.mi.fu-berlin.de and the mailinglistscatterweb@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 voidcl_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 voidcl_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_tcl_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_tcl_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_tgetReg16bit(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 voidsetCSReg(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 voidSystem_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 voidinitClock(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. */}/*--------------------------------------------------------------------------*/voidds1629_init(){ initClock();}/*--------------------------------------------------------------------------*/voidds1629_start(){ System_startConversion();}/*--------------------------------------------------------------------------*/signed intds1629_temperature(){ temp_t temperature; ds1629_start(); temperature.u = getReg16bit(ACC_RT,0xFFFF); return temperature.s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -