
nothing to say
Dependencies: mbed
Diff: heimann32x32.cpp
- Revision:
- 0:ca29dd5bc1d8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/heimann32x32.cpp Wed Feb 21 18:13:45 2018 +0000 @@ -0,0 +1,502 @@ +#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 ); + } + } + } + + } + + + + + + + +