Basic functions is OK. Lack interrupts function.
AK9750.cpp
- Committer:
- bcc6
- Date:
- 2017-03-23
- Revision:
- 4:413b8ef9aed5
- Parent:
- 3:14f634433c89
File content as of revision 4:413b8ef9aed5:
/* Copyright (c) 2016 MtM Technology Corporation, MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #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) RegWrite(0x1C, 0x0D); // EEPMODE(Normal), EFC(0.6Hz), EMODE(ContMode1) /* 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; } void AK9750::SetIntEvent(uint8_t int_enable, void(*fptr)(void)) { RegWrite(0x1B, int_enable); _int1.mode(PullNone); // external pull-up _int1.fall(fptr); // falling edge trigger } uint8_t AK9750::GetIntStatus() { char status; RegRead(0x04, &status, 1); return status; } 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 }