353 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			353 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*****************************************************************************
 | ||
|  |  * | ||
|  |  *   Copyright(C) 2011, Embedded Artists AB | ||
|  |  *   All rights reserved. | ||
|  |  * | ||
|  |  ****************************************************************************** | ||
|  |  * Software that is described herein is for illustrative purposes only | ||
|  |  * which provides customers with programming information regarding the | ||
|  |  * products. This software is supplied "AS IS" without any warranties. | ||
|  |  * Embedded Artists AB assumes no responsibility or liability for the | ||
|  |  * use of the software, conveys no license or title under any patent, | ||
|  |  * copyright, or mask work right to the product. Embedded Artists AB | ||
|  |  * reserves the right to make changes in the software without | ||
|  |  * notification. Embedded Artists AB also make no representation or | ||
|  |  * warranty that such application will be suitable for the specified | ||
|  |  * use without further testing or modification. | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * NOTE: I2C must have been initialized before calling any functions in this | ||
|  |  * file. | ||
|  |  */ | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * Includes | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | //#include "board.h"
 | ||
|  | #include "chip.h"
 | ||
|  | 
 | ||
|  | #include "pca9532.h"
 | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * Defines and typedefs | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | #define I2C_PORT (LPC_I2C0)
 | ||
|  | 
 | ||
|  | #define LS_MODE_ON     0x01
 | ||
|  | #define LS_MODE_BLINK0 0x02
 | ||
|  | #define LS_MODE_BLINK1 0x03
 | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * External global variables | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * Local variables | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | static uint16_t blink0Shadow = 0; | ||
|  | static uint16_t blink1Shadow = 0; | ||
|  | static uint16_t ledStateShadow = 0; | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * Local Functions | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | static Status I2CWrite(uint32_t addr, uint8_t* buf, uint32_t len)  | ||
|  | { | ||
|  | 	I2CM_XFER_T i2cData; | ||
|  | 
 | ||
|  | 	i2cData.slaveAddr = addr; | ||
|  | 	i2cData.options = 0; | ||
|  | 	i2cData.status = 0; | ||
|  | 	i2cData.txBuff = buf; | ||
|  | 	i2cData.txSz = len; | ||
|  | 	i2cData.rxBuff = NULL; | ||
|  | 	i2cData.rxSz = 0; | ||
|  | 
 | ||
|  | 	if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) { | ||
|  | 		return ERROR; | ||
|  | 	} | ||
|  | 	return SUCCESS; | ||
|  | } | ||
|  | 
 | ||
|  | static Status I2CRead(uint32_t addr, uint8_t* buf, uint32_t len)  | ||
|  | { | ||
|  | 	I2CM_XFER_T i2cData; | ||
|  | 
 | ||
|  | 	i2cData.slaveAddr = addr; | ||
|  | 	i2cData.options = 0; | ||
|  | 	i2cData.status = 0; | ||
|  | 	i2cData.txBuff = NULL; | ||
|  | 	i2cData.txSz = 0; | ||
|  | 	i2cData.rxBuff = buf; | ||
|  | 	i2cData.rxSz = len; | ||
|  | 
 | ||
|  | 	if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) { | ||
|  | 		return ERROR; | ||
|  | 	} | ||
|  | 	return SUCCESS; | ||
|  | } | ||
|  | 
 | ||
|  | static void setLsStates(uint16_t states, uint8_t* ls, uint8_t mode) | ||
|  | { | ||
|  | #define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 )
 | ||
|  | 
 | ||
|  |     int i = 0; | ||
|  | 
 | ||
|  |     for (i = 0; i < 4; i++) { | ||
|  | 
 | ||
|  |         ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0) | ||
|  |                 | (IS_LED_SET(0x0002, states)*mode << 2) | ||
|  |                 | (IS_LED_SET(0x0004, states)*mode << 4) | ||
|  |                 | (IS_LED_SET(0x0008, states)*mode << 6) ); | ||
|  | 
 | ||
