mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
147 lines
3.1 KiB
C++
147 lines
3.1 KiB
C++
#include <Driver_ESPEasySC16IS752_Serial.h>
|
|
|
|
#ifndef DISABLE_SC16IS752_Serial
|
|
|
|
#include <map>
|
|
|
|
|
|
// Use a self-made smart pointer type, as I don't see how to create a map of smart pointers (or shared pointers)
|
|
// which will be cleared automatically when destroying the object.
|
|
// Problem here is that we can have 2 (max) references to the same object for channel A and B
|
|
// stored in a map or list shared among all instances of this object.
|
|
typedef std::pair<uint8_t, SC16IS752 *> SC16IS752_ptr_t;
|
|
static std::map<ESPEasySC16IS752_Serial::I2C_address, SC16IS752_ptr_t> SC16IS752_map;
|
|
|
|
|
|
ESPEasySC16IS752_Serial::ESPEasySC16IS752_Serial(ESPEasySC16IS752_Serial::I2C_address addr,
|
|
ESPEasySC16IS752_Serial::SC16IS752_channel ch) : _address(addr), _channel(ch)
|
|
{
|
|
auto it = SC16IS752_map.find(_address);
|
|
|
|
if (it == SC16IS752_map.end()) {
|
|
SC16IS752_ptr_t ptr;
|
|
ptr.first = 0; // link count
|
|
ptr.second = new SC16IS752(SC16IS750_PROTOCOL_I2C, _address);
|
|
SC16IS752_map[_address] = ptr;
|
|
it = SC16IS752_map.find(_address);
|
|
}
|
|
it->second.first++; // Increase link count
|
|
_i2cuart = it->second.second;
|
|
}
|
|
|
|
ESPEasySC16IS752_Serial::~ESPEasySC16IS752_Serial()
|
|
{
|
|
auto it = SC16IS752_map.find(_address);
|
|
|
|
if (it != SC16IS752_map.end()) {
|
|
// Should always return one....
|
|
it->second.first--;
|
|
|
|
if (it->second.first == 0) {
|
|
// We are the last one.
|
|
delete it->second.second;
|
|
SC16IS752_map.erase(_address);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ESPEasySC16IS752_Serial::initialized() const
|
|
{
|
|
if (_i2cuart) {
|
|
return _pingReplied;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ESPEasySC16IS752_Serial::begin(long speed)
|
|
{
|
|
if (!_i2cuart) {
|
|
return;
|
|
}
|
|
|
|
if (!_pingReplied) {
|
|
_pingReplied = _i2cuart->ping();
|
|
}
|
|
|
|
if (_pingReplied) {
|
|
if (_channel == SC16IS752_CHANNEL_A) {
|
|
_i2cuart->beginA(speed);
|
|
}
|
|
else {
|
|
_i2cuart->beginB(speed);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ESPEasySC16IS752_Serial::end()
|
|
{
|
|
// Not implemented
|
|
}
|
|
|
|
int ESPEasySC16IS752_Serial::peek(void)
|
|
{
|
|
if (initialized()) {
|
|
return _i2cuart->peek(_channel);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
size_t ESPEasySC16IS752_Serial::write(uint8_t val)
|
|
{
|
|
if (initialized()) {
|
|
return _i2cuart->write(_channel, val);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
size_t ESPEasySC16IS752_Serial::write(const uint8_t *buffer, size_t size)
|
|
{
|
|
size_t count = 0;
|
|
|
|
for (size_t i = 0; i < size; ++i) {
|
|
size_t written = write(buffer[i]);
|
|
|
|
if (written == 0) { return count; }
|
|
count += written;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int ESPEasySC16IS752_Serial::read(void)
|
|
{
|
|
if (initialized()) {
|
|
return _i2cuart->read(_channel);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
size_t ESPEasySC16IS752_Serial::readBytes(char *buffer, size_t size)
|
|
{
|
|
size_t count = 0;
|
|
|
|
for (size_t i = 0; i < size; ++i) {
|
|
int res = read();
|
|
|
|
if (res < 0) { return count; }
|
|
buffer[i] = static_cast<char>(res & 0xFF);
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int ESPEasySC16IS752_Serial::available(void)
|
|
{
|
|
if (initialized()) {
|
|
return _i2cuart->available(_channel);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ESPEasySC16IS752_Serial::flush(void)
|
|
{
|
|
if (initialized()) {
|
|
_i2cuart->flush(_channel);
|
|
}
|
|
}
|
|
|
|
#endif |