mirror of
https://github.com/Xinyuan-LilyGO/T-Display-S3.git
synced 2024-09-21 09:57:26 +00:00
Add files via upload
This commit is contained in:
parent
88f7d68fd8
commit
33164d2469
21
lib/PCA95x5/LICENSE
Normal file
21
lib/PCA95x5/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Hideaki Tai
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
187
lib/PCA95x5/PCA95x5.h
Normal file
187
lib/PCA95x5/PCA95x5.h
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* @Description: None
|
||||
* @version: V1.0.0
|
||||
* @Author: None
|
||||
* @Date: 2023-07-14 09:26:36
|
||||
* @LastEditors: LILYGO_L
|
||||
* @LastEditTime: 2023-07-14 09:45:19
|
||||
* @License: GPL 3.0
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
namespace PCA95x5 {
|
||||
|
||||
namespace Reg {
|
||||
enum : uint8_t {
|
||||
INPUT_PORT_0,
|
||||
INPUT_PORT_1,
|
||||
OUTPUT_PORT_0,
|
||||
OUTPUT_PORT_1,
|
||||
POLARITY_INVERSION_PORT_0,
|
||||
POLARITY_INVERSION_PORT_1,
|
||||
CONFIGURATION_PORT_0,
|
||||
CONFIGURATION_PORT_1,
|
||||
};
|
||||
}
|
||||
|
||||
namespace Port {
|
||||
enum Port : uint8_t {
|
||||
P00,
|
||||
P01,
|
||||
P02,
|
||||
P03,
|
||||
P04,
|
||||
P05,
|
||||
P06,
|
||||
P07,
|
||||
P10,
|
||||
P11,
|
||||
P12,
|
||||
P13,
|
||||
P14,
|
||||
P15,
|
||||
P16,
|
||||
P17,
|
||||
};
|
||||
} // namespace Port
|
||||
|
||||
namespace Level {
|
||||
enum Level : uint8_t { L, H };
|
||||
enum LevelAll : uint16_t { L_ALL = 0x0000, H_ALL = 0xFFFF };
|
||||
} // namespace Level
|
||||
|
||||
namespace Polarity {
|
||||
enum Polarity : uint8_t { ORIGINAL, INVERTED };
|
||||
enum PolarityAll : uint16_t { ORIGINAL_ALL = 0x0000, INVERTED_ALL = 0xFFFF };
|
||||
} // namespace Polarity
|
||||
|
||||
namespace Direction {
|
||||
enum Direction : uint8_t { OUT, IN };
|
||||
enum DirectionAll : uint16_t { OUT_ALL = 0x0000, IN_ALL = 0xFFFF };
|
||||
} // namespace Direction
|
||||
|
||||
template <typename WireType = TwoWire>
|
||||
class PCA95x5 {
|
||||
union Ports {
|
||||
uint16_t w;
|
||||
uint8_t b[2];
|
||||
};
|
||||
|
||||
static constexpr uint8_t BASE_I2C_ADDR = 0x20;
|
||||
|
||||
WireType* wire {nullptr};
|
||||
uint8_t addr {BASE_I2C_ADDR};
|
||||
Ports input {0x0000};
|
||||
Ports output {0xFFFF};
|
||||
Ports pol {0x0000};
|
||||
Ports dir {0xFFFF};
|
||||
uint8_t status {0x00};
|
||||
|
||||
public:
|
||||
void attach(WireType& wire, uint8_t i2c_addr = BASE_I2C_ADDR) {
|
||||
this->wire = &wire;
|
||||
this->addr = i2c_addr;
|
||||
}
|
||||
|
||||
uint16_t read() {
|
||||
read_bytes(this->addr, Reg::INPUT_PORT_0, this->input.b, 2);
|
||||
return this->input.w;
|
||||
}
|
||||
Level::Level read(const Port::Port port) {
|
||||
uint16_t v = read();
|
||||
return (v & (1 << port)) ? Level::H : Level::L;
|
||||
}
|
||||
Level::Level read(uint8_t port) {
|
||||
uint16_t v = read();
|
||||
return (v & (1 << port)) ? Level::H : Level::L;
|
||||
}
|
||||
|
||||
bool write(const uint16_t value) {
|
||||
this->output.w = value;
|
||||
return write_impl();
|
||||
}
|
||||
bool write(const Port::Port port, const Level::Level level) {
|
||||
if (level == Level::H) {
|
||||
this->output.w |= (1 << port);
|
||||
} else {
|
||||
this->output.w &= ~(1 << port);
|
||||
}
|
||||
return write_impl();
|
||||
}
|
||||
bool write(uint8_t port, uint8_t level) {
|
||||
if (level == Level::H) {
|
||||
this->output.w |= (1 << port);
|
||||
} else {
|
||||
this->output.w &= ~(1 << port);
|
||||
}
|
||||
return write_impl();
|
||||
}
|
||||
|
||||
bool polarity(const uint16_t value) {
|
||||
this->pol.w = value;
|
||||
return polarity_impl();
|
||||
}
|
||||
bool polarity(const Port::Port port, const Polarity::Polarity pol) {
|
||||
if (pol == Polarity::INVERTED) {
|
||||
this->pol.w |= (1 << port);
|
||||
} else {
|
||||
this->pol.w &= ~(1 << port);
|
||||
}
|
||||
return polarity_impl();
|
||||
}
|
||||
|
||||
bool direction(const uint16_t value) {
|
||||
this->dir.w = value;
|
||||
return direction_impl();
|
||||
}
|
||||
|
||||
bool direction(const Port::Port port, const Direction::Direction dir) {
|
||||
if (dir == Direction::IN) {
|
||||
this->dir.w |= (1 << port);
|
||||
} else {
|
||||
this->dir.w &= ~(1 << port);
|
||||
}
|
||||
return direction_impl();
|
||||
}
|
||||
|
||||
uint8_t i2c_error() const {
|
||||
return status;
|
||||
}
|
||||
|
||||
private:
|
||||
bool write_impl() {
|
||||
return write_bytes(this->addr, Reg::OUTPUT_PORT_0, this->output.b, 2);
|
||||
}
|
||||
|
||||
bool polarity_impl() {
|
||||
return write_bytes(this->addr, Reg::POLARITY_INVERSION_PORT_0, this->pol.b, 2);
|
||||
}
|
||||
|
||||
bool direction_impl() {
|
||||
return write_bytes(this->addr, Reg::CONFIGURATION_PORT_0, this->dir.b, 2);
|
||||
}
|
||||
|
||||
int8_t read_bytes(const uint8_t dev, const uint8_t reg, uint8_t* data, const uint8_t size) {
|
||||
wire->beginTransmission(dev);
|
||||
wire->write(reg);
|
||||
wire->endTransmission();
|
||||
wire->requestFrom(dev, size);
|
||||
int8_t count = 0;
|
||||
while (wire->available()) data[count++] = wire->read();
|
||||
return count;
|
||||
}
|
||||
|
||||
bool write_bytes(const uint8_t dev, const uint8_t reg, const uint8_t* data, const uint8_t size) {
|
||||
wire->beginTransmission(dev);
|
||||
wire->write(reg);
|
||||
for (uint8_t i = 0; i < size; i++) wire->write(data[i]);
|
||||
status = wire->endTransmission();
|
||||
return (status == 0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace PCA95x5
|
||||
|
||||
using PCA9535 = PCA95x5::PCA95x5<>;
|
||||
using PCA9555 = PCA95x5::PCA95x5<>;
|
127
lib/PCA95x5/README.md
Normal file
127
lib/PCA95x5/README.md
Normal file
@ -0,0 +1,127 @@
|
||||
# PCA95x5
|
||||
|
||||
Arduino library for [PCA9535](https://www.ti.com/product/PCA9535) and [PCA9555](https://www.ti.com/product/PCA9555) (Remote 16-bit I2C and SMBus I/O Expander with Interrupt Output and Configuration Registers).
|
||||
|
||||
## Usage
|
||||
|
||||
You can specify a port using either index (`0` - `15`) or enum (`PCA95x5::Port::P02`, etc.).
|
||||
|
||||
### Input
|
||||
|
||||
```C++
|
||||
#include <PCA95x5.h>
|
||||
|
||||
// select one of them
|
||||
PCA9535 ioex;
|
||||
// PCA9555 ioex;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(2000);
|
||||
|
||||
Wire.begin();
|
||||
ioex.attach(Wire);
|
||||
ioex.polarity(PCA95x5::Polarity::ORIGINAL_ALL);
|
||||
ioex.direction(PCA95x5::Direction::IN_ALL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println(ioex.read(), BIN);
|
||||
delay(1000);
|
||||
}
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```C++
|
||||
#include <PCA95x5.h>
|
||||
|
||||
// select one of them
|
||||
// PCA9535 ioex;
|
||||
PCA9555 ioex;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(2000);
|
||||
|
||||
Wire.begin();
|
||||
ioex.attach(Wire);
|
||||
ioex.polarity(PCA95x5::Polarity::ORIGINAL_ALL);
|
||||
ioex.direction(PCA95x5::Direction::OUT_ALL);
|
||||
ioex.write(PCA95x5::Level::L_ALL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
Serial.print("set port high: ");
|
||||
Serial.println(i);
|
||||
|
||||
ioex.write(i, PCA95x5::Level::H);
|
||||
Serial.println(ioex.read(), BIN);
|
||||
delay(500);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
Serial.print("set port low: ");
|
||||
Serial.println(i);
|
||||
|
||||
ioex.write(i, PCA95x5::Level::L);
|
||||
Serial.println(ioex.read(), BIN);
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## APIs
|
||||
|
||||
```C++
|
||||
void attach(WireType& wire, uint8_t i2c_addr = BASE_I2C_ADDR);
|
||||
uint16_t read();
|
||||
Level::Level read(const uint8_t port);
|
||||
bool write(const uint16_t value);
|
||||
bool write(const uint8_t port, const Level::Level level);
|
||||
bool polarity(const uint16_t value);
|
||||
bool polarity(const uint8_t port, const Polarity::Polarity pol);
|
||||
bool direction(const uint16_t value);
|
||||
bool direction(const uint8_t port, const Direction::Direction dir);
|
||||
uint8_t i2c_error() const;
|
||||
```
|
||||
|
||||
```C++
|
||||
namespace Port {
|
||||
enum Port : uint8_t {
|
||||
P00,
|
||||
P01,
|
||||
P02,
|
||||
P03,
|
||||
P04,
|
||||
P05,
|
||||
P06,
|
||||
P07,
|
||||
P10,
|
||||
P11,
|
||||
P12,
|
||||
P13,
|
||||
P14,
|
||||
P15,
|
||||
P16,
|
||||
P17,
|
||||
};
|
||||
}
|
||||
namespace Level {
|
||||
enum Level : uint8_t { L, H };
|
||||
enum LevelAll : uint16_t { L_ALL = 0x0000, H_ALL = 0xFFFF };
|
||||
}
|
||||
namespace Polarity {
|
||||
enum Polarity : uint8_t { ORIGINAL, INVERTED };
|
||||
enum PolarityAll : uint16_t { ORIGINAL_ALL = 0x0000, INVERTED_ALL = 0xFFFF };
|
||||
}
|
||||
namespace Direction {
|
||||
enum Direction : uint8_t { OUT, IN };
|
||||
enum DirectionAll : uint16_t { OUT_ALL = 0x0000, IN_ALL = 0xFFFF };
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
18
lib/PCA95x5/examples/input/input.ino
Normal file
18
lib/PCA95x5/examples/input/input.ino
Normal file
@ -0,0 +1,18 @@
|
||||
#include <PCA95x5.h>
|
||||
|
||||
PCA9555 ioex;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(2000);
|
||||
|
||||
Wire.begin();
|
||||
ioex.attach(Wire);
|
||||
ioex.polarity(PCA95x5::Polarity::ORIGINAL_ALL);
|
||||
ioex.direction(PCA95x5::Direction::IN_ALL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println(ioex.read(), BIN);
|
||||
delay(1000);
|
||||
}
|
34
lib/PCA95x5/examples/output/output.ino
Normal file
34
lib/PCA95x5/examples/output/output.ino
Normal file
@ -0,0 +1,34 @@
|
||||
#include <PCA95x5.h>
|
||||
|
||||
PCA9555 ioex;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(2000);
|
||||
|
||||
Wire.begin();
|
||||
ioex.attach(Wire);
|
||||
ioex.polarity(PCA95x5::Polarity::ORIGINAL_ALL);
|
||||
ioex.direction(PCA95x5::Direction::OUT_ALL);
|
||||
ioex.write(PCA95x5::Level::L_ALL);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
Serial.print("set port high: ");
|
||||
Serial.println(i);
|
||||
|
||||
ioex.write(i, PCA95x5::Level::H);
|
||||
Serial.println(ioex.read(), BIN);
|
||||
delay(500);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
Serial.print("set port low: ");
|
||||
Serial.println(i);
|
||||
|
||||
ioex.write(i, PCA95x5::Level::L);
|
||||
Serial.println(ioex.read(), BIN);
|
||||
delay(500);
|
||||
}
|
||||
}
|
20
lib/PCA95x5/library.json
Normal file
20
lib/PCA95x5/library.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "PCA95x5",
|
||||
"keywords": "i2c,mux,io expander,pca9535,pca9555",
|
||||
"description": "Arduino library for PCA9535 and PCA9555 (Remote 16-bit I2C and SMBus I/O Expander with Interrupt Output and Configuration Registers)",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/hideakitai/PCA95x5.git"
|
||||
},
|
||||
"authors":
|
||||
{
|
||||
"name": "Hideaki Tai",
|
||||
"url": "https://github.com/hideakitai",
|
||||
"maintainer": true
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
9
lib/PCA95x5/library.properties
Normal file
9
lib/PCA95x5/library.properties
Normal file
@ -0,0 +1,9 @@
|
||||
name=PCA95x5
|
||||
version=0.1.1
|
||||
author=hideakitai
|
||||
maintainer=hideakitai
|
||||
sentence=Arduino library for PCA9535 and PCA9555 (Remote 16-bit I2C and SMBus I/O Expander with Interrupt Output and Configuration Registers)
|
||||
paragraph=Arduino library for PCA9535 and PCA9555 (Remote 16-bit I2C and SMBus I/O Expander with Interrupt Output and Configuration Registers)
|
||||
category=Device Control
|
||||
url=https://github.com/hideakitai
|
||||
architectures=*
|
Loading…
Reference in New Issue
Block a user