Skip to content

Commit b6f8a27

Browse files
authored
[EGD-3045] Magnetometer driver (#788)
* [EGD-3045] magnetometer driver - timer polling approach - magneto pin mux - magneto reg structs - magneto irq skeleton - bluetooth irq handler moved - dedicated i2c methods - bitfields parsed and populated explicitly * [misc] big endian ↔ long conversion in Utils + UT
1 parent e0c8ae4 commit b6f8a27

File tree

16 files changed

+723
-46
lines changed

16 files changed

+723
-46
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* `[audio][bluetooth]` Added Bluetooth A2DP playback
1212
* `[settings]` Added sql script for file indexer DB schema
1313
* `[settings][bluetooth]` Create "Add device" windows
14+
* `[hardware]` Slider driver (offline/online mode selection)
1415

1516
### Fixed
1617

module-bsp/board/linux/magnetometer/magnetometer.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33

44
#include "bsp/magnetometer/magnetometer.hpp"
55

6-
#include "bsp/BoardDefinitions.hpp"
7-
8-
using namespace drivers;
9-
106
static xQueueHandle qHandleIrq = NULL;
117

128
namespace bsp
@@ -31,5 +27,13 @@ namespace bsp
3127
{
3228
return bsp::Board::Linux;
3329
}
30+
31+
std::optional<bsp::KeyCodes> WorkerEventHandler()
32+
{
33+
return std::nullopt;
34+
}
35+
36+
void enableIRQ()
37+
{}
3438
} // namespace magnetometer
3539
} // namespace bsp

