Ich versuche gerade die ID des BMP280 mittels Software-I2C auszulesen,
mein bisheriger Code sieht so aus:
1 | void BMP280::read_reg(uint8_t reg_addr, uint8_t amount, uint8_t reg_data[]) {
|
2 | const uint8_t last_index = amount - 1;
|
3 | i2c.start();
|
4 |
|
5 | if(i2c.send_byte(SLAVE_WRITE)) {
|
6 | if(i2c.send_byte(reg_addr)) {
|
7 | i2c.repeated_start();
|
8 | if(i2c.send_byte(SLAVE_READ)) {
|
9 | for(uint8_t i = 0; i < amount; i++) {
|
10 | uint8_t data = i2c.read_byte();
|
11 | if(i == last_index)
|
12 | i2c.master_nack();
|
13 | else
|
14 | i2c.master_ack();
|
15 | reg_data[i] = data;
|
16 | }
|
17 | }
|
18 | }
|
19 | }
|
20 |
|
21 | i2c.stop();
|
22 | }
|
Die entsprechenden Funktionen, die aufgerufen werden:
1 | bool ICACHE_FLASH_ATTR I2C::send_byte(uint8_t byte) {
|
2 | for(uint8_t i = 0; i < 8; i++) {
|
3 | if(byte & (1 << 7 - i))
|
4 | set_SDA_high();
|
5 | else
|
6 | set_SDA_low();
|
7 | set_SCL_high();
|
8 | os_delay_us(DELAY);
|
9 | set_SCL_low();
|
10 | }
|
11 |
|
12 | set_SDA_high();
|
13 |
|
14 | /* 9th clock for slave to ack transmitted byte */
|
15 | set_SCL_high();
|
16 | os_delay_us(DELAY);
|
17 | uint8_t ack = read_SDA();
|
18 | os_delay_us(DELAY);
|
19 | set_SCL_low();
|
20 |
|
21 | return ack == 0;
|
22 | }
|
23 | /****************************************************/
|
24 | uint8_t ICACHE_FLASH_ATTR I2C::read_byte(void) {
|
25 | uint8_t result = 0x00;
|
26 | for(uint8_t i = 0; i < 8; i++) {
|
27 | set_SCL_high();
|
28 | if(read_SDA())
|
29 | result |= (1 << 7 - i);
|
30 | set_SCL_low();
|
31 | }
|
32 | return result;
|
33 | }
|
34 | /****************************************************/
|
35 | void ICACHE_FLASH_ATTR I2C::repeated_start(void) {
|
36 | set_SDA_high();
|
37 | os_delay_us(DELAY);
|
38 | set_SCL_high();
|
39 | os_delay_us(DELAY);
|
40 | set_SDA_low();
|
41 | os_delay_us(DELAY);
|
42 | set_SCL_low();
|
43 | }
|
44 | /****************************************************/
|
45 | void ICACHE_FLASH_ATTR I2C::master_ack(void) {
|
46 | set_SDA_low();
|
47 | os_delay_us(DELAY);
|
48 | set_SCL_high();
|
49 | os_delay_us(DELAY);
|
50 | set_SCL_low();
|
51 | os_delay_us(DELAY);
|
52 | set_SDA_high();
|
53 | }
|
54 | /****************************************************/
|
55 | void ICACHE_FLASH_ATTR I2C::master_nack(void) {
|
56 | set_SCL_low();
|
57 | os_delay_us(DELAY);
|
58 | set_SCL_high();
|
59 | os_delay_us(DELAY);
|
60 | set_SCL_low();
|
61 | }
|
62 | /****************************************************/
|
63 | void ICACHE_FLASH_ATTR I2C::start(void) {
|
64 | set_SDA_low();
|
65 | os_delay_us(DELAY);
|
66 | set_SCL_low();
|
67 | }
|
68 | /****************************************************/
|
69 | void ICACHE_FLASH_ATTR I2C::stop(void) {
|
70 | set_SCL_high();
|
71 | os_delay_us(DELAY);
|
72 | set_SDA_high();
|
73 | }
|
74 | /****************************************************/
|
75 | uint8_t ICACHE_FLASH_ATTR I2C::read_SDA(void) {
|
76 | return GPIO_INPUT_GET(I2C_MASTER_SDA_GPIO);
|
77 | }
|
78 | /****************************************************/
|
79 | void ICACHE_FLASH_ATTR I2C::set_SDA_high(void) {
|
80 | gpio_output_set(1 << I2C_MASTER_SDA_GPIO, 0, 1 << I2C_MASTER_SDA_GPIO, 0);
|
81 | }
|
82 | /****************************************************/
|
83 | void ICACHE_FLASH_ATTR I2C::set_SDA_low(void) {
|
84 | gpio_output_set(0, 1 << I2C_MASTER_SDA_GPIO, 1 << I2C_MASTER_SDA_GPIO, 0);
|
85 | }
|
86 | /****************************************************/
|
87 | void ICACHE_FLASH_ATTR I2C::set_SCL_high(void) {
|
88 | gpio_output_set(1 << I2C_MASTER_SCL_GPIO, 0, 1 << I2C_MASTER_SCL_GPIO, 0);
|
89 | }
|
90 | /****************************************************/
|
91 | void ICACHE_FLASH_ATTR I2C::set_SCL_low(void) {
|
92 | gpio_output_set(0, 1 << I2C_MASTER_SCL_GPIO, 1 << I2C_MASTER_SCL_GPIO, 0);
|
93 | }
|
Nach Datenblatt sollte im Register 0x58 stehen, stattdessen lese ich
allerdings 0x7F - hat jemand eine Idee, warum das so ist? Ich hab die
Logic-Analyzer Aufnahme mit angehängt. Seltsamerweise sind die Zeiten
unterschiedlich - scheint mir fast, als würde der ESP da was machen und
daher kommt es zu unterschiedlichen Verzögerungen?
Edit: Das Bild ist etwas klein, hier die volle Auflösung:
https://pasteboard.co/IcIBjQR.png