Using the I2C LED driver on the Embedded Artists baseboard to control the LEDS.

Dependencies:   mbed

Committer:
chris
Date:
Tue Mar 02 07:40:02 2010 +0000
Revision:
0:5d07670e5b83

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chris 0:5d07670e5b83 1 /*
chris 0:5d07670e5b83 2 PCA9532
chris 0:5d07670e5b83 3 (c) 2009, cstyles
chris 0:5d07670e5b83 4 */
chris 0:5d07670e5b83 5
chris 0:5d07670e5b83 6 #include "PCA9532.h"
chris 0:5d07670e5b83 7 #include "mbed.h"
chris 0:5d07670e5b83 8
chris 0:5d07670e5b83 9 /*
chris 0:5d07670e5b83 10 Constructor, pin names for I2C and the I2C addrss of the device
chris 0:5d07670e5b83 11 */
chris 0:5d07670e5b83 12
chris 0:5d07670e5b83 13
chris 0:5d07670e5b83 14 PCA9532::PCA9532(PinName scl, PinName sda, int addr)
chris 0:5d07670e5b83 15 : _i2c(scl, sda) {
chris 0:5d07670e5b83 16
chris 0:5d07670e5b83 17 _addr = addr;
chris 0:5d07670e5b83 18
chris 0:5d07670e5b83 19 }
chris 0:5d07670e5b83 20
chris 0:5d07670e5b83 21
chris 0:5d07670e5b83 22
chris 0:5d07670e5b83 23
chris 0:5d07670e5b83 24
chris 0:5d07670e5b83 25 /*
chris 0:5d07670e5b83 26 force the LEDs on or off according to thier corresponding bits
chris 0:5d07670e5b83 27 in the vector
chris 0:5d07670e5b83 28 */
chris 0:5d07670e5b83 29
chris 0:5d07670e5b83 30 void PCA9532::write (int leds) {
chris 0:5d07670e5b83 31
chris 0:5d07670e5b83 32 // cycle through the array
chris 0:5d07670e5b83 33 for (int i=0; i < 16; i++) {
chris 0:5d07670e5b83 34
chris 0:5d07670e5b83 35 // if the ith bit is '1'
chris 0:5d07670e5b83 36 if (leds & (0x1 << i)) {
chris 0:5d07670e5b83 37 _rmw(i,PCA9532_MODE_SET);
chris 0:5d07670e5b83 38 }
chris 0:5d07670e5b83 39
chris 0:5d07670e5b83 40 else {
chris 0:5d07670e5b83 41 _rmw(i,PCA9532_MODE_CLEAR);
chris 0:5d07670e5b83 42 }
chris 0:5d07670e5b83 43 }
chris 0:5d07670e5b83 44 }
chris 0:5d07670e5b83 45
chris 0:5d07670e5b83 46
chris 0:5d07670e5b83 47
chris 0:5d07670e5b83 48 /*
chris 0:5d07670e5b83 49 this is one hot encoding for the LED array
chris 0:5d07670e5b83 50 any bit set will have it's corresponding LED switched on
chris 0:5d07670e5b83 51 */
chris 0:5d07670e5b83 52
chris 0:5d07670e5b83 53 void PCA9532::set (int leds) {
chris 0:5d07670e5b83 54 for (int i=0; i < 16; i++) {
chris 0:5d07670e5b83 55 if (leds & (0x1 << i)) {
chris 0:5d07670e5b83 56 _rmw(i,PCA9532_MODE_SET);
chris 0:5d07670e5b83 57 }
chris 0:5d07670e5b83 58 }
chris 0:5d07670e5b83 59 }
chris 0:5d07670e5b83 60
chris 0:5d07670e5b83 61
chris 0:5d07670e5b83 62 void PCA9532::clear (int leds) {
chris 0:5d07670e5b83 63 for (int i=0; i < 16; i++) {
chris 0:5d07670e5b83 64 if (leds & (0x1 << i)) {
chris 0:5d07670e5b83 65 _rmw(i,PCA9532_MODE_CLEAR);
chris 0:5d07670e5b83 66 }
chris 0:5d07670e5b83 67 }
chris 0:5d07670e5b83 68 }
chris 0:5d07670e5b83 69
chris 0:5d07670e5b83 70
chris 0:5d07670e5b83 71 void PCA9532::pwm0 (int leds) {
chris 0:5d07670e5b83 72 for (int i=0; i < 16; i++) {
chris 0:5d07670e5b83 73 if (leds & (0x1 << i)) {
chris 0:5d07670e5b83 74 _rmw(i,PCA9532_MODE_PWM0);
chris 0:5d07670e5b83 75 }
chris 0:5d07670e5b83 76 }
chris 0:5d07670e5b83 77 }
chris 0:5d07670e5b83 78
chris 0:5d07670e5b83 79
chris 0:5d07670e5b83 80 void PCA9532::pwm1 (int leds) {
chris 0:5d07670e5b83 81 for (int i=0; i < 16; i++) {
chris 0:5d07670e5b83 82 if (leds & (0x1 << i)) {
chris 0:5d07670e5b83 83 _rmw(i,PCA9532_MODE_PWM1);
chris 0:5d07670e5b83 84 }
chris 0:5d07670e5b83 85 }
chris 0:5d07670e5b83 86 }
chris 0:5d07670e5b83 87
chris 0:5d07670e5b83 88
chris 0:5d07670e5b83 89 void PCA9532::duty0 (float d) {
chris 0:5d07670e5b83 90
chris 0:5d07670e5b83 91 char duty = 0;
chris 0:5d07670e5b83 92
chris 0:5d07670e5b83 93 if (d > 1.0) { duty = 255; }
chris 0:5d07670e5b83 94 else if ( d < 0.0 ) { duty = 0; }
chris 0:5d07670e5b83 95 else { duty = 256 * d; }
chris 0:5d07670e5b83 96
chris 0:5d07670e5b83 97 _write(PCA9532_REG_PWM0,duty);
chris 0:5d07670e5b83 98
chris 0:5d07670e5b83 99 }
chris 0:5d07670e5b83 100
chris 0:5d07670e5b83 101
chris 0:5d07670e5b83 102 void PCA9532::duty1 (float d) {
chris 0:5d07670e5b83 103
chris 0:5d07670e5b83 104 char duty = 0;
chris 0:5d07670e5b83 105
chris 0:5d07670e5b83 106 if (d > 1.0) { duty = 255; }
chris 0:5d07670e5b83 107 else if ( d < 0.0 ) { duty = 0; }
chris 0:5d07670e5b83 108 else { duty = 256 * d; }
chris 0:5d07670e5b83 109
chris 0:5d07670e5b83 110 _write(PCA9532_REG_PWM1,duty);
chris 0:5d07670e5b83 111
chris 0:5d07670e5b83 112 }
chris 0:5d07670e5b83 113
chris 0:5d07670e5b83 114
chris 0:5d07670e5b83 115
chris 0:5d07670e5b83 116
chris 0:5d07670e5b83 117
chris 0:5d07670e5b83 118
chris 0:5d07670e5b83 119
chris 0:5d07670e5b83 120 /*
chris 0:5d07670e5b83 121 led is in the range 0-15
chris 0:5d07670e5b83 122 mode is inthe range 0-3
chris 0:5d07670e5b83 123 */
chris 0:5d07670e5b83 124
chris 0:5d07670e5b83 125 void PCA9532::_rmw(int led, int mode) {
chris 0:5d07670e5b83 126
chris 0:5d07670e5b83 127 int reg = 0;
chris 0:5d07670e5b83 128 int offset = (led % 4);
chris 0:5d07670e5b83 129
chris 0:5d07670e5b83 130 // makesure mode is within bounds
chris 0:5d07670e5b83 131 if ( (mode < 0) || (mode > 3) ) {
chris 0:5d07670e5b83 132 return;
chris 0:5d07670e5b83 133 }
chris 0:5d07670e5b83 134
chris 0:5d07670e5b83 135
chris 0:5d07670e5b83 136 // determine which register this is,
chris 0:5d07670e5b83 137 if (led < 4) {
chris 0:5d07670e5b83 138 reg = PCA9532_REG_LS0;}
chris 0:5d07670e5b83 139
chris 0:5d07670e5b83 140 else if ( (led > 3) && (led < 8) ) {
chris 0:5d07670e5b83 141 reg = PCA9532_REG_LS1;}
chris 0:5d07670e5b83 142
chris 0:5d07670e5b83 143 else if ( (led > 7) && (led < 12) ) {
chris 0:5d07670e5b83 144 reg = PCA9532_REG_LS2;}
chris 0:5d07670e5b83 145
chris 0:5d07670e5b83 146 else if ( (led > 11) && (led < 16) ) {
chris 0:5d07670e5b83 147 reg = PCA9532_REG_LS3;}
chris 0:5d07670e5b83 148
chris 0:5d07670e5b83 149 else { return; }
chris 0:5d07670e5b83 150
chris 0:5d07670e5b83 151 // read the current status of the register
chris 0:5d07670e5b83 152 char regval = _read(reg);
chris 0:5d07670e5b83 153
chris 0:5d07670e5b83 154 // clear the two bit slice at the calculated offset
chris 0:5d07670e5b83 155 regval &= ~(0x3 << (2 * offset));
chris 0:5d07670e5b83 156
chris 0:5d07670e5b83 157 // now OR in the mode, shifted by 2 8 offset
chris 0:5d07670e5b83 158 regval |= (mode << (2 * offset));
chris 0:5d07670e5b83 159
chris 0:5d07670e5b83 160 // write this back
chris 0:5d07670e5b83 161
chris 0:5d07670e5b83 162 _write(reg,regval);
chris 0:5d07670e5b83 163
chris 0:5d07670e5b83 164 return;
chris 0:5d07670e5b83 165 }
chris 0:5d07670e5b83 166
chris 0:5d07670e5b83 167
chris 0:5d07670e5b83 168 void PCA9532::_write(int reg, int data) {
chris 0:5d07670e5b83 169 char args[2];
chris 0:5d07670e5b83 170 args[0] = reg;
chris 0:5d07670e5b83 171 args[1] = data;
chris 0:5d07670e5b83 172 _i2c.write(_addr,args,2);
chris 0:5d07670e5b83 173 }
chris 0:5d07670e5b83 174
chris 0:5d07670e5b83 175
chris 0:5d07670e5b83 176 int PCA9532::_read(int reg) {
chris 0:5d07670e5b83 177 char args[2];
chris 0:5d07670e5b83 178 args[0] = reg;
chris 0:5d07670e5b83 179 _i2c.write(_addr,args,2);
chris 0:5d07670e5b83 180 return(args[1]);
chris 0:5d07670e5b83 181 }
chris 0:5d07670e5b83 182
chris 0:5d07670e5b83 183
chris 0:5d07670e5b83 184
chris 0:5d07670e5b83 185
chris 0:5d07670e5b83 186