module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -257,22 +257,3 @@ void BluetoothCommon::set_irq(bool enable)
257257
LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, true);
258258
LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, true);
259259
}
260-
261-
extern "C"
262-
{
263-
void GPIO1_Combined_16_31_IRQHandler(void)
264-
{
265-
BaseType_t xHigherPriorityTaskWoken = 0;
266-
uint32_t irq_mask = GPIO_GetPinsInterruptFlags(GPIO1);
267-
268-
if (irq_mask & (1 << BSP_BLUETOOTH_UART_CTS_PIN)) {
269-
LOG_DEBUG("CTS IRQ!\n");
270-
}
271-
272-
// Clear all IRQs
273-
GPIO_PortClearInterruptFlags(GPIO1, irq_mask);
274-
275-
// Switch context if necessary
276-
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
277-
}
278-
};
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
2+
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
3+
4+
#include "ALS31300.hpp"
5+
6+
namespace drivers::als31300
7+
{
8+
9+
conf_reg::conf_reg(whole_reg_t whole_reg)
10+
{
11+
user_eeprom = whole_reg & 0b11111;
12+
int_latch_enable = (whole_reg >> 5) & 0b1;
13+
channel_X_en = (whole_reg >> 6) & 0b1;
14+
channel_Y_en = (whole_reg >> 7) & 0b1;
15+
channel_Z_en = (whole_reg >> 8) & 0b1;
16+
I2C_threshold = (whole_reg >> 9) & 0b1;
17+
slave_addr = (whole_reg >> 10) & 0b1111111;
18+
disable_slave_ADC = (whole_reg >> 17) & 0b1;
19+
I2C_CRC_en = (whole_reg >> 18) & 0b1;
20+
hall_mode = (whole_reg >> 19) & 0b11;
21+
bandwidth = (whole_reg >> 21) & 0b111;
22+
RESERVED = (whole_reg >> 24) & 0xFF;
23+
}
24+
25+
conf_reg::operator whole_reg_t() const
26+
{
27+
return (user_eeprom & 0b11111) | (int_latch_enable & 0b1) << 5 | (channel_X_en & 0b1) << 6 |
28+
(channel_Y_en & 0b1) << 7 | (channel_Z_en & 0b1) << 8 | (I2C_threshold & 0b1) << 9 |
29+
(slave_addr & 0b1111111) << 10 | (disable_slave_ADC & 0b1) << 17 | (I2C_CRC_en & 0b1) << 18 |
30+
(hall_mode & 0b11) << 19 | (bandwidth & 0b111) << 21 | (RESERVED & 0xFF) << 24;
31+
}
32+
33+
int_reg::int_reg(whole_reg_t whole_reg)
34+
{
35+
int_X_threshold = whole_reg & 0b111111;
36+
int_Y_threshold = (whole_reg >> 6) & 0b111111;
37+
int_Z_threshold = (whole_reg >> 12) & 0b111111;
38+
int_X_en = (whole_reg >> 18) & 0b1;
39+
int_Y_en = (whole_reg >> 19) & 0b1;
40+
int_Z_en = (whole_reg >> 20) & 0b1;
41+
int_eeprom_en = (whole_reg >> 21) & 0b1;
42+
int_eeprom_status = (whole_reg >> 22) & 0b1;
43+
int_mode = (whole_reg >> 23) & 0b1;
44+
int_threshold_signed = (whole_reg >> 24) & 0b1;
45+
RESERVED = (whole_reg >> 25) & 0b1111111;
46+
}
47+
48+
int_reg::operator whole_reg_t() const
49+
{
50+
return (int_X_threshold & 0b111111) | (int_Y_threshold & 0b111111) << 6 | (int_Z_threshold & 0b111111) << 12 |
51+
(int_X_en & 0b1) << 18 | (int_Y_en & 0b1) << 19 | (int_Z_en & 0b1) << 20 | (int_eeprom_en & 0b1) << 21 |
52+
(int_eeprom_status & 0b1) << 22 | (int_mode & 0b1) << 23 | (int_threshold_signed & 0b1) << 24 |
53+
(RESERVED & 0b1111111) << 25;
54+
}
55+
56+
pwr_reg::pwr_reg(whole_reg_t whole_reg)
57+
{
58+
sleep = whole_reg & 0b11;
59+
I2C_loop_mode = (whole_reg >> 2) & 0b11;
60+
count_max_LP_mode = (whole_reg >> 4) & 0b111;
61+
RESERVED = (whole_reg >> 7) & 0x1FFFFFF;
62+
}
63+
64+
pwr_reg::operator whole_reg_t() const
65+
{
66+
return (sleep & 0b11) | (I2C_loop_mode & 0b11) << 2 | (count_max_LP_mode & 0b111) << 4 |
67+
(RESERVED & 0x1FFFFFF) << 7;
68+
}
69+
70+
measurements_MSB_reg::measurements_MSB_reg(whole_reg_t whole_reg)
71+
{
72+
temperature_MSB = whole_reg & 0b111111;
73+
int_flag = (whole_reg >> 6) & 0b1;
74+
new_data_flag = (whole_reg >> 7) & 0b1;
75+
Z_MSB = (whole_reg >> 8) & 0xFF;
76+
Y_MSB = (whole_reg >> 16) & 0xFF;
77+
X_MSB = (whole_reg >> 24) & 0xFF;
78+
}
79+
80+
measurements_MSB_reg::operator whole_reg_t() const
81+
{
82+
return (temperature_MSB & 0b111111) | (int_flag & 0b1) << 6 | (new_data_flag & 0b1) << 7 | (Z_MSB & 0xFF) << 8 |
83+
(Y_MSB & 0xFF) << 16 | (X_MSB & 0xFF) << 24;
84+
}
85+
86+
measurements_LSB_reg::measurements_LSB_reg(whole_reg_t whole_reg)
87+
{
88+
temperature_LSB = whole_reg & 0b111111;
89+
hall_mode_status = (whole_reg >> 6) & 0b11;
90+
Z_LSB = (whole_reg >> 8) & 0b1111;
91+
Y_LSB = (whole_reg >> 12) & 0b1111;
92+
X_LSB = (whole_reg >> 16) & 0b1111;
93+
int_eeprom_write_pending = (whole_reg >> 20) & 0b1;
94+
RESERVED = (whole_reg >> 21) & 0x7FF;
95+
}
96+
97+
measurements_LSB_reg::operator whole_reg_t() const
98+
{
99+
return (temperature_LSB & 0b111111) | (hall_mode_status & 0b11) << 6 | (Z_LSB & 0b1111) << 8 |
100+
(Y_LSB & 0b1111) << 12 | (X_LSB & 0b1111) << 16 | (int_eeprom_write_pending & 0b1) << 20 |
101+
(RESERVED & 0x7FF) << 21;
102+
}
103+
104+
float temperature_convert(uint16_t raw_temperature)
105+
{
106+
const int32_t intermediate = raw_temperature - 1708;
107+
return intermediate * 0.0737;
108+
}
109+
110+
int16_t measurement_sign_convert(uint16_t raw_measurement, uint8_t bit_length)
111+
{
112+
// via: https://stackoverflow.com/questions/16946801/n-bit-2s-binary-to-decimal-in-c
113+
const auto sign_flag = 1 << (bit_length - 1);
114+
if (raw_measurement & sign_flag) {
115+
raw_measurement |= -(1 << bit_length);
116+
}
117+
return raw_measurement;
118+
}
119+
} // namespace drivers::als31300
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
2+
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
3+
4+
#pragma once
5+
6+
#include <cstdint>
7+
#include <cstring>
8+
#include <set>
9+
#include <chrono>
10+
11+
// ALS31300 magnetometer driver
12+
namespace drivers::als31300
13+
{
14+
15+
// Note: this device returns 32-bit register values in MSB order
16+
17+
using whole_reg_t = uint32_t; // ALS31300 always talks 4 bytes
18+
19+
constexpr auto I2C_ADDRESS = 0x64;
20+
21+
// base ALS31300 register struct.
22+
struct base_reg
23+
{
24+
virtual operator whole_reg_t() const = 0;
25+
};
26+
27+
// REGISTER DEFINITIONS
28+
29+
// there is no 0x01 register
30+
// --------
31+
constexpr auto CONF_REG = 0x02;
32+
struct conf_reg : base_reg
33+
{
34+
conf_reg(whole_reg_t whole_reg);
35+
operator whole_reg_t() const override;
36+
uint8_t user_eeprom : 5;
37+
bool int_latch_enable : 1;
38+
bool channel_X_en : 1;
39+
bool channel_Y_en : 1;
40+
bool channel_Z_en : 1;
41+
bool I2C_threshold : 1;
42+
uint8_t slave_addr : 7;
43+
bool disable_slave_ADC : 1;
44+
bool I2C_CRC_en : 1;
45+
uint8_t hall_mode : 2;
46+
uint8_t bandwidth : 3;
47+
uint8_t RESERVED : 8;
48+
};
49+
50+
constexpr auto CONF_REG_LATCH_disabled = 0b0;
51+
constexpr auto CONF_REG_LATCH_enabled = 0b1;
52+
53+
constexpr auto CONF_REG_CHANNEL_disabled = 0b0;
54+
constexpr auto CONF_REG_CHANNEL_enabled = 0b1;
55+
56+
constexpr auto CONF_REG_I2C_THRES_3v0 = 0b0;
57+
constexpr auto CONF_REG_I2C_THRES_1v8 = 0b1;
58+
59+
// --------
60+
constexpr auto INT_REG = 0x03;
61+
62+
struct int_reg : base_reg
63+
{
64+
int_reg(whole_reg_t whole_reg);
65+
operator whole_reg_t() const override;
66+
uint8_t int_X_threshold : 6;
67+
uint8_t int_Y_threshold : 6;
68+
uint8_t int_Z_threshold : 6;
69+
bool int_X_en : 1;
70+
bool int_Y_en : 1;
71+
bool int_Z_en : 1;
72+
bool int_eeprom_en : 1;
73+
bool int_eeprom_status : 1;
74+
bool int_mode : 1;
75+
bool int_threshold_signed : 1;
76+
uint8_t RESERVED : 7;
77+
};
78+
79+
constexpr auto INT_REG_INT_CHANNEL_disabled = 0b0;
80+
constexpr auto INT_REG_INT_CHANNEL_enabled = 0b1;
81+
82+
constexpr auto INT_REG_INT_MODE_threshold = 0b0;
83+
constexpr auto INT_REG_INT_MODE_delta = 0b1;
84+
85+
constexpr auto INT_REG_THRESHOLD_absolute = 0b0;
86+
constexpr auto INT_REG_THRESHOLD_signed = 0b1;
87+
88+
constexpr auto INT_REG_INT_EEPROM_disable = 0b0;
89+
constexpr auto INT_REG_INT_EEPROM_enable = 0b1;
90+
91+
// --------
92+
constexpr auto PWR_REG = 0x27;
93+
94+
struct pwr_reg : base_reg
95+
{
96+
pwr_reg(whole_reg_t whole_reg);
97+
operator whole_reg_t() const override;
98+
uint8_t sleep : 2;
99+
uint8_t I2C_loop_mode : 2;
100+
uint8_t count_max_LP_mode : 3;
101+
uint32_t RESERVED : 25;
102+
};
103+
104+
constexpr auto PWR_REG_SLEEP_MODE_active = 0b00;
105+
constexpr auto PWR_REG_SLEEP_MODE_sleep = 0b01;
106+
constexpr auto PWR_REG_SLEEP_MODE_LPDCM = 0b10; // Low-Power Duty Cycle Mode
107+
108+
constexpr auto PWR_REG_LOOP_MODE_single = 0b00;
109+
constexpr auto PWR_REG_LOOP_MODE_fast_loop = 0b01;
110+
constexpr auto PWR_REG_LOOP_MODE_full_loop = 0b10;
111+
112+
enum PWR_REG_SLEEP_MODE
113+
{
114+
active = PWR_REG_SLEEP_MODE_active,
115+
sleep = PWR_REG_SLEEP_MODE_sleep,
116+
periodic_active = PWR_REG_SLEEP_MODE_LPDCM,
117+
};
118+
119+
constexpr auto PWR_ON_DELAY_MS = 1; // spec'd as 600µs at most
120+
121+
// --------
122+
constexpr auto MEASUREMENTS_MSB_REG = 0x28;
123+
124+
struct measurements_MSB_reg : base_reg
125+
{
126+
measurements_MSB_reg(whole_reg_t whole_reg);
127+
operator whole_reg_t() const override;
128+
uint8_t temperature_MSB : 6;
129+
bool int_flag : 1;
130+
bool new_data_flag : 1;
131+
uint8_t Z_MSB : 8;
132+
uint8_t Y_MSB : 8;
133+
uint8_t X_MSB : 8;
134+
};
135+
136+
constexpr auto MEAS_REG_NEW_DATA_not_avail = 0b0;
137+
constexpr auto MEAS_REG_NEW_DATA_available = 0b1;
138+
139+
// --------
140+
constexpr auto MEASUREMENTS_LSB_REG = 0x29;
141+
142+
struct measurements_LSB_reg : base_reg
143+
{
144+
measurements_LSB_reg(whole_reg_t whole_reg);
145+
operator whole_reg_t() const override;
146+
uint8_t temperature_LSB : 6;
147+
uint8_t hall_mode_status : 2;
148+
uint8_t Z_LSB : 4;
149+
uint8_t Y_LSB : 4;
150+
uint8_t X_LSB : 4;
151+
bool int_eeprom_write_pending : 1;
152+
uint16_t RESERVED : 11;
153+
};
154+
155+
float temperature_convert(uint16_t raw_temperature);
156+
157+
// NOTE: device sensitivity HW fixed at 4 LSB/Gauss == 0.4 LSB/mT
158+
// All measurements are supposed to be raw 4 LSB/Gauss. No need to introduce fractions
159+
constexpr auto MEASUREMENTS_REG_bitlength_full_scale = 12;
160+
161+
int16_t measurement_sign_convert(uint16_t raw_measurement,
162+
uint8_t bit_length = MEASUREMENTS_REG_bitlength_full_scale);
163+
// --------
164+
constexpr uint8_t CUSTOMER_ACCESS_REG = 0x35;
165+
constexpr whole_reg_t CUSTOMER_ACCESS_REG_code = 0x2C413534;
166+
167+
// --------
168+
169+
/// give eeprom registers time to complete WRITE
170+
const std::set<uint8_t> EEPROM_REGS = {CUSTOMER_ACCESS_REG, CONF_REG, INT_REG};
171+
172+
using std::chrono_literals::operator""ms;
173+
constexpr auto EEPROM_REG_WRITE_DELAY_MS = 60ms; // docs say 50ms, +10ms for good measure
174+
175+
/////////////////////
176+
} // namespace drivers::als31300

0 commit comments

Comments
 (0)