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

Dependents:   chuk

Revision:
0:8edf69cf40fc
Child:
1:b204db0e7687
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tlc59108.h	Wed Jan 04 06:15:55 2017 +0000
@@ -0,0 +1,236 @@
+#ifndef __TLC59108_H__
+#define __TLC59108_H__
+
+#include "mbed.h"
+
+class TLC59108
+{
+public:
+
+    typedef uint8_t byte;
+
+    // default I2C addresses
+    // datasheet, pp 12-13
+    struct I2C_ADDR
+    {
+        static const byte BASE = 0x80;
+        static const byte SWRESET = 0x4b;
+        static const byte ALLCALL = 0x90;
+        static const byte SUB1 = 0x92;
+        static const byte SUB2 = 0x94;
+        static const byte SUB3 = 0x98;
+    };
+
+    // register auto-increment modes for setting multiple registers
+    // datasheet, p 13
+    struct AUTO_INCREMENT
+    {
+        static const byte ALL = 0x80; // increment through all registers (for initial setup)
+        static const byte IND = 0xa0; // increment through individual brightness registers
+        static const byte GLOBAL = 0xc0; // increment through global control registers
+        static const byte INDGLOBAL = 0xe0; // increment through individual and global registers
+    };
+
+    struct LED_MODE
+    {
+        static const byte OFF = 0;
+        static const byte FULL_ON = 1;
+        static const byte PWM_IND = 2;
+        static const byte PWM_INDGRP = 3;
+    };
+
+    // register names
+    // datasheet, p 16
+    struct REGISTER
+    {
+    public:
+        struct MODE1
+        {
+            static const byte ADDR = 0x00;
+
+            static const byte OSC_OFF = 0x10;
+            static const byte SUB1 = 0x08;
+            static const byte SUB2 = 0x04;
+            static const byte SUB3 = 0x02;
+            static const byte ALLCALL = 0x01;
+        };
+
+        struct MODE2
+        {
+            static const byte ADDR = 0x01;
+
+            static const byte EFCLR = 0x80;
+            static const byte DMBLNK = 0x20;
+            static const byte OCH = 0x08;
+        };
+
+        struct PWM0
+        {
+            static const byte ADDR = 0x02;
+        };
+
+        struct PWM1
+        {
+            static const byte ADDR = 0x03;
+        };
+
+        struct PWM2
+        {
+            static const byte ADDR = 0x04;
+        };
+
+        struct PWM3
+        {
+            static const byte ADDR = 0x05;
+        };
+
+        struct PWM4
+        {
+            static const byte ADDR = 0x06;
+        };
+
+        struct PWM5
+        {
+            static const byte ADDR = 0x07;
+        };
+
+        struct PWM6
+        {
+            static const byte ADDR = 0x08;
+        };
+
+        struct PWM7
+        {
+            static const byte ADDR = 0x09;
+        };
+
+        struct GRPPWM
+        {
+            static const byte ADDR = 0x0a;
+        };
+
+        struct GRPFREQ
+        {
+            static const byte ADDR = 0x0b;
+        };
+
+        struct LEDOUT0
+        {
+            static const byte ADDR = 0x0c;
+        };
+
+        struct LEDOUT1
+        {
+            static const byte ADDR = 0x0d;
+        };
+
+        struct SUBADR1
+        {
+            static const byte ADDR = 0x0e;
+        };
+
+        struct SUBADR2
+        {
+            static const byte ADDR = 0x0f;
+        };
+
+        struct SUBADR3
+        {
+            static const byte ADDR = 0x10;
+        };
+
+        struct ALLCALLADR
+        {
+            static const byte ADDR = 0x11;
+        };
+
+        struct IREF
+        {
+            static const byte ADDR = 0x12;
+
+            static const byte CM = 0x80; // current multiplier
+            static const byte HC = 0x40; // subcurrent
+        };
+
+        struct EFLAG
+        {
+            static const byte ADDR = 0x13;
+        };
+    };
+
+    struct ERROR
+    {
+        static const uint8_t EINVAL = 2;
+    };
+
+    TLC59108(const PinName sda, const PinName scl, const byte selectable_address = 0):
+        addr(I2C_ADDR::BASE | selectable_address),
+        i2c(sda, scl) {
+        setRegister(REGISTER::MODE1::ADDR, REGISTER::MODE1::ALLCALL);
+    }
+
+    uint8_t setLedOutputMode(const uint8_t outputMode)
+    {
+        if(outputMode & 0xfc)
+            return ERROR::EINVAL;
+        
+        byte regValue = (outputMode << 6) | (outputMode << 4) | (outputMode << 2) | outputMode;
+        
+        uint8_t retVal = setRegister(REGISTER::LEDOUT0::ADDR, regValue);
+        retVal &= setRegister(REGISTER::LEDOUT1::ADDR, regValue);
+        return retVal;
+    }
+
+    uint8_t setBrightness(const uint8_t pwmChannel, const uint8_t dutyCycle)
+    {
+        if(pwmChannel > 7)
+            return ERROR::EINVAL;
+        
+        return setRegister(REGISTER::PWM0::ADDR + pwmChannel, dutyCycle);
+    }
+
+    uint8_t setBrightness(const uint8_t dutyCycle)
+    {
+        uint8_t status = 0;
+        i2c.start();
+        status &= i2c.write(addr);
+        status &= i2c.write(REGISTER::PWM0::ADDR | AUTO_INCREMENT::IND);
+        for (uint8_t i = 0; i < NUM_CHANNELS; i++)
+            status &= i2c.write(dutyCycle);
+        i2c.stop();
+        return status;
+    }
+    
+    uint8_t setBrightness(const byte dutyCycles[]) 
+    {
+        return setRegisters(REGISTER::PWM0::ADDR, dutyCycles, NUM_CHANNELS);
+    }
+
+    uint8_t setGroupBrightness(const uint8_t dutyCycle)
+    {
+        return setRegister(REGISTER::GRPPWM::ADDR, dutyCycle);
+    }
+
+    int setRegister(const byte reg, const byte value) {
+        char cmd[2] = { reg, value };
+        return i2c.write(addr, cmd, 2);
+    }
+    
+    int setRegisters(const byte reg, const byte values[], const uint8_t length) {
+        uint8_t status = 0;
+        i2c.start();
+        status &= i2c.write(addr);
+        status &= i2c.write(reg | AUTO_INCREMENT::ALL);
+        for (uint8_t i = 0; i < length; i++)
+            status &= i2c.write(values[i]);
+        i2c.stop();
+        return status;
+    }
+
+protected:
+    const static uint8_t NUM_CHANNELS = 8;
+    byte addr;
+    I2C i2c;
+};
+
+#endif
\ No newline at end of file