Subversion Repositories seema-scanner

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 jakw 1
/*
2
 * API.cpp
3
 *
4
 * This module provides C callable APIs for each of the command supported by LightCrafter4500 platform and detailed in the programmer's guide.
5
 *
6
 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
7
 * ALL RIGHTS RESERVED
8
 *
9
*/
10
 
11
#include "API.h"
12
#include "string.h"
13
#include "usb.h"
14
#include "Common.h"
15
#include <stdlib.h>
16
 
17
extern unsigned char OutputBuffer[];
18
extern unsigned char InputBuffer[];
19
 
20
CmdFormat CmdList[255] =
21
{
22
    {   0x1A,  0x00,  0x01   },      //SOURCE_SEL,
23
    {   0x1A,  0x02,  0x01   },      //PIXEL_FORMAT,
24
    {   0x1A,  0x03,  0x01   },      //CLK_SEL,
25
    {   0x1A,  0x37,  0x01   },      //CHANNEL_SWAP,
26
    {   0x1A,  0x04,  0x01   },      //FPD_MODE,
27
    {   0,  0,  0   },      //CURTAIN_COLOR,
28
    {   0x02,  0x00,  0x01   },      //POWER_CONTROL,
29
    {   0x10,  0x08,  0x01   },      //FLIP_LONG,
30
    {   0x10,  0x09,  0x01   },      //FLIP_SHORT,
31
    {   0x12,  0x03,  0x01   },      //TPG_SEL,
32
    {   0x1A,  0x05,  0x01   },      //PWM_INVERT,
33
    {   0x1A,  0x07,  0x01   },      //LED_ENABLE,
34
    {   0x02,  0x05,  0x00   },      //GET_VERSION,
35
    {   0x08,  0x02,  0x00   },      //SW_RESET,
36
    {   0,  0,  0   },      //DMD_PARK,
37
    {   0,  0,  0   },      //BUFFER_FREEZE,
38
    {   0x1A,  0x0A,  0x00   },      //STATUS_HW,
39
    {   0x1A,  0x0B,  0x00   },      //STATUS_SYS,
40
    {   0x1A,  0x0C,  0x00   },      //STATUS_MAIN,
41
    {   0,  0,  0   },      //CSC_DATA,
42
    {   0,  0,  0   },      //GAMMA_CTL,
43
    {   0,  0,  0   },      //BC_CTL,
44
    {   0x1A,  0x10,  0x01   },      //PWM_ENABLE,
45
    {   0x1A,  0x11,  0x06   },      //PWM_SETUP,
46
    {   0x1A,  0x12,  0x05   },      //PWM_CAPTURE_CONFIG,
47
    {   0x1A,  0x38,  0x02   },      //GPIO_CONFIG,
48
    {   0x0B,  0x01,  0x03   },      //LED_CURRENT,
49
    {   0x10,  0x00,  0x10   },      //DISP_CONFIG,
50
    {   0,  0,  0   },      //TEMP_CONFIG,
51
    {   0,  0,  0   },      //TEMP_READ,
52
    {   0x1A,  0x16,  0x09   },      //MEM_CONTROL,
53
    {   0,  0,  0   },      //I2C_CONTROL,
54
    {   0x1A,  0x1A,  0x01   },      //LUT_VALID,
55
    {   0x1A,  0x1B,  0x01   },      //DISP_MODE,
56
    {   0x1A,  0x1D,  0x03   },      //TRIG_OUT1_CTL,
57
    {   0x1A,  0x1E,  0x03   },      //TRIG_OUT2_CTL,
58
    {   0x1A,  0x1F,  0x02   },      //RED_STROBE_DLY,
59
    {   0x1A,  0x20,  0x02   },      //GRN_STROBE_DLY,
60
    {   0x1A,  0x21,  0x02   },      //BLU_STROBE_DLY,
61
    {   0x1A,  0x22,  0x01   },      //PAT_DISP_MODE,
62
    {   0x1A,  0x23,  0x01   },      //PAT_TRIG_MODE,
63
    {   0x1A,  0x24,  0x01   },      //PAT_START_STOP,
64
    {   0,  0,  0   },      //BUFFER_SWAP,
65
    {   0,  0,  0   },      //BUFFER_WR_DISABLE,
66
    {   0,  0,  0   },      //CURRENT_RD_BUFFER,
67
    {   0x1A,  0x29,  0x08   },      //PAT_EXPO_PRD,
68
    {   0x1A,  0x30,  0x01   },      //INVERT_DATA,
69
    {   0x1A,  0x31,  0x04   },      //PAT_CONFIG,
70
    {   0x1A,  0x32,  0x01   },      //MBOX_ADDRESS,
71
    {   0x1A,  0x33,  0x01   },      //MBOX_CONTROL,
72
    {   0x1A,  0x34,  0x00   },      //MBOX_DATA,
73
    {   0x1A,  0x35,  0x04   },      //TRIG_IN1_DELAY,
74
    {   0,  0,  0   },      //TRIG_IN2_CONTROL,
75
    {   0x1A,  0x39,  0x01   },      //SPLASH_LOAD,
76
    {   0x1A,  0x3A,  0x02   },      //SPLASH_LOAD_TIMING,
77
    {   0x08,  0x07,  0x03   },      //GPCLK_CONFIG,
78
    {   0,  0,  0   },      //PULSE_GPIO_23,
79
    {   0,  0,  0   },      //ENABLE_LCR_DEBUG,
80
    {   0x12,  0x04,  0x0C   },      //TPG_COLOR,
81
    {   0x1A,  0x13,  0x05   },     //PWM_CAPTURE_READ,
82
    {   0x30,  0x01,  0x00   },     //PROG_MODE,
83
    {   0x00,  0x00,  0x00   },     //BL_STATUS
84
    {   0x00,  0x23,  0x01   },     //BL_SPL_MODE
85
    {   0x00,  0x15,  0x01   },     //BL_GET_MANID,
86
    {   0x00,  0x15,  0x01   },     //BL_GET_DEVID,
87
    {   0x00,  0x15,  0x01   },     //BL_GET_CHKSUM,
88
    {   0x00,  0x29,  0x04   },     //BL_SETSECTADDR,
89
    {   0x00,  0x28,  0x00   },     //BL_SECT_ERASE,
90
    {   0x00,  0x2C,  0x04   },     //BL_SET_DNLDSIZE,
91
    {   0x00,  0x25,  0x00   },     //BL_DNLD_DATA,
92
    {   0x00,  0x2F,  0x01   },     //BL_FLASH_TYPE,
93
    {   0x00,  0x26,  0x00   },     //BL_CALC_CHKSUM,
94
    {   0x00,  0x30,  0x01   }     //BL_PROG_MODE,
95
};
96
 
97
static unsigned char seqNum=0;
98
static unsigned int PatLut[128] = {0};
99
static unsigned int PatLutIndex = 0;
100
 
101
int LCR_Write()
102
{
103
    return USB_Write();
104
}
105
 
106
int LCR_Read()
107
{
108
    int ret_val;
109
    hidMessageStruct *pMsg = (hidMessageStruct *)InputBuffer;
110
    if(USB_Write() > 0)
111
    {
112
        ret_val =  USB_Read();
113
 
114
        if((pMsg->head.flags.nack == 1) || (pMsg->head.length == 0))
115
            return -2;
116
        else
117
            return ret_val;
118
    }
119
    return -1;
120
}
121
 
122
int LCR_ContinueRead()
123
{
124
    return USB_Read();
125
}
126
 
127
int LCR_SendMsg(hidMessageStruct *pMsg)
128
{
129
    int maxDataSize = USB_MAX_PACKET_SIZE-sizeof(pMsg->head);
130
    int dataBytesSent = MIN(pMsg->head.length, maxDataSize);    //Send all data or max possible
131
 
132
    OutputBuffer[0]=0; // First byte is the report number
133
    memcpy(&OutputBuffer[1], pMsg, (sizeof(pMsg->head) + dataBytesSent));
134
 
135
    if(LCR_Write() < 0)
136
        return -1;
137
 
138
    //dataBytesSent = maxDataSize;
139
 
140
    while(dataBytesSent < pMsg->head.length)
141
    {
142
        memcpy(&OutputBuffer[1], &pMsg->text.data[dataBytesSent], USB_MAX_PACKET_SIZE);
143
        if(LCR_Write() < 0)
144
            return -1;
145
        dataBytesSent += USB_MAX_PACKET_SIZE;
146
    }
147
    return dataBytesSent+sizeof(pMsg->head);
148
}
149
 
