TLC59108 8-bit LED Sink Driver module (C) 2013 Christopher Smith <chrylis@gmail.com> GNU Lesser General Public License v3.0

Dependents:   chuk

Committer:
eisd
Date:
Thu Aug 24 15:13:52 2017 +0000
Revision:
2:38e938dbb50a
Parent:
1:b204db0e7687
Attribution

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eisd 2:38e938dbb50a 1 /*
eisd 2:38e938dbb50a 2 * TLC59108: Arduino library to control TI TLC59108/TLC59108F/TLC59208 LED drivers
eisd 2:38e938dbb50a 3 *
eisd 2:38e938dbb50a 4 * (C) 2013 Christopher Smith <chrylis@gmail.com>
eisd 2:38e938dbb50a 5 *
eisd 2:38e938dbb50a 6 * This program is free software: you can redistribute it and/or modify
eisd 2:38e938dbb50a 7 * it under the terms of the GNU Lesser General Public License as published by
eisd 2:38e938dbb50a 8 * the Free Software Foundation, either version 3 of the License, or
eisd 2:38e938dbb50a 9 * (at your option) any later version.
eisd 2:38e938dbb50a 10 *
eisd 2:38e938dbb50a 11 * This program is distributed in the hope that it will be useful,
eisd 2:38e938dbb50a 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
eisd 2:38e938dbb50a 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
eisd 2:38e938dbb50a 14 * GNU General Public License for more details.
eisd 2:38e938dbb50a 15 *
eisd 2:38e938dbb50a 16 * You should have received a copy of the GNU Lesser General Public License
eisd 2:38e938dbb50a 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
eisd 2:38e938dbb50a 18 */
eisd 2:38e938dbb50a 19
eisd 0:8edf69cf40fc 20 #ifndef __TLC59108_H__
eisd 0:8edf69cf40fc 21 #define __TLC59108_H__
eisd 0:8edf69cf40fc 22
eisd 0:8edf69cf40fc 23 #include "mbed.h"
eisd 0:8edf69cf40fc 24
eisd 0:8edf69cf40fc 25 class TLC59108
eisd 0:8edf69cf40fc 26 {
eisd 0:8edf69cf40fc 27 public:
eisd 0:8edf69cf40fc 28
eisd 0:8edf69cf40fc 29 typedef uint8_t byte;
eisd 0:8edf69cf40fc 30
eisd 0:8edf69cf40fc 31 // default I2C addresses
eisd 0:8edf69cf40fc 32 // datasheet, pp 12-13
eisd 0:8edf69cf40fc 33 struct I2C_ADDR
eisd 0:8edf69cf40fc 34 {
eisd 0:8edf69cf40fc 35 static const byte BASE = 0x80;
eisd 0:8edf69cf40fc 36 static const byte SWRESET = 0x4b;
eisd 0:8edf69cf40fc 37 static const byte ALLCALL = 0x90;
eisd 0:8edf69cf40fc 38 static const byte SUB1 = 0x92;
eisd 0:8edf69cf40fc 39 static const byte SUB2 = 0x94;
eisd 0:8edf69cf40fc 40 static const byte SUB3 = 0x98;
eisd 0:8edf69cf40fc 41 };
eisd 0:8edf69cf40fc 42
eisd 0:8edf69cf40fc 43 // register auto-increment modes for setting multiple registers
eisd 0:8edf69cf40fc 44 // datasheet, p 13
eisd 0:8edf69cf40fc 45 struct AUTO_INCREMENT
eisd 0:8edf69cf40fc 46 {
eisd 0:8edf69cf40fc 47 static const byte ALL = 0x80; // increment through all registers (for initial setup)
eisd 0:8edf69cf40fc 48 static const byte IND = 0xa0; // increment through individual brightness registers
eisd 0:8edf69cf40fc 49 static const byte GLOBAL = 0xc0; // increment through global control registers
eisd 0:8edf69cf40fc 50 static const byte INDGLOBAL = 0xe0; // increment through individual and global registers
eisd 0:8edf69cf40fc 51 };
eisd 0:8edf69cf40fc 52
eisd 0:8edf69cf40fc 53 struct LED_MODE
eisd 0:8edf69cf40fc 54 {
eisd 0:8edf69cf40fc 55 static const byte OFF = 0;
eisd 0:8edf69cf40fc 56 static const byte FULL_ON = 1;
eisd 0:8edf69cf40fc 57 static const byte PWM_IND = 2;
eisd 0:8edf69cf40fc 58 static const byte PWM_INDGRP = 3;
eisd 0:8edf69cf40fc 59 };
eisd 0:8edf69cf40fc 60
eisd 0:8edf69cf40fc 61 // register names
eisd 0:8edf69cf40fc 62 // datasheet, p 16
eisd 0:8edf69cf40fc 63 struct REGISTER
eisd 0:8edf69cf40fc 64 {
eisd 0:8edf69cf40fc 65 public:
eisd 0:8edf69cf40fc 66 struct MODE1
eisd 0:8edf69cf40fc 67 {
eisd 0:8edf69cf40fc 68 static const byte ADDR = 0x00;
eisd 0:8edf69cf40fc 69
eisd 0:8edf69cf40fc 70 static const byte OSC_OFF = 0x10;
eisd 0:8edf69cf40fc 71 static const byte SUB1 = 0x08;
eisd 0:8edf69cf40fc 72 static const byte SUB2 = 0x04;
eisd 0:8edf69cf40fc 73 static const byte SUB3 = 0x02;
eisd 0:8edf69cf40fc 74 static const byte ALLCALL = 0x01;
eisd 0:8edf69cf40fc 75 };
eisd 0:8edf69cf40fc 76
eisd 0:8edf69cf40fc 77 struct MODE2
eisd 0:8edf69cf40fc 78 {
eisd 0:8edf69cf40fc 79 static const byte ADDR = 0x01;
eisd 0:8edf69cf40fc 80
eisd 0:8edf69cf40fc 81 static const byte EFCLR = 0x80;
eisd 0:8edf69cf40fc 82 static const byte DMBLNK = 0x20;
eisd 0:8edf69cf40fc 83 static const byte OCH = 0x08;
eisd 0:8edf69cf40fc 84 };
eisd 0:8edf69cf40fc 85
eisd 0:8edf69cf40fc 86 struct PWM0
eisd 0:8edf69cf40fc 87 {
eisd 0:8edf69cf40fc 88 static const byte ADDR = 0x02;
eisd 0:8edf69cf40fc 89 };
eisd 0:8edf69cf40fc 90
eisd 0:8edf69cf40fc 91 struct PWM1
eisd 0:8edf69cf40fc 92 {
eisd 0:8edf69cf40fc 93 static const byte ADDR = 0x03;
eisd 0:8edf69cf40fc 94 };
eisd 0:8edf69cf40fc 95
eisd 0:8edf69cf40fc 96 struct PWM2
eisd 0:8edf69cf40fc 97 {
eisd 0:8edf69cf40fc 98 static const byte ADDR = 0x04;
eisd 0:8edf69cf40fc 99 };
eisd 0:8edf69cf40fc 100
eisd 0:8edf69cf40fc 101 struct PWM3
eisd 0:8edf69cf40fc 102 {
eisd 0:8edf69cf40fc 103 static const byte ADDR = 0x05;
eisd 0:8edf69cf40fc 104 };
eisd 0:8edf69cf40fc 105
eisd 0:8edf69cf40fc 106 struct PWM4
eisd 0:8edf69cf40fc 107 {
eisd 0:8edf69cf40fc 108 static const byte ADDR = 0x06;
eisd 0:8edf69cf40fc 109 };
eisd 0:8edf69cf40fc 110
eisd 0:8edf69cf40fc 111 struct PWM5
eisd 0:8edf69cf40fc 112 {
eisd 0:8edf69cf40fc 113 static const byte ADDR = 0x07;
eisd 0:8edf69cf40fc 114 };
eisd 0:8edf69cf40fc 115
eisd 0:8edf69cf40fc 116 struct PWM6
eisd 0:8edf69cf40fc 117 {
eisd 0:8edf69cf40fc 118 static const byte ADDR = 0x08;
eisd 0:8edf69cf40fc 119 };
eisd 0:8edf69cf40fc 120
eisd 0:8edf69cf40fc 121 struct PWM7
eisd 0:8edf69cf40fc 122 {
eisd 0:8edf69cf40fc 123 static const byte ADDR = 0x09;
eisd 0:8edf69cf40fc 124 };
eisd 0:8edf69cf40fc 125
eisd 0:8edf69cf40fc 126 struct GRPPWM
eisd 0:8edf69cf40fc 127 {
eisd 0:8edf69cf40fc 128 static const byte ADDR = 0x0a;
eisd 0:8edf69cf40fc 129 };
eisd 0:8edf69cf40fc 130
eisd 0:8edf69cf40fc 131 struct GRPFREQ
eisd 0:8edf69cf40fc 132 {
eisd 0:8edf69cf40fc 133 static const byte ADDR = 0x0b;
eisd 0:8edf69cf40fc 134 };
eisd 0:8edf69cf40fc 135
eisd 0:8edf69cf40fc 136 struct LEDOUT0
eisd 0:8edf69cf40fc 137 {
eisd 0:8edf69cf40fc 138 static const byte ADDR = 0x0c;
eisd 0:8edf69cf40fc 139 };
eisd 0:8edf69cf40fc 140
eisd 0:8edf69cf40fc 141 struct LEDOUT1
eisd 0:8edf69cf40fc 142 {
eisd 0:8edf69cf40fc 143 static const byte ADDR = 0x0d;
eisd 0:8edf69cf40fc 144 };
eisd 0:8edf69cf40fc 145
eisd 0:8edf69cf40fc 146 struct SUBADR1
eisd 0:8edf69cf40fc 147 {
eisd 0:8edf69cf40fc 148 static const byte ADDR = 0x0e;
eisd 0:8edf69cf40fc 149 };
eisd 0:8edf69cf40fc 150
eisd 0:8edf69cf40fc 151 struct SUBADR2
eisd 0:8edf69cf40fc 152 {
eisd 0:8edf69cf40fc 153 static const byte ADDR = 0x0f;
eisd 0:8edf69cf40fc 154 };
eisd 0:8edf69cf40fc 155
eisd 0:8edf69cf40fc 156 struct SUBADR3
eisd 0:8edf69cf40fc 157 {
eisd 0:8edf69cf40fc 158 static const byte ADDR = 0x10;
eisd 0:8edf69cf40fc 159 };
eisd 0:8edf69cf40fc 160
eisd 0:8edf69cf40fc 161 struct ALLCALLADR
eisd 0:8edf69cf40fc 162 {
eisd 0:8edf69cf40fc 163 static const byte ADDR = 0x11;
eisd 0:8edf69cf40fc 164 };
eisd 0:8edf69cf40fc 165
eisd 0:8edf69cf40fc 166 struct IREF
eisd 0:8edf69cf40fc 167 {
eisd 0:8edf69cf40fc 168 static const byte ADDR = 0x12;
eisd 0:8edf69cf40fc 169
eisd 0:8edf69cf40fc 170 static const byte CM = 0x80; // current multiplier
eisd 0:8edf69cf40fc 171 static const byte HC = 0x40; // subcurrent
eisd 0:8edf69cf40fc 172 };
eisd 0:8edf69cf40fc 173
eisd 0:8edf69cf40fc 174 struct EFLAG
eisd 0:8edf69cf40fc 175 {
eisd 0:8edf69cf40fc 176 static const byte ADDR = 0x13;
eisd 0:8edf69cf40fc 177 };
eisd 0:8edf69cf40fc 178 };
eisd 0:8edf69cf40fc 179
eisd 0:8edf69cf40fc 180 struct ERROR
eisd 0:8edf69cf40fc 181 {
eisd 0:8edf69cf40fc 182 static const uint8_t EINVAL = 2;
eisd 0:8edf69cf40fc 183 };
eisd 0:8edf69cf40fc 184
eisd 0:8edf69cf40fc 185 TLC59108(const PinName sda, const PinName scl, const byte selectable_address = 0):
eisd 0:8edf69cf40fc 186 addr(I2C_ADDR::BASE | selectable_address),
eisd 0:8edf69cf40fc 187 i2c(sda, scl) {
eisd 0:8edf69cf40fc 188 setRegister(REGISTER::MODE1::ADDR, REGISTER::MODE1::ALLCALL);
eisd 0:8edf69cf40fc 189 }
eisd 0:8edf69cf40fc 190
eisd 0:8edf69cf40fc 191 uint8_t setLedOutputMode(const uint8_t outputMode)
eisd 0:8edf69cf40fc 192 {
eisd 0:8edf69cf40fc 193 if(outputMode & 0xfc)
eisd 0:8edf69cf40fc 194 return ERROR::EINVAL;
eisd 0:8edf69cf40fc 195
eisd 0:8edf69cf40fc 196 byte regValue = (outputMode << 6) | (outputMode << 4) | (outputMode << 2) | outputMode;
eisd 0:8edf69cf40fc 197
eisd 0:8edf69cf40fc 198 uint8_t retVal = setRegister(REGISTER::LEDOUT0::ADDR, regValue);
eisd 0:8edf69cf40fc 199 retVal &= setRegister(REGISTER::LEDOUT1::ADDR, regValue);
eisd 0:8edf69cf40fc 200 return retVal;
eisd 0:8edf69cf40fc 201 }
eisd 0:8edf69cf40fc 202
eisd 0:8edf69cf40fc 203 uint8_t setBrightness(const uint8_t pwmChannel, const uint8_t dutyCycle)
eisd 0:8edf69cf40fc 204 {
eisd 0:8edf69cf40fc 205 if(pwmChannel > 7)
eisd 0:8edf69cf40fc 206 return ERROR::EINVAL;
eisd 0:8edf69cf40fc 207
eisd 0:8edf69cf40fc 208 return setRegister(REGISTER::PWM0::ADDR + pwmChannel, dutyCycle);
eisd 0:8edf69cf40fc 209 }
eisd 0:8edf69cf40fc 210
eisd 0:8edf69cf40fc 211 uint8_t setBrightness(const uint8_t dutyCycle)
eisd 0:8edf69cf40fc 212 {
eisd 0:8edf69cf40fc 213 uint8_t status = 0;
eisd 0:8edf69cf40fc 214 i2c.start();
eisd 0:8edf69cf40fc 215 status &= i2c.write(addr);
eisd 0:8edf69cf40fc 216 status &= i2c.write(REGISTER::PWM0::ADDR | AUTO_INCREMENT::IND);
eisd 0:8edf69cf40fc 217 for (uint8_t i = 0; i < NUM_CHANNELS; i++)
eisd 0:8edf69cf40fc 218 status &= i2c.write(dutyCycle);
eisd 0:8edf69cf40fc 219 i2c.stop();
eisd 0:8edf69cf40fc 220 return status;
eisd 0:8edf69cf40fc 221 }
eisd 0:8edf69cf40fc 222
eisd 1:b204db0e7687 223 uint8_t setBrightness(const byte dutyCycles[], const uint8_t length = NUM_CHANNELS)
eisd 0:8edf69cf40fc 224 {
eisd 1:b204db0e7687 225 return setRegisters(REGISTER::PWM0::ADDR, dutyCycles, length);
eisd 0:8edf69cf40fc 226 }
eisd 0:8edf69cf40fc 227
eisd 0:8edf69cf40fc 228 uint8_t setGroupBrightness(const uint8_t dutyCycle)
eisd 0:8edf69cf40fc 229 {
eisd 0:8edf69cf40fc 230 return setRegister(REGISTER::GRPPWM::ADDR, dutyCycle);
eisd 0:8edf69cf40fc 231 }
eisd 0:8edf69cf40fc 232
eisd 0:8edf69cf40fc 233 int setRegister(const byte reg, const byte value) {
eisd 0:8edf69cf40fc 234 char cmd[2] = { reg, value };
eisd 0:8edf69cf40fc 235 return i2c.write(addr, cmd, 2);
eisd 0:8edf69cf40fc 236 }
eisd 0:8edf69cf40fc 237
eisd 0:8edf69cf40fc 238 int setRegisters(const byte reg, const byte values[], const uint8_t length) {
eisd 0:8edf69cf40fc 239 uint8_t status = 0;
eisd 0:8edf69cf40fc 240 i2c.start();
eisd 0:8edf69cf40fc 241 status &= i2c.write(addr);
eisd 0:8edf69cf40fc 242 status &= i2c.write(reg | AUTO_INCREMENT::ALL);
eisd 0:8edf69cf40fc 243 for (uint8_t i = 0; i < length; i++)
eisd 0:8edf69cf40fc 244 status &= i2c.write(values[i]);
eisd 0:8edf69cf40fc 245 i2c.stop();
eisd 0:8edf69cf40fc 246 return status;
eisd 0:8edf69cf40fc 247 }
eisd 0:8edf69cf40fc 248
eisd 0:8edf69cf40fc 249 protected:
eisd 0:8edf69cf40fc 250 const static uint8_t NUM_CHANNELS = 8;
eisd 0:8edf69cf40fc 251 byte addr;
eisd 0:8edf69cf40fc 252 I2C i2c;
eisd 0:8edf69cf40fc 253 };
eisd 0:8edf69cf40fc 254
eisd 0:8edf69cf40fc 255 #endif