nothing to say

Dependencies:   mbed

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 );
+            }
+        }
+    }
+  
+ }
+
+
+
+
+
+
+
+