150
int LCR_PrepReadCmd(LCR_CMD cmd)
151
{
152
    hidMessageStruct msg;
153
 
154
    msg.head.flags.rw = 1; //Read
155
    msg.head.flags.reply = 1; //Host wants a reply from device
156
    msg.head.flags.dest = 0; //Projector Control Endpoint
157
    msg.head.flags.reserved = 0;
158
    msg.head.flags.nack = 0;
159
    msg.head.seq = 0;
160
 
161
    msg.text.cmd = (CmdList[cmd].CMD2 << 8) | CmdList[cmd].CMD3;
162
    msg.head.length = 2;
163
 
164
    if(cmd == BL_GET_MANID)
165
    {
166
        msg.text.data[2] = 0x0C;
167
        msg.head.length += 1;
168
    }
169
    else if (cmd == BL_GET_DEVID)
170
    {
171
        msg.text.data[2] = 0x0D;
172
        msg.head.length += 1;
173
    }
174
    else if (cmd == BL_GET_CHKSUM)
175
    {
176
        msg.text.data[2] = 0x00;
177
        msg.head.length += 1;
178
    }
179
 
180
    OutputBuffer[0]=0; // First byte is the report number
181
    memcpy(&OutputBuffer[1], &msg, (sizeof(msg.head)+sizeof(msg.text.cmd) + msg.head.length));
182
    return 0;
183
}
184
 
185
int LCR_PrepReadCmdWithParam(LCR_CMD cmd, unsigned char param)
186
{
187
    hidMessageStruct msg;
188
 
189
    msg.head.flags.rw = 1; //Read
190
    msg.head.flags.reply = 1; //Host wants a reply from device
191
    msg.head.flags.dest = 0; //Projector Control Endpoint
192
    msg.head.flags.reserved = 0;
193
    msg.head.flags.nack = 0;
194
    msg.head.seq = 0;
195
 
196
    msg.text.cmd = (CmdList[cmd].CMD2 << 8) | CmdList[cmd].CMD3;
197
    msg.head.length = 3;
198
 
199
    msg.text.data[2] = param;
200
 
201
    OutputBuffer[0]=0; // First byte is the report number
202
    memcpy(&OutputBuffer[1], &msg, (sizeof(msg.head)+sizeof(msg.text.cmd) + msg.head.length));
203
    return 0;
204
}
205
 
206
int LCR_PrepMemReadCmd(unsigned int addr)
207
{
208
    hidMessageStruct msg;
209
 
210
    msg.head.flags.rw = 1; //Read
211
    msg.head.flags.reply = 1; //Host wants a reply from device
212
    msg.head.flags.dest = 0; //Projector Control Endpoint
213
    msg.head.flags.reserved = 0;
214
    msg.head.flags.nack = 0;
215
    msg.head.seq = 0;
216
 
217
    msg.text.cmd = (CmdList[MEM_CONTROL].CMD2 << 8) | CmdList[MEM_CONTROL].CMD3;
218
    msg.head.length = 6;
219
 
220
    msg.text.data[2] = addr;
221
    msg.text.data[3] = addr >>8;
222
    msg.text.data[4] = addr >>16;
223
    msg.text.data[5] = addr >>24;
224
 
225
    OutputBuffer[0]=0; // First byte is the report number
226
    memcpy(&OutputBuffer[1], &msg, (sizeof(msg.head)+sizeof(msg.text.cmd) + msg.head.length));
227
    return 0;
228
}
229
 
230
int LCR_PrepWriteCmd(hidMessageStruct *pMsg, LCR_CMD cmd)
231
{
232
    pMsg->head.flags.rw = 0; //Write
233
    pMsg->head.flags.reply = 0; //Host wants a reply from device
234
    pMsg->head.flags.dest = 0; //Projector Control Endpoint
235
    pMsg->head.flags.reserved = 0;
236
    pMsg->head.flags.nack = 0;
237
    pMsg->head.seq = seqNum++;
238
 
239
    pMsg->text.cmd = (CmdList[cmd].CMD2 << 8) | CmdList[cmd].CMD3;
240
    pMsg->head.length = CmdList[cmd].len + 2;
241
 
242
    return 0;
243
}
244
 
245
int LCR_GetVersion(unsigned int *pApp_ver, unsigned int *pAPI_ver, unsigned int *pSWConfig_ver, unsigned int *pSeqConfig_ver)
246
{
247
    hidMessageStruct msg;
248
 
249
    LCR_PrepReadCmd(GET_VERSION);
250
 
251
    if(LCR_Read() > 0)
252
    {
253
        memcpy(&msg, InputBuffer, 65);
254
 
255
        *pApp_ver = *(unsigned int *)&msg.text.data[0];
256
        *pAPI_ver = *(unsigned int *)&msg.text.data[4];
257
        *pSWConfig_ver = *(unsigned int *)&msg.text.data[8];
258
        *pSeqConfig_ver = *(unsigned int *)&msg.text.data[12];
259
        return 0;
260
    }
261
    return -1;
262
}
263
 
264
int LCR_GetLedEnables(bool *pSeqCtrl, bool *pRed, bool *pGreen, bool *pBlue)
265
{
266
    hidMessageStruct msg;
267
 
268
    LCR_PrepReadCmd(LED_ENABLE);
269
 
270
    if(LCR_Read() > 0)
271
    {
272
        memcpy(&msg, InputBuffer, 65);
273
 
274
        if(msg.text.data[0] & BIT0)
275
            *pRed = true;
276
        else
277
            *pRed = false;
278
 
279
        if(msg.text.data[0] & BIT1)
280
            *pGreen = true;
281
        else
282
            *pGreen = false;
283
 
284
        if(msg.text.data[0] & BIT2)
285
            *pBlue = true;
286
        else
287
            *pBlue = false;
288
 
289
        if(msg.text.data[0] & BIT3)
290
            *pSeqCtrl = true;
291
        else
292
            *pSeqCtrl = false;
293
        return 0;
294
    }
295
    return -1;
296
}
297
 
298
 
299
int LCR_SetLedEnables(bool SeqCtrl, bool Red, bool Green, bool Blue)
300
{
301
    hidMessageStruct msg;
302
    unsigned char Enable=0;
303
 
304
    if(SeqCtrl)
305
        Enable |= BIT3;
306
    if(Red)
307
        Enable |= BIT0;
308
    if(Green)
309
        Enable |= BIT1;
310
    if(Blue)
311
        Enable |= BIT2;
312
 
313
    msg.text.data[2] = Enable;
314
    LCR_PrepWriteCmd(&msg, LED_ENABLE);
315
 
316
    return LCR_SendMsg(&msg);
317
}
318
 
319
int LCR_GetLedCurrents(unsigned char *pRed, unsigned char *pGreen, unsigned char *pBlue)
320
{
321
    hidMessageStruct msg;
322
 
323
    LCR_PrepReadCmd(LED_CURRENT);
324
    if(LCR_Read() > 0)
325
    {
326
        memcpy(&msg, InputBuffer, 65);
327
 
328
        *pRed = msg.text.data[0];
329
        *pGreen = msg.text.data[1];
330
        *pBlue = msg.text.data[2];
331
 
332
        return 0;
333
    }
334
    return -1;
335
}
336
 
337
 
338
int LCR_SetLedCurrents(unsigned char RedCurrent, unsigned char GreenCurrent, unsigned char BlueCurrent)
339
{
340
    hidMessageStruct msg;
341
 
342
    msg.text.data[2] = RedCurrent;
343
    msg.text.data[3] = GreenCurrent;
344
    msg.text.data[4] = BlueCurrent;
345
 
346
    LCR_PrepWriteCmd(&msg, LED_CURRENT);
347
 
348
    return LCR_SendMsg(&msg);
349
}
350
 
351
bool LCR_GetLongAxisImageFlip(void)
352
{
353
    hidMessageStruct msg;
354
 
355
    LCR_PrepReadCmd(FLIP_LONG);
356
    if(LCR_Read() > 0)
357
    {
358
        memcpy(&msg, InputBuffer, 65);
359
 
360
        if ((msg.text.data[0] & BIT0) == BIT0)
361
            return true;
362
        else
363
            return false;
364
    }
365
    return false;
366
}
367
 
368
bool LCR_GetShortAxisImageFlip(void)
369
{
370
    hidMessageStruct msg;
371
 
372
    LCR_PrepReadCmd(FLIP_SHORT);
373
    if(LCR_Read() > 0)
374
    {
375
        memcpy(&msg, InputBuffer, 65);
376
 
377
        if ((msg.text.data[0] & BIT0) == BIT0)
378
            return true;
379
        else
380
            return false;
381
    }
382
    return false;
383
}
384
 
385
 
386
int LCR_SetLongAxisImageFlip(bool Flip)
387
{
388
    hidMessageStruct msg;
389
 
390
    if(Flip)
391
        msg.text.data[2] = BIT0;
392
    else
393
        msg.text.data[2] = 0;
394
 
395
    LCR_PrepWriteCmd(&msg, FLIP_LONG);
396
 
397
    return LCR_SendMsg(&msg);
398
}
399
 
400
int LCR_SetShortAxisImageFlip(bool Flip)
401
{
402
    hidMessageStruct msg;
403
 
404
    if(Flip)
405
        msg.text.data[2] = BIT0;
406
    else
407
        msg.text.data[2] = 0;
408
 
409
    LCR_PrepWriteCmd(&msg, FLIP_SHORT);
410
 
411
    return LCR_SendMsg(&msg);
412
}
413
 
