Chris Styles
/
EA_PCA9532
Example code and library for the PCF9532 I2C LED driver on the Embedded Artists baseboard
PCA9532.cpp
- Committer:
- chris
- Date:
- 2010-04-27
- Revision:
- 0:a64165168954
File content as of revision 0:a64165168954:
/* mbed PCF9532 LED Driver Library * * Copyright (c) 2010, cstyles (http://mbed.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "PCA9532.h" #include "mbed.h" /* Constructor, pin names for I2C and the I2C addrss of the device */ PCA9532::PCA9532(PinName scl, PinName sda, int addr) : _i2c(scl, sda) { _i2c.frequency(1000000); _addr = addr; } /* Set the period */ int PCA9532::Period (int channel, float period) { char reg = 0; if (channel == 0) { reg = PCA9532_REG_PSC0; } else if (channel == 1) { reg = PCA9532_REG_PSC1; } else { return (1); } if (period > 1.0) { period = 255; } else if ( period < 0.0 ) { period = 0; } else { period = 256 * period; } _write(reg, period); return(0); } /* Set the duty cycle */ int PCA9532::Duty (int channel, float d) { char duty = 0; char reg = 0; if (channel == 0) { reg = PCA9532_REG_PWM0; } else if (channel == 1) { reg = PCA9532_REG_PWM1; } else { return (1); } if (d > 1.0) { duty = 255; } else if ( d < 0.0 ) { duty = 0; } else { duty = 256 * d; } _write(reg, duty); return(0); } /* Set each of the LEDs in this mask to the give mode Loop through the mask calling SetLed on each match alt_mode specifies the mode of the non-Matches of SetMode */ int PCA9532::SetMode (int mask, int mode) { if ( (mode < 0) || (mode > 3) ) { return(1); } else { for (int i=0 ; i < 16 ; i++ ) { // if this matches, set the LED to the mode if (mask & (0x1 << i)) { SetLed(i,mode); } } } return(0); } /* led is in the range 0-15 mode is inthe range 0-3 */ int PCA9532::SetLed(int led, int mode) { int reg = 0; int offset = (led % 4); printf("\nSetLed(%d,%d)\n", led, mode); // makesure mode is within bounds if ( (mode < 0) || (mode > 3) ) { printf("Error : Invalid mode supplied\n"); return(1); } // determine which register this is, if (led < 4) { reg = PCA9532_REG_LS0; } else if ( (led > 3) && (led < 8) ) { reg = PCA9532_REG_LS1; } else if ( (led > 7) && (led < 12) ) { reg = PCA9532_REG_LS2; } else if ( (led > 11) && (led < 16) ) { reg = PCA9532_REG_LS3; } else { return(1); } // read the current status of the register char regval = _read(reg); // clear the two bit slice at the calculated offset regval &= ~(0x3 << (2 * offset)); // now OR in the mode, shifted by 2*offset regval |= (mode << (2 * offset)); // write the new value back _write(reg, regval); return(0); } // private functions for low level IO void PCA9532::_write(int reg, int data) { char args[2]; args[0] = reg; args[1] = data; _i2c.write(_addr, args,2); } int PCA9532::_read(int reg) { char args[2]; args[0] = reg; _i2c.write(_addr, args, 1); _i2c.read(_addr, args, 1); return(args[0]); }