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:
Wed Jan 04 06:15:55 2017 +0000
Revision:
0:8edf69cf40fc
Child:
1:b204db0e7687
Working TLC59108 driver library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eisd 0:8edf69cf40fc 1 #ifndef __TLC59108_H__
eisd 0:8edf69cf40fc 2 #define __TLC59108_H__
eisd 0:8edf69cf40fc 3
eisd 0:8edf69cf40fc 4 #include "mbed.h"
eisd 0:8edf69cf40fc 5
eisd 0:8edf69cf40fc 6 class TLC59108
eisd 0:8edf69cf40fc 7 {
eisd 0:8edf69cf40fc 8 public:
eisd 0:8edf69cf40fc 9
eisd 0:8edf69cf40fc 10 typedef uint8_t byte;
eisd 0:8edf69cf40fc 11
eisd 0:8edf69cf40fc 12 // default I2C addresses
eisd 0:8edf69cf40fc 13 // datasheet, pp 12-13
eisd 0:8edf69cf40fc 14 struct I2C_ADDR
eisd 0:8edf69cf40fc 15 {
eisd 0:8edf69cf40fc 16 static const byte BASE = 0x80;
eisd 0:8edf69cf40fc 17 static const byte SWRESET = 0x4b;
eisd 0:8edf69cf40fc 18 static const byte ALLCALL = 0x90;
eisd 0:8edf69cf40fc 19 static const byte SUB1 = 0x92;
eisd 0:8edf69cf40fc 20 static const byte SUB2 = 0x94;
eisd 0:8edf69cf40fc 21 static const byte SUB3 = 0x98;
eisd 0:8edf69cf40fc 22 };
eisd 0:8edf69cf40fc 23
eisd 0:8edf69cf40fc 24 // register auto-increment modes for setting multiple registers
eisd 0:8edf69cf40fc 25 // datasheet, p 13
eisd 0:8edf69cf40fc 26 struct AUTO_INCREMENT
eisd 0:8edf69cf40fc 27 {
eisd 0:8edf69cf40fc 28 static const byte ALL = 0x80; // increment through all registers (for initial setup)
eisd 0:8edf69cf40fc 29 static const byte IND = 0xa0; // increment through individual brightness registers
eisd 0:8edf69cf40fc 30 static const byte GLOBAL = 0xc0; // increment through global control registers
eisd 0:8edf69cf40fc 31 static const byte INDGLOBAL = 0xe0; // increment through individual and global registers
eisd 0:8edf69cf40fc 32 };
eisd 0:8edf69cf40fc 33
eisd 0:8edf69cf40fc 34 struct LED_MODE
eisd 0:8edf69cf40fc 35 {
eisd 0:8edf69cf40fc 36 static const byte OFF = 0;
eisd 0:8edf69cf40fc 37 static const byte FULL_ON = 1;
eisd 0:8edf69cf40fc 38 static const byte PWM_IND = 2;
eisd 0:8edf69cf40fc 39 static const byte PWM_INDGRP = 3;
eisd 0:8edf69cf40fc 40 };
eisd 0:8edf69cf40fc 41
eisd 0:8edf69cf40fc 42 // register names
eisd 0:8edf69cf40fc 43 // datasheet, p 16
eisd 0:8edf69cf40fc 44 struct REGISTER
eisd 0:8edf69cf40fc 45 {
eisd 0:8edf69cf40fc 46 public:
eisd 0:8edf69cf40fc 47 struct MODE1
eisd 0:8edf69cf40fc 48 {
eisd 0:8edf69cf40fc 49 static const byte ADDR = 0x00;
eisd 0:8edf69cf40fc 50
eisd 0:8edf69cf40fc 51 static const byte OSC_OFF = 0x10;
eisd 0:8edf69cf40fc 52 static const byte SUB1 = 0x08;
eisd 0:8edf69cf40fc 53 static const byte SUB2 = 0x04;
eisd 0:8edf69cf40fc 54 static const byte SUB3 = 0x02;
eisd 0:8edf69cf40fc 55 static const byte ALLCALL = 0x01;
eisd 0:8edf69cf40fc 56 };
eisd 0:8edf69cf40fc 57
eisd 0:8edf69cf40fc 58 struct MODE2
eisd 0:8edf69cf40fc 59 {
eisd 0:8edf69cf40fc 60 static const byte ADDR = 0x01;
eisd 0:8edf69cf40fc 61
eisd 0:8edf69cf40fc 62 static const byte EFCLR = 0x80;
eisd 0:8edf69cf40fc 63 static const byte DMBLNK = 0x20;
eisd 0:8edf69cf40fc 64 static const byte OCH = 0x08;
eisd 0:8edf69cf40fc 65 };
eisd 0:8edf69cf40fc 66
eisd 0:8edf69cf40fc 67 struct PWM0
eisd 0:8edf69cf40fc 68 {
eisd 0:8edf69cf40fc 69 static const byte ADDR = 0x02;
eisd 0:8edf69cf40fc 70 };
eisd 0:8edf69cf40fc 71
eisd 0:8edf69cf40fc 72 struct PWM1
eisd 0:8edf69cf40fc 73 {
eisd 0:8edf69cf40fc 74 static const byte ADDR = 0x03;
eisd 0:8edf69cf40fc 75 };
eisd 0:8edf69cf40fc 76
eisd 0:8edf69cf40fc 77 struct PWM2
eisd 0:8edf69cf40fc 78 {
eisd 0:8edf69cf40fc 79 static const byte ADDR = 0x04;
eisd 0:8edf69cf40fc 80 };
eisd 0:8edf69cf40fc 81
eisd 0:8edf69cf40fc 82 struct PWM3
eisd 0:8edf69cf40fc 83 {
eisd 0:8edf69cf40fc 84 static const byte ADDR = 0x05;
eisd 0:8edf69cf40fc 85 };
eisd 0:8edf69cf40fc 86
eisd 0:8edf69cf40fc 87 struct PWM4
eisd 0:8edf69cf40fc 88 {
eisd 0:8edf69cf40fc 89 static const byte ADDR = 0x06;
eisd 0:8edf69cf40fc 90 };
eisd 0:8edf69cf40fc 91
eisd 0:8edf69cf40fc 92 struct PWM5
eisd 0:8edf69cf40fc 93 {
eisd 0:8edf69cf40fc 94 static const byte ADDR = 0x07;
eisd 0:8edf69cf40fc 95 };
eisd 0:8edf69cf40fc 96
eisd 0:8edf69cf40fc 97 struct PWM6
eisd 0:8edf69cf40fc 98 {
eisd 0:8edf69cf40fc 99 static const byte ADDR = 0x08;
eisd 0:8edf69cf40fc 100 };
eisd 0:8edf69cf40fc 101
eisd 0:8edf69cf40fc 102 struct PWM7
eisd 0:8edf69cf40fc 103 {
eisd 0:8edf69cf40fc 104 static const byte ADDR = 0x09;
eisd 0:8edf69cf40fc 105 };
eisd 0:8edf69cf40fc 106
eisd 0:8edf69cf40fc 107 struct GRPPWM
eisd 0:8edf69cf40fc 108 {
eisd 0:8edf69cf40fc 109 static const byte ADDR = 0x0a;
eisd 0:8edf69cf40fc 110 };
eisd 0:8edf69cf40fc 111
eisd 0:8edf69cf40fc 112 struct GRPFREQ
eisd 0:8edf69cf40fc 113 {
eisd 0:8edf69cf40fc 114 static const byte ADDR = 0x0b;
eisd 0:8edf69cf40fc 115 };
eisd 0:8edf69cf40fc 116
eisd 0:8edf69cf40fc 117 struct LEDOUT0
eisd 0:8edf69cf40fc 118 {
eisd 0:8edf69cf40fc 119 static const byte ADDR = 0x0c;
eisd 0:8edf69cf40fc 120 };
eisd 0:8edf69cf40fc 121
eisd 0:8edf69cf40fc 122 struct LEDOUT1
eisd 0:8edf69cf40fc 123 {
eisd 0:8edf69cf40fc 124 static const byte ADDR = 0x0d;
eisd 0:8edf69cf40fc 125 };
eisd 0:8edf69cf40fc 126
eisd 0:8edf69cf40fc 127 struct SUBADR1
eisd 0:8edf69cf40fc 128 {
eisd 0:8edf69cf40fc 129 static const byte ADDR = 0x0e;
eisd 0:8edf69cf40fc 130 };
eisd 0:8edf69cf40fc 131
eisd 0:8edf69cf40fc 132 struct SUBADR2
eisd 0:8edf69cf40fc 133 {
eisd 0:8edf69cf40fc 134 static const byte ADDR = 0x0f;
eisd 0:8edf69cf40fc 135 };
eisd 0:8edf69cf40fc 136
eisd 0:8edf69cf40fc 137 struct SUBADR3
eisd 0:8edf69cf40fc 138 {
eisd 0:8edf69cf40fc 139 static const byte ADDR = 0x10;
eisd 0:8edf69cf40fc 140 };
eisd 0:8edf69cf40fc 141
eisd 0:8edf69cf40fc 142 struct ALLCALLADR
eisd 0:8edf69cf40fc 143 {
eisd 0:8edf69cf40fc 144 static const byte ADDR = 0x11;
eisd 0:8edf69cf40fc 145 };
eisd 0:8edf69cf40fc 146
eisd 0:8edf69cf40fc 147 struct IREF
eisd 0:8edf69cf40fc 148 {
eisd 0:8edf69cf40fc 149 static const byte ADDR = 0x12;
eisd 0:8edf69cf40fc 150
eisd 0:8edf69cf40fc 151 static const byte CM = 0x80; // current multiplier
eisd 0:8edf69cf40fc 152 static const byte HC = 0x40; // subcurrent
eisd 0:8edf69cf40fc 153 };
eisd 0:8edf69cf40fc 154
eisd 0:8edf69cf40fc 155 struct EFLAG
eisd 0:8edf69cf40fc 156 {
eisd 0:8edf69cf40fc 157 static const byte ADDR = 0x13;
eisd 0:8edf69cf40fc 158 };
eisd 0:8edf69cf40fc 159 };
eisd 0:8edf69cf40fc 160
eisd 0:8edf69cf40fc 161 struct ERROR
eisd 0:8edf69cf40fc 162 {
eisd 0:8edf69cf40fc 163 static const uint8_t EINVAL = 2;
eisd 0:8edf69cf40fc 164 };
eisd 0:8edf69cf40fc 165
eisd 0:8edf69cf40fc 166 TLC59108(const PinName sda, const PinName scl, const byte selectable_address = 0):
eisd 0:8edf69cf40fc 167 addr(I2C_ADDR::BASE | selectable_address),
eisd 0:8edf69cf40fc 168 i2c(sda, scl) {
eisd 0:8edf69cf40fc 169 setRegister(REGISTER::MODE1::ADDR, REGISTER::MODE1::ALLCALL);
eisd 0:8edf69cf40fc 170 }
eisd 0:8edf69cf40fc 171
eisd 0:8edf69cf40fc 172 uint8_t setLedOutputMode(const uint8_t outputMode)
eisd 0:8edf69cf40fc 173 {
eisd 0:8edf69cf40fc 174 if(outputMode & 0xfc)
eisd 0:8edf69cf40fc 175 return ERROR::EINVAL;
eisd 0:8edf69cf40fc 176
eisd 0:8edf69cf40fc 177 byte regValue = (outputMode << 6) | (outputMode << 4) | (outputMode << 2) | outputMode;
eisd 0:8edf69cf40fc 178
eisd 0:8edf69cf40fc 179 uint8_t retVal = setRegister(REGISTER::LEDOUT0::ADDR, regValue);
eisd 0:8edf69cf40fc 180 retVal &= setRegister(REGISTER::LEDOUT1::ADDR, regValue);
eisd 0:8edf69cf40fc 181 return retVal;
eisd 0:8edf69cf40fc 182 }
eisd 0:8edf69cf40fc 183
eisd 0:8edf69cf40fc 184 uint8_t setBrightness(const uint8_t pwmChannel, const uint8_t dutyCycle)
eisd 0:8edf69cf40fc 185 {
eisd 0:8edf69cf40fc 186 if(pwmChannel > 7)
eisd 0:8edf69cf40fc 187 return ERROR::EINVAL;
eisd 0:8edf69cf40fc 188
eisd 0:8edf69cf40fc 189 return setRegister(REGISTER::PWM0::ADDR + pwmChannel, dutyCycle);
eisd 0:8edf69cf40fc 190 }
eisd 0:8edf69cf40fc 191
eisd 0:8edf69cf40fc 192 uint8_t setBrightness(const uint8_t dutyCycle)
eisd 0:8edf69cf40fc 193 {
eisd 0:8edf69cf40fc 194 uint8_t status = 0;
eisd 0:8edf69cf40fc 195 i2c.start();
eisd 0:8edf69cf40fc 196 status &= i2c.write(addr);
eisd 0:8edf69cf40fc 197 status &= i2c.write(REGISTER::PWM0::ADDR | AUTO_INCREMENT::IND);
eisd 0:8edf69cf40fc 198 for (uint8_t i = 0; i < NUM_CHANNELS; i++)
eisd 0:8edf69cf40fc 199 status &= i2c.write(dutyCycle);
eisd 0:8edf69cf40fc 200 i2c.stop();
eisd 0:8edf69cf40fc 201 return status;
eisd 0:8edf69cf40fc 202 }
eisd 0:8edf69cf40fc 203
eisd 0:8edf69cf40fc 204 uint8_t setBrightness(const byte dutyCycles[])
eisd 0:8edf69cf40fc 205 {
eisd 0:8edf69cf40fc 206 return setRegisters(REGISTER::PWM0::ADDR, dutyCycles, NUM_CHANNELS);
eisd 0:8edf69cf40fc 207 }
eisd 0:8edf69cf40fc 208
eisd 0:8edf69cf40fc 209 uint8_t setGroupBrightness(const uint8_t dutyCycle)
eisd 0:8edf69cf40fc 210 {
eisd 0:8edf69cf40fc 211 return setRegister(REGISTER::GRPPWM::ADDR, dutyCycle);
eisd 0:8edf69cf40fc 212 }
eisd 0:8edf69cf40fc 213
eisd 0:8edf69cf40fc 214 int setRegister(const byte reg, const byte value) {
eisd 0:8edf69cf40fc 215 char cmd[2] = { reg, value };
eisd 0:8edf69cf40fc 216 return i2c.write(addr, cmd, 2);
eisd 0:8edf69cf40fc 217 }
eisd 0:8edf69cf40fc 218
eisd 0:8edf69cf40fc 219 int setRegisters(const byte reg, const byte values[], const uint8_t length) {
eisd 0:8edf69cf40fc 220 uint8_t status = 0;
eisd 0:8edf69cf40fc 221 i2c.start();
eisd 0:8edf69cf40fc 222 status &= i2c.write(addr);
eisd 0:8edf69cf40fc 223 status &= i2c.write(reg | AUTO_INCREMENT::ALL);
eisd 0:8edf69cf40fc 224 for (uint8_t i = 0; i < length; i++)
eisd 0:8edf69cf40fc 225 status &= i2c.write(values[i]);
eisd 0:8edf69cf40fc 226 i2c.stop();
eisd 0:8edf69cf40fc 227 return status;
eisd 0:8edf69cf40fc 228 }
eisd 0:8edf69cf40fc 229
eisd 0:8edf69cf40fc 230 protected:
eisd 0:8edf69cf40fc 231 const static uint8_t NUM_CHANNELS = 8;
eisd 0:8edf69cf40fc 232 byte addr;
eisd 0:8edf69cf40fc 233 I2C i2c;
eisd 0:8edf69cf40fc 234 };
eisd 0:8edf69cf40fc 235
eisd 0:8edf69cf40fc 236 #endif