414
int LCR_SetProgrammingMode(bool EnterProgMode)
415
{
416
    hidMessageStruct msg;
417
 
418
    if(EnterProgMode)
419
        msg.text.data[2] = 1;
420
    else
421
        msg.text.data[2] = 2;
422
 
423
    LCR_PrepWriteCmd(&msg, PROG_MODE);
424
 
425
    return LCR_SendMsg(&msg);
426
}
427
 
428
int LCR_ExitProgrammingMode(void)
429
{
430
    hidMessageStruct msg;
431
 
432
    msg.text.data[2] = 2;
433
    LCR_PrepWriteCmd(&msg, BL_PROG_MODE);
434
 
435
    return LCR_SendMsg(&msg);
436
}
437
 
438
 
439
int LCR_GetProgrammingMode(bool *ProgMode)
440
{
441
    hidMessageStruct msg;
442
 
443
    LCR_PrepReadCmd(PROG_MODE);
444
 
445
    if(LCR_Read() > 0)
446
    {
447
        memcpy(&msg, InputBuffer, 65);
448
 
449
        if(msg.text.data[0] == 1)
450
            *ProgMode = true;
451
        else
452
            *ProgMode = false;
453
        return 0;
454
    }
455
    return -1;
456
}
457
 
458
int LCR_GetFlashManID(unsigned short *pManID)
459
{
460
    hidMessageStruct msg;
461
 
462
    LCR_PrepReadCmd(BL_GET_MANID);
463
    if(LCR_Read() > 0)
464
    {
465
        memcpy(&msg, InputBuffer, 65);
466
 
467
        *pManID = msg.text.data[6];
468
        *pManID |= (unsigned short)msg.text.data[7] << 8;
469
        return 0;
470
    }
471
    return -1;
472
}
473
 
474
int LCR_GetFlashDevID(unsigned long long *pDevID)
475
{
476
    hidMessageStruct msg;
477
 
478
    LCR_PrepReadCmd(BL_GET_DEVID);
479
    if(LCR_Read() > 0)
480
    {
481
        memcpy(&msg, InputBuffer, 65);
482
 
483
        *pDevID = msg.text.data[6];
484
        *pDevID |= (unsigned long long)msg.text.data[7] << 8;
485
        *pDevID |= (unsigned long long)msg.text.data[8] << 16;
486
        *pDevID |= (unsigned long long)msg.text.data[9] << 24;
487
        *pDevID |= (unsigned long long)msg.text.data[12] << 32;
488
        *pDevID |= (unsigned long long)msg.text.data[13] << 40;
489
        *pDevID |= (unsigned long long)msg.text.data[14] << 48;
490
        *pDevID |= (unsigned long long)msg.text.data[15] << 56;
491
        return 0;
492
    }
493
    return -1;
494
}
495
 
496
int LCR_GetBLStatus(unsigned char *BL_Status)
497
{
498
    hidMessageStruct msg;
499
 
500
    /* For some reason BL_STATUS readback is not working properly.
501
     * However, after going through the bootloader code, I have ascertained that any
502
     * readback is fine - Byte 0 is always teh bootloader status */
503
    LCR_PrepReadCmd(BL_GET_CHKSUM);
504
    if(LCR_Read() > 0)
505
    {
506
        memcpy(&msg, InputBuffer, 65);
507
 
508
        *BL_Status = msg.text.data[0];
509
        return 0;
510
    }
511
    return -1;
512
}
513
 
514
int LCR_BLSpecialMode(unsigned int Mode)
515
{
516
    hidMessageStruct msg;
517
 
518
    msg.text.data[2] = Mode;
519
 
520
    LCR_PrepWriteCmd(&msg, BL_SPL_MODE);
521
 
522
    return LCR_SendMsg(&msg);
523
}
524
 
525
int LCR_SetFlashAddr(unsigned int Addr)
526
{
527
    hidMessageStruct msg;
528
 
529
    msg.text.data[2] = Addr;
530
    msg.text.data[3] = Addr >> 8;
531
    msg.text.data[4] = Addr >> 16;
532
    msg.text.data[5] = Addr >> 24;
533
 
534
    LCR_PrepWriteCmd(&msg, BL_SET_SECTADDR);
535
 
536
    return LCR_SendMsg(&msg);
537
}
538
 
539
 int LCR_FlashSectorErase(void)
540
 {
541
     hidMessageStruct msg;
542
 
543
     LCR_PrepWriteCmd(&msg, BL_SECT_ERASE);
544
     return LCR_SendMsg(&msg);
545
 }
546
 
547
int LCR_SetDownloadSize(unsigned int dataLen)
548
{
549
    hidMessageStruct msg;
550
 
551
    msg.text.data[2] = dataLen;
552
    msg.text.data[3] = dataLen >> 8;
553
    msg.text.data[4] = dataLen >> 16;
554
    msg.text.data[5] = dataLen >> 24;
555
 
556
    LCR_PrepWriteCmd(&msg, BL_SET_DNLDSIZE);
557
 
558
    return LCR_SendMsg(&msg);
559
}
560
 
561
int LCR_DownloadData(unsigned char *pByteArray, unsigned int dataLen)
562
{
563
    hidMessageStruct msg;
564
    int retval;
565
    unsigned int sendSize;
566
 
567
    sendSize = HID_MESSAGE_MAX_SIZE - sizeof(msg.head)- sizeof(msg.text.cmd) - 2;//The last -2 is to workaround a bug in bootloader.
568
 
569
    if(dataLen > sendSize)
570
        dataLen = sendSize;
571
 
572
    CmdList[BL_DNLD_DATA].len = dataLen;
573
    memcpy(&msg.text.data[2], pByteArray, dataLen);
574
 
575
    LCR_PrepWriteCmd(&msg, BL_DNLD_DATA);
576
 
577
    retval = LCR_SendMsg(&msg);
578
    if(retval > 0)
579
        return dataLen;
580
 
581
    return -1;
582
}
583
 
584
void LCR_WaitForFlashReady()
585
{
586
    unsigned char BLstatus=STAT_BIT_FLASH_BUSY;
587
 
588
    do
589
    {
590
        LCR_GetBLStatus(&BLstatus);
591
    }
592
    while((BLstatus & STAT_BIT_FLASH_BUSY) == STAT_BIT_FLASH_BUSY);//Wait for flash busy flag to go off
593
}
594
 
595
int LCR_SetFlashType(unsigned char Type)
596
{
597
    hidMessageStruct msg;
598
 
599
    msg.text.data[2] = Type;
600
 
601
    LCR_PrepWriteCmd(&msg, BL_FLASH_TYPE);
602
 
603
    return LCR_SendMsg(&msg);
604
}
605
 
606
int LCR_CalculateFlashChecksum(void)
607
{
608
    hidMessageStruct msg;
609
 
610
    LCR_PrepWriteCmd(&msg, BL_CALC_CHKSUM);
611
 
612
    if(LCR_SendMsg(&msg) <= 0)
613
        return -1;
614
 
615
    return 0;
616
 
617
}
618
 
619
int LCR_GetFlashChecksum(unsigned int*checksum)
620
{
621
    hidMessageStruct msg;
622
#if 0
623
    LCR_PrepWriteCmd(&msg, BL_CALC_CHKSUM);
624
 
625
    if(LCR_SendMsg(&msg) <= 0)
626
        return -1;
627
 
628
    LCR_WaitForFlashReady();
629
#endif
630
    LCR_PrepReadCmd(BL_GET_CHKSUM);
631
    if(LCR_Read() > 0)
632
    {
633
        memcpy(&msg, InputBuffer, 65);
634
 
635
        *checksum = msg.text.data[6];
636
        *checksum |= (unsigned int)msg.text.data[7] << 8;
637
        *checksum |= (unsigned int)msg.text.data[8] << 16;
638
        *checksum |= (unsigned int)msg.text.data[9] << 24;
639
        return 0;
640
    }
641
    return -1;
642
}
643
 
644
int LCR_GetStatus(unsigned char *pHWStatus, unsigned char *pSysStatus, unsigned char *pMainStatus)
645
{
646
    hidMessageStruct msg;
647
 
648
    LCR_PrepReadCmd(STATUS_HW);
649
    if(LCR_Read() > 0)
650
    {
651
        memcpy(&msg, InputBuffer, 65);
652
 
653
        *pHWStatus = msg.text.data[0];
654
    }
655
    else
656
        return -1;
657
 
658
    LCR_PrepReadCmd(STATUS_SYS);
659
    if(LCR_Read() > 0)
660
    {
661
        memcpy(&msg, InputBuffer, 65);
662
 
663
        *pSysStatus = msg.text.data[0];
664
    }
665
    else
666
        return -1;
667
 
668
    LCR_PrepReadCmd(STATUS_MAIN);
669
    if(LCR_Read() > 0)
670
    {
671
        memcpy(&msg, InputBuffer, 65);
672
 
673
        *pMainStatus = msg.text.data[0];
674
    }
675
    else
676
        return -1;
677
 
678
    return 0;
679
}
680
 
681
int LCR_SoftwareReset(void)
682
{
683
    hidMessageStruct msg;
684
 
685
    LCR_PrepWriteCmd(&msg, SW_RESET);
686
 
687
    return LCR_SendMsg(&msg);
688
}
689
 
