Driver for the IO Expander/LED Driver
SX1509.cpp
- Committer:
- mwilkens241
- Date:
- 2017-04-26
- Revision:
- 2:0f4b9539feca
- Parent:
- 1:0176ec93c3fe
File content as of revision 2:0f4b9539feca:
#include "SX1509.h"
const uint8_t onTReg[16] = {REGTON0, REGTON1, REGTON2, REGTON3, REGTON4, REGTON5, REGTON6, REGTON7, REGTON8, REGTON9, REGTON10, REGTON11, REGTON12, REGTON13, REGTON14, REGTON15};
const uint8_t onIReg[16] = {REGION0, REGION1, REGION2, REGION3, REGION4, REGION5, REGION6, REGION7, REGION8, REGION9, REGION10, REGION11, REGION12, REGION13, REGION14, REGION15};
const uint8_t offTReg[16] = {REGOFF0, REGOFF1, REGOFF2, REGOFF3, REGOFF4, REGOFF5, REGOFF6, REGOFF7, REGOFF8, REGOFF9, REGOFF10, REGOFF11, REGOFF12, REGOFF13, REGOFF14, REGOFF15};
const uint8_t riseTReg[16] = {0,0,0,0, REGTRISE4, REGTRISE5, REGTRISE6, REGTRISE7, 0,0,0,0, REGTRISE12, REGTRISE13, REGTRISE14, REGTRISE15};
const uint8_t fallTReg[16] = {0,0,0,0, REGTFALL4, REGTFALL5, REGTFALL6, REGTFALL7, 0,0,0,0, REGTFALL12, REGTFALL13, REGTFALL14, REGTFALL15};
SX1509::SX1509(PinName sda, PinName scl) : i2c(sda,scl) {}
void SX1509::i2cWrite8(char reg, char data){
char packet[2] = {reg ,data & 0xFF};
i2c.write(SX1509_ADDR,packet,2,false);
wait(0.01);
}
uint8_t SX1509::i2cRead8(char reg){
char packet[1] = {reg};
char data[1] = {0};
i2c.write(SX1509_ADDR,packet,1, true);
i2c.read(SX1509_ADDR,data,1,false);
wait(0.01);
return (uint8_t)data[0];
}
uint16_t SX1509::i2cRead16(char reg){
char packet[1] = {reg};
char data[2] = {0,0};
i2c.write(SX1509_ADDR,packet,1, true);
i2c.read(SX1509_ADDR,data,2, false);
wait(0.01);
return ((uint16_t)data[1] << 8) | (uint16_t)data[0];
}
bool SX1509::init(){
i2c.frequency(400000);
uint8_t val = i2cRead8(REGINTERRUPTMASKA); //defaults to 0xFF
if(val == 0xFF){
val = i2cRead8(REGSENSEHIGHB); //defaults to 0x00
if(val == 0x00){
return 0;
}
}
return 1;
}
void SX1509::enableLEDDriver(){
enableLEDDriver(7, 0);
}
void SX1509::enableLEDDriver(uint8_t div, bool mode){
if(div > 7)div=7;
div_g = div;
//REGCLOCK (0x1E)
// 6:5 10
// 01000000 = 0x40
//REGMISC (0x1F)
// 7 0/1
// 6:4 div
// 3 0/1
// 2 1
// 1 1
// 0 0
//00000110 | (div<<4)
//00000110 = 0x06 or 0x8E for log mode
i2cWrite8(REGCLOCK, 0x40);
i2cWrite8(REGMISC, 0x06 | (div<<4) | (mode<<3) | (mode<<7));
}
void SX1509::setLEDMode(bool mode){
uint8_t buf = i2cRead8(REGMISC);
if(mode==LINEAR){
buf &= ~(1<<3);
buf &= ~(1<<7);
} else {
buf |= (1<<3);
buf |= (1<<7);
}
i2cWrite8(REGMISC, buf);
}
void SX1509::setMode(uint8_t pin, mode_t mode){
// REGINPUTDISABLEA 1 0 0
// REGPULLUPA 0 0 0
// REGOPENDRAINA 0 1 1
// REGDIRA 1 0 0
uint8_t inputReg, pullupReg, opendReg, dirReg, ledReg;
if(pin < 8){
inputReg = REGINPUTDISABLEA;
pullupReg = REGPULLUPA;
opendReg = REGOPENDRAINA;
dirReg = REGDIRA;
ledReg = REGLEDDRIVERENABLEA;
} else {
inputReg = REGINPUTDISABLEB;
pullupReg = REGPULLUPB;
opendReg = REGOPENDRAINB;
dirReg = REGDIRB;
ledReg = REGLEDDRIVERENABLEB;
pin-=8;
}
uint8_t buf;
switch(mode){
case INPUT:
//TODO: Finish this
break;
case OUTPUT:
//TODO: Finish this
break;
case LED:
buf = i2cRead8(inputReg);
buf &= ~(1<<pin);
i2cWrite8(inputReg, buf);
buf = i2cRead8(pullupReg);
buf &= ~(1<<pin);
i2cWrite8(pullupReg, buf);
buf = i2cRead8(opendReg);
buf |= (1<<pin);
i2cWrite8(opendReg, buf);
buf = i2cRead8(dirReg);
buf &= ~(1<<pin);
i2cWrite8(dirReg, buf);
buf = i2cRead8(ledReg);
buf |= (1<<pin);
i2cWrite8(ledReg, buf);
break;
default:
break;
}
}
void SX1509::setBreath(uint8_t pin, uint8_t fadeIn, uint8_t fadeOut){
// Clamp these
fadeIn &= 0x1F;
fadeOut &= 0x1F;
i2cWrite8(riseTReg[pin],fadeIn);
i2cWrite8(fallTReg[pin],fadeOut);
}
void SX1509::setBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t iOff){
tOn &= 0x1F;
tOff &= 0x1F;
iOff &= 0x07;
i2cWrite8(onTReg[pin],tOn);
uint8_t buf = i2cRead8(offTReg[pin]) & 0x07;
i2cWrite8(offTReg[pin],tOff<<3 | buf | iOff);
}
void SX1509::writePin(uint8_t pin, uint8_t intensity){
i2cWrite8(onIReg[pin], intensity&0xFF);
uint8_t dataReg;
if(pin < 8){
dataReg = REGDATAA;
} else {
dataReg = REGDATAB;
pin-=8;
}
uint8_t buf = i2cRead8(dataReg);
if(intensity == 0)
i2cWrite8(dataReg, buf | (1<<pin));
else
i2cWrite8(dataReg, buf & ~(1<<pin));
}
void SX1509::setReset(){
uint8_t buf = i2cRead8(REGMISC);
buf |= (1<<2);
i2cWrite8(REGMISC, buf);
}
void SX1509::fullReset(){
i2cWrite8(REGRESET, 0x12);
i2cWrite8(REGRESET, 0x34);
}