blob: eae3805c236ee595918397068692db9c0789843d [file] [log] [blame]
Austin Schuh41baf202022-01-01 14:33:40 -08001/*****************************************************************************
2 *
3 * Copyright(C) 2011, Embedded Artists AB
4 * All rights reserved.
5 *
6 ******************************************************************************
7 * Software that is described herein is for illustrative purposes only
8 * which provides customers with programming information regarding the
9 * products. This software is supplied "AS IS" without any warranties.
10 * Embedded Artists AB assumes no responsibility or liability for the
11 * use of the software, conveys no license or title under any patent,
12 * copyright, or mask work right to the product. Embedded Artists AB
13 * reserves the right to make changes in the software without
14 * notification. Embedded Artists AB also make no representation or
15 * warranty that such application will be suitable for the specified
16 * use without further testing or modification.
17 *****************************************************************************/
18
19/*
20 * NOTE: I2C must have been initialized before calling any functions in this
21 * file.
22 */
23
24/******************************************************************************
25 * Includes
26 *****************************************************************************/
27
28//#include "board.h"
29#include "chip.h"
30
31#include "pca9532.h"
32
33/******************************************************************************
34 * Defines and typedefs
35 *****************************************************************************/
36
37#define I2C_PORT (LPC_I2C0)
38
39#define LS_MODE_ON 0x01
40#define LS_MODE_BLINK0 0x02
41#define LS_MODE_BLINK1 0x03
42
43/******************************************************************************
44 * External global variables
45 *****************************************************************************/
46
47
48/******************************************************************************
49 * Local variables
50 *****************************************************************************/
51
52static uint16_t blink0Shadow = 0;
53static uint16_t blink1Shadow = 0;
54static uint16_t ledStateShadow = 0;
55
56/******************************************************************************
57 * Local Functions
58 *****************************************************************************/
59
60static Status I2CWrite(uint32_t addr, uint8_t* buf, uint32_t len)
61{
62 I2CM_XFER_T i2cData;
63
64 i2cData.slaveAddr = addr;
65 i2cData.options = 0;
66 i2cData.status = 0;
67 i2cData.txBuff = buf;
68 i2cData.txSz = len;
69 i2cData.rxBuff = NULL;
70 i2cData.rxSz = 0;
71
72 if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) {
73 return ERROR;
74 }
75 return SUCCESS;
76}
77
78static Status I2CRead(uint32_t addr, uint8_t* buf, uint32_t len)
79{
80 I2CM_XFER_T i2cData;
81
82 i2cData.slaveAddr = addr;
83 i2cData.options = 0;
84 i2cData.status = 0;
85 i2cData.txBuff = NULL;
86 i2cData.txSz = 0;
87 i2cData.rxBuff = buf;
88 i2cData.rxSz = len;
89
90 if (Chip_I2CM_XferBlocking(LPC_I2C0, &i2cData) == 0) {
91 return ERROR;
92 }
93 return SUCCESS;
94}
95
96static void setLsStates(uint16_t states, uint8_t* ls, uint8_t mode)
97{
98#define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 )
99
100 int i = 0;
101
102 for (i = 0; i < 4; i++) {
103
104 ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0)
105 | (IS_LED_SET(0x0002, states)*mode << 2)
106 | (IS_LED_SET(0x0004, states)*mode << 4)
107 | (IS_LED_SET(0x0008, states)*mode << 6) );
108
109 states >>= 4;
110 }
111}
112
113static void setLeds(void)
114{
115 uint8_t buf[5];
116 uint8_t ls[4] = {0,0,0,0};
117 uint16_t states = ledStateShadow;
118
119 /* LEDs in On/Off state */
120 setLsStates(states, ls, LS_MODE_ON);
121
122 /* set the LEDs that should blink */
123 setLsStates(blink0Shadow, ls, LS_MODE_BLINK0);
124 setLsStates(blink1Shadow, ls, LS_MODE_BLINK1);
125
126
127 buf[0] = PCA9532_LS0 | PCA9532_AUTO_INC;
128 buf[1] = ls[0];
129 buf[2] = ls[1];
130 buf[3] = ls[2];
131 buf[4] = ls[3];
132 I2CWrite(PCA9532_I2C_ADDR, buf, 5);
133}
134
135/******************************************************************************
136 * Public Functions
137 *****************************************************************************/
138
139/******************************************************************************
140 *
141 * Description:
142 * Initialize the PCA9532 Device
143 *
144 *****************************************************************************/
145void pca9532_init (void)
146{
147 /* nothing to initialize */
148}
149
150/******************************************************************************
151 *
152 * Description:
153 * Get the LED states
154 *
155 * Params:
156 * [in] shadow - TRUE if the states should be retrieved from the shadow
157 * variables. The shadow variable are updated when any
158 * of setLeds, setBlink0Leds and/or setBlink1Leds are
159 * called.
160 *
161 * FALSE if the state should be retrieved from the PCA9532
162 * device. A blinkin LED may be reported as on or off
163 * depending on the state when calling the function.
164 *
165 * Returns:
166 * A mask where a 1 indicates that a LED is on (or blinking).
167 *
168 *****************************************************************************/
169uint16_t pca9532_getLedState (uint32_t shadow)
170{
171 uint8_t buf[2];
172 uint16_t ret = 0;
173
174 if (shadow) {
175 /* a blink LED is reported as on*/
176 ret = (ledStateShadow | blink0Shadow | blink1Shadow);
177 }
178 else {
179
180 /*
181 * A blinking LED may be reported as on or off depending on
182 * its state when reading the Input register.
183 */
184
185 buf[0] = PCA9532_INPUT0;
186 I2CWrite(PCA9532_I2C_ADDR, buf, 1);
187
188 I2CRead(PCA9532_I2C_ADDR, buf, 1);
189 ret = buf[0];
190
191
192 buf[0] = PCA9532_INPUT1;
193 I2CWrite(PCA9532_I2C_ADDR, buf, 1);
194
195 I2CRead(PCA9532_I2C_ADDR, buf, 1);
196 ret |= (buf[0] << 8);
197
198
199 /* invert since LEDs are active low */
200 ret = ((~ret) & 0xFFFF);
201 }
202
203 return (ret & ~PCA9532_NOT_USED);
204}
205
206
207/******************************************************************************
208 *
209 * Description:
210 * Set LED states (on or off).
211 *
212 * Params:
213 * [in] ledOnMask - The LEDs that should be turned on. This mask has
214 * priority over ledOffMask
215 * [in] ledOffMask - The LEDs that should be turned off.
216 *
217 *****************************************************************************/
218void pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask)
219{
220 /* turn off leds */
221 ledStateShadow &= (~(ledOffMask) & 0xffff);
222
223 /* ledOnMask has priority over ledOffMask */
224 ledStateShadow |= ledOnMask;
225
226 /* turn off blinking */
227 blink0Shadow &= (~(ledOffMask) & 0xffff);
228 blink1Shadow &= (~(ledOffMask) & 0xffff);
229
230 setLeds();
231}
232
233/******************************************************************************
234 *
235 * Description:
236 * Set the blink period for PWM0. Valid values are 0 - 255 where 0
237 * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz.
238 *
239 * Params:
240 * [in] period - the period for pwm0
241 *
242 *****************************************************************************/
243void pca9532_setBlink0Period(uint8_t period)
244{
245 uint8_t buf[2];
246
247 buf[0] = PCA9532_PSC0;
248 buf[1] = period;
249 I2CWrite(PCA9532_I2C_ADDR, buf, 2);
250}
251
252/******************************************************************************
253 *
254 * Description:
255 * Set the duty cycle for PWM0. Valid values are 0 - 100. 25 means the LED
256 * is on 25% of the period.
257 *
258 * Params:
259 * [in] duty - duty cycle
260 *
261 *****************************************************************************/
262void pca9532_setBlink0Duty(uint8_t duty)
263{
264 uint8_t buf[2];
265 uint32_t tmp = duty;
266 if (tmp > 100) {
267 tmp = 100;
268 }
269
270 tmp = (256 * tmp)/100;
271
272 buf[0] = PCA9532_PWM0;
273 buf[1] = tmp;
274 I2CWrite(PCA9532_I2C_ADDR, buf, 2);
275}
276
277/******************************************************************************
278 *
279 * Description:
280 * Set the LEDs that should blink with rate and duty cycle from PWM0.
281 * Blinking is turned off with pca9532_setLeds.
282 *
283 * Params:
284 * [in] ledMask - LEDs that should blink.
285 *
286 *****************************************************************************/
287void pca9532_setBlink0Leds(uint16_t ledMask)
288{
289 blink0Shadow |= ledMask;
290 setLeds();
291}
292
293/******************************************************************************
294 *
295 * Description:
296 * Set the blink period for PWM1. Valid values are 0 - 255 where 0
297 * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz.
298 *
299 * Params:
300 * [in] period - The period for PWM1
301 *
302 *****************************************************************************/
303void pca9532_setBlink1Period(uint8_t period)
304{
305 uint8_t buf[2];
306
307 buf[0] = PCA9532_PSC1;
308 buf[1] = period;
309 I2CWrite(PCA9532_I2C_ADDR, buf, 2);
310}
311
312/******************************************************************************
313 *
314 * Description:
315 * Set the duty cycle for PWM1. Valid values are 0 - 100. 25 means the LED
316 * is on 25% of the period.
317 *
318 * Params:
319 * [in] duty - duty cycle.
320 *
321 *****************************************************************************/
322void pca9532_setBlink1Duty(uint8_t duty)
323{
324 uint8_t buf[2];
325
326 uint32_t tmp = duty;
327 if (tmp > 100) {
328 tmp = 100;
329 }
330
331 tmp = (256 * tmp)/100;
332
333 buf[0] = PCA9532_PWM1;
334 buf[1] = tmp;
335 I2CWrite(PCA9532_I2C_ADDR, buf, 2);
336}
337
338/******************************************************************************
339 *
340 * Description:
341 * Set the LEDs that should blink with rate and duty cycle from PWM1.
342 * Blinking is turned off with pca9532_setLeds.
343 *
344 * Params:
345 * [in] ledMask - LEDs that should blink.
346 *
347 *****************************************************************************/
348void pca9532_setBlink1Leds(uint16_t ledMask)
349{
350 blink1Shadow |= ledMask;
351 setLeds();
352}