00001
00028 #include "si114x_functions.h"
00029
00030
00031
00032
00033
00034 #ifndef INCLUDE_SI114X_CALIBRATIONCODE
00035
00041 #define INCLUDE_SI114X_CALIBRATIONCODE 1
00042 #endif
00043
00044
00045
00046 #ifndef INCLUDE_SI114X_COMPRESS_CODE
00047
00054 #define INCLUDE_SI114X_COMPRESS_CODE 1
00055 #endif
00056
00057 #define LOOP_TIMEOUT_MS 200
00058
00062 static int16_t _waitUntilSleep(HANDLE si114x_handle)
00063 {
00064 int8_t retval = -1;
00065 uint8_t count = 0;
00066
00067
00068 while(count < LOOP_TIMEOUT_MS)
00069 {
00070 retval = Si114xReadFromRegister(si114x_handle, REG_CHIP_STAT);
00071 if(retval == 1) break;
00072 if(retval < 0) return retval;
00073 count++;
00074 delay_1ms();
00075 }
00076 return 0;
00077 }
00078
00079
00090 int16_t Si114xReset(HANDLE si114x_handle)
00091 {
00092 int32_t retval = 0;
00093
00094
00095
00096
00097
00098
00099
00100 delay_10ms();
00101 delay_10ms();
00102 delay_10ms();
00103
00104 retval+=Si114xWriteToRegister(si114x_handle, REG_MEAS_RATE, 0x00);
00105 retval+=Si114xWriteToRegister(si114x_handle, REG_ALS_RATE, 0x00);
00106 retval+=Si114xPauseAll(si114x_handle);
00107
00108
00109
00110 retval+=Si114xWriteToRegister(si114x_handle, REG_MEAS_RATE, 0x00);
00111 retval+=Si114xWriteToRegister(si114x_handle, REG_IRQ_ENABLE, 0x00);
00112 retval+=Si114xWriteToRegister(si114x_handle, REG_IRQ_MODE1, 0x00);
00113 retval+=Si114xWriteToRegister(si114x_handle, REG_IRQ_MODE2, 0x00);
00114 retval+=Si114xWriteToRegister(si114x_handle, REG_INT_CFG , 0x00);
00115 retval+=Si114xWriteToRegister(si114x_handle, REG_IRQ_STATUS, 0xFF);
00116
00117
00118 retval+=Si114xWriteToRegister(si114x_handle, REG_COMMAND, 1);
00119
00120
00121
00122 delay_10ms();
00123
00124
00125 retval+=Si114xWriteToRegister(si114x_handle, REG_HW_KEY, HW_KEY_VAL0);
00126
00127 return retval;
00128 }
00129
00130
00134 static int16_t _sendCmd(HANDLE si114x_handle, uint8_t command)
00135 {
00136 int16_t response;
00137 int8_t retval;
00138 uint8_t count = 0;
00139
00140
00141 response = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00142 if(response < 0)
00143 return response;
00144
00145
00146 while(count < LOOP_TIMEOUT_MS)
00147 {
00148 if((retval=_waitUntilSleep(si114x_handle)) != 0) return retval;
00149
00150 if(command==0) break;
00151
00152 retval=Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00153 if(retval==response) break;
00154 else if(retval<0) return retval;
00155 else response = retval;
00156 count++;
00157 }
00158
00159
00160 if((retval=Si114xWriteToRegister(si114x_handle, REG_COMMAND, command)) !=0)
00161 return retval;
00162
00163 count = 0;
00164
00165 while(count < LOOP_TIMEOUT_MS)
00166 {
00167 if(command==0) break;
00168
00169 retval= Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00170 if(retval != response) break;
00171 else if(retval<0) return retval;
00172 count++;
00173 delay_1ms();
00174 }
00175 return 0;
00176 }
00177
00178
00186 int16_t Si114xNop(HANDLE si114x_handle)
00187 {
00188 return _sendCmd(si114x_handle,0x00);
00189 }
00190
00191
00201 int16_t Si114xPsForce(HANDLE si114x_handle)
00202 {
00203 return _sendCmd(si114x_handle,0x05);
00204 }
00205
00206
00216 int16_t Si114xAlsForce(HANDLE si114x_handle)
00217 {
00218 return _sendCmd(si114x_handle,0x06);
00219 }
00220
00221
00231 int16_t Si114xPsAlsForce(HANDLE si114x_handle)
00232 {
00233 return _sendCmd(si114x_handle,0x07);
00234 }
00235
00236
00246 int16_t Si114xPsAlsAuto (HANDLE si114x_handle)
00247 {
00248 return _sendCmd(si114x_handle,0x0F);
00249 }
00250
00251
00263 int16_t Si114xParamRead(HANDLE si114x_handle, uint8_t address)
00264 {
00265
00266 int16_t retval;
00267 uint8_t cmd = 0x80 + (address & 0x1F);
00268
00269 retval=_sendCmd(si114x_handle, cmd);
00270 if( retval != 0 ) return retval;
00271
00272 retval = Si114xReadFromRegister(si114x_handle, REG_PARAM_RD);
00273 return retval;
00274 }
00275
00276
00296 int16_t Si114xParamSet(HANDLE si114x_handle, uint8_t address, uint8_t value)
00297 {
00298 int16_t retval;
00299 uint8_t buffer[2];
00300 int16_t response_stored;
00301 int16_t response;
00302
00303 if((retval = _waitUntilSleep(si114x_handle))!=0) return retval;
00304
00305 response_stored = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00306
00307 buffer[0]= value;
00308 buffer[1]= 0xA0 + (address & 0x1F);
00309
00310 retval=Si114xBlockWrite(si114x_handle, REG_PARAM_WR, 2, ( uint8_t* ) buffer);
00311 if(retval != 0) return retval;
00312
00313
00314 response = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00315 while(response == response_stored )
00316 {
00317 response = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00318 if (response == response_stored)
00319 {
00320 delay_1ms();
00321 }
00322 }
00323
00324 if(retval < 0)
00325 return retval;
00326 else
00327 return 0;
00328 }
00329
00330
00334 static int16_t _PsAlsPause (HANDLE si114x_handle)
00335 {
00336 return _sendCmd(si114x_handle,0x0B);
00337 }
00338
00339
00349 int16_t Si114xPauseAll(HANDLE si114x_handle)
00350 {
00351 uint8_t countA, countB;
00352 int8_t retval;
00353
00354
00355
00356
00357
00358
00359
00360 retval = 0;
00361 while(retval != 0x01)
00362 {
00363 retval = Si114xReadFromRegister( si114x_handle, REG_CHIP_STAT);
00364 if (retval != 0x01)
00365 {
00366 delay_1ms();
00367 }
00368 }
00369
00370 countA = 0;
00371 while(countA < LOOP_TIMEOUT_MS)
00372 {
00373 countB = 0;
00374
00375 while(countB < LOOP_TIMEOUT_MS)
00376 {
00377 retval = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00378 if( retval == 0 )
00379 break;
00380 else
00381 {
00382
00383
00384
00385 Si114xWriteToRegister(si114x_handle, REG_COMMAND, 0x00);
00386 }
00387 countB++;
00388 delay_1ms();
00389 }
00390
00391
00392 _PsAlsPause(si114x_handle);
00393
00394 countB = 0;
00395
00396 while(countB < LOOP_TIMEOUT_MS)
00397 {
00398 retval = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00399 if( retval !=0 )
00400 break;
00401 countB++;
00402 delay_1ms();
00403 }
00404
00405
00406 retval = Si114xReadFromRegister(si114x_handle, REG_RESPONSE);
00407 if( retval == 1 )
00408 break;
00409 countA++;
00410 }
00411 return 0;
00412 }
00413
00414
00415
00416
00417 #if( INCLUDE_SI114X_COMPRESS_CODE == 1 )
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00551 uint16_t Uncompress(uint8_t input)
00552
00553 {
00554 uint16_t output = 0;
00555 uint8_t exponent = 0;
00556
00557
00558
00559
00560
00561
00562
00563 if( input < 8 ) return 0;
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 exponent = (input & 0xF0 ) >> 4;
00577 output = 0x10 | (input & 0x0F);
00578
00579
00580 if( exponent >= 4 ) return ( output << (exponent-4) );
00581 return( output >> (4-exponent) );
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00639 uint8_t Compress(uint16_t input)
00640 {
00641 uint32_t tmp = 0;
00642 uint32_t exponent = 0;
00643 uint32_t significand = 0;
00644
00645 if(input==0)
00646 return 0;
00647
00648
00649
00650
00651
00652
00653
00654
00655 if(input == 0x0000) return 0x00;
00656 if(input == 0x0001) return 0x08;
00657
00658
00659
00660 exponent = 0;
00661 tmp = input;
00662 while(1)
00663 {
00664 tmp >>= 1;
00665
00666 exponent += 1;
00667 if(tmp == 1)
00668 {
00669 break;
00670 }
00671 }
00672
00673
00674
00675
00676
00677
00678 if(exponent < 5)
00679
00680 {
00681 significand = ( input << (4 - exponent) ) ;
00682 return ( (exponent << 4) | (significand & 0xF));
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 significand = input >> (exponent - 5);
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 if(significand & 1)
00711 {
00712 significand += 2;
00713
00714
00715
00716
00717 if(significand & 0x0040)
00718 {
00719 exponent += 1;
00720 significand >>= 1;
00721 }
00722 }
00723
00724
00725 return ( (exponent << 4) | ( (significand >> 1) & 0xF ) );
00726 }
00727 #endif // INCLUDE_SI114X_COMPRESS_CODE
00728
00729
00730
00731
00732
00733
00734
00735
00737
00738 #define FLT_TO_FX20(x) ((int32_t)((x*1048576)+.5))
00739 #define FX20_ONE FLT_TO_FX20( 1.000000)
00740 #define FX20_BAD_VALUE 0xffffffff
00741
00742
00743 #if(INCLUDE_SI114X_CALIBRATIONCODE == 1)
00744
00745
00746
00747
00748 #define SIRPD_ADCHI_IRLED (collect(buffer, 0x23, 0x22, 0))
00749 #define SIRPD_ADCLO_IRLED (collect(buffer, 0x22, 0x25, 1))
00750 #define SIRPD_ADCLO_WHLED (collect(buffer, 0x24, 0x26, 0))
00751 #define VISPD_ADCHI_WHLED (collect(buffer, 0x26, 0x27, 1))
00752 #define VISPD_ADCLO_WHLED (collect(buffer, 0x28, 0x29, 0))
00753 #define LIRPD_ADCHI_IRLED (collect(buffer, 0x29, 0x2a, 1))
00754 #define LED_DRV65 (collect(buffer, 0x2b, 0x2c, 0))
00755
00756
00757
00758 #ifdef SI114x_CAL_DEBUG
00759 #include "Si114x_cal_debug.c"
00760 #else
00761 #define DEBUG_PRINT_OUTPUT
00762 #define DEBUG_PRINT_OUTPUT_2
00763 #define DEBUG_UCOEF
00764 #endif
00765
00766
00767
00771 struct cal_ref_t
00772 {
00773 uint32_t sirpd_adchi_irled;
00774 uint32_t sirpd_adclo_irled;
00775 uint32_t sirpd_adclo_whled;
00776 uint32_t vispd_adchi_whled;
00777 uint32_t vispd_adclo_whled;
00778 uint32_t lirpd_adchi_irled;
00779 uint32_t ledi_65ma;
00780 uint8_t ucoef[4];
00781 };
00782
00783
00787 struct cal_ref_t calref[2] =
00788 {
00789 {
00790 FLT_TO_FX20( 4.021290),
00791 FLT_TO_FX20(57.528500),
00792 FLT_TO_FX20( 2.690010),
00793 FLT_TO_FX20( 0.042903),
00794 FLT_TO_FX20( 0.633435),
00795 FLT_TO_FX20(23.902900),
00796 FLT_TO_FX20(56.889300),
00797 {0x7B, 0x6B, 0x01, 0x00}
00798 },
00799 {
00800 FLT_TO_FX20( 2.325484),
00801 FLT_TO_FX20(33.541500),
00802 FLT_TO_FX20( 1.693750),
00803 FLT_TO_FX20( 0.026775),
00804 FLT_TO_FX20( 0.398443),
00805 FLT_TO_FX20(12.190900),
00806 FLT_TO_FX20(56.558200),
00807 {0xdb, 0x8f, 0x01, 0x00}
00808 }
00809 };
00810
00811
00816 static uint32_t decode(uint32_t input)
00817 {
00818 int32_t exponent, exponent_bias9;
00819 uint32_t mantissa;
00820
00821 if(input==0) return 0.0;
00822
00823 exponent_bias9 = (input & 0x0f00) >> 8;
00824 exponent = exponent_bias9 - 9;
00825
00826 mantissa = input & 0x00ff;
00827 mantissa |= 0x0100;
00828
00829
00830 mantissa = mantissa << (12+exponent);
00831 return mantissa;
00832 }
00833
00834
00841 static uint32_t collect(uint8_t* buffer,
00842 uint8_t msb_addr,
00843 uint8_t lsb_addr,
00844 uint8_t alignment)
00845 {
00846 uint16_t value;
00847 uint8_t msb_ind = msb_addr - 0x22;
00848 uint8_t lsb_ind = lsb_addr - 0x22;
00849
00850 if(alignment == 0)
00851 {
00852 value = buffer[msb_ind]<<4;
00853 value += buffer[lsb_ind]>>4;
00854 }
00855 else
00856 {
00857 value = buffer[msb_ind]<<8;
00858 value += buffer[lsb_ind];
00859 value &= 0x0fff;
00860 }
00861
00862 if( ( value == 0x0fff )
00863 || ( value == 0x0000 ) ) return FX20_BAD_VALUE;
00864 else return decode( value );
00865 }
00866
00867
00873 static void shift_left(uint32_t* value_p, int8_t shift)
00874 {
00875 if(shift > 0)
00876 *value_p = *value_p<<shift ;
00877 else
00878 *value_p = *value_p>>(-shift) ;
00879 }
00880
00882 #define ALIGN_LEFT 1
00883 #define ALIGN_RIGHT -1
00884
00885
00891 static int8_t align( uint32_t* value_p, int8_t direction )
00892 {
00893 int8_t local_shift, shift ;
00894 uint32_t mask;
00895
00896
00897 if( value_p == NULL ) return 0;
00898 if( *value_p == 0 ) return 0;
00899
00900
00901 switch( direction )
00902 {
00903 case ALIGN_LEFT:
00904 local_shift = 1 ;
00905 mask = 0x80000000L;
00906 break;
00907
00908 case ALIGN_RIGHT:
00909 local_shift = -1 ;
00910 mask = 0x00000001L;
00911 break;
00912
00913 default:
00914
00915 return 0;
00916 }
00917
00918 shift = 0;
00919 while(1)
00920 {
00921 if(*value_p & mask ) break;
00922 shift++;
00923 shift_left( value_p, local_shift );
00924 }
00925 return shift;
00926 }
00927
00928
00934 #define FORCE_ROUND_16 1
00935
00936
00946 static void fx20_round
00947 (
00948 uint32_t *value_p
00949 #if !FORCE_ROUND_16
00950 , int8_t round
00951 #endif
00952 )
00953 {
00954 int8_t shift;
00955
00956 #if FORCE_ROUND_16
00957
00958 uint32_t mask1 = 0xffff8000;
00959 uint32_t mask2 = 0xffff0000;
00960 uint32_t lsb = 0x00008000;
00961 #else
00962
00963
00964 uint32_t mask1 = ((2<<(round))-1)<<(31-(round));
00965 uint32_t mask2 = ((2<<(round-1))-1)<<(31-(round-1));
00966 uint32_t lsb = mask1-mask2;
00967 #endif
00968
00969 shift = align( value_p, ALIGN_LEFT );
00970 if( ( (*value_p)&mask1 ) == mask1 )
00971 {
00972 *value_p = 0x80000000;
00973 shift -= 1;
00974 }
00975 else
00976 {
00977 *value_p += lsb;
00978 *value_p &= mask2;
00979 }
00980
00981 shift_left( value_p, -shift );
00982 }
00983
00984
00989 struct operand_t
00990 {
00991 uint32_t op1;
00992 uint32_t op2;
00993 };
00994
00995
00999 static uint32_t fx20_divide( struct operand_t* operand_p )
01000 {
01001 int8_t numerator_sh=0, denominator_sh=0;
01002 uint32_t result;
01003 uint32_t* numerator_p;
01004 uint32_t* denominator_p;
01005
01006 if( operand_p == NULL ) return FX20_BAD_VALUE;
01007
01008 numerator_p = &operand_p->op1;
01009 denominator_p = &operand_p->op2;
01010
01011 if( (*numerator_p == FX20_BAD_VALUE)
01012 || (*denominator_p == FX20_BAD_VALUE)
01013 || (*denominator_p == 0 ) ) return FX20_BAD_VALUE;
01014
01015 fx20_round ( numerator_p );
01016 fx20_round ( denominator_p );
01017 numerator_sh = align ( numerator_p, ALIGN_LEFT );
01018 denominator_sh = align ( denominator_p, ALIGN_RIGHT );
01019
01020 result = *numerator_p / ( (uint16_t)(*denominator_p) );
01021 shift_left( &result , 20-numerator_sh-denominator_sh );
01022
01023 return result;
01024 }
01025
01026
01030 static uint32_t fx20_multiply( struct operand_t* operand_p )
01031 {
01032 uint32_t result;
01033 int8_t val1_sh, val2_sh;
01034 uint32_t* val1_p;
01035 uint32_t* val2_p;
01036
01037 if( operand_p == NULL ) return FX20_BAD_VALUE;
01038
01039 val1_p = &(operand_p->op1);
01040 val2_p = &(operand_p->op2);
01041
01042 fx20_round( val1_p );
01043 fx20_round( val2_p );
01044
01045 val1_sh = align( val1_p, ALIGN_RIGHT );
01046 val2_sh = align( val2_p, ALIGN_RIGHT );
01047
01048
01049 result = (uint32_t)( ( (uint32_t)(*val1_p) ) * ( (uint32_t)(*val2_p) ) );
01050 shift_left( &result, -20+val1_sh+val2_sh );
01051
01052 return result;
01053 }
01054
01055
01062 static int16_t find_cal_index( uint8_t* buffer )
01063 {
01064 int16_t index;
01065 uint8_t size;
01066
01067
01068 index = ( int16_t )( buffer[12] + ( (uint16_t)( buffer[13] ) << 8 ) );
01069
01070 switch( index )
01071 {
01072 case -1:
01073 index = 0;
01074 break;
01075 case -2:
01076 index = 0;
01077 break;
01078 case -3:
01079 index = 1;
01080 default:
01081 index = -(4+index) ;
01082 }
01083
01084 size = sizeof(calref)/sizeof(calref[0]);
01085
01086 if( index < size )
01087 {
01088 return index;
01089 }
01090 else
01091 {
01092 return -1;
01093 }
01094 }
01095
01096
01100 static uint32_t vispd_correction(uint8_t* buffer)
01101 {
01102
01103 struct operand_t op;
01104 uint32_t result;
01105 int16_t index = find_cal_index( buffer );
01106
01107 if( index < 0 ) result = FX20_ONE;
01108
01109 op.op1 = calref[ index ].vispd_adclo_whled;
01110 op.op2 = VISPD_ADCLO_WHLED;
01111 result = fx20_divide( &op );
01112
01113 if( result == FX20_BAD_VALUE ) result = FX20_ONE;
01114
01115 return result;
01116 }
01117
01118
01122 static uint32_t irpd_correction(uint8_t* buffer)
01123 {
01124 struct operand_t op;
01125 uint32_t result;
01126 int16_t index = find_cal_index( buffer );
01127
01128 if( index < 0 ) result = FX20_ONE;
01129
01130
01131 op.op1 = calref[ index ].sirpd_adclo_irled;
01132 op.op2 = SIRPD_ADCLO_IRLED;
01133 result = fx20_divide( &op );
01134
01135 if( result == FX20_BAD_VALUE ) result = FX20_ONE;
01136
01137 return result;
01138 }
01139
01140
01146 static uint32_t adcrange_ratio(uint8_t* buffer)
01147 {
01148 struct operand_t op;
01149 uint32_t result;
01150
01151 op.op1 = SIRPD_ADCLO_IRLED ; op.op2 = SIRPD_ADCHI_IRLED ;
01152 result = fx20_divide( &op );
01153
01154 if( result == FX20_BAD_VALUE ) result = FLT_TO_FX20( 14.5 );
01155
01156 return result;
01157 }
01158
01159
01164 static uint32_t irsize_ratio(uint8_t* buffer)
01165 {
01166 struct operand_t op;
01167 uint32_t result;
01168
01169 op.op1 = LIRPD_ADCHI_IRLED ; op.op2 = SIRPD_ADCHI_IRLED ;
01170
01171 result = fx20_divide( &op );
01172
01173 if( result == FX20_BAD_VALUE ) result = FLT_TO_FX20( 6.0 );
01174
01175 return result;
01176 }
01177
01178
01183 static uint32_t ledi_ratio(uint8_t* buffer)
01184 {
01185
01186 struct operand_t op;
01187 uint32_t result;
01188 int16_t index;
01189
01190 index = find_cal_index( buffer );
01191
01192 if( index < 0 ) result = FX20_ONE;
01193
01194
01195 op.op1 = calref[ index ].ledi_65ma;
01196 op.op2 = LED_DRV65;
01197 result = fx20_divide( &op );
01198
01199 if( result == FX20_BAD_VALUE ) result = FX20_ONE;
01200
01201 return result;
01202 }
01203
01204
01210 static int16_t si114x_get_cal_index( HANDLE si114x_handle, uint8_t* buffer )
01211 {
01212 int16_t retval;
01213 uint8_t response;
01214
01215 if( ( si114x_handle == NULL ) || ( buffer == NULL ) )
01216 return -1;
01217
01218
01219 do
01220 {
01221 retval = Si114xNop( si114x_handle );
01222 if( retval != 0 ) return -1;
01223
01224
01225 response = Si114xReadFromRegister( si114x_handle, REG_RESPONSE );
01226 if (response != 0)
01227 {
01228 delay_1ms();
01229 }
01230 } while( response != 0 );
01231
01232
01233 retval = Si114xWriteToRegister( si114x_handle, REG_COMMAND, 0x11 );
01234 _waitUntilSleep(si114x_handle);
01235
01236 if( retval != 0 ) return -1;
01237
01238 retval = Si114xBlockRead( si114x_handle, REG_PS1_DATA0, 2, &(buffer[12]) );
01239 if( retval != 0 ) return -1;
01240
01241 return 0;
01242 }
01243
01244
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298 int16_t si114x_get_calibration( HANDLE si114x_handle,
01299 SI114X_CAL_S* si114x_cal,
01300 uint8_t security)
01301 {
01302 uint8_t buffer[14];
01303 int16_t retval = 0;
01304 uint8_t response;
01305
01306 if( si114x_handle == NULL ) { retval = -4; goto error_exit; }
01307
01308 if( si114x_cal == NULL ) { retval = -4; goto error_exit; }
01309
01310
01311
01312
01313 if( security == 1 )
01314 {
01315 int8_t i;
01316
01317 retval = Si114xBlockRead( si114x_handle, REG_ALS_VIS_DATA0, 12, buffer );
01318 if( retval != 0 ) { retval = -2; goto error_exit; }
01319
01320 for( i=0; i<12; i++)
01321 {
01322 if( buffer[i] != 0 ) { retval = -1; goto error_exit; }
01323 }
01324
01325 DEBUG_PRINT_OUTPUT;
01326
01327 }
01328
01329
01330 do
01331 {
01332 retval = Si114xNop( si114x_handle );
01333 if( retval != 0 ) { retval = -2; goto error_exit; }
01334
01335
01336 response = Si114xReadFromRegister( si114x_handle, REG_RESPONSE );
01337 if (response != 0)
01338 {
01339 delay_1ms();
01340 }
01341 } while( response != 0 );
01342
01343
01344 retval = Si114xWriteToRegister( si114x_handle, REG_COMMAND, 0x12 );
01345 _waitUntilSleep(si114x_handle);
01346
01347 if( retval != 0 ) { retval = -2; goto error_exit; }
01348
01349
01350 do
01351 {
01352 response = Si114xReadFromRegister( si114x_handle, REG_RESPONSE );
01353
01354 if( response == 0x80 )
01355 {
01356
01357
01358
01359
01360 Si114xNop( si114x_handle );
01361 retval = -3;
01362 goto error_exit;
01363 }
01364 else if( response & 0xfff0 )
01365 {
01366
01367 retval = -2;
01368 goto error_exit;
01369 }
01370 if (response != 1)
01371 {
01372 delay_1ms();
01373 }
01374 } while( response != 1 );
01375
01376
01377 retval = Si114xBlockRead( si114x_handle, REG_ALS_VIS_DATA0, 12, buffer );
01378 if( retval != 0 ) { retval = -2; goto error_exit; }
01379
01380 DEBUG_PRINT_OUTPUT;
01381
01382 retval=si114x_get_cal_index( si114x_handle, buffer );
01383
01384 if( retval != 0 )
01385 {
01386 retval = -2; goto error_exit;
01387 }
01388
01389 si114x_cal->ledi_ratio = ledi_ratio(buffer);
01390 si114x_cal->vispd_correction = vispd_correction(buffer);
01391 si114x_cal->irpd_correction = irpd_correction(buffer);
01392 si114x_cal->adcrange_ratio = adcrange_ratio(buffer);
01393 si114x_cal->ucoef_p = calref[find_cal_index(buffer)].ucoef;
01394 si114x_cal->irsize_ratio = irsize_ratio(buffer);
01395
01396 DEBUG_PRINT_OUTPUT_2;
01397
01398 return 0;
01399
01400 error_exit:
01401 si114x_cal->vispd_correction = FX20_ONE;
01402 si114x_cal->irpd_correction = FX20_ONE;
01403 si114x_cal->adcrange_ratio = FLT_TO_FX20( 14.5 );
01404 si114x_cal->irsize_ratio = FLT_TO_FX20( 6.0 );
01405 si114x_cal->ledi_ratio = FX20_ONE;
01406 si114x_cal->ucoef_p = NULL;
01407 return retval;
01408 }
01409
01410
01438 int16_t si114x_set_ucoef( HANDLE si114x_handle,
01439 uint8_t* input_ucoef,
01440 SI114X_CAL_S* si114x_cal )
01441 {
01442 int8_t response;
01443 uint8_t temp;
01444 uint32_t vc=FX20_ONE, ic=FX20_ONE, long_temp;
01445 struct operand_t op;
01446 uint8_t* ref_ucoef = si114x_cal->ucoef_p;
01447 uint8_t out_ucoef[4];
01448
01449 if( input_ucoef != NULL ) ref_ucoef = input_ucoef;
01450
01451 if( ref_ucoef == NULL ) return -1 ;
01452
01453
01454 response = Si114xReadFromRegister( si114x_handle, REG_PART_ID );
01455 switch( response )
01456 {
01457 case 0x32: case 0x45: case 0x46: case 0x47: temp = 1; break;
01458 default: temp = 0; break;
01459 }
01460 if( !temp ) return -1;
01461
01462 if(si114x_cal != 0)
01463 {
01464 if(si114x_cal->vispd_correction > 0) vc = si114x_cal->vispd_correction;
01465 if(si114x_cal->irpd_correction > 0) ic = si114x_cal->irpd_correction;
01466 }
01467
01468 op.op1 = ref_ucoef[0] + ((ref_ucoef[1])<<8);
01469 op.op2 = vc;
01470 long_temp = fx20_multiply( &op );
01471 out_ucoef[0] = (long_temp & 0x00ff);
01472 out_ucoef[1] = (long_temp & 0xff00)>>8;
01473
01474 op.op1 = ref_ucoef[2] + (ref_ucoef[3]<<8);
01475 op.op2 = ic;
01476 long_temp = fx20_multiply( &op );
01477 out_ucoef[2] = (long_temp & 0x00ff);
01478 out_ucoef[3] = (long_temp & 0xff00)>>8;
01479
01480 DEBUG_UCOEF
01481
01482 response = Si114xBlockWrite( si114x_handle, REG_UCOEF0 , 4, out_ucoef);
01483
01484 return response;
01485 }
01486 #else // INCLUDE_SI114X_CALIBRATION_CODE
01487
01488
01489
01490 int16_t si114x_get_calibration( HANDLE si114x_handle,
01491 SI114X_CAL_S* si114x_cal,
01492 uint8_t security)
01493 {
01494
01495
01496 return 0;
01497 }
01498
01499 int16_t si114x_set_ucoef( HANDLE si114x_handle,
01500 uint8_t* input_ucoef,
01501 SI114X_CAL_S* si114x_cal )
01502 {
01503 int16_t response;
01504 uint8_t code ucoef[4] = { 0x7B, 0x6B, 0x01, 0x00 } ;
01505
01506
01507 response = Si114xBlockWrite( si114x_handle, REG_UCOEF0, 4, &ucoef[0] );
01508 return response;
01509 }
01510 #endif // INCLUDE_SI114X_CALIBRATION_CODE
01511
01512
01513
01514
01515