690
int LCR_SetMode(bool SLmode)
691
{
692
    hidMessageStruct msg;
693
 
694
    msg.text.data[2] = SLmode;
695
    LCR_PrepWriteCmd(&msg, DISP_MODE);
696
 
697
    return LCR_SendMsg(&msg);
698
}
699
 
700
int LCR_GetMode(bool *pMode)
701
{
702
    hidMessageStruct msg;
703
 
704
    LCR_PrepReadCmd(DISP_MODE);
705
    if(LCR_Read() > 0)
706
    {
707
        memcpy(&msg, InputBuffer, 65);
708
        *pMode = (msg.text.data[0] != 0);
709
        return 0;
710
    }
711
    return -1;
712
}
713
 
714
int LCR_SetPowerMode(bool Standby)
715
{
716
    hidMessageStruct msg;
717
 
718
    msg.text.data[2] = Standby;
719
    LCR_PrepWriteCmd(&msg, POWER_CONTROL);
720
 
721
    return LCR_SendMsg(&msg);
722
}
723
 
724
int LCR_SetRedLEDStrobeDelay(unsigned char rising, unsigned char falling)
725
{
726
    hidMessageStruct msg;
727
 
728
    msg.text.data[2] = rising;
729
    msg.text.data[3] = falling;
730
 
731
    LCR_PrepWriteCmd(&msg, RED_STROBE_DLY);
732
 
733
    return LCR_SendMsg(&msg);
734
}
735
 
736
int LCR_SetGreenLEDStrobeDelay(unsigned char rising, unsigned char falling)
737
{
738
    hidMessageStruct msg;
739
 
740
    msg.text.data[2] = rising;
741
    msg.text.data[3] = falling;
742
 
743
    LCR_PrepWriteCmd(&msg, GRN_STROBE_DLY);
744
 
745
    return LCR_SendMsg(&msg);
746
}
747
 
748
int LCR_SetBlueLEDStrobeDelay(unsigned char rising, unsigned char falling)
749
{
750
    hidMessageStruct msg;
751
 
752
    msg.text.data[2] = rising;
753
    msg.text.data[3] = falling;
754
 
755
    LCR_PrepWriteCmd(&msg, BLU_STROBE_DLY);
756
 
757
    return LCR_SendMsg(&msg);
758
}
759
 
760
int LCR_GetRedLEDStrobeDelay(unsigned char *pRising, unsigned char *pFalling)
761
{
762
    hidMessageStruct msg;
763
 
764
    LCR_PrepReadCmd(RED_STROBE_DLY);
765
 
766
    if(LCR_Read() > 0)
767
    {
768
        memcpy(&msg, InputBuffer, 65);
769
        *pRising = msg.text.data[0];
770
        *pFalling = msg.text.data[1];
771
        return 0;
772
    }
773
    return -1;
774
}
775
 
776
int LCR_GetGreenLEDStrobeDelay(unsigned char *pRising, unsigned char *pFalling)
777
{
778
    hidMessageStruct msg;
779
 
780
    LCR_PrepReadCmd(GRN_STROBE_DLY);
781
 
782
    if(LCR_Read() > 0)
783
    {
784
        memcpy(&msg, InputBuffer, 65);
785
        *pRising = msg.text.data[0];
786
        *pFalling = msg.text.data[1];
787
        return 0;
788
    }
789
    return -1;
790
}
791
 
792
int LCR_GetBlueLEDStrobeDelay(unsigned char *pRising, unsigned char *pFalling)
793
{
794
    hidMessageStruct msg;
795
 
796
    LCR_PrepReadCmd(BLU_STROBE_DLY);
797
 
798
    if(LCR_Read() > 0)
799
    {
800
        memcpy(&msg, InputBuffer, 65);
801
        *pRising = msg.text.data[0];
802
        *pFalling = msg.text.data[1];
803
        return 0;
804
    }
805
    return -1;
806
}
807
 
808
int LCR_SetInputSource(unsigned int source, unsigned int portWidth)
809
{
810
    hidMessageStruct msg;
811
 
812
    msg.text.data[2] = source;
813
    msg.text.data[2] |= portWidth << 3;
814
    LCR_PrepWriteCmd(&msg, SOURCE_SEL);
815
 
816
    return LCR_SendMsg(&msg);
817
}
818
 
819
int LCR_GetInputSource(unsigned int *pSource, unsigned int *pPortWidth)
820
{
821
    hidMessageStruct msg;
822
 
823
    LCR_PrepReadCmd(SOURCE_SEL);
824
 
825
    if(LCR_Read() > 0)
826
    {
827
        memcpy(&msg, InputBuffer, 65);
828
        *pSource = msg.text.data[0] & (BIT0 | BIT1 | BIT2);
829
        *pPortWidth = msg.text.data[0] >> 3;
830
        return 0;
831
    }
832
    return -1;
833
}
834
 
835
int LCR_SetPatternDisplayMode(bool external)
836
{
837
    hidMessageStruct msg;
838
 
839
    if(external)
840
        msg.text.data[2] = 0;
841
    else
842
        msg.text.data[2] = 3;
843
 
844
    LCR_PrepWriteCmd(&msg, PAT_DISP_MODE);
845
 
846
    return LCR_SendMsg(&msg);
847
}
848
 
849
int LCR_GetPatternDisplayMode(bool *external)
850
{
851
    hidMessageStruct msg;
852
 
853
    LCR_PrepReadCmd(PAT_DISP_MODE);
854
 
855
    if(LCR_Read() > 0)
856
    {
857
        memcpy(&msg, InputBuffer, 65);
858
        if(msg.text.data[0] == 0)
859
            *external = true;
860
        else
861
            *external = false;
862
        return 0;
863
    }
864
    return -1;
865
}
866
 
867
int LCR_SetPixelFormat(unsigned int format)
868
{
869
    hidMessageStruct msg;
870
 
871
    msg.text.data[2] = format;
872
    LCR_PrepWriteCmd(&msg, PIXEL_FORMAT);
873
 
874
    return LCR_SendMsg(&msg);
875
}
876
 
877
int LCR_GetPixelFormat(unsigned int *pFormat)
878
{
879
    hidMessageStruct msg;
880
 
881
    LCR_PrepReadCmd(PIXEL_FORMAT);
882
 
883
    if(LCR_Read() > 0)
884
    {
885
        memcpy(&msg, InputBuffer, 65);
886
        *pFormat = msg.text.data[0] & (BIT0 | BIT1 | BIT2);
887
        return 0;
888
    }
889
    return -1;
890
}
891
 
892
int LCR_SetPortClock(unsigned int clock)
893
{
894
    hidMessageStruct msg;
895
 
896
    msg.text.data[2] = clock;
897
    LCR_PrepWriteCmd(&msg, CLK_SEL);
898
 
899
    return LCR_SendMsg(&msg);
900
}
901
 
902
int LCR_GetPortClock(unsigned int *pClock)
903
{
904
    hidMessageStruct msg;
905
 
906
    LCR_PrepReadCmd(CLK_SEL);
907
 
908
    if(LCR_Read() > 0)
909
    {
910
        memcpy(&msg, InputBuffer, 65);
911
        *pClock = msg.text.data[0] & (BIT0 | BIT1 | BIT2);
912
        return 0;
913
    }
914
    return -1;
915
}
916
 
917
int LCR_SetDataChannelSwap(unsigned int port, unsigned int swap)
918
{
919
    hidMessageStruct msg;
920
 
921
    msg.text.data[2] = port << 7;
922
    msg.text.data[2] |= swap & (BIT0 | BIT1 | BIT2);
923
    LCR_PrepWriteCmd(&msg, CHANNEL_SWAP);
924
 
925
    return LCR_SendMsg(&msg);
926
}
927
 
928
int LCR_GetDataChannelSwap(unsigned int *pPort, unsigned int *pSwap)
929
{
930
    hidMessageStruct msg;
931
 
932
    LCR_PrepReadCmd(CHANNEL_SWAP);
933
 
934
    if(LCR_Read() > 0)
935
    {
936
        memcpy(&msg, InputBuffer, 65);
937
        *pSwap = msg.text.data[0] & (BIT0 | BIT1 | BIT2);
938
        if(msg.text.data[0] & BIT7)
939
            *pPort = 1;
940
        else
941
            *pPort = 0;
942
        return 0;
943
    }
944
    return -1;
945
}
946
 
947
int LCR_SetFPD_Mode_Field(unsigned int PixelMappingMode, bool SwapPolarity, unsigned int FieldSignalSelect)
948
{
949
    hidMessageStruct msg;
950
 
951
    msg.text.data[2] = PixelMappingMode << 6;
952
    msg.text.data[2] |= FieldSignalSelect & (BIT0 | BIT1 | BIT2);
953
    if(SwapPolarity)
954
        msg.text.data[2] |= BIT3;
955
    LCR_PrepWriteCmd(&msg, FPD_MODE);
956
 
957
    return LCR_SendMsg(&msg);
958
}
959
 
