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