00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <string.h>
00024
00025 #if defined(_WIN32)
00026 # include "pthread_w32.h"
00027 # include "time_w32.h"
00028 #else
00029 #endif
00030
00031 #include "lcd.h"
00032 #include "trace.h"
00033 #include "packet.h"
00034 #include "driver.h"
00035 #include "cfontz.h"
00036
00037
00038 #define IILC_MODULE MODULE_TYPE_PACKET
00039
00040
00041
00042
00043
00044
00045
00046 #define CFONTZ_CFA633_STRING "CFA633"
00047 #define CFONTZ_CFA635_STRING "CFA635"
00048
00049
00050
00051 static int cfontz_WritePacket(LP_CFONTZ_DEV_INSTANCE pDevice,
00052 LPPACKET pPacket,
00053 LPPACKET * ppReplyPacket);
00054
00055 static int cfontz_UpdateFanReport(LP_CFONTZ_DEV_INSTANCE pInst);
00056
00057 static int cfontz_UpdateTempReport(LP_CFONTZ_DEV_INSTANCE pInst);
00058
00059 static int cfontz_UpdateFanPower(LP_CFONTZ_DEV_INSTANCE pInst);
00060
00061 static int cfontz_UpdateKeyReport(LP_CFONTZ_DEV_INSTANCE pInst);
00062
00063 static int cfontz_ReceiveTempReport(LP_CFONTZ_DEV_INSTANCE pInst,
00064 LPPACKET pPacket);
00065
00066 static int cfontz_ReceiveFanSpeedReport(LP_CFONTZ_DEV_INSTANCE pInst,
00067 LPPACKET pPacket);
00068
00069 static int cfontz_ReceiveKeyPressReport(LP_CFONTZ_DEV_INSTANCE pInst,
00070 LPPACKET pPacket);
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static int cfontz_InitDeviceType(LP_CFONTZ_DEV_INSTANCE pInst,
00081 const char * pszVersionString);
00082
00083
00084 static void * RxThread(void * arg);
00085
00086 static int cfontz_detectSCAB(LP_CFONTZ_DEV_INSTANCE pInst);
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 int driver_Create(const char * pszPort, LP_DRIVER_FN_ARRAY pFnArray,
00098 LP_DRIVER_INSTANCE * ppDriverInstData)
00099 {
00100 int rc = 0;
00101 LP_CFONTZ_DEV_INSTANCE pInst = NULL;
00102
00103 int i = 0;
00104 char pszVersionInfo[MAX_DATA_LENGTH + 1];
00105 LPPACKET pPacket = NULL, pReplyPacket = NULL;
00106
00107 IILC_TRACE_ENTRY(IILC_MODULE, T_driver_Create);
00108 traceDebug(IILC_TRACE_CONTEXT,
00109 "pszPort %p, pFnArray %p, ppDevice %p", pszPort, pFnArray, ppDriverInstData);
00110
00111
00112 if (pszPort == NULL || pFnArray == NULL || ppDriverInstData == NULL) {
00113 traceError(IILC_TRACE_CONTEXT, "Input parameter NULL");
00114 rc = ERR_BAD_PARAMETER;
00115 goto end_of_function;
00116 }
00117
00118 traceDebug(IILC_TRACE_CONTEXT, "Creating CrystalFontz device on port [%s]", pszPort);
00119
00120
00121 pInst = (LP_CFONTZ_DEV_INSTANCE) calloc(1, sizeof(CFONTZ_DEV_INSTANCE));
00122
00123
00124
00125
00126
00127
00128 pInst->pszPort = (char *) malloc(strlen(pszPort) + 1);
00129 strcpy(pInst->pszPort, pszPort);
00130
00131
00132
00133
00134
00135
00136
00137
00138 pthread_mutex_init(&(pInst->RxMutex), NULL);
00139
00140
00141 pthread_cond_init(&(pInst->RxSemaphore), NULL);
00142
00143
00144 pInst->RxRunning = 1;
00145
00146
00147 pthread_mutex_init(&(pInst->RunningMutex), NULL);
00148
00149
00150
00151
00152
00153
00154 pInst->pfn.FanSpeed = NULL;
00155 pInst->pfn.KeyEvent = NULL;
00156 pInst->pfn.Temp = NULL;
00157
00158
00159 pInst->context.FanSpeed = NULL;
00160 pInst->context.KeyEvent = NULL;
00161 pInst->context.Temp = NULL;
00162
00163
00164
00165
00166 pFnArray->Dispose = driver_Dispose;
00167 pFnArray->Start = driver_Start;
00168 pFnArray->Stop = driver_Stop;
00169 pFnArray->SetBacklight = driver_SetBacklight;
00170 pFnArray->GetScreenSize = driver_GetScreenSize;
00171 pFnArray->SetFanPower = driver_SetFanPower;
00172 pFnArray->WriteText = driver_WriteText;
00173 pFnArray->EnableFanReport = driver_EnableFanReport;
00174 pFnArray->DisableFanReport = driver_DisableFanReport;
00175 pFnArray->SetCallbackFan = driver_SetCallbackFan;
00176 pFnArray->SetContrast = driver_SetContrast;
00177 pFnArray->EnableTempReport = driver_EnableTempReport;
00178 pFnArray->DisableTempReport = driver_DisableTempReport;
00179 pFnArray->SetCallbackTemp = driver_SetCallbackTemp;
00180
00181
00182
00183
00184
00185
00186
00187 rc = cfontz_InitDevice(pInst);
00188 if (rc) {
00189 goto end_of_function;
00190 }
00191
00192
00193 SLEEP(350);
00194
00195
00196 rc = pthread_create(&(pInst->RxThreadID), NULL, RxThread, (void *) pInst);
00197 if (rc) {
00198 traceError(IILC_TRACE_CONTEXT, "pthread_create error %d (%s)\n", errno, strerror(errno));
00199 goto end_of_function;
00200 }
00201
00202
00203
00204
00205
00206
00207 packetCreate(PACKET_TYPE_GET_VERSION_INFO, &pPacket);
00208 cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00209 packetDispose(&pPacket);
00210
00211
00212 if (pReplyPacket != NULL) {
00213 if (packetGetClass(pReplyPacket) != PACKET_CLASS_NORMAL_RESPONSE) {
00214 traceError(IILC_TRACE_CONTEXT, "Invalid response to hardware version request");
00215 }
00216 }
00217 else {
00218 traceError(IILC_TRACE_CONTEXT, "No response to hardware version request");
00219 }
00220
00221
00222
00223 memset((void *) pszVersionInfo, 0, MAX_DATA_LENGTH + 1);
00224
00225
00226 while (packetReadData(pReplyPacket, (unsigned char *) &pszVersionInfo[i++]) != ERR_END_OF_PACKET);
00227
00228
00229 traceDebug(IILC_TRACE_CONTEXT, "Connected to CrystalFontz hardware [%s]", pszVersionInfo);
00230
00231
00232 rc = cfontz_InitDeviceType(pInst, pszVersionInfo);
00233 if (rc) { goto end_of_function; }
00234
00235
00236 if (pInst->nFanCount > 0) {
00237
00238
00239 pInst->nFanPower = (unsigned int *) calloc(pInst->nFanCount, sizeof(unsigned int));
00240 for (i = 0; i < pInst->nFanCount; i++) {
00241 pInst->nFanPower[i] = 100;
00242 }
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 *ppDriverInstData = (LP_DRIVER_INSTANCE) pInst;
00264
00265 end_of_function:
00266
00267 IILC_TRACE_EXIT_RC(rc);
00268 return rc;
00269
00270 }
00271
00272 int cfontz_detectSCAB(LP_CFONTZ_DEV_INSTANCE pInst)
00273 {
00274 int rc = 0;
00275
00276 unsigned char gpio = 0;
00277 unsigned char state = 0;
00278
00279 LPPACKET pPacket = NULL, pReplyPacket = NULL;
00280
00281
00282 pInst->bSCABPresent = 0;
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 packetCreate(PACKET_TYPE_SET_GPIO, &pPacket);
00300 packetWriteData(pPacket, 4);
00301 packetWriteData(pPacket, 0);
00302 packetWriteData(pPacket, 8);
00303 cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00304
00305
00306 if (packetGetClass(pReplyPacket) != PACKET_CLASS_NORMAL_RESPONSE) {
00307
00308 }
00309
00310
00311 packetDispose(&pPacket);
00312 packetDispose(&pReplyPacket);
00313
00314
00315 packetCreate(PACKET_TYPE_GET_GPIO, &pPacket);
00316 packetWriteData(pPacket, 4);
00317 cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00318
00319
00320 if (packetGetClass(pReplyPacket) != PACKET_CLASS_NORMAL_RESPONSE) {
00321
00322 }
00323
00324
00325 packetReadData(pReplyPacket, &gpio);
00326 packetReadData(pReplyPacket, &state);
00327
00328 if (gpio == 4 && state > 0) {
00329
00330 pInst->bSCABPresent = 1;
00331 }
00332
00333
00334 packetDispose(&pPacket);
00335 packetDispose(&pReplyPacket);
00336
00337
00338 packetCreate(PACKET_TYPE_SET_GPIO, &pPacket);
00339 packetWriteData(pPacket, 4);
00340 packetWriteData(pPacket, 0);
00341 packetWriteData(pPacket, 7);
00342 cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00343
00344
00345 packetDispose(&pPacket);
00346 packetDispose(&pReplyPacket);
00347
00348 return (rc);
00349 }
00350
00351
00352 int driver_Dispose(LP_DRIVER_INSTANCE * ppDriverInstData)
00353 {
00354 int rc = 0;
00355
00356 LP_CFONTZ_DEV_INSTANCE * ppInst = (LP_CFONTZ_DEV_INSTANCE *) ppDriverInstData;
00357 LP_CFONTZ_DEV_INSTANCE pInst = NULL;
00358 void * pTermValue = NULL;
00359
00360 if (ppInst == NULL || *ppInst == NULL) {
00361 rc = ERR_BAD_PARAMETER;
00362 goto end_of_function;
00363 }
00364
00365
00366 pInst = *ppInst;
00367
00368
00369 pInst->keyPressMask = 0;
00370 pInst->keyReleaseMask = 0;
00371 cfontz_UpdateKeyReport(pInst);
00372
00373
00374 pInst->tempReportMask = 0;
00375 cfontz_UpdateTempReport(pInst);
00376
00377
00378 pInst->fanReportMask = 0;
00379 cfontz_UpdateFanReport(pInst);
00380
00381
00382 pInst->RxRunning = 0;
00383
00384
00385 pthread_join(pInst->RxThreadID, &pTermValue);
00386
00387
00388 #if defined(_WIN32)
00389 CloseHandle(pInst->Device);
00390 #else
00391 close(pInst->Device);
00392 #endif
00393
00394
00395
00396
00397 if (pInst->pszPort != NULL) {
00398 free(pInst->pszPort);
00399 }
00400
00401 free(pInst);
00402
00403 end_of_function:
00404
00405 return rc;
00406 }
00407
00408
00409 int driver_Start(LP_DRIVER_INSTANCE pDriverInstData)
00410 {
00411 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00412
00413 pInst->bStarted = 1;
00414
00415 return 0;
00416 }
00417
00418
00419 int driver_Stop(LP_DRIVER_INSTANCE pDriverInstData)
00420 {
00421 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00422
00423 pInst->bStarted = 0;
00424
00425 return 0;
00426 }
00427
00428
00429 int driver_GetScreenSize(LP_DRIVER_INSTANCE pDriverInstData,
00430 unsigned int * pnScreenWidth, unsigned int * pnScreenHeight)
00431 {
00432 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00433
00434 *pnScreenHeight = pInst->nHeight;
00435 *pnScreenWidth = pInst->nWidth;
00436
00437 return 0;
00438 }
00439
00440
00441 int driver_SetLED(LP_DRIVER_INSTANCE pDriverInstData, unsigned int led_id,
00442 unsigned int nRed, unsigned int nGreen, unsigned int nBlue)
00443 {
00444 int rc = 0;
00445 LPPACKET pPacket = NULL;
00446 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00447
00448 IILC_TRACE_ENTRY(IILC_MODULE, T_displaySetLED);
00449 traceDebug(IILC_TRACE_CONTEXT,
00450 "pInst %p, led_id %u, nRed %u, nGreen %u, nBlue %u",
00451 pInst, led_id, nRed, nGreen, nBlue);
00452
00453
00454
00455
00456 packetCreate(PACKET_TYPE_SET_GPIO, &pPacket);
00457 packetWriteData(pPacket, 11 - (led_id * 2));
00458 packetWriteData(pPacket, (unsigned char) nGreen);
00459 cfontz_WritePacket(pInst, pPacket, NULL);
00460 packetDispose(&pPacket);
00461
00462
00463 packetCreate(PACKET_TYPE_SET_GPIO, &pPacket);
00464 packetWriteData(pPacket, 12 - (led_id * 2));
00465 packetWriteData(pPacket, (unsigned char) nRed);
00466 cfontz_WritePacket(pInst, pPacket, NULL);
00467 packetDispose(&pPacket);
00468
00469 IILC_TRACE_EXIT_RC(rc);
00470 return (rc);
00471 }
00472
00473
00474 int driver_SetFanFailsafeTimeout(LP_DRIVER_INSTANCE pDriverInstData, unsigned int mask, int milliseconds)
00475 {
00476 int rc = 0, timeout = 0;
00477 PACKET_TYPE replyType = 0;
00478 LPPACKET pPacket = NULL, pReplyPacket = NULL;
00479 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00480
00481
00482 timeout = milliseconds / 125;
00483
00484
00485 if (timeout == 0) { timeout++; }
00486 else if (timeout > 255) { timeout = 255; }
00487
00488 rc = packetCreate(PACKET_TYPE_SET_FAN_FAILSAFE, &pPacket);
00489 if (rc) { goto end_of_function; }
00490
00491 rc = packetWriteData(pPacket, mask);
00492 if (rc) { goto end_of_function; }
00493
00494 rc = packetWriteData(pPacket, timeout);
00495 if (rc) { goto end_of_function; }
00496
00497 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00498 if (rc) { goto end_of_function; }
00499
00500 rc = packetGetType(pReplyPacket, &replyType);
00501 if (replyType != (PACKET_TYPE_SET_FAN_FAILSAFE | 0x40)) {
00502 printf("Bad packet ack received for temperature reporting (%d)\n", replyType);
00503 rc = -1;
00504 }
00505
00506 end_of_function:
00507
00508
00509 if (pPacket != NULL) {
00510 (void) packetDispose(&pPacket);
00511 }
00512
00513 if (pReplyPacket != NULL) {
00514 (void) packetDispose(&pReplyPacket);
00515 }
00516
00517 return rc;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 int cfontz_WritePacket(LP_CFONTZ_DEV_INSTANCE pDevice, LPPACKET pPacket, LPPACKET * ppReplyPacket)
00534 {
00535 int rc = 0;
00536 int run, ret;
00537
00538 struct timespec timeToWait;
00539
00540 unsigned char buf[1024];
00541 int bufLen = sizeof(buf) / sizeof(buf[0]);
00542 int dataLen = bufLen;
00543
00544 LPPACKET pReplyPacket = NULL;
00545
00546 IILC_TRACE_ENTRY(IILC_MODULE, T_deviceWritePacket);
00547 traceDebug(IILC_TRACE_CONTEXT,
00548 "pDevice %p, pPacket %p, ppReplyPacket %p", pDevice, pPacket, ppReplyPacket);
00549
00550 IILC_ASSERT(pDevice != NULL);
00551 IILC_ASSERT(pPacket != NULL);
00552
00553
00554
00555 rc = packetFlatten(pPacket, buf, &dataLen);
00556 if (rc) {
00557 traceDebug(IILC_TRACE_CONTEXT, "Failure while flattening packet %d", rc);
00558 goto end_of_function;
00559 }
00560
00561
00562
00563
00564
00565 for (run = 0; run < 10; run++) {
00566
00567 #if defined(_WIN32)
00568 rc = WriteFile(pDevice->Device, buf, dataLen, &ret, NULL);
00569 if (!rc) {
00570 printf("WriteFile failed\n");
00571 }
00572 #else
00573 ret = write(pDevice->Device, buf, dataLen);
00574 #endif
00575
00576 if (ret < 0) {
00577 traceDebug(IILC_TRACE_CONTEXT, "write %d %s", ret, strerror(errno));
00578 }
00579 else {
00580 break;
00581 }
00582 if (run > 0) {
00583 traceDebug(IILC_TRACE_CONTEXT, "write(): EAGAIN #%d", run);
00584 }
00585
00586 SLEEP(1);
00587 }
00588
00589 if (ret < 0) {
00590 traceDebug(IILC_TRACE_CONTEXT, "write() failed; %s", strerror(errno));
00591 goto end_of_function;
00592 }
00593 else if (ret != dataLen) {
00594 traceDebug(IILC_TRACE_CONTEXT, "partial write(): len=%d ret=%d", dataLen, ret);
00595 goto end_of_function;
00596 }
00597
00598
00599
00600
00601
00602
00603 rc = pthread_mutex_lock(&pDevice->RxMutex);
00604 if (rc) {
00605 printf("Rx mutex lock failed: %s\n", strerror(errno));
00606 goto end_of_function;
00607 }
00608
00609
00610 {
00611 unsigned int milliseconds = 250;
00612
00613 clock_gettime(CLOCK_REALTIME, &timeToWait);
00614
00615 timeToWait.tv_nsec += (milliseconds % 1000) * 1000000;
00616 timeToWait.tv_sec += (milliseconds / 1000);
00617
00618
00619 if (timeToWait.tv_nsec > 1000000000) {
00620 timeToWait.tv_sec++;
00621 timeToWait.tv_nsec -= 1000000000;
00622 }
00623 }
00624
00625
00626 rc = pthread_cond_timedwait(&(pDevice->RxSemaphore), &(pDevice->RxMutex), &timeToWait);
00627
00628 if (pDevice->pReplyPacket == NULL) {
00629 printf("No reply packet! rc = %d\n", rc);
00630 exit(1);
00631 }
00632
00633 if (rc == ETIMEDOUT) {
00634
00635 packetCreate(0xFF, &(pDevice->pReplyPacket));
00636 }
00637 else if (rc) {
00638 printf("Wait on semaphore failed: %s\n", strerror(errno));
00639 goto end_of_function;
00640 }
00641
00642
00643 pReplyPacket = pDevice->pReplyPacket;
00644 pDevice->pReplyPacket = NULL;
00645
00646
00647 rc = pthread_mutex_unlock(&(pDevice->RxMutex));
00648 if (rc) {
00649 printf("Rx mutex unlock failed: %s\n", strerror(errno));
00650 goto end_of_function;
00651 }
00652
00653
00654
00655 if (pReplyPacket != NULL) {
00656
00657 if (ppReplyPacket != NULL) {
00658 *ppReplyPacket = pReplyPacket;
00659 }
00660 else {
00661 packetDispose(&pReplyPacket);
00662 }
00663 }
00664
00665 end_of_function:
00666
00667 IILC_TRACE_EXIT_RC(rc);
00668 return rc;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 void * RxThread(void * arg)
00678 {
00679 LP_CFONTZ_DEV_INSTANCE pDevice = (LP_CFONTZ_DEV_INSTANCE) arg;
00680
00681 int bytesRead = 0;
00682 int bytesAvail = 0;
00683 int ret;
00684
00685 unsigned char buf[1024];
00686 int bufLen = sizeof(buf) / sizeof(buf[0]);
00687
00688 do {
00689 int rc = 0;
00690 LPPACKET pReplyPacket = NULL;
00691
00692
00693 #if defined(_WIN32)
00694 rc = ReadFile(pDevice->Device, &buf[bytesAvail], bufLen - bytesAvail, &ret, NULL);
00695 if (!rc) {
00696 printf("ReadFile failed\n");
00697 }
00698 #else
00699 ret = read(pDevice->Device, &buf[bytesAvail], bufLen - bytesAvail);
00700 #endif
00701
00702 if (ret < 0 && errno == EAGAIN) {
00703
00704 SLEEP(10);
00705 continue;
00706 }
00707
00708
00709 bytesAvail += ret;
00710
00711
00712 bytesRead = 0;
00713
00714 do {
00715
00716
00717 rc = packetInflate(buf, bytesAvail, &bytesRead, &pReplyPacket);
00718
00719
00720 if (bytesRead > 0) {
00721 bytesAvail -= bytesRead;
00722 memmove(buf, buf + bytesRead, bytesAvail);
00723 }
00724
00725
00726 if (rc == 0) {
00727
00728
00729 int packetClass = packetGetClass(pReplyPacket);
00730 switch (packetClass) {
00731
00732
00733 case PACKET_CLASS_NORMAL_REPORT:
00734 {
00735
00736 PACKET_TYPE packetType;
00737 packetGetType(pReplyPacket, &packetType);
00738
00739
00740 if (pDevice->bStarted) {
00741
00742
00743 switch (packetType) {
00744
00745 case PACKET_TYPE_RPT_TEMP_SENSOR:
00746 cfontz_ReceiveTempReport(pDevice, pReplyPacket);
00747 break;
00748
00749 case PACKET_TYPE_RPT_FAN_SPEED:
00750 cfontz_ReceiveFanSpeedReport(pDevice, pReplyPacket);
00751 break;
00752
00753 case PACKET_TYPE_RPT_KEY_ACTIVITY:
00754 cfontz_ReceiveKeyPressReport(pDevice, pReplyPacket);
00755 break;
00756
00757 default:
00758 printf("Unknown packet type (%X)\n", packetType);
00759 break;
00760 }
00761 }
00762 break;
00763 }
00764
00765
00766 case PACKET_CLASS_NORMAL_RESPONSE:
00767 case PACKET_CLASS_ERROR_RESPONSE:
00768 {
00769 PACKET_TYPE ptype;
00770 packetGetType(pReplyPacket, &ptype);
00771
00772
00773 rc = pthread_mutex_lock(&pDevice->RxMutex);
00774 if (rc) {
00775 printf("Rx mutex lock failed: %s\n", strerror(errno));
00776 break;
00777 }
00778
00779
00780 pDevice->pReplyPacket = pReplyPacket;
00781 pReplyPacket = NULL;
00782
00783
00784 rc = pthread_cond_signal(&(pDevice->RxSemaphore));
00785 if (rc) {
00786 printf("Rx semaphore signal failed: %s\n", strerror(errno));
00787 break;
00788 }
00789
00790
00791 rc = pthread_mutex_unlock(&(pDevice->RxMutex));
00792 if (rc) {
00793 printf("Rx mutex unlock failed: %s\n", strerror(errno));
00794 break;
00795 }
00796
00797 break;
00798 }
00799
00800
00801 case PACKET_CLASS_NORMAL_REQUEST:
00802 printf("Strange packet type received\n");
00803 break;
00804
00805
00806 default:
00807 printf("Unable to determine packet class\n");
00808 break;
00809 }
00810
00811
00812 if (pReplyPacket != NULL) {
00813 packetDispose(&pReplyPacket);
00814 }
00815 }
00816 else if (rc == ERR_INSUFFICIENT_DATA) {
00817
00818 SLEEP(10);
00819 break;
00820 }
00821 else {
00822
00823 printf("Fatal error from packet inflate %d\n", rc);
00824 break;
00825 }
00826
00827 } while (bytesAvail > 0);
00828
00829 } while (pDevice->RxRunning);
00830
00831 return NULL;
00832 }
00833
00834 int driver_SetBacklight(LP_DRIVER_INSTANCE pDriverInstData, unsigned int backlightValue)
00835 {
00836 int rc = 0;
00837 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00838 LPPACKET pPacket = NULL, pReplyPacket = NULL;
00839
00840 rc = packetCreate(PACKET_TYPE_SET_BACKLIGHT, &pPacket);
00841 if (rc) { goto end_of_function; }
00842
00843 rc = packetWriteData(pPacket, backlightValue);
00844 if (rc) { goto end_of_function; }
00845
00846 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00847 if (rc) { goto end_of_function; }
00848
00849 end_of_function:
00850
00851 if (pPacket != NULL) {
00852 (void) packetDispose(&pPacket);
00853 }
00854 if (pReplyPacket != NULL) {
00855 (void) packetDispose(&pReplyPacket);
00856 }
00857
00858 return rc;
00859 }
00860
00861 int driver_SetContrast(LP_DRIVER_INSTANCE pDriverInstData, unsigned int contrastValue)
00862 {
00863 int rc = 0;
00864 LPPACKET pPacket = NULL;
00865 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00866
00867 rc = packetCreate(PACKET_TYPE_SET_LCD_CONTRAST, &pPacket);
00868 if (rc) { goto end_of_function; }
00869
00870 rc = packetWriteData(pPacket, contrastValue);
00871 if (rc) { goto end_of_function; }
00872
00873 rc = cfontz_WritePacket(pInst, pPacket, NULL);
00874 if (rc) { goto end_of_function; }
00875
00876 end_of_function:
00877
00878 if (pPacket != NULL) { packetDispose(&pPacket); }
00879
00880 return rc;
00881 }
00882
00883
00884 int driver_ClearScreen(LP_DRIVER_INSTANCE pDriverInstData)
00885 {
00886 int rc = 0;
00887 LPPACKET pPacket = NULL;
00888 LPPACKET pReplyPacket = NULL;
00889 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00890
00891 rc = packetCreate(PACKET_TYPE_CLEAR_SCREEN, &pPacket);
00892 if (rc) { goto end_of_function; }
00893
00894 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00895 if (rc) { goto end_of_function; }
00896
00897 end_of_function:
00898
00899 if (pPacket != NULL) { packetDispose(&pPacket); }
00900 if (pReplyPacket != NULL) { packetDispose(&pReplyPacket); }
00901
00902 return rc;
00903 }
00904
00905
00906
00907 int driver_WriteText(LP_DRIVER_INSTANCE pDriverInstData, unsigned int x, unsigned int y, char * strData, unsigned int width)
00908 {
00909 int rc = 0;
00910 LPPACKET pPacket = NULL, pReplyPacket = NULL;
00911 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00912
00913 rc = packetCreate(PACKET_TYPE_WRITE_DATA, &pPacket);
00914 if (rc) { goto end_of_function; }
00915
00916 rc = packetWriteData(pPacket, x);
00917 if (rc) { goto end_of_function; }
00918
00919 rc = packetWriteData(pPacket, y);
00920 if (rc) { goto end_of_function; }
00921
00922 rc = packetWriteString(pPacket, strData, width);
00923 if (rc) { goto end_of_function; }
00924
00925 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
00926 if (rc) { goto end_of_function; }
00927
00928 end_of_function:
00929
00930 if (pPacket) { packetDispose(&pPacket); }
00931 if (pReplyPacket) { packetDispose(&pReplyPacket); }
00932
00933 return rc;
00934 }
00935
00936
00937
00938 int driver_Restart(LP_DRIVER_INSTANCE pDriverInstData)
00939 {
00940 int rc = 0;
00941 LPPACKET pPacket = NULL;
00942 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00943
00944 rc = packetCreate(PACKET_TYPE_POWER_CONTROL, &pPacket);
00945 if (rc) { goto end_of_function; }
00946
00947 rc = packetWriteData(pPacket, 8);
00948 if (rc) { goto end_of_function; }
00949
00950 rc = packetWriteData(pPacket, 18);
00951 if (rc) { goto end_of_function; }
00952
00953 rc = packetWriteData(pPacket, 99);
00954 if (rc) { goto end_of_function; }
00955
00956 rc = cfontz_WritePacket(pInst, pPacket, NULL);
00957 if (rc) { goto end_of_function; }
00958
00959 end_of_function:
00960
00961
00962 if (pPacket != NULL) {
00963 (void) packetDispose(&pPacket);
00964 }
00965
00966 return rc;
00967 }
00968
00969 int driver_SetFanPower(LP_DRIVER_INSTANCE pDriverInstData, unsigned int fan_id, unsigned int nPower)
00970 {
00971 int rc = 0;
00972
00973 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
00974
00975 IILC_TRACE_ENTRY(IILC_MODULE, T_driver_SetFanPower);
00976 traceDebug(IILC_TRACE_CONTEXT, "pInst %p, fan_id %u, nPower %u", pInst, fan_id, nPower);
00977
00978
00979 if (pDriverInstData == NULL) {
00980 rc = ERR_BAD_PARAMETER;
00981 goto end_of_function;
00982 }
00983
00984
00985 if (fan_id >= pInst->nFanCount) {
00986 rc = ERR_BAD_PARAMETER;
00987 goto end_of_function;
00988 }
00989
00990
00991 if (nPower > 100) {
00992 rc = ERR_BAD_PARAMETER;
00993 goto end_of_function;
00994 }
00995
00996
00997 pInst->nFanPower[fan_id] = nPower;
00998
00999
01000 cfontz_UpdateFanPower(pInst);
01001
01002 end_of_function:
01003
01004 IILC_TRACE_EXIT_RC(rc);
01005 return rc;
01006 }
01007
01008 int cfontz_UpdateFanReport(LP_CFONTZ_DEV_INSTANCE pInst)
01009 {
01010 int rc = 0;
01011 LPPACKET pPacket = NULL;
01012 LPPACKET pReplyPacket = NULL;
01013
01014
01015 rc = packetCreate(PACKET_TYPE_SET_FAN_REPORTING, &pPacket);
01016 if (rc) { goto end_of_function; }
01017
01018 rc = packetWriteData(pPacket, pInst->fanReportMask);
01019 if (rc) { goto end_of_function; }
01020
01021 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
01022 if (rc) { goto end_of_function; }
01023
01024 end_of_function:
01025
01026 if (pPacket) packetDispose(&pPacket);
01027 if (pReplyPacket) packetDispose(&pReplyPacket);
01028
01029 return rc;
01030 }
01031
01032
01033 int cfontz_UpdateKeyReport(LP_CFONTZ_DEV_INSTANCE pInst)
01034 {
01035 int rc = 0;
01036 LPPACKET pPacket = NULL;
01037 LPPACKET pReplyPacket = NULL;
01038
01039
01040 rc = packetCreate(PACKET_TYPE_SET_KEY_REPORTING, &pPacket);
01041 if (rc) { goto end_of_function; }
01042
01043 rc = packetWriteData(pPacket, pInst->keyPressMask);
01044 if (rc) { goto end_of_function; }
01045
01046 rc = packetWriteData(pPacket, pInst->keyReleaseMask);
01047 if (rc) { goto end_of_function; }
01048
01049 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
01050 if (rc) { goto end_of_function; }
01051
01052 end_of_function:
01053
01054 if (pPacket) packetDispose(&pPacket);
01055 if (pReplyPacket) packetDispose(&pReplyPacket);
01056
01057 return rc;
01058 }
01059
01060 int driver_EnableFanReport(LP_DRIVER_INSTANCE pDriverInstData, unsigned int fan_id)
01061 {
01062 int rc = 0;
01063
01064 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01065
01066
01067 pInst->fanReportMask |= (1 << fan_id);
01068 rc = cfontz_UpdateFanReport(pInst);
01069
01070 return rc;
01071 }
01072
01073 int driver_DisableFanReport(LP_DRIVER_INSTANCE pDriverInstData, unsigned int fan_id)
01074 {
01075 int rc = 0;
01076
01077 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01078
01079
01080 pInst->fanReportMask &= ~(1 << fan_id);
01081 rc = cfontz_UpdateFanReport(pInst);
01082
01083 return rc;
01084 }
01085
01086 int driver_EnableTempReport(LP_DRIVER_INSTANCE pDriverInstData, unsigned int sensor_id)
01087 {
01088 int rc = 0;
01089
01090 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01091
01092
01093 pInst->tempReportMask |= (1 << sensor_id);
01094 rc = cfontz_UpdateTempReport(pInst);
01095
01096 return rc;
01097 }
01098
01099 int driver_DisableTempReport(LP_DRIVER_INSTANCE pDriverInstData, unsigned int sensor_id)
01100 {
01101 int rc = 0;
01102
01103 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01104
01105
01106 pInst->tempReportMask &= ~(1 << sensor_id);
01107 rc = cfontz_UpdateTempReport(pInst);
01108
01109 return rc;
01110 }
01111
01112
01113 int driver_SetTemperatureReporting(LP_DRIVER_INSTANCE pDriverInstData, unsigned int mask)
01114 {
01115 int rc = 0;
01116
01117 LPPACKET pPacket = NULL, pReplyPacket = NULL;
01118 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01119
01120 rc = packetCreate(PACKET_TYPE_SET_TEMP_REPORTING, &pPacket);
01121 if (rc) { goto end_of_function; }
01122
01123 rc = packetWriteData(pPacket, mask & 0x000000FF);
01124 if (rc) { goto end_of_function; }
01125
01126 rc = packetWriteData(pPacket, (mask & 0x0000FF00) >> 8);
01127 if (rc) { goto end_of_function; }
01128
01129 rc = packetWriteData(pPacket, (mask & 0x00FF0000) >> 16);
01130 if (rc) { goto end_of_function; }
01131
01132 rc = packetWriteData(pPacket, (mask & 0xFF000000) >> 24);
01133 if (rc) { goto end_of_function; }
01134
01135 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
01136 if (rc) { goto end_of_function; }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146 end_of_function:
01147
01148
01149 if (pPacket != NULL) {
01150 (void) packetDispose(&pPacket);
01151 }
01152
01153 if (pReplyPacket != NULL) {
01154 (void) packetDispose(&pReplyPacket);
01155 }
01156
01157 return rc;
01158 }
01159
01163 int cfontz_ReceiveFanSpeedReport(LP_CFONTZ_DEV_INSTANCE pInst, LPPACKET pPacket)
01164 {
01165 int rc = 0;
01166
01167
01168 unsigned int fanSpeed = 0;
01169
01170
01171 unsigned char LSB, MSB, fan_number, number_of_fan_tach_cycles;
01172
01173
01174 const int PPR = 2;
01175
01176
01177 unsigned short Fan_Timer_Ticks;
01178
01179 IILC_TRACE_ENTRY(IILC_MODULE, T_displayReceiveFanSpeedReport);
01180 traceDebug(IILC_TRACE_CONTEXT, "pInst %p, pPacket %p", pInst, pPacket);
01181
01182
01183 if (pInst->pfn.FanSpeed == NULL) {
01184 goto end_of_function;
01185 }
01186
01187
01188 if (!rc) { rc = packetReadData(pPacket, &fan_number); }
01189 if (!rc) { rc = packetReadData(pPacket, &number_of_fan_tach_cycles); }
01190 if (!rc) { rc = packetReadData(pPacket, &LSB); }
01191 if (!rc) { rc = packetReadData(pPacket, &MSB); }
01192 if (rc) {
01193 traceWarning(IILC_TRACE_CONTEXT, "Badly-formed fan speed report packet");
01194 goto end_of_function;
01195 }
01196
01197
01198 Fan_Timer_Ticks = (MSB << 8) + LSB;
01199
01200
01201 traceDebug(IILC_TRACE_CONTEXT,
01202 "fan_number " T_FMT_UINT " Fan_Timer_Ticks " T_FMT_UINT " Tach_Cycles " T_FMT_UINT,
01203 (unsigned int) fan_number, (unsigned int) Fan_Timer_Ticks, number_of_fan_tach_cycles);
01204
01205 if (number_of_fan_tach_cycles <= 3) {
01206 fanSpeed = 0;
01207 }
01208 else if (number_of_fan_tach_cycles <= 4) {
01209 fanSpeed = 1;
01210 }
01211 else if (number_of_fan_tach_cycles == 0xFF) {
01212 fanSpeed = 0XFFFFFFFF;
01213 }
01214 else {
01215
01216 fanSpeed = ((27692308L / PPR) * (unsigned long)(number_of_fan_tach_cycles - 3)) / (Fan_Timer_Ticks);
01217 }
01218
01219 traceDebug(IILC_TRACE_CONTEXT, "fan speed " T_FMT_UINT, fanSpeed);
01220
01221
01222 (pInst->pfn.FanSpeed)(pInst->context.FanSpeed, (unsigned int) fan_number, fanSpeed);
01223
01224 end_of_function:
01225
01226 IILC_TRACE_EXIT;
01227 return rc;
01228 }
01229
01230
01231 int cfontz_ReceiveKeyPressReport(LP_CFONTZ_DEV_INSTANCE pInst, LPPACKET pPacket)
01232 {
01233 unsigned char event;
01234
01235 IILC_TRACE_ENTRY(IILC_MODULE, T_displayReceiveKeyPressReport);
01236 traceDebug(IILC_TRACE_CONTEXT, "pInst %p, pPacket %p", pInst, pPacket);
01237
01238
01239 if (pInst->pfn.KeyEvent == NULL) {
01240 goto end_of_function;
01241 }
01242
01243
01244 packetReadData(pPacket, &event);
01245
01246
01247 (pInst->pfn.KeyEvent)(pInst->context.KeyEvent, 0);
01248
01249 end_of_function:
01250
01251 IILC_TRACE_EXIT;
01252 return 0;
01253 }
01254
01255
01259 int cfontz_ReceiveTempReport(LP_CFONTZ_DEV_INSTANCE pInst, LPPACKET pPacket)
01260 {
01261 int rc = 0;
01262
01263 double degc = 0.0;
01264 unsigned char sensor, MSB, LSB, DOW_crc_status;
01265 unsigned short report;
01266
01267 IILC_TRACE_ENTRY(IILC_MODULE, T_cfontz_ReceiveTempReport);
01268 traceDebug(IILC_TRACE_CONTEXT, "pInst %p, pPacket %p", pInst, pPacket);
01269
01270
01271 if (pInst->pfn.Temp == NULL) {
01272 traceDebug(IILC_TRACE_CONTEXT, "No temp callbacks registered");
01273 goto end_of_function;
01274 }
01275
01276
01277 packetReadData(pPacket, &sensor);
01278 packetReadData(pPacket, &LSB);
01279 packetReadData(pPacket, &MSB);
01280 packetReadData(pPacket, &DOW_crc_status);
01281
01282
01283 if (DOW_crc_status == 0) {
01284 printf("Bad DOW CRC\n");
01285 rc = -1;
01286 goto end_of_function;
01287 }
01288
01289
01290 report = (MSB << 8) + LSB;
01291 degc = ((double) report) / 16.0;
01292
01293 (pInst->pfn.Temp)(pInst->context.Temp, sensor, degc);
01294
01295 end_of_function:
01296
01297 IILC_TRACE_EXIT_RC(rc);
01298 return rc;
01299 }
01300
01301
01302
01303 int driver_SetCallbackTemp(LP_DRIVER_INSTANCE pDriverInstData, pfnDrvCBTemp pfn, void * context)
01304 {
01305 int rc = 0;
01306 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01307
01308 pInst->pfn.Temp = pfn;
01309 pInst->context.Temp = context;
01310
01311 return rc;
01312 }
01313
01314 int driver_SetCallbackFan(LP_DRIVER_INSTANCE pDriverInstData, pfnDrvCBFanSpeed pfn, void * context)
01315 {
01316 int rc = 0;
01317 LP_CFONTZ_DEV_INSTANCE pInst = (LP_CFONTZ_DEV_INSTANCE) pDriverInstData;
01318
01319 pInst->pfn.FanSpeed = pfn;
01320 pInst->context.FanSpeed = context;
01321
01322 return rc;
01323 }
01324
01325 int cfontz_SetCallbackKeyEvent(LP_CFONTZ_DEV_INSTANCE pInst, pfnDrvCBKeyEvent pfn, void * context)
01326 {
01327 pInst->pfn.KeyEvent = pfn;
01328 pInst->context.KeyEvent = context;
01329 return 0;
01330 }
01331
01332
01333 int cfontz_InitDeviceType(LP_CFONTZ_DEV_INSTANCE pInst, const char * pszVersionString)
01334 {
01335 int rc = 0;
01336
01337 IILC_TRACE_ENTRY(IILC_MODULE, T_cfontz_InitDeviceType);
01338
01339 if (strncmp(pszVersionString, CFONTZ_CFA635_STRING, strlen(CFONTZ_CFA635_STRING)) == 0) {
01340
01341
01342 pInst->deviceType = CFONTZ_DEVICE_TYPE_CFA635;
01343 pInst->nHeight = 4;
01344 pInst->nWidth = 20;
01345 pInst->nLEDCount = 4;
01346 pInst->nFanCount = 0;
01347
01348
01349 rc = cfontz_detectSCAB(pInst);
01350 if (rc) { goto end_of_function; }
01351
01352
01353 if (pInst->bSCABPresent) {
01354
01355
01356 pInst->nFanCount = 4;
01357 }
01358 }
01359 else if (strncmp(pszVersionString, CFONTZ_CFA633_STRING, strlen(CFONTZ_CFA633_STRING)) == 0) {
01360
01361
01362 pInst->deviceType = CFONTZ_DEVICE_TYPE_CFA633;
01363 pInst->nHeight = 2;
01364 pInst->nWidth = 16;
01365 pInst->nLEDCount = 0;
01366 pInst->nFanCount = 0;
01367 }
01368 else {
01369 traceDebug(IILC_TRACE_CONTEXT, "Did not recognise device type");
01370 }
01371
01372 end_of_function:
01373
01374 IILC_TRACE_EXIT_RC(rc);
01375 return rc;
01376 }
01377
01378 int cfontz_UpdateFanPower(LP_CFONTZ_DEV_INSTANCE pInst)
01379 {
01380 int rc = 0;
01381 int i = 0;
01382
01383 LPPACKET pPacket = NULL, pReplyPacket = NULL;
01384
01385
01386 if (pInst == NULL) {
01387 rc = ERR_BAD_PARAMETER;
01388 goto end_of_function;
01389 }
01390
01391
01392 rc = packetCreate(PACKET_TYPE_SET_FAN_POWER, &pPacket);
01393 if (rc) { goto end_of_function; }
01394
01395
01396 for (i = 0; i < pInst->nFanCount; i++) {
01397 packetWriteData(pPacket, pInst->nFanPower[i]);
01398 }
01399
01400
01401 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
01402 if (rc) { goto end_of_function; }
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 end_of_function:
01413
01414
01415 if (pPacket) { (void) packetDispose(&pPacket); }
01416 if (pReplyPacket) { (void) packetDispose(&pReplyPacket); }
01417
01418 return rc;
01419
01420
01421 }
01422
01430 int cfontz_UpdateTempReport(LP_CFONTZ_DEV_INSTANCE pInst)
01431 {
01432 int rc = 0;
01433 int i = 0;
01434
01435 LPPACKET pPacket = NULL, pReplyPacket = NULL;
01436 PACKET_TYPE replyType;
01437
01438 IILC_TRACE_ENTRY(IILC_MODULE, T_cfontz_UpdateTempReport);
01439
01440
01441 if (pInst == NULL) {
01442 rc = ERR_BAD_PARAMETER;
01443 goto end_of_function;
01444 }
01445
01446
01447 rc = packetCreate(PACKET_TYPE_SET_TEMP_REPORTING, &pPacket);
01448 if (rc) { goto end_of_function; }
01449
01450
01451 for (i = 0; i < 4; i++) {
01452 unsigned int val = (pInst->tempReportMask & (0xFF << (i*8))) >> (i*8);
01453 packetWriteData(pPacket, (unsigned char) val);
01454 traceDebug(IILC_TRACE_CONTEXT, "Written data %u", val);
01455 }
01456
01457
01458 rc = cfontz_WritePacket(pInst, pPacket, &pReplyPacket);
01459 if (rc) { goto end_of_function; }
01460
01461 rc = packetGetType(pReplyPacket, &replyType);
01462 if (replyType != (PACKET_TYPE_SET_TEMP_REPORTING | 0x40)) {
01463 traceError(IILC_TRACE_CONTEXT,
01464 "Bad packet ack received for temperature reporting (%d)\n", replyType);
01465 rc = -1;
01466 goto end_of_function;
01467 }
01468
01469 end_of_function:
01470
01471
01472 if (pPacket) { (void) packetDispose(&pPacket); }
01473 if (pReplyPacket) { (void) packetDispose(&pReplyPacket); }
01474
01475 IILC_TRACE_EXIT_RC(rc);
01476 return rc;
01477
01478
01479 }