Skip to content

Commit 20140b2

Browse files
authored
Merge pull request #661 from betrusted-io/add-bmp180
Add BMP180
2 parents 63b18ec + 04bf756 commit 20140b2

File tree

6 files changed

+175
-1
lines changed

6 files changed

+175
-1
lines changed

libs/cramium-hal/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@ camera-ov2640 = []
3232
camera-gc2145 = []
3333
display-sh1107 = []
3434
axp2101 = []
35+
bmp180 = []
3536
board-baosec = [
37+
"std",
3638
"camera-gc2145",
3739
"display-sh1107",
3840
"axp2101",
41+
"bmp180",
3942
"utralib/cramium-soc",
4043
"ux-api/board-baosec",
4144
] # USB form factor token
@@ -44,13 +47,16 @@ loader-baosec = [
4447
"camera-gc2145",
4548
"display-sh1107",
4649
"axp2101",
50+
"bmp180",
4751
"ux-api/loader-baosec",
4852
]
4953
kernel-baosec = ["utralib/cramium-soc"]
5054
kernel-baosor = ["utralib/cramium-soc"]
5155
kernel-dabao = ["utralib/cramium-soc"]
5256
test-baosec = ["ux-api/loader-baosec", "camera-gc2145"]
53-
hosted-baosec = [] # emulated hardware on x86 platform
57+
hosted-baosec = [
58+
"std"
59+
] # emulated hardware on x86 platform
5460
board-baosor = [
5561
"camera-gc2145",
5662
"axp2101",

libs/cramium-hal/src/bmp180.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
use cramium_api::{I2cApi, I2cResult};
2+
3+
pub const BMP180_ADDR: u8 = 0x77;
4+
const REG_CALIB_START: u8 = 0xAA;
5+
const REG_CTRL: u8 = 0xF4;
6+
const REG_DATA_START: u8 = 0xF6;
7+
const CMD_READ_TEMP: u8 = 0x2E;
8+
const REG_CHIP_ID: u8 = 0xD0;
9+
10+
#[derive(Debug, Clone, Copy)]
11+
12+
struct Bmp180Calibration {
13+
ac1: i16,
14+
ac2: i16,
15+
ac3: i16,
16+
ac4: u16,
17+
ac5: u16,
18+
ac6: u16,
19+
b1: i16,
20+
b2: i16,
21+
mb: i16,
22+
mc: i16,
23+
md: i16,
24+
}
25+
26+
pub struct Bmp180 {
27+
calibration: Bmp180Calibration,
28+
}
29+
30+
impl Bmp180 {
31+
pub fn new(i2c: &mut dyn I2cApi) -> Result<Self, I2cResult> {
32+
// dummy read to wake the chip
33+
let mut chip_id_buf = [0u8; 1];
34+
match i2c.i2c_read(BMP180_ADDR, REG_CHIP_ID, &mut chip_id_buf, true) {
35+
Ok(I2cResult::Ack(_)) => (),
36+
Ok(I2cResult::Nack) => (),
37+
Ok(other) => return Err(other),
38+
Err(_) => return Err(I2cResult::InternalError),
39+
}
40+
41+
let mut cal_buf = [0u8; 22];
42+
match i2c.i2c_read(BMP180_ADDR, REG_CALIB_START, &mut cal_buf, true) {
43+
Ok(i2c_result) => match i2c_result {
44+
I2cResult::Ack(_) => (),
45+
other => return Err(other),
46+
},
47+
Err(_) => return Err(I2cResult::InternalError),
48+
}
49+
50+
// note: calibration data is Big Endian, hence the from_be_bytes
51+
let calibration = Bmp180Calibration {
52+
ac1: i16::from_be_bytes([cal_buf[0], cal_buf[1]]),
53+
ac2: i16::from_be_bytes([cal_buf[2], cal_buf[3]]),
54+
ac3: i16::from_be_bytes([cal_buf[4], cal_buf[5]]),
55+
ac4: u16::from_be_bytes([cal_buf[6], cal_buf[7]]),
56+
ac5: u16::from_be_bytes([cal_buf[8], cal_buf[9]]),
57+
ac6: u16::from_be_bytes([cal_buf[10], cal_buf[11]]),
58+
b1: i16::from_be_bytes([cal_buf[12], cal_buf[13]]),
59+
b2: i16::from_be_bytes([cal_buf[14], cal_buf[15]]),
60+
mb: i16::from_be_bytes([cal_buf[16], cal_buf[17]]),
61+
mc: i16::from_be_bytes([cal_buf[18], cal_buf[19]]),
62+
md: i16::from_be_bytes([cal_buf[20], cal_buf[21]]),
63+
};
64+
65+
if calibration.ac1 == 0
66+
|| calibration.ac2 == 0
67+
|| calibration.ac3 == 0
68+
|| calibration.ac4 == 0
69+
|| calibration.ac5 == 0
70+
|| calibration.ac6 == 0
71+
|| calibration.b1 == 0
72+
|| calibration.b2 == 0
73+
|| calibration.mb == 0
74+
|| calibration.mc == 0
75+
|| calibration.md == 0
76+
|| calibration.ac1 == -1
77+
{
78+
return Err(I2cResult::InternalError);
79+
}
80+
81+
Ok(Bmp180 { calibration })
82+
}
83+
84+
pub fn read_temperature(&self, i2c: &mut dyn I2cApi) -> Result<f32, I2cResult> {
85+
match i2c.i2c_write(BMP180_ADDR, REG_CTRL, &[CMD_READ_TEMP]) {
86+
Ok(I2cResult::Ack(_)) => (),
87+
Ok(other) => return Err(other),
88+
Err(_) => return Err(I2cResult::InternalError),
89+
}
90+
91+
self.delay(5);
92+
93+
let mut temp_buffer = [0u8; 2];
94+
match i2c.i2c_read(BMP180_ADDR, REG_DATA_START, &mut temp_buffer, true) {
95+
Ok(I2cResult::Ack(_)) => (),
96+
Ok(other) => return Err(other),
97+
Err(_) => return Err(I2cResult::InternalError),
98+
}
99+
100+
let ut = i16::from_be_bytes(temp_buffer) as i32;
101+
102+
let cal = &self.calibration;
103+
let x1 = (ut - cal.ac6 as i32) * cal.ac5 as i32 >> 15;
104+
let x2 = (cal.mc as i32 * 2048) / (x1 + cal.md as i32);
105+
let b5 = x1 + x2;
106+
let temp = ((b5 + 8) >> 4) as f32 / 10.0;
107+
108+
Ok(temp)
109+
}
110+
111+
pub fn delay(&self, quantum: usize) {
112+
#[cfg(feature = "std")]
113+
{
114+
let tt = xous_api_ticktimer::Ticktimer::new().unwrap();
115+
tt.sleep_ms(quantum).ok();
116+
}
117+
#[cfg(not(feature = "std"))]
118+
{
119+
use utralib::{CSR, utra};
120+
// abuse the d11ctime timer to create some time-out like thing
121+
let mut d11c = CSR::new(utra::d11ctime::HW_D11CTIME_BASE as *mut u32);
122+
d11c.wfo(utra::d11ctime::CONTROL_COUNT, 333_333); // 1.0ms per interval
123+
let mut polarity = d11c.rf(utra::d11ctime::HEARTBEAT_BEAT);
124+
for _ in 0..quantum {
125+
while polarity == d11c.rf(utra::d11ctime::HEARTBEAT_BEAT) {}
126+
polarity = d11c.rf(utra::d11ctime::HEARTBEAT_BEAT);
127+
}
128+
// we have to split this because we don't know where we caught the previous interval
129+
if quantum == 1 {
130+
while polarity == d11c.rf(utra::d11ctime::HEARTBEAT_BEAT) {}
131+
}
132+
}
133+
}
134+
}

libs/cramium-hal/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
pub mod debug;
66
#[cfg(feature = "axp2101")]
77
pub mod axp2101;
8+
#[cfg(feature = "bmp180")]
9+
pub mod bmp180;
810
pub mod board;
911
#[cfg(feature = "camera-gc2145")]
1012
pub mod gc2145;

services/bao-console/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ hosted-baosec = [
4949
"pddb/hosted-baosec",
5050
"cramium-hal/hosted-baosec",
5151
]
52+
bmp180 = [
53+
"cramium-hal/bmp180",
54+
"cram-hal-service",
55+
]
5256
usb = []
5357
battery-readout = []
5458
with-pddb = []

services/bao-console/src/cmds/test.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,39 @@ impl<'a> ShellCmdApi<'a> for Test {
1313
fn process(&mut self, args: String, _env: &mut CommonEnv) -> Result<Option<String>, xous::Error> {
1414
use core::fmt::Write;
1515
let mut ret = String::new();
16+
17+
#[allow(unused_variables)]
1618
let helpstring = "Test commands. See code for options.";
1719

20+
#[cfg(feature = "bmp180")]
21+
let helpstring = "Usage:
22+
temp - reads temperature from bmp180.";
23+
1824
let mut tokens = args.split(' ');
1925

2026
if let Some(sub_cmd) = tokens.next() {
2127
match sub_cmd {
28+
#[cfg(feature = "bmp180")]
29+
"temp" => {
30+
use cram_hal_service::I2c;
31+
use cramium_hal::bmp180::Bmp180;
32+
let mut i2c = I2c::new();
33+
34+
match Bmp180::new(&mut i2c) {
35+
Ok(sensor) => match sensor.read_temperature(&mut i2c) {
36+
Ok(temp) => {
37+
write!(ret, "BMP180 Temperature: {:.1}°C", temp).unwrap();
38+
}
39+
Err(e) => {
40+
write!(ret, "Failed to read temperature: {:?}", e).unwrap();
41+
}
42+
},
43+
Err(e) => {
44+
write!(ret, "Failed to initialize BMP180 sensor: {:?}", e).unwrap();
45+
}
46+
}
47+
}
48+
2249
_ => {
2350
write!(ret, "{}", helpstring).unwrap();
2451
}

services/cram-hal-service/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ rawserial = []
4545
pinger = []
4646
swap = []
4747
mpw = ["cramium-hal/mpw"]
48+
bmp180 = ["cramium-hal/bmp180"]
4849
board-baosec = ["cramium-hal/board-baosec"]
4950
board-baosor = ["cramium-hal/board-baosor"]
5051
board-dabao = ["cramium-hal/board-dabao"]

0 commit comments

Comments
 (0)