tinyusb  0.4
Click here to lend your support to tinyusb donation and make a donation at pledgie.com
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
pca9532.c
1 /*****************************************************************************
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 #include "../../board.h"
28 
29 #if BOARD == BOARD_EA4357
30 
31 #include "lpc43xx_i2c.h"
32 #include "lpc43xx_cgu.h"
33 #include "lpc_types.h"
34 #include "pca9532.h"
35 
36 /******************************************************************************
37  * Defines and typedefs
38  *****************************************************************************/
39 
40 #define I2C_PORT (LPC_I2C0)
41 
42 #define LS_MODE_ON 0x01
43 #define LS_MODE_BLINK0 0x02
44 #define LS_MODE_BLINK1 0x03
45 
46 /******************************************************************************
47  * External global variables
48  *****************************************************************************/
49 
50 
51 /******************************************************************************
52  * Local variables
53  *****************************************************************************/
54 
55 static uint16_t blink0Shadow = 0;
56 static uint16_t blink1Shadow = 0;
57 static uint16_t ledStateShadow = 0;
58 
59 /******************************************************************************
60  * Local Functions
61  *****************************************************************************/
62 
63 static Status I2CWrite(uint32_t addr, uint8_t* buf, uint32_t len)
64 {
65  I2C_M_SETUP_Type i2cData;
66 
67  i2cData.sl_addr7bit = addr;
68  i2cData.tx_data = buf;
69  i2cData.tx_length = len;
70  i2cData.rx_data = NULL;
71  i2cData.rx_length = 0;
72  i2cData.retransmissions_max = 3;
73 
74  return I2C_MasterTransferData(I2C_PORT, &i2cData, I2C_TRANSFER_POLLING);
75 }
76 
77 static Status I2CRead(uint32_t addr, uint8_t* buf, uint32_t len)
78 {
79  I2C_M_SETUP_Type i2cData;
80 
81  i2cData.sl_addr7bit = addr;
82  i2cData.tx_data = NULL;
83  i2cData.tx_length = 0;
84  i2cData.rx_data = buf;
85  i2cData.rx_length = len;
86  i2cData.retransmissions_max = 3;
87 
88  return I2C_MasterTransferData(I2C_PORT, &i2cData, I2C_TRANSFER_POLLING);
89 }
90 
91 static void setLsStates(uint16_t states, uint8_t* ls, uint8_t mode)
92 {
93 #define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 )
94 
95  int i = 0;
96 
97  for (i = 0; i < 4; i++) {
98 
99  ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0)
100  | (IS_LED_SET(0x0002, states)*mode << 2)
101  | (IS_LED_SET(0x0004, states)*mode << 4)
102  | (IS_LED_SET(0x0008, states)*mode << 6) );
103 
104  states >>= 4;
105  }
106 }
107 
108 static void setLeds(void)
109 {
110  uint8_t buf[5];
111  uint8_t ls[4] = {0,0,0,0};
112  uint16_t states = ledStateShadow;
113 
114  /* LEDs in On/Off state */
115  setLsStates(states, ls, LS_MODE_ON);
116 
117  /* set the LEDs that should blink */
118  setLsStates(blink0Shadow, ls, LS_MODE_BLINK0);
119  setLsStates(blink1Shadow, ls, LS_MODE_BLINK1);
120 
121 
122  buf[0] = PCA9532_LS0 | PCA9532_AUTO_INC;
123  buf[1] = ls[0];
124  buf[2] = ls[1];
125  buf[3] = ls[2];
126  buf[4] = ls[3];
127  I2CWrite(PCA9532_I2C_ADDR, buf, 5);
128 }
129 
130 /******************************************************************************
131  * Public Functions
132  *****************************************************************************/
133 
134 /******************************************************************************
135  *
136  * Description:
137  * Initialize the PCA9532 Device
138  *
139  *****************************************************************************/
140 void pca9532_init (void)
141 {
142  /* nothing to initialize */
143 }
144 
145 /******************************************************************************
146  *
147  * Description:
148  * Get the LED states
149  *
150  * Params:
151  * [in] shadow - TRUE if the states should be retrieved from the shadow
152  * variables. The shadow variable are updated when any
153  * of setLeds, setBlink0Leds and/or setBlink1Leds are
154  * called.
155  *
156  * FALSE if the state should be retrieved from the PCA9532
157  * device. A blinkin LED may be reported as on or off
158  * depending on the state when calling the function.
159  *
160  * Returns:
161  * A mask where a 1 indicates that a LED is on (or blinking).
162  *
163  *****************************************************************************/
164 uint16_t pca9532_getLedState (uint32_t shadow)
165 {
166  uint8_t buf[2];
167  uint16_t ret = 0;
168 
169  if (shadow) {
170  /* a blink LED is reported as on*/
171  ret = (ledStateShadow | blink0Shadow | blink1Shadow);
172  }
173  else {
174 
175  /*
176  * A blinking LED may be reported as on or off depending on
177  * its state when reading the Input register.
178  */
179 
180  buf[0] = PCA9532_INPUT0;
181  I2CWrite(PCA9532_I2C_ADDR, buf, 1);
182 
183  I2CRead(PCA9532_I2C_ADDR, buf, 1);
184  ret = buf[0];
185 
186 
187  buf[0] = PCA9532_INPUT1;
188  I2CWrite(PCA9532_I2C_ADDR, buf, 1);
189 
190  I2CRead(PCA9532_I2C_ADDR, buf, 1);
191  ret |= (buf[0] << 8);
192 
193 
194  /* invert since LEDs are active low */
195  ret = ((~ret) & 0xFFFF);
196  }
197 
198  return (ret & ~PCA9532_NOT_USED);
199 }
200 
201 
202 /******************************************************************************
203  *
204  * Description:
205  * Set LED states (on or off).
206  *
207  * Params:
208  * [in] ledOnMask - The LEDs that should be turned on. This mask has
209  * priority over ledOffMask
210  * [in] ledOffMask - The LEDs that should be turned off.
211  *
212  *****************************************************************************/
213 void pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask)
214 {
215  /* turn off leds */
216  ledStateShadow &= (~(ledOffMask) & 0xffff);
217 
218  /* ledOnMask has priority over ledOffMask */
219  ledStateShadow |= ledOnMask;
220 
221  /* turn off blinking */
222  blink0Shadow &= (~(ledOffMask) & 0xffff);
223  blink1Shadow &= (~(ledOffMask) & 0xffff);
224 
225  setLeds();
226 }
227 
228 /******************************************************************************
229  *
230  * Description:
231  * Set the blink period for PWM0. Valid values are 0 - 255 where 0
232  * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz.
233  *
234  * Params:
235  * [in] period - the period for pwm0
236  *
237  *****************************************************************************/
238 void pca9532_setBlink0Period(uint8_t period)
239 {
240  uint8_t buf[2];
241 
242  buf[0] = PCA9532_PSC0;
243  buf[1] = period;
244  I2CWrite(PCA9532_I2C_ADDR, buf, 2);
245 }
246 
247 /******************************************************************************
248  *
249  * Description:
250  * Set the duty cycle for PWM0. Valid values are 0 - 100. 25 means the LED
251  * is on 25% of the period.
252  *
253  * Params:
254  * [in] duty - duty cycle
255  *
256  *****************************************************************************/
257 void pca9532_setBlink0Duty(uint8_t duty)
258 {
259  uint8_t buf[2];
260  uint32_t tmp = duty;
261  if (tmp > 100) {
262  tmp = 100;
263  }
264 
265  tmp = (256 * tmp)/100;
266 
267  buf[0] = PCA9532_PWM0;
268  buf[1] = tmp;
269  I2CWrite(PCA9532_I2C_ADDR, buf, 2);
270 }
271 
272 /******************************************************************************
273  *
274  * Description:
275  * Set the LEDs that should blink with rate and duty cycle from PWM0.
276  * Blinking is turned off with pca9532_setLeds.
277  *
278  * Params:
279  * [in] ledMask - LEDs that should blink.
280  *
281  *****************************************************************************/
282 void pca9532_setBlink0Leds(uint16_t ledMask)
283 {
284  blink0Shadow |= ledMask;
285  setLeds();
286 }
287 
288 /******************************************************************************
289  *
290  * Description:
291  * Set the blink period for PWM1. Valid values are 0 - 255 where 0
292  * means 152 Hz and 255 means 0.59 Hz. A value of 151 means 1 Hz.
293  *
294  * Params:
295  * [in] period - The period for PWM1
296  *
297  *****************************************************************************/
298 void pca9532_setBlink1Period(uint8_t period)
299 {
300  uint8_t buf[2];
301 
302  buf[0] = PCA9532_PSC1;
303  buf[1] = period;
304  I2CWrite(PCA9532_I2C_ADDR, buf, 2);
305 }
306 
307 /******************************************************************************
308  *
309  * Description:
310  * Set the duty cycle for PWM1. Valid values are 0 - 100. 25 means the LED
311  * is on 25% of the period.
312  *
313  * Params:
314  * [in] duty - duty cycle.
315  *
316  *****************************************************************************/
317 void pca9532_setBlink1Duty(uint8_t duty)
318 {
319  uint8_t buf[2];
320 
321  uint32_t tmp = duty;
322  if (tmp > 100) {
323  tmp = 100;
324  }
325 
326  tmp = (256 * tmp)/100;
327 
328  buf[0] = PCA9532_PWM1;
329  buf[1] = tmp;
330  I2CWrite(PCA9532_I2C_ADDR, buf, 2);
331 }
332 
333 /******************************************************************************
334  *
335  * Description:
336  * Set the LEDs that should blink with rate and duty cycle from PWM1.
337  * Blinking is turned off with pca9532_setLeds.
338  *
339  * Params:
340  * [in] ledMask - LEDs that should blink.
341  *
342  *****************************************************************************/
343 void pca9532_setBlink1Leds(uint16_t ledMask)
344 {
345  blink1Shadow |= ledMask;
346  setLeds();
347 }
348 
349 #endif