Update housing and code
--add local timezone --add sunrise/sunset calculation and LED illumination accordingly --remove touch sensor check --change mqtt messages
This commit is contained in:
1 parent
6435550e29
commit
379b4887c3
47 files changed
+26343
-2850
No files matched your search
@@ -0,0 +1,860 @@
|
||||
/******************************************************************************
|
||||
SparkFunSX1509.cpp
|
||||
SparkFun SX1509 I/O Expander Library Source File
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
#include "Arduino.h"
|
||||
#include "SparkFunSX1509.h"
|
||||
#include "util/sx1509_registers.h"
|
||||
|
||||
SX1509::SX1509()
|
||||
{
|
||||
_clkX = 0;
|
||||
}
|
||||
|
||||
SX1509::SX1509(uint8_t address, uint8_t resetPin, uint8_t interruptPin, uint8_t oscillatorPin)
|
||||
{
|
||||
// Store the received parameters into member variables
|
||||
deviceAddress = address;
|
||||
pinInterrupt = interruptPin;
|
||||
pinOscillator = oscillatorPin;
|
||||
pinReset = resetPin;
|
||||
}
|
||||
|
||||
uint8_t SX1509::begin(uint8_t address, TwoWire &wirePort, uint8_t resetPin)
|
||||
{
|
||||
// Store the received parameters into member variables
|
||||
_i2cPort = &wirePort;
|
||||
deviceAddress = address;
|
||||
pinReset = resetPin;
|
||||
|
||||
return init();
|
||||
}
|
||||
|
||||
uint8_t SX1509::init(void)
|
||||
{
|
||||
// Begin I2C should be done externally, before beginning SX1509
|
||||
//Wire.begin();
|
||||
|
||||
// If the reset pin is connected
|
||||
if (pinReset != 255)
|
||||
reset(1);
|
||||
else
|
||||
reset(0);
|
||||
|
||||
// Communication test. We'll read from two registers with different
|
||||
// default values to verify communication.
|
||||
uint16_t testRegisters = 0;
|
||||
testRegisters = readWord(REG_INTERRUPT_MASK_A); // This should return 0xFF00
|
||||
|
||||
// Then read a byte that should be 0x00
|
||||
if (testRegisters == 0xFF00)
|
||||
{
|
||||
// Set the clock to a default of 2MHz using internal
|
||||
clock(INTERNAL_CLOCK_2MHZ);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SX1509::reset(bool hardware)
|
||||
{
|
||||
// if hardware bool is set
|
||||
if (hardware)
|
||||
{
|
||||
// Check if bit 2 of REG_MISC is set
|
||||
// if so nReset will not issue a POR, we'll need to clear that bit first
|
||||
uint8_t regMisc = readByte(REG_MISC);
|
||||
if (regMisc & (1 << 2))
|
||||
{
|
||||
regMisc &= ~(1 << 2);
|
||||
writeByte(REG_MISC, regMisc);
|
||||
}
|
||||
// Reset the SX1509, the pin is active low
|
||||
::pinMode(pinReset, OUTPUT); // set reset pin as output
|
||||
::digitalWrite(pinReset, LOW); // pull reset pin low
|
||||
delay(1); // Wait for the pin to settle
|
||||
::digitalWrite(pinReset, HIGH); // pull reset pin back high
|
||||
}
|
||||
else
|
||||
{
|
||||
// Software reset command sequence:
|
||||
writeByte(REG_RESET, 0x12);
|
||||
writeByte(REG_RESET, 0x34);
|
||||
}
|
||||
}
|
||||
|
||||
void SX1509::pinDir(uint8_t pin, uint8_t inOut, uint8_t initialLevel)
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
uint16_t tempRegData = readWord(REG_DATA_B);
|
||||
if (initialLevel == LOW)
|
||||
{
|
||||
tempRegData &= ~(1 << pin);
|
||||
writeWord(REG_DATA_B, tempRegData);
|
||||
}
|
||||
modeBit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
modeBit = 1;
|
||||
}
|
||||
|
||||
uint16_t tempRegDir = readWord(REG_DIR_B);
|
||||
if (modeBit)
|
||||
tempRegDir |= (1 << pin);
|
||||
else
|
||||
tempRegDir &= ~(1 << pin);
|
||||
|
||||
writeWord(REG_DIR_B, tempRegDir);
|
||||
|
||||
// If INPUT_PULLUP was called, set up the pullup too:
|
||||
if (inOut == INPUT_PULLUP)
|
||||
writePin(pin, HIGH);
|
||||
|
||||
if (inOut == ANALOG_OUTPUT)
|
||||
{
|
||||
ledDriverInit(pin);
|
||||
}
|
||||
}
|
||||
|
||||
void SX1509::pinMode(uint8_t pin, uint8_t inOut, uint8_t initialLevel)
|
||||
{
|
||||
pinDir(pin, inOut, initialLevel);
|
||||
}
|
||||
|
||||
bool SX1509::writePin(uint8_t pin, uint8_t highLow)
|
||||
{
|
||||
|
||||
uint16_t tempRegDir = readWord(REG_DIR_B);
|
||||
|
||||
if ((0xFFFF ^ tempRegDir) & (1 << pin)) // If the pin is an output, write high/low
|
||||
{
|
||||
uint16_t tempRegData = readWord(REG_DATA_B);
|
||||
if (highLow)
|
||||
tempRegData |= (1 << pin);
|
||||
else
|
||||
tempRegData &= ~(1 << pin);
|
||||
return writeWord(REG_DATA_B, tempRegData);
|
||||
}
|
||||
else // Otherwise the pin is an input, pull-up/down
|
||||
{
|
||||
uint16_t tempPullUp = readWord(REG_PULL_UP_B);
|
||||
uint16_t tempPullDown = readWord(REG_PULL_DOWN_B);
|
||||
|
||||
if (highLow) // if HIGH, do pull-up, disable pull-down
|
||||
{
|
||||
tempPullUp |= (1 << pin);
|
||||
tempPullDown &= ~(1 << pin);
|
||||
return writeWord(REG_PULL_UP_B, tempPullUp) && writeWord(REG_PULL_DOWN_B, tempPullDown);
|
||||
}
|
||||
else // If LOW do pull-down, disable pull-up
|
||||
{
|
||||
tempPullDown |= (1 << pin);
|
||||
tempPullUp &= ~(1 << pin);
|
||||
return writeWord(REG_PULL_UP_B, tempPullUp) && writeWord(REG_PULL_DOWN_B, tempPullDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SX1509::digitalWrite(uint8_t pin, uint8_t highLow)
|
||||
{
|
||||
return writePin(pin, highLow);
|
||||
}
|
||||
|
||||
uint8_t SX1509::readPin(uint8_t pin)
|
||||
{
|
||||
uint16_t tempRegDir = readWord(REG_DIR_B);
|
||||
|
||||
if (tempRegDir & (1 << pin)) // If the pin is an input
|
||||
{
|
||||
uint16_t tempRegData = readWord(REG_DATA_B);
|
||||
if (tempRegData & (1 << pin))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// log_d("Pin %d not INPUT, REG_DIR_B: %d", pin, tempRegDir);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SX1509::readPin(const uint8_t pin, bool *value)
|
||||
{
|
||||
uint16_t tempRegDir;
|
||||
if (readWord(REG_DIR_B, &tempRegDir))
|
||||
{
|
||||
if (tempRegDir & (1 << pin))
|
||||
{ // If the pin is an input
|
||||
uint16_t tempRegData;
|
||||
if (readWord(REG_DATA_B, &tempRegData))
|
||||
{
|
||||
*value = (tempRegData & (1 << pin)) != 0;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
*value = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t SX1509::digitalRead(uint8_t pin)
|
||||
{
|
||||
return readPin(pin);
|
||||
}
|
||||
|
||||
bool SX1509::digitalRead(uint8_t pin, bool *value)
|
||||
{
|
||||
return readPin(pin, value);
|
||||
}
|
||||
|
||||
void SX1509::ledDriverInit(uint8_t pin, uint8_t freq /*= 1*/, bool log /*= false*/)
|
||||
{
|
||||
uint16_t tempWord;
|
||||
uint8_t tempByte;
|
||||
|
||||
// Disable input buffer
|
||||
// Writing a 1 to the pin bit will disable that pins input buffer
|
||||
tempWord = readWord(REG_INPUT_DISABLE_B);
|
||||
tempWord |= (1 << pin);
|
||||
writeWord(REG_INPUT_DISABLE_B, tempWord);
|
||||
|
||||
// Disable pull-up
|
||||
// Writing a 0 to the pin bit will disable that pull-up resistor
|
||||
tempWord = readWord(REG_PULL_UP_B);
|
||||
tempWord &= ~(1 << pin);
|
||||
writeWord(REG_PULL_UP_B, tempWord);
|
||||
|
||||
// Set direction to output (REG_DIR_B)
|
||||
tempWord = readWord(REG_DIR_B);
|
||||
tempWord &= ~(1 << pin); // 0=output
|
||||
writeWord(REG_DIR_B, tempWord);
|
||||
|
||||
// Enable oscillator (REG_CLOCK)
|
||||
tempByte = readByte(REG_CLOCK);
|
||||
tempByte |= (1 << 6); // Internal 2MHz oscillator part 1 (set bit 6)
|
||||
tempByte &= ~(1 << 5); // Internal 2MHz oscillator part 2 (clear bit 5)
|
||||
writeByte(REG_CLOCK, tempByte);
|
||||
|
||||
// Configure LED driver clock and mode (REG_MISC)
|
||||
tempByte = readByte(REG_MISC);
|
||||
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
|
||||
_clkX = 2000000.0;
|
||||
|
||||
// uint8_t freq = (1 & 0x07) << 4; // freq should only be 3 bits from 6:4
|
||||
// tempByte |= freq;
|
||||
}
|
||||
|
||||
freq = (freq & 0x7) << 4; // mask only 3 bits and shift to bit position 6:4
|
||||
tempByte |= freq;
|
||||
|
||||
writeByte(REG_MISC, tempByte);
|
||||
|
||||
// Enable LED driver operation (REG_LED_DRIVER_ENABLE)
|
||||
tempWord = readWord(REG_LED_DRIVER_ENABLE_B);
|
||||
tempWord |= (1 << pin);
|
||||
writeWord(REG_LED_DRIVER_ENABLE_B, tempWord);
|
||||
|
||||
// Set REG_DATA bit low ~ LED driver started
|
||||
tempWord = readWord(REG_DATA_B);
|
||||
tempWord &= ~(1 << pin);
|
||||
writeWord(REG_DATA_B, tempWord);
|
||||
}
|
||||
|
||||
void SX1509::pwm(uint8_t pin, uint8_t iOn)
|
||||
{
|
||||
// Write the on intensity of pin
|
||||
// Linear mode: Ion = iOn
|
||||
// Log mode: Ion = f(iOn)
|
||||
writeByte(REG_I_ON[pin], iOn);
|
||||
}
|
||||
|
||||
void SX1509::analogWrite(uint8_t pin, uint8_t iOn)
|
||||
{
|
||||
pwm(pin, iOn);
|
||||
}
|
||||
|
||||
void SX1509::blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity, uint8_t offIntensity)
|
||||
{
|
||||
uint8_t onReg = calculateLEDTRegister(tOn);
|
||||
uint8_t offReg = calculateLEDTRegister(tOff);
|
||||
|
||||
setupBlink(pin, onReg, offReg, onIntensity, offIntensity, 0, 0);
|
||||
}
|
||||
|
||||
void SX1509::breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, uint8_t onInt, uint8_t offInt, bool log)
|
||||
{
|
||||
offInt = constrain(offInt, 0, 7);
|
||||
|
||||
uint8_t onReg = calculateLEDTRegister(tOn);
|
||||
uint8_t offReg = calculateLEDTRegister(tOff);
|
||||
|
||||
uint8_t riseTime = calculateSlopeRegister(rise, onInt, offInt);
|
||||
uint8_t fallTime = calculateSlopeRegister(fall, onInt, offInt);
|
||||
|
||||
setupBlink(pin, onReg, offReg, onInt, offInt, riseTime, fallTime, log);
|
||||
}
|
||||
|
||||
void SX1509::setupBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t onIntensity, uint8_t offIntensity, uint8_t tRise, uint8_t tFall, bool log)
|
||||
{
|
||||
ledDriverInit(pin, log);
|
||||
|
||||
// Keep parameters within their limits:
|
||||
tOn &= 0x1F; // tOn should be a 5-bit value
|
||||
tOff &= 0x1F; // tOff should be a 5-bit value
|
||||
offIntensity &= 0x07;
|
||||
// Write the time on
|
||||
// 1-15: TON = 64 * tOn * (255/ClkX)
|
||||
// 16-31: TON = 512 * tOn * (255/ClkX)
|
||||
writeByte(REG_T_ON[pin], tOn);
|
||||
|
||||
// Write the time/intensity off register
|
||||
// 1-15: TOFF = 64 * tOff * (255/ClkX)
|
||||
// 16-31: TOFF = 512 * tOff * (255/ClkX)
|
||||
// linear Mode - IOff = 4 * offIntensity
|
||||
// log mode - Ioff = f(4 * offIntensity)
|
||||
writeByte(REG_OFF[pin], (tOff << 3) | offIntensity);
|
||||
|
||||
// Write the on intensity:
|
||||
writeByte(REG_I_ON[pin], onIntensity);
|
||||
|
||||
// Prepare tRise and tFall
|
||||
tRise &= 0x1F; // tRise is a 5-bit value
|
||||
tFall &= 0x1F; // tFall is a 5-bit value
|
||||
|
||||
// Write regTRise
|
||||
// 0: Off
|
||||
// 1-15: TRise = (regIOn - (4 * offIntensity)) * tRise * (255/ClkX)
|
||||
// 16-31: TRise = 16 * (regIOn - (4 * offIntensity)) * tRise * (255/ClkX)
|
||||
if (REG_T_RISE[pin] != 0xFF)
|
||||
writeByte(REG_T_RISE[pin], tRise);
|
||||
// Write regTFall
|
||||
// 0: off
|
||||
// 1-15: TFall = (regIOn - (4 * offIntensity)) * tFall * (255/ClkX)
|
||||
// 16-31: TFall = 16 * (regIOn - (4 * offIntensity)) * tFall * (255/ClkX)
|
||||
if (REG_T_FALL[pin] != 0xFF)
|
||||
writeByte(REG_T_FALL[pin], tFall);
|
||||
}
|
||||
|
||||
void SX1509::keypad(uint8_t rows, uint8_t columns, uint16_t sleepTime, uint8_t scanTime, uint8_t debounceTime)
|
||||
{
|
||||
uint16_t tempWord;
|
||||
uint8_t tempByte;
|
||||
|
||||
// If clock hasn't been set up, set it to internal 2MHz
|
||||
if (_clkX == 0)
|
||||
clock(INTERNAL_CLOCK_2MHZ);
|
||||
|
||||
// Set regDir 0:7 outputs, 8:15 inputs:
|
||||
tempWord = readWord(REG_DIR_B);
|
||||
for (uint8_t i = 0; i < rows; i++)
|
||||
tempWord &= ~(1 << i);
|
||||
for (uint8_t i = 8; i < (columns * 2); i++)
|
||||
tempWord |= (1 << i);
|
||||
writeWord(REG_DIR_B, tempWord);
|
||||
|
||||
// Set regOpenDrain on 0:7:
|
||||
tempByte = readByte(REG_OPEN_DRAIN_A);
|
||||
for (uint8_t i = 0; i < rows; i++)
|
||||
tempByte |= (1 << i);
|
||||
writeByte(REG_OPEN_DRAIN_A, tempByte);
|
||||
|
||||
// Set regPullUp on 8:15:
|
||||
tempByte = readByte(REG_PULL_UP_B);
|
||||
for (uint8_t i = 0; i < columns; i++)
|
||||
tempByte |= (1 << i);
|
||||
writeByte(REG_PULL_UP_B, tempByte);
|
||||
|
||||
// Debounce Time must be less than scan time
|
||||
debounceTime = constrain(debounceTime, 1, 64);
|
||||
scanTime = constrain(scanTime, 1, 128);
|
||||
if (debounceTime >= scanTime)
|
||||
{
|
||||
debounceTime = scanTime >> 1; // Force debounceTime to be less than scanTime
|
||||
}
|
||||
debounceKeypad(debounceTime, rows, columns);
|
||||
|
||||
// Calculate scanTimeBits, based on scanTime
|
||||
uint8_t scanTimeBits = 0;
|
||||
for (uint8_t i = 7; i > 0; i--)
|
||||
{
|
||||
if (scanTime & (1 << i))
|
||||
{
|
||||
scanTimeBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate sleepTimeBits, based on sleepTime
|
||||
uint8_t sleepTimeBits = 0;
|
||||
if (sleepTime != 0)
|
||||
{
|
||||
for (uint8_t i = 7; i > 0; i--)
|
||||
{
|
||||
if (sleepTime & ((uint16_t)1 << (i + 6)))
|
||||
{
|
||||
sleepTimeBits = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If sleepTime was non-zero, but less than 128,
|
||||
// assume we wanted to turn sleep on, set it to minimum:
|
||||
if (sleepTimeBits == 0)
|
||||
sleepTimeBits = 1;
|
||||
}
|
||||
|
||||
// RegKeyConfig1 sets the auto sleep time and scan time per row
|
||||
sleepTimeBits = (sleepTimeBits & 0b111) << 4;
|
||||
scanTimeBits &= 0b111; // Scan time is bits 2:0
|
||||
tempByte = sleepTime | scanTimeBits;
|
||||
writeByte(REG_KEY_CONFIG_1, tempByte);
|
||||
|
||||
// RegKeyConfig2 tells the SX1509 how many rows and columns we've got going
|
||||
rows = (rows - 1) & 0b111; // 0 = off, 0b001 = 2 rows, 0b111 = 8 rows, etc.
|
||||
columns = (columns - 1) & 0b111; // 0b000 = 1 column, ob111 = 8 columns, etc.
|
||||
writeByte(REG_KEY_CONFIG_2, (rows << 3) | columns);
|
||||
}
|
||||
|
||||
uint16_t SX1509::readKeypad()
|
||||
{
|
||||
return readKeyData();
|
||||
}
|
||||
|
||||
uint16_t SX1509::readKeyData()
|
||||
{
|
||||
return (0xFFFF ^ readWord(REG_KEY_DATA_1));
|
||||
}
|
||||
|
||||
uint8_t SX1509::getRow(uint16_t keyData)
|
||||
{
|
||||
uint8_t rowData = uint8_t(keyData & 0x00FF);
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (rowData & (1 << i))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SX1509::getCol(uint16_t keyData)
|
||||
{
|
||||
uint8_t colData = uint8_t((keyData & 0xFF00) >> 8);
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (colData & (1 << i))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SX1509::sync(void)
|
||||
{
|
||||
// First check if nReset functionality is set
|
||||
uint8_t regMisc = readByte(REG_MISC);
|
||||
if (!(regMisc & 0x04))
|
||||
{
|
||||
regMisc |= (1 << 2);
|
||||
writeByte(REG_MISC, regMisc);
|
||||
}
|
||||
|
||||
// Toggle nReset pin to sync LED timers
|
||||
::pinMode(pinReset, OUTPUT); // set reset pin as output
|
||||
::digitalWrite(pinReset, LOW); // pull reset pin low
|
||||
delay(1); // Wait for the pin to settle
|
||||
::digitalWrite(pinReset, HIGH); // pull reset pin back high
|
||||
|
||||
// Return nReset to POR functionality
|
||||
writeByte(REG_MISC, (regMisc & ~(1 << 2)));
|
||||
}
|
||||
|
||||
void SX1509::debounceConfig(uint8_t configValue)
|
||||
{
|
||||
// First make sure clock is configured
|
||||
uint8_t tempByte = readByte(REG_MISC);
|
||||
if ((tempByte & 0x70) == 0)
|
||||
{
|
||||
tempByte |= (1 << 4); // Just default to no divider if not set
|
||||
writeByte(REG_MISC, tempByte);
|
||||
}
|
||||
tempByte = readByte(REG_CLOCK);
|
||||
if ((tempByte & 0x60) == 0)
|
||||
{
|
||||
tempByte |= (1 << 6); // default to internal osc.
|
||||
writeByte(REG_CLOCK, tempByte);
|
||||
}
|
||||
|
||||
configValue &= 0b111; // 3-bit value
|
||||
writeByte(REG_DEBOUNCE_CONFIG, configValue);
|
||||
}
|
||||
|
||||
void SX1509::debounceTime(uint8_t time)
|
||||
{
|
||||
if (_clkX == 0) // If clock hasn't been set up.
|
||||
clock(INTERNAL_CLOCK_2MHZ, 1); // Set clock to 2MHz.
|
||||
|
||||
// Debounce time-to-byte map: (assuming fOsc = 2MHz)
|
||||
// 0: 0.5ms 1: 1ms
|
||||
// 2: 2ms 3: 4ms
|
||||
// 4: 8ms 5: 16ms
|
||||
// 6: 32ms 7: 64ms
|
||||
// 2^(n-1)
|
||||
uint8_t configValue = 0;
|
||||
// We'll check for the highest set bit position,
|
||||
// and use that for debounceConfig
|
||||
for (int8_t i = 7; i >= 0; i--)
|
||||
{
|
||||
if (time & (1 << i))
|
||||
{
|
||||
configValue = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
configValue = constrain(configValue, 0, 7);
|
||||
|
||||
debounceConfig(configValue);
|
||||
}
|
||||
|
||||
void SX1509::debounceEnable(uint8_t pin)
|
||||
{
|
||||
uint16_t debounceEnable = readWord(REG_DEBOUNCE_ENABLE_B);
|
||||
debounceEnable |= (1 << pin);
|
||||
writeWord(REG_DEBOUNCE_ENABLE_B, debounceEnable);
|
||||
}
|
||||
|
||||
void SX1509::debouncePin(uint8_t pin)
|
||||
{
|
||||
debounceEnable(pin);
|
||||
}
|
||||
|
||||
void SX1509::debounceKeypad(uint8_t time, uint8_t numRows, uint8_t numCols)
|
||||
{
|
||||
// Set up debounce time:
|
||||
debounceTime(time);
|
||||
|
||||
// Set up debounce pins:
|
||||
for (uint8_t i = 0; i < numRows; i++)
|
||||
debouncePin(i);
|
||||
for (uint8_t i = 0; i < (8 + numCols); i++)
|
||||
debouncePin(i);
|
||||
}
|
||||
|
||||
void SX1509::enableInterrupt(uint8_t pin, uint8_t riseFall)
|
||||
{
|
||||
// Set REG_INTERRUPT_MASK
|
||||
uint16_t tempWord = readWord(REG_INTERRUPT_MASK_B);
|
||||
tempWord &= ~(1 << pin); // 0 = event on IO will trigger interrupt
|
||||
writeWord(REG_INTERRUPT_MASK_B, tempWord);
|
||||
|
||||
uint8_t sensitivity = 0;
|
||||
switch (riseFall)
|
||||
{
|
||||
case CHANGE:
|
||||
sensitivity = 0b11;
|
||||
break;
|
||||
case FALLING:
|
||||
sensitivity = 0b10;
|
||||
break;
|
||||
case RISING:
|
||||
sensitivity = 0b01;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set REG_SENSE_XXX
|
||||
// Sensitivity is set as follows:
|
||||
// 00: None
|
||||
// 01: Rising
|
||||
// 10: Falling
|
||||
// 11: Both
|
||||
uint8_t pinMask = (pin & 0x07) * 2;
|
||||
uint8_t senseRegister;
|
||||
|
||||
// Need to select between two words. One for bank A, one for B.
|
||||
if (pin >= 8)
|
||||
senseRegister = REG_SENSE_HIGH_B;
|
||||
else
|
||||
senseRegister = REG_SENSE_HIGH_A;
|
||||
|
||||
tempWord = readWord(senseRegister);
|
||||
tempWord &= ~(0b11 << pinMask); // Mask out the bits we want to write
|
||||
tempWord |= (sensitivity << pinMask); // Add our new bits
|
||||
writeWord(senseRegister, tempWord);
|
||||
}
|
||||
|
||||
uint16_t SX1509::interruptSource(bool clear /* =true*/)
|
||||
{
|
||||
uint16_t intSource = readWord(REG_INTERRUPT_SOURCE_B);
|
||||
if (clear)
|
||||
writeWord(REG_INTERRUPT_SOURCE_B, 0xFFFF); // Clear interrupts
|
||||
return intSource;
|
||||
}
|
||||
|
||||
bool SX1509::checkInterrupt(uint8_t pin)
|
||||
{
|
||||
if (interruptSource(false) & (1 << pin))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SX1509::clock(uint8_t oscSource, uint8_t oscDivider, uint8_t oscPinFunction, uint8_t oscFreqOut)
|
||||
{
|
||||
configClock(oscSource, oscPinFunction, oscFreqOut, oscDivider);
|
||||
}
|
||||
|
||||
void SX1509::configClock(uint8_t oscSource /*= 2*/, uint8_t oscPinFunction /*= 0*/, uint8_t oscFreqOut /*= 0*/, uint8_t oscDivider /*= 1*/)
|
||||
{
|
||||
// RegClock constructed as follows:
|
||||
// 6:5 - Oscillator frequency souce
|
||||
// 00: off, 01: external input, 10: internal 2MHz, 1: reserved
|
||||
// 4 - OSCIO pin function
|
||||
// 0: input, 1 ouptut
|
||||
// 3:0 - Frequency of oscout pin
|
||||
// 0: LOW, 0xF: high, else fOSCOUT = FoSC/(2^(RegClock[3:0]-1))
|
||||
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
|
||||
uint8_t regClock = oscSource | oscPinFunction | oscFreqOut;
|
||||
writeByte(REG_CLOCK, regClock);
|
||||
|
||||
// Config RegMisc[6:4] with oscDivider
|
||||
// 0: off, else ClkX = fOSC / (2^(RegMisc[6:4] -1))
|
||||
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 = readByte(REG_MISC);
|
||||
regMisc &= ~(0b111 << 4);
|
||||
regMisc |= oscDivider;
|
||||
writeByte(REG_MISC, regMisc);
|
||||
}
|
||||
|
||||
uint8_t SX1509::calculateLEDTRegister(unsigned long ms)
|
||||
{
|
||||
uint8_t regOn1, regOn2;
|
||||
float timeOn1, timeOn2;
|
||||
|
||||
if (_clkX == 0)
|
||||
return 0;
|
||||
|
||||
regOn1 = (float)(ms / 1000.0) / (64.0 * 255.0 / (float)_clkX);
|
||||
regOn2 = regOn1 / 8;
|
||||
regOn1 = constrain(regOn1, 1, 15);
|
||||
regOn2 = constrain(regOn2, 16, 31);
|
||||
|
||||
timeOn1 = 64.0 * regOn1 * 255.0 / _clkX * 1000.0;
|
||||
timeOn2 = 512.0 * regOn2 * 255.0 / _clkX * 1000.0;
|
||||
|
||||
if (abs(timeOn1 - ms) < abs(timeOn2 - ms))
|
||||
return regOn1;
|
||||
else
|
||||
return regOn2;
|
||||
}
|
||||
|
||||
uint8_t SX1509::calculateSlopeRegister(unsigned long ms, uint8_t onIntensity, uint8_t offIntensity)
|
||||
{
|
||||
uint16_t regSlope1, regSlope2;
|
||||
float regTime1, regTime2;
|
||||
|
||||
if (_clkX == 0)
|
||||
return 0;
|
||||
|
||||
float tFactor = ((float)onIntensity - (4.0 * (float)offIntensity)) * 255.0 / (float)_clkX;
|
||||
float timeS = float(ms) / 1000.0;
|
||||
|
||||
regSlope1 = timeS / tFactor;
|
||||
regSlope2 = regSlope1 / 16;
|
||||
|
||||
regSlope1 = constrain(regSlope1, 1, 15);
|
||||
regSlope2 = constrain(regSlope2, 16, 31);
|
||||
|
||||
regTime1 = regSlope1 * tFactor * 1000.0;
|
||||
regTime2 = 16 * regTime1;
|
||||
|
||||
if (abs(regTime1 - ms) < abs(regTime2 - ms))
|
||||
return regSlope1;
|
||||
else
|
||||
return regSlope2;
|
||||
}
|
||||
|
||||
// readByte(uint8_t registerAddress)
|
||||
// This function reads a single byte located at the registerAddress register.
|
||||
// - deviceAddress should already be set by the constructor.
|
||||
// - Return value is the byte read from registerAddress
|
||||
// - Currently returns 0 if communication has timed out
|
||||
uint8_t SX1509::readByte(uint8_t registerAddress)
|
||||
{
|
||||
uint8_t readValue;
|
||||
// Commented the line as variable seems unused;
|
||||
//uint16_t timeout = RECEIVE_TIMEOUT_VALUE;
|
||||
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
_i2cPort->write(registerAddress);
|
||||
_i2cPort->endTransmission();
|
||||
_i2cPort->requestFrom(deviceAddress, (uint8_t)1);
|
||||
|
||||
readValue = _i2cPort->read();
|
||||
|
||||
return readValue;
|
||||
}
|
||||
|
||||
// readWord(uint8_t registerAddress)
|
||||
// This function will read a two-byte word beginning at registerAddress
|
||||
// - A 16-bit uint16_t will be returned.
|
||||
// - The msb of the return value will contain the value read from registerAddress
|
||||
// - The lsb of the return value will contain the value read from registerAddress + 1
|
||||
uint16_t SX1509::readWord(uint8_t registerAddress)
|
||||
{
|
||||
uint16_t readValue;
|
||||
uint16_t msb, lsb;
|
||||
// Commented the line as variable seems unused;
|
||||
//uint16_t timeout = RECEIVE_TIMEOUT_VALUE * 2;
|
||||
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
_i2cPort->write(registerAddress);
|
||||
_i2cPort->endTransmission();
|
||||
_i2cPort->requestFrom(deviceAddress, (uint8_t)2);
|
||||
|
||||
msb = (_i2cPort->read() & 0x00FF) << 8;
|
||||
lsb = (_i2cPort->read() & 0x00FF);
|
||||
readValue = msb | lsb;
|
||||
|
||||
return readValue;
|
||||
}
|
||||
|
||||
bool SX1509::readByte(uint8_t registerAddress, uint8_t *value)
|
||||
{
|
||||
return readBytes(registerAddress, value, 1);
|
||||
}
|
||||
|
||||
// readWord(uint8_t registerAddress)
|
||||
// This function will read a two-byte word beginning at registerAddress
|
||||
// - A 16-bit uint16_t will be set in value.
|
||||
// - The msb of the return value will contain the value read from registerAddress
|
||||
// - The lsb of the return value will contain the value read from registerAddress + 1
|
||||
// - Return boolean true if succesfull
|
||||
bool SX1509::readWord(uint8_t registerAddress, uint16_t *value)
|
||||
{
|
||||
uint8_t dest[2];
|
||||
if (readBytes(registerAddress, dest, 2))
|
||||
{
|
||||
*value = dest[1] | dest[0] << 8;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// readBytes(uint8_t firstRegisterAddress, uint8_t * destination, uint8_t length)
|
||||
// This function reads a series of bytes incrementing from a given address
|
||||
// - firstRegisterAddress is the first address to be read
|
||||
// - destination is an array of bytes where the read values will be stored into
|
||||
// - length is the number of bytes to be read
|
||||
// - Return boolean true if succesfull
|
||||
bool SX1509::readBytes(uint8_t firstRegisterAddress, uint8_t *destination, uint8_t length)
|
||||
{
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
_i2cPort->write(firstRegisterAddress);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
bool result = (endResult == I2C_ERROR_OK) && (_i2cPort->requestFrom(deviceAddress, length) == length);
|
||||
|
||||
if (result)
|
||||
{
|
||||
for (uint8_t i = 0; i < length; i++)
|
||||
{
|
||||
destination[i] = _i2cPort->read();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// writeByte(uint8_t registerAddress, uint8_t writeValue)
|
||||
// This function writes a single byte to a single register on the SX509.
|
||||
// - writeValue is written to registerAddress
|
||||
// - deviceAddres should already be set from the constructor
|
||||
// - Return value: true if succeeded, false if failed
|
||||
bool SX1509::writeByte(uint8_t registerAddress, uint8_t writeValue)
|
||||
{
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
bool result = _i2cPort->write(registerAddress) && _i2cPort->write(writeValue);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
return result && (endResult == I2C_ERROR_OK);
|
||||
}
|
||||
|
||||
// writeWord(uint8_t registerAddress, uint16_t writeValue)
|
||||
// This function writes a two-byte word to registerAddress and registerAddress + 1
|
||||
// - the upper byte of writeValue is written to registerAddress
|
||||
// - the lower byte of writeValue is written to registerAddress + 1
|
||||
// - Return value: true if succeeded, false if failed
|
||||
bool SX1509::writeWord(uint8_t registerAddress, uint16_t writeValue)
|
||||
{
|
||||
uint8_t msb, lsb;
|
||||
msb = ((writeValue & 0xFF00) >> 8);
|
||||
lsb = (writeValue & 0x00FF);
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
bool result = _i2cPort->write(registerAddress) && _i2cPort->write(msb) && _i2cPort->write(lsb);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
return result && (endResult == I2C_ERROR_OK);
|
||||
}
|
||||
|
||||
// writeBytes(uint8_t firstRegisterAddress, uint8_t * writeArray, uint8_t length)
|
||||
// This function writes an array of bytes, beggining at a specific adddress
|
||||
// - firstRegisterAddress is the initial register to be written.
|
||||
// - All writes following will be at incremental register addresses.
|
||||
// - writeArray should be an array of byte values to be written.
|
||||
// - length should be the number of bytes to be written.
|
||||
// - Return value: true if succeeded, false if failed
|
||||
bool SX1509::writeBytes(uint8_t firstRegisterAddress, uint8_t *writeArray, uint8_t length)
|
||||
{
|
||||
_i2cPort->beginTransmission(deviceAddress);
|
||||
bool result = _i2cPort->write(firstRegisterAddress);
|
||||
result = _i2cPort->write(writeArray, length);
|
||||
uint8_t endResult = _i2cPort->endTransmission();
|
||||
return result && (endResult == I2C_ERROR_OK);
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
/******************************************************************************
|
||||
SparkFunSX1509.h
|
||||
SparkFun SX1509 I/O Expander Library Header File
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifndef SparkFunSX1509_H
|
||||
#define SparkFunSX1509_H
|
||||
|
||||
#ifndef I2C_ERROR_OK
|
||||
#define I2C_ERROR_OK 0
|
||||
#endif
|
||||
|
||||
#define RECEIVE_TIMEOUT_VALUE 1000 // Timeout for I2C receive
|
||||
|
||||
// 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 SX1509
|
||||
{
|
||||
private: // These private functions are not available to Arduino sketches.
|
||||
// If you need to read or write directly to registers, consider
|
||||
// putting the writeByte, readByte functions in the public section
|
||||
TwoWire *_i2cPort;
|
||||
uint8_t deviceAddress; // I2C Address of SX1509
|
||||
// Pin definitions:
|
||||
uint8_t pinInterrupt;
|
||||
uint8_t pinOscillator;
|
||||
uint8_t pinReset;
|
||||
// Misc variables:
|
||||
unsigned long _clkX;
|
||||
// Read Functions:
|
||||
uint8_t readByte(uint8_t registerAddress);
|
||||
uint16_t readWord(uint8_t registerAddress);
|
||||
|
||||
// Read Functions returning success or failure:
|
||||
bool readBytes(uint8_t firstRegisterAddress, uint8_t *destination, uint8_t length);
|
||||
|
||||
bool readByte(uint8_t registerAddress, uint8_t *value);
|
||||
bool readWord(uint8_t registerAddress, uint16_t *value);
|
||||
// Write functions, returning success or failure:
|
||||
bool writeByte(uint8_t registerAddress, uint8_t writeValue);
|
||||
bool writeWord(uint8_t registerAddress, uint16_t writeValue);
|
||||
bool writeBytes(uint8_t firstRegisterAddress, uint8_t *writeArray, uint8_t length);
|
||||
// Helper functions:
|
||||
// calculateLEDTRegister - Try to estimate an LED on/off duration register,
|
||||
// given the number of milliseconds and LED clock frequency.
|
||||
uint8_t calculateLEDTRegister(unsigned long ms);
|
||||
// calculateSlopeRegister - Try to estimate an LED rise/fall duration
|
||||
// register, given the number of milliseconds and LED clock frequency.
|
||||
uint8_t calculateSlopeRegister(unsigned long ms, uint8_t onIntensity, uint8_t offIntensity);
|
||||
|
||||
public:
|
||||
// -----------------------------------------------------------------------------
|
||||
// Constructor - SX1509: This function sets up the pins connected to the
|
||||
// SX1509, and sets up the private deviceAddress variable.
|
||||
// -----------------------------------------------------------------------------
|
||||
SX1509();
|
||||
// Legacy below. Use 0-parameter constructor, and set these parameters in the
|
||||
// begin function:
|
||||
SX1509(uint8_t address, uint8_t resetPin = 255, uint8_t interruptPin = 255, uint8_t oscillatorPin = 255);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// begin(uint8_t address, uint8_t resetPin): This function initializes the SX1509.
|
||||
// It requires wire to already be begun (previous versions did not do this), resets the IC, and tries to read some
|
||||
// registers to prove it's connected.
|
||||
// Inputs:
|
||||
// - address: should be the 7-bit address of the SX1509. This should be
|
||||
// one of four values - 0x3E, 0x3F, 0x70, 0x71 - all depending on what the
|
||||
// ADDR0 and ADDR1 pins ar se to. This variable is required.
|
||||
// - resetPin: This is the Arduino pin tied to the SX1509 RST pin. This
|
||||
// pin is optional. If not declared, the library will attempt to
|
||||
// software reset the SX1509.
|
||||
// Output: Returns a 1 if communication is successful, 0 on error.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t begin(uint8_t address = 0x3E, TwoWire &wirePort = Wire, uint8_t resetPin = 0xFF);
|
||||
uint8_t init(void); // Legacy -- use begin now
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// reset(bool hardware): This function resets the SX1509 - either a hardware
|
||||
// reset or software. A hardware reset (hardware parameter = 1) pulls the
|
||||
// reset line low, pausing, then pulling the reset line high. A software
|
||||
// reset writes a 0x12 then 0x34 to the REG_RESET as outlined in the
|
||||
// datasheet.
|
||||
//
|
||||
// Input:
|
||||
// - hardware: 0 executes a software reset, 1 executes a hardware reset
|
||||
// -----------------------------------------------------------------------------
|
||||
void reset(bool hardware);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// pinMode(uint8_t pin, uint8_t inOut): This function sets one of the SX1509's 16
|
||||
// outputs to either an INPUT or OUTPUT.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: should be a value between 0 and 15
|
||||
// - inOut: The Arduino INPUT and OUTPUT constants should be used for the
|
||||
// inOut parameter. They do what they say!
|
||||
// -----------------------------------------------------------------------------
|
||||
void pinMode(uint8_t pin, uint8_t inOut, uint8_t initialLevel = HIGH);
|
||||
void pinDir(uint8_t pin, uint8_t inOut, uint8_t initialLevel = HIGH); // Legacy - use pinMode
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// digitalWrite(uint8_t pin, uint8_t highLow): This function writes a pin to either high
|
||||
// or low if it's configured as an OUTPUT. If the pin is configured as an
|
||||
// INPUT, this method will activate either the PULL-UP or PULL-DOWN
|
||||
// resistor (HIGH or LOW respectively).
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin number. Should be a value between 0 and 15.
|
||||
// - highLow: should be Arduino's defined HIGH or LOW constants.
|
||||
// -----------------------------------------------------------------------------
|
||||
bool digitalWrite(uint8_t pin, uint8_t highLow);
|
||||
bool writePin(uint8_t pin, uint8_t highLow); // Legacy - use digitalWrite
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// digitalRead(uint8_t pin): This function reads the HIGH/LOW status of a pin.
|
||||
// The pin should be configured as an INPUT, using the pinDir function.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin to be read. should be a value between 0 and 15.
|
||||
// Outputs:
|
||||
// This function returns a 1 if HIGH, 0 if LOW
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
bool digitalRead(uint8_t pin, bool *value);
|
||||
uint8_t readPin(uint8_t pin); // Legacy - use digitalRead
|
||||
bool readPin(const uint8_t pin, bool *value);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ledDriverInit(uint8_t pin, uint8_t freq, bool log): This function initializes LED
|
||||
// driving on a pin. It must be called if you want to use the pwm or blink
|
||||
// functions on that pin.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin connected to an LED. Should be 0-15.
|
||||
// - freq: Sets LED clock frequency divider.
|
||||
// - log: selects either linear or logarithmic mode on the LED drivers
|
||||
// - log defaults to 0, linear mode
|
||||
// - currently log sets both bank A and B to the same mode
|
||||
// Note: this function automatically decides to use the internal 2MHz osc.
|
||||
// -----------------------------------------------------------------------------
|
||||
void ledDriverInit(uint8_t pin, uint8_t freq = 1, bool log = false);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// analogWrite(uint8_t pin, uint8_t iOn): This function can be used to control the intensity
|
||||
// of an output pin connected to an LED.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: The SX1509 pin connecte to an LED.Should be 0-15.
|
||||
// - iOn: should be a 0-255 value setting the intensity of the LED
|
||||
// - 0 is completely off, 255 is 100% on.
|
||||
//
|
||||
// Note: ledDriverInit should be called on the pin before calling this.
|
||||
// -----------------------------------------------------------------------------
|
||||
void analogWrite(uint8_t pin, uint8_t iOn);
|
||||
void pwm(uint8_t pin, uint8_t iOn); // Legacy - use analogWrite
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// setupBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t offIntensity, uint8_t tRise, uint8_t
|
||||
// tFall): blink performs both the blink and breath LED driver functions.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: the SX1509 pin (0-15) you want to set blinking/breathing.
|
||||
// - tOn: the amount of time the pin is HIGH
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// - tOff: the amount of time the pin is at offIntensity
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// - offIntensity: How dim the LED is during the off period.
|
||||
// - This value should be between 0 and 7. 0 is completely off.
|
||||
// - onIntensity: How bright the LED will be when completely on.
|
||||
// - This value can be between 0 (0%) and 255 (100%).
|
||||
// - tRise: This sets the time the LED takes to fade in.
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// - This value is used with tFall to make the LED breath.
|
||||
// - tFall: This sets the time the LED takes to fade out.
|
||||
// - This value should be between 1 and 31. 0 is off.
|
||||
// Notes:
|
||||
// - The breathable pins are 4, 5, 6, 7, 12, 13, 14, 15 only. If tRise and
|
||||
// tFall are set on 0-3 or 8-11 those pins will still only blink.
|
||||
// - ledDriverInit should be called on the pin to be blinked before this.
|
||||
// -----------------------------------------------------------------------------
|
||||
void setupBlink(uint8_t pin, uint8_t tOn, uint8_t toff, uint8_t onIntensity = 255, uint8_t offIntensity = 0, uint8_t tRise = 0, uint8_t tFall = 0, bool log = false);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity, uint8_t offIntensity);
|
||||
// Set a pin to blink output for estimated on/off millisecond durations.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: the SX1509 pin (0-15) you want to set blinking
|
||||
// - tOn: estimated number of milliseconds the pin is LOW (LED sinking current will be on)
|
||||
// - tOff: estimated number of milliseconds the pin is HIGH (LED sinking current will be off)
|
||||
// - onIntensity: 0-255 value determining LED on brightness
|
||||
// - offIntensity: 0-255 value determining LED off brightness
|
||||
// Notes:
|
||||
// - The breathable pins are 4, 5, 6, 7, 12, 13, 14, 15 only. If tRise and
|
||||
// tFall are set on 0-3 or 8-11 those pins will still only blink.
|
||||
// - ledDriverInit should be called on the pin to be blinked before this.
|
||||
// -----------------------------------------------------------------------------
|
||||
void blink(uint8_t pin, unsigned long tOn, unsigned long tOff, uint8_t onIntensity = 255, uint8_t offIntensity = 0);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, uint8_t onInt, uint8_t offInt, bool log);
|
||||
// Set a pin to breathe output for estimated on/off millisecond durations, with
|
||||
// estimated rise and fall durations.
|
||||
//
|
||||
// Inputs:
|
||||
// - pin: the SX1509 pin (0-15) you want to set blinking
|
||||
// - tOn: estimated number of milliseconds the pin is LOW (LED sinking current will be on)
|
||||
// - tOff: estimated number of milliseconds the pin is HIGH (LED sinking current will be off)
|
||||
// - rise: estimated number of milliseconds the pin rises from LOW to HIGH
|
||||
// - falll: estimated number of milliseconds the pin falls from HIGH to LOW
|
||||
// - onIntensity: 0-255 value determining LED on brightness
|
||||
// - offIntensity: 0-255 value determining LED off brightness
|
||||
// Notes:
|
||||
// - The breathable pins are 4, 5, 6, 7, 12, 13, 14, 15 only. If tRise and
|
||||
// tFall are set on 0-3 or 8-11 those pins will still only blink.
|
||||
// - ledDriverInit should be called on the pin to be blinked before this,
|
||||
// Or call pinMode(<pin>, ANALOG_OUTPUT);
|
||||
// -----------------------------------------------------------------------------
|
||||
void breathe(uint8_t pin, unsigned long tOn, unsigned long tOff, unsigned long rise, unsigned long fall, uint8_t onInt = 255, uint8_t offInt = 0, bool log = LINEAR);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// keypad(uint8_t rows, uint8_t columns, uint8_t sleepTime, uint8_t scanTime, uint8_t debounceTime)
|
||||
// Initializes the keypad function on the SX1509. Millisecond durations for sleep,
|
||||
// scan, and debounce can be set.
|
||||
//
|
||||
// Inputs:
|
||||
// - rows: The number of rows in the button matrix.
|
||||
// - This value must be between 1 and 7. 0 will turn it off.
|
||||
// - eg: 1 = 2 rows, 2 = 3 rows, 7 = 8 rows, etc.
|
||||
// - columns: The number of columns in the button matrix
|
||||
// - This value should be between 0 and 7.
|
||||
// - 0 = 1 column, 7 = 8 columns, etc.
|
||||
// - sleepTime: Sets the auto-sleep time of the keypad engine.
|
||||
// Should be a millisecond duration between 0 (OFF) and 8000 (8 seconds).
|
||||
// Possible values are 0, 128, 256, 512, 1000, 2000, 4000, 8000
|
||||
// - scanTime: Sets the scan time per row. Must be set above debounce.
|
||||
// Should be a millisecond duration between 1 and 128.
|
||||
// Possible values are 1, 2, 4, 8, 16, 32, 64, 128.
|
||||
// - debounceTime: Sets the debounc time per button. Must be set below scan.
|
||||
// Should be a millisecond duration between 0 and 64.
|
||||
// Possible values are 0 (0.5), 1, 2, 4, 8, 16, 32, 64.
|
||||
// -----------------------------------------------------------------------------
|
||||
void keypad(uint8_t rows, uint8_t columns, uint16_t sleepTime = 0, uint8_t scanTime = 1, uint8_t debounceTime = 0);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// readKeypad(): This function returns a 16-bit value containing the status of
|
||||
// keypad engine.
|
||||
//
|
||||
// Output:
|
||||
// A 16-bit value is returned. The lower 8 bits represent the up-to 8 rows,
|
||||
// while the MSB represents the up-to 8 columns. Bit-values of 1 indicate a
|
||||
// button in that row or column is being pressed. As such, at least two
|
||||
// bits should be set.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint16_t readKeypad();
|
||||
uint16_t readKeyData(); // Legacy: use readKeypad();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// getRow(): This function returns the first active row from the return value of
|
||||
// readKeypad().
|
||||
//
|
||||
// Input:
|
||||
// - keyData: Should be the uint16_t value returned from readKeypad().
|
||||
// Output:
|
||||
// A 16-bit value is returned. The lower 8 bits represent the up-to 8 rows,
|
||||
// while the MSB represents the up-to 8 columns. Bit-values of 1 indicate a
|
||||
// button in that row or column is being pressed. As such, at least two
|
||||
// bits should be set.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t getRow(uint16_t keyData);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// getCol(): This function returns the first active column from the return value of
|
||||
// readKeypad().
|
||||
//
|
||||
// Input:
|
||||
// - keyData: Should be the uint16_t value returned from readKeypad().
|
||||
// Output:
|
||||
// A 16-bit value is returned. The lower 8 bits represent the up-to 8 rows,
|
||||
// while the MSB represents the up-to 8 columns. Bit-values of 1 indicate a
|
||||
// button in that row or column is being pressed. As such, at least two
|
||||
// bits should be set.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint8_t getCol(uint16_t keyData);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// sync(void): this function resets the PWM/Blink/Fade counters, syncing any
|
||||
// blinking LEDs. Bit 2 of REG_MISC is set, which alters the functionality
|
||||
// of the nReset pin. The nReset pin is toggled low->high, which should
|
||||
// reset all LED counters. Bit 2 of REG_MISC is again cleared, returning
|
||||
// nReset pin to POR functionality
|
||||
// -----------------------------------------------------------------------------
|
||||
void sync(void);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debounceConfig(uint8_t configValue): This method configures the debounce time of
|
||||
// every input.
|
||||
//
|
||||
// Input:
|
||||
// - configValue: A 3-bit value configuring the debounce time.
|
||||
// 000: 0.5ms * 2MHz/fOSC
|
||||
// 001: 1ms * 2MHz/fOSC
|
||||
// 010: 2ms * 2MHz/fOSC
|
||||
// 011: 4ms * 2MHz/fOSC
|
||||
// 100: 8ms * 2MHz/fOSC
|
||||
// 101: 16ms * 2MHz/fOSC
|
||||
// 110: 32ms * 2MHz/fOSC
|
||||
// 111: 64ms * 2MHz/fOSC
|
||||
//
|
||||
// Note: fOSC is set with the configClock function. It defaults to 2MHz.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debounceConfig(uint8_t configVaule);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debounceTime(uint8_t configValue): This method configures the debounce time of
|
||||
// every input to an estimated millisecond time duration.
|
||||
//
|
||||
// Input:
|
||||
// - time: A millisecond duration estimating the debounce time. Actual
|
||||
// debounce time will depend on fOSC. Assuming it's 2MHz, debounce will
|
||||
// be set to the 0.5, 1, 2, 4, 8, 16, 32, or 64 ms (whatever's closest)
|
||||
//
|
||||
// Note: fOSC is set with the configClock function. It defaults to 2MHz.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debounceTime(uint8_t time);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debouncePin(uint8_t pin): This method enables debounce on SX1509 input pin.
|
||||
//
|
||||
// Input:
|
||||
// - pin: The SX1509 pin to be debounced. Should be between 0 and 15.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debouncePin(uint8_t pin);
|
||||
void debounceEnable(uint8_t pin); // Legacy, use debouncePin
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// debounceKeypad(uint8_t pin): This method enables debounce on all pins connected
|
||||
// to a row/column keypad matrix.
|
||||
//
|
||||
// Input:
|
||||
// - time: Millisecond time estimate for debounce (see debounceTime()).
|
||||
// - numRows: The number of rows in the keypad matrix.
|
||||
// - numCols: The number of columns in the keypad matrix.
|
||||
// -----------------------------------------------------------------------------
|
||||
void debounceKeypad(uint8_t time, uint8_t numRows, uint8_t numCols);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// enableInterrupt(uint8_t pin, uint8_t riseFall): This function sets up an interrupt
|
||||
// on a pin. Interrupts can occur on all SX1509 pins, and can be generated
|
||||
// on rising, falling, or both.
|
||||
//
|
||||
// Inputs:
|
||||
// -pin: SX1509 input pin that will generate an input. Should be 0-15.
|
||||
// -riseFall: Configures if you want an interrupt generated on rise fall or
|
||||
// both. For this param, send the pin-change values previously defined
|
||||
// by Arduino:
|
||||
// #define CHANGE 1 <-Both
|
||||
// #define FALLING 2 <- Falling
|
||||
// #define RISING 3 <- Rising
|
||||
//
|
||||
// Note: This function does not set up a pin as an input, or configure its
|
||||
// pull-up/down resistors! Do that before (or after).
|
||||
// -----------------------------------------------------------------------------
|
||||
void enableInterrupt(uint8_t pin, uint8_t riseFall);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// interruptSource(void): Returns an uint16_t representing which pin caused
|
||||
// an interrupt.
|
||||
//
|
||||
// Output: 16-bit value, with a single bit set representing the pin(s) that
|
||||
// generated an interrupt. E.g. a return value of 0x0104 would mean pins 8
|
||||
// and 3 (bits 8 and 3) have generated an interrupt.
|
||||
// Input:
|
||||
// - clear: boolean commanding whether the interrupt should be cleared
|
||||
// after reading or not.
|
||||
// -----------------------------------------------------------------------------
|
||||
uint16_t interruptSource(bool clear = true);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// checkInterrupt(void): Checks if a single pin generated an interrupt.
|
||||
//
|
||||
// Output: Boolean value. True if the requested pin has triggered an interrupt/
|
||||
// Input:
|
||||
// - pin: Pin to be checked for generating an input.
|
||||
// -----------------------------------------------------------------------------
|
||||
bool checkInterrupt(uint8_t pin);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// configClock(uint8_t oscSource, uint8_t oscPinFunction, uint8_t oscFreqOut, uint8_t oscDivider)
|
||||
// This function configures the oscillator source/speed
|
||||
// and the clock, which is used to drive LEDs and time debounces.
|
||||
//
|
||||
// Inputs:
|
||||
// - oscSource: Choose either internal 2MHz oscillator or an external signal
|
||||
// applied to the OSCIO pin.
|
||||
// - INTERNAL_CLOCK and EXTERNAL_CLOCK are defined in the header file.
|
||||
// Use those.
|
||||
// - This value defaults to internal.
|
||||
// - oscDivider: Sets the clock divider in REG_MISC.
|
||||
// - ClkX = fOSC / (2^(RegMisc[6:4] -1))
|
||||
// - This value defaults to 1.
|
||||
// - oscPinFunction: Allows you to set OSCIO as an input or output.
|
||||
// - You can use Arduino's INPUT, OUTPUT defines for this value
|
||||
// - This value defaults to input
|
||||
// - oscFreqOut: If oscio is configured as an output, this will set the output
|
||||
// frequency
|
||||
// - This should be a 4-bit value. 0=0%, 0xF=100%, else
|
||||
// fOSCOut = FOSC / (2^(RegClock[3:0]-1))
|
||||
// - This value defaults to 0.
|
||||
// -----------------------------------------------------------------------------
|
||||
void configClock(uint8_t oscSource = 2, uint8_t oscPinFunction = 0, uint8_t oscFreqOut = 0, uint8_t oscDivider = 1); // Legacy, use clock();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// clock(uint8_t oscSource, uint8_t oscDivider, uint8_t oscPinFunction, uint8_t oscFreqOut)
|
||||
// This function configures the oscillator source/speed
|
||||
// and the clock, which is used to drive LEDs and time debounces.
|
||||
// This is just configClock in a bit more sane order.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
void clock(uint8_t oscSource = 2, uint8_t oscDivider = 1, uint8_t oscPinFunction = 0, uint8_t oscFreqOut = 0);
|
||||
};
|
||||
|
||||
// Add backwards compatibility for the old class name: sx1509Class
|
||||
typedef SX1509 sx1509Class;
|
||||
|
||||
#endif // SX1509_library_H
|
||||
@@ -0,0 +1,163 @@
|
||||
/******************************************************************************
|
||||
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
|
||||
|
||||
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};
|
||||
Reference in new issue
Block a user