AKM AK09970N 3D Magnetic Sensor with Programmable Switch
AK09970N.cpp
- Committer:
- Rhyme
- Date:
- 2017-12-28
- Revision:
- 1:2b2ead3e4efc
File content as of revision 1:2b2ead3e4efc:
#include "mbed.h" #include "AK09970N.h" /* Read only Registers */ #define REG_ID 0x00 #define REG_STATUS 0x10 #define REG_ST_X 0x11 #define REG_ST_Y 0x12 #define REG_ST_X_Y 0x13 #define REG_ST_Z 0x14 #define REG_ST_X_Z 0x15 #define REG_ST_Y_Z 0x16 #define REG_ST_X_Y_Z 0x17 #define REG_ST_BX 0x19 #define REG_ST_BY 0x1A #define REG_ST_BX_BY 0x1B #define REG_ST_BZ 0x1C #define REG_ST_BX_BZ 0x1D #define REG_ST_BY_BZ 0x1E #define REG_ST_BX_BY_BZ 0x1F /* Read/Write Registers */ #define REG_INT 0x20 #define REG_CONFIG 0x21 #define REG_THS_X1 0x22 #define REG_THS_X2 0x23 #define REG_THS_Y1 0x24 #define REG_THS_Y2 0x25 #define REG_THS_Z1 0x26 #define REG_THS_Z2 0x27 /* Special function */ #define REG_RESET 0x30 #define REG_I2C_Disable 0x31 #define REG_TEST1 0x40 #define REG_TEST2 0x41 AK09970N::AK09970N(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) { uint8_t data[2] ; // activate the peripheral _mode = 0 ; /* power-down mode */ _sdr = 0 ; /* Sensor drive setting */ _smr = 0 ; /* 0: High sensitivity 1: Wide measurement range */ data[0] = REG_INT ; data[1] = 0x01 ; writeRegs(data, 2) ; } AK09970N::~AK09970N() { } int AK09970N::readRegs(int addr, uint8_t * data, int len) { int result ; char t[1] = {addr}; result = m_i2c.write(m_addr, t, 1, true); if (result == 0) { m_i2c.read(m_addr, (char *)data, len); } return( result ) ; } int AK09970N::writeRegs(uint8_t * data, int len) { int result ; result = m_i2c.write(m_addr, (char *)data, len); return( result ) ; } int AK09970N::software_reset(void) { int result ; uint8_t data[2] = { REG_RESET, 0x01 } ; result = writeRegs(data, 2) ; return( result ) ; } int AK09970N::getID(uint16_t *CompanyID, uint16_t *DeviceID) { int result ; uint8_t data[4] ; result = readRegs(REG_ID, data, 4) ; if (result == 0) { *CompanyID = data[0] ; *DeviceID = data[1] ; } return( result ) ; } /** * REG_STATUS 0x10 * REG_STATUS[15:10] (reserved) * REG_STATUS[9] DOR : 0: Normal 1: Data overrun * REG_STATUS[8] ERRADC : 0: Normal 1: ADC overflow * REG_STATUS[7] ERRXY : 0: Normal 1: Magnetic sensor overflow (X and/or Y) * REG_STATUS[6] SWZ2 : exceed_THSeshold 2 * REG_STATUS[5] SWZ1 : exceed_THSeshold 1 * REG_STATUS[4] SWY2 : exceed_THSeshold 2 * REG_STATUS[3] SWY1 : exceed_THSeshold 1 * REG_STATUS[2] SWX2 : exceed THSeshold 2 * REG_STATUS[1] SWX1 : exceed THSeshold 1 * REG_STATUS[0] DRDY : 0: Normal 1: Data is ready */ uint16_t AK09970N::getStatus(void) { int result ; uint8_t data[2] ; uint16_t status = 0 ; result = readRegs(REG_STATUS, data, 2) ; if (result == 0) { /* success */ status = (data[0] << 8) | data[1] ; } return( status ) ; } int AK09970N::setINT(uint16_t value) { int result ; uint8_t data[3] ; data[0] = REG_INT ; data[1] = (value >> 8) & 0xFF ; data[2] = value & 0xFF ; result = writeRegs(data, 3) ; return(result) ; } uint16_t AK09970N::getINT(void) { int result ; uint8_t data[2] ; uint16_t value ; result = readRegs(REG_INT, data, 2) ; if (result == 0) { value = (data[0] << 8) | data[1] ; } return(value) ; } int AK09970N::setConfig(uint8_t config) { int result ; uint8_t data[2] ; data[0] = REG_CONFIG ; data[1] = config ; result = writeRegs(data, 2) ; _mode = config & 0x0F ; /* operation mode 0: power down 1: single 2~: other */ _sdr = (config >> 4) & 0x01 ; /* Sensor drive setting */ _smr = (config >> 5) & 0x01 ; /* Measurement range and sensitivity */ return( result ) ; } uint8_t AK09970N::getConfig(void) { int result ; uint8_t config = 0x00 ; result = readRegs(REG_CONFIG, &config, 1) ; if (result == 0) { /* read success, reflect each bits */ _mode = config & 0x0F ; _sdr = (config >> 4) & 0x01 ; _smr = (config >> 5) & 0x01 ; } return( config ) ; } int AK09970N::singleShot(void) { int result ; uint8_t config ; config = (_smr << 5)|(_sdr << 4)|0x01 ; result = setConfig(config) ; return( result ) ; } float AK09970N::i2f(int16_t value) { float fvalue ; if (_smr) { fvalue = 0.0011 * ((float)value) ; } else { fvalue = 0.0031 * ((float)value) ; } return( fvalue ) ; } int AK09970N::getX(uint16_t *status, float *x) { int result ; int16_t hx ; result = getHX(status, &hx) ; if (result == 0) { *x = i2f(hx) ; } return(result) ; } int AK09970N::getY(uint16_t *status, float *y) { int result ; int16_t hy ; result = getHY(status, &hy) ; if (result == 0) { *y = i2f(hy) ; } return(result) ; } int AK09970N::getZ(uint16_t *status, float *z) { int result ; int16_t hz ; result = getHZ(status, &hz) ; if (result == 0) { *z = i2f(hz) ; } return( result ) ; } int AK09970N::getX_Y(uint16_t *status, float *x, float *y) { int result ; int16_t hx, hy ; result = getHX_HY(status, &hx, &hy) ; if (result == 0) { *x = i2f(hx) ; *y = i2f(hy) ; } return( result ) ; } int AK09970N::getX_Z(uint16_t *status, float *x, float *z) { int result ; int16_t hx, hz ; result = getHX_HZ(status, &hx, &hz) ; if (result == 0) { *x = i2f(hx) ; *z = i2f(hz) ; } return( result ) ; } int AK09970N::getY_Z(uint16_t *status, float *y, float *z) { int result ; int16_t hy, hz ; result = getHY_HZ(status, &hy, &hz) ; if (result == 0) { *y = i2f(hy) ; *z = i2f(hz) ; } return( result ) ; } int AK09970N::getX_Y_Z(uint16_t *status, float *x, float *y, float *z) { int result ; int16_t hx, hy, hz ; result = getHX_HY_HZ(status, &hx, &hy, &hz) ; if (result == 0) { *x = i2f(hx) ; *y = i2f(hy) ; *z = i2f(hz) ; } return( result ) ; } int AK09970N::getHX(uint16_t *status, int16_t *x) { int result ; uint8_t data[4] ; result = readRegs(REG_ST_X, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *x = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getHY(uint16_t *status, int16_t *y) { int result ; uint8_t data[4] ; result = readRegs(REG_ST_Y, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *y = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getHZ(uint16_t *status, int16_t *z) { int result ; uint8_t data[4] ; result = readRegs(REG_ST_Z, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getHX_HY(uint16_t *status, int16_t *x, int16_t *y) { int result ; uint8_t data[6] ; result = readRegs(REG_ST_X_Y, data, 6) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *y = (int16_t)((data[2] << 8) | data[3]) ; *x = (int16_t)((data[4] << 8) | data[5]) ; } return( result ) ; } int AK09970N::getHX_HZ(uint16_t *status, int16_t *x, int16_t *z) { int result ; uint8_t data[6] ; result = readRegs(REG_ST_X_Z, data, 6) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int16_t)((data[2] << 8) | data[3]) ; *x = (int16_t)((data[4] << 8) | data[5]) ; } return( result ) ; } int AK09970N::getHY_HZ(uint16_t *status, int16_t *y, int16_t *z) { int result ; uint8_t data[6] ; result = readRegs(REG_ST_Y_Z, data, 6) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int16_t)((data[2] << 8) | data[3]) ; *y = (int16_t)((data[4] << 8) | data[5]) ; } return( result ) ; } int AK09970N::getHX_HY_HZ(uint16_t *status, int16_t *x, int16_t *y, int16_t *z) { int result ; uint8_t data[8] ; result = readRegs(REG_ST_X_Y_Z, data, 8) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int16_t)((data[2] << 8) | data[3]) ; *y = (int16_t)((data[4] << 8) | data[5]) ; *x = (int16_t)((data[6] << 8) | data[7]) ; } return( result ) ; } /* get measured data 8bit versions */ int AK09970N::getBX(uint16_t *status, int8_t *x) { int result ; uint8_t data[3] ; result = readRegs(REG_ST_BX, data, 3) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *x = (int8_t)data[2] ; } return( result ) ; } int AK09970N::getBY(uint16_t *status, int8_t *y) { int result ; uint8_t data[3] ; result = readRegs(REG_ST_BY, data, 3) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *y = (int8_t)data[2] ; } return( result ) ; } int AK09970N::getBZ(uint16_t *status, int8_t *z) { int result ; uint8_t data[3] ; result = readRegs(REG_ST_BZ, data, 3) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int8_t)data[2] ; } return( result ) ; } int AK09970N::getBX_BY(uint16_t *status, int8_t *x, int8_t *y) { int result ; uint8_t data[4] ; result = readRegs(REG_ST_BX_BY, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *y = (int8_t)data[2] ; *x = (int8_t)data[3] ; } return( result ) ; } int AK09970N::getBX_BZ(uint16_t *status, int8_t *x, int8_t *z) { int result ; uint8_t data[4] ; result = readRegs(REG_ST_BX_BZ, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int8_t)data[2] ; *x = (int8_t)data[3] ; } return( result ) ; } int AK09970N::getBY_BZ(uint16_t *status, int8_t *y, int8_t *z) { int result ; uint8_t data[4] ; result = readRegs(REG_ST_BY_BZ, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int8_t)data[2] ; *y = (int8_t)data[3] ; } return( result ) ; } int AK09970N::getBX_BY_BZ(uint16_t *status, int8_t *x, int8_t *y, int8_t *z) { int result ; uint8_t data[5] ; result = readRegs(REG_ST_BX_BY_BZ, data, 4) ; if (result == 0) { /* success */ *status = (data[0] << 8) | data[1] ; *z = (int8_t)data[2] ; *y = (int8_t)data[3] ; *x = (int8_t)data[4] ; } return( result ) ; } int AK09970N::getTHS_X1(int16_t *bop, int16_t *brp) { int result ; uint8_t data[4] ; result = readRegs(REG_THS_X1, data, 4) ; if (result == 0) { /* success */ *bop = (int16_t)((data[0] << 8) | data[1]) ; *brp = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getTHS_X2(int16_t *bop, int16_t *brp) { int result ; uint8_t data[4] ; result = readRegs(REG_THS_X2, data, 4) ; if (result == 0) { /* success */ *bop = (int16_t)((data[0] << 8) | data[1]) ; *brp = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getTHS_Y1(int16_t *bop, int16_t *brp) { int result ; uint8_t data[4] ; result = readRegs(REG_THS_Y1, data, 4) ; if (result == 0) { /* success */ *bop = (int16_t)((data[0] << 8) | data[1]) ; *brp = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getTHS_Y2(int16_t *bop, int16_t *brp) { int result ; uint8_t data[4] ; result = readRegs(REG_THS_Y2, data, 4) ; if (result == 0) { /* success */ *bop = (int16_t)((data[0] << 8) | data[1]) ; *brp = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getTHS_Z1(int16_t *bop, int16_t *brp) { int result ; uint8_t data[4] ; result = readRegs(REG_THS_Z1, data, 4) ; if (result == 0) { /* success */ *bop = (int16_t)((data[0] << 8) | data[1]) ; *brp = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::getTHS_Z2(int16_t *bop, int16_t *brp) { int result ; uint8_t data[4] ; result = readRegs(REG_THS_Z2, data, 4) ; if (result == 0) { /* success */ *bop = (int16_t)((data[0] << 8) | data[1]) ; *brp = (int16_t)((data[2] << 8) | data[3]) ; } return( result ) ; } int AK09970N::setTHS_X1(int16_t bop, int16_t brp) { int result ; uint8_t data[5] ; data[0] = REG_THS_X1 ; data[1] = (bop >> 8) & 0xFF ; data[2] = bop & 0xFF ; data[3] = (brp >> 8) & 0xFF ; data[4] = brp & 0xFF ; result = writeRegs(data, 5) ; return( result ) ; } int AK09970N::setTHS_X2(int16_t bop, int16_t brp) { int result ; uint8_t data[5] ; data[0] = REG_THS_X2 ; data[1] = (bop >> 8) & 0xFF ; data[2] = bop & 0xFF ; data[3] = (brp >> 8) & 0xFF ; data[4] = brp & 0xFF ; result = writeRegs(data, 5) ; return( result ) ; } int AK09970N::setTHS_Y1(int16_t bop, int16_t brp) { int result ; uint8_t data[5] ; data[0] = REG_THS_Y1 ; data[1] = (bop >> 8) & 0xFF ; data[2] = bop & 0xFF ; data[3] = (brp >> 8) & 0xFF ; data[4] = brp & 0xFF ; result = writeRegs(data, 5) ; return( result ) ; } int AK09970N::setTHS_Y2(int16_t bop, int16_t brp) { int result ; uint8_t data[5] ; data[0] = REG_THS_Y2 ; data[1] = (bop >> 8) & 0xFF ; data[2] = bop & 0xFF ; data[3] = (brp >> 8) & 0xFF ; data[4] = brp & 0xFF ; result = writeRegs(data, 5) ; return( result ) ; } int AK09970N::setTHS_Z1(int16_t bop, int16_t brp) { int result ; uint8_t data[5] ; data[0] = REG_THS_Z1 ; data[1] = (bop >> 8) & 0xFF ; data[2] = bop & 0xFF ; data[3] = (brp >> 8) & 0xFF ; data[4] = brp & 0xFF ; result = writeRegs(data, 5) ; return( result ) ; } int AK09970N::setTHS_Z2(int16_t bop, int16_t brp) { int result ; uint8_t data[5] ; data[0] = REG_THS_Z2 ; data[1] = (bop >> 8) & 0xFF ; data[2] = bop & 0xFF ; data[3] = (brp >> 8) & 0xFF ; data[4] = brp & 0xFF ; result = writeRegs(data, 5) ; return( result ) ; }