1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! LSM303xx Sensors
//!

#![allow(non_camel_case_types)]

use enum_primitive::cast::FromPrimitive;
use enum_primitive::enum_from_primitive;

use kernel::utilities::registers::register_bitfields;

pub const ACCELEROMETER_BASE_ADDRESS: u8 = 0x19;
pub const MAGNETOMETER_BASE_ADDRESS: u8 = 0x1e;

// Manual page Table 20, page 25
enum_from_primitive! {
    #[derive(Clone, Copy, PartialEq)]
    pub enum Lsm303AccelDataRate {
        Off = 0,
        DataRate1Hz = 1,
        DataRate10Hz = 2,
        DataRate25Hz = 3,
        DataRate50Hz = 4,
        DataRate100Hz = 5,
        DataRate200Hz = 6,
        DataRate400Hz = 7,
        LowPower1620Hz = 8,
        Normal1344LowPower5376Hz = 9,
    }
}

// Manual table 72, page 25
enum_from_primitive! {
    #[derive(Clone, Copy, PartialEq)]
    pub enum Lsm303MagnetoDataRate {
        DataRate0_75Hz = 0,
        DataRate1_5Hz = 1,
        DataRate3_0Hz = 2,
        DataRate7_5Hz = 3,
        DataRate15_0Hz = 4,
        DataRate30_0Hz = 5,
        DataRate75_0Hz = 6,
        DataRate220_0Hz = 7,
    }
}

enum_from_primitive! {
    #[derive(Clone, Copy, PartialEq)]
    pub enum Lsm303Scale {
        Scale2G = 0,
        Scale4G = 1,
        Scale8G = 2,
        Scale16G = 3
    }
}

// Manual table 27, page 27
pub(crate) const SCALE_FACTOR: [u8; 4] = [2, 4, 8, 16];

// Manual table 75, page 38
enum_from_primitive! {
    #[derive(Clone, Copy, PartialEq)]
    pub enum Lsm303Range {
        Range1G = 0,
        Range1_3G = 1,
        Range1_9G = 2,
        Range2_5G = 3,
        Range4_0G = 4,
        Range4_7G = 5,
        Range5_6G = 7,
        Range8_1 = 8,
    }
}

// Manual table 75, page 38
pub(crate) const RANGE_FACTOR_X_Y: [i16; 8] = [
    1000, // placeholder
    1100, 855, 670, 450, 400, 330, 230,
];

// Manual table 75, page 38
pub(crate) const RANGE_FACTOR_Z: [i16; 8] = [
    1000, // placeholder
    980, 760, 600, 400, 355, 295, 205,
];

register_bitfields![u8,
    pub (crate) CTRL_REG1 [
        /// Output data rate
        ODR OFFSET(4) NUMBITS(4) [],
        /// Low Power enable
        LPEN OFFSET(3) NUMBITS(1) [],
        /// Z enable
        ZEN OFFSET(2) NUMBITS(1) [],
        /// Y enable
        YEN OFFSET(1) NUMBITS(1) [],
        /// X enable
        XEN OFFSET(0) NUMBITS(1) []
    ],
    pub (crate) CTRL_REG4 [
        /// Block Data update
        BDU OFFSET(7) NUMBITS(2) [],
        /// Big Little Endian
        BLE OFFSET(6) NUMBITS(1) [],
        /// Full Scale selection
        FS OFFSET(4) NUMBITS(2) [],
        /// High Resolution
        HR OFFSET(3) NUMBITS(1) [],
        /// SPI Serial Interface
        SIM OFFSET(0) NUMBITS(1) []
    ]
];

enum_from_primitive! {
    pub enum AccelerometerRegisters {
        CTRL_REG1 = 0x20,
        CTRL_REG4 = 0x23,
        OUT_X_L_A = 0x28,
        OUT_X_H_A = 0x29,
        OUT_Y_L_A = 0x2A,
        OUT_Y_H_A = 0x2B,
        OUT_Z_L_A = 0x2C,
        OUT_Z_H_A = 0x2D,
    }
}