first commit
This commit is contained in:
289
libraries/Rtc_by_Makuna/src/RtcDS1302.h
Normal file
289
libraries/Rtc_by_Makuna/src/RtcDS1302.h
Normal file
@@ -0,0 +1,289 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
RTC library
|
||||
|
||||
Written by Michael C. Miller.
|
||||
|
||||
I invest time and resources providing this open source code,
|
||||
please support me by dontating (see https://github.com/Makuna/Rtc)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the Makuna/Rtc library.
|
||||
|
||||
Rtc is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Rtc is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with Rtc. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "RtcUtility.h"
|
||||
#include "RtcDateTime.h"
|
||||
#include "ThreeWire.h"
|
||||
|
||||
|
||||
//DS1302 Register Addresses
|
||||
const uint8_t DS1302_REG_TIMEDATE = 0x80;
|
||||
const uint8_t DS1302_REG_TIMEDATE_BURST = 0xBE;
|
||||
const uint8_t DS1302_REG_TCR = 0x90;
|
||||
const uint8_t DS1302_REG_RAM_BURST = 0xFE;
|
||||
const uint8_t DS1302_REG_RAMSTART = 0xc0;
|
||||
const uint8_t DS1302_REG_RAMEND = 0xfd;
|
||||
// ram read and write addresses are interleaved
|
||||
const uint8_t DS1302RamSize = 31;
|
||||
|
||||
|
||||
// DS1302 Trickle Charge Control Register Bits
|
||||
enum DS1302TcrResistor
|
||||
{
|
||||
DS1302TcrResistor_Disabled = 0,
|
||||
DS1302TcrResistor_2KOhm = B00000001,
|
||||
DS1302TcrResistor_4KOhm = B00000010,
|
||||
DS1302TcrResistor_8KOhm = B00000011,
|
||||
DS1302TcrResistor_MASK = B00000011,
|
||||
};
|
||||
|
||||
enum DS1302TcrDiodes
|
||||
{
|
||||
DS1302TcrDiodes_None = 0,
|
||||
DS1302TcrDiodes_One = B00000100,
|
||||
DS1302TcrDiodes_Two = B00001000,
|
||||
DS1302TcrDiodes_Disabled = B00001100,
|
||||
DS1302TcrDiodes_MASK = B00001100,
|
||||
};
|
||||
|
||||
enum DS1302TcrStatus
|
||||
{
|
||||
DS1302TcrStatus_Enabled = B10100000,
|
||||
DS1302TcrStatus_Disabled = B01010000,
|
||||
DS1302TcrStatus_MASK = B11110000,
|
||||
};
|
||||
|
||||
const uint8_t DS1302Tcr_Disabled = DS1302TcrStatus_Disabled | DS1302TcrDiodes_Disabled | DS1302TcrResistor_Disabled;
|
||||
|
||||
// DS1302 Clock Halt Register & Bits
|
||||
const uint8_t DS1302_REG_CH = 0x80; // bit in the seconds register
|
||||
const uint8_t DS1302_CH = 7;
|
||||
|
||||
// Write Protect Register & Bits
|
||||
const uint8_t DS1302_REG_WP = 0x8E;
|
||||
const uint8_t DS1302_WP = 7;
|
||||
|
||||
template<class T_WIRE_METHOD> class RtcDS1302
|
||||
{
|
||||
public:
|
||||
RtcDS1302(T_WIRE_METHOD& wire) :
|
||||
_wire(wire)
|
||||
{
|
||||
}
|
||||
|
||||
void Begin()
|
||||
{
|
||||
_wire.begin();
|
||||
}
|
||||
|
||||
bool GetIsWriteProtected()
|
||||
{
|
||||
uint8_t wp = getReg(DS1302_REG_WP);
|
||||
return !!(wp & _BV(DS1302_WP));
|
||||
}
|
||||
|
||||
void SetIsWriteProtected(bool isWriteProtected)
|
||||
{
|
||||
uint8_t wp = getReg(DS1302_REG_WP);
|
||||
if (isWriteProtected)
|
||||
{
|
||||
wp |= _BV(DS1302_WP);
|
||||
}
|
||||
else
|
||||
{
|
||||
wp &= ~_BV(DS1302_WP);
|
||||
}
|
||||
setReg(DS1302_REG_WP, wp);
|
||||
}
|
||||
|
||||
bool IsDateTimeValid()
|
||||
{
|
||||
return GetDateTime().IsValid();
|
||||
}
|
||||
|
||||
bool GetIsRunning()
|
||||
{
|
||||
uint8_t ch = getReg(DS1302_REG_CH);
|
||||
return !(ch & _BV(DS1302_CH));
|
||||
}
|
||||
|
||||
void SetIsRunning(bool isRunning)
|
||||
{
|
||||
uint8_t ch = getReg(DS1302_REG_CH);
|
||||
if (isRunning)
|
||||
{
|
||||
ch &= ~_BV(DS1302_CH);
|
||||
}
|
||||
else
|
||||
{
|
||||
ch |= _BV(DS1302_CH);
|
||||
}
|
||||
setReg(DS1302_REG_CH, ch);
|
||||
}
|
||||
|
||||
uint8_t GetTrickleChargeSettings()
|
||||
{
|
||||
uint8_t setting = getReg(DS1302_REG_TCR);
|
||||
return setting;
|
||||
}
|
||||
|
||||
void SetTrickleChargeSettings(uint8_t setting)
|
||||
{
|
||||
if ((setting & DS1302TcrResistor_MASK) == DS1302TcrResistor_Disabled)
|
||||
{
|
||||
// invalid resistor setting, set to disabled
|
||||
setting = DS1302Tcr_Disabled;
|
||||
}
|
||||
else if ((setting & DS1302TcrDiodes_MASK) == DS1302TcrDiodes_Disabled ||
|
||||
(setting & DS1302TcrDiodes_MASK) == DS1302TcrDiodes_None)
|
||||
{
|
||||
// invalid diode setting, set to disabled
|
||||
setting = DS1302Tcr_Disabled;
|
||||
}
|
||||
else if ((setting & DS1302TcrStatus_MASK) != DS1302TcrStatus_Enabled)
|
||||
{
|
||||
// invalid status setting, set to disabled
|
||||
setting = DS1302Tcr_Disabled;
|
||||
}
|
||||
|
||||
setReg(DS1302_REG_TCR, setting);
|
||||
}
|
||||
|
||||
void SetDateTime(const RtcDateTime& dt)
|
||||
{
|
||||
// set the date time
|
||||
_wire.beginTransmission(DS1302_REG_TIMEDATE_BURST);
|
||||
|
||||
_wire.write(Uint8ToBcd(dt.Second()));
|
||||
_wire.write(Uint8ToBcd(dt.Minute()));
|
||||
_wire.write(Uint8ToBcd(dt.Hour())); // 24 hour mode only
|
||||
_wire.write(Uint8ToBcd(dt.Day()));
|
||||
_wire.write(Uint8ToBcd(dt.Month()));
|
||||
|
||||
// RTC Hardware Day of Week is 1-7, 1 = Monday
|
||||
// convert our Day of Week to Rtc Day of Week
|
||||
uint8_t rtcDow = RtcDateTime::ConvertDowToRtc(dt.DayOfWeek());
|
||||
|
||||
_wire.write(Uint8ToBcd(rtcDow));
|
||||
_wire.write(Uint8ToBcd(dt.Year() - 2000));
|
||||
_wire.write(0); // no write protect, as all of this is ignored if it is protected
|
||||
|
||||
_wire.endTransmission();
|
||||
}
|
||||
|
||||
RtcDateTime GetDateTime()
|
||||
{
|
||||
_wire.beginTransmission(DS1302_REG_TIMEDATE_BURST | THREEWIRE_READFLAG);
|
||||
|
||||
uint8_t second = BcdToUint8(_wire.read() & 0x7F);
|
||||
uint8_t minute = BcdToUint8(_wire.read());
|
||||
uint8_t hour = BcdToBin24Hour(_wire.read());
|
||||
uint8_t dayOfMonth = BcdToUint8(_wire.read());
|
||||
uint8_t month = BcdToUint8(_wire.read());
|
||||
|
||||
_wire.read(); // throwing away day of week as we calculate it
|
||||
|
||||
uint16_t year = BcdToUint8(_wire.read()) + 2000;
|
||||
|
||||
_wire.read(); // throwing away write protect flag
|
||||
|
||||
_wire.endTransmission();
|
||||
|
||||
return RtcDateTime(year, month, dayOfMonth, hour, minute, second);
|
||||
}
|
||||
|
||||
void SetMemory(uint8_t memoryAddress, uint8_t value)
|
||||
{
|
||||
// memory addresses interleaved read and write addresses
|
||||
// so we need to calculate the offset
|
||||
uint8_t address = memoryAddress * 2 + DS1302_REG_RAMSTART;
|
||||
if (address <= DS1302_REG_RAMEND)
|
||||
{
|
||||
setReg(address, value);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetMemory(uint8_t memoryAddress)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
// memory addresses interleaved read and write addresses
|
||||
// so we need to calculate the offset
|
||||
uint8_t address = memoryAddress * 2 + DS1302_REG_RAMSTART;
|
||||
if (address <= DS1302_REG_RAMEND)
|
||||
{
|
||||
value = getReg(address);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint8_t SetMemory(const uint8_t* pValue, uint8_t countBytes)
|
||||
{
|
||||
uint8_t countWritten = 0;
|
||||
|
||||
_wire.beginTransmission(DS1302_REG_RAM_BURST);
|
||||
|
||||
while (countBytes > 0 && countWritten < DS1302RamSize)
|
||||
{
|
||||
_wire.write(*pValue++);
|
||||
countBytes--;
|
||||
countWritten++;
|
||||
}
|
||||
|
||||
_wire.endTransmission();
|
||||
|
||||
return countWritten;
|
||||
}
|
||||
|
||||
uint8_t GetMemory(uint8_t* pValue, uint8_t countBytes)
|
||||
{
|
||||
uint8_t countRead = 0;
|
||||
|
||||
_wire.beginTransmission(DS1302_REG_RAM_BURST | THREEWIRE_READFLAG);
|
||||
|
||||
while (countBytes > 0 && countRead < DS1302RamSize)
|
||||
{
|
||||
*pValue++ = _wire.read();
|
||||
countRead++;
|
||||
countBytes--;
|
||||
}
|
||||
|
||||
_wire.endTransmission();
|
||||
|
||||
return countRead;
|
||||
}
|
||||
|
||||
private:
|
||||
T_WIRE_METHOD& _wire;
|
||||
|
||||
uint8_t getReg(uint8_t regAddress)
|
||||
{
|
||||
_wire.beginTransmission(regAddress | THREEWIRE_READFLAG);
|
||||
uint8_t regValue = _wire.read();
|
||||
_wire.endTransmission();
|
||||
return regValue;
|
||||
}
|
||||
|
||||
void setReg(uint8_t regAddress, uint8_t regValue)
|
||||
{
|
||||
_wire.beginTransmission(regAddress);
|
||||
_wire.write(regValue);
|
||||
_wire.endTransmission();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user