Self test boot program for testing icarus sensors

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_UARTConsole by Bluetooth Low Energy

ADXL362Sensor.cpp

Committer:
smigielski
Date:
2015-04-15
Revision:
14:cb369746225d
Parent:
13:ef0ce8fa871f

File content as of revision 14:cb369746225d:

#include "ADXL362Sensor.h"



ADXL362Sensor::ADXL362Sensor(SPI& spi_,DigitalOut& cs_,void (*debug_)(const char* format, ...)) : BaseSensor(debug_), spi(spi_), cs(cs_)  {    
    cs = UP;
    writeRegister(ADXL362_SOFT_RESET, 0x52);  
    wait_ms(1);
    writeRegister(ADXL362_POWER_CTL,0x02);
}

 
char* ADXL362Sensor::getSimpleName() {
    return "ADXL362";
}


uint32_t ADXL362Sensor::verifyIntegrity(uint32_t* errorResult) {
    LOG("Start verfication of ADXL362 Sensor\r\n");
    uint32_t errors = 0;
    //Device id is 0xAD
    //Device mems id is 0x1D
    //Part id is 0xF2
    uint32_t sensorId = readRegister32(ADXL362_DEVID_AD);
    
    if (sensorId >> 8 !=0xAD1DF2){
        errorResult[errors++] = ERROR_WRONG_DEVICE_ID;
        LOG("Wrong sensorId: %X\r\n",sensorId);
    }
    
    //check status registry
    uint8_t status  = readRegister(ADXL362_STATUS);
    
    //indicate that SEU error was detetcted 
    if (status & (1 << 7)){
        errorResult[errors++] = ERROR_WRONG_DEVICE_STATE;
        LOG("SEU error detected: %X\r\n",status);        
    }
    //check that chip is in awaken state  
    if (!(status & (1 << 6))){
        errorResult[errors++] = ERROR_DEVICE_SLEEPING;
        LOG("Chip not awaken: %X\r\n",status);
    }    
    
    //perform self test
    errors+=selfTest(&errorResult[errors]); 
    
    return errors;
}

void ADXL362Sensor::getSensorDetails(sensor_t* sensorDetails) {

}

uint32_t ADXL362Sensor::selfTest(uint32_t* errorResult){
    uint32_t errors = 0;
// 0. base data
    int16_t x12,y12,z12;
    int16_t test_x12,test_y12,test_z12;
// 1. Read acceleration data for the x-, y-, and z-axes.    
    refreshAcceleration12(&x12, &y12, &z12); 
// 2. Assert self test by setting the ST bit in the SELF_TEST register, Address 0x2E.
    writeRegister(ADXL362_SELF_TEST,0x01);
// 3. Wait 1/ODR for the output to settle to its new value.
    wait(4.0/ADXL362_ODR);
// 4. Read acceleration data for the x-, y-, and z-axes.
    refreshAcceleration12(&test_x12, &test_y12, &test_z12);
// 5. Compare to the values from Step 1, and convert the difference from LSB to mg by multiplying by the sensitivity. If the observed difference falls within the self test output change specification listed in Table 1, then the device passes self test and is deemed operational.
    float reactionX = (test_x12-x12) * 0.250f;
    float reactionY = (test_y12-y12) * 0.250f;
    float reactionZ = (test_z12-z12) * 0.250f;
        
    
    if (reactionX<230.0F || reactionX>870.0F ||
        reactionY<-870.0F || reactionY>-230.0F ||
        reactionZ<270.0F || reactionZ>800.0F){
        errorResult[errors++] = ERROR_ACCE_SELF_TEST_FAILED;
        LOG("Reaction: %+5.3f %+5.3f %+5.3f\r\n",reactionX,reactionY,reactionZ);
    }
    
// 6. Deassert self test by clearing the ST bit in the SELF_TEST register, Address 0x2E.
    writeRegister(ADXL362_SELF_TEST,0x00);
    wait(4.0/ADXL362_ODR);
    return errors;
}

void ADXL362Sensor::refreshAcceleration12(int16_t* x, int16_t* y, int16_t* z)
{
    int16_t xyzVal[6] = {0, 0, 0, 0, 0, 0};
 
    cs = DOWN;
    spi.write(ADXL362_READ_REGISTER);
    spi.write(ADXL362_DATA_12);
 
    for (int i = 0; i < 6; i++) {
        xyzVal[i] = spi.write(0x00);
    }
 
    *x = (xyzVal[1] << 8) + xyzVal[0];
    *y = (xyzVal[3] << 8) + xyzVal[2];
    *z = (xyzVal[5] << 8) + xyzVal[4];
 
    cs = UP;
}

uint32_t ADXL362Sensor::readRegister32( uint8_t reg){
    uint32_t val[4] = {0,0,0,0};
    cs = DOWN;
    spi.write(ADXL362_READ_REGISTER);
    spi.write(reg);
    for (int i=0;i<4;i++){
        val[i] = spi.write(0x00);
    }    
    cs = UP;
        
    return (val[0] << 24) + (val[1] << 16) + (val[2] << 8) + val[3];
}


uint8_t ADXL362Sensor::readRegister( uint8_t reg){
    cs = DOWN;
    spi.write(ADXL362_READ_REGISTER);
    spi.write(reg);
    uint8_t val = spi.write(0x00);
    cs = UP;
    return (val);
}

void ADXL362Sensor::writeRegister( uint8_t reg, uint8_t cmd ){
    cs = DOWN;
    spi.write(ADXL362_WRITE_REGISTER);
    spi.write(reg);
    spi.write(cmd);
    cs = UP;
}