Driver for the IO Expander/LED Driver
SX1509.cpp@2:0f4b9539feca, 2017-04-26 (annotated)
- Committer:
- mwilkens241
- Date:
- Wed Apr 26 18:04:24 2017 +0000
- Revision:
- 2:0f4b9539feca
- Parent:
- 1:0176ec93c3fe
nothing here changed lol
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mwilkens241 | 0:c36e6bab0c22 | 1 | #include "SX1509.h" |
| mwilkens241 | 0:c36e6bab0c22 | 2 | |
| mwilkens241 | 0:c36e6bab0c22 | 3 | const uint8_t onTReg[16] = {REGTON0, REGTON1, REGTON2, REGTON3, REGTON4, REGTON5, REGTON6, REGTON7, REGTON8, REGTON9, REGTON10, REGTON11, REGTON12, REGTON13, REGTON14, REGTON15}; |
| mwilkens241 | 0:c36e6bab0c22 | 4 | |
| mwilkens241 | 0:c36e6bab0c22 | 5 | const uint8_t onIReg[16] = {REGION0, REGION1, REGION2, REGION3, REGION4, REGION5, REGION6, REGION7, REGION8, REGION9, REGION10, REGION11, REGION12, REGION13, REGION14, REGION15}; |
| mwilkens241 | 0:c36e6bab0c22 | 6 | |
| mwilkens241 | 0:c36e6bab0c22 | 7 | const uint8_t offTReg[16] = {REGOFF0, REGOFF1, REGOFF2, REGOFF3, REGOFF4, REGOFF5, REGOFF6, REGOFF7, REGOFF8, REGOFF9, REGOFF10, REGOFF11, REGOFF12, REGOFF13, REGOFF14, REGOFF15}; |
| mwilkens241 | 0:c36e6bab0c22 | 8 | |
| mwilkens241 | 0:c36e6bab0c22 | 9 | const uint8_t riseTReg[16] = {0,0,0,0, REGTRISE4, REGTRISE5, REGTRISE6, REGTRISE7, 0,0,0,0, REGTRISE12, REGTRISE13, REGTRISE14, REGTRISE15}; |
| mwilkens241 | 0:c36e6bab0c22 | 10 | |
| mwilkens241 | 0:c36e6bab0c22 | 11 | const uint8_t fallTReg[16] = {0,0,0,0, REGTFALL4, REGTFALL5, REGTFALL6, REGTFALL7, 0,0,0,0, REGTFALL12, REGTFALL13, REGTFALL14, REGTFALL15}; |
| mwilkens241 | 0:c36e6bab0c22 | 12 | |
| mwilkens241 | 0:c36e6bab0c22 | 13 | |
| mwilkens241 | 0:c36e6bab0c22 | 14 | SX1509::SX1509(PinName sda, PinName scl) : i2c(sda,scl) {} |
| mwilkens241 | 0:c36e6bab0c22 | 15 | |
| mwilkens241 | 0:c36e6bab0c22 | 16 | void SX1509::i2cWrite8(char reg, char data){ |
| mwilkens241 | 0:c36e6bab0c22 | 17 | char packet[2] = {reg ,data & 0xFF}; |
| mwilkens241 | 0:c36e6bab0c22 | 18 | i2c.write(SX1509_ADDR,packet,2,false); |
| mwilkens241 | 0:c36e6bab0c22 | 19 | wait(0.01); |
| mwilkens241 | 0:c36e6bab0c22 | 20 | } |
| mwilkens241 | 0:c36e6bab0c22 | 21 | |
| mwilkens241 | 0:c36e6bab0c22 | 22 | uint8_t SX1509::i2cRead8(char reg){ |
| mwilkens241 | 0:c36e6bab0c22 | 23 | char packet[1] = {reg}; |
| mwilkens241 | 0:c36e6bab0c22 | 24 | char data[1] = {0}; |
| mwilkens241 | 0:c36e6bab0c22 | 25 | i2c.write(SX1509_ADDR,packet,1, true); |
| mwilkens241 | 0:c36e6bab0c22 | 26 | i2c.read(SX1509_ADDR,data,1,false); |
| mwilkens241 | 0:c36e6bab0c22 | 27 | wait(0.01); |
| mwilkens241 | 0:c36e6bab0c22 | 28 | return (uint8_t)data[0]; |
| mwilkens241 | 0:c36e6bab0c22 | 29 | } |
| mwilkens241 | 0:c36e6bab0c22 | 30 | |
| mwilkens241 | 0:c36e6bab0c22 | 31 | uint16_t SX1509::i2cRead16(char reg){ |
| mwilkens241 | 0:c36e6bab0c22 | 32 | char packet[1] = {reg}; |
| mwilkens241 | 0:c36e6bab0c22 | 33 | char data[2] = {0,0}; |
| mwilkens241 | 0:c36e6bab0c22 | 34 | i2c.write(SX1509_ADDR,packet,1, true); |
| mwilkens241 | 0:c36e6bab0c22 | 35 | i2c.read(SX1509_ADDR,data,2, false); |
| mwilkens241 | 0:c36e6bab0c22 | 36 | wait(0.01); |
| mwilkens241 | 0:c36e6bab0c22 | 37 | return ((uint16_t)data[1] << 8) | (uint16_t)data[0]; |
| mwilkens241 | 0:c36e6bab0c22 | 38 | } |
| mwilkens241 | 0:c36e6bab0c22 | 39 | |
| mwilkens241 | 0:c36e6bab0c22 | 40 | bool SX1509::init(){ |
| mwilkens241 | 0:c36e6bab0c22 | 41 | i2c.frequency(400000); |
| mwilkens241 | 0:c36e6bab0c22 | 42 | uint8_t val = i2cRead8(REGINTERRUPTMASKA); //defaults to 0xFF |
| mwilkens241 | 0:c36e6bab0c22 | 43 | if(val == 0xFF){ |
| mwilkens241 | 0:c36e6bab0c22 | 44 | val = i2cRead8(REGSENSEHIGHB); //defaults to 0x00 |
| mwilkens241 | 0:c36e6bab0c22 | 45 | if(val == 0x00){ |
| mwilkens241 | 0:c36e6bab0c22 | 46 | return 0; |
| mwilkens241 | 0:c36e6bab0c22 | 47 | } |
| mwilkens241 | 0:c36e6bab0c22 | 48 | } |
| mwilkens241 | 0:c36e6bab0c22 | 49 | return 1; |
| mwilkens241 | 0:c36e6bab0c22 | 50 | } |
| mwilkens241 | 0:c36e6bab0c22 | 51 | |
| mwilkens241 | 0:c36e6bab0c22 | 52 | void SX1509::enableLEDDriver(){ |
| mwilkens241 | 0:c36e6bab0c22 | 53 | enableLEDDriver(7, 0); |
| mwilkens241 | 0:c36e6bab0c22 | 54 | } |
| mwilkens241 | 0:c36e6bab0c22 | 55 | |
| mwilkens241 | 0:c36e6bab0c22 | 56 | void SX1509::enableLEDDriver(uint8_t div, bool mode){ |
| mwilkens241 | 0:c36e6bab0c22 | 57 | if(div > 7)div=7; |
| mwilkens241 | 0:c36e6bab0c22 | 58 | div_g = div; |
| mwilkens241 | 0:c36e6bab0c22 | 59 | //REGCLOCK (0x1E) |
| mwilkens241 | 0:c36e6bab0c22 | 60 | // 6:5 10 |
| mwilkens241 | 0:c36e6bab0c22 | 61 | // 01000000 = 0x40 |
| mwilkens241 | 0:c36e6bab0c22 | 62 | |
| mwilkens241 | 0:c36e6bab0c22 | 63 | //REGMISC (0x1F) |
| mwilkens241 | 0:c36e6bab0c22 | 64 | // 7 0/1 |
| mwilkens241 | 0:c36e6bab0c22 | 65 | // 6:4 div |
| mwilkens241 | 0:c36e6bab0c22 | 66 | // 3 0/1 |
| mwilkens241 | 0:c36e6bab0c22 | 67 | // 2 1 |
| mwilkens241 | 0:c36e6bab0c22 | 68 | // 1 1 |
| mwilkens241 | 0:c36e6bab0c22 | 69 | // 0 0 |
| mwilkens241 | 0:c36e6bab0c22 | 70 | //00000110 | (div<<4) |
| mwilkens241 | 0:c36e6bab0c22 | 71 | //00000110 = 0x06 or 0x8E for log mode |
| mwilkens241 | 0:c36e6bab0c22 | 72 | |
| mwilkens241 | 0:c36e6bab0c22 | 73 | i2cWrite8(REGCLOCK, 0x40); |
| mwilkens241 | 0:c36e6bab0c22 | 74 | i2cWrite8(REGMISC, 0x06 | (div<<4) | (mode<<3) | (mode<<7)); |
| mwilkens241 | 0:c36e6bab0c22 | 75 | } |
| mwilkens241 | 0:c36e6bab0c22 | 76 | |
| mwilkens241 | 0:c36e6bab0c22 | 77 | void SX1509::setLEDMode(bool mode){ |
| mwilkens241 | 1:0176ec93c3fe | 78 | uint8_t buf = i2cRead8(REGMISC); |
| mwilkens241 | 1:0176ec93c3fe | 79 | if(mode==LINEAR){ |
| mwilkens241 | 1:0176ec93c3fe | 80 | buf &= ~(1<<3); |
| mwilkens241 | 1:0176ec93c3fe | 81 | buf &= ~(1<<7); |
| mwilkens241 | 1:0176ec93c3fe | 82 | } else { |
| mwilkens241 | 1:0176ec93c3fe | 83 | buf |= (1<<3); |
| mwilkens241 | 1:0176ec93c3fe | 84 | buf |= (1<<7); |
| mwilkens241 | 1:0176ec93c3fe | 85 | } |
| mwilkens241 | 1:0176ec93c3fe | 86 | i2cWrite8(REGMISC, buf); |
| mwilkens241 | 0:c36e6bab0c22 | 87 | } |
| mwilkens241 | 0:c36e6bab0c22 | 88 | |
| mwilkens241 | 0:c36e6bab0c22 | 89 | void SX1509::setMode(uint8_t pin, mode_t mode){ |
| mwilkens241 | 0:c36e6bab0c22 | 90 | |
| mwilkens241 | 0:c36e6bab0c22 | 91 | // REGINPUTDISABLEA 1 0 0 |
| mwilkens241 | 0:c36e6bab0c22 | 92 | // REGPULLUPA 0 0 0 |
| mwilkens241 | 0:c36e6bab0c22 | 93 | // REGOPENDRAINA 0 1 1 |
| mwilkens241 | 0:c36e6bab0c22 | 94 | // REGDIRA 1 0 0 |
| mwilkens241 | 0:c36e6bab0c22 | 95 | |
| mwilkens241 | 0:c36e6bab0c22 | 96 | uint8_t inputReg, pullupReg, opendReg, dirReg, ledReg; |
| mwilkens241 | 0:c36e6bab0c22 | 97 | |
| mwilkens241 | 1:0176ec93c3fe | 98 | if(pin < 8){ |
| mwilkens241 | 0:c36e6bab0c22 | 99 | inputReg = REGINPUTDISABLEA; |
| mwilkens241 | 0:c36e6bab0c22 | 100 | pullupReg = REGPULLUPA; |
| mwilkens241 | 0:c36e6bab0c22 | 101 | opendReg = REGOPENDRAINA; |
| mwilkens241 | 0:c36e6bab0c22 | 102 | dirReg = REGDIRA; |
| mwilkens241 | 0:c36e6bab0c22 | 103 | ledReg = REGLEDDRIVERENABLEA; |
| mwilkens241 | 1:0176ec93c3fe | 104 | } else { |
| mwilkens241 | 0:c36e6bab0c22 | 105 | inputReg = REGINPUTDISABLEB; |
| mwilkens241 | 0:c36e6bab0c22 | 106 | pullupReg = REGPULLUPB; |
| mwilkens241 | 0:c36e6bab0c22 | 107 | opendReg = REGOPENDRAINB; |
| mwilkens241 | 0:c36e6bab0c22 | 108 | dirReg = REGDIRB; |
| mwilkens241 | 0:c36e6bab0c22 | 109 | ledReg = REGLEDDRIVERENABLEB; |
| mwilkens241 | 1:0176ec93c3fe | 110 | pin-=8; |
| mwilkens241 | 0:c36e6bab0c22 | 111 | } |
| mwilkens241 | 0:c36e6bab0c22 | 112 | |
| mwilkens241 | 2:0f4b9539feca | 113 | uint8_t buf; |
| mwilkens241 | 2:0f4b9539feca | 114 | |
| mwilkens241 | 0:c36e6bab0c22 | 115 | switch(mode){ |
| mwilkens241 | 0:c36e6bab0c22 | 116 | case INPUT: |
| mwilkens241 | 0:c36e6bab0c22 | 117 | //TODO: Finish this |
| mwilkens241 | 0:c36e6bab0c22 | 118 | break; |
| mwilkens241 | 0:c36e6bab0c22 | 119 | case OUTPUT: |
| mwilkens241 | 0:c36e6bab0c22 | 120 | //TODO: Finish this |
| mwilkens241 | 0:c36e6bab0c22 | 121 | break; |
| mwilkens241 | 0:c36e6bab0c22 | 122 | case LED: |
| mwilkens241 | 2:0f4b9539feca | 123 | buf = i2cRead8(inputReg); |
| mwilkens241 | 0:c36e6bab0c22 | 124 | buf &= ~(1<<pin); |
| mwilkens241 | 0:c36e6bab0c22 | 125 | i2cWrite8(inputReg, buf); |
| mwilkens241 | 0:c36e6bab0c22 | 126 | buf = i2cRead8(pullupReg); |
| mwilkens241 | 0:c36e6bab0c22 | 127 | buf &= ~(1<<pin); |
| mwilkens241 | 0:c36e6bab0c22 | 128 | i2cWrite8(pullupReg, buf); |
| mwilkens241 | 0:c36e6bab0c22 | 129 | buf = i2cRead8(opendReg); |
| mwilkens241 | 0:c36e6bab0c22 | 130 | buf |= (1<<pin); |
| mwilkens241 | 0:c36e6bab0c22 | 131 | i2cWrite8(opendReg, buf); |
| mwilkens241 | 0:c36e6bab0c22 | 132 | buf = i2cRead8(dirReg); |
| mwilkens241 | 0:c36e6bab0c22 | 133 | buf &= ~(1<<pin); |
| mwilkens241 | 0:c36e6bab0c22 | 134 | i2cWrite8(dirReg, buf); |
| mwilkens241 | 0:c36e6bab0c22 | 135 | buf = i2cRead8(ledReg); |
| mwilkens241 | 0:c36e6bab0c22 | 136 | buf |= (1<<pin); |
| mwilkens241 | 0:c36e6bab0c22 | 137 | i2cWrite8(ledReg, buf); |
| mwilkens241 | 0:c36e6bab0c22 | 138 | break; |
| mwilkens241 | 0:c36e6bab0c22 | 139 | default: |
| mwilkens241 | 0:c36e6bab0c22 | 140 | break; |
| mwilkens241 | 0:c36e6bab0c22 | 141 | } |
| mwilkens241 | 0:c36e6bab0c22 | 142 | } |
| mwilkens241 | 0:c36e6bab0c22 | 143 | |
| mwilkens241 | 0:c36e6bab0c22 | 144 | void SX1509::setBreath(uint8_t pin, uint8_t fadeIn, uint8_t fadeOut){ |
| mwilkens241 | 0:c36e6bab0c22 | 145 | // Clamp these |
| mwilkens241 | 0:c36e6bab0c22 | 146 | fadeIn &= 0x1F; |
| mwilkens241 | 0:c36e6bab0c22 | 147 | fadeOut &= 0x1F; |
| mwilkens241 | 0:c36e6bab0c22 | 148 | i2cWrite8(riseTReg[pin],fadeIn); |
| mwilkens241 | 0:c36e6bab0c22 | 149 | i2cWrite8(fallTReg[pin],fadeOut); |
| mwilkens241 | 0:c36e6bab0c22 | 150 | } |
| mwilkens241 | 0:c36e6bab0c22 | 151 | |
| mwilkens241 | 0:c36e6bab0c22 | 152 | void SX1509::setBlink(uint8_t pin, uint8_t tOn, uint8_t tOff, uint8_t iOff){ |
| mwilkens241 | 0:c36e6bab0c22 | 153 | tOn &= 0x1F; |
| mwilkens241 | 0:c36e6bab0c22 | 154 | tOff &= 0x1F; |
| mwilkens241 | 0:c36e6bab0c22 | 155 | iOff &= 0x07; |
| mwilkens241 | 0:c36e6bab0c22 | 156 | i2cWrite8(onTReg[pin],tOn); |
| mwilkens241 | 0:c36e6bab0c22 | 157 | uint8_t buf = i2cRead8(offTReg[pin]) & 0x07; |
| mwilkens241 | 0:c36e6bab0c22 | 158 | i2cWrite8(offTReg[pin],tOff<<3 | buf | iOff); |
| mwilkens241 | 0:c36e6bab0c22 | 159 | } |
| mwilkens241 | 0:c36e6bab0c22 | 160 | |
| mwilkens241 | 0:c36e6bab0c22 | 161 | void SX1509::writePin(uint8_t pin, uint8_t intensity){ |
| mwilkens241 | 0:c36e6bab0c22 | 162 | i2cWrite8(onIReg[pin], intensity&0xFF); |
| mwilkens241 | 0:c36e6bab0c22 | 163 | uint8_t dataReg; |
| mwilkens241 | 1:0176ec93c3fe | 164 | if(pin < 8){ |
| mwilkens241 | 0:c36e6bab0c22 | 165 | dataReg = REGDATAA; |
| mwilkens241 | 1:0176ec93c3fe | 166 | } else { |
| mwilkens241 | 0:c36e6bab0c22 | 167 | dataReg = REGDATAB; |
| mwilkens241 | 1:0176ec93c3fe | 168 | pin-=8; |
| mwilkens241 | 0:c36e6bab0c22 | 169 | } |
| mwilkens241 | 0:c36e6bab0c22 | 170 | uint8_t buf = i2cRead8(dataReg); |
| mwilkens241 | 0:c36e6bab0c22 | 171 | if(intensity == 0) |
| mwilkens241 | 0:c36e6bab0c22 | 172 | i2cWrite8(dataReg, buf | (1<<pin)); |
| mwilkens241 | 0:c36e6bab0c22 | 173 | else |
| mwilkens241 | 0:c36e6bab0c22 | 174 | i2cWrite8(dataReg, buf & ~(1<<pin)); |
| mwilkens241 | 1:0176ec93c3fe | 175 | } |
| mwilkens241 | 1:0176ec93c3fe | 176 | |
| mwilkens241 | 1:0176ec93c3fe | 177 | void SX1509::setReset(){ |
| mwilkens241 | 1:0176ec93c3fe | 178 | uint8_t buf = i2cRead8(REGMISC); |
| mwilkens241 | 1:0176ec93c3fe | 179 | buf |= (1<<2); |
| mwilkens241 | 1:0176ec93c3fe | 180 | i2cWrite8(REGMISC, buf); |
| mwilkens241 | 2:0f4b9539feca | 181 | } |
| mwilkens241 | 2:0f4b9539feca | 182 | |
| mwilkens241 | 2:0f4b9539feca | 183 | void SX1509::fullReset(){ |
| mwilkens241 | 2:0f4b9539feca | 184 | i2cWrite8(REGRESET, 0x12); |
| mwilkens241 | 2:0f4b9539feca | 185 | i2cWrite8(REGRESET, 0x34); |
| mwilkens241 | 0:c36e6bab0c22 | 186 | } |