added ANALOG_OUTPUT as first functionality

This commit is contained in:
mvturnho 2019-05-24 16:17:15 +02:00
parent 9d1c15d06c
commit dad38bb220
5 changed files with 497 additions and 0 deletions

View file

@ -0,0 +1,20 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c
from esphome.const import CONF_FREQUENCY, CONF_ID
DEPENDENCIES = ['i2c']
MULTI_CONF = True
sx1509_ns = cg.esphome_ns.namespace('sx1509')
SX1509Component = sx1509_ns.class_('SX1509Component', cg.Component, i2c.I2CDevice)
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(SX1509Component),
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x3E))
def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield cg.register_component(var, config)
yield i2c.register_i2c_device(var, config)

View file

@ -0,0 +1,24 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import output
from esphome.const import CONF_CHANNEL, CONF_ID
from . import SX1509Component, sx1509_ns
DEPENDENCIES = ['sx1509']
SX1509FloatOutputChannel = sx1509_ns.class_('SX1509FloatOutputChannel', output.FloatOutput)
CONF_SX1509_ID = 'sx1509_id'
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
cv.Required(CONF_ID): cv.declare_id(SX1509FloatOutputChannel),
cv.GenerateID(CONF_SX1509_ID): cv.use_id(SX1509Component),
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=15),
})
def to_code(config):
paren = yield cg.get_variable(config[CONF_SX1509_ID])
rhs = paren.create_float_output_channel(config[CONF_CHANNEL])
var = cg.Pvariable(config[CONF_ID], rhs)
yield output.register_output(var, config)

View file

