2018-12-03 17:23:59 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2023-03-17 10:12:49 +01:00
|
|
|
static Status I2CWrite(uint32_t addr, uint8_t* buf, uint32_t len)
|
2018-12-03 17:23:59 +01:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-03-17 10:12:49 +01:00
|
|
|
static Status I2CRead(uint32_t addr, uint8_t* buf, uint32_t len)
|
2018-12-03 17:23:59 +01:00
|
|
|
{
|
|
|
|
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.
|
|
|
|
*/
|
2023-03-17 10:12:49 +01:00
|
|
|
|
2018-12-03 17:23:59 +01:00
|
|
|
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();
|
|
|
|
}
|