[realtek-ambz] Add Wire library
This commit is contained in:
@@ -179,7 +179,7 @@ Flash I/O | ❓
|
||||
**CORE LIBRARIES** |
|
||||
SoftwareSerial | ❌
|
||||
SPI | ❌
|
||||
Wire | ❌
|
||||
Wire | ❗
|
||||
**OTHER LIBRARIES** |
|
||||
Wi-Fi STA/AP/Mixed | ✔️
|
||||
Wi-Fi Client (SSL) | ✔️ (✔️)
|
||||
|
||||
66
arduino/libretuya/api/Wire.h
Normal file
66
arduino/libretuya/api/Wire.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-09. */
|
||||
|
||||
#include <api/Stream.h>
|
||||
|
||||
class ITwoWire : public Stream {
|
||||
protected:
|
||||
int8_t _sda = -1;
|
||||
int8_t _scl = -1;
|
||||
uint32_t _freq = 0;
|
||||
|
||||
void (*onRequestCallback)(void);
|
||||
void (*onReceiveCallback)(int);
|
||||
|
||||
public:
|
||||
bool begin() {
|
||||
return begin(_sda, _scl, _freq);
|
||||
}
|
||||
|
||||
bool begin(uint8_t address) {
|
||||
return begin(address, _sda, _scl, _freq);
|
||||
}
|
||||
|
||||
virtual bool setPins(int8_t sda, int8_t scl) = 0;
|
||||
|
||||
virtual bool begin(int8_t sda, int8_t scl, uint32_t frequency = 0) = 0;
|
||||
virtual bool begin(uint8_t address, int8_t sda, int8_t scl, uint32_t frequency = 0) = 0;
|
||||
virtual bool end() = 0;
|
||||
|
||||
virtual bool setClock(uint32_t freq) = 0;
|
||||
|
||||
virtual void beginTransmission(uint8_t address) = 0;
|
||||
virtual uint8_t endTransmission(bool stopBit) = 0;
|
||||
|
||||
virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) = 0;
|
||||
|
||||
virtual size_t write(const uint8_t *data, size_t len) = 0;
|
||||
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
uint32_t getClock() {
|
||||
return _freq;
|
||||
}
|
||||
|
||||
uint8_t endTransmission() {
|
||||
return endTransmission(true);
|
||||
}
|
||||
|
||||
size_t requestFrom(uint8_t address, size_t len) {
|
||||
return requestFrom(address, len, true);
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t data) {
|
||||
return write(&data, 1);
|
||||
}
|
||||
|
||||
void onReceive(void (*cb)(int)) {
|
||||
onReceiveCallback = cb;
|
||||
}
|
||||
|
||||
void onRequest(void (*cb)(void)) {
|
||||
onRequestCallback = cb;
|
||||
}
|
||||
};
|
||||
@@ -4,15 +4,12 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include <flash_api.h>
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
// Global Flash object.
|
||||
FlashClass Flash;
|
||||
|
||||
FlashClass::FlashClass() {
|
||||
flash = NULL;
|
||||
@@ -67,5 +64,3 @@ bool FlashClass::writeBlock(uint32_t offset, uint8_t *data, size_t size) {
|
||||
initialize();
|
||||
return flash_stream_write(flash, offset, size, data);
|
||||
}
|
||||
|
||||
FlashClass Flash;
|
||||
|
||||
192
arduino/realtek-ambz/libraries/Wire/Wire.cpp
Normal file
192
arduino/realtek-ambz/libraries/Wire/Wire.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-08. */
|
||||
|
||||
#include "Wire.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
extern "C" {
|
||||
#include <i2c_api.h>
|
||||
extern int i2c_write_timeout(i2c_t *obj, int address, char *data, int length, int stop, int timeout_ms);
|
||||
}
|
||||
|
||||
#ifdef PIN_WIRE0_SDA
|
||||
// Wire object associated to I2C0 interface.
|
||||
TwoWire Wire(PIN_WIRE0_SDA, PIN_WIRE0_SCL);
|
||||
#endif
|
||||
|
||||
#if defined(PIN_WIRE0_SDA) && defined(PIN_WIRE1_SDA)
|
||||
// Wire object associated to I2C1 interface.
|
||||
TwoWire Wire1(PIN_WIRE1_SDA, PIN_WIRE1_SCL);
|
||||
#endif
|
||||
|
||||
#if !defined(PIN_WIRE0_SDA) && defined(PIN_WIRE1_SDA)
|
||||
// Wire object associated to I2C1 interface. The board doesn't support I2C0.
|
||||
TwoWire Wire(PIN_WIRE1_SDA, PIN_WIRE1_SCL);
|
||||
#endif
|
||||
|
||||
TwoWire::TwoWire() {
|
||||
_timeout = 50;
|
||||
}
|
||||
|
||||
TwoWire::TwoWire(int8_t sda, int8_t scl) {
|
||||
_timeout = 50;
|
||||
_sda = sda;
|
||||
_scl = scl;
|
||||
}
|
||||
|
||||
TwoWire::~TwoWire() {}
|
||||
|
||||
bool TwoWire::setPins(int8_t sda, int8_t scl) {
|
||||
// return true when changing pins on initialized I2C
|
||||
if (_inSetPins)
|
||||
return true;
|
||||
// check if pins are provided
|
||||
if (sda == -1 || scl == -1)
|
||||
return false;
|
||||
// set private pins
|
||||
_sda = sda;
|
||||
_scl = scl;
|
||||
sda = g_APinDescription[sda].pinname;
|
||||
scl = g_APinDescription[scl].pinname;
|
||||
|
||||
// check if pins are valid
|
||||
if ((sda == PA_4 || sda == PA_19 || sda == PA_30) && (scl == PA_1 || scl == PA_22 || scl == PA_29)) {
|
||||
// I2C index 0
|
||||
_idx = 0;
|
||||
} else if ((sda == PA_27 || sda == PA_2 || sda == PA_23) && (scl == PA_28 || scl == PA_3 || scl == PA_18)) {
|
||||
// I2C index 1
|
||||
_idx = 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// restart I2C if changing pins
|
||||
// this will never be called from begin()
|
||||
if (_i2c) {
|
||||
_inSetPins = true;
|
||||
end();
|
||||
begin();
|
||||
_inSetPins = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwoWire::begin(int8_t sda, int8_t scl, uint32_t frequency) {
|
||||
if (_i2c)
|
||||
return true;
|
||||
// set private i2c pins
|
||||
if (!setPins(sda, scl))
|
||||
return false;
|
||||
// use default frequency
|
||||
if (!frequency)
|
||||
frequency = WIRE_DEFAULT_FREQ;
|
||||
|
||||
_i2c = new i2c_t;
|
||||
i2c_init(_i2c, (PinName)g_APinDescription[_sda].pinname, (PinName)g_APinDescription[_scl].pinname);
|
||||
i2c_frequency(_i2c, frequency);
|
||||
_freq = frequency;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwoWire::begin(uint8_t address, int8_t sda, int8_t scl, uint32_t frequency) {
|
||||
if (_i2c)
|
||||
return true;
|
||||
// init master bus first, return if failed (wrong pins)
|
||||
if (!begin(sda, scl, frequency))
|
||||
return false;
|
||||
|
||||
i2c_slave_address(_i2c, _idx, address, 0xff);
|
||||
i2c_slave_mode(_i2c, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TwoWire::end() {
|
||||
i2c_reset(_i2c);
|
||||
delete _i2c;
|
||||
_i2c = NULL;
|
||||
}
|
||||
|
||||
bool TwoWire::setClock(uint32_t freq) {
|
||||
if (_i2c) {
|
||||
i2c_frequency(_i2c, freq);
|
||||
}
|
||||
_freq = freq;
|
||||
}
|
||||
|
||||
void TwoWire::beginTransmission(uint8_t address) {
|
||||
_txAddr = address;
|
||||
_txBuf.clear();
|
||||
}
|
||||
|
||||
// Errors:
|
||||
// 0 : Success
|
||||
// 1 : Data too long
|
||||
// 2 : NACK on transmit of address
|
||||
// 3 : NACK on transmit of data
|
||||
// 4 : Other error
|
||||
uint8_t TwoWire::endTransmission(bool stopBit) {
|
||||
if (!_i2c || !_txAddr)
|
||||
return 4;
|
||||
char *buf = (char *)malloc(_txBuf.available());
|
||||
uint8_t i = 0;
|
||||
while (_txBuf.available()) {
|
||||
buf[i++] = _txBuf.read_char();
|
||||
}
|
||||
int len = i2c_write_timeout(_i2c, _txAddr, buf, i, stopBit, _timeout);
|
||||
free(buf);
|
||||
_txAddr = 0;
|
||||
if (len == -1)
|
||||
return 2; // slave not available (if tx length == 0)
|
||||
if (len != i)
|
||||
return 3; // less bytes written
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t TwoWire::requestFrom(uint8_t address, size_t len, bool stopBit) {
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (len > SERIAL_BUFFER_SIZE)
|
||||
len = SERIAL_BUFFER_SIZE;
|
||||
|
||||
_rxBuf.clear();
|
||||
|
||||
char *buf = (char *)malloc(_txBuf.available());
|
||||
i2c_read(_i2c, address, buf, len, stopBit);
|
||||
uint8_t i = 0;
|
||||
while (len) {
|
||||
_rxBuf.store_char(buf[i++]);
|
||||
len--;
|
||||
}
|
||||
free(buf);
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t TwoWire::write(uint8_t data) {
|
||||
if (!_txAddr || _txBuf.isFull())
|
||||
return 0;
|
||||
_txBuf.store_char(data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t TwoWire::write(const uint8_t *data, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (!write(data[i]))
|
||||
return i;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int TwoWire::available() {
|
||||
return _rxBuf.available();
|
||||
}
|
||||
|
||||
int TwoWire::read() {
|
||||
return _rxBuf.read_char();
|
||||
}
|
||||
|
||||
int TwoWire::peek() {
|
||||
return _rxBuf.peek();
|
||||
}
|
||||
|
||||
void TwoWire::flush() {}
|
||||
75
arduino/realtek-ambz/libraries/Wire/Wire.h
Normal file
75
arduino/realtek-ambz/libraries/Wire/Wire.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-08. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <api/RingBuffer.h>
|
||||
#include <api/Wire.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// #include <i2c_api.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(PIN_WIRE0_SDA) && defined(PIN_WIRE1_SDA)
|
||||
#define Wire1 Wire
|
||||
#endif
|
||||
|
||||
#define WIRE_HAS_END 1
|
||||
#define WIRE_DEFAULT_FREQ 100000
|
||||
|
||||
struct i2c_s;
|
||||
typedef struct i2c_s i2c_t;
|
||||
|
||||
using arduino::RingBuffer;
|
||||
|
||||
class TwoWire : public ITwoWire {
|
||||
private:
|
||||
i2c_t *_i2c = NULL;
|
||||
uint8_t _idx = 0;
|
||||
|
||||
RingBuffer _rxBuf;
|
||||
RingBuffer _txBuf;
|
||||
uint8_t _txAddr = 0;
|
||||
bool _inSetPins = false;
|
||||
|
||||
public:
|
||||
TwoWire();
|
||||
TwoWire(int8_t sda, int8_t scl);
|
||||
~TwoWire();
|
||||
|
||||
bool setPins(int8_t sda, int8_t scl);
|
||||
|
||||
bool begin(int8_t sda, int8_t scl, uint32_t frequency = 0);
|
||||
bool begin(uint8_t address, int8_t sda, int8_t scl, uint32_t frequency = 0);
|
||||
bool end();
|
||||
|
||||
bool setClock(uint32_t freq);
|
||||
|
||||
void beginTransmission(uint8_t address);
|
||||
uint8_t endTransmission(bool stopBit);
|
||||
|
||||
size_t requestFrom(uint8_t address, size_t len, bool stopBit);
|
||||
size_t write(uint8_t data);
|
||||
size_t write(const uint8_t *data, size_t len);
|
||||
|
||||
int available();
|
||||
int read();
|
||||
int peek();
|
||||
void flush();
|
||||
|
||||
using ITwoWire::begin;
|
||||
using ITwoWire::endTransmission;
|
||||
using ITwoWire::requestFrom;
|
||||
using ITwoWire::write;
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#ifdef PIN_WIRE0_SDA
|
||||
extern TwoWire Wire;
|
||||
#endif
|
||||
#ifdef PIN_WIRE1_SDA
|
||||
extern TwoWire Wire1;
|
||||
#endif
|
||||
@@ -40,7 +40,11 @@ static const uint8_t A2 = PIN_A2;
|
||||
|
||||
// Wire Interfaces
|
||||
// ---------------
|
||||
#define WIRE_INTERFACES_COUNT 0
|
||||
#define WIRE_INTERFACES_COUNT 2
|
||||
#define PIN_WIRE0_SDA 1u // PA_19
|
||||
#define PIN_WIRE0_SCL 0u // PA_22
|
||||
#define PIN_WIRE1_SDA 10u // PA_23
|
||||
#define PIN_WIRE1_SCL 9u // PA_18
|
||||
|
||||
// Serial ports
|
||||
// ------------
|
||||
|
||||
Reference in New Issue
Block a user