PCA9532 I2C LED Dimmer. Library files only, no mbed.lib or main.cpp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCA9532.cpp Source File

PCA9532.cpp

00001 /* mbed PCF9532 LED Driver Library
00002  *
00003  * Copyright (c) 2010, cstyles (http://mbed.org)
00004  *
00005  * Permission is hereby granted, free of charge, to any person obtaining a copy
00006  * of this software and associated documentation files (the "Software"), to deal
00007  * in the Software without restriction, including without limitation the rights
00008  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009  * copies of the Software, and to permit persons to whom the Software is
00010  * furnished to do so, subject to the following conditions:
00011  *
00012  * The above copyright notice and this permission notice shall be included in
00013  * all copies or substantial portions of the Software.
00014  *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021  * THE SOFTWARE.
00022  */
00023 
00024 
00025 #include "PCA9532.h"
00026 #include "mbed.h"
00027 
00028 /*
00029  Constructor, pin names for I2C and the I2C addrss of the device
00030  */
00031 PCA9532::PCA9532(PinName scl, PinName sda, int addr)
00032         : _i2c(scl, sda) {
00033 
00034     _i2c.frequency(1000000);
00035 
00036     _addr = addr;
00037 
00038 }
00039 
00040 
00041 
00042 
00043 
00044 /*
00045  Set the period
00046  */
00047 int PCA9532::Period (int channel, float period) {
00048 
00049     char reg = 0;
00050     
00051     if (channel == 0) {
00052        reg = PCA9532_REG_PSC0;
00053     } else if (channel == 1) {
00054        reg = PCA9532_REG_PSC1;
00055     } else {
00056         return (1);
00057     }
00058 
00059     if (period > 1.0) {
00060         period = 255;
00061     } else if ( period < 0.0 ) {
00062         period = 0;
00063     } else {
00064         period = 256 * period;
00065     }
00066 
00067     _write(reg, period);
00068     return(0);
00069 
00070 }
00071 
00072 
00073 /*
00074  Set the duty cycle
00075  */
00076 int PCA9532::Duty (int channel, float d) {
00077 
00078     char duty = 0;
00079     char reg = 0;
00080     
00081     if (channel == 0) {
00082        reg = PCA9532_REG_PWM0;
00083     } else if (channel == 1) {
00084        reg = PCA9532_REG_PWM1;
00085     } else {
00086         return (1);
00087     }
00088 
00089     if (d > 1.0) {
00090         duty = 255;
00091     } else if ( d < 0.0 ) {
00092         duty = 0;
00093     } else {
00094         duty = 256 * d;
00095     }
00096 
00097     _write(reg, duty);
00098     return(0);
00099 
00100 }
00101 
00102 /*
00103  Set each of the LEDs in this mask to the give mode
00104  Loop through the mask calling SetLed on each match
00105  alt_mode specifies the mode of the non-Matches of SetMode
00106  */
00107 int PCA9532::SetMode (int mask, int mode) {
00108     if ( (mode < 0) || (mode > 3) ) {
00109         return(1);
00110     } else {
00111         for (int i=0 ; i < 16 ; i++ ) {
00112 
00113             // if this matches, set the LED to the mode
00114             if (mask & (0x1 << i)) {
00115                 SetLed(i,mode);
00116             }
00117         }
00118     }
00119     return(0);
00120 }
00121 
00122 
00123 
00124 /*
00125  led is in the range 0-15
00126  mode is inthe range 0-3
00127  */
00128 int PCA9532::SetLed(int led, int mode) {
00129 
00130     int reg = 0;
00131     int offset = (led % 4);
00132 
00133     printf("\nSetLed(%d,%d)\n", led, mode);
00134 
00135     // makesure mode is within bounds
00136     if ( (mode < 0) || (mode > 3) ) {
00137         printf("Error : Invalid mode supplied\n");
00138         return(1);
00139     }
00140 
00141     // determine which register this is,
00142     if (led < 4) {
00143         reg = PCA9532_REG_LS0;
00144     } else if ( (led > 3) && (led < 8) ) {
00145         reg = PCA9532_REG_LS1;
00146     } else if ( (led > 7) && (led < 12) ) {
00147         reg = PCA9532_REG_LS2;
00148     } else if ( (led > 11) && (led < 16) ) {
00149         reg = PCA9532_REG_LS3;
00150     } else {
00151         return(1);
00152     }
00153 
00154     // read the current status of the register
00155     char regval = _read(reg);
00156 
00157     // clear the two bit slice at the calculated offset
00158     regval &= ~(0x3 << (2 * offset));
00159 
00160     // now OR in the mode, shifted by 2*offset
00161     regval |= (mode << (2 * offset));
00162 
00163     // write the new value back
00164     _write(reg, regval);
00165 
00166     return(0);
00167 }
00168 
00169 
00170 
00171 // private functions for low level IO
00172 
00173 void PCA9532::_write(int reg, int data) {
00174     char args[2];
00175     args[0] = reg;
00176     args[1] = data;
00177     _i2c.write(_addr, args,2);
00178 }
00179 
00180 int PCA9532::_read(int reg) {
00181     char args[2];
00182     args[0] = reg;
00183     _i2c.write(_addr, args, 1);
00184     _i2c.read(_addr, args, 1);
00185     return(args[0]);
00186 }
00187 
00188 
00189 
00190 
00191