960
int LCR_GetFPD_Mode_Field(unsigned int *pPixelMappingMode, bool *pSwapPolarity, unsigned int *pFieldSignalSelect)
961
{
962
    hidMessageStruct msg;
963
 
964
    LCR_PrepReadCmd(FPD_MODE);
965
 
966
    if(LCR_Read() > 0)
967
    {
968
        memcpy(&msg, InputBuffer, 65);
969
        *pFieldSignalSelect = msg.text.data[0] & (BIT0 | BIT1 | BIT2);
970
        if(msg.text.data[0] & BIT3)
971
            *pSwapPolarity = 1;
972
        else
973
            *pSwapPolarity = 0;
974
        *pPixelMappingMode = msg.text.data[0] >> 6;
975
        return 0;
976
    }
977
    return -1;
978
}
979
 
980
int LCR_SetTPGSelect(unsigned int pattern)
981
{
982
    hidMessageStruct msg;
983
 
984
    msg.text.data[2] = pattern;
985
    LCR_PrepWriteCmd(&msg, TPG_SEL);
986
 
987
    return LCR_SendMsg(&msg);
988
}
989
 
990
int LCR_GetTPGSelect(unsigned int *pPattern)
991
{
992
    hidMessageStruct msg;
993
 
994
    LCR_PrepReadCmd(TPG_SEL);
995
 
996
    if(LCR_Read() > 0)
997
    {
998
        memcpy(&msg, InputBuffer, 65);
999
        *pPattern = msg.text.data[0] & (BIT0 | BIT1 | BIT2 | BIT3);
1000
        return 0;
1001
    }
1002
    return -1;
1003
}
1004
 
1005
int LCR_LoadSplash(unsigned int index)
1006
{
1007
    hidMessageStruct msg;
1008
 
1009
    msg.text.data[2] = index;
1010
    LCR_PrepWriteCmd(&msg, SPLASH_LOAD);
1011
 
1012
    return LCR_SendMsg(&msg);
1013
}
1014
 
1015
int LCR_GetSplashIndex(unsigned int *pIndex)
1016
{
1017
    hidMessageStruct msg;
1018
 
1019
    LCR_PrepReadCmd(SPLASH_LOAD);
1020
 
1021
    if(LCR_Read() > 0)
1022
    {
1023
        memcpy(&msg, InputBuffer, 65);
1024
        *pIndex = msg.text.data[0];
1025
        return 0;
1026
    }
1027
    return -1;
1028
}
1029
 
1030
int LCR_SetDisplay(rectangle croppedArea, rectangle displayArea)
1031
{
1032
    hidMessageStruct msg;
1033
 
1034
    msg.text.data[2] = croppedArea.firstPixel & 0xFF;
1035
    msg.text.data[3] = croppedArea.firstPixel >> 8;
1036
    msg.text.data[4] = croppedArea.firstLine & 0xFF;
1037
    msg.text.data[5] = croppedArea.firstLine >> 8;
1038
    msg.text.data[6] = croppedArea.pixelsPerLine & 0xFF;
1039
    msg.text.data[7] = croppedArea.pixelsPerLine >> 8;
1040
    msg.text.data[8] = croppedArea.linesPerFrame & 0xFF;
1041
    msg.text.data[9] = croppedArea.linesPerFrame >> 8;
1042
    msg.text.data[10] = displayArea.firstPixel & 0xFF;
1043
    msg.text.data[11] = displayArea.firstPixel >> 8;
1044
    msg.text.data[12] = displayArea.firstLine & 0xFF;
1045
    msg.text.data[13] = displayArea.firstLine >> 8;
1046
    msg.text.data[14] = displayArea.pixelsPerLine & 0xFF;
1047
    msg.text.data[15] = displayArea.pixelsPerLine >> 8;
1048
    msg.text.data[16] = displayArea.linesPerFrame & 0xFF;
1049
    msg.text.data[17] = displayArea.linesPerFrame >> 8;
1050
 
1051
    LCR_PrepWriteCmd(&msg, DISP_CONFIG);
1052
 
1053
    return LCR_SendMsg(&msg);
1054
}
1055
 
1056
int LCR_GetDisplay(rectangle *pCroppedArea, rectangle *pDisplayArea)
1057
{
1058
    hidMessageStruct msg;
1059
 
1060
    LCR_PrepReadCmd(DISP_CONFIG);
1061
 
1062
    if(LCR_Read() > 0)
1063
    {
1064
        memcpy(&msg, InputBuffer, 65);
1065
        pCroppedArea->firstPixel = msg.text.data[0] | msg.text.data[1] << 8;
1066
        pCroppedArea->firstLine = msg.text.data[2] | msg.text.data[3] << 8;
1067
        pCroppedArea->pixelsPerLine = msg.text.data[4] | msg.text.data[5] << 8;
1068
        pCroppedArea->linesPerFrame = msg.text.data[6] | msg.text.data[7] << 8;
1069
        pDisplayArea->firstPixel = msg.text.data[8] | msg.text.data[9] << 8;
1070
        pDisplayArea->firstLine = msg.text.data[10] | msg.text.data[11] << 8;
1071
        pDisplayArea->pixelsPerLine = msg.text.data[12] | msg.text.data[13] << 8;
1072
        pDisplayArea->linesPerFrame = msg.text.data[14] | msg.text.data[15] << 8;
1073
 
1074
        return 0;
1075
    }
1076
    return -1;
1077
}
1078
 
1079
int LCR_SetTPGColor(unsigned short redFG, unsigned short greenFG, unsigned short blueFG, unsigned short redBG, unsigned short greenBG, unsigned short blueBG)
1080
{
1081
    hidMessageStruct msg;
1082
 
1083
    msg.text.data[2] = (char)redFG;
1084
    msg.text.data[3] = (char)(redFG >> 8);
1085
    msg.text.data[4] = (char)greenFG;
1086
    msg.text.data[5] = (char)(greenFG >> 8);
1087
    msg.text.data[6] = (char)blueFG;
1088
    msg.text.data[7] = (char)(blueFG >> 8);
1089
    msg.text.data[8] = (char)redBG;
1090
    msg.text.data[9] = (char)(redBG >> 8);
1091
    msg.text.data[10] = (char)greenBG;
1092
    msg.text.data[11] = (char)(greenBG >> 8);
1093
    msg.text.data[12] = (char)blueBG;
1094
    msg.text.data[13] = (char)(blueBG >> 8);
1095
 
1096
    LCR_PrepWriteCmd(&msg, TPG_COLOR);
1097
 
1098
    return LCR_SendMsg(&msg);
1099
}
1100
 
1101
int LCR_GetTPGColor(unsigned short *pRedFG, unsigned short *pGreenFG, unsigned short *pBlueFG, unsigned short *pRedBG, unsigned short *pGreenBG, unsigned short *pBlueBG)
1102
{
1103
    hidMessageStruct msg;
1104
 
1105
    LCR_PrepReadCmd(TPG_COLOR);
1106
 
1107
    if(LCR_Read() > 0)
1108
    {
1109
        memcpy(&msg, InputBuffer, 65);
1110
        *pRedFG = msg.text.data[0] | msg.text.data[1] << 8;
1111
        *pGreenFG = msg.text.data[2] | msg.text.data[3] << 8;
1112
        *pBlueFG = msg.text.data[4] | msg.text.data[5] << 8;
1113
        *pRedBG = msg.text.data[6] | msg.text.data[7] << 8;
1114
        *pGreenBG = msg.text.data[8] | msg.text.data[9] << 8;
1115
        *pBlueBG = msg.text.data[10] | msg.text.data[11] << 8;
1116
 
1117
        return 0;
1118
    }
1119
    return -1;
1120
}
1121
 
1122
int LCR_ClearPatLut(void)
1123
{
1124
    PatLutIndex = 0;
1125
    return 0;
1126
}
1127
 
1128
int LCR_AddToPatLut(int TrigType, int PatNum,int BitDepth,int LEDSelect,bool InvertPat, bool InsertBlack,bool BufSwap, bool trigOutPrev)
1129
{
1130
    unsigned int lutWord = 0;
1131
 
1132
    lutWord = TrigType & 3;
1133
    if(PatNum > 24)
1134
        return -1;
1135
 
1136
    lutWord |= ((PatNum & 0x3F) << 2);
1137
    if( (BitDepth > 8) || (BitDepth <= 0))
1138
        return -1;
1139
    lutWord |= ((BitDepth & 0xF) << 8);
1140
    if(LEDSelect > 7)
1141
        return -1;
1142
    lutWord |= ((LEDSelect & 0x7) << 12);
1143
    if(InvertPat)
1144
        lutWord |= BIT16;
1145
    if(InsertBlack)
1146
        lutWord |= BIT17;
1147
    if(BufSwap)
1148
        lutWord |= BIT18;
1149
    if(trigOutPrev)
1150
        lutWord |= BIT19;
1151
 
1152
    PatLut[PatLutIndex++] = lutWord;
1153
    return 0;
1154
}
1155
 
