28#include "../functors.h"
30#include "../utilities.h"
31#include "../i2c_device.h"
32#include "../i2c_device_utilities.h"
115 template<
typename MANAGER>
120 template<
typename OUT,
typename IN>
using FUTURE =
typename PARENT::template FUTURE<OUT, IN>;
122 template<u
int8_t REGISTER,
typename T = u
int8_t,
typename FUNCTOR = functor::Identity<T>>
124 template<u
int8_t REGISTER,
typename T = u
int8_t,
typename FUNCTOR = functor::Identity<T>>
127 static constexpr const uint8_t DEVICE_ADDRESS = 0x68 << 1;
128 static constexpr const uint8_t RAM_START = 0x08;
129 static constexpr const uint8_t RAM_END = 0x40;
130 static constexpr const uint8_t RAM_SIZE = RAM_END - RAM_START;
131 static constexpr const uint8_t TIME_ADDRESS = 0x00;
132 static constexpr const uint8_t CLOCK_HALT = 0x80;
133 static constexpr const uint8_t CONTROL_ADDRESS = 0x07;
135 class ControlRegister
138 static constexpr ControlRegister create_output_level(
bool level)
140 return ControlRegister(level ? OUT_MASK : 0);
144 return ControlRegister(SQWE_MASK | uint8_t(frequency));
148 explicit ControlRegister(uint8_t data = 0) : data_{data} {}
150 static constexpr uint8_t FREQUENCY_MASK =
bits::BV8(0, 1);
151 static constexpr uint8_t SQWE_MASK =
bits::BV8(4);
152 static constexpr uint8_t OUT_MASK =
bits::BV8(7);
158 class DatetimeConverterToDevice
163 RES_TYPE operator()(
const ARG_TYPE& datetime)
const
176 class DatetimeConverterFromDevice
181 RES_TYPE operator()(
const ARG_TYPE& datetime)
const
292 template<u
int8_t SIZE_>
293 class SetRamFuture :
public FUTURE<void, containers::array<uint8_t, SIZE_ + 1>>
295 using PARENT = FUTURE<void, containers::array<uint8_t, SIZE_ + 1>>;
296 using IN =
typename PARENT::IN;
298 static IN build_array(uint8_t address,
const uint8_t (&data)[SIZE_])
301 input[0] =
static_cast<uint8_t
>(address + RAM_START);
308 explicit SetRamFuture(uint8_t address,
const uint8_t (&data)[SIZE_])
309 : PARENT{build_array(address, data)}
311 static_assert(SIZE_ <= RAM_SIZE,
"SIZE_ template paraneter must be less than RAM_SIZE!");
314 bool is_input_valid()
const
316 return ((this->get_input()[0] + SIZE_) <= RAM_END);
343 if (!
future.is_input_valid())
360 using PARENT = FUTURE<void, containers::array<uint8_t, 2>>;
364 : PARENT{{
static_cast<uint8_t
>(address + RAM_START), data}} {}
366 bool is_input_valid()
const
368 return (this->get_input()[0] < RAM_END);
393 if (!
future.is_input_valid())
408 template<u
int8_t SIZE_>
409 class GetRamFuture :
public FUTURE<containers::array<uint8_t, SIZE_>, uint8_t>
411 using PARENT = FUTURE<containers::array<uint8_t, SIZE_>, uint8_t>;
414 explicit GetRamFuture(uint8_t address) : PARENT{
static_cast<uint8_t
>(address + RAM_START)}
416 static_assert(SIZE_ <= RAM_SIZE,
"SIZE_ template paraneter must be less than RAM_SIZE!");
419 bool is_input_valid()
const
421 return ((this->get_input() + SIZE_) <= RAM_END);
448 if (!
future.is_input_valid())
464 using PARENT = FUTURE<uint8_t, uint8_t>;
467 explicit GetRam1Future(uint8_t address) : PARENT{
static_cast<uint8_t
>(address + RAM_START)} {}
469 bool is_input_valid()
const
471 return this->get_input() < RAM_END;
496 if (!
future.is_input_valid())
558 :
PARENT{ControlRegister::create_square_wave_enable(frequency)} {}
601 :
PARENT{ControlRegister::create_output_level(output_value)} {}
645 return this->
template sync_write<SetDatetimeFuture>(datetime);
661 return this->
template sync_read<GetDatetimeFuture>(datetime);
678 return this->
template sync_write<HaltClockFuture>();
695 return this->
template sync_write<EnableOutputFuture>(frequency);
711 return this->
template sync_write<DisableOutputFuture>(output_value);
769 template<u
int8_t SIZE>
bool set_ram(uint8_t address,
const uint8_t (&data)[SIZE])
791 template<u
int8_t SIZE>
bool get_ram(uint8_t address, uint8_t (&data)[SIZE])
796 if (!
future.get(temp))
return false;
797 memcpy(data, temp.data(), SIZE);
815 template<
typename T>
bool set_ram(uint8_t address,
const T& data)
817 uint8_t temp[
sizeof(T)];
818 utils::as_array<T>(data, temp);
841 template<
typename T>
bool get_ram(uint8_t address, T& data)
845 return future.get(
reinterpret_cast<uint8_t&
>(data));
Create a future to be used by asynchronous method disable_output(DisableOutputFuture&).
Create a future to be used by asynchronous method enable_output(EnableOutputFuture&).
Create a future to be used by asynchronous method get_ram(GetRam1Future&).
Create a future to be used by asynchronous method get_ram(GetRamFuture<SIZE>&).
Create a future to be used by asynchronous method halt_clock(HaltClockFuture&).
Create a future to be used by asynchronous method set_ram(SetRam1Future&).
Create a future to be used by asynchronous method set_ram(SetRamFuture<SIZE>&).
I2C device driver for the DS1307 RTC chip.
uint8_t get_ram(uint8_t address)
Get the value of one cell of the chip internal RAM.
bool get_ram(uint8_t address, T &data)
Read any type of data from the chip internal RAM.
int get_datetime(GetDatetimeFuture &future)
Get the current date and time from the RTC chip.
int set_ram(SetRamFuture< SIZE > &future)
Set several cells of the chip internal RAM to specified values.
bool get_datetime(tm &datetime)
Get the current date and time from the RTC chip.
int set_datetime(SetDatetimeFuture &future)
Change date and time of the RTC chip connected to this driver.
static constexpr uint8_t ram_size()
Get the size of the additional RAM size of the chip.
bool set_ram(uint8_t address, const uint8_t(&data)[SIZE])
Set several cells of the chip internal RAM to specified values.
bool halt_clock()
Disable the RTC oscillator, hence the time will not be updated anymore.
bool set_ram(uint8_t address, const T &data)
Write any type of data to the chip internal RAM.
bool disable_output(bool output_value=false)
Disable square wave output to the SQW/OUT pin of the RTC chip.
int get_ram(GetRamFuture< SIZE > &future)
Get values of several cells from the chip internal RAM.
DS1307(MANAGER &manager)
Create a new device driver for a DS1307 chip.
bool enable_output(SquareWaveFrequency frequency=SquareWaveFrequency::FREQ_1HZ)
Enable square wave output to the SQW/OUT pin of the RTC chip.
bool set_datetime(const tm &datetime)
Change date and time of the RTC chip connected to this driver.
int get_ram(GetRam1Future &future)
Get the value of one cell of the chip internal RAM.
bool set_ram(uint8_t address, uint8_t data)
Set one cell of the chip internal RAM to the specified value.
int enable_output(EnableOutputFuture &future)
Enable square wave output to the SQW/OUT pin of the RTC chip.
int set_ram(SetRam1Future &future)
Set one cell of the chip internal RAM to the specified value.
bool get_ram(uint8_t address, uint8_t(&data)[SIZE])
Get values of several cells from the chip internal RAM.
int halt_clock(HaltClockFuture &future)
Disable the RTC oscillator, hence the time will not be updated anymore.
int disable_output(DisableOutputFuture &future)
Enable square wave output to the SQW/OUT pin of the RTC chip.
Base class for all I2C devices.
int async_write(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing only one write...
MANAGER MANAGER
the type of I2C Manager that can handle this device.
int async_read(F &future, bool stop=true)
Helper method that asynchronously launches I2C commands for a simple Future performing one write foll...
Generic Future that can be used to read an I2C device register.
Generic Future that can be used to write to an I2C device register.
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
Defines API for Real-Time Clock chips usage.
SquareWaveFrequency
The possible frequencies that can be generated by DS1307 RTC SQW/OUT pin.
Defines all API for all external devices supported by FastArduino.
constexpr const int EINVAL
Invalid argument or invalid Future.
Contains the API around Future implementation.
@ READY
The status of a Future once its output value has been fully set by a provider.
Define API to define and manage I2C devices.
uint8_t binary_to_bcd(uint8_t binary)
Convert a natural integers to a BCD byte (2 digits).
uint8_t bcd_to_binary(uint8_t bcd)
Convert Binary-coded decimal byte (each nibble is a digit from 0 to 9) into a natural byte.
The datetime structure used by the RTC API.
uint8_t tm_mon
months since January - [ 1 to 12 ]
WeekDay tm_wday
days since Sunday - [ 1 to 7 ]
uint8_t tm_year
years since 2000
uint8_t tm_mday
day of the month - [ 1 to 31 ]
uint8_t tm_min
minutes after the hour - [ 0 to 59 ]
uint8_t tm_hour
hours since midnight - [ 0 to 23 ]
uint8_t tm_sec
seconds after the minute - [ 0 to 59 ]