Skip to content

Commit

Permalink
add support for mag3110
Browse files Browse the repository at this point in the history
  • Loading branch information
ajita02 committed Feb 5, 2019
1 parent 8707488 commit 0f91364
Show file tree
Hide file tree
Showing 5 changed files with 585 additions and 2 deletions.
24 changes: 24 additions & 0 deletions components/i2c_devices/sensor/mag3110/component.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

# componet standalone mode
ifndef CONFIG_IOT_SOLUTION_EMBED

COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_SRCDIRS := .

else

ifdef CONFIG_IOT_MPU6050_ENABLE
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_SRCDIRS := .
else
# Disable component
COMPONENT_ADD_INCLUDEDIRS :=
COMPONENT_ADD_LDFLAGS :=
COMPONENT_SRCDIRS :=
endif

endif
180 changes: 180 additions & 0 deletions components/i2c_devices/sensor/mag3110/include/iot_mag3110.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _IOT_MAG3110_H_
#define _IOT_MAG3110_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "driver/i2c.h"
#include "iot_i2c_bus.h"



#define MAG3110_I2C_ADDRESS 0x0E /*!< slave address for mag3110 sensor */

/* MAG3110 register */
#define MAG3110_DR_STATUS 0x00 /*Default value is 0x00 */
#define MAG3110_OUT_X_MSB 0x01
#define MAG3110_OUT_X_LSB 0x02
#define MAG3110_OUT_Y_MSB 0x03
#define MAG3110_OUT_Y_LSB 0x04
#define MAG3110_OUT_Z_MSB 0x05
#define MAG3110_OUT_Z_LSB 0x06
#define MAG3110_WHO_AM_I 0x07
#define MAG3110_SYSMOD 0x08
#define MAG3110_OFF_X_MSB 0x09
#define MAG3110_OFF_X_LSB 0x0A
#define MAG3110_OFF_Y_MSB 0x0B
#define MAG3110_OFF_Y_LSB 0x0C
#define MAG3110_OFF_Z_MSB 0x0D
#define MAG3110_OFF_Z_LSB 0x0E
#define MAG3110_DIE_TEMP 0x0F
#define MAG3110_CTRL_REG1 0x10
#define MAG3110_CTRL_REG2 0x11

typedef struct {
int16_t magno_x;
int16_t magno_y;
int16_t magno_z;
} mag3110_raw_values_t;

typedef enum {
stand_by_mode = 0x00, /*!< Accelerometer full scale range is +/- 2g */
active_raw_mode = 0x01, /*!< Accelerometer full scale range is +/- 4g */
} mag3110_mode_sel_t;


typedef void* mag3110_handle_t;

/**
* @brief Create and init sensor object and return a sensor handle
*
* @param bus I2C bus object handle
* @param dev_addr I2C device address of sensor
*
* @return
* - NULL Fail
* - Others Success
*/
mag3110_handle_t iot_mag3110_create(i2c_bus_handle_t bus, uint16_t dev_addr);

/**
* @brief Read value from register of mag3110
*
* @param sensor object handle of mag3110
* @param reg_addr register address
* @param data register value
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_read_byte(mag3110_handle_t sensor, uint8_t reg, uint8_t *data);

/**
* @brief Read value from multiple register of mag3110
*
* @param sensor object handle of mag3110
* @param reg_addr start address of register
* @param data_buf Pointer of register values buffer
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_read(mag3110_handle_t sensor, uint8_t reg_start_addr, uint8_t reg_num, uint8_t *data_buf);

/**
* @brief Write value to one register of mag3110
*
* @param sensor object handle of mag3110
* @param reg_addr register address
* @param data register value
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_write_byte(mag3110_handle_t sensor, uint8_t reg_addr, uint8_t data);

/**
* @brief Write value to multiple register of mag3110
*
* @param sensor object handle of mag3110
* @param reg_addr start address of register
* @param data_buf Pointer of register values buffer
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_write(mag3110_handle_t sensor, uint8_t reg_start_addr, uint8_t reg_num, uint8_t *data_buf);

/**
* @brief Wake up mag3110
*
* @param sensor object handle of mag3110
* @ 0 for standby mode, 1 for active mode
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_mode_set(mag3110_handle_t sensor,mag3110_mode_sel_t mode_sel);

/**
* @brief Delete and release a sensor object
*
* @param sensor object handle of mag3110
* @param del_bus Whether to delete the I2C bus
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_delete(mag3110_handle_t sensor, bool del_bus);

/**
* @brief Get device identification of mag3110
*
* @param sensor object handle of mag3110
* @param deviceid a pointer of device ID
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_get_deviceid(mag3110_handle_t sensor, uint8_t* deviceid);


/**
* @brief Read raw magnetometer measurements
*
* @param sensor object handle of mag3110
* @param raw magnetometer measurements
*
* @return
* - ESP_OK Success
* - ESP_FAIL Fail
*/
esp_err_t iot_mag3110_get_magneticfield(mag3110_handle_t sensor, mag3110_raw_values_t* magneticfield);