1156
int LCR_GetPatLutItem(int index, int *pTrigType, int *pPatNum,int *pBitDepth,int *pLEDSelect,bool *pInvertPat, bool *pInsertBlack,bool *pBufSwap, bool *pTrigOutPrev)
1157
{
1158
    unsigned int lutWord;
1159
 
1160
    lutWord = PatLut[index];
1161
 
1162
    *pTrigType = lutWord & 3;
1163
    *pPatNum = (lutWord >> 2) & 0x3F;
1164
    *pBitDepth = (lutWord >> 8) & 0xF;
1165
    *pLEDSelect = (lutWord >> 12) & 7;
1166
    *pInvertPat = ((lutWord & BIT16) == BIT16);
1167
    *pInsertBlack = ((lutWord & BIT17) == BIT17);
1168
    *pBufSwap = ((lutWord & BIT18) == BIT18);
1169
    *pTrigOutPrev = ((lutWord & BIT19) == BIT19);
1170
 
1171
    return 0;
1172
}
1173
 
1174
int LCR_OpenMailbox(int MboxNum)
1175
{
1176
    hidMessageStruct msg;
1177
 
1178
    msg.text.data[2] = MboxNum;
1179
    LCR_PrepWriteCmd(&msg, MBOX_CONTROL);
1180
 
1181
    return LCR_SendMsg(&msg);
1182
}
1183
 
1184
int LCR_CloseMailbox(void)
1185
{
1186
    hidMessageStruct msg;
1187
 
1188
    msg.text.data[2] = 0;
1189
    LCR_PrepWriteCmd(&msg, MBOX_CONTROL);
1190
 
1191
    return LCR_SendMsg(&msg);
1192
}
1193
 
1194
int LCR_MailboxSetAddr(int Addr)
1195
{
1196
    hidMessageStruct msg;
1197
 
1198
    if(Addr > 127)
1199
        return -1;
1200
 
1201
    msg.text.data[2] = Addr;
1202
    LCR_PrepWriteCmd(&msg, MBOX_ADDRESS);
1203
 
1204
    return LCR_SendMsg(&msg);
1205
}
1206
 
1207
int LCR_SendPatLut(void)
1208
{
1209
    hidMessageStruct msg;
1210
    int bytesToSend=PatLutIndex*3;
1211
    unsigned int i;
1212
 
1213
    if(LCR_OpenMailbox(2) < 0)
1214
        return -1;
1215
    LCR_MailboxSetAddr(0);
1216
 
1217
    CmdList[MBOX_DATA].len = bytesToSend;
1218
    LCR_PrepWriteCmd(&msg, MBOX_DATA);
1219
 
1220
    for(i=0; i<PatLutIndex; i++)
1221
    {
1222
        msg.text.data[2+3*i] = PatLut[i];
1223
        msg.text.data[2+3*i+1] = PatLut[i]>>8;
1224
        msg.text.data[2+3*i+2] = PatLut[i]>>16;
1225
    }
1226
 
1227
    LCR_SendMsg(&msg);
1228
    LCR_CloseMailbox();
1229
    return 0;
1230
}
1231
 
1232
int LCR_SendSplashLut(unsigned char *lutEntries, unsigned int numEntries)
1233
{
1234
    hidMessageStruct msg;
1235
    unsigned int i;
1236
 
1237
    if(numEntries < 1 || numEntries > 64)
1238
        return -1;
1239
 
1240
    LCR_OpenMailbox(1);
1241
    LCR_MailboxSetAddr(0);
1242
 
1243
    // Check for special case of 2 entries
1244
    if( numEntries == 2)
1245
    {
1246
         msg.text.data[2+0] = lutEntries[1];
1247
         msg.text.data[2+1] = lutEntries[0];
1248
    }
1249
    else
1250
    {
1251
        for(i=0; i < numEntries; i++)
1252
        {
1253
            msg.text.data[2+i] = lutEntries[i];
1254
        }
1255
    }
1256
 
1257
    CmdList[MBOX_DATA].len = numEntries;
1258
    LCR_PrepWriteCmd(&msg, MBOX_DATA);
1259
    LCR_SendMsg(&msg);
1260
    LCR_CloseMailbox();
1261
 
1262
    return 0;
1263
}
1264
 
1265
 
1266
int LCR_GetPatLut(int numEntries)
1267
{
1268
    hidMessageStruct msg;
1269
    unsigned int lutWord = 0;
1270
    int numBytes, i;
1271
    unsigned char *readBuf;
1272
 
1273
    if(numEntries > 128)
1274
        return -1;
1275
 
1276
    if(LCR_OpenMailbox(2) < 0)
1277
        return -1;
1278
 
1279
    if(LCR_MailboxSetAddr(0) < 0)
1280
        return -1;
1281
 
1282
    numBytes = sizeof(msg.head)+numEntries*3;
1283
    readBuf = (unsigned char *)&msg;
1284
    LCR_PrepReadCmd(MBOX_DATA);
1285
 
1286
 
1287
    if(LCR_Read() > 0)
1288
    {
1289
        memcpy(readBuf, InputBuffer, MIN(numBytes,64));
1290
        readBuf+=64;
1291
        numBytes -=64;
1292
    }
1293
    else
1294
    {
1295
        LCR_CloseMailbox();
1296
        return -1;
1297
    }
1298
    /* If packet is greater than 64 bytes, continue to read */
1299
    while(numBytes > 0)
1300
    {
1301
        LCR_ContinueRead();
1302
        memcpy(readBuf, InputBuffer, MIN(numBytes,64));
1303
        readBuf+=64;
1304
        numBytes -=64;
1305
    }
1306
 
1307
    LCR_ClearPatLut();
1308
    for(i=0; i<numEntries*3; i+=3)
1309
    {
1310
        lutWord = msg.text.data[i] | msg.text.data[i+1] << 8 | msg.text.data[i+2] << 16;
1311
        PatLut[PatLutIndex++] = lutWord;
1312
    }
1313
 
1314
    if(LCR_CloseMailbox() < 0)
1315
        return -1;
1316
 
1317
    return 0;
1318
}
1319
 
1320
int LCR_GetSplashLut(unsigned char *pLut, int numEntries)
1321
{
1322
    hidMessageStruct *pMsg;
1323
    if(LCR_OpenMailbox(1) < 0)
1324
        return -1;
1325
 
1326
    if(LCR_MailboxSetAddr(0) < 0)
1327
        return -1;
1328
 
1329
    LCR_PrepReadCmd(MBOX_DATA);
1330
 
1331
    if(LCR_Read() > 0)
1332
    {
1333
        memcpy(pLut, InputBuffer+sizeof(pMsg->head), MIN(numEntries,64-sizeof(pMsg->head)));
1334
        pLut+= (64-sizeof(pMsg->head));
1335
        numEntries -= (64-sizeof(pMsg->head));
1336
    }
1337
    else
1338
    {
1339
        LCR_CloseMailbox();
1340
        return -1;
1341
    }
1342
 
1343
    /* If packet is greater than 64 bytes, continue to read */
1344
    while(numEntries > 0)
1345
    {
1346
        LCR_ContinueRead();
1347
        memcpy(pLut, InputBuffer, MIN(numEntries,64));
1348
        pLut+=64;
1349
        numEntries -= 64;
1350
    }
1351
 
1352
    if(LCR_CloseMailbox() < 0)
1353
        return -1;
1354
 
1355
    return 0;
1356
}
1357
 
1358
int LCR_SetPatternTriggerMode(bool Vsync_or_Generated)
1359
{
1360
    hidMessageStruct msg;
1361
 
1362
    msg.text.data[2] = Vsync_or_Generated;
1363
    LCR_PrepWriteCmd(&msg, PAT_TRIG_MODE);
1364
 
1365
    return LCR_SendMsg(&msg);
1366
}
1367
 
1368
int LCR_GetPatternTriggerMode(bool *Vsync_or_Generated)
1369
{    hidMessageStruct msg;
1370
 
1371
     LCR_PrepReadCmd(PAT_TRIG_MODE);
1372
 
1373
     if(LCR_Read() > 0)
1374
     {
1375
         memcpy(&msg, InputBuffer, 65);
1376
         *Vsync_or_Generated = (msg.text.data[0] != 0);
1377
         return 0;
1378
     }
1379
     return -1;
1380
}
1381
 
1382
 
1383
int LCR_PatternDisplay(int Action)
1384
{
1385
    hidMessageStruct msg;
1386
 
1387
    msg.text.data[2] = Action;
1388
    LCR_PrepWriteCmd(&msg, PAT_START_STOP);
1389
 
1390
    return LCR_SendMsg(&msg);
1391
}
1392
 
1393
int LCR_SetPatternConfig(unsigned int numLutEntries, bool repeat, unsigned int numPatsForTrigOut2, unsigned int numSplash)
1394
{
1395
    hidMessageStruct msg;
1396
 
1397
    msg.text.data[2] = numLutEntries-1; /* -1 because the firmware command takes 0-based indices (0 means 1) */
1398
    msg.text.data[3] = repeat;
1399
    msg.text.data[4] = numPatsForTrigOut2 - 1;  /* -1 because the firmware command takes 0-based indices (0 means 1) */
1400
    msg.text.data[5] = numSplash - 1;   /* -1 because the firmware command takes 0-based indices (0 means 1) */
1401
    LCR_PrepWriteCmd(&msg, PAT_CONFIG);
1402
 
1403
    return LCR_SendMsg(&msg);
1404
}
1405
 
