-
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
235 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* © 2024, Chris Harlow. All rights reserved. | ||
* | ||
* This file is part of CommandStation-EX | ||
* | ||
* This is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* It 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 General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
/* | ||
This is the list of HAL drivers automatically included by IODevice.h | ||
It has been moved here to be easier to maintain than editing IODevice.h | ||
*/ | ||
#include "IO_MCP23008.h" | ||
#include "IO_MCP23017.h" | ||
#include "IO_PCF8574.h" | ||
#include "IO_PCF8575.h" | ||
#include "IO_PCA9555.h" | ||
#include "IO_duinoNodes.h" | ||
#include "IO_EXIOExpander.h" | ||
#include "IO_trainbrains.h" | ||
#include "IO_EncoderThrottle.h" | ||
#include "IO_TCA8418.h" | ||
#include "IO_NeoPixel.h" | ||
#include "IO_I2CRailcom.h" | ||
#include "IO_TM1638.h" | ||
#include "IO_EXSensorCAM.h" | ||
#include "IO_DS1307.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* | ||
* © 2024, Chris Harlow. All rights reserved. | ||
* | ||
* This file is part of CommandStation-EX | ||
* | ||
* This is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* It 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 General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/* | ||
* The IO_DS1307 device driver is used to interface a standalone realtime clock. | ||
* The clock will announce every minute (which will trigger EXRAIL ONTIME events). | ||
* Seconds, and Day/date info is ignored, except that the announced hhmm time | ||
* will attempt to synchronize with the 0 seconds of the clock. | ||
* An analog read in EXRAIL (IFGTE(vpin, value) etc will check against the hh*60+mm time. | ||
* The clock can be easily set by an analog write to the vpin using 24 hr clock time | ||
* with the command <z vpin hh mm ss> | ||
*/ | ||
|
||
#include "IO_DS1307.h" | ||
#include "I2CManager.h" | ||
#include "DIAG.h" | ||
#include "CommandDistributor.h" | ||
|
||
uint8_t d2b(uint8_t d) { | ||
return (d >> 4)*10 + (d & 0x0F); | ||
} | ||
|
||
void DS1307::create(VPIN vpin, I2CAddress i2cAddress) { | ||
if (checkNoOverlap(vpin, 1, i2cAddress)) new DS1307(vpin, i2cAddress); | ||
} | ||
|
||
|
||
// Constructor | ||
DS1307::DS1307(VPIN vpin,I2CAddress i2cAddress){ | ||
_firstVpin = vpin; | ||
_nPins = 1; | ||
_I2CAddress = i2cAddress; | ||
addDevice(this); | ||
} | ||
|
||
uint32_t DS1307::getTime() { | ||
// Obtain ss,mm,hh buffers from device | ||
uint8_t readBuffer[3]; | ||
const uint8_t writeBuffer[1]={0}; | ||
|
||
// address register 0 for read. | ||
I2CManager.write(_I2CAddress, writeBuffer, 1); | ||
if (I2CManager.read(_I2CAddress, readBuffer, 3) != I2C_STATUS_OK) { | ||
_deviceState=DEVSTATE_FAILED; | ||
return 0; | ||
} | ||
_deviceState=DEVSTATE_NORMAL; | ||
|
||
if (debug) { | ||
static const char hexchars[]="0123456789ABCDEF"; | ||
USB_SERIAL.print(F("<*RTC")); | ||
for (int i=2;i>=0;i--) { | ||
USB_SERIAL.write(' '); | ||
USB_SERIAL.write(hexchars[readBuffer[i]>>4]); | ||
USB_SERIAL.write(hexchars[readBuffer[i]& 0x0F ]); | ||
} | ||
StringFormatter::send(&USB_SERIAL,F(" %d *>\n"),_deviceState); | ||
} | ||
|
||
if (readBuffer[0] & 0x80) { | ||
_deviceState=DEVSTATE_INITIALISING; | ||
DIAG(F("DS1307 clock in standby")); | ||
return 0; // clock is not running | ||
} | ||
// convert device format to seconds since midnight | ||
uint8_t ss=d2b(readBuffer[0] & 0x7F); | ||
uint8_t mm=d2b(readBuffer[1]); | ||
uint8_t hh=d2b(readBuffer[2] & 0x3F); | ||
return (hh*60ul +mm)*60ul +ss; | ||
} | ||
|
||
void DS1307::_begin() { | ||
// Initialise device and sync loop() to zero seconds | ||
I2CManager.begin(); | ||
auto tstamp=getTime(); | ||
if (_deviceState==DEVSTATE_NORMAL) { | ||
byte seconds=tstamp%60; | ||
delayUntil(micros() + ((60-seconds) * 1000000)); | ||
} | ||
_display(); | ||
} | ||
|
||
// Processing loop to obtain clock time. | ||
// This self-synchronizes to the next minute tickover | ||
void DS1307::_loop(unsigned long currentMicros) { | ||
auto time=getTime(); | ||
if (_deviceState==DEVSTATE_NORMAL) { | ||
byte ss=time%60; | ||
CommandDistributor::setClockTime(time/60, 1, 1); | ||
delayUntil(currentMicros + ((60-ss) * 1000000)); | ||
} | ||
} | ||
|
||
|
||
// Display device driver info. | ||
void DS1307::_display() { | ||
auto tstamp=getTime(); | ||
byte ss=tstamp%60; | ||
tstamp/=60; | ||
byte mm=tstamp%60; | ||
byte hh=tstamp/60; | ||
DIAG(F("DS1307 on I2C:%s vpin %d %d:%d:%d %S"), | ||
_I2CAddress.toString(), _firstVpin, | ||
hh,mm,ss, | ||
(_deviceState==DEVSTATE_FAILED) ? F("OFFLINE") : F("")); | ||
} | ||
|
||
// allow user to set the clock | ||
void DS1307::_writeAnalogue(VPIN vpin, int hh, uint8_t mm, uint16_t ss) { | ||
(void) vpin; | ||
uint8_t writeBuffer[3]; | ||
writeBuffer[0]=1; // write mm,hh first | ||
writeBuffer[1]=((mm/10)<<4) + (mm % 10); | ||
writeBuffer[2]=((hh/10)<<4) + (hh % 10); | ||
I2CManager.write(_I2CAddress, writeBuffer, 3); | ||
writeBuffer[0]=0; // write ss | ||
writeBuffer[1]=((ss/10)<<4) + (ss % 10); | ||
I2CManager.write(_I2CAddress, writeBuffer, 2); | ||
_loop(micros()); // resync with seconds rollover | ||
} | ||
|
||
// Method to read analogue hh*60+mm time | ||
int DS1307::_readAnalogue(VPIN vpin) { | ||
(void)vpin; | ||
return getTime()/60; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* © 2024, Chris Harlow. All rights reserved. | ||
* | ||
* This file is part of CommandStation-EX | ||
* | ||
* This is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* It 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 General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/* | ||
* The IO_DS1307 device driver is used to interface a standalone realtime clock. | ||
* The clock will announce every minute (which will trigger EXRAIL ONTIME events). | ||
* Seconds, and Day/date info is ignored, except that the announced hhmm time | ||
* will attempt to synchronize with the 0 seconds of the clock. | ||
* An analog read in EXRAIL (IFGTE(vpin, value) etc will check against the hh*60+mm time. | ||
* The clock can be easily set by an analog write to the vpin using 24 hr clock time | ||
* with the command <z vpin hh mm ss> | ||
*/ | ||
|
||
#ifndef IO_DS1307_h | ||
#define IO_DS1307_h | ||
|
||
|
||
#include "IODevice.h" | ||
|
||
class DS1307 : public IODevice { | ||
public: | ||
static const bool debug=false; | ||
static void create(VPIN vpin, I2CAddress i2cAddress); | ||
|
||
|
||
private: | ||
|
||
// Constructor | ||
DS1307(VPIN vpin,I2CAddress i2cAddress); | ||
uint32_t getTime(); | ||
void _begin() override; | ||
void _display() override; | ||
void _loop(unsigned long currentMicros) override; | ||
int _readAnalogue(VPIN vpin) override; | ||
void _writeAnalogue(VPIN vpin, int hh, uint8_t mm, uint16_t ss) override; | ||
}; | ||
|
||
#endif |