Skip to content

Commit 5bcff94

Browse files
committed
add ICM-42688-P
1 parent d460d1d commit 5bcff94

File tree

12 files changed

+969
-313
lines changed

12 files changed

+969
-313
lines changed

src/madflight/cfg/cfg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ SOFTWARE.
203203
MF_PARAM( gps_baud, 0, int32_t, 'i') \
204204
\
205205
/*IMU - Inertial Measurement Unit (acc/gyro)*/ \
206-
MF_PARAM( imu_gizmo, 0, int32_t, 'e', mf_NONE,mf_BMI270,mf_MPU6000,mf_MPU6050,mf_MPU6500,mf_MPU9150,mf_MPU9250,mf_ICM45686) \
206+
MF_PARAM( imu_gizmo, 0, int32_t, 'e', mf_NONE,mf_BMI270,mf_MPU6000,mf_MPU6050,mf_MPU6500,mf_MPU9150,mf_MPU9250,mf_ICM45686,mf_ICM42688) \
207207
MF_PARAM( imu_spi_bus, -1, int32_t, 'i') \
208208
MF_PARAM( imu_i2c_bus, -1, int32_t, 'i') \
209209
MF_PARAM( imu_i2c_adr, 0, int32_t, 'i') \
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// madflight https://github.com/qqqlab/madflight
2+
// Interface for MPU and ICM sensors
3+
4+
#pragma once
5+
6+
#include "../../hal/MF_I2C.h"
7+
8+
#include "Arduino.h"
9+
#include <SPI.h>
10+
11+
//Datasheet: spi clock up to 1MHz for register operations, up to 20MHz allowed for reading data.
12+
#define ICM_SPI_FREQ_LOW 1000000
13+
#define ICM_SPI_FREQ_HIGH 20000000
14+
15+
//Datasheet: i2c clock up to 400kHz
16+
#define ICM_I2C_FREQ_LOW 400000
17+
#define ICM_I2C_FREQ_HIGH 1000000 //2.5 times overclocking
18+
19+
class ICM_Interface {
20+
public:
21+
virtual ~ICM_Interface() {};
22+
23+
int freqLow;
24+
int freqHigh;
25+
26+
virtual void setFreq(int freq) = 0;
27+
28+
virtual unsigned int write_register( uint8_t reg, uint8_t data ) = 0;
29+
30+
virtual void read_registers( uint8_t reg, uint8_t *data, uint8_t n ) = 0;
31+
32+
unsigned int ReadReg(uint8_t reg) {
33+
uint8_t data = 0;
34+
read_registers(reg, &data, 1);
35+
return data;
36+
}
37+
38+
inline void setFreqLow() {
39+
setFreq(freqLow);
40+
}
41+
42+
inline void setFreqHigh() {
43+
setFreq(freqHigh);
44+
}
45+
};
46+
47+
//================================================================
48+
// SPI
49+
//================================================================
50+
class ICM_InterfaceSPI : public ICM_Interface {
51+
public:
52+
ICM_InterfaceSPI(SPIClass *spi, uint8_t cs) {
53+
_spi = spi;
54+
_spi_cs = cs;
55+
freqLow = ICM_SPI_FREQ_LOW;
56+
freqHigh = ICM_SPI_FREQ_HIGH;
57+
setFreq(freqLow);
58+
pinMode(_spi_cs, OUTPUT);
59+
digitalWrite(_spi_cs, HIGH);
60+
}
61+
62+
void setFreq(int freq) override {
63+
_freq = freq;
64+
}
65+
66+
virtual unsigned int write_register( uint8_t reg, uint8_t data ) override {
67+
_spi->beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE3));
68+
digitalWrite(_spi_cs, LOW);
69+
_spi->transfer(reg & 0x7f);
70+
unsigned int temp_val = _spi->transfer(data);
71+
digitalWrite(_spi_cs, HIGH);
72+
_spi->endTransaction();
73+
return temp_val;
74+
}
75+
76+
virtual void read_registers( uint8_t reg, uint8_t *data, uint8_t n ) override {
77+
_spi->beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE3));
78+
digitalWrite(_spi_cs, LOW);
79+
_spi->transfer(reg | 0x80);
80+
for(int i = 0; i < n; i++) {
81+
data[i] = _spi->transfer(0x00);
82+
}
83+
digitalWrite(_spi_cs, HIGH);
84+
_spi->endTransaction();
85+
}
86+
87+
private:
88+
SPIClass * _spi;
89+
int _freq;
90+
uint8_t _spi_cs;
91+
unsigned int _WriteReg_SPI(uint8_t reg, uint8_t data);
92+
void _ReadRegs_SPI(uint8_t reg, uint8_t *buf, int n);
93+
};
94+
95+
//================================================================
96+
// I2C
97+
//================================================================
98+
99+
class ICM_InterfaceI2C : public ICM_Interface{
100+
public:
101+
ICM_InterfaceI2C(MF_I2C *i2c, uint8_t i2c_adr) {
102+
_i2c = i2c;
103+
_i2c_adr = i2c_adr;
104+
freqLow = ICM_I2C_FREQ_LOW;
105+
freqHigh = ICM_I2C_FREQ_HIGH;
106+
setFreq(freqLow);
107+
}
108+
109+
void setFreq(int freq) override {
110+
_i2c->setClock(freq);
111+
}
112+
113+
virtual unsigned int write_register( uint8_t reg, uint8_t data ) override {
114+
_i2c->beginTransmission(_i2c_adr);
115+
_i2c->write(reg);
116+
_i2c->write(data);
117+
_i2c->endTransmission();
118+
//Serial.printf("write_register(reg0x%02X, data=0x%02X) --> ", reg, data); ReadReg(reg);
119+
return 0;
120+
}
121+
122+
virtual void read_registers( uint8_t reg, uint8_t *data, uint8_t n ) override {
123+
_i2c->beginTransmission(_i2c_adr);
124+
_i2c->write(reg);
125+
_i2c->endTransmission(false); //false = repeated start
126+
uint8_t bytesReceived = _i2c->requestFrom(_i2c_adr, n);
127+
if(bytesReceived == n) {
128+
_i2c->readBytes(data, bytesReceived);
129+
}
130+
//Serial.printf("ReadRegs(reg=0x%02X, n=%d) --> data[%d]=0x%02X\n", reg, n, bytesReceived, data[0]);
131+
}
132+
133+
private:
134+
MF_I2C *_i2c;
135+
uint8_t _i2c_adr;
136+
unsigned int _WriteReg_I2C(uint8_t reg, uint8_t data);
137+
void _ReadRegs_I2C(uint8_t reg, uint8_t *buf, uint8_t n);
138+
};
139+
140+
141+

0 commit comments

Comments
 (0)