1406
int LCR_GetPatternConfig(unsigned int *pNumLutEntries, bool *pRepeat, unsigned int *pNumPatsForTrigOut2, unsigned int *pNumSplash)
1407
{
1408
    hidMessageStruct msg;
1409
 
1410
    LCR_PrepReadCmd(PAT_CONFIG);
1411
 
1412
    if(LCR_Read() > 0)
1413
    {
1414
        memcpy(&msg, InputBuffer, 65);
1415
        *pNumLutEntries = msg.text.data[0] + 1; /* +1 because the firmware gives 0-based indices (0 means 1) */
1416
        *pRepeat = (msg.text.data[1] != 0);
1417
        *pNumPatsForTrigOut2 = msg.text.data[2]+1;    /* +1 because the firmware gives 0-based indices (0 means 1) */
1418
        *pNumSplash = msg.text.data[3]+1;     /* +1 because the firmware gives 0-based indices (0 means 1) */
1419
        return 0;
1420
    }
1421
    return -1;
1422
}
1423
 
1424
int LCR_SetExpsosure_FramePeriod(unsigned int exposurePeriod, unsigned int framePeriod)
1425
{
1426
        hidMessageStruct msg;
1427
 
1428
        msg.text.data[2] = exposurePeriod;
1429
        msg.text.data[3] = exposurePeriod>>8;
1430
        msg.text.data[4] = exposurePeriod>>16;
1431
        msg.text.data[5] = exposurePeriod>>24;
1432
        msg.text.data[6] = framePeriod;
1433
        msg.text.data[7] = framePeriod>>8;
1434
        msg.text.data[8] = framePeriod>>16;
1435
        msg.text.data[9] = framePeriod>>24;
1436
        LCR_PrepWriteCmd(&msg, PAT_EXPO_PRD);
1437
 
1438
        return LCR_SendMsg(&msg);
1439
}
1440
 
1441
int LCR_GetExposure_FramePeriod(unsigned int *pExposure, unsigned int *pFramePeriod)
1442
{
1443
    hidMessageStruct msg;
1444
 
1445
    LCR_PrepReadCmd(PAT_EXPO_PRD);
1446
 
1447
    if(LCR_Read() > 0)
1448
    {
1449
        memcpy(&msg, InputBuffer, 65);
1450
        *pExposure = msg.text.data[0] | msg.text.data[1] << 8 | msg.text.data[2] << 16 | msg.text.data[3] << 24;
1451
        *pFramePeriod = msg.text.data[4] | msg.text.data[5] << 8 | msg.text.data[6] << 16 | msg.text.data[7] << 24;
1452
        return 0;
1453
    }
1454
    return -1;
1455
}
1456
 
1457
 
1458
int LCR_SetTrigOutConfig(unsigned int trigOutNum, bool invert, unsigned int rising, unsigned int falling)
1459
{
1460
    hidMessageStruct msg;
1461
 
1462
    msg.text.data[2] = invert;
1463
    msg.text.data[3] = rising;
1464
    msg.text.data[4] = falling;
1465
    if(trigOutNum == 1)
1466
        LCR_PrepWriteCmd(&msg, TRIG_OUT1_CTL);
1467
    else if(trigOutNum==2)
1468
        LCR_PrepWriteCmd(&msg, TRIG_OUT2_CTL);
1469
 
1470
    return LCR_SendMsg(&msg);
1471
}
1472
 
1473
int LCR_GetTrigOutConfig(unsigned int trigOutNum, bool *pInvert,unsigned int *pRising, unsigned int *pFalling)
1474
{
1475
    hidMessageStruct msg;
1476
 
1477
    if(trigOutNum == 1)
1478
        LCR_PrepReadCmd(TRIG_OUT1_CTL);
1479
    else if(trigOutNum==2)
1480
        LCR_PrepReadCmd(TRIG_OUT2_CTL);
1481
 
1482
    if(LCR_Read() > 0)
1483
    {
1484
        memcpy(&msg, InputBuffer, 65);
1485
        *pInvert = (msg.text.data[0] != 0);
1486
        *pRising = msg.text.data[1];
1487
        *pFalling = msg.text.data[2];
1488
        return 0;
1489
    }
1490
    return -1;
1491
}
1492
 
1493
int LCR_ValidatePatLutData(unsigned int *pStatus)
1494
{
1495
    hidMessageStruct msg;
1496
 
1497
    LCR_PrepWriteCmd(&msg, LUT_VALID);    
1498
    if(LCR_SendMsg(&msg) < 0)
1499
        return -1;
1500
 
1501
    LCR_PrepReadCmd(LUT_VALID);
1502
    if(LCR_Read() > 0)
1503
    {
1504
        memcpy(&msg, InputBuffer, 65);
1505
        *pStatus = msg.text.data[0];
1506
        return 0;
1507
    }
1508
    return -1;
1509
}
1510
 
1511
 
1512
int LCR_SetTrigIn1Delay(unsigned int Delay)
1513
{
1514
    hidMessageStruct msg;
1515
 
1516
    msg.text.data[2] = Delay;
1517
    msg.text.data[3] = Delay >> 8;
1518
    msg.text.data[4] = Delay >> 16;
1519
    msg.text.data[5] = Delay >> 24;
1520
    LCR_PrepWriteCmd(&msg, TRIG_IN1_DELAY);
1521
 
1522
    return LCR_SendMsg(&msg);
1523
}
1524
 
1525
int LCR_GetTrigIn1Delay(unsigned int *pDelay)
1526
{
1527
    hidMessageStruct msg;
1528
 
1529
    LCR_PrepReadCmd(TRIG_IN1_DELAY);
1530
 
1531
    if(LCR_Read() > 0)
1532
    {
1533
        memcpy(&msg, InputBuffer, 65);
1534
        *pDelay = msg.text.data[0] | msg.text.data[1]<<8 | msg.text.data[2]<<16 | msg.text.data[3]<<24;
1535
        return 0;
1536
    }
1537
    return -1;
1538
}
1539
 
1540
int LCR_SetInvertData(bool invert)
1541
{
1542
    hidMessageStruct msg;
1543
 
1544
    msg.text.data[2] = invert;
1545
    LCR_PrepWriteCmd(&msg, INVERT_DATA);
1546
 
1547
    return LCR_SendMsg(&msg);
1548
}
1549
 
1550
int LCR_SetPWMConfig(unsigned int channel, unsigned int pulsePeriod, unsigned int dutyCycle)
1551
{
1552
    hidMessageStruct msg;
1553
 
1554
    msg.text.data[2] = channel;
1555
    msg.text.data[3] = pulsePeriod;
1556
    msg.text.data[4] = pulsePeriod >> 8;
1557
    msg.text.data[5] = pulsePeriod >> 16;
1558
    msg.text.data[6] = pulsePeriod >> 24;
1559
    msg.text.data[7] = dutyCycle;
1560
 
1561
    LCR_PrepWriteCmd(&msg, PWM_SETUP);
1562
 
1563
    return LCR_SendMsg(&msg);
1564
}
1565
 
1566
int LCR_GetPWMConfig(unsigned int channel, unsigned int *pPulsePeriod, unsigned int *pDutyCycle)
1567
{
1568
    hidMessageStruct msg;
1569
 
1570
    LCR_PrepReadCmdWithParam(PWM_SETUP, (unsigned char)channel);
1571
    if(LCR_Read() > 0)
1572
    {
1573
        memcpy(&msg, InputBuffer, 65);
1574
        *pPulsePeriod = msg.text.data[1] | msg.text.data[2] << 8 | msg.text.data[3] << 16 | msg.text.data[4] << 24;
1575
        *pDutyCycle = msg.text.data[5];
1576
        return 0;
1577
    }
1578
    return -1;
1579
}
1580
 
1581
int LCR_SetPWMEnable(unsigned int channel, bool Enable)
1582
{
1583
    hidMessageStruct msg;
1584
    unsigned char value = 0;
1585
 
1586
    if(Enable)
1587
        value = BIT7;
1588
 
1589
    if(channel == 2)
1590
        value |= 2;
1591
    else if (channel != 0)
1592
        return -1;
1593
 
1594
    msg.text.data[2] = value;
1595
    LCR_PrepWriteCmd(&msg, PWM_ENABLE);
1596
 
1597
    return LCR_SendMsg(&msg);
1598
}
1599
 
1600
int LCR_GetPWMEnable(unsigned int channel, bool *pEnable)
1601
{
1602
    hidMessageStruct msg;
1603
 
1604
    LCR_PrepReadCmdWithParam(PWM_ENABLE, (unsigned char)channel);
1605
 
1606
    if(LCR_Read() > 0)
1607
    {
1608
        memcpy(&msg, InputBuffer, 65);       
1609
        if(msg.text.data[0] & BIT7)
1610
            *pEnable =  true;
1611
        else
1612
            *pEnable = false;
1613
 
1614
        return 0;
1615
    }
1616
    return -1;
1617
}
1618
 
