
nothing to say
Dependencies: mbed
heimann32x32.cpp
- Committer:
- withboobs
- Date:
- 2018-02-21
- Revision:
- 0:ca29dd5bc1d8
File content as of revision 0:ca29dd5bc1d8:
#include "mbed.h" #include "heimann32x32.h" #include "heimann32x32_table.cpp" HTPA32x32::HTPA32x32(I2C * _i2c, I2C * _i2ce, uint8_t addr1, uint8_t addr2) { i2c = _i2c; // i2c->frequency(400000); i2c->frequency(1000000); i2ce = _i2ce; i2ce->frequency(400000); i2c_addr_htpa = addr1; i2c_addr_eeprom = addr2; proc = HTPA_PROC_ELOFFS | HTPA_PROC_THOFFS | HTPA_PROC_CONVERT; available = 0; } uint8_t HTPA32x32::ADC( void ) { return mbit; } uint8_t HTPA32x32::ADC( uint8_t m ) { char data_write[2]; data_write[0] = HTP_TRIM1_ADC; if (m < 4) m = 4; if (m > 12) m = 12; mbit = m; data_write[1] = m & TRIM1_ADC_MASK; i2c->write((int) i2c_addr_htpa, data_write, 2, 1); return mbit; } uint8_t HTPA32x32::BIAS ( void ) { return bias; } uint8_t HTPA32x32::BIAS ( uint8_t m ) { char data_write[2]; data_write[0] = HTP_TRIM2_BIAS1; if (m > 31) m = 31; bias = m; data_write[1] = m & TRIM_BIAS_MASK; i2c->write(i2c_addr_htpa, data_write, 2, 1); data_write[0] = HTP_TRIM3_BIAS2; i2c->write(i2c_addr_htpa, data_write, 2, 1); return bias; } uint8_t HTPA32x32::CLOCK( void ) { return clk; } uint8_t HTPA32x32::CLOCK( uint8_t m ) { char data_write[2]; data_write[0] = HTP_TRIM4_FREQ; if (m > 63) m = 63; clk = m; data_write[1] = m & TRIM_FREQ_MASK; i2c->write(i2c_addr_htpa, data_write, 2, 1); return clk; } uint8_t HTPA32x32::PU( void ) { return (pu>>4); } uint8_t HTPA32x32::PU( uint8_t m ) { char data_write[2]; data_write[0] = HTP_TRIM7_PU; if (m == 1 || m ==2 || m==4 || m==8) { pu = m<<4 | m; data_write[1] = pu; i2c->write(i2c_addr_htpa, data_write, 2, 1); } return pu; } uint8_t HTPA32x32::BPA ( void ) { return bpa; } uint8_t HTPA32x32::BPA ( uint8_t m ) { char data_write[2]; data_write[0] = HTP_TRIM5_BPA1; if (m > 31) m = 31; bpa = m & TRIM_BPA_MASK; data_write[1] = bpa; i2c->write(i2c_addr_htpa, data_write, 2, 1); data_write[0] = HTP_TRIM6_BPA2; i2c->write(i2c_addr_htpa, data_write, 2, 1); return bpa; } void HTPA32x32::read_eeprom(uint8_t HiReg, uint8_t LoReg, char *data_ptr, int DCnt) { char data_write[2]; data_write[0] = HiReg; data_write[1] = LoReg; i2ce->write((int) i2c_addr_eeprom, data_write,2,1); while (DCnt) { if (DCnt > 32) { i2ce->read ((int) i2c_addr_eeprom, data_ptr, 32, 0); DCnt -= 32; data_ptr += 32; } else { i2ce->read ((int) i2c_addr_eeprom, data_ptr, DCnt, 0); DCnt=0; } } } void HTPA32x32::download_PIJ( void ) { int8_t i,j; uint16_t * dummyPix = (uint16_t *) PixC; float rcp_eps, a, b; read_eeprom(HTP_EEPROM_PIX_HI, HTP_EEPROM_PIX_LO, (char *) dummyPix, 2048); read_eeprom(HTP_EEPROM_THGRAD_HI, HTP_EEPROM_THGRAD_LO, (char *) ThGrad, 2048); read_eeprom(HTP_EEPROM_THOFFS_HI, HTP_EEPROM_THOFFS_LO, (char *) ThOffs, 2048); rcp_eps = 100.0 / epsilon; a = (PixCmax - PixCmin) / (float) 65535.0 * rcp_eps; b = rcp_eps * PixCmin; /* top */ for (i=31; i>=0; i--) { for (j=31; j>=0; j--) { PixC[i*32 + j] = (float) dummyPix[i*32 + j]; PixC[i*32 + j] = a * PixC[i*32 + j] + b; PixC[i*32 + j] = 1e8/PixC[i*32 + j]; } } return; } void HTPA32x32::init( void ) { uint8_t raw[5] = {0}; read_eeprom(HTP_EEPROM_CALIB_HI, HTP_EEPROM_CALIB_LO, (char *) raw, 5); mbit = raw[0]; bias = raw[1]; clk = raw[2]; bpa = raw[3]; pu = raw[4]; read_eeprom(HTP_EEPROM_PTAT_HI, HTP_EEPROM_PTAT_GRAD_LO, (char *) &PTATgrad, 4); read_eeprom(HTP_EEPROM_PTAT_HI, HTP_EEPROM_PTAT_OFFS_LO, (char *) &PTAToffs, 4); read_eeprom(HTP_EEPROM_PIXC_HI, HTP_EEPROM_PIXCMIN_LO, (char *) &PixCmin, 4); read_eeprom(HTP_EEPROM_PIXC_HI, HTP_EEPROM_PIXCMAX_LO, (char *) &PixCmax, 4); read_eeprom(HTP_EEPROM_TN_EPS_HI, HTP_EEPROM_TN_LO, (char *) raw, 2); tn=raw[0]; epsilon=raw[1]; read_eeprom(HTP_EEPROM_GRADSCALE_HI, HTP_EEPROM_GRADSCALE_LO, (char *) &gradScale, 1); download_PIJ(); Ta_dK = Ta_dK_prev = Ta_dK_prev_prev = 0; return; } uint8_t HTPA32x32::end ( ) { uint8_t rval = HTP_STATUS; i2c->write(i2c_addr_htpa, (char *) &rval, 1, 1); i2c->read (i2c_addr_htpa, (char *) &rval, 1, 0); rval &= STATUS_EOC; return rval; } void HTPA32x32::start() { char data_write[2] = { HTP_CONFIG, CONFIG_WAKEUP | CONFIG_START }; b = 0; i2c->write(i2c_addr_htpa, data_write, 2, 1); return; } void HTPA32x32::readb() { uint8_t i, j, data_write[2], data_buffer[258]; if (!b) { Ta_dK_prev_prev = Ta_dK_prev; Ta_dK_prev = Ta_dK; Ta_dK = PTAToffs; available = 0; } /** * download top */ data_write[0] = HTP_DATA1; i2c->write(i2c_addr_htpa, (char *) data_write, 1, 1); i2c->read (i2c_addr_htpa, (char *) data_buffer, 258, 0); if (b < 4) { // process Ta_dK += ( (data_buffer[0]<<5) + (data_buffer[1]>>3) ) * PTATgrad; for(i=0; i<4; i++) { for (j=0; j<32; j++) { // endianess flip-flopping uint8_t * d = (uint8_t *) &Data[i * 32 + j + b*128]; d[0] = data_buffer[64*i + 2*j + 3]; // LO d[1] = data_buffer[64*i + 2*j + 2]; // HI } } } else { /* electrical offsets */ for(i=0; i<4; i++) { for (j=0; j<32; j++) { // endianess flip-flopping uint8_t * d = (uint8_t *) &ElOffs[i * 32 + j ]; d[0] = data_buffer[64*i + 2*j + 3]; // LO d[1] = data_buffer[64*i + 2*j + 2]; // HI } } } /** * download bottom */ data_write[0] = HTP_DATA2; i2c->write(i2c_addr_htpa, (char *) data_write, 1, 1); i2c->read (i2c_addr_htpa, (char *) data_buffer, 258, 0); if (b<4) { // process temperatures Ta_dK += ( (data_buffer[0]<<5) + (data_buffer[1]>>3) ) * PTATgrad; for(i=0; i<4; i++) { for (j=0; j<32; j++) { // endianess flip-flopping uint8_t * d = (uint8_t *) &Data[(3-i) * 32 + j + (7-b)*128]; d[0] = data_buffer[64*i + 2*j + 3]; // LO d[1] = data_buffer[64*i + 2*j + 2]; // HI } } } else { /* electrical offsets */ for(i=0; i<4; i++) { for (j=0; j<32; j++) { // endianess flip-flopping uint8_t * d = (uint8_t *) &ElOffs[(3-i) * 32 + j + 128]; d[0] = data_buffer[64*i + 2*j + 3]; // LO d[1] = data_buffer[64*i + 2*j + 2]; // HI } } } // initiate conversion for next call to readb: data_write[0] = HTP_CONFIG; data_write[1] = CONFIG_WAKEUP | CONFIG_START; if (proc & HTPA_PROC_ELOFFS) b = (b+1) % 5; else b = (b+1) % 4; if (b<4) { data_write[1] |= ((b & 0x03)<<4); } else { data_write[1] |= CONFIG_BLIND; } i2c->write(i2c_addr_htpa, (char *) data_write, 2, 1); if (!b) available = 1; } /** * prepare interpolation table based on Ta_dK * calculate table every time Ta_dK changes */ void HTPA32x32::find_temptable_from_ta ( void ) { uint16_t j, i, i_star; if (Ta_dK <= XTATemps[0]) { for (j=0;j<NROFADELEMENTS;j++) { TempTable_TA[j] = TempTable[j][0]; } } else if (Ta_dK >= XTATemps[NROFTAELEMENTS-1]) { for (j=0;j<NROFADELEMENTS;j++) { TempTable_TA[j] = TempTable[j][NROFTAELEMENTS-1]; } } else { /* construct interpolant for Ta_dK for all V_j */ for (i=1;i<(NROFTAELEMENTS-1);i++) { if (XTATemps[i] == Ta_dK) { i_star = i; break; } if (XTATemps[i+1] == Ta_dK) { i++; i_star = i; break; } if ( (XTATemps[i] < Ta_dK) && (Ta_dK < XTATemps[i+1]) ) { i_star = i+1; break; } } if (i == i_star) { for (j=0;j<NROFADELEMENTS;j++) { TempTable_TA[j] = TempTable[j][i]; } } else { uint16_t d1 = Ta_dK - XTATemps[i]; uint16_t d2 = XTATemps[i_star] - Ta_dK; for (j=0;j<NROFADELEMENTS;j++) { float d = (d2 * TempTable[j][i] + d1 * TempTable[j][i_star]) / TAEQUIDISTANCE; TempTable_TA[j] = d; } } } } uint16_t HTPA32x32::find_dk_from_v ( int16_t v) { uint16_t t_dk, k; if ( v <= YADValues[0] ) { t_dk = TempTable_TA[0]; } else if ( v >= YADValues[NROFADELEMENTS-1] ) { t_dk = TempTable_TA[NROFADELEMENTS-1]; } else { for (k=1; k<NROFADELEMENTS; k++) { if ( v == YADValues[k] ) { t_dk = TempTable_TA[k]; break; } else if ( v < YADValues[k] ) { float dummy = TempTable_TA[k-1]; dummy += (TempTable_TA[k] - TempTable_TA[k-1]) * ( v - YADValues[k-1]) / ADEQUIDISTANCE; t_dk = dummy; break; } } } // else return t_dk; } void HTPA32x32::apply_offsets( void ) { uint16_t i,j; float dummyData; // do we need to do apply any offsets? if (!proc) return; if (proc & HTPA_PROC_CONVERT) { if (Ta_dK_prev != Ta_dK) { find_temptable_from_ta (); } } /** * finish calculation of temperatures: * thermal offset */ for (i=0; i<16; i++) { for (j=0; j<32; j++) { /* thermal offsets */ if (proc & HTPA_PROC_THOFFS) { Data[i * 32 + j] -= ThOffs[i * 32 + j]; Data[i * 32 + j] -= ThGrad[i * 32 + j] * Ta_dK / (2<<gradScale); } /* electric (blind) offsets */ if (proc & HTPA_PROC_ELOFFS) Data[i * 32 + j] -= ElOffs[(i%4) * 32 + j]; /* do interpolation */ if (proc & HTPA_PROC_CONVERT) { dummyData = (float) Data[i * 32 + j] * PixC[i*32 + j] + TABLEOFFSET; Data[i * 32 + j] = find_dk_from_v( dummyData ); } } } for (;i<32; i++) { for (j=0; j<32; j++) { /* thermal offsets */ if (proc & HTPA_PROC_THOFFS) { Data[i * 32 + j] -= ThOffs[ (47-i) * 32 + j]; Data[i * 32 + j] -= ThGrad[ (47-i) * 32 + j] * Ta_dK / (2<<gradScale); } /* electric (blind) offsets */ if (proc & HTPA_PROC_ELOFFS) Data[i * 32 + j] -= ElOffs[(i%4) * 32 + j + 128]; /* do interpolation */ if (proc & HTPA_PROC_CONVERT) { dummyData = (float) Data[i * 32 + j] * PixC[(47 - i)*32 + j] + TABLEOFFSET; Data[i * 32 + j] = find_dk_from_v( dummyData ); } } } }