AKM AK09970N 3D Magnetic Sensor with Programmable Switch

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AK09970N.cpp Source File

AK09970N.cpp

00001 #include "mbed.h"
00002 #include "AK09970N.h"
00003 
00004 /* Read only Registers */
00005 #define REG_ID          0x00
00006 #define REG_STATUS      0x10
00007 #define REG_ST_X        0x11
00008 #define REG_ST_Y        0x12
00009 #define REG_ST_X_Y      0x13
00010 #define REG_ST_Z        0x14
00011 #define REG_ST_X_Z      0x15
00012 #define REG_ST_Y_Z      0x16
00013 #define REG_ST_X_Y_Z    0x17
00014 #define REG_ST_BX       0x19
00015 #define REG_ST_BY       0x1A
00016 #define REG_ST_BX_BY    0x1B
00017 #define REG_ST_BZ       0x1C
00018 #define REG_ST_BX_BZ    0x1D
00019 #define REG_ST_BY_BZ    0x1E
00020 #define REG_ST_BX_BY_BZ 0x1F
00021 /* Read/Write Registers */
00022 #define REG_INT         0x20
00023 #define REG_CONFIG      0x21
00024 #define REG_THS_X1      0x22
00025 #define REG_THS_X2      0x23
00026 #define REG_THS_Y1      0x24
00027 #define REG_THS_Y2      0x25
00028 #define REG_THS_Z1      0x26
00029 #define REG_THS_Z2      0x27
00030 /* Special function */
00031 #define REG_RESET       0x30
00032 #define REG_I2C_Disable 0x31
00033 #define REG_TEST1       0x40
00034 #define REG_TEST2       0x41
00035 
00036 AK09970N::AK09970N(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
00037     uint8_t data[2] ;
00038     // activate the peripheral
00039     _mode = 0 ; /* power-down mode */
00040     _sdr = 0 ; /* Sensor drive setting */
00041     _smr = 0 ; /* 0: High sensitivity 1: Wide measurement range */
00042     data[0] = REG_INT ;
00043     data[1] = 0x01 ;
00044     writeRegs(data, 2) ;
00045 }
00046 
00047 AK09970N::~AK09970N() { }
00048 
00049 int AK09970N::readRegs(int addr, uint8_t * data, int len) {
00050     int result ;
00051     char t[1] = {addr};
00052     result = m_i2c.write(m_addr, t, 1, true);
00053     if (result == 0) {
00054         m_i2c.read(m_addr, (char *)data, len);
00055     }
00056     return( result ) ;
00057 }
00058 
00059 int AK09970N::writeRegs(uint8_t * data, int len) {
00060     int result ;
00061     result = m_i2c.write(m_addr, (char *)data, len);
00062     return( result ) ;
00063 }
00064 
00065 int AK09970N::software_reset(void)
00066 {
00067     int result ;
00068     uint8_t data[2] = { REG_RESET, 0x01 } ;
00069     result = writeRegs(data, 2) ;
00070     return( result ) ;
00071 }
00072 
00073 int AK09970N::getID(uint16_t *CompanyID, uint16_t *DeviceID)
00074 {
00075     int result ;
00076     uint8_t data[4] ;
00077     result = readRegs(REG_ID, data, 4) ;
00078     if (result == 0) {
00079         *CompanyID = data[0] ;
00080         *DeviceID = data[1] ;
00081     }
00082     return( result ) ;
00083 }
00084 
00085 /**
00086  * REG_STATUS 0x10
00087  * REG_STATUS[15:10] (reserved)
00088  * REG_STATUS[9] DOR : 0: Normal 1: Data overrun
00089  * REG_STATUS[8] ERRADC : 0: Normal 1: ADC overflow
00090  * REG_STATUS[7] ERRXY : 0: Normal 1: Magnetic sensor overflow (X and/or Y)
00091  * REG_STATUS[6] SWZ2 : exceed_THSeshold 2
00092  * REG_STATUS[5] SWZ1 : exceed_THSeshold 1
00093  * REG_STATUS[4] SWY2 : exceed_THSeshold 2
00094  * REG_STATUS[3] SWY1 : exceed_THSeshold 1
00095  * REG_STATUS[2] SWX2 : exceed THSeshold 2
00096  * REG_STATUS[1] SWX1 : exceed THSeshold 1
00097  * REG_STATUS[0] DRDY : 0: Normal 1: Data is ready
00098  */
00099 uint16_t AK09970N::getStatus(void) 
00100 {
00101     int result ;
00102     uint8_t data[2] ;
00103     uint16_t status = 0 ;
00104     result = readRegs(REG_STATUS, data, 2) ;
00105     if (result == 0) { /* success */
00106         status = (data[0] << 8) | data[1] ;
00107     }
00108     return( status ) ;
00109 }
00110 
00111 int AK09970N::setINT(uint16_t value) 
00112 {
00113     int result ;
00114     uint8_t data[3] ;
00115     data[0] = REG_INT ;
00116     data[1] = (value >> 8) & 0xFF ;
00117     data[2] = value & 0xFF ;
00118     result = writeRegs(data, 3) ;
00119     return(result) ;
00120 }
00121 
00122 uint16_t AK09970N::getINT(void) 
00123 {
00124     int result ;
00125     uint8_t data[2] ;
00126     uint16_t value ;
00127     result = readRegs(REG_INT, data, 2) ;
00128     if (result == 0) {
00129         value = (data[0] << 8) | data[1] ;
00130     }
00131     return(value) ;
00132 }
00133 
00134 int AK09970N::setConfig(uint8_t config) 
00135 {
00136     int result ;
00137     uint8_t data[2] ;
00138     data[0] = REG_CONFIG ;
00139     data[1] = config ;
00140     result = writeRegs(data, 2) ;
00141     _mode = config & 0x0F ; /* operation mode 0: power down 1: single 2~: other */
00142     _sdr = (config >> 4) & 0x01 ; /* Sensor drive setting */
00143     _smr = (config >> 5) & 0x01 ; /* Measurement range and sensitivity */
00144     return( result ) ;
00145 }
00146 
00147 uint8_t AK09970N::getConfig(void)
00148 {
00149     int result ;
00150     uint8_t config = 0x00 ;
00151     result = readRegs(REG_CONFIG, &config, 1) ;
00152     if (result == 0) { /* read success, reflect each bits */
00153         _mode = config & 0x0F ;
00154         _sdr = (config >> 4) & 0x01 ;
00155         _smr = (config >> 5) & 0x01 ;
00156     }   
00157     return( config ) ;
00158 }
00159 
00160 int AK09970N::singleShot(void)
00161 {
00162     int result ;
00163     uint8_t config ;
00164     config = (_smr << 5)|(_sdr << 4)|0x01 ;
00165     result = setConfig(config) ;
00166     return( result ) ;
00167 }
00168 
00169 float AK09970N::i2f(int16_t value) 
00170 {
00171     float fvalue ;
00172     if (_smr) {
00173         fvalue = 0.0011 * ((float)value) ;
00174     } else {
00175         fvalue = 0.0031 * ((float)value) ;
00176     }
00177     return( fvalue ) ;
00178 }
00179 
00180 int AK09970N::getX(uint16_t *status, float *x) 
00181 {
00182     int result ;
00183     int16_t hx ;
00184     result = getHX(status, &hx) ;
00185     if (result == 0) {
00186         *x = i2f(hx) ;
00187     }
00188     return(result) ;
00189 }
00190 
00191 int AK09970N::getY(uint16_t *status, float *y) 
00192 {
00193     int result ;
00194     int16_t hy ;
00195     result = getHY(status, &hy) ;
00196     if (result == 0) {
00197         *y = i2f(hy) ;
00198     }
00199     return(result) ;    
00200 }
00201 
00202 int AK09970N::getZ(uint16_t *status, float *z) 
00203 {
00204     int result ;
00205     int16_t hz ;
00206     result = getHZ(status, &hz) ;
00207     if (result == 0) {
00208         *z = i2f(hz) ;
00209     }
00210     return( result ) ;    
00211 }
00212 int AK09970N::getX_Y(uint16_t *status, float *x, float *y) 
00213 {
00214     int result ;
00215     int16_t hx, hy ;
00216     result = getHX_HY(status, &hx, &hy) ;
00217     if (result == 0) {
00218         *x = i2f(hx) ;
00219         *y = i2f(hy) ;
00220     }
00221     return( result ) ;
00222 }
00223 
00224 int AK09970N::getX_Z(uint16_t *status, float *x, float *z) 
00225 {
00226     int result ;
00227     int16_t hx, hz ;
00228     result = getHX_HZ(status, &hx, &hz) ;
00229     if (result == 0) {
00230         *x = i2f(hx) ;
00231         *z = i2f(hz) ;
00232     }
00233     return( result ) ;
00234 }
00235 
00236 int AK09970N::getY_Z(uint16_t *status, float *y, float *z) 
00237 {
00238     int result ;
00239     int16_t hy, hz ;
00240     result = getHY_HZ(status, &hy, &hz) ;
00241     if (result == 0) {
00242         *y = i2f(hy) ;
00243         *z = i2f(hz) ;
00244     }
00245     return( result ) ;
00246 }
00247 
00248 int AK09970N::getX_Y_Z(uint16_t *status, float *x, float *y, float *z) 
00249 {
00250     int result ;
00251     int16_t hx, hy, hz ;
00252     result = getHX_HY_HZ(status, &hx, &hy, &hz) ;
00253     if (result == 0) {
00254         *x = i2f(hx) ;
00255         *y = i2f(hy) ;
00256         *z = i2f(hz) ;
00257     }
00258     return( result ) ;
00259 }
00260   
00261 int AK09970N::getHX(uint16_t *status, int16_t *x) 
00262 {
00263     int result ;
00264     uint8_t data[4] ;
00265     result = readRegs(REG_ST_X, data, 4) ;
00266     if (result == 0) { /* success */
00267         *status = (data[0] << 8) | data[1] ;
00268         *x = (int16_t)((data[2] << 8) | data[3]) ;
00269     }
00270     return( result ) ;
00271 }
00272 
00273 int AK09970N::getHY(uint16_t *status, int16_t *y) 
00274 {
00275     int result ;
00276     uint8_t data[4] ;
00277     result = readRegs(REG_ST_Y, data, 4) ;
00278     if (result == 0) { /* success */
00279         *status = (data[0] << 8) | data[1] ;
00280         *y = (int16_t)((data[2] << 8) | data[3]) ;
00281     }
00282     return( result ) ;
00283 }
00284 
00285 int AK09970N::getHZ(uint16_t *status, int16_t *z) 
00286 {
00287     int result ;
00288     uint8_t data[4] ;
00289     result = readRegs(REG_ST_Z, data, 4) ;
00290     if (result == 0) { /* success */
00291         *status = (data[0] << 8) | data[1] ;
00292         *z = (int16_t)((data[2] << 8) | data[3]) ;
00293     }
00294     return( result ) ;
00295 }
00296 
00297 int AK09970N::getHX_HY(uint16_t *status, int16_t *x, int16_t *y) 
00298 {
00299     int result ;
00300     uint8_t data[6] ;
00301     result = readRegs(REG_ST_X_Y, data, 6) ;
00302     if (result == 0) { /* success */
00303         *status = (data[0] << 8) | data[1] ;
00304         *y = (int16_t)((data[2] << 8) | data[3]) ;
00305         *x = (int16_t)((data[4] << 8) | data[5]) ;
00306     }
00307     return( result ) ;
00308 }
00309 
00310 int AK09970N::getHX_HZ(uint16_t *status, int16_t *x, int16_t *z) 
00311 {
00312     int result ;
00313     uint8_t data[6] ;
00314     result = readRegs(REG_ST_X_Z, data, 6) ;
00315     if (result == 0) { /* success */
00316         *status = (data[0] << 8) | data[1] ;
00317         *z = (int16_t)((data[2] << 8) | data[3]) ;
00318         *x = (int16_t)((data[4] << 8) | data[5]) ;
00319     }
00320     return( result ) ;
00321 }
00322 
00323 int AK09970N::getHY_HZ(uint16_t *status, int16_t *y, int16_t *z) 
00324 {
00325     int result ;
00326     uint8_t data[6] ;
00327     result = readRegs(REG_ST_Y_Z, data, 6) ;
00328     if (result == 0) { /* success */
00329         *status = (data[0] << 8) | data[1] ;
00330         *z = (int16_t)((data[2] << 8) | data[3]) ;
00331         *y = (int16_t)((data[4] << 8) | data[5]) ;
00332     }
00333     return( result ) ;
00334 }
00335 
00336 int AK09970N::getHX_HY_HZ(uint16_t *status, int16_t *x, int16_t *y, int16_t *z) 
00337 {
00338     int result ;
00339     uint8_t data[8] ;
00340     result = readRegs(REG_ST_X_Y_Z, data, 8) ;
00341     if (result == 0) { /* success */
00342         *status = (data[0] << 8) | data[1] ;
00343         *z = (int16_t)((data[2] << 8) | data[3]) ;
00344         *y = (int16_t)((data[4] << 8) | data[5]) ;
00345         *x = (int16_t)((data[6] << 8) | data[7]) ;
00346     }
00347     return( result ) ;    
00348 }
00349 
00350 /* get measured data 8bit versions */
00351 int AK09970N::getBX(uint16_t *status, int8_t *x) 
00352 {
00353     int result ;
00354     uint8_t data[3] ;
00355     result = readRegs(REG_ST_BX, data, 3) ;
00356     if (result == 0) { /* success */
00357         *status = (data[0] << 8) | data[1] ;
00358         *x = (int8_t)data[2] ; 
00359     }
00360     return( result ) ;
00361 }
00362 
00363 int AK09970N::getBY(uint16_t *status, int8_t *y) 
00364 {
00365     int result ;
00366     uint8_t data[3] ;
00367     result = readRegs(REG_ST_BY, data, 3) ;
00368     if (result == 0) { /* success */
00369         *status = (data[0] << 8) | data[1] ;
00370         *y = (int8_t)data[2] ; 
00371     }
00372     return( result ) ;
00373 }
00374 
00375 int AK09970N::getBZ(uint16_t *status, int8_t *z) 
00376 {
00377     int result ;
00378     uint8_t data[3] ;
00379     result = readRegs(REG_ST_BZ, data, 3) ;
00380     if (result == 0) { /* success */
00381         *status = (data[0] << 8) | data[1] ;
00382         *z = (int8_t)data[2] ; 
00383     }
00384     return( result ) ;
00385 }
00386 
00387 int AK09970N::getBX_BY(uint16_t *status, int8_t *x, int8_t *y) 
00388 {
00389     int result ;
00390     uint8_t data[4] ;
00391     result = readRegs(REG_ST_BX_BY, data, 4) ;
00392     if (result == 0) { /* success */
00393         *status = (data[0] << 8) | data[1] ;
00394         *y = (int8_t)data[2] ;
00395         *x = (int8_t)data[3] ; 
00396     }
00397     return( result ) ;
00398 }
00399 
00400 int AK09970N::getBX_BZ(uint16_t *status, int8_t *x, int8_t *z) 
00401 {
00402     int result ;
00403     uint8_t data[4] ;
00404     result = readRegs(REG_ST_BX_BZ, data, 4) ;
00405     if (result == 0) { /* success */
00406         *status = (data[0] << 8) | data[1] ;
00407         *z = (int8_t)data[2] ;
00408         *x = (int8_t)data[3] ; 
00409     }
00410     return( result ) ;
00411 }
00412 
00413 int AK09970N::getBY_BZ(uint16_t *status, int8_t *y, int8_t *z)
00414 {
00415     int result ;
00416     uint8_t data[4] ;
00417     result = readRegs(REG_ST_BY_BZ, data, 4) ;
00418     if (result == 0) { /* success */
00419         *status = (data[0] << 8) | data[1] ;
00420         *z = (int8_t)data[2] ;
00421         *y = (int8_t)data[3] ; 
00422     }
00423     return( result ) ;
00424 }
00425 
00426 int AK09970N::getBX_BY_BZ(uint16_t *status, int8_t *x, int8_t *y, int8_t *z) 
00427 {
00428     int result ;
00429     uint8_t data[5] ;
00430     result = readRegs(REG_ST_BX_BY_BZ, data, 4) ;
00431     if (result == 0) { /* success */
00432         *status = (data[0] << 8) | data[1] ;
00433         *z = (int8_t)data[2] ;
00434         *y = (int8_t)data[3] ; 
00435         *x = (int8_t)data[4] ;
00436     }
00437     return( result ) ;    
00438 }
00439   
00440 int AK09970N::getTHS_X1(int16_t *bop, int16_t *brp) 
00441 {
00442     int result ;
00443     uint8_t data[4] ;
00444     result = readRegs(REG_THS_X1, data, 4) ;
00445     if (result == 0) { /* success */
00446         *bop = (int16_t)((data[0] << 8) | data[1]) ;
00447         *brp = (int16_t)((data[2] << 8) | data[3]) ;
00448     }
00449     return( result ) ;
00450 }
00451 
00452 int AK09970N::getTHS_X2(int16_t *bop, int16_t *brp) 
00453 {
00454     int result ;
00455     uint8_t data[4] ;
00456     result = readRegs(REG_THS_X2, data, 4) ;
00457     if (result == 0) { /* success */
00458         *bop = (int16_t)((data[0] << 8) | data[1]) ;
00459         *brp = (int16_t)((data[2] << 8) | data[3]) ;
00460     }
00461     return( result ) ;    
00462 }
00463 
00464 int AK09970N::getTHS_Y1(int16_t *bop, int16_t *brp) 
00465 {
00466     int result ;
00467     uint8_t data[4] ;
00468     result = readRegs(REG_THS_Y1, data, 4) ;
00469     if (result == 0) { /* success */
00470         *bop = (int16_t)((data[0] << 8) | data[1]) ;
00471         *brp = (int16_t)((data[2] << 8) | data[3]) ;
00472     }
00473     return( result ) ;    
00474 }
00475 
00476 int AK09970N::getTHS_Y2(int16_t *bop, int16_t *brp) 
00477 {
00478     int result ;
00479     uint8_t data[4] ;
00480     result = readRegs(REG_THS_Y2, data, 4) ;
00481     if (result == 0) { /* success */
00482         *bop = (int16_t)((data[0] << 8) | data[1]) ;
00483         *brp = (int16_t)((data[2] << 8) | data[3]) ;
00484     }
00485     return( result ) ;    
00486 }
00487 
00488 int AK09970N::getTHS_Z1(int16_t *bop, int16_t *brp) 
00489 {
00490     int result ;
00491     uint8_t data[4] ;
00492     result = readRegs(REG_THS_Z1, data, 4) ;
00493     if (result == 0) { /* success */
00494         *bop = (int16_t)((data[0] << 8) | data[1]) ;
00495         *brp = (int16_t)((data[2] << 8) | data[3]) ;
00496     }
00497     return( result ) ;    
00498 }
00499 
00500 int AK09970N::getTHS_Z2(int16_t *bop, int16_t *brp)
00501 {
00502     int result ;
00503     uint8_t data[4] ;
00504     result = readRegs(REG_THS_Z2, data, 4) ;
00505     if (result == 0) { /* success */
00506         *bop = (int16_t)((data[0] << 8) | data[1]) ;
00507         *brp = (int16_t)((data[2] << 8) | data[3]) ;
00508     }
00509     return( result ) ;    
00510 }
00511   
00512 int AK09970N::setTHS_X1(int16_t bop, int16_t brp)
00513 {
00514     int result ;
00515     uint8_t data[5] ;
00516     data[0] = REG_THS_X1 ;
00517     data[1] = (bop >> 8) & 0xFF ;
00518     data[2] = bop & 0xFF ;
00519     data[3] = (brp >> 8) & 0xFF ;
00520     data[4] = brp & 0xFF ;
00521     result = writeRegs(data, 5) ;
00522     return( result ) ;    
00523 }
00524 
00525 int AK09970N::setTHS_X2(int16_t bop, int16_t brp) 
00526 {
00527     int result ;
00528     uint8_t data[5] ;
00529     data[0] = REG_THS_X2 ;
00530     data[1] = (bop >> 8) & 0xFF ;
00531     data[2] = bop & 0xFF ;
00532     data[3] = (brp >> 8) & 0xFF ;
00533     data[4] = brp & 0xFF ;
00534     result = writeRegs(data, 5) ;
00535     return( result ) ;    
00536 }
00537 
00538 int AK09970N::setTHS_Y1(int16_t bop, int16_t brp) 
00539 {
00540     int result ;
00541     uint8_t data[5] ;
00542     data[0] = REG_THS_Y1 ;
00543     data[1] = (bop >> 8) & 0xFF ;
00544     data[2] = bop & 0xFF ;
00545     data[3] = (brp >> 8) & 0xFF ;
00546     data[4] = brp & 0xFF ;
00547     result = writeRegs(data, 5) ;
00548     return( result ) ;    
00549 }
00550 
00551 int AK09970N::setTHS_Y2(int16_t bop, int16_t brp) 
00552 {
00553     int result ;
00554     uint8_t data[5] ;
00555     data[0] = REG_THS_Y2 ;
00556     data[1] = (bop >> 8) & 0xFF ;
00557     data[2] = bop & 0xFF ;
00558     data[3] = (brp >> 8) & 0xFF ;
00559     data[4] = brp & 0xFF ;
00560     result = writeRegs(data, 5) ;
00561     return( result ) ;    
00562 }
00563 
00564 int AK09970N::setTHS_Z1(int16_t bop, int16_t brp) 
00565 {
00566     int result ;
00567     uint8_t data[5] ;
00568     data[0] = REG_THS_Z1 ;
00569     data[1] = (bop >> 8) & 0xFF ;
00570     data[2] = bop & 0xFF ;
00571     data[3] = (brp >> 8) & 0xFF ;
00572     data[4] = brp & 0xFF ;
00573     result = writeRegs(data, 5) ;
00574     return( result ) ;    
00575 }
00576 
00577 int AK09970N::setTHS_Z2(int16_t bop, int16_t brp) 
00578 {
00579     int result ;
00580     uint8_t data[5] ;
00581     data[0] = REG_THS_Z2 ;
00582     data[1] = (bop >> 8) & 0xFF ;
00583     data[2] = bop & 0xFF ;
00584     data[3] = (brp >> 8) & 0xFF ;
00585     data[4] = brp & 0xFF ;
00586     result = writeRegs(data, 5) ;
00587     return( result ) ;    
00588 }