mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Refactor the I2C library API
This commit is contained in:
parent
5819690b42
commit
8a601d3a80
@ -45,6 +45,9 @@ BitBangI2C::BitBangI2C(uint8_t dataPin, uint8_t clockPin)
|
||||
: _dataPin(dataPin)
|
||||
, _clockPin(clockPin)
|
||||
, started(false)
|
||||
, acked(true)
|
||||
, inWrite(false)
|
||||
, readCount(0)
|
||||
{
|
||||
// Initially set the CLOCK and DATA lines to be outputs in the high state.
|
||||
pinMode(_clockPin, OUTPUT);
|
||||
@ -53,26 +56,11 @@ BitBangI2C::BitBangI2C(uint8_t dataPin, uint8_t clockPin)
|
||||
digitalWrite(_dataPin, HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
* \typedef BitBangI2C::ack_t
|
||||
* \brief Type that represents an I2C ACK or NACK indication.
|
||||
*/
|
||||
unsigned int BitBangI2C::maxTransferSize() const
|
||||
{
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* \var BitBangI2C::ACK
|
||||
* \brief Indicates that an I2C operation was acknowledged.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \var BitBangI2C::NACK
|
||||
* \brief Indicates that an I2C operation was not acknowledged.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Transmits an I2C start condition on the bus.
|
||||
*
|
||||
* \sa startRead(), startWrite()
|
||||
*/
|
||||
void BitBangI2C::start()
|
||||
{
|
||||
pinMode(_dataPin, OUTPUT);
|
||||
@ -87,11 +75,9 @@ void BitBangI2C::start()
|
||||
digitalWrite(_clockPin, LOW);
|
||||
i2cDelay();
|
||||
started = true;
|
||||
acked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Transmits an I2C stop condition on the bus.
|
||||
*/
|
||||
void BitBangI2C::stop()
|
||||
{
|
||||
pinMode(_dataPin, OUTPUT);
|
||||
@ -101,6 +87,7 @@ void BitBangI2C::stop()
|
||||
digitalWrite(_dataPin, HIGH);
|
||||
i2cDelay();
|
||||
started = false;
|
||||
inWrite = false;
|
||||
}
|
||||
|
||||
#define I2C_WRITE 0x00
|
||||
@ -108,84 +95,77 @@ void BitBangI2C::stop()
|
||||
#define I2C_READ 0x01
|
||||
#define I2C_READ10 0xF1
|
||||
|
||||
/**
|
||||
* \brief Starts a write operation by sending a start condition and the I2C control byte.
|
||||
*
|
||||
* The \a address must be the 7-bit or 10-bit address of the I2C slave
|
||||
* on the bus.
|
||||
*
|
||||
* Returns BitBangI2C::ACK or BitBangI2C::NACK to indicate whether the
|
||||
* read operation was acknowledged by the slave or not.
|
||||
*
|
||||
* \sa startWrite()
|
||||
*/
|
||||
BitBangI2C::ack_t BitBangI2C::startWrite(unsigned int address)
|
||||
void BitBangI2C::startWrite(unsigned int address)
|
||||
{
|
||||
start();
|
||||
inWrite = true;
|
||||
if (address < 0x80) {
|
||||
// 7-bit address.
|
||||
return write((uint8_t)((address << 1) | I2C_WRITE));
|
||||
write((uint8_t)((address << 1) | I2C_WRITE));
|
||||
} else {
|
||||
// 10-bit address.
|
||||
if (write((uint8_t)(((address >> 7) & 0x06)) | I2C_WRITE10) == NACK)
|
||||
return NACK;
|
||||
return write((uint8_t)address);
|
||||
write((uint8_t)(((address >> 7) & 0x06)) | I2C_WRITE10);
|
||||
write((uint8_t)address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Starts a read operation by sending the start condition and the I2C control byte.
|
||||
*
|
||||
* The \a address must be the 7-bit or 10-bit address of the I2C slave
|
||||
* on the bus.
|
||||
*
|
||||
* Returns BitBangI2C::ACK or BitBangI2C::NACK to indicate whether the
|
||||
* read operation was acknowledged by the slave or not.
|
||||
*
|
||||
* \sa startWrite()
|
||||
*/
|
||||
BitBangI2C::ack_t BitBangI2C::startRead(unsigned int address)
|
||||
{
|
||||
start();
|
||||
if (address < 0x80) {
|
||||
// 7-bit address.
|
||||
return write((uint8_t)((address << 1) | I2C_READ));
|
||||
} else {
|
||||
// 10-bit address.
|
||||
if (write((uint8_t)(((address >> 7) & 0x06)) | I2C_READ10) == NACK)
|
||||
return NACK;
|
||||
return write((uint8_t)address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes a single byte \a value on the I2C bus.
|
||||
*
|
||||
* Returns BitBangI2C::ACK or BitBangI2C::NACK to indicate whether the
|
||||
* slave acknowledged the byte or not.
|
||||
*/
|
||||
BitBangI2C::ack_t BitBangI2C::write(uint8_t value)
|
||||
void BitBangI2C::write(uint8_t value)
|
||||
{
|
||||
uint8_t mask = 0x80;
|
||||
while (mask != 0) {
|
||||
writeBit((value & mask) != 0);
|
||||
mask >>= 1;
|
||||
}
|
||||
return readBit();
|
||||
if (readBit()) // 0: ACK, 1: NACK
|
||||
acked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads a single byte from the I2C bus.
|
||||
*
|
||||
* If \a ack is BitBangI2C::ACK, then the byte is acknowledged. Otherwise
|
||||
* the byte will not be acknowledged.
|
||||
*/
|
||||
uint8_t BitBangI2C::read(ack_t ack)
|
||||
bool BitBangI2C::endWrite()
|
||||
{
|
||||
stop();
|
||||
return acked;
|
||||
}
|
||||
|
||||
bool BitBangI2C::startRead(unsigned int address, unsigned int count)
|
||||
{
|
||||
start();
|
||||
inWrite = false;
|
||||
if (address < 0x80) {
|
||||
// 7-bit address.
|
||||
write((uint8_t)((address << 1) | I2C_READ));
|
||||
} else {
|
||||
// 10-bit address.
|
||||
write((uint8_t)(((address >> 7) & 0x06)) | I2C_READ10);
|
||||
write((uint8_t)address);
|
||||
}
|
||||
if (!acked) {
|
||||
readCount = 0;
|
||||
return false;
|
||||
}
|
||||
readCount = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int BitBangI2C::available()
|
||||
{
|
||||
return readCount;
|
||||
}
|
||||
|
||||
uint8_t BitBangI2C::read()
|
||||
{
|
||||
uint8_t value = 0;
|
||||
for (uint8_t bit = 0; bit < 8; ++bit)
|
||||
value = (value << 1) | readBit();
|
||||
writeBit(ack);
|
||||
if (readCount > 1) {
|
||||
// More bytes left to read - send an ACK.
|
||||
writeBit(false);
|
||||
--readCount;
|
||||
} else {
|
||||
// Last byte - send the NACK and a stop condition.
|
||||
writeBit(true);
|
||||
stop();
|
||||
readCount = 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -23,31 +23,32 @@
|
||||
#ifndef BitBangI2C_h
|
||||
#define BitBangI2C_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "I2CMaster.h"
|
||||
|
||||
class BitBangI2C {
|
||||
class BitBangI2C : public I2CMaster {
|
||||
public:
|
||||
BitBangI2C(uint8_t dataPin, uint8_t clockPin);
|
||||
|
||||
typedef bool ack_t;
|
||||
unsigned int maxTransferSize() const;
|
||||
|
||||
static const ack_t ACK = false;
|
||||
static const ack_t NACK = true;
|
||||
void startWrite(unsigned int address);
|
||||
void write(uint8_t value);
|
||||
bool endWrite();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
ack_t startWrite(unsigned int address);
|
||||
ack_t startRead(unsigned int address);
|
||||
|
||||
ack_t write(uint8_t value);
|
||||
uint8_t read(ack_t ack = ACK);
|
||||
bool startRead(unsigned int address, unsigned int count);
|
||||
unsigned int available();
|
||||
uint8_t read();
|
||||
|
||||
private:
|
||||
uint8_t _dataPin;
|
||||
uint8_t _clockPin;
|
||||
bool started;
|
||||
bool acked;
|
||||
bool inWrite;
|
||||
unsigned int readCount;
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void writeBit(bool bit);
|
||||
bool readBit();
|
||||
};
|
||||
|
89
libraries/I2C/I2CMaster.cpp
Normal file
89
libraries/I2C/I2CMaster.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "I2CMaster.h"
|
||||
|
||||
/**
|
||||
* \class I2CMaster I2CMaster.h <I2CMaster.h>
|
||||
* \brief Abstract base class for I2C master implementations.
|
||||
*
|
||||
* \sa I2CMaster
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn unsigned int I2CMaster::maxTransferSize() const
|
||||
* \brief Returns the maximum number of bytes that can be read or written in a single request by this bus master.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn void I2CMaster::startWrite(unsigned int address)
|
||||
* \brief Starts a write operation by sending a start condition and the I2C control byte.
|
||||
*
|
||||
* The \a address must be the 7-bit or 10-bit address of the I2C slave
|
||||
* on the bus.
|
||||
*
|
||||
* \sa write(), endWrite(), startRead()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn void I2CMaster::write(uint8_t value)
|
||||
* \brief Writes a single byte \a value on the I2C bus.
|
||||
*
|
||||
* \sa startWrite(), endWrite()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn bool I2CMaster::endWrite()
|
||||
* \brief Ends the current write operation.
|
||||
*
|
||||
* Returns true if the write operation was acknowledged; false otherwise.
|
||||
*
|
||||
* \sa startWrite(), write()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn bool I2CMaster::startRead(unsigned int address, unsigned int count)
|
||||
* \brief Starts a read operation for \a count bytes by sending the start condition and the I2C control byte.
|
||||
*
|
||||
* The \a address must be the 7-bit or 10-bit address of the I2C slave
|
||||
* on the bus.
|
||||
*
|
||||
* Returns true if the read request was acknowledged by the I2C slave
|
||||
* or false otherwise. If true, this function should be followed by
|
||||
* \a count calls to read() to fetch the bytes.
|
||||
*
|
||||
* \sa available(), read(), startWrite()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn unsigned int I2CMaster::available()
|
||||
* \brief Returns the number of bytes that are still available for reading.
|
||||
*
|
||||
* \sa startRead(), read()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn uint8_t I2CMaster::read()
|
||||
* \brief Reads a single byte from the I2C bus.
|
||||
*
|
||||
* \sa startRead(), available()
|
||||
*/
|
41
libraries/I2C/I2CMaster.h
Normal file
41
libraries/I2C/I2CMaster.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef I2CMaster_h
|
||||
#define I2CMaster_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
class I2CMaster {
|
||||
public:
|
||||
virtual unsigned int maxTransferSize() const = 0;
|
||||
|
||||
virtual void startWrite(unsigned int address);
|
||||
virtual void write(uint8_t value) = 0;
|
||||
virtual bool endWrite() = 0;
|
||||
|
||||
virtual bool startRead(unsigned int address, unsigned int count) = 0;
|
||||
virtual unsigned int available() = 0;
|
||||
virtual uint8_t read() = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "DS1307RTC.h"
|
||||
#include "../I2C/BitBangI2C.h"
|
||||
#include "../I2C/I2CMaster.h"
|
||||
#include <WProgram.h>
|
||||
|
||||
/**
|
||||
@ -76,38 +76,29 @@
|
||||
*
|
||||
* \sa hasUpdates()
|
||||
*/
|
||||
DS1307RTC::DS1307RTC(BitBangI2C &bus, uint8_t oneHzPin)
|
||||
DS1307RTC::DS1307RTC(I2CMaster &bus, uint8_t oneHzPin)
|
||||
: _bus(&bus)
|
||||
, _oneHzPin(oneHzPin)
|
||||
, prevOneHz(false)
|
||||
, _isRealTime(true)
|
||||
{
|
||||
// Make sure the CH bit in register 0 is off or the clock won't update.
|
||||
if (_bus->startWrite(DS1307_I2C_ADDRESS) == BitBangI2C::ACK) {
|
||||
_bus->write(DS1307_SECOND);
|
||||
_bus->startRead(DS1307_I2C_ADDRESS);
|
||||
uint8_t value = _bus->read(BitBangI2C::NACK);
|
||||
_bus->stop();
|
||||
if ((value & 0x80) != 0) {
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_SECOND);
|
||||
_bus->write(value & 0x7F);
|
||||
_bus->stop();
|
||||
}
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_SECOND);
|
||||
if (_bus->startRead(DS1307_I2C_ADDRESS, 1)) {
|
||||
uint8_t value = _bus->read();
|
||||
if ((value & 0x80) != 0)
|
||||
writeRegister(DS1307_SECOND, value & 0x7F);
|
||||
} else {
|
||||
// Did not get an acknowledgement from the RTC chip.
|
||||
_isRealTime = false;
|
||||
_bus->stop();
|
||||
}
|
||||
|
||||
// Turn on the 1 Hz square wave signal if required.
|
||||
if (oneHzPin != 255 && _isRealTime) {
|
||||
pinMode(oneHzPin, INPUT);
|
||||
digitalWrite(oneHzPin, HIGH);
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_CONTROL);
|
||||
_bus->write(0x10);
|
||||
_bus->stop();
|
||||
writeRegister(DS1307_CONTROL, 0x10);
|
||||
}
|
||||
|
||||
// Initialize the alarms in the RTC chip's NVRAM.
|
||||
@ -168,11 +159,16 @@ void DS1307RTC::readTime(RTCTime *value)
|
||||
if (_isRealTime) {
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_SECOND);
|
||||
_bus->startRead(DS1307_I2C_ADDRESS);
|
||||
value->second = fromBCD(_bus->read() & 0x7F);
|
||||
value->minute = fromBCD(_bus->read());
|
||||
value->hour = fromHourBCD(_bus->read(BitBangI2C::NACK));
|
||||
_bus->stop();
|
||||
if (_bus->startRead(DS1307_I2C_ADDRESS, 3)) {
|
||||
value->second = fromBCD(_bus->read() & 0x7F);
|
||||
value->minute = fromBCD(_bus->read());
|
||||
value->hour = fromHourBCD(_bus->read());
|
||||
} else {
|
||||
// RTC chip is not responding.
|
||||
value->second = 0;
|
||||
value->minute = 0;
|
||||
value->hour = 0;
|
||||
}
|
||||
} else {
|
||||
RTC::readTime(value);
|
||||
}
|
||||
@ -186,11 +182,16 @@ void DS1307RTC::readDate(RTCDate *value)
|
||||
}
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_DATE);
|
||||
_bus->startRead(DS1307_I2C_ADDRESS);
|
||||
value->day = fromBCD(_bus->read());
|
||||
value->month = fromBCD(_bus->read());
|
||||
value->year = fromBCD(_bus->read(BitBangI2C::NACK)) + 2000;
|
||||
_bus->stop();
|
||||
if (_bus->startRead(DS1307_I2C_ADDRESS, 3)) {
|
||||
value->day = fromBCD(_bus->read());
|
||||
value->month = fromBCD(_bus->read());
|
||||
value->year = fromBCD(_bus->read()) + 2000;
|
||||
} else {
|
||||
// RTC chip is not responding.
|
||||
value->day = 1;
|
||||
value->month = 1;
|
||||
value->year = 2012;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t toBCD(uint8_t value)
|
||||
@ -206,7 +207,7 @@ void DS1307RTC::writeTime(const RTCTime *value)
|
||||
_bus->write(toBCD(value->second));
|
||||
_bus->write(toBCD(value->minute));
|
||||
_bus->write(toBCD(value->hour)); // Changes mode to 24-hour clock.
|
||||
_bus->stop();
|
||||
_bus->endWrite();
|
||||
} else {
|
||||
RTC::writeTime(value);
|
||||
}
|
||||
@ -220,7 +221,7 @@ void DS1307RTC::writeDate(const RTCDate *value)
|
||||
_bus->write(toBCD(value->day));
|
||||
_bus->write(toBCD(value->month));
|
||||
_bus->write(toBCD(value->year % 100));
|
||||
_bus->stop();
|
||||
_bus->endWrite();
|
||||
} else {
|
||||
RTC::writeDate(value);
|
||||
}
|
||||
@ -231,11 +232,16 @@ void DS1307RTC::readAlarm(uint8_t alarmNum, RTCAlarm *value)
|
||||
if (_isRealTime) {
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_ALARMS + alarmNum * DS1307_ALARM_SIZE);
|
||||
_bus->startRead(DS1307_I2C_ADDRESS);
|
||||
value->hour = fromBCD(_bus->read());
|
||||
value->minute = fromBCD(_bus->read());
|
||||
value->flags = _bus->read(BitBangI2C::NACK);
|
||||
_bus->stop();
|
||||
if (_bus->startRead(DS1307_I2C_ADDRESS, 3)) {
|
||||
value->hour = fromBCD(_bus->read());
|
||||
value->minute = fromBCD(_bus->read());
|
||||
value->flags = _bus->read();
|
||||
} else {
|
||||
// RTC chip is not responding.
|
||||
value->hour = 0;
|
||||
value->minute = 0;
|
||||
value->flags = 0;
|
||||
}
|
||||
} else {
|
||||
RTC::readAlarm(alarmNum, value);
|
||||
}
|
||||
@ -249,7 +255,7 @@ void DS1307RTC::writeAlarm(uint8_t alarmNum, const RTCAlarm *value)
|
||||
_bus->write(toBCD(value->hour));
|
||||
_bus->write(toBCD(value->minute));
|
||||
_bus->write(value->flags);
|
||||
_bus->stop();
|
||||
_bus->endWrite();
|
||||
} else {
|
||||
RTC::writeAlarm(alarmNum, value);
|
||||
}
|
||||
@ -257,37 +263,23 @@ void DS1307RTC::writeAlarm(uint8_t alarmNum, const RTCAlarm *value)
|
||||
|
||||
uint8_t DS1307RTC::readByte(uint8_t offset)
|
||||
{
|
||||
if (_isRealTime) {
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_NVRAM + offset);
|
||||
_bus->startRead(DS1307_I2C_ADDRESS);
|
||||
uint8_t value = _bus->read(BitBangI2C::NACK);
|
||||
_bus->stop();
|
||||
return value;
|
||||
} else {
|
||||
if (_isRealTime)
|
||||
return readRegister(DS1307_NVRAM + offset);
|
||||
else
|
||||
return RTC::readByte(offset);
|
||||
}
|
||||
}
|
||||
|
||||
void DS1307RTC::writeByte(uint8_t offset, uint8_t value)
|
||||
{
|
||||
if (_isRealTime) {
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_NVRAM + offset);
|
||||
_bus->write(value);
|
||||
_bus->stop();
|
||||
} else {
|
||||
if (_isRealTime)
|
||||
writeRegister(DS1307_NVRAM + offset, value);
|
||||
else
|
||||
RTC::writeByte(offset, value);
|
||||
}
|
||||
}
|
||||
|
||||
void DS1307RTC::initAlarms()
|
||||
{
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_ALARM_MAGIC);
|
||||
_bus->startRead(DS1307_I2C_ADDRESS);
|
||||
uint8_t value = _bus->read(BitBangI2C::NACK);
|
||||
_bus->stop();
|
||||
uint8_t value = readRegister(DS1307_ALARM_MAGIC);
|
||||
if (value != (0xB0 + ALARM_COUNT)) {
|
||||
// This is the first time we have used this clock chip,
|
||||
// so initialize all alarms to their default state.
|
||||
@ -297,10 +289,7 @@ void DS1307RTC::initAlarms()
|
||||
alarm.flags = 0;
|
||||
for (uint8_t index = 0; index < ALARM_COUNT; ++index)
|
||||
writeAlarm(index, &alarm);
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(DS1307_ALARM_MAGIC);
|
||||
_bus->write(0xB0 + ALARM_COUNT);
|
||||
_bus->stop();
|
||||
writeRegister(DS1307_I2C_ADDRESS, 0xB0 + ALARM_COUNT);
|
||||
|
||||
// Also clear the rest of NVRAM so that it is in a known state.
|
||||
// Otherwise we'll have whatever garbage was present at power-on.
|
||||
@ -308,6 +297,23 @@ void DS1307RTC::initAlarms()
|
||||
_bus->write(DS1307_NVRAM);
|
||||
for (uint8_t index = DS1307_NVRAM; index < DS1307_ALARMS; ++index)
|
||||
_bus->write(0);
|
||||
_bus->stop();
|
||||
_bus->endWrite();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t DS1307RTC::readRegister(uint8_t reg)
|
||||
{
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(reg);
|
||||
if (!_bus->startRead(DS1307_I2C_ADDRESS, 1))
|
||||
return 0; // RTC chip is not responding.
|
||||
return _bus->read();
|
||||
}
|
||||
|
||||
bool DS1307RTC::writeRegister(uint8_t reg, uint8_t value)
|
||||
{
|
||||
_bus->startWrite(DS1307_I2C_ADDRESS);
|
||||
_bus->write(reg);
|
||||
_bus->write(value);
|
||||
return _bus->endWrite();
|
||||
}
|
||||
|
@ -25,11 +25,11 @@
|
||||
|
||||
#include "RTC.h"
|
||||
|
||||
class BitBangI2C;
|
||||
class I2CMaster;
|
||||
|
||||
class DS1307RTC : public RTC {
|
||||
public:
|
||||
DS1307RTC(BitBangI2C &bus, uint8_t oneHzPin = 255);
|
||||
DS1307RTC(I2CMaster &bus, uint8_t oneHzPin = 255);
|
||||
~DS1307RTC();
|
||||
|
||||
bool isRealTime() const { return _isRealTime; }
|
||||
@ -49,12 +49,15 @@ public:
|
||||
void writeByte(uint8_t offset, uint8_t value);
|
||||
|
||||
private:
|
||||
BitBangI2C *_bus;
|
||||
I2CMaster *_bus;
|
||||
uint8_t _oneHzPin;
|
||||
bool prevOneHz;
|
||||
bool _isRealTime;
|
||||
|
||||
void initAlarms();
|
||||
|
||||
uint8_t readRegister(uint8_t reg);
|
||||
bool writeRegister(uint8_t reg, uint8_t value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user