|  |         states >>= 4; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | static void setLeds(void) | ||
|  | { | ||
|  |     uint8_t buf[5]; | ||
|  |     uint8_t ls[4] = {0,0,0,0}; | ||
|  |     uint16_t states = ledStateShadow; | ||
|  | 
 | ||
|  |     /* LEDs in On/Off state */ | ||
|  |     setLsStates(states, ls, LS_MODE_ON); | ||
|  | 
 | ||
|  |     /* set the LEDs that should blink */ | ||
|  |     setLsStates(blink0Shadow, ls, LS_MODE_BLINK0); | ||
|  |     setLsStates(blink1Shadow, ls, LS_MODE_BLINK1); | ||
|  | 
 | ||
|  | 
 | ||
|  |     buf[0] = PCA9532_LS0 | PCA9532_AUTO_INC; | ||
|  |     buf[1] = ls[0]; | ||
|  |     buf[2] = ls[1]; | ||
|  |     buf[3] = ls[2]; | ||
|  |     buf[4] = ls[3]; | ||
|  |     I2CWrite(PCA9532_I2C_ADDR, buf, 5); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * Public Functions | ||
|  |  *****************************************************************************/ | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Initialize the PCA9532 Device | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_init (void) | ||
|  | { | ||
|  |     /* nothing to initialize */ | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Get the LED states | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  shadow  - TRUE if the states should be retrieved from the shadow | ||
|  |  *                    variables. The shadow variable are updated when any | ||
|  |  *                    of setLeds, setBlink0Leds and/or setBlink1Leds are | ||
|  |  *                    called. | ||
|  |  * | ||
|  |  *                    FALSE if the state should be retrieved from the PCA9532 | ||
|  |  *                    device. A blinkin LED may be reported as on or off | ||
|  |  *                    depending on the state when calling the function. | ||
|  |  * | ||
|  |  * Returns: | ||
|  |  *      A mask where a 1 indicates that a LED is on (or blinking). | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | uint16_t pca9532_getLedState (uint32_t shadow) | ||
|  | { | ||
|  |     uint8_t buf[2]; | ||
|  |     uint16_t ret = 0; | ||
|  | 
 | ||
|  |     if (shadow) { | ||
|  |         /* a blink LED is reported as on*/ | ||
|  |         ret = (ledStateShadow | blink0Shadow | blink1Shadow); | ||
|  |     } | ||
|  |     else { | ||
|  | 
 | ||
|  |         /*
 | ||
|  |          * A blinking LED may be reported as on or off depending on | ||
|  |          * its state when reading the Input register. | ||
|  |          */ | ||
|  |          | ||
|  |         buf[0] = PCA9532_INPUT0; | ||
|  |         I2CWrite(PCA9532_I2C_ADDR, buf, 1); | ||
|  | 
 | ||
|  |         I2CRead(PCA9532_I2C_ADDR, buf, 1); | ||
|  |         ret = buf[0]; | ||
|  | 
 | ||
|  | 
 | ||
|  |         buf[0] = PCA9532_INPUT1; | ||
|  |         I2CWrite(PCA9532_I2C_ADDR, buf, 1); | ||
|  | 
 | ||
|  |         I2CRead(PCA9532_I2C_ADDR, buf, 1); | ||
|  |         ret |= (buf[0] << 8); | ||
|  | 
 | ||
|  | 
 | ||
|  |         /* invert since LEDs are active low */ | ||
|  |         ret = ((~ret) & 0xFFFF); | ||
|  |     } | ||
|  | 
 | ||
|  |     return (ret & ~PCA9532_NOT_USED); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set LED states (on or off). | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  ledOnMask  - The LEDs that should be turned on. This mask has | ||
|  |  *                       priority over ledOffMask | ||
|  |  *    [in]  ledOffMask - The LEDs that should be turned off. | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask) | ||
|  | { | ||
|  |     /* turn off leds */ | ||
|  |     ledStateShadow &= (~(ledOffMask) & 0xffff); | ||
|  | 
 | ||
|  |     /* ledOnMask has priority over ledOffMask */ | ||
|  |     ledStateShadow |= ledOnMask; | ||
|  | 
 | ||
|  |     /* turn off blinking */ | ||
|  |     blink0Shadow &= (~(ledOffMask) & 0xffff); | ||
|  |     blink1Shadow &= (~(ledOffMask) & 0xffff); | ||
|  | 
 | ||
|  |     setLeds(); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set the blink period for PWM0. Valid values are 0 - 255 where 0 | ||
|  |  *    means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz. | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  period  - the period for pwm0 | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setBlink0Period(uint8_t period) | ||
|  | { | ||
|  |     uint8_t buf[2]; | ||
|  | 
 | ||
|  |     buf[0] = PCA9532_PSC0; | ||
|  |     buf[1] = period; | ||
|  |     I2CWrite(PCA9532_I2C_ADDR, buf, 2); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set the duty cycle for PWM0. Valid values are 0 - 100. 25 means the LED | ||
|  |  *    is on 25% of the period. | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  duty  - duty cycle | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setBlink0Duty(uint8_t duty) | ||
|  | { | ||
|  |     uint8_t buf[2]; | ||
|  |     uint32_t tmp = duty; | ||
|  |     if (tmp > 100) { | ||
|  |         tmp = 100; | ||
|  |     } | ||
|  | 
 | ||
|  |     tmp = (256 * tmp)/100; | ||
|  | 
 | ||
|  |     buf[0] = PCA9532_PWM0; | ||
|  |     buf[1] = tmp; | ||
|  |     I2CWrite(PCA9532_I2C_ADDR, buf, 2); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set the LEDs that should blink with rate and duty cycle from PWM0. | ||
|  |  *    Blinking is turned off with pca9532_setLeds. | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  ledMask  - LEDs that should blink. | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setBlink0Leds(uint16_t ledMask) | ||
|  | { | ||
|  |     blink0Shadow |= ledMask; | ||
|  |     setLeds(); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set the blink period for PWM1. Valid values are 0 - 255 where 0 | ||
|  |  *    means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz. | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  period  - The period for PWM1 | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setBlink1Period(uint8_t period) | ||
|  | { | ||
|  |     uint8_t buf[2]; | ||
|  | 
 | ||
|  |     buf[0] = PCA9532_PSC1; | ||
|  |     buf[1] = period; | ||
|  |     I2CWrite(PCA9532_I2C_ADDR, buf, 2); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set the duty cycle for PWM1. Valid values are 0 - 100. 25 means the LED | ||
|  |  *    is on 25% of the period. | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  duty  - duty cycle. | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setBlink1Duty(uint8_t duty) | ||
|  | { | ||
|  |     uint8_t buf[2]; | ||
|  | 
 | ||
|  |     uint32_t tmp = duty; | ||
|  |     if (tmp > 100) { | ||
|  |         tmp = 100; | ||
|  |     } | ||
|  | 
 | ||
|  |     tmp = (256 * tmp)/100; | ||
|  | 
 | ||
|  |     buf[0] = PCA9532_PWM1; | ||
|  |     buf[1] = tmp; | ||
|  |     I2CWrite(PCA9532_I2C_ADDR, buf, 2); | ||
|  | } | ||
|  | 
 | ||
|  | /******************************************************************************
 | ||
|  |  * | ||
|  |  * Description: | ||
|  |  *    Set the LEDs that should blink with rate and duty cycle from PWM1. | ||
|  |  *    Blinking is turned off with pca9532_setLeds. | ||
|  |  * | ||
|  |  * Params: | ||
|  |  *    [in]  ledMask  - LEDs that should blink. | ||
|  |  * | ||
|  |  *****************************************************************************/ | ||
|  | void pca9532_setBlink1Leds(uint16_t ledMask) | ||
|  | { | ||
|  |     blink1Shadow |= ledMask; | ||
|  |     setLeds(); | ||
|  | } |