1619
int LCR_SetPWMCaptureConfig(unsigned int channel, bool enable, unsigned int sampleRate)
1620
{
1621
    hidMessageStruct msg;
1622
    unsigned char value = 0;
1623
 
1624
    value = channel & 1;
1625
 
1626
    if(enable)
1627
        value |= BIT7;
1628
 
1629
    msg.text.data[2] = value;
1630
    msg.text.data[3] = sampleRate;
1631
    msg.text.data[4] = sampleRate >> 8;
1632
    msg.text.data[5] = sampleRate >> 16;
1633
    msg.text.data[6] = sampleRate >> 24;
1634
    LCR_PrepWriteCmd(&msg, PWM_CAPTURE_CONFIG);
1635
 
1636
    return LCR_SendMsg(&msg);
1637
}
1638
 
1639
int LCR_GetPWMCaptureConfig(unsigned int channel, bool *pEnabled, unsigned int *pSampleRate)
1640
{
1641
    hidMessageStruct msg;
1642
 
1643
    LCR_PrepReadCmdWithParam(PWM_CAPTURE_CONFIG, (unsigned char)channel);
1644
 
1645
    if(LCR_Read() > 0)
1646
    {
1647
        memcpy(&msg, InputBuffer, 65);
1648
        if(msg.text.data[0] & BIT7)
1649
            *pEnabled =  true;
1650
        else
1651
            *pEnabled = false;
1652
 
1653
        *pSampleRate = msg.text.data[1] | msg.text.data[2] << 8 | msg.text.data[3] << 16 | msg.text.data[4] << 24;
1654
 
1655
        return 0;
1656
    }
1657
    return -1;
1658
}
1659
 
1660
int LCR_PWMCaptureRead(unsigned int channel, unsigned int *pLowPeriod, unsigned int *pHighPeriod)
1661
{
1662
    hidMessageStruct msg;
1663
 
1664
    LCR_PrepReadCmdWithParam(PWM_CAPTURE_READ, (unsigned char)channel);
1665
 
1666
    if(LCR_Read() > 0)
1667
    {
1668
        memcpy(&msg, InputBuffer, 65);
1669
        *pLowPeriod = msg.text.data[1] | msg.text.data[2] << 8;
1670
        *pHighPeriod = msg.text.data[3] | msg.text.data[4] << 8;
1671
        return 0;
1672
    }
1673
    return -1;
1674
}
1675
 
1676
int LCR_SetGPIOConfig(unsigned int pinNum, bool enAltFunc, bool altFunc1, bool dirOutput, bool outTypeOpenDrain, bool pinState)
1677
{
1678
    hidMessageStruct msg;
1679
    unsigned char value = 0;
1680
 
1681
    if(enAltFunc)
1682
        value |= BIT7;
1683
    if(altFunc1)
1684
        value |= BIT6;
1685
    if(dirOutput)
1686
        value |= BIT5;
1687
    if(outTypeOpenDrain)
1688
        value |= BIT4;
1689
    if(pinState)
1690
        value |= BIT3;
1691
 
1692
    msg.text.data[2] = pinNum;
1693
    msg.text.data[3] = value;
1694
    LCR_PrepWriteCmd(&msg, GPIO_CONFIG);
1695
 
1696
    return LCR_SendMsg(&msg);
1697
}
1698
 
1699
int LCR_GetGPIOConfig(unsigned int pinNum, bool *pEnAltFunc, bool *pAltFunc1, bool *pDirOutput, bool *pOutTypeOpenDrain, bool *pState)
1700
{
1701
    hidMessageStruct msg;
1702
 
1703
    LCR_PrepReadCmdWithParam(GPIO_CONFIG, (unsigned char)pinNum);
1704
 
1705
    if(LCR_Read() > 0)
1706
    {
1707
        memcpy(&msg, InputBuffer, 65);
1708
        *pEnAltFunc = ((msg.text.data[1] & BIT7) == BIT7);
1709
        *pAltFunc1 = ((msg.text.data[1] & BIT6) == BIT6);
1710
        *pDirOutput = ((msg.text.data[1] & BIT5) == BIT5);
1711
        *pOutTypeOpenDrain = ((msg.text.data[1] & BIT4) == BIT4);
1712
        if(*pDirOutput)
1713
            *pState = ((msg.text.data[1] & BIT3) == BIT3);
1714
        else
1715
            *pState = ((msg.text.data[1] & BIT2) == BIT2);
1716
        return 0;
1717
    }
1718
    return -1;
1719
}
1720
 
1721
int LCR_SetGeneralPurposeClockOutFreq(unsigned int clkId, bool enable, unsigned int clkDivider)
1722
{
1723
    hidMessageStruct msg;
1724
 
1725
    msg.text.data[2] = clkId;
1726
    msg.text.data[3] = enable;
1727
    msg.text.data[4] = clkDivider;
1728
    LCR_PrepWriteCmd(&msg, GPCLK_CONFIG);
1729
 
1730
    return LCR_SendMsg(&msg);
1731
}
1732
 
1733
int LCR_GetGeneralPurposeClockOutFreq(unsigned int clkId, bool *pEnabled, unsigned int *pClkDivider)
1734
{
1735
    hidMessageStruct msg;
1736
 
1737
    LCR_PrepReadCmdWithParam(GPCLK_CONFIG, (unsigned char)clkId);
1738
 
1739
    if(LCR_Read() > 0)
1740
    {
1741
        memcpy(&msg, InputBuffer, 65);
1742
        *pEnabled = (msg.text.data[0] != 0);
1743
        *pClkDivider = msg.text.data[1];
1744
        return 0;
1745
    }
1746
    return -1;
1747
}
1748
 
1749
int LCR_SetPWMInvert(bool invert)
1750
{
1751
    hidMessageStruct msg;
1752
 
1753
    msg.text.data[2] = invert;
1754
    LCR_PrepWriteCmd(&msg, PWM_INVERT);
1755
 
1756
    return LCR_SendMsg(&msg);
1757
}
1758
 
1759
int LCR_GetPWMInvert(bool *inverted)
1760
{
1761
    hidMessageStruct msg;
1762
 
1763
    LCR_PrepReadCmd(PWM_INVERT);
1764
 
1765
    if(LCR_Read() > 0)
1766
    {
1767
        memcpy(&msg, InputBuffer, 65);
1768
        *inverted = (msg.text.data[0] != 0);
1769
        return 0;
1770
    }
1771
    return -1;
1772
}
1773
 
1774
int LCR_MemRead(unsigned int addr, unsigned int *readWord)
1775
{
1776
    hidMessageStruct msg;
1777
 
1778
    LCR_PrepMemReadCmd(addr);
1779
    if(LCR_Read() > 0)
1780
    {
1781
        memcpy(&msg, InputBuffer, 65);
1782
        *readWord = msg.text.data[0] | msg.text.data[1] << 8 | msg.text.data[2] << 16 | msg.text.data[3] << 24;
1783
        //*readWord = msg.text.data[3] | msg.text.data[2] << 8 | msg.text.data[1] << 16 | msg.text.data[0] << 24; //MSB first
1784
        return 0;
1785
    }
1786
    return -1;
1787
}
1788
 
1789
int LCR_MemWrite(unsigned int addr, unsigned int data)
1790
{
1791
    hidMessageStruct msg;
1792
 
1793
    msg.text.data[2] = 0; //absolute write
1794
    msg.text.data[3] = addr >> 24; //MSB first
1795
    msg.text.data[4] = addr >> 16;
1796
    msg.text.data[5] = addr >> 8;
1797
    msg.text.data[6] = addr;
1798
    msg.text.data[7] = data >> 24; //MSB first
1799
    msg.text.data[8] = data >> 16;
1800
    msg.text.data[9] = data >> 8;
1801
    msg.text.data[10] = data;
1802
    LCR_PrepWriteCmd(&msg, MEM_CONTROL);
1803
 
1804
    return LCR_SendMsg(&msg);
1805
}
1806
 
1807
 int LCR_MeasureSplashLoadTiming(unsigned int startIndex, unsigned int numSplash)
1808
 {
1809
     hidMessageStruct msg;
1810
 
1811
     msg.text.data[2] = startIndex;
1812
     msg.text.data[3] = numSplash;
1813
     LCR_PrepWriteCmd(&msg, SPLASH_LOAD_TIMING);
1814
 
1815
     return LCR_SendMsg(&msg);
1816
 }
1817
 
1818
 int LCR_ReadSplashLoadTiming(unsigned int *pTimingData)
1819
 {
1820
     hidMessageStruct msg;
1821
     int i;
1822
 
1823
     LCR_PrepReadCmd(SPLASH_LOAD_TIMING);
1824
 
1825
     if(LCR_Read() > 0)
1826
     {
1827
         memcpy(&msg, InputBuffer, 65);
1828
         for(i=0; i<12; i++)
1829
         {
1830
             *(pTimingData+i) = (msg.text.data[4*i+0] | msg.text.data[4*i+1] << 8 | msg.text.data[4*i+2] << 16 | msg.text.data[4*i+3] << 24);
1831
         }
1832
         return 0;
1833
     }
1834
     return -1;
1835
 }