Update
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Sun Jul 17 2022 16:50:02 by 1.7.2