Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of AkmSensor by
akmirsensor.cpp
- Committer:
- masahikofukasawa
- Date:
- 2016-05-05
- Revision:
- 1:b46b8653331f
- Parent:
- 0:7a00359e701e
- Child:
- 3:a817a3b3e9ae
File content as of revision 1:b46b8653331f:
#include "akmirsensor.h"
#include "debug.h"
#define CONV16I(high,low) ((int16_t)(((high) << 8) | (low)))
/**
* Constructor.
*
*/
AkmIrSensor::AkmIrSensor(){
ak9750 = NULL;
event = false;
interrupt = NULL;
}
/**
* Destructor.
*
*/
AkmIrSensor::~AkmIrSensor(){
if (ak9750) delete ak9750;
if (interrupt) delete interrupt;
}
AkmSensor::Status AkmIrSensor::init(const uint8_t id, const uint8_t subid){
primaryId = id;
subId = subid;
interrupt = new InterruptIn(DRDY);
I2C* i2c = new I2C(I2C_SDA,I2C_SCL);
i2c->frequency(I2C_SPEED_100KHZ);
if(subId == SUB_ID_AK9750){
ak9750 = new AK9750();
}
else{
return AkmSensor::ERROR;
}
bool foundSensor = false;
AK9750::SlaveAddress slaveAddr[]
= { AK9750::SLAVE_ADDR_1,
AK9750::SLAVE_ADDR_2,
AK9750::SLAVE_ADDR_3};
for(int i=0; i<sizeof(slaveAddr); i++)
{
ak9750->init(i2c, slaveAddr[i]);
// Checks connectivity
if(ak9750->checkConnection() == AkmIrSensor::SUCCESS) {
// found
foundSensor = true;
break;
}
}
if(foundSensor != true) return AkmSensor::ERROR;
// reset
if (ak9750->reset() != AK9750::SUCCESS) {
MSG("#Failed to reset AK9750.\n");
}
// Set to EEPROM mode to EEPROM access
if(ak9750->setOperationMode(AK9750::MODE_EEPROM_ACCESS, AK9750::DF_0P3HZ) != AK9750::SUCCESS) {
MSG("#Error setOperationMode to EEPROM mode. AK9750.\n");
return AkmSensor::ERROR;
}
// Gets threshold from EEPROM
AK9750::Threshold th;
if (ak9750->getThresholdFromEEPROM(&th) != AK9750::SUCCESS) {
MSG("#Failed to get threshold from EEPROM AK9750.\n");
}
// Gets hysteresis from EEPROM
AK9750::Hysteresis hys;
if (ak9750->getHysteresisFromEEPROM(&hys) != AK9750::SUCCESS) {
MSG("#Failed to get hysteresis from EEPROM AK9750.\n");
}
// Gets interrupt status from EEPROM
AK9750::InterruptStatus intStatus;
if ((ak9750->getInterruptStatusFromEEPROM(&intStatus)) != AK9750::SUCCESS) {
MSG("#Failed to get interrupts of AK9750 from EEPROM.\n");
}
// Gets operation mode from EEPROM
if ((ak9750->getOperationModeFromEEPROM(&mode,&filter)) != AK9750::SUCCESS) {
MSG("#Failed to get operation mode of AK9750 from EEPROM.\n");
}
MSG("#Operation Mode:(0x%02X,0x%02X)\n",mode, filter);
// Back to Stand-by Mode for register access
if(ak9750->setOperationMode(AK9750::MODE_STANDBY, filter) != AK9750::SUCCESS) {
MSG("#Error setOperationMode to stand-by mode of AK9750.\n");
return AkmSensor::ERROR;
}
// Sets threshold from the red EEPROM values
if (ak9750->setThreshold(&th) != AK9750::SUCCESS) {
MSG("#Failed to set threshold to AK9750.\n");
}
MSG("#Threshold:(0x%02X,0x%02X,0x%02X,0x%02X)\n",th.eth13h,th.eth13l,th.eth24h,th.eth24l);
// Sets hysteresis from the red EEPROM values
if (ak9750->setHysteresis(&hys) != AK9750::SUCCESS) {
MSG("#Failed to set hysteresis to AK9750.\n");
}
MSG("#Hysteresis:(0x%02X,0x%02X)\n",hys.ehys13,hys.ehys24);
// Sets interruput status from the red EEPROM values
AK9750::Status status;
if ((status=ak9750->setInterruptStatus(&intStatus)) != AK9750::SUCCESS) {
MSG("#Failed to set interrupts of AK9750. Status = 0x%02X\n", status);
}
MSG("#Interrupt:(0x%02X,0x%02X,0x%02X,0x%02X,0x%02X)\n",intStatus.drdy,intStatus.ir13h,intStatus.ir13l,intStatus.ir24h,intStatus.ir24l);
MSG("#Init success AK9750.\n");
return AkmSensor::SUCCESS;
}
void AkmIrSensor::detectINT(){
event = true;
}
bool AkmIrSensor::isEvent(){
return event;
}
void AkmIrSensor::checkINT(){
}
AkmSensor::Status AkmIrSensor::startSensor(){
if(ak9750->setOperationMode(mode,filter) != AK9750::SUCCESS) {
MSG("#Error setOperationMode. AK9750.\n");
return AkmSensor::ERROR;
}
interrupt->fall(this, &AkmIrSensor::detectINT);
MSG("#Start Sensor success AK9750.\n");
return AkmSensor::SUCCESS;
}
AkmSensor::Status AkmIrSensor::startSensor(const float sec){
interrupt->fall(this, &AkmIrSensor::detectINT);
return AkmSensor::ERROR;
}
AkmSensor::Status AkmIrSensor::stopSensor(){
event = false;
interrupt->fall(0);
if(ak9750->setOperationMode(AK9750::MODE_STANDBY, filter) != AK9750::SUCCESS) {
MSG("#Error setOperationMode. AK9750.\n");
return AkmSensor::ERROR;
}
// read one data to clear INT pin
Message msg;
AkmIrSensor::readSensorData(&msg);
return AkmSensor::SUCCESS;
}
AkmSensor::Status AkmIrSensor::readSensorData(Message* msg){
event = false;
// check interrupt status to release INT pin status
AK9750::InterruptStatus interrupt;
AK9750::Status status = ak9750->getInterruptStatus(&interrupt);
if( status != AK9750::SUCCESS){
MSG("#Error getInterruptStatus. AK9750.\n");
return AkmSensor::ERROR;
}
AK9750::SensorData data;
status = ak9750->getSensorData(&data);
if( status != AK9750::SUCCESS){
MSG("#Error getSensorData. AK9750.\n");
return AkmSensor::ERROR;
}
msg->setCommand(Message::CMD_START_MEASUREMENT);
msg->setArgument( 0, interrupt.drdy);
msg->setArgument( 1, interrupt.ir13h);
msg->setArgument( 2, interrupt.ir13l);
msg->setArgument( 3, interrupt.ir24h);
msg->setArgument( 4, interrupt.ir24l);
msg->setArgument( 5,(char)((int32_t)(data.ir1) >> 8));
msg->setArgument( 6, (char)((int32_t)(data.ir1) & 0x00FF) );
msg->setArgument( 7,(char)((int32_t)(data.ir2) >> 8));
msg->setArgument( 8, (char)((int32_t)(data.ir2) & 0x00FF) );
msg->setArgument( 9,(char)((int32_t)(data.ir3) >> 8));
msg->setArgument( 10, (char)((int32_t)(data.ir3) & 0x00FF) );
msg->setArgument( 11,(char)((int32_t)(data.ir4) >> 8));
msg->setArgument( 12, (char)((int32_t)(data.ir4) & 0x00FF) );
msg->setArgument( 13,(char)((int32_t)(data.temperature) >> 8));
msg->setArgument( 14, (char)((int32_t)(data.temperature) & 0x00FF) );
return AkmSensor::SUCCESS;
}
AkmSensor::Status AkmIrSensor::requestCommand(Message* in, Message* out){
AkmSensor::Status status = AkmSensor::SUCCESS;
Message::Command cmd = in->getCommand();
AK9750::Threshold th;
AK9750::Hysteresis hys;
AK9750::InterruptStatus interrupt;
out->setCommand(cmd);
switch(cmd){
case Message::CMD_IR_GET_THRESHOLD:
{
if (ak9750->getThreshold(&th) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set threshold to AK9750.\n");
}
out->setArgument(0,(char)((int32_t)(th.eth13h) >> 8));
out->setArgument(1,(char)((int32_t)(th.eth13h) & 0x00FF));
out->setArgument(2,(char)((int32_t)(th.eth13l) >> 8));
out->setArgument(3,(char)((int32_t)(th.eth13l) & 0x00FF));
out->setArgument(4,(char)((int32_t)(th.eth24h) >> 8));
out->setArgument(5,(char)((int32_t)(th.eth24h) & 0x00FF));
out->setArgument(6,(char)((int32_t)(th.eth24l) >> 8));
out->setArgument(7,(char)((int32_t)(th.eth24l) & 0x00FF));
break;
}
case Message::CMD_IR_SET_THRESHOLD:
{
th.eth13h = CONV16I(in->getArgument(0), in->getArgument(1));
th.eth13l = CONV16I(in->getArgument(2), in->getArgument(3));
th.eth24h = CONV16I(in->getArgument(4), in->getArgument(5));
th.eth24l = CONV16I(in->getArgument(6), in->getArgument(7));
if (ak9750->setThreshold(&th) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set threshold to AK9750.\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_HYSTERESIS:
{
if (ak9750->getHysteresis(&hys) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set hysteresis to AK9750.\n");
}
out->setArgument(0,hys.ehys13);
out->setArgument(1,hys.ehys24);
break;
}
case Message::CMD_IR_SET_HYSTERESIS:
{
hys.ehys13 = in->getArgument(0);
hys.ehys24 = in->getArgument(1);
if (ak9750->setHysteresis(&hys) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set hysteresis to AK9750.\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_INTERRUPT:
{
if (ak9750->getInterruptStatus(&interrupt) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set hysteresis to AK9750.\n");
}
out->setArgument(0, interrupt.drdy);
out->setArgument(1, interrupt.ir13h);
out->setArgument(2, interrupt.ir13l);
out->setArgument(3, interrupt.ir24h);
out->setArgument(4, interrupt.ir24l);
break;
}
case Message::CMD_IR_SET_INTERRUPT:
{
interrupt.drdy = in->getArgument(0);
interrupt.ir13h = in->getArgument(1);
interrupt.ir13l = in->getArgument(2);
interrupt.ir24h = in->getArgument(3);
interrupt.ir24l = in->getArgument(4);
if (ak9750->setInterruptStatus(&interrupt) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set hysteresis to AK9750.\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_OPERATION_MODE:
{
AK9750::OperationMode mode;
AK9750::DigitalFilter filter;
if(ak9750->getOperationMode(&mode, &filter) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Error setOperationMode. AK9750.\n");
}
out->setArgument(0,(char)mode);
out->setArgument(1,(char)filter);
break;
}
case Message::CMD_IR_SET_OPERATION_MODE:
{
char mode = in->getArgument(0);
char filter = in->getArgument(1);
if(ak9750->setOperationMode((AK9750::OperationMode)mode, (AK9750::DigitalFilter)filter) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Error setOperationMode. AK9750.\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_THRESHOLD_EEPROM:
{
if (ak9750->getThresholdFromEEPROM(&th) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set threshold to AK9750(EEPROM).\n");
}
out->setArgument(0,(char)((int32_t)(th.eth13h) >> 8));
out->setArgument(1,(char)((int32_t)(th.eth13h) & 0x00FF));
out->setArgument(2,(char)((int32_t)(th.eth13l) >> 8));
out->setArgument(3,(char)((int32_t)(th.eth13l) & 0x00FF));
out->setArgument(4,(char)((int32_t)(th.eth24h) >> 8));
out->setArgument(5,(char)((int32_t)(th.eth24h) & 0x00FF));
out->setArgument(6,(char)((int32_t)(th.eth24l) >> 8));
out->setArgument(7,(char)((int32_t)(th.eth24l) & 0x00FF));
break;
}
case Message::CMD_IR_SET_THRESHOLD_EEPROM:
{
th.eth13h = CONV16I(in->getArgument(0), in->getArgument(1));
th.eth13l = CONV16I(in->getArgument(2), in->getArgument(3));
th.eth24h = CONV16I(in->getArgument(4), in->getArgument(5));
th.eth24l = CONV16I(in->getArgument(6), in->getArgument(7));
if (ak9750->setThresholdToEEPROM(&th) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set threshold to AK9750(EEPROM).\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_HYSTERESIS_EEPROM:
{
if (ak9750->getHysteresisFromEEPROM(&hys) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set hysteresis to AK9750(EEPROM).\n");
}
out->setArgument(0,hys.ehys13);
out->setArgument(1,hys.ehys24);
break;
}
case Message::CMD_IR_SET_HYSTERESIS_EEPROM:
{
hys.ehys13 = in->getArgument(0);
hys.ehys24 = in->getArgument(1);
if (ak9750->setHysteresisToEEPROM(&hys) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set hysteresis to AK9750(EEPROM).\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_INTERRUPT_EEPROM:
{
if (ak9750->getInterruptStatusFromEEPROM(&interrupt) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set interrupt to AK9750(EEPROM).\n");
}
out->setArgument(0, interrupt.drdy);
out->setArgument(1, interrupt.ir13h);
out->setArgument(2, interrupt.ir13l);
out->setArgument(3, interrupt.ir24h);
out->setArgument(4, interrupt.ir24l);
break;
}
case Message::CMD_IR_SET_INTERRUPT_EEPROM:
{
interrupt.drdy = in->getArgument(0);
interrupt.ir13h = in->getArgument(1);
interrupt.ir13l = in->getArgument(2);
interrupt.ir24h = in->getArgument(3);
interrupt.ir24l = in->getArgument(4);
if (ak9750->setInterruptStatusToEEPROM(&interrupt) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Failed to set interrupt to AK9750(EEPROM).\n");
}
out->setArgument(0,(char)status);
break;
}
case Message::CMD_IR_GET_OPERATION_MODE_EEPROM:
{
AK9750::OperationMode mode;
AK9750::DigitalFilter filter;
if(ak9750->getOperationModeFromEEPROM(&mode, &filter) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Error getOperationMode. AK9750(EEPROM).\n");
}
out->setArgument(0,(char)mode);
out->setArgument(1,(char)filter);
break;
}
case Message::CMD_IR_SET_OPERATION_MODE_EEPROM:
{
char mode = in->getArgument(0);
char filter = in->getArgument(1);
if(ak9750->setOperationModeToEEPROM((AK9750::OperationMode)mode, (AK9750::DigitalFilter)filter) != AK9750::SUCCESS) {
status = AkmSensor::ERROR;
MSG("#Error setOperationMode. AK9750(EEPROM).\n");
}
out->setArgument(0,(char)status);
break;
}
default:
{
MSG("#Error no command.\n");
status = AkmSensor::ERROR;
break;
}
}
return status;
}