@ -0,0 +1,213 @@
#include "sx1509.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace sx1509 {
static const char *TAG = "sx1509";
void SX1509Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up SX1509ComponentComponent...");
ESP_LOGV(TAG, " Resetting devices...");
this->write_byte(REG_RESET, 0x12);
this->write_byte(REG_RESET, 0x34);
// Communication test.
uint16_t data;
this->read_byte_16(REG_INTERRUPT_MASK_A, &data);
if (data == 0xFF00) {
clock(INTERNAL_CLOCK_2MHZ);
} else {
this->mark_failed();
return;
}
for (auto *channel : this->float_output_channels_)
channel->setup_channel();
delayMicroseconds(500);
this->loop();
}
void SX1509Component::dump_config() {
ESP_LOGCONFIG(TAG, "SX1509:");
if (this->is_failed()) {
ESP_LOGE(TAG, "Setting up SX1509 failed!");
}
}
void SX1509Component::loop() {}
SX1509FloatOutputChannel *
SX1509Component::create_float_output_channel(uint8_t channel) {
ESP_LOGD(TAG, "Set pin mode for channel %d", channel);
auto *c = new SX1509FloatOutputChannel(this, channel);
float_output_channels_.push_back(c);
return c;
}
void SX1509Component::digitalWrite(uint8_t channel, uint8_t highLow) {
uint16_t tempRegDir = 0;
this->read_byte_16(REG_DIR_B, &tempRegDir);
if ((0xFFFF ^ tempRegDir) &
(1 << channel)) // If the pin is an output, write high/low
{
uint16_t tempRegData = 0;
this->read_byte_16(REG_DATA_B, &tempRegData);
if (highLow)
tempRegData |= (1 << channel);
else
tempRegData &= ~(1 << channel);
this->write_byte_16(REG_DATA_B, tempRegData);
} else // Otherwise the pin is an input, pull-up/down
{
uint16_t tempPullUp;
this->read_byte_16(REG_PULL_UP_B, &tempPullUp);
uint16_t tempPullDown;
this->read_byte_16(REG_PULL_DOWN_B, &tempPullDown);
if (highLow) // if HIGH, do pull-up, disable pull-down
{
tempPullUp |= (1 << channel);
tempPullDown &= ~(1 << channel);
this->write_byte_16(REG_PULL_UP_B, tempPullUp);
this->write_byte_16(REG_PULL_DOWN_B, tempPullDown);
} else // If LOW do pull-down, disable pull-up
{
tempPullDown |= (1 << channel);
tempPullUp &= ~(1 << channel);
this->write_byte_16(REG_PULL_UP_B, tempPullUp);
this->write_byte_16(REG_PULL_DOWN_B, tempPullDown);
}
}
}
void SX1509Component::pinMode(uint8_t channel, uint8_t inOut) {
// The SX1509 RegDir registers: REG_DIR_B, REG_DIR_A
// 0: IO is configured as an output
// 1: IO is configured as an input
uint8_t modeBit;
if ((inOut == OUTPUT) || (inOut == ANALOG_OUTPUT))
modeBit = 0;
else
modeBit = 1;
uint16_t tempRegDir = 0;
this->read_byte_16(REG_DIR_B, &tempRegDir);
if (modeBit)
tempRegDir |= (1 << channel);
else
tempRegDir &= ~(1 << channel);
this->write_byte_16(REG_DIR_B, tempRegDir);
// If INPUT_PULLUP was called, set up the pullup too:
if (inOut == INPUT_PULLUP)
digitalWrite(channel, HIGH);
if (inOut == ANALOG_OUTPUT) {
ledDriverInit(channel);
}
}
void SX1509Component::ledDriverInit(uint8_t channel, uint8_t freq, bool log) {
uint16_t tempWord;
uint8_t tempByte;
// Disable input buffer
// Writing a 1 to the pin bit will disable that pins input buffer
this->read_byte_16(REG_INPUT_DISABLE_B, &tempWord);
tempWord |= (1 << channel);
this->write_byte_16(REG_INPUT_DISABLE_B, tempWord);
// Disable pull-up
// Writing a 0 to the pin bit will disable that pull-up resistor
this->read_byte_16(REG_PULL_UP_B, &tempWord);
tempWord &= ~(1 << channel);
this->write_byte_16(REG_PULL_UP_B, tempWord);
// Set direction to output (REG_DIR_B)
this->read_byte_16(REG_DIR_B, &tempWord);
tempWord &= ~(1 << channel); // 0=output
this->write_byte_16(REG_DIR_B, tempWord);
// Enable oscillator (REG_CLOCK)
this->read_byte(REG_CLOCK, &tempByte);
tempByte |= (1 << 6); // Internal 2MHz oscillator part 1 (set bit 6)
tempByte &= ~(1 << 5); // Internal 2MHz oscillator part 2 (clear bit 5)
this->write_byte(REG_CLOCK, tempByte);
// Configure LED driver clock and mode (REG_MISC)
this->read_byte(REG_MISC, &tempByte);
if (log) {
tempByte |= (1 << 7); // set logarithmic mode bank B
tempByte |= (1 << 3); // set logarithmic mode bank A
} else {
tempByte &= ~(1 << 7); // set linear mode bank B
tempByte &= ~(1 << 3); // set linear mode bank A
}
// Use configClock to setup the clock divder
if (_clkX == 0) // Make clckX non-zero
{
_clkX = 2000000.0 / (1 << (1 - 1)); // Update private clock variable
byte freq = (1 & 0x07) << 4; // freq should only be 3 bits from 6:4
tempByte |= freq;
}
this->write_byte(REG_MISC, tempByte);
// Enable LED driver operation (REG_LED_DRIVER_ENABLE)
this->read_byte_16(REG_LED_DRIVER_ENABLE_B, &tempWord);
tempWord |= (1 << channel);
this->write_byte_16(REG_LED_DRIVER_ENABLE_B, tempWord);
// Set REG_DATA bit low ~ LED driver started
this->read_byte_16(REG_DATA_B, &tempWord);
tempWord &= ~(1 << channel);
this->write_byte_16(REG_DATA_B, tempWord);
}
void SX1509Component::clock(byte oscSource, byte oscPinFunction,
byte oscFreqOut, byte oscDivider) {
oscSource = (oscSource & 0b11) << 5; // 2-bit value, bits 6:5
oscPinFunction = (oscPinFunction & 1) << 4; // 1-bit value bit 4
oscFreqOut = (oscFreqOut & 0b1111); // 4-bit value, bits 3:0
byte regClock = oscSource | oscPinFunction | oscFreqOut;
this->write_byte(REG_CLOCK, regClock);
oscDivider = constrain(oscDivider, 1, 7);
_clkX = 2000000.0 / (1 << (oscDivider - 1)); // Update private clock variable
oscDivider = (oscDivider & 0b111) << 4; // 3-bit value, bits 6:4
uint8_t regMisc;
this->read_byte(REG_MISC, &regMisc);
regMisc &= ~(0b111 << 4);
regMisc |= oscDivider;
this->write_byte(REG_MISC, regMisc);
}
void SX1509Component::set_channel_value_(uint8_t channel, uint8_t iOn) {
ESP_LOGD(TAG, "set_channel_value_ for channel %d to %d", channel, iOn);
this->write_byte(REG_I_ON[channel], iOn);
}
void SX1509FloatOutputChannel::write_state(float state) {
ESP_LOGD(TAG, "write_state %f", state);
const uint16_t max_duty = 255;
const float duty_rounded = roundf(state * max_duty);
auto duty = static_cast<uint16_t>(duty_rounded);
this->parent_->set_channel_value_(this->channel_, duty);
}
void SX1509FloatOutputChannel::setup_channel() {
this->parent_->pinMode(this->channel_, ANALOG_OUTPUT);
}
} // namespace sx1509
} // namespace esphome

