Basic functions is OK. Lack interrupts function.
Revision 0:4f87d5af61b1, committed 2017-01-26
- Comitter:
- bcc6
- Date:
- Thu Jan 26 03:08:15 2017 +0000
- Child:
- 1:4eefcf1d7351
- Commit message:
- Basic functions is OK. Lack interrupts function.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AK09912.cpp Thu Jan 26 03:08:15 2017 +0000 @@ -0,0 +1,76 @@ +#include "AK09912.h" + + +AK09912::AK09912(I2C &i2c, PinName int1) : _i2c(i2c), _int1(int1) { + +} + +void AK09912::ConfigDevice() { + /* Soft reset */ + RegWrite(0x32, 0x01); + + /* Get sensitivity adjustment values */ + RegWrite(0x31, 0x1F); // MODE(Fuse ROM ACCESS) + RegRead(0x60, (char *)_asa, 3); // ASAX, ASAY, ASAZ + RegWrite(0x31, 0x00); // MODE(Power down) + + /* Enable both temperature measurement and noise suppression filter */ + RegWrite(0x30, 0xE0); // TEM(Enable), NSF(High) + + /* Mode */ + RegWrite(0x31, 0x02); // MODE(ContMode1) +} + +void AK09912::GetDeviceID(uint8_t *id) { + RegRead(0x01, (char *)id, 1); +} + +void AK09912::GetData(Data *data){ + char status; + char buf[10]; + + /* Read data */ + RegRead(0x10, &status, 1); + RegRead(0x11, buf, 7); + RegRead(0x18, &status, 1); // Dummy read + + /* Format data */ + int16_t x_adc = (((int16_t)buf[1]) << 8) | buf[0]; + int16_t y_adc = (((int16_t)buf[3]) << 8) | buf[2]; + int16_t z_adc = (((int16_t)buf[5]) << 8) | buf[4]; + uint8_t t_adc = buf[6]; + + /* Convert data */ + data->x = ConvertAdcToMagnetic(x_adc, _asa[0]); + data->y = ConvertAdcToMagnetic(y_adc, _asa[1]); + data->z = ConvertAdcToMagnetic(z_adc, _asa[2]); + data->t = ConvertAdcToTemperature(t_adc); +} + +float AK09912::ConvertAdcToMagnetic(int16_t adc, uint8_t asa) { + float magnetic_flux_density = (float)adc * 0.15f; // Original + return magnetic_flux_density * (((float)asa - 128) * 0.5f / 128 + 1); // Adjustment +} + +float AK09912::ConvertAdcToTemperature(uint8_t adc) { + return (120.0f - (float)adc) / 1.6f + 35.0f; +} + +void AK09912::RegWrite(char reg, char val) { + char data[2]; + data[0] = reg; + data[1] = val; + _i2c.write(AK09912_SLAVE_ADDR, data, 2, 0); +} + +void AK09912::RegRead(char reg, char *val, int len) { + _i2c.write(AK09912_SLAVE_ADDR, ®, 1, 0); + _i2c.read (AK09912_SLAVE_ADDR, val, len); +} + +void AK09912::RegReadModifyWrite(char reg, char clr_mask, char set_mask) { + char val; + RegRead (reg, &val, 1); // Read + val = (val & ~clr_mask) | set_mask; // Modify + RegWrite(reg, val); // Write +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AK09912.h Thu Jan 26 03:08:15 2017 +0000 @@ -0,0 +1,41 @@ +#ifndef AK09912_H +#define AK09912_H + +#include "mbed.h" + + +#define AK09912_SLAVE_ADDR 0x1A // 0001_1010b + + +class AK09912 { +public: + struct Data { + float x; // uT/LSB + float y; + float z; + float t; // 'C + }; + + static const uint8_t DEVICE_ID = 0x04; + + AK09912(I2C &i2c, PinName int1 = NC); + + void ConfigDevice(); + void GetDeviceID(uint8_t *id); + void GetData(Data *data); + +private: + I2C &_i2c; + InterruptIn _int1; + + uint8_t _asa[3]; // ASAX, ASAY, ASAZ + + float ConvertAdcToMagnetic(int16_t adc, uint8_t asa); + float ConvertAdcToTemperature(uint8_t adc); + + void RegWrite(char reg, char val); + void RegRead (char reg, char *val, int len); + void RegReadModifyWrite(char reg, char clr_mask, char set_mask); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AK09970.cpp Thu Jan 26 03:08:15 2017 +0000 @@ -0,0 +1,76 @@ +#include "AK09970.h" + + +AK09970::AK09970(I2C &i2c, PinName int1) : _i2c(i2c), _int1(int1) { + +} + +void AK09970::ConfigDevice() { + char val[8]; + + /* Soft reset */ + RegWrite(0x30, 0x01); + + /* Disable all interrupts */ + val[0] = 0x00; + val[1] = 0x00; + RegWrite(0x20, val, 2); + + /* Mode */ + RegWrite(0x21, 0x02); // SMR(HighSensitivity), SDR(LowNoiseDrive), MODE(ContMode1) +} + +void AK09970::GetDeviceID(uint8_t *id) { + char buf[2]; + RegRead(0x00, buf, 2); + *id = buf[1]; +} + +void AK09970::GetData(Data *data) { + char buf[8]; + + /* Read data */ + RegRead(0x17, buf, 8); + + /* Format data */ + uint16_t status = (((uint16_t)buf[0]) << 8) | buf[1]; + int16_t x_adc = (((int16_t)buf[6]) << 8) | buf[7]; + int16_t y_adc = (((int16_t)buf[4]) << 8) | buf[5]; + int16_t z_adc = (((int16_t)buf[2]) << 8) | buf[3]; + + /* Convert data */ + data->x = ConvertAdcToMagnetic(x_adc); + data->y = ConvertAdcToMagnetic(y_adc); + data->z = ConvertAdcToMagnetic(z_adc); +} + +float AK09970::ConvertAdcToMagnetic(int16_t adc) { + float magnetic_flux_density = (float)adc * 1.1f; + return magnetic_flux_density; +} + +void AK09970::RegWrite(char reg, char val) { + char data[2]; + data[0] = reg; + data[1] = val; + _i2c.write(AK09970_SLAVE_ADDR, data, 2, 0); +} + +void AK09970::RegWrite(char reg, char *val, int len) { + char data[9]; + data[0] = reg; + memcpy((data+1), val, len); + _i2c.write(AK09970_SLAVE_ADDR, data, (len+1), 0); +} + +void AK09970::RegRead(char reg, char *val, int len) { + _i2c.write(AK09970_SLAVE_ADDR, ®, 1, 0); + _i2c.read (AK09970_SLAVE_ADDR, val, len); +} + +void AK09970::RegReadModifyWrite(char reg, char clr_mask, char set_mask) { + char val; + RegRead (reg, &val, 1); // Read + val = (val & ~clr_mask) | set_mask; // Modify + RegWrite(reg, &val, 1); // Write +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AK09970.h Thu Jan 26 03:08:15 2017 +0000 @@ -0,0 +1,38 @@ +#ifndef AK09970_H +#define AK09970_H + +#include "mbed.h" + + +#define AK09970_SLAVE_ADDR 0x18 // 0001_1000b + + +class AK09970 { +public: + struct Data { + float x; // uT/LSB + float y; + float z; + }; + + static const uint8_t DEVICE_ID = 0xC0; + + AK09970(I2C &i2c, PinName int1 = NC); + + void ConfigDevice(); + void GetDeviceID(uint8_t *id); + void GetData(Data *data); + +private: + I2C &_i2c; + InterruptIn _int1; + + float ConvertAdcToMagnetic(int16_t adc); + + void RegWrite(char reg, char val); + void RegWrite(char reg, char *val, int len); + void RegRead (char reg, char *val, int len); + void RegReadModifyWrite(char reg, char clr_mask, char set_mask); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AK9750.cpp Thu Jan 26 03:08:15 2017 +0000 @@ -0,0 +1,135 @@ +#include "AK9750.h" + + +/* ADC to IR(current) */ +struct AdcToIr { + int16_t adc; + float current; // Unit:pA +}; +static const AdcToIr a2i_table[] = { + {0x7FFF, 14286.4f}, + {0x5998, 10000.1f}, + {0x4082, 7000.1f}, + {0x08F6, 1000.2f}, + {0x0020, 14.0f}, + {0x0000, 0.0f}, + {0xFFE0, -13.5f}, + {0xF709, -1000.2f}, + {0xBF7D, -7200.1f}, + {0x9667, -10000.1f}, + {0x8000, -14286.8f}, +}; +#define A2I_TABLE_COUNT ((sizeof(a2i_table) / sizeof(AdcToIr))) + +/* ADC to temperature('C) */ +#define A2T_TEMPERATURE_OFFSET (26.75f) +#define A2T_10BIT_RESOLUTION (0.125f) + + +AK9750::AK9750(I2C &i2c, PinName int1) : _i2c(i2c), _int1(int1) { + +} + +void AK9750::ConfigDevice () { + /* Soft reset */ + RegWrite(0x1D, 0x01); + + /* Mode & Fc */ + RegWrite(0x1C, 0x0C); // EEPMODE(Normal), EFC(0.6Hz), EMODE(ContMode0) + + /* Disable all interrupts */ + RegWrite(0x1B, 0x00); +} + +void AK9750::GetDeviceID(uint8_t *id) { + RegRead(0x01, (char *)id, 1); +} + +void AK9750::GetData(Data *data) { + char status; + char buf[10]; + + RegRead(0x05, &status, 1); + RegRead(0x06, buf, 10); + RegRead(0x10, &status, 1); // Dummy read + + /* Format data */ + int16_t ir1_adc = (((int16_t)buf[1]) << 8) | buf[0]; + int16_t ir2_adc = (((int16_t)buf[3]) << 8) | buf[2]; + int16_t ir3_adc = (((int16_t)buf[5]) << 8) | buf[4]; + int16_t ir4_adc = (((int16_t)buf[7]) << 8) | buf[6]; + int16_t tmp_adc = (((int16_t)buf[9]) << 8) | buf[8]; + + /* Convert data */ + data->ir1 = ConvertAdcToIr(ir1_adc); + data->ir2 = ConvertAdcToIr(ir2_adc); + data->ir3 = ConvertAdcToIr(ir3_adc); + data->ir4 = ConvertAdcToIr(ir4_adc); + data->tmp = ConvertAdcToTemperature(tmp_adc); +} + +int32_t AK9750::GetTriggeredAreaNum(Data *data) { + int32_t index = 1; + float max = data->ir1; + + if(data->ir2 > max) { + index = 2; + max = data->ir2; + } + if(data->ir3 > max) { + index = 3; + max = data->ir3; + } + if(data->ir4 > max) { + index = 4; + max = data->ir4; + } + return index; +} + +float AK9750::ConvertAdcToIr(int16_t adc) { + const AdcToIr *a2i_up, *a2i_down; + + /* Look up */ + for(int i=0; i<(A2I_TABLE_COUNT-1); i++) { + a2i_up = &(a2i_table[i]); + a2i_down = &(a2i_table[i+1]); + + if((a2i_up->adc >= adc) && (a2i_down->adc <= adc)) { + /* Found & calculate */ + return (a2i_up->current - a2i_down->current) / (a2i_up->adc - a2i_down->adc) * adc; + } + } + return 0; // Shall not go here +} + +float AK9750::ConvertAdcToTemperature(int16_t adc) { + /* Shift-right with 6 bits */ + bool is_negative = (adc < 0)? true : false; + adc >>= 6; + if(is_negative) { + adc |= 0xFC00; + } + + /* Calculate */ + return (float)adc * A2T_10BIT_RESOLUTION + A2T_TEMPERATURE_OFFSET; +} + +void AK9750::RegWrite(char reg, char val) { + char data[2]; + data[0] = reg; + data[1] = val; + _i2c.write(AK9750_SLAVE_ADDR, data, 2, 0); +} + +void AK9750::RegRead(char reg, char *val, int len) { + _i2c.write(AK9750_SLAVE_ADDR, ®, 1, 0); + _i2c.read (AK9750_SLAVE_ADDR, val, len); +} + +void AK9750::RegReadModifyWrite(char reg, char clr_mask, char set_mask) { + char val; + RegRead (reg, &val, 1); // Read + val = (val & ~clr_mask) | set_mask; // Modify + RegWrite(reg, val); // Write +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AK9750.h Thu Jan 26 03:08:15 2017 +0000 @@ -0,0 +1,41 @@ +#ifndef AK9750_H +#define AK9750_H + +#include "mbed.h" + + +#define AK9750_SLAVE_ADDR 0xC8 // 1100_1000b + + +class AK9750 { +public: + struct Data { + float ir1; // pA + float ir2; + float ir3; + float ir4; + float tmp; // 'C + }; + + static const uint8_t DEVICE_ID = 0x13; + + AK9750(I2C &i2c, PinName int1 = NC); + + void ConfigDevice(); + void GetDeviceID(uint8_t *id); + void GetData(Data *data); + int32_t GetTriggeredAreaNum(Data *data); + +private: + I2C &_i2c; + InterruptIn _int1; + + float ConvertAdcToIr(int16_t adc); + float ConvertAdcToTemperature(int16_t adc); + + void RegWrite(char reg, char val); + void RegRead (char reg, char *val, int len); + void RegReadModifyWrite(char reg, char clr_mask, char set_mask); +}; + +#endif \ No newline at end of file