Example Device: DEBIX Model A + I/O Board
Overview
lThe BMP180 is a high-precision barometric pressure sensor with low power consumption and low noise. It comes with an internal temperature sensor to compensate for barometric pressure measurements and uses I2C communication.
Hardware installation
lBarometric Pressure Sensor module's VCC terminal is connected to J2 Pin2 of DEBIX Model A I/O board
lBarometric Pressure Sensor module's SDA terminal is connected to J2 Pin3 of DEBIX Model A I/O board
lBarometric Pressure Sensor module's SCL terminal is connected to J2 Pin5 of DEBIX Model A I/O board
lBarometric Pressure Sensor module's GND terminal is connected to J2 Pin39 of DEBIX Model A I/O board
lBarometric Pressure Sensor module's 3.3V terminal is connected to J2 Pin1 of DEBIX Model A I/O board
Modify the device tree imx8mp-evk.dts
1. Add a BMP180 node under i2c4 node:
&i2c4 {
status = "okay";
BMP180: BMP180@77 {
compatible = "BMP180";
reg = <0x77>;
};
2. Compile and replace the device tree file
lCompile the device tree in the source directory: make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- dtbs
lCopy the compiled new device tree file arch/arm64/boot/dts/freescale/imx8mp-evk.dtb to the /boot directory of DEBIX and restart DEBIX.
3. Check whether dts contains the modified device tree node.
lRun the command ls /sys/bus/i2c/devices/
Write and Load Drivers
The driver code is as follows:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/delay.h>
static struct i2c_client* fxs_i2c_client;
typedef struct {
s16 AC1;
s16 AC2;
s16 AC3;
u16 AC4;
u16 AC5;
u16 AC6;
s16 B1;
s16 B2;
s16 MB;
s16 MC;
s16 MD;
}BMP180_CalcParam_t;
typedef struct {
s32 T;
s32 P;
}BMP180_Result;
BMP180_CalcParam_t BMP180_CalcParams;
static s32 i2c_write_reg(u8 reg_addr, u8 *data, u8 len)
{
u8 buff[256];
struct i2c_msg msgs[] = {
[0] = {
.addr = fxs_i2c_client->addr,
.flags = 0,
.len = len + 1,
.buf = buff,
},
};
buff[0] = reg_addr;
memcpy(&buff[1], data, len);
return i2c_transfer(fxs_i2c_client->adapter, msgs, 1);
}
static s32 i2c_read_reg(u8 reg,void* data, int len){
int ret;
struct i2c_msg msgs[] = {
[0]={
.addr = fxs_i2c_client->addr,
.flags = 0,
.buf = ®,
.len = sizeof(reg),
},
[1]={
.addr = fxs_i2c_client->addr,
.flags = I2C_M_RD,
.buf = data,
.len = len,
},
};
ret = i2c_transfer(fxs_i2c_client->adapter,msgs,2);
if(ret == 2) {
return ret;
}else{
printk("read:i2c_transfer err..\n");
return -1;
}
}
static s16 BMP180_Reads16Reg(u8 regh,u8 regl){
u8 datah,datal;
s16 val;
i2c_read_reg(regh,&datah,1);
i2c_read_reg(regl,&datal,1);
val = (datah & 0x00ff) << 8;
val |= datal & 0xff;
return val;
}
static u16 BMP180_Readu16Reg(u8 regh,u8 regl){