View file

@ -0,0 +1,102 @@
#pragma once
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/output/float_output.h"
#include "esphome/core/component.h"
#include "sx1509_registers.h"
namespace esphome {
namespace sx1509 {
// These are used for setting LED driver to linear or log mode:
#define LINEAR 0
#define LOGARITHMIC 1
// These are used for clock config:
#define INTERNAL_CLOCK_2MHZ 2
#define EXTERNAL_CLOCK 1
#define SOFTWARE_RESET 0
#define HARDWARE_RESET 1
#define ANALOG_OUTPUT 0x3 // To set a pin mode for PWM output
class SX1509Component;
class SX1509FloatOutputChannel : public output::FloatOutput {
public:
SX1509FloatOutputChannel(SX1509Component *parent, uint8_t channel)
: parent_(parent), channel_(channel) {}
void setup_channel();
protected:
void write_state(float state) override;
SX1509Component *parent_;
uint8_t channel_;
};
/// SX1509 float output component.
class SX1509Component : public Component, public i2c::I2CDevice {
public:
SX1509Component() {}
SX1509FloatOutputChannel *create_float_output_channel(uint8_t channel);
void setup() override;
void dump_config() override;
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void loop() override;
protected:
friend SX1509FloatOutputChannel;
std::vector<SX1509FloatOutputChannel *> float_output_channels_{};
void pinMode(uint8_t channel, uint8_t inOut);
void ledDriverInit(uint8_t channel, uint8_t freq = 1, bool log = false);
void clock(uint8_t oscSource = 2, uint8_t oscDivider = 1,
uint8_t oscPinFunction = 0, uint8_t oscFreqOut = 0);
void digitalWrite(uint8_t channel, uint8_t highLow);
void set_channel_value_(uint8_t channel, uint8_t iOn);
// Pin definitions:
uint8_t pinInterrupt_;
uint8_t pinOscillator_;
uint8_t pinReset_;
// variables:
u_long _clkX;
uint8_t frequency_ = 0;
bool update_{true};
byte REG_I_ON[16] = {REG_I_ON_0, REG_I_ON_1, REG_I_ON_2, REG_I_ON_3,
REG_I_ON_4, REG_I_ON_5, REG_I_ON_6, REG_I_ON_7,
REG_I_ON_8, REG_I_ON_9, REG_I_ON_10, REG_I_ON_11,
REG_I_ON_12, REG_I_ON_13, REG_I_ON_14, REG_I_ON_15};
byte REG_T_ON[16] = {REG_T_ON_0, REG_T_ON_1, REG_T_ON_2, REG_T_ON_3,
REG_T_ON_4, REG_T_ON_5, REG_T_ON_6, REG_T_ON_7,
REG_T_ON_8, REG_T_ON_9, REG_T_ON_10, REG_T_ON_11,
REG_T_ON_12, REG_T_ON_13, REG_T_ON_14, REG_T_ON_15};
byte REG_OFF[16] = {REG_OFF_0, REG_OFF_1, REG_OFF_2, REG_OFF_3,
REG_OFF_4, REG_OFF_5, REG_OFF_6, REG_OFF_7,
REG_OFF_8, REG_OFF_9, REG_OFF_10, REG_OFF_11,
REG_OFF_12, REG_OFF_13, REG_OFF_14, REG_OFF_15};
byte REG_T_RISE[16] = {
0xFF, 0xFF, 0xFF, 0xFF,
REG_T_RISE_4, REG_T_RISE_5, REG_T_RISE_6, REG_T_RISE_7,
0xFF, 0xFF, 0xFF, 0xFF,
REG_T_RISE_12, REG_T_RISE_13, REG_T_RISE_14, REG_T_RISE_15};
byte REG_T_FALL[16] = {
0xFF, 0xFF, 0xFF, 0xFF,
REG_T_FALL_4, REG_T_FALL_5, REG_T_FALL_6, REG_T_FALL_7,
0xFF, 0xFF, 0xFF, 0xFF,
REG_T_FALL_12, REG_T_FALL_13, REG_T_FALL_14, REG_T_FALL_15};
};
} // namespace sx1509
} // namespace esphome