#ifdef __cplusplus
}
#endif

#endif

167 changes: 167 additions & 0 deletions components/i2c_devices/sensor/mag3110/mag3110.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include "esp_system.h"
#include "driver/i2c.h"
#include "iot_i2c_bus.h"
#include "iot_mag3110.h"


#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */


typedef struct {
i2c_bus_handle_t bus;
uint16_t dev_addr;
} mag3110_dev_t;

mag3110_handle_t iot_mag3110_create(i2c_bus_handle_t bus, uint16_t dev_addr)
{

mag3110_dev_t* sensor = (mag3110_dev_t*) calloc(1, sizeof(mag3110_dev_t));
sensor->bus = bus;
sensor->dev_addr = dev_addr;

return (mag3110_handle_t) sensor;

}


esp_err_t iot_mag3110_get_deviceid(mag3110_handle_t sensor, uint8_t* deviceid)
{
esp_err_t ret;
uint8_t tmp;
ret = iot_mag3110_read_byte(sensor, MAG3110_WHO_AM_I, &tmp);
*deviceid = tmp;
return ret;
}

esp_err_t iot_mag3110_mode_set(mag3110_handle_t sensor, mag3110_mode_sel_t mode_sel)
{
esp_err_t ret;
uint8_t tmp=0;
ret = iot_mag3110_read_byte(sensor, MAG3110_CTRL_REG1, &tmp);
if (ret == ESP_FAIL) {
return ret;
}

tmp &= (~BIT0);
tmp |= mode_sel;
ret = iot_mag3110_write_byte(sensor, MAG3110_CTRL_REG1, tmp);
return ret;


}


esp_err_t iot_mag3110_read_byte(mag3110_handle_t sensor, uint8_t reg, uint8_t *data)
{
mag3110_dev_t* sens = (mag3110_dev_t*) sensor;
esp_err_t ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (sens->dev_addr << 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = iot_i2c_bus_cmd_begin(sens->bus, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_FAIL) {
return ret;
}

cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (sens->dev_addr << 1) | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, data, NACK_VAL);
i2c_master_stop(cmd);
ret = iot_i2c_bus_cmd_begin(sens->bus, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return ret;
}

esp_err_t iot_mag3110_read(mag3110_handle_t sensor, uint8_t reg_start_addr, uint8_t reg_num, uint8_t *data_buf)
{
uint32_t i = 0;
uint8_t data_t = 0;
if (data_buf != NULL) {
for(i=0; i<reg_num; i++) {
iot_mag3110_read_byte(sensor, reg_start_addr+i, &data_t);
data_buf[i] = data_t;
}
return ESP_OK;
}
return ESP_FAIL;
}

esp_err_t iot_mag3110_write_byte(mag3110_handle_t sensor, uint8_t reg_addr, uint8_t data)
{
mag3110_dev_t* sens = (mag3110_dev_t*) sensor;
esp_err_t ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (sens->dev_addr << 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg_addr, ACK_CHECK_EN);
i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
ret = iot_i2c_bus_cmd_begin(sens->bus, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_FAIL) {
return ret;
}
return ESP_OK;
}

esp_err_t iot_mag3110_write(mag3110_handle_t sensor, uint8_t reg_start_addr, uint8_t reg_num, uint8_t *data_buf)
{
uint32_t i = 0;
if (data_buf != NULL) {
for(i=0; i<reg_num; i++) {
iot_mag3110_write_byte(sensor, reg_start_addr+i, data_buf[i]);
}
return ESP_OK;
}
return ESP_FAIL;
}

esp_err_t iot_mag3110_get_magneticfield(mag3110_handle_t sensor, mag3110_raw_values_t* magneticfield)
{

uint8_t data_rd[6] = {0};
mag3110_dev_t* sens = (mag3110_dev_t*) sensor;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( MAG3110_I2C_ADDRESS << 1 ) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, MAG3110_OUT_X_MSB, ACK_CHECK_EN);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( MAG3110_I2C_ADDRESS << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_read(cmd, data_rd, 5, ACK_VAL);
i2c_master_read(cmd, data_rd + 5, 1, NACK_VAL);
i2c_master_stop(cmd);
int ret = iot_i2c_bus_cmd_begin(sens->bus, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

magneticfield->magno_x = (int16_t)((data_rd[0] << 8) + (data_rd[1]));
magneticfield->magno_y = (int16_t)((data_rd[2] << 8) + (data_rd[3]));
magneticfield->magno_z = (int16_t)((data_rd[4] << 8) + (data_rd[5]));
return ret;

}

Loading

0 comments on commit 0f91364

Please sign in to comment.