diff --git a/libraries/ADG2128_RT/.arduino-ci.yml b/libraries/ADG2128_RT/.arduino-ci.yml new file mode 100644 index 00000000..d9b3a2aa --- /dev/null +++ b/libraries/ADG2128_RT/.arduino-ci.yml @@ -0,0 +1,30 @@ +platforms: + rpipico: + board: rp2040:rp2040:rpipico + package: rp2040:rp2040 + gcc: + features: + defines: + - ARDUINO_ARCH_RP2040 + warnings: + flags: + +packages: + rp2040:rp2040: + url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + +compile: + # Choosing to run compilation tests on 2 different Arduino platforms + platforms: + - uno + # - due + # - zero + # - leonardo + - m4 + - esp32 + - esp8266 + # - mega2560 + - rpipico + + libraries: + - "printHelpers" diff --git a/libraries/ADG2128_RT/.github/FUNDING.yml b/libraries/ADG2128_RT/.github/FUNDING.yml new file mode 100644 index 00000000..554358c3 --- /dev/null +++ b/libraries/ADG2128_RT/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: RobTillaart +custom: "https://www.paypal.me/robtillaart" diff --git a/libraries/ADG2128_RT/.github/workflows/arduino-lint.yml b/libraries/ADG2128_RT/.github/workflows/arduino-lint.yml new file mode 100644 index 00000000..7f8f4ef4 --- /dev/null +++ b/libraries/ADG2128_RT/.github/workflows/arduino-lint.yml @@ -0,0 +1,13 @@ +name: Arduino-lint + +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update + compliance: strict \ No newline at end of file diff --git a/libraries/ADG2128_RT/.github/workflows/arduino_test_runner.yml b/libraries/ADG2128_RT/.github/workflows/arduino_test_runner.yml new file mode 100644 index 00000000..dbd0ce79 --- /dev/null +++ b/libraries/ADG2128_RT/.github/workflows/arduino_test_runner.yml @@ -0,0 +1,17 @@ +name: Arduino CI + +on: [push, pull_request] + +jobs: + runTest: + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/ADG2128_RT/.github/workflows/jsoncheck.yml b/libraries/ADG2128_RT/.github/workflows/jsoncheck.yml new file mode 100644 index 00000000..1cbb5e2c --- /dev/null +++ b/libraries/ADG2128_RT/.github/workflows/jsoncheck.yml @@ -0,0 +1,18 @@ +name: JSON check + +on: + push: + paths: + - '**.json' + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - name: json-syntax-check + uses: limitusus/json-syntax-check@v2 + with: + pattern: "\\.json$" \ No newline at end of file diff --git a/libraries/ADG2128_RT/ADG2128.cpp b/libraries/ADG2128_RT/ADG2128.cpp new file mode 100644 index 00000000..66226144 --- /dev/null +++ b/libraries/ADG2128_RT/ADG2128.cpp @@ -0,0 +1,184 @@ +// +// FILE: ADG2128.cpp +// AUTHOR: Rob Tillaart +// DATE: 2025-02-28 +// VERSION: 0.1.0 +// PURPOSE: Arduino library for ADG2128 8x8 (cross-point) matrix switch with I2C. +// URL: https://github.com/RobTillaart/ADG2128 + + + +#include "ADG2128.h" + +#define ADG2128_LATCHED_MODE 0x00 +#define ADG2128_DIRECT_MODE 0x01 + + +ADG2128::ADG2128(uint8_t address, TwoWire *wire) +{ + _address = address; + _wire = wire; + _error = 0; + _mode = ADG2128_DIRECT_MODE; + _reset = 255; +} + +bool ADG2128::begin() +{ + // reset variables + _error = 0; + + if ((_address < 0x70) || (_address > 0x77)) + { + _error = -1; + return false; + } + if (! isConnected()) + { + return false; + } + return true; +} + +bool ADG2128::isConnected() +{ + _wire->beginTransmission(_address); + return (_wire->endTransmission() == 0); +} + +uint8_t ADG2128::getAddress() +{ + return _address; +} + + +///////////////////////////////////////////// +// +// SWITCHES +// +void ADG2128::on(uint8_t row, uint8_t col) +{ + if ((row > 7 ) || (col > 11)) return; + uint8_t pins = 0x80; // 0x80 == ON + if (col < 6) pins |= (col << 3) + row; + else pins |= ((col + 2) << 3) + row; + _send(pins, _mode); +} + +void ADG2128::off(uint8_t row, uint8_t col) +{ + if ((row > 7 ) || (col > 11)) return; + uint8_t pins = 0x00; // 0x00 == OFF + if (col < 6) pins |= (col << 3) + row; + else pins |= ((col + 2) << 3) + row; + + _send(pins, _mode); +} + +bool ADG2128::isOn(uint8_t row, uint8_t col) +{ + if ((row > 7 ) || (col > 11)) return false; + uint8_t value = isOn(col); + return (value & (1 << row)) > 0; +} + +uint8_t ADG2128::isOnMask(uint8_t col) +{ + if (col > 11) return false; + // Table 8 datasheet + uint8_t mask = 0x34; // == 0b00110100; + if (col & 0x08) mask |= 0x02; + if (col & 0x04) mask |= 0x01; + if (col & 0x02) mask |= 0x40; + if (col & 0x01) mask |= 0x08; + + return _readback(mask); +} + + +///////////////////////////////////////////// +// +// MODE +// +// default direct (transparent) mode +void ADG2128::setMode(bool latched) +{ + _mode = latched ? ADG2128_LATCHED_MODE : ADG2128_DIRECT_MODE; +} + +bool ADG2128::isLatchedMode() +{ + return _mode == ADG2128_LATCHED_MODE; +} + +bool ADG2128::isDirectMode() +{ + return _mode == ADG2128_DIRECT_MODE; +} + + +///////////////////////////////////////////// +// +// RESET +// +void ADG2128::setResetPin(uint8_t resetPin) +{ + _reset = resetPin; + pinMode(_reset, OUTPUT); + digitalWrite(_reset, HIGH); +} + + +void ADG2128::pulseResetPin() +{ + digitalWrite(_reset, LOW); + // need delay(1); + digitalWrite(_reset, HIGH); +} + + +///////////////////////////////////////////// +// +// DEBUG +// +int ADG2128::getLastError() +{ + int e = _error; + _error = 0; + return e; +} + + +/////////////////////////////////////////////// +// +// PRIVATE +// + +int ADG2128::_send(uint8_t pins, uint8_t value) +{ + _wire->beginTransmission(_address); + _wire->write(pins); + _wire->write(value); + _error = _wire->endTransmission(); + return _error; +} + + +int ADG2128::_readback(uint8_t value) +{ + _wire->beginTransmission(_address); + _wire->write(value); + _error = _wire->endTransmission(); + uint8_t bytes = _wire->requestFrom(_address, (uint8_t)2); + if (bytes != 2) + { + _error = -1; + return 0; + } + _wire->read(); // skip dummy data + return _wire->read(); +} + + +// -- END OF FILE -- + diff --git a/libraries/ADG2128_RT/ADG2128.h b/libraries/ADG2128_RT/ADG2128.h new file mode 100644 index 00000000..f48e42c9 --- /dev/null +++ b/libraries/ADG2128_RT/ADG2128.h @@ -0,0 +1,85 @@ +#pragma once +// +// FILE: ADG2128.h +// AUTHOR: Rob Tillaart +// DATE: 2025-02-28 +// VERSION: 0.1.0 +// PURPOSE: Arduino library for ADG2128 8x12 (cross-point) matrix switch with I2C. +// URL: https://github.com/RobTillaart/ADG2128 +// + + +#include "Arduino.h" +#include "Wire.h" + + +#define ADG2128_LIB_VERSION (F("0.1.0")) + +#define ADG2128_DEFAULT_ADDRESS 0x70 + +// ERROR CODES +// values <> 0 are errors. +#define ADG2128_OK 0x00 +#define ADG2128_CRC_ERROR 0x01 +#define ADG2128_NOT_READY 0x10 +#define ADG2128_REQUEST_ERROR 0x11 + + +class ADG2128 +{ +public: + ADG2128(uint8_t address = ADG2128_DEFAULT_ADDRESS, TwoWire *wire = &Wire); + + bool begin(); + bool isConnected(); + uint8_t getAddress(); + + + // SWITCH + void on(uint8_t row, uint8_t col); + void off(uint8_t row, uint8_t col); + bool isOn(uint8_t row, uint8_t col); + uint8_t isOnMask(uint8_t col); // get a whole column at once as bit mask. + + // WRAPPERS. + void on(uint8_t sw) { on(sw / 12, sw % 12); }; + void off(uint8_t sw) { off(sw / 12, sw % 12); }; + uint8_t isOn(uint8_t sw) { return isOn(sw / 12, sw % 12); }; + + + // MODE + // default direct (transparent) mode + void setMode(bool latched = false); + bool isLatchedMode(); + bool isDirectMode(); + + + // RESET + void setResetPin(uint8_t resetPin); + // reset ==> all switches off, registers ==> 0. + void pulseResetPin(); + + + // DEBUG + int getLastError(); + + +private: + uint8_t _address = 0x2A; + TwoWire* _wire; + + int _send(uint8_t pins, uint8_t value); + int _readback(uint8_t value); + + int _error; + uint8_t _mode; + uint8_t _reset; +}; + + +// -- END OF FILE -- + + + + + diff --git a/libraries/ADG2128_RT/CHANGELOG.md b/libraries/ADG2128_RT/CHANGELOG.md new file mode 100644 index 00000000..5edbbe9b --- /dev/null +++ b/libraries/ADG2128_RT/CHANGELOG.md @@ -0,0 +1,13 @@ +# Change Log ADG2128 + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + + +## [0.1.0] - 2025-02-28 +- initial version + + + diff --git a/libraries/ADG2128_RT/LICENSE b/libraries/ADG2128_RT/LICENSE new file mode 100644 index 00000000..0c1afa34 --- /dev/null +++ b/libraries/ADG2128_RT/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025-2025 Rob Tillaart + +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. diff --git a/libraries/ADG2128_RT/README.md b/libraries/ADG2128_RT/README.md new file mode 100644 index 00000000..2648926a --- /dev/null +++ b/libraries/ADG2128_RT/README.md @@ -0,0 +1,171 @@ + +[![Arduino CI](https://github.com/RobTillaart/ADG2128/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/ADG2128/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/ADG2128/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/ADG2128/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/ADG2128/actions/workflows/jsoncheck.yml) +[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/ADG2128.svg)](https://github.com/RobTillaart/ADG2128/issues) + +[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/ADG2128/blob/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/RobTillaart/ADG2128.svg?maxAge=3600)](https://github.com/RobTillaart/ADG2128/releases) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/ADG2128.svg)](https://registry.platformio.org/libraries/robtillaart/ADG2128) + + +# ADG2128 + +Arduino library for ADG2128 8x12 (cross-point) matrix switch with I2C. + + +## Description + +**Experimental** + +The library is **NOT** tested with hardware yet. Feedback is welcome. + +This library is to use an ADG2128 8x12 cross-point matrix switch from a microcontroller. +That means the ADG2128 device implements a matrix of switches of 8 rows and 12 columns. +Every row has a switch to every column, which can be on or off. + +The device can operate in two modi, direct (transparent) or latched (delayed) mode. +In the first setting a switch will be visible immediately, while the latch mode +waits until they can all be switched simultaneously. + +The device has a reset line that can be "pulsed LOW" which will reset +all registers and switches to OFF state. + +The library is based on datasheet Rev. E, www.analog.com + +- https://www.analog.com/media/en/technical-documentation/data-sheets/ADG2128.pdf + +Feedback as always is welcome. + + +### Compatibles + +There exists 8x12 ADG2128, however that device is not 100% compatible with this library. + + +### Related + +- https://github.com/RobTillaart/ADG2128 8x12 cross-point switch +- https://github.com/RobTillaart/ADG2188 8x8 cross-point switch + + +## I2C + +### I2C Address + +The ADG2128 has three address pins, A0, A1, A2, which allows for a total of +8 addresses. These are in the range 0x70..0x77 or decimal 112..119. + + +### I2C multiplexing + +Sometimes you need to control more devices than possible with the default +address range the device provides. +This is possible with an I2C multiplexer e.g. TCA9548 which creates up +to eight channels (think of it as I2C subnets) which can use the complete +address range of the device. + +Drawback of using a multiplexer is that it takes more administration in +your code e.g. which device is on which channel. +This will slow down the access, which must be taken into account when +deciding which devices are on which channel. +Also note that switching between channels will slow down other devices +too if they are behind the multiplexer. + +- https://github.com/RobTillaart/TCA9548 + +See example **TCA9548_demo_ADG2128.ino** + + +### I2C Performance + +Should work in Standard mode 100 kHz, Fast mode 400 kHz and +High speed mode 1.7 / 3.4 MHz (see notes datasheet). + +TODO: run performance sketch on hardware. feedback is welcome. + +| Clock | time (us) | Notes | +|:----------:|:-----------:|:--------| +| 100 KHz | | default +| 200 KHz | | +| 300 KHz | | +| 400 KHz | | +| 500 KHz | | +| 600 KHz | | + + +## Interface + +```cpp +#include "ADG2128.h" +``` + +### Constructor + +- **ADG2128(uint8_t address = 0x70, TwoWire \*wire = &Wire)** optional select I2C bus. +- **bool begin()** checks if device is visible on the I2C bus. +- **bool isConnected()** Checks if device address can be found on I2C bus. +- **uint8_t getAddress()** Returns the address, 0x70-0x77 (112-119). + +### On Off + +- **void on(uint8_t row, uint8_t col)** idem. +- **void off(uint8_t row, uint8_t col)** idem. +- **bool isOn(uint8_t row, uint8_t col)** returns true if switch os on. +- **uint8_t isOnMask(uint8_t col)** get a whole column at once as bit mask. + +Convenience wrappers, sw = 0..95, row = sw / 12, col = sw % 12; +- **void on(uint8_t sw)** +- **void off(uint8_t sw)** +- **bool isOn(uint8_t sw)** + +### Mode + +The default is direct (transparent) mode. + +- **void setMode(bool latched = false)** set mode, default direct. +- **bool isLatchedMode()**idem. +- **bool isDirectMode()** idem. + +### Reset + +Using the reset pin is optional, keep it HIGH if you do not use it. +Otherwise you cannot write to the device. + +- **void setResetPin(uint8_t resetPin)** set the reset pin. +- **void pulseResetPin()** resets all switches off, all registers ==> 0. + +### Debug + +Error handling is to be elaborated. + +- **uint8_t getLastError()** returns last error of low level communication. + +## Future + +#### Must + +- improve documentation +- get hardware to test +- keep in sync with ADG2188 + +#### Should + + +#### Could + +- cache status of switches to speed up On/Off + - import export cache + +#### Wont + + +## Support + +If you appreciate my libraries, you can support the development and maintenance. +Improve the quality of the libraries by providing issues and Pull Requests, or +donate through PayPal or GitHub sponsors. + +Thank you, + + diff --git a/libraries/ADG2128_RT/examples/ADG2128_demo/ADG2128_demo.ino b/libraries/ADG2128_RT/examples/ADG2128_demo/ADG2128_demo.ino new file mode 100644 index 00000000..424ee12a --- /dev/null +++ b/libraries/ADG2128_RT/examples/ADG2128_demo/ADG2128_demo.ino @@ -0,0 +1,52 @@ +// +// FILE: ADG2128_demo.ino +// AUTHOR: Rob Tillaart +// PURPOSE: test basic behaviour and performance +// URL: https://github.com/RobTillaart/ADG2128 + + +#include "ADG2128.h" + + +ADG2128 sw(0x70); + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + Serial.println(__FILE__); + Serial.print("ADG2128_LIB_VERSION: "); + Serial.println(ADG2128_LIB_VERSION); + + Wire.begin(); + if (sw.begin() == false) + { + Serial.println("Error connecting to device"); + while(1); + } +} + + +void loop() +{ + for (int row = 0; row < 8; row++) + { + for (int col = 0; col < 12; col++) + { + sw.on(row, col); + } + } + delay(100); + for (int row = 0; row < 8; row++) + { + for (int col = 0; col < 12; col++) + { + sw.off(row, col); + } + } + delay(1000); +} + + +// -- END OF FILE -- diff --git a/libraries/ADG2128_RT/keywords.txt b/libraries/ADG2128_RT/keywords.txt new file mode 100644 index 00000000..df407abb --- /dev/null +++ b/libraries/ADG2128_RT/keywords.txt @@ -0,0 +1,34 @@ +# Syntax Colouring Map For ADG2128 + +# Data types (KEYWORD1) +ADG2128 KEYWORD1 + + +# Methods and Functions (KEYWORD2) +begin KEYWORD2 +isConnected KEYWORD2 +getAddress KEYWORD2 + +on KEYWORD2 +off KEYWORD2 +isOn KEYWORD2 + +setMode KEYWORD2 +isLatchedMode KEYWORD2 +isDirectMode KEYWORD2 + +setResetPin KEYWORD2 +pulseResetPin KEYWORD2 + +getLastError KEYWORD2 + + +# Constants (LITERAL1) +ADG2128_LIB_VERSION LITERAL1 + +ADG2128_DEFAULT_ADDRESS LITERAL1 + +ADG2128_OK LITERAL1 +ADG2128_CRC_ERROR LITERAL1 +ADG2128_NOT_READY LITERAL1 +ADG2128_REQUEST_ERROR LITERAL1 diff --git a/libraries/ADG2128_RT/library.json b/libraries/ADG2128_RT/library.json new file mode 100644 index 00000000..6deb486a --- /dev/null +++ b/libraries/ADG2128_RT/library.json @@ -0,0 +1,23 @@ +{ + "name": "ADG2128", + "keywords": "", + "description": "Arduino library for ADG2128 8x12 (cross-point) matrix switch with I2C.", + "authors": + [ + { + "name": "Rob Tillaart", + "email": "Rob.Tillaart@gmail.com", + "maintainer": true + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/RobTillaart/ADG2128.git" + }, + "version": "0.1.0", + "license": "MIT", + "frameworks": "*", + "platforms": "*", + "headers": "ADG2128.h" +} diff --git a/libraries/ADG2128_RT/library.properties b/libraries/ADG2128_RT/library.properties new file mode 100644 index 00000000..4a1d2a24 --- /dev/null +++ b/libraries/ADG2128_RT/library.properties @@ -0,0 +1,11 @@ +name=ADG2128_RT +version=0.1.0 +author=Rob Tillaart +maintainer=Rob Tillaart +sentence=Arduino library for ADG2128 8x12 (cross-point) matrix switch with I2C. +paragraph= +category=Sensors +url=https://github.com/RobTillaart/ADG2128_RT +architectures=* +includes=ADG2128.h +depends= diff --git a/libraries/ADG2128_RT/test/unit_test_001.cpp b/libraries/ADG2128_RT/test/unit_test_001.cpp new file mode 100644 index 00000000..3871658b --- /dev/null +++ b/libraries/ADG2128_RT/test/unit_test_001.cpp @@ -0,0 +1,66 @@ +// +// FILE: unit_test_001.cpp +// AUTHOR: Rob Tillaart +// DATE: 2025-02-28 +// PURPOSE: unit tests for the ADG2128 library +// URL: https://github.com/RobTillaart/ADG2128 +// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md +// + +// supported assertions +// https://github.com/Arduino-CI/arduino_ci/blob/master/cpp/unittest/Assertion.h#L33-L42 +// ---------------------------- +// assertEqual(expected, actual) +// assertNotEqual(expected, actual) +// assertLess(expected, actual) +// assertMore(expected, actual) +// assertLessOrEqual(expected, actual) +// assertMoreOrEqual(expected, actual) +// assertTrue(actual) +// assertFalse(actual) +// assertNull(actual) +// assertNotNull(actual) + +#include + + +#include "Arduino.h" +#include "ADG2128.h" + + +unittest_setup() +{ + fprintf(stderr, "ADG2128_LIB_VERSION: %s\n", (char *) ADG2128_LIB_VERSION); +} + + +unittest_teardown() +{ +} + + +unittest(test_constants) +{ + assertEqual(ADG2128_DEFAULT_ADDRESS, 0x70); + + assertEqual(ADG2128_OK , 0x00); + assertEqual(ADG2128_CRC_ERROR , 0x01); + assertEqual(ADG2128_NOT_READY , 0x10); + assertEqual(ADG2128_REQUEST_ERROR, 0x11); +} + + +unittest(test_constructor) +{ + ADG2128 adg; + + assertEqual(adg.getAddress(), ADG2128_DEFAULT_ADDRESS); + assertEqual(adg.getLastError(), 0); +} + + +unittest_main() + + +// -- END OF FILE -- +