View file

@ -0,0 +1,138 @@
/******************************************************************************
sx1509_registers.h
Register definitions for SX1509.
Jim Lindblom @ SparkFun Electronics
Original Creation Date: September 21, 2015
https://github.com/sparkfun/SparkFun_SX1509_Arduino_Library
Here you'll find the Arduino code used to interface with the SX1509 I2C
16 I/O expander. There are functions to take advantage of everything the
SX1509 provides - input/output setting, writing pins high/low, reading
the input value of pins, LED driver utilities (blink, breath, pwm), and
keypad engine utilites.
Development environment specifics:
IDE: Arduino 1.6.5
Hardware Platform: Arduino Uno
SX1509 Breakout Version: v2.0
This code is beerware; if you see me (or any other SparkFun employee) at the
local, and you've found our code helpful, please buy us a round!
Distributed as-is; no warranty is given.
******************************************************************************/
#define REG_INPUT_DISABLE_B 0x00 // RegInputDisableB Input buffer disable register _ I/O[15_8] (Bank B) 0000 0000
#define REG_INPUT_DISABLE_A 0x01 // RegInputDisableA Input buffer disable register _ I/O[7_0] (Bank A) 0000 0000
#define REG_LONG_SLEW_B 0x02 // RegLongSlewB Output buffer long slew register _ I/O[15_8] (Bank B) 0000 0000
#define REG_LONG_SLEW_A 0x03 // RegLongSlewA Output buffer long slew register _ I/O[7_0] (Bank A) 0000 0000
#define REG_LOW_DRIVE_B 0x04 // RegLowDriveB Output buffer low drive register _ I/O[15_8] (Bank B) 0000 0000
#define REG_LOW_DRIVE_A 0x05 // RegLowDriveA Output buffer low drive register _ I/O[7_0] (Bank A) 0000 0000
#define REG_PULL_UP_B 0x06 // RegPullUpB Pull_up register _ I/O[15_8] (Bank B) 0000 0000
#define REG_PULL_UP_A 0x07 // RegPullUpA Pull_up register _ I/O[7_0] (Bank A) 0000 0000
#define REG_PULL_DOWN_B 0x08 // RegPullDownB Pull_down register _ I/O[15_8] (Bank B) 0000 0000
#define REG_PULL_DOWN_A 0x09 // RegPullDownA Pull_down register _ I/O[7_0] (Bank A) 0000 0000
#define REG_OPEN_DRAIN_B 0x0A // RegOpenDrainB Open drain register _ I/O[15_8] (Bank B) 0000 0000
#define REG_OPEN_DRAIN_A 0x0B // RegOpenDrainA Open drain register _ I/O[7_0] (Bank A) 0000 0000
#define REG_POLARITY_B 0x0C // RegPolarityB Polarity register _ I/O[15_8] (Bank B) 0000 0000
#define REG_POLARITY_A 0x0D // RegPolarityA Polarity register _ I/O[7_0] (Bank A) 0000 0000
#define REG_DIR_B 0x0E // RegDirB Direction register _ I/O[15_8] (Bank B) 1111 1111
#define REG_DIR_A 0x0F // RegDirA Direction register _ I/O[7_0] (Bank A) 1111 1111
#define REG_DATA_B 0x10 // RegDataB Data register _ I/O[15_8] (Bank B) 1111 1111*
#define REG_DATA_A 0x11 // RegDataA Data register _ I/O[7_0] (Bank A) 1111 1111*
#define REG_INTERRUPT_MASK_B 0x12 // RegInterruptMaskB Interrupt mask register _ I/O[15_8] (Bank B) 1111 1111
#define REG_INTERRUPT_MASK_A 0x13 // RegInterruptMaskA Interrupt mask register _ I/O[7_0] (Bank A) 1111 1111
#define REG_SENSE_HIGH_B 0x14 // RegSenseHighB Sense register for I/O[15:12] 0000 0000
#define REG_SENSE_LOW_B 0x15 // RegSenseLowB Sense register for I/O[11:8] 0000 0000
#define REG_SENSE_HIGH_A 0x16 // RegSenseHighA Sense register for I/O[7:4] 0000 0000
#define REG_SENSE_LOW_A 0x17 // RegSenseLowA Sense register for I/O[3:0] 0000 0000
#define REG_INTERRUPT_SOURCE_B 0x18 // RegInterruptSourceB Interrupt source register _ I/O[15_8] (Bank B) 0000 0000
#define REG_INTERRUPT_SOURCE_A 0x19 // RegInterruptSourceA Interrupt source register _ I/O[7_0] (Bank A) 0000 0000
#define REG_EVENT_STATUS_B 0x1A // RegEventStatusB Event status register _ I/O[15_8] (Bank B) 0000 0000
#define REG_EVENT_STATUS_A 0x1B // RegEventStatusA Event status register _ I/O[7_0] (Bank A) 0000 0000
#define REG_LEVEL_SHIFTER_1 0x1C // RegLevelShifter1 Level shifter register 0000 0000
#define REG_LEVEL_SHIFTER_2 0x1D // RegLevelShifter2 Level shifter register 0000 0000
#define REG_CLOCK 0x1E // RegClock Clock management register 0000 0000
#define REG_MISC 0x1F // RegMisc Miscellaneous device settings register 0000 0000
#define REG_LED_DRIVER_ENABLE_B 0x20 // RegLEDDriverEnableB LED driver enable register _ I/O[15_8] (Bank B) 0000 0000
#define REG_LED_DRIVER_ENABLE_A 0x21 // RegLEDDriverEnableA LED driver enable register _ I/O[7_0] (Bank A) 0000 0000
// Debounce and Keypad Engine
#define REG_DEBOUNCE_CONFIG 0x22 // RegDebounceConfig Debounce configuration register 0000 0000
#define REG_DEBOUNCE_ENABLE_B 0x23 // RegDebounceEnableB Debounce enable register _ I/O[15_8] (Bank B) 0000 0000
#define REG_DEBOUNCE_ENABLE_A 0x24 // RegDebounceEnableA Debounce enable register _ I/O[7_0] (Bank A) 0000 0000
#define REG_KEY_CONFIG_1 0x25 // RegKeyConfig1 Key scan configuration register 0000 0000
#define REG_KEY_CONFIG_2 0x26 // RegKeyConfig2 Key scan configuration register 0000 0000
#define REG_KEY_DATA_1 0x27 // RegKeyData1 Key value (column) 1111 1111
#define REG_KEY_DATA_2 0x28 // RegKeyData2 Key value (row) 1111 1111
// LED Driver (PWM, blinking, breathing)
#define REG_T_ON_0 0x29 // RegTOn0 ON time register for I/O[0] 0000 0000
#define REG_I_ON_0 0x2A // RegIOn0 ON intensity register for I/O[0] 1111 1111
#define REG_OFF_0 0x2B // RegOff0 OFF time/intensity register for I/O[0] 0000 0000
#define REG_T_ON_1 0x2C // RegTOn1 ON time register for I/O[1] 0000 0000
#define REG_I_ON_1 0x2D // RegIOn1 ON intensity register for I/O[1] 1111 1111
#define REG_OFF_1 0x2E // RegOff1 OFF time/intensity register for I/O[1] 0000 0000
#define REG_T_ON_2 0x2F // RegTOn2 ON time register for I/O[2] 0000 0000
#define REG_I_ON_2 0x30 // RegIOn2 ON intensity register for I/O[2] 1111 1111
#define REG_OFF_2 0x31 // RegOff2 OFF time/intensity register for I/O[2] 0000 0000
#define REG_T_ON_3 0x32 // RegTOn3 ON time register for I/O[3] 0000 0000
#define REG_I_ON_3 0x33 // RegIOn3 ON intensity register for I/O[3] 1111 1111
#define REG_OFF_3 0x34 // RegOff3 OFF time/intensity register for I/O[3] 0000 0000
#define REG_T_ON_4 0x35 // RegTOn4 ON time register for I/O[4] 0000 0000
#define REG_I_ON_4 0x36 // RegIOn4 ON intensity register for I/O[4] 1111 1111
#define REG_OFF_4 0x37 // RegOff4 OFF time/intensity register for I/O[4] 0000 0000
#define REG_T_RISE_4 0x38 // RegTRise4 Fade in register for I/O[4] 0000 0000
#define REG_T_FALL_4 0x39 // RegTFall4 Fade out register for I/O[4] 0000 0000
#define REG_T_ON_5 0x3A // RegTOn5 ON time register for I/O[5] 0000 0000
#define REG_I_ON_5 0x3B // RegIOn5 ON intensity register for I/O[5] 1111 1111
#define REG_OFF_5 0x3C // RegOff5 OFF time/intensity register for I/O[5] 0000 0000
#define REG_T_RISE_5 0x3D // RegTRise5 Fade in register for I/O[5] 0000 0000
#define REG_T_FALL_5 0x3E // RegTFall5 Fade out register for I/O[5] 0000 0000
#define REG_T_ON_6 0x3F // RegTOn6 ON time register for I/O[6] 0000 0000
#define REG_I_ON_6 0x40 // RegIOn6 ON intensity register for I/O[6] 1111 1111
#define REG_OFF_6 0x41 // RegOff6 OFF time/intensity register for I/O[6] 0000 0000
#define REG_T_RISE_6 0x42 // RegTRise6 Fade in register for I/O[6] 0000 0000
#define REG_T_FALL_6 0x43 // RegTFall6 Fade out register for I/O[6] 0000 0000
#define REG_T_ON_7 0x44 // RegTOn7 ON time register for I/O[7] 0000 0000
#define REG_I_ON_7 0x45 // RegIOn7 ON intensity register for I/O[7] 1111 1111
#define REG_OFF_7 0x46 // RegOff7 OFF time/intensity register for I/O[7] 0000 0000
#define REG_T_RISE_7 0x47 // RegTRise7 Fade in register for I/O[7] 0000 0000
#define REG_T_FALL_7 0x48 // RegTFall7 Fade out register for I/O[7] 0000 0000
#define REG_T_ON_8 0x49 // RegTOn8 ON time register for I/O[8] 0000 0000
#define REG_I_ON_8 0x4A // RegIOn8 ON intensity register for I/O[8] 1111 1111
#define REG_OFF_8 0x4B // RegOff8 OFF time/intensity register for I/O[8] 0000 0000
#define REG_T_ON_9 0x4C // RegTOn9 ON time register for I/O[9] 0000 0000
#define REG_I_ON_9 0x4D // RegIOn9 ON intensity register for I/O[9] 1111 1111
#define REG_OFF_9 0x4E // RegOff9 OFF time/intensity register for I/O[9] 0000 0000
#define REG_T_ON_10 0x4F // RegTOn10 ON time register for I/O[10] 0000 0000
#define REG_I_ON_10 0x50 // RegIOn10 ON intensity register for I/O[10] 1111 1111
#define REG_OFF_10 0x51 // RegOff10 OFF time/intensity register for I/O[10] 0000 0000
#define REG_T_ON_11 0x52 // RegTOn11 ON time register for I/O[11] 0000 0000
#define REG_I_ON_11 0x53 // RegIOn11 ON intensity register for I/O[11] 1111 1111
#define REG_OFF_11 0x54 // RegOff11 OFF time/intensity register for I/O[11] 0000 0000
#define REG_T_ON_12 0x55 // RegTOn12 ON time register for I/O[12] 0000 0000
#define REG_I_ON_12 0x56 // RegIOn12 ON intensity register for I/O[12] 1111 1111
#define REG_OFF_12 0x57 // RegOff12 OFF time/intensity register for I/O[12] 0000 0000
#define REG_T_RISE_12 0x58 // RegTRise12 Fade in register for I/O[12] 0000 0000
#define REG_T_FALL_12 0x59 // RegTFall12 Fade out register for I/O[12] 0000 0000
#define REG_T_ON_13 0x5A // RegTOn13 ON time register for I/O[13] 0000 0000
#define REG_I_ON_13 0x5B // RegIOn13 ON intensity register for I/O[13] 1111 1111
#define REG_OFF_13 0x5C // RegOff13 OFF time/intensity register for I/O[13] 0000 0000
#define REG_T_RISE_13 0x5D // RegTRise13 Fade in register for I/O[13] 0000 0000
#define REG_T_FALL_13 0x5E // RegTFall13 Fade out register for I/O[13] 0000 0000
#define REG_T_ON_14 0x5F // RegTOn14 ON time register for I/O[14] 0000 0000
#define REG_I_ON_14 0x60 // RegIOn14 ON intensity register for I/O[14] 1111 1111
#define REG_OFF_14 0x61 // RegOff14 OFF time/intensity register for I/O[14] 0000 0000
#define REG_T_RISE_14 0x62 // RegTRise14 Fade in register for I/O[14] 0000 0000
#define REG_T_FALL_14 0x63 // RegTFall14 Fade out register for I/O[14] 0000 0000
#define REG_T_ON_15 0x64 // RegTOn15 ON time register for I/O[15] 0000 0000
#define REG_I_ON_15 0x65 // RegIOn15 ON intensity register for I/O[15] 1111 1111
#define REG_OFF_15 0x66 // RegOff15 OFF time/intensity register for I/O[15] 0000 0000
#define REG_T_RISE_15 0x67 // RegTRise15 Fade in register for I/O[15] 0000 0000
#define REG_T_FALL_15 0x68 // RegTFall15 Fade out register for I/O[15] 0000 0000
// Miscellaneous
#define REG_HIGH_INPUT_B 0x69 // RegHighInputB High input enable register _ I/O[15_8] (Bank B) 0000 0000
#define REG_HIGH_INPUT_A 0x6A // RegHighInputA High input enable register _ I/O[7_0] (Bank A) 0000 0000
// Software Reset
#define REG_RESET 0x7D // RegReset Software reset register 0000 0000
#define REG_TEST_1 0x7E // RegTest1 Test register 0000 0000
#define REG_TEST_2 0x7F // RegTest2 Test register 0000 0000