Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 49 additions & 102 deletions lib/Ds1302/Ds1302.cpp
Original file line number Diff line number Diff line change
@@ -1,60 +1,39 @@
/** Ds1302.cpp
*
* Ds1302 class.
*
* @version 1.1.1
* @author Rafa Couto <caligari@treboada.net>
* @license GNU Affero General Public License v3.0
* @see https://github.com/Treboada/Ds1302
*
*/

#include "Ds1302.h"

#include <Arduino.h>

#define REG_SECONDS 0x80
#define REG_MINUTES 0x82
#define REG_HOUR 0x84
#define REG_DATE 0x86
#define REG_MONTH 0x88
#define REG_DAY 0x8A
#define REG_YEAR 0x8C
#define REG_WP 0x8E
#define REG_BURST 0xBE


Ds1302::Ds1302(uint8_t pin_ena, uint8_t pin_clk, uint8_t pin_dat)
{
#define REG_SECONDS 0x80
#define REG_MINUTES 0x82
#define REG_HOUR 0x84
#define REG_DATE 0x86
#define REG_MONTH 0x88
#define REG_DAY 0x8A
#define REG_YEAR 0x8C
#define REG_WP 0x8E
#define REG_BURST 0xBE

Ds1302::Ds1302(uint8_t pin_ena, uint8_t pin_clk, uint8_t pin_dat) {
_pin_ena = pin_ena;
_pin_clk = pin_clk;
_pin_dat = pin_dat;
_dat_direction = INPUT;
}


void Ds1302::init()
{
void Ds1302::init() {
pinMode(_pin_ena, OUTPUT);
pinMode(_pin_clk, OUTPUT);
pinMode(_pin_dat, _dat_direction);

digitalWrite(_pin_ena, LOW);
digitalWrite(_pin_clk, LOW);
}


bool Ds1302::isHalted()
{
bool Ds1302::isHalted() {
_prepareRead(REG_SECONDS);
uint8_t seconds = _readByte();
_end();
return (seconds & 0b10000000);
}


void Ds1302::getDateTime(DateTime* dt)
{
void Ds1302::getDateTime(DateTime* dt) {
_prepareRead(REG_BURST);
dt->second = _bcd2dec(_readByte() & 0b01111111);
dt->minute = _bcd2dec(_readByte() & 0b01111111);
Expand All @@ -66,40 +45,40 @@ void Ds1302::getDateTime(DateTime* dt)
_end();
}


void Ds1302::setDateTime(DateTime* dt)
{
void Ds1302::setDateTime(DateTime* dt) {
_prepareWrite(REG_WP);
_writeByte(0b00000000);
_end();

_prepareWrite(REG_BURST);
_writeByte(_dec2bcd(dt->second % 60 ));
_writeByte(_dec2bcd(dt->minute % 60 ));
_writeByte(_dec2bcd(dt->hour % 24 ));
_writeByte(_dec2bcd(dt->day % 32 ));
_writeByte(_dec2bcd(dt->month % 13 ));
_writeByte(_dec2bcd(dt->dow % 8 ));
_writeByte(_dec2bcd(dt->second % 60) & 0x7F);
_writeByte(_dec2bcd(dt->minute % 60));
_writeByte(_dec2bcd(dt->hour % 24));
_writeByte(_dec2bcd(dt->day % 32));
_writeByte(_dec2bcd(dt->month % 13));
_writeByte(_dec2bcd(dt->dow % 8));
_writeByte(_dec2bcd(dt->year % 100));
_writeByte(0b10000000);
_end();
}


void Ds1302::halt()
{
_setHaltFlag(true);
uint8_t Ds1302::readRegister(uint8_t reg) {
_prepareRead(reg);
uint8_t val = _readByte();
_end();
return val;
}


void Ds1302::start()
{
_setHaltFlag(false);
void Ds1302::writeRegister(uint8_t reg, uint8_t value) {
_prepareWrite(reg);
_writeByte(value);
_end();
}

void Ds1302::halt() { _setHaltFlag(true); }
void Ds1302::start() { _setHaltFlag(false); }

void Ds1302::_setHaltFlag(bool stopped)
{
void Ds1302::_setHaltFlag(bool stopped) {
uint8_t regs[8];
_prepareRead(REG_BURST);
for (int b = 0; b < 8; b++) regs[b] = _readByte();
Expand All @@ -117,85 +96,53 @@ void Ds1302::_setHaltFlag(bool stopped)
_end();
}


void Ds1302::_prepareRead(uint8_t address)
{
void Ds1302::_prepareRead(uint8_t address) {
_setDirection(OUTPUT);
digitalWrite(_pin_ena, HIGH);
uint8_t command = 0b10000001 | address;
_writeByte(command);
_setDirection(INPUT);
}


void Ds1302::_prepareWrite(uint8_t address)
{
void Ds1302::_prepareWrite(uint8_t address) {
_setDirection(OUTPUT);
digitalWrite(_pin_ena, HIGH);
uint8_t command = 0b10000000 | address;
_writeByte(command);
}

void Ds1302::_end() { digitalWrite(_pin_ena, LOW); }

void Ds1302::_end()
{
digitalWrite(_pin_ena, LOW);
}


uint8_t Ds1302::_readByte()
{
uint8_t Ds1302::_readByte() {
uint8_t byte = 0;

for(uint8_t b = 0; b < 8; b++)
{
for(uint8_t b = 0; b < 8; b++) {
if (digitalRead(_pin_dat) == HIGH) byte |= 0x01 << b;
_nextBit();
}

return byte;
}


void Ds1302::_writeByte(uint8_t value)
{
for(uint8_t b = 0; b < 8; b++)
{
void Ds1302::_writeByte(uint8_t value) {
for(uint8_t b = 0; b < 8; b++) {
digitalWrite(_pin_dat, (value & 0x01) ? HIGH : LOW);
_nextBit();
value >>= 1;
}
}

void Ds1302::_nextBit()
{
digitalWrite(_pin_clk, HIGH);
delayMicroseconds(1);

digitalWrite(_pin_clk, LOW);
delayMicroseconds(1);
void Ds1302::_nextBit() {
digitalWrite(_pin_clk, HIGH);
delayMicroseconds(1);
digitalWrite(_pin_clk, LOW);
delayMicroseconds(1);
}


void Ds1302::_setDirection(int direction)
{
if (_dat_direction != direction)
{
void Ds1302::_setDirection(int direction) {
if (_dat_direction != direction) {
_dat_direction = direction;
pinMode(_pin_dat, direction);
}
}


uint8_t Ds1302::_dec2bcd(uint8_t dec)
{
return ((dec / 10 * 16) + (dec % 10));
}


uint8_t Ds1302::_bcd2dec(uint8_t bcd)
{
return ((bcd / 16 * 10) + (bcd % 16));
}


uint8_t Ds1302::_dec2bcd(uint8_t dec) { return ((dec / 10 * 16) + (dec % 10)); }
uint8_t Ds1302::_bcd2dec(uint8_t bcd) { return ((bcd / 16 * 10) + (bcd % 16)); }
69 changes: 13 additions & 56 deletions lib/Ds1302/Ds1302.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
*
* Ds1302 class.
*
* @version 1.1.1
* @author Rafa Couto <caligari@treboada.net>
* @version 1.0.4
* @author Rafa Couto
* @license GNU Affero General Public License v3.0
* @see https://github.com/Treboada/Ds1302
*
Expand All @@ -28,74 +28,32 @@ class Ds1302
uint8_t dow;
} DateTime;

/**
* Months of year
*/
enum MONTH : uint8_t {
MONTH_JAN = 1,
MONTH_FEB = 2,
MONTH_MAR = 3,
MONTH_APR = 4,
MONTH_MAY = 5,
MONTH_JUN = 6,
MONTH_JUL = 7,
MONTH_AUG = 8,
MONTH_SEP = 9,
MONTH_OCT = 10,
MONTH_NOV = 11,
MONTH_DEC = 12
MONTH_JAN = 1, MONTH_FEB, MONTH_MAR, MONTH_APR,
MONTH_MAY, MONTH_JUN, MONTH_JUL, MONTH_AUG,
MONTH_SEP, MONTH_OCT, MONTH_NOV, MONTH_DEC
};

/**
* Days of week
*/
enum DOW : uint8_t {
DOW_MON = 1,
DOW_TUE = 2,
DOW_WED = 3,
DOW_THU = 4,
DOW_FRI = 5,
DOW_SAT = 6,
DOW_SUN = 7
DOW_MON = 1, DOW_TUE, DOW_WED, DOW_THU,
DOW_FRI, DOW_SAT, DOW_SUN
};

/**
* Constructor (pin configuration).
*/
uint8_t readRegister(uint8_t reg);

void writeRegister(uint8_t reg, uint8_t value);

Ds1302(uint8_t pin_ena, uint8_t pin_clk, uint8_t pin_dat);

/**
* Initializes the DW1302 chip.
*/
void init();

/**
* Returns when the oscillator is disabled.
*/
bool isHalted();

/**
* Stops the oscillator.
*/
void halt();

/**
* Starts the oscillator.
*/
void start();

/**
* Returns the current date and time.
*/
void getDateTime(DateTime* dt);;

/**
* Sets the current date and time.
*/
void getDateTime(DateTime* dt);
void setDateTime(DateTime* dt);

private:

uint8_t _pin_ena;
uint8_t _pin_clk;
uint8_t _pin_dat;
Expand All @@ -117,5 +75,4 @@ class Ds1302
void _setHaltFlag(bool stopped);
};

#endif // _DS_1302_H

#endif