summaryrefslogtreecommitdiffstats
path: root/tinyusb/hw/bsp/ea4357/pca9532.c
blob: eae3805c236ee595918397068692db9c0789843d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*****************************************************************************
 *
 *   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();
}