Line Health / SX1509
Revision:
0:c36e6bab0c22
Child:
1:0176ec93c3fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SX1509.cpp	Tue Apr 18 19:49:29 2017 +0000
@@ -0,0 +1,173 @@
+#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){
+    enableLEDDriver(div_g,mode);    
+}
+
+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;
+    
+    switch(PINBANK(pin)){
+        case 'A':
+            inputReg = REGINPUTDISABLEA;
+            pullupReg = REGPULLUPA;
+            opendReg = REGOPENDRAINA;
+            dirReg = REGDIRA;
+            ledReg = REGLEDDRIVERENABLEA;
+            break;
+        case 'B':
+            inputReg = REGINPUTDISABLEB;
+            pullupReg = REGPULLUPB;
+            opendReg = REGOPENDRAINB;
+            dirReg = REGDIRB;
+            ledReg = REGLEDDRIVERENABLEB;
+            break;
+        default:
+            return;
+    }
+    
+    switch(mode){
+        case INPUT:
+            //TODO: Finish this
+            break;
+        case OUTPUT:
+            //TODO: Finish this
+            break;
+        case LED:
+            uint8_t 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;
+    switch(PINBANK(pin)){
+        case 'A':
+            dataReg = REGDATAA;
+            break;
+        case 'B':
+            dataReg = REGDATAB;
+            break;
+        default:
+            return;
+    }
+    uint8_t buf = i2cRead8(dataReg);
+    if(intensity == 0)
+        i2cWrite8(dataReg, buf | (1<<pin));
+    else
+        i2cWrite8(dataReg, buf & ~(1<<pin));
+}
\ No newline at end of file