Self test boot program for testing icarus sensors

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_UARTConsole by Bluetooth Low Energy

Committer:
smigielski
Date:
Tue Mar 03 20:00:21 2015 +0000
Revision:
12:9076e6453115
Parent:
11:70359785c2a7
Child:
13:ef0ce8fa871f
Fiexes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
smigielski 8:e9ae7a01d866 1 #include "ADXL362Sensor.h"
smigielski 8:e9ae7a01d866 2 #include "mbed.h"
smigielski 8:e9ae7a01d866 3
smigielski 8:e9ae7a01d866 4 #ifndef LOG
smigielski 8:e9ae7a01d866 5 #define LOG(...) do printf(__VA_ARGS__); while (0)
smigielski 8:e9ae7a01d866 6 #endif
smigielski 8:e9ae7a01d866 7
smigielski 12:9076e6453115 8 ADXL362Sensor::ADXL362Sensor(SPI& spi_,DigitalOut& cs_) : BaseSensor(), spi(spi_), cs(cs_) {
smigielski 12:9076e6453115 9 cs = UP;
smigielski 8:e9ae7a01d866 10 }
smigielski 8:e9ae7a01d866 11
smigielski 8:e9ae7a01d866 12 char* ADXL362Sensor::getSimpleName() {
smigielski 8:e9ae7a01d866 13 return "ADXL362";
smigielski 8:e9ae7a01d866 14 }
smigielski 8:e9ae7a01d866 15
smigielski 8:e9ae7a01d866 16
smigielski 9:ed3636e1873f 17 uint32_t ADXL362Sensor::verifyIntegrity(uint32_t* errorResult) {
smigielski 8:e9ae7a01d866 18 LOG("Start verfication of ADXL362 Sensor");
smigielski 9:ed3636e1873f 19 uint32_t errors = 0;
smigielski 9:ed3636e1873f 20 //Device id is 0xAD
smigielski 9:ed3636e1873f 21 //Device mems id is 0x1D
smigielski 9:ed3636e1873f 22 //Part id is 0xF2
smigielski 10:3a24c970db40 23 uint32_t sensorId = readRegister32(ADXL362_DEVID_AD);
smigielski 9:ed3636e1873f 24
smigielski 9:ed3636e1873f 25 if (sensorId >> 8 !=0xAD1DF2){
smigielski 9:ed3636e1873f 26 errorResult[errors++] = ERROR_WRONG_DEVICE_ID;
smigielski 9:ed3636e1873f 27 LOG("Wrong sensorId: %X",sensorId);
smigielski 9:ed3636e1873f 28 }
smigielski 9:ed3636e1873f 29
smigielski 9:ed3636e1873f 30 //check status registry
smigielski 10:3a24c970db40 31 uint8_t status = readRegister(ADXL362_STATUS);
smigielski 9:ed3636e1873f 32
smigielski 9:ed3636e1873f 33 //indicate that SEU error was detetcted
smigielski 9:ed3636e1873f 34 if (status & (1 << 7)){
smigielski 9:ed3636e1873f 35 errorResult[errors++] = ERROR_SEU_ERROR_DETECT;
smigielski 9:ed3636e1873f 36 LOG("SEU error detected: %X",status);
smigielski 9:ed3636e1873f 37 }
smigielski 9:ed3636e1873f 38 //check that chip is in awaken state
smigielski 9:ed3636e1873f 39 if (!(status & (1 << 6))){
smigielski 9:ed3636e1873f 40 errorResult[errors++] = ERROR_DEVICE_SLEEPING;
smigielski 9:ed3636e1873f 41 LOG("Chip not awaken: %X",status);
smigielski 9:ed3636e1873f 42 }
smigielski 9:ed3636e1873f 43
smigielski 9:ed3636e1873f 44 //perform self test
smigielski 9:ed3636e1873f 45 errors+=selfTest(&errorResult[errors]);
smigielski 9:ed3636e1873f 46
smigielski 9:ed3636e1873f 47 return errors;
smigielski 8:e9ae7a01d866 48 }
smigielski 8:e9ae7a01d866 49
smigielski 8:e9ae7a01d866 50 void ADXL362Sensor::getSensorDetails(sensor_t* sensorDetails) {
smigielski 8:e9ae7a01d866 51
smigielski 8:e9ae7a01d866 52 }
smigielski 8:e9ae7a01d866 53
smigielski 9:ed3636e1873f 54 uint32_t ADXL362Sensor::selfTest(uint32_t* errorResult){
smigielski 9:ed3636e1873f 55 uint32_t errors = 0;
smigielski 9:ed3636e1873f 56 // 0. base data
smigielski 9:ed3636e1873f 57 int16_t x12,y12,z12;
smigielski 9:ed3636e1873f 58 int16_t test_x12,test_y12,test_z12;
smigielski 9:ed3636e1873f 59 // 1. Read acceleration data for the x-, y-, and z-axes.
smigielski 9:ed3636e1873f 60 refreshAcceleration12(&x12, &y12, &z12);
smigielski 9:ed3636e1873f 61 // 2. Assert self test by setting the ST bit in the SELF_TEST register, Address 0x2E.
smigielski 10:3a24c970db40 62 writeRegister(ADXL362_SELF_TEST,0x01);
smigielski 9:ed3636e1873f 63 // 3. Wait 1/ODR for the output to settle to its new value.
smigielski 10:3a24c970db40 64 wait(1/ADXL362_ODR);
smigielski 9:ed3636e1873f 65 // 4. Read acceleration data for the x-, y-, and z-axes.
smigielski 9:ed3636e1873f 66 refreshAcceleration12(&test_x12, &test_y12, &test_z12);
smigielski 9:ed3636e1873f 67 // 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.
smigielski 10:3a24c970db40 68 float reactionX = (x12-test_x12)* ADXL362_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD / ADXL362_SELF_TEST_SCALE_FACTOR;
smigielski 10:3a24c970db40 69 float reactionY = (y12-test_y12)* ADXL362_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD / ADXL362_SELF_TEST_SCALE_FACTOR;
smigielski 10:3a24c970db40 70 float reactionZ = (z12-test_z12)* ADXL362_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD / ADXL362_SELF_TEST_SCALE_FACTOR;
smigielski 9:ed3636e1873f 71
smigielski 9:ed3636e1873f 72 if (reactionX<0.450F || reactionX>0.710F ||
smigielski 9:ed3636e1873f 73 reactionY<-0.710F || reactionY>-0.450F ||
smigielski 9:ed3636e1873f 74 reactionZ<0.350F || reactionZ>0.650F){
smigielski 9:ed3636e1873f 75 errorResult[errors++] = ERROR_SELF_TEST_FAILED;
smigielski 9:ed3636e1873f 76 LOG("Reaction: %+5.3f %+5.3f %+5.3f\r\n",reactionX,reactionY,reactionZ);
smigielski 9:ed3636e1873f 77 }
smigielski 9:ed3636e1873f 78
smigielski 9:ed3636e1873f 79 // 6. Deassert self test by clearing the ST bit in the SELF_TEST register, Address 0x2E.
smigielski 10:3a24c970db40 80 writeRegister(ADXL362_SELF_TEST,0x01);
smigielski 9:ed3636e1873f 81
smigielski 9:ed3636e1873f 82 return errors;
smigielski 9:ed3636e1873f 83 }
smigielski 9:ed3636e1873f 84
smigielski 9:ed3636e1873f 85 void ADXL362Sensor::refreshAcceleration12(int16_t* x, int16_t* y, int16_t* z)
smigielski 9:ed3636e1873f 86 {
smigielski 9:ed3636e1873f 87 int16_t xyzVal[6] = {0, 0, 0, 0, 0, 0};
smigielski 9:ed3636e1873f 88
smigielski 12:9076e6453115 89 cs = DOWN;
smigielski 12:9076e6453115 90 spi.write(ADXL362_READ_REGISTER);
smigielski 12:9076e6453115 91 spi.write(ADXL362_DATA_12);
smigielski 9:ed3636e1873f 92
smigielski 9:ed3636e1873f 93 for (int i = 0; i < 6; i++) {
smigielski 12:9076e6453115 94 xyzVal[i] = spi.write(0x00);
smigielski 9:ed3636e1873f 95 }
smigielski 9:ed3636e1873f 96
smigielski 9:ed3636e1873f 97 *x = (xyzVal[1] << 8) + xyzVal[0];
smigielski 9:ed3636e1873f 98 *y = (xyzVal[3] << 8) + xyzVal[2];
smigielski 9:ed3636e1873f 99 *z = (xyzVal[5] << 8) + xyzVal[4];
smigielski 9:ed3636e1873f 100
smigielski 12:9076e6453115 101 cs = UP;
smigielski 9:ed3636e1873f 102 }
smigielski 9:ed3636e1873f 103
smigielski 9:ed3636e1873f 104 uint32_t ADXL362Sensor::readRegister32( uint8_t reg){
smigielski 9:ed3636e1873f 105 uint32_t val[4] = {0,0,0,0};
smigielski 12:9076e6453115 106 cs = DOWN;
smigielski 12:9076e6453115 107 spi.write(ADXL362_READ_REGISTER);
smigielski 12:9076e6453115 108 spi.write(reg);
smigielski 9:ed3636e1873f 109 for (int i=0;i<4;i++){
smigielski 12:9076e6453115 110 val[i] = spi.write(0x00);
smigielski 9:ed3636e1873f 111 }
smigielski 12:9076e6453115 112 cs = UP;
smigielski 9:ed3636e1873f 113
smigielski 9:ed3636e1873f 114 return (val[0] << 24) + (val[1] << 16) + (val[2] << 8) + val[3];
smigielski 9:ed3636e1873f 115 }
smigielski 8:e9ae7a01d866 116
smigielski 8:e9ae7a01d866 117
smigielski 9:ed3636e1873f 118 uint8_t ADXL362Sensor::readRegister( uint8_t reg){
smigielski 12:9076e6453115 119 cs = DOWN;
smigielski 12:9076e6453115 120 spi.write(ADXL362_READ_REGISTER);
smigielski 12:9076e6453115 121 spi.write(reg);
smigielski 12:9076e6453115 122 uint8_t val = spi.write(0x00);
smigielski 12:9076e6453115 123 cs = UP;
smigielski 9:ed3636e1873f 124 return (val);
smigielski 9:ed3636e1873f 125 }
smigielski 9:ed3636e1873f 126
smigielski 9:ed3636e1873f 127 void ADXL362Sensor::writeRegister( uint8_t reg, uint8_t cmd ){
smigielski 12:9076e6453115 128 cs = DOWN;
smigielski 12:9076e6453115 129 spi.write(ADXL362_WRITE_REGISTER);
smigielski 12:9076e6453115 130 spi.write(reg);
smigielski 12:9076e6453115 131 spi.write(cmd);
smigielski 12:9076e6453115 132 cs = UP;
smigielski 9:ed3636e1873f 133 }