Basic functions is OK. Lack interrupts function.

Dependents:   Mt05_MtSense07

Files at this revision

API Documentation at this revision

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

AK09912.cpp Show annotated file Show diff for this revision Revisions of this file
AK09912.h Show annotated file Show diff for this revision Revisions of this file
AK09970.cpp Show annotated file Show diff for this revision Revisions of this file
AK09970.h Show annotated file Show diff for this revision Revisions of this file
AK9750.cpp Show annotated file Show diff for this revision Revisions of this file
AK9750.h Show annotated file Show diff for this revision Revisions of this file
--- /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, &reg, 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, &reg, 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, &reg, 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