Update

Dependents:   COG_UART_Base

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ADXL362.cpp Source File

ADXL362.cpp

00001 #include "ADXL362.h"
00002 
00003 #define WAIT_US(value)      (0.000001 * ((float)value))
00004 
00005 #define REGADDR_WRITE       (0x80)
00006 #define REGADDR_WR_L        (0x00)
00007 #define REGADDR_WR_H        (0x01)
00008 
00009 #define GET_VAL_L(value)    ((value >> 0) & 0xFF)
00010 #define GET_VAL_H(value)    ((value >> 8) & 0xFF)
00011 
00012 // define for EV-COG-AD3029LZ
00013 #define SPI_CS    SPI1_CS3
00014 
00015 /** ==========================================
00016  *  Public ( initializing )
00017  *  ========================================== */
00018 ADXL362::ADXL362(Serial *setUart, SPI* spi1) {  
00019     int check;
00020 
00021     uart = setUart;  
00022     _spi = spi1;
00023     _cs = new DigitalOut(SPI_CS);
00024     
00025     _spi->format(8,3);
00026     _spi->frequency(1000000);
00027     
00028     chipSelOff();
00029 
00030     /* start */
00031     check = regRD(DEVID_AD);
00032     if (check != DEVID_AD_ADXL362) {    
00033         return;
00034     }
00035     check = regRD(DEVID_MST);
00036     if (check != DEVID_MST_ADXL362) {   
00037         return;
00038     }
00039     check = regRD(PARTID);
00040     if (check != PARTID_ADXL362) {  
00041         return;
00042     }
00043 
00044     /* init MIN/MAX store */
00045     initMinMax(&minStore, &maxStore);   
00046     /* set convert parameter */     
00047     SoftReset();
00048 
00049     scaleAccel = PARAM_ADXL362_SCALE_ACCEL;
00050     scaleThermal = PARAM_ADXL362_SCALE_THERMAL;
00051     offsetThermal = PARAM_ADXL362_THERMAL_OFFSET;
00052     
00053     //SetMesureParam(POWER_CTL_PARAM_LOWNOISE_ULTRA);
00054     //StartMesure();
00055 }
00056 
00057 ADXL362::~ADXL362() {
00058     delete this->_cs;
00059 }
00060 
00061 
00062 /** ==========================================
00063  *  Private ( Control Pins )
00064  *  ========================================== */
00065 /* Assert CHIP_SEL = enable */
00066 void ADXL362::chipSelOn() {
00067     chipSelDelay();
00068     *_cs = 0;
00069 }
00070 
00071 /* Assert CHIP_SEL = disable */
00072 void ADXL362::chipSelOff() {
00073     *_cs = 1;
00074 }
00075 
00076 /* delay for CHIP_SEL */
00077 void ADXL362::chipSelDelay() {
00078     wait(WAIT_US(0.2));
00079 }
00080 /** ==========================================
00081  *  Public ( ADXL Configuration )
00082  *  ========================================== */
00083 void ADXL362::set_gravity(int g)
00084 {
00085     int value;
00086     unsigned char g_reg;
00087     
00088     switch(g)
00089     {
00090         case GRAVITY_2G:
00091             gravity = GRAVITY_2G;
00092             g_reg = 0x00;
00093             break;
00094         case GRAVITY_4G:
00095             gravity = GRAVITY_4G;
00096             g_reg = 0x40;
00097             break;
00098         case GRAVITY_8G:
00099             gravity = GRAVITY_8G;
00100             g_reg = 0x80;
00101             break;
00102         default:
00103             gravity = GRAVITY_2G;
00104             g_reg = 0x00;
00105             break;
00106     }
00107     value = regRD(FILTER_CTL);
00108     value &= 0x3f;
00109     value |= g_reg;
00110     regWR(FILTER_CTL, value);
00111     set_scalefactor();
00112 }
00113 
00114 void ADXL362::set_ODR(int o)
00115 {
00116     int value;
00117     unsigned char o_reg;
00118     
00119     switch(o)
00120     {
00121         case ODR_12:
00122             odr = ODR_12;
00123             o_reg = 0x00; 
00124             break;
00125         case ODR_25:
00126             odr = ODR_25;
00127             o_reg = 0x01; 
00128             break;
00129         case ODR_50:
00130             odr = ODR_50;
00131             o_reg = 0x02; 
00132             break;
00133         case ODR_100:
00134             odr = ODR_100;
00135             o_reg = 0x03; 
00136             break;
00137         case ODR_200:
00138             odr = ODR_200;
00139             o_reg = 0x04; 
00140             break;
00141         case ODR_400:
00142             odr = ODR_400;
00143             o_reg = 0x07; 
00144             break;
00145         default:
00146             odr = ODR_100;
00147             o_reg = 0x03;
00148             break;
00149     }
00150     value = regRD(FILTER_CTL);
00151     value &= 0xf8;
00152     value |= o_reg;
00153     regWR(FILTER_CTL, value);
00154 }
00155 
00156 void ADXL362::set_powermode(int m)
00157 {
00158     ADXL362::SetMesureParam(m);
00159 }
00160 
00161 void ADXL362::set_wakeupmode(void)
00162 {
00163     regWR(THRESH_ACT_L, 0x50);
00164     regWR(THRESH_ACT_H, 0x00);
00165     regWR(TIME_ACT, 0x00);
00166     regWR(THRESH_INACT_L, 0xff);
00167     regWR(THRESH_INACT_H, 0x07);
00168     regWR(TIME_INACT_L, 0x06);
00169     regWR(TIME_INACT_H, 0x00);
00170     regWR(ACT_INACT_CTL, 0x1F);
00171     regWR(INTMAP1, 0xC0);
00172     regWR(POWER_CTL, 0x0E);
00173 }
00174 
00175 void ADXL362::set_scalefactor(void)
00176 {
00177     float base, sf;
00178     
00179     base = (gravity / 2.0f);
00180     sf = base*(0.001f)*9.80665f;
00181     scaleAccel = sf;
00182 }
00183 
00184 void ADXL362::start(void)
00185 {
00186     int value;
00187     value = regRD(POWER_CTL);
00188     value &= 0xfc;
00189     value |= POWER_CTL_MESURE;
00190     regWR(POWER_CTL, value);
00191     wait_ms(5);
00192     GetStatus();
00193 }
00194     
00195 void ADXL362::stop(void)
00196 {
00197     int value;
00198     value = regRD(POWER_CTL);
00199     value &= 0xfc;
00200     value |= POWER_CTL_STOP;
00201     regWR(POWER_CTL, value);
00202     wait_ms(5);
00203     GetStatus();
00204 }
00205 
00206 /** ==========================================
00207  *  Public ( Send Command to Device )
00208  *  ========================================== */
00209 /* Write 16bit-Aligned Register */
00210 void ADXL362::SoftReset() {
00211     regWR(SOFT_RESET, SOFT_RESET_ADXL362);
00212     wait(0.5);  
00213 }
00214 
00215 void ADXL362::SetMesureParam(int param) {
00216     int value;
00217     value = regRD(POWER_CTL);
00218     param &= ~(POWER_CTL_MODEMASK);
00219     value &= POWER_CTL_MODEMASK;
00220     value |= param;
00221     regWR(POWER_CTL, value);
00222 }
00223 
00224 void ADXL362::StartMesure() {
00225     int value;
00226     GetStatus();
00227     value = regRD(POWER_CTL);
00228     value &= ~(POWER_CTL_MODEMASK);
00229     value |= POWER_CTL_MESURE;
00230     regWR(POWER_CTL, POWER_CTL_MESURE);
00231     value = regRD(POWER_CTL);   
00232     wait_ms(5);
00233     GetStatus();
00234 }
00235 
00236 int ADXL362::GetStatus() {
00237     int value;
00238     value = regRD(STATUS);
00239     return value;
00240 }
00241 
00242 /** ==========================================
00243  *  Public ( Sensing )
00244  *  ========================================== */
00245 void ADXL362::SensorRead(AccelTemp *pAT) {
00246     int burstBuf[8];
00247     /* Xx2 + Yx2 + Zx2 + Tempx2 = 8*/
00248     regBurstRD(XDATA_L, 8, burstBuf);
00249     convertSensorData(pAT, burstBuf);
00250 #if 0   
00251     uart->printf("ADXL362[ax] = 0x%02x\n", pAT->ax);
00252     uart->printf("ADXL362[ay] = 0x%02x\n", pAT->ay);
00253     uart->printf("ADXL362[az] = 0x%02x\n", pAT->az);
00254     uart->printf("ADXL362[tm] = 0x%02x\n", pAT->tm)
00255 #endif  
00256     updateMinMax(&minStore, &maxStore, pAT);    
00257 }
00258 
00259 /** ==========================================
00260  *  Public ( Sub Infomation )
00261  *  ========================================== */
00262 /* Get Internal Store (for Min Info) */
00263 AccelTemp* ADXL362::GetMinInfo(void) {
00264     return &minStore;
00265 }
00266 
00267 /* Get Internal Store (for Max Info) */
00268 AccelTemp* ADXL362::GetMaxInfo(void) {
00269     return &maxStore;
00270 }
00271 
00272 /* Convert CtrlValue to Real for Accelerometer */
00273 float ADXL362::ConvAccel(int ctrlval) {
00274     return scaleAccel * (float)ctrlval;
00275 }
00276 
00277 /* Convert CtrlValue to Real for Thermal Sensor */
00278 float ADXL362::ConvThermal(int ctrlval) {
00279     return (scaleThermal * (float)ctrlval) + offsetThermal;
00280 }
00281 
00282 /** ==========================================
00283  *  Private ( convert sensing value )
00284  *  ========================================== */
00285 void ADXL362::convertSensorData(AccelTemp *at, int *buf) {
00286     at->ax = ext12bitToInt(buf[0], buf[1]);
00287     at->ay = ext12bitToInt(buf[2], buf[3]);
00288     at->az = ext12bitToInt(buf[4], buf[5]);
00289     at->tm = ext12bitToInt(buf[6], buf[7]); 
00290 }
00291 
00292 int ADXL362::ext12bitToInt(int l, int h)
00293 {
00294     h <<= 8;
00295     h &= 0x0f00;
00296     h |= l & 0xff;
00297     if ((h & 0x800) != 0) {
00298         h |= 0xfffff000;
00299     }
00300     return h;
00301 }
00302 
00303 /** ==========================================
00304  *  Private ( SPI Communication )
00305  *  ========================================== */
00306 #define ADXL362_SPI_CMD_WR      0x0A
00307 #define ADXL362_SPI_CMD_RD      0x0B
00308 #define ADXL362_SPI_CMD_RD_FIFO 0x0D
00309  
00310 /* Read Single Register */
00311 int ADXL362::regRD(int regAddr) {
00312     int recvData;
00313     regBurstRD(regAddr, 1, &recvData);
00314     return recvData;
00315 }
00316 
00317 /* Read Multi Register */
00318 void ADXL362::regBurstRD(int regAddr, int numBurst, int *recvBuf) {
00319     int cnt;
00320 
00321     /* SPI Burst Read Loop **
00322      * Write A -> Write B : Read A -> Write C : Read B -> ... */
00323     _spi->lock();
00324     chipSelOn();
00325     /* WriteADDR[n] and ReadData[n-1] */
00326     _spi->write(ADXL362_SPI_CMD_RD);
00327     _spi->write(regAddr);       
00328     for (cnt = 0; cnt < numBurst; cnt++) {
00329         /* WriteADDR[n] and ReadData[n-1] */
00330         recvBuf[cnt] = _spi->write(0x00);       
00331     }
00332     chipSelOff();   
00333     _spi->unlock();
00334     return;
00335 }
00336 
00337 /* Write 16bit-Aligned Register */
00338 void ADXL362::regWR(int regAddr, int value) {
00339     _spi->lock();
00340     chipSelOn();
00341     _spi->write(ADXL362_SPI_CMD_WR);    
00342     _spi->write(regAddr);
00343     _spi->write(value);
00344     chipSelOff();
00345     _spi->unlock();
00346     return;
00347 }
00348 
00349 /** ==========================================
00350  *  Private ( Control internal Stores )
00351  *  ========================================== */
00352 /* clear internal Min/Max infomation */ 
00353 void ADXL362::initMinMax
00354 (AccelTemp *minData, AccelTemp *maxData) {
00355     minData->ax = INT_MAX;
00356     minData->ay = INT_MAX;
00357     minData->az = INT_MAX;
00358     minData->tm = INT_MAX;
00359 
00360     maxData->ax = INT_MIN;
00361     maxData->ay = INT_MIN;
00362     maxData->az = INT_MIN;
00363     maxData->tm = INT_MIN;
00364 }
00365 
00366 /* update internal Min/Max infomation */
00367 #define TEST_MIN_AND_SET(now, test) (now = (now >= test)? test : now)
00368 #define TEST_MAX_AND_SET(now, test) (now = (now <= test)? test : now)
00369 void ADXL362::updateMinMax
00370 (AccelTemp *minData, AccelTemp *maxData, AccelTemp *getData) {
00371     TEST_MIN_AND_SET(minData->ax, getData->ax);
00372     TEST_MIN_AND_SET(minData->ay, getData->ay);
00373     TEST_MIN_AND_SET(minData->az, getData->az);
00374     TEST_MIN_AND_SET(minData->tm, getData->tm);
00375 
00376     TEST_MAX_AND_SET(maxData->ax, getData->ax);
00377     TEST_MAX_AND_SET(maxData->ay, getData->ay);
00378     TEST_MAX_AND_SET(maxData->az, getData->az);
00379     TEST_MAX_AND_SET(maxData->tm, getData->tm);
00380 }