STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
dev_ms5611.c
Go to the documentation of this file.
1#include "dev_ms5611.h"
2
3#include <stddef.h>
4
5#define CMD_ADC_READ 0x00U
6#define CMD_PROM_READ 0xA0U
7
8uint8_t ms5611_crc4(const ms5611_prom_t* prom) {
9 uint16_t remainder = 0;
10 for (uint8_t byte = 0; byte < 16; ++byte) {
11 uint16_t word = prom->word[byte / 2];
12 if (byte / 2 == 7) {
13 word &= 0xFF00U; /* CRC byte itself is not covered */
14 }
15 remainder ^=
16 (byte & 1U) ? (uint16_t)(word & 0xFFU) : (uint16_t)(word >> 8);
17 for (uint8_t bit = 0; bit < 8; ++bit) {
18 /* Both arms uint16_t: GCC's -Wsign-compare rejects an int and an
19 * unsigned int arm. AN520 keeps bits above 15, but only bits
20 * 15..12 are read and higher bits never shift back down. */
21 uint16_t shifted = (uint16_t)(remainder << 1);
22 remainder =
23 (remainder & 0x8000U) ? (uint16_t)(shifted ^ 0x3000U) : shifted;
24 }
25 }
26 return (uint8_t)((remainder >> 12) & 0x0FU);
27}
28
30 if (!bus || !prom) {
31 return DEV_ERR_PARAM;
32 }
33 uint16_t all_and = 0xFFFF, all_or = 0;
34 for (uint8_t i = 0; i < 8; ++i) {
35 const uint8_t tx[3] = {(uint8_t)(CMD_PROM_READ + 2U * i), 0, 0};
36 uint8_t rx[3];
37 if (bus->xfer(bus->ctx, tx, rx, sizeof(tx)) != DEV_OK) {
38 return DEV_ERR_BUS;
39 }
40 prom->word[i] = (uint16_t)(rx[1] << 8 | rx[2]);
41 all_and &= prom->word[i];
42 all_or |= prom->word[i];
43 }
44 if (all_and == 0xFFFF || all_or == 0) {
45 return DEV_ERR_DATA; /* dead bus: a CRC could match by chance */
46 }
47 return ms5611_crc4(prom) == (prom->word[7] & 0x0FU) ? DEV_OK : DEV_ERR_DATA;
48}
49
51 if (!bus ||
52 (which != MS5611_D1_PRESSURE && which != MS5611_D2_TEMPERATURE)) {
53 return DEV_ERR_PARAM;
54 }
55 const uint8_t cmd = (uint8_t)which;
56 return bus->xfer(bus->ctx, &cmd, NULL, 1) == DEV_OK ? DEV_OK : DEV_ERR_BUS;
57}
58
59int ms5611_read_adc(const dev_bus_t* bus, uint32_t* raw) {
60 if (!bus || !raw) {
61 return DEV_ERR_PARAM;
62 }
63 const uint8_t tx[4] = {CMD_ADC_READ, 0, 0, 0};
64 uint8_t rx[4];
65 if (bus->xfer(bus->ctx, tx, rx, sizeof(tx)) != DEV_OK) {
66 return DEV_ERR_BUS;
67 }
68 *raw = (uint32_t)rx[1] << 16 | (uint32_t)rx[2] << 8 | rx[3];
69 return *raw ? DEV_OK : DEV_ERR_DATA; /* 0: read before conversion ended */
70}
71
72void ms5611_compensate(const ms5611_prom_t* prom, uint32_t d1, uint32_t d2,
73 int32_t* temp_c100, int32_t* pressure_pa) {
74 const int64_t c1 = prom->word[1], c2 = prom->word[2], c3 = prom->word[3];
75 const int64_t c4 = prom->word[4], c5 = prom->word[5], c6 = prom->word[6];
76 /* First order, p.8 */
77 const int64_t dt = (int64_t)d2 - c5 * 256;
78 int64_t temp = 2000 + dt * c6 / 8388608; /* 2^23 */
79 int64_t off = c2 * 65536 + c4 * dt / 128; /* 2^16, 2^7 */
80 int64_t sens = c1 * 32768 + c3 * dt / 256; /* 2^15, 2^8 */
81 /* Second order below 20 degC, p.9 */
82 if (temp < 2000) {
83 const int64_t t2 = dt * dt / 2147483648LL; /* 2^31 */
84 const int64_t low = (temp - 2000) * (temp - 2000);
85 int64_t off2 = 5 * low / 2;
86 int64_t sens2 = 5 * low / 4;
87 if (temp < -1500) {
88 const int64_t very_low = (temp + 1500) * (temp + 1500);
89 off2 += 7 * very_low;
90 sens2 += 11 * very_low / 2;
91 }
92 temp -= t2;
93 off -= off2;
94 sens -= sens2;
95 }
96 *temp_c100 = (int32_t)temp;
97 *pressure_pa = (int32_t)(((int64_t)d1 * sens / 2097152 - off) /
98 32768); /* 2^21, 2^15 */
99}
uint8_t byte
Minimal Arduino.h stub for native unit tests.
Definition Arduino.h:16
@ DEV_OK
Definition dev_bus.h:17
@ DEV_ERR_DATA
Definition dev_bus.h:23
@ DEV_ERR_PARAM
Definition dev_bus.h:22
@ DEV_ERR_BUS
Definition dev_bus.h:18
int ms5611_read_adc(const dev_bus_t *bus, uint32_t *raw)
Definition dev_ms5611.c:59
uint8_t ms5611_crc4(const ms5611_prom_t *prom)
Definition dev_ms5611.c:8
#define CMD_PROM_READ
Definition dev_ms5611.c:6
int ms5611_start(const dev_bus_t *bus, ms5611_conversion_t which)
Definition dev_ms5611.c:50
int ms5611_read_prom(const dev_bus_t *bus, ms5611_prom_t *prom)
Definition dev_ms5611.c:29
void ms5611_compensate(const ms5611_prom_t *prom, uint32_t d1, uint32_t d2, int32_t *temp_c100, int32_t *pressure_pa)
Definition dev_ms5611.c:72
#define CMD_ADC_READ
Definition dev_ms5611.c:5
ms5611_conversion_t
Definition dev_ms5611.h:35
@ MS5611_D1_PRESSURE
Definition dev_ms5611.h:36
@ MS5611_D2_TEMPERATURE
Definition dev_ms5611.h:37
uint32_t d1
Definition flight_e2e.c:77
uint32_t d2
Definition flight_e2e.c:77
int32_t temp
Definition flight_e2e.c:78
#define NULL
Definition usbd_def.h:44
uint16_t word[8]
Definition dev_ms5611.h:32