Skip to content

Commit cc3c55b

Browse files
committed
fix i2c hal
1 parent 917286a commit cc3c55b

File tree

1 file changed

+86
-26
lines changed

1 file changed

+86
-26
lines changed

Diff for: cores/esp32/esp32-hal-i2c.c

+86-26
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ enum {
6363
/*
6464
* index - command index (0 to 15)
6565
* op_code - is the command
66+
* byte_num - This register is to store the amounts of data that is read and written. byte_num in RSTART, STOP, END is null.
6667
* ack_val - Each data byte is terminated by an ACK bit used to set the bit level.
6768
* ack_exp - This bit is to set an expected ACK value for the transmitter.
6869
* ack_check - This bit is to decide whether the transmitter checks ACK bit. 1 means yes and 0 means no.
69-
* byte_num - This register is to store the amounts of data that is read and written. byte_num in RSTART, STOP, END is null.
7070
* */
7171
void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bool ack_val, bool ack_exp, bool ack_check)
7272
{
@@ -80,15 +80,19 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo
8080

8181
int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop)
8282
{
83+
int i;
8384
uint8_t index = 0;
8485
uint8_t dataLen = len + (addr_10bit?2:1);
8586
address = (address << 1);
8687

8788
while(dataLen) {
8889
uint8_t willSend = (dataLen > 32)?32:dataLen;
8990
uint8_t dataSend = willSend;
90-
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);//START
91-
i2cSetCmd(i2c, 1, I2C_CMD_WRITE, willSend, false, false, true);
91+
92+
//CMD START
93+
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
94+
95+
//CMD WRITE(ADDRESS + DATA)
9296
if(!index) {
9397
i2c->dev->fifo_data.data = address & 0xFF;
9498
dataSend--;
@@ -97,27 +101,56 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
97101
dataSend--;
98102
}
99103
}
100-
int i = 0;
104+
i = 0;
101105
while(i<dataSend) {
102106
i++;
103107
i2c->dev->fifo_data.data = data[index++];
104108
}
109+
i2cSetCmd(i2c, 1, I2C_CMD_WRITE, willSend, false, false, true);
105110
dataLen -= willSend;
111+
112+
//CMD STOP or CMD END if there is more data
106113
if(dataLen) {
107114
i2cSetCmd(i2c, 2, I2C_CMD_END, 0, false, false, false);
108115
} else if(sendStop) {
109-
i2cSetCmd(i2c, 2, I2C_CMD_STOP, 0, false, false, true);
116+
i2cSetCmd(i2c, 2, I2C_CMD_STOP, 0, false, false, false);
110117
}
118+
119+
//Clear Interrupts
120+
i2c->dev->int_clr.val = 0xFFFFFFFF;
121+
122+
//START Transmission
111123
i2c->dev->ctr.trans_start = 1;
112-
while(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || (!i2c->dev->int_raw.ack_err && !i2c->dev->command[2].done));
113-
if(!i2c->dev->command[2].done) {
114-
log_e("Ack Error");
115-
return -1;
124+
125+
//WAIT Transmission
126+
while(1) {
127+
if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) {
128+
continue;
129+
} else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) {
130+
break;
131+
} else if(i2c->dev->command[2].done) {
132+
break;
133+
}
116134
}
117-
if(i2c->dev->status_reg.arb_lost || i2c->dev->status_reg.time_out) {
118-
log_e("Bus Fail");
119-
return -1;
135+
136+
//Bus failed (maybe check for this while waiting?
137+
if(i2c->dev->int_raw.arbitration_lost) {
138+
//log_e("Bus Fail! Addr: %x", address >> 1);
139+
return 4;
140+
}
141+
142+
//Bus timeout
143+
if(i2c->dev->int_raw.time_out) {
144+
//log_e("Bus Timeout! Addr: %x", address >> 1);
145+
return 3;
120146
}
147+
148+
//Transmission did not finish and ACK_ERR is set
149+
if(i2c->dev->int_raw.ack_err) {
150+
//log_e("Ack Error! Addr: %x", address >> 1);
151+
return 1;
152+
}
153+
121154
}
122155
return 0;
123156
}
@@ -130,12 +163,16 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
130163
uint8_t cmdIdx;
131164
uint8_t willRead;
132165

133-
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);//START
134-
i2cSetCmd(i2c, 1, I2C_CMD_WRITE, addrLen, false, false, true);
166+
//CMD START
167+
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
168+
169+
//CMD WRITE ADDRESS
135170
i2c->dev->fifo_data.data = address & 0xFF;
136171
if(addr_10bit) {
137172
i2c->dev->fifo_data.data = (address >> 8) & 0xFF;
138173
}
174+
i2cSetCmd(i2c, 1, I2C_CMD_WRITE, addrLen, false, false, true);
175+
139176
while(len) {
140177
cmdIdx = (index)?0:2;
141178
willRead = (len > 32)?32:(len-1);
@@ -150,14 +187,38 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
150187
}
151188
}
152189

190+
//Clear Interrupts
191+
i2c->dev->int_clr.val = 0xFFFFFFFF;
192+
193+
//START Transmission
153194
i2c->dev->ctr.trans_start = 1;
154-
while(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || (!i2c->dev->int_raw.ack_err && !i2c->dev->command[cmdIdx-1].done));
155-
if(!i2c->dev->command[cmdIdx-1].done) {
156-
log_e("Ack Error");
157-
return -1;
195+
196+
//WAIT Transmission
197+
while(1) {
198+
if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) {
199+
continue;
200+
} else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) {
201+
break;
202+
} else if(i2c->dev->command[cmdIdx-1].done) {
203+
break;
204+
}
205+
}
206+
207+
//Bus failed (maybe check for this while waiting?
208+
if(i2c->dev->int_raw.arbitration_lost) {
209+
//log_e("Bus Fail! Addr: %x", address >> 1);
210+
return -4;
211+
}
212+
213+
//Bus timeout
214+
if(i2c->dev->int_raw.time_out) {
215+
//log_e("Bus Timeout! Addr: %x", address >> 1);
216+
return -3;
158217
}
159-
if(i2c->dev->status_reg.arb_lost || i2c->dev->status_reg.time_out) {
160-
log_e("Bus Fail");
218+
219+
//Transmission did not finish and ACK_ERR is set
220+
if(i2c->dev->int_raw.ack_err) {
221+
//log_e("Ack Error! Addr: %x", address >> 1);
161222
return -1;
162223
}
163224
int i = 0;
@@ -192,8 +253,8 @@ void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
192253
i2c->dev->scl_stop_hold.time = 50;
193254
i2c->dev->scl_stop_setup.time = 50;
194255

195-
i2c->dev->sda_hold.time = 40;
196-
i2c->dev->sda_sample.time = 40;
256+
i2c->dev->sda_hold.time = 25;
257+
i2c->dev->sda_sample.time = 25;
197258
}
198259

199260
uint32_t i2cGetFrequency(i2c_t * i2c)
@@ -205,7 +266,6 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
205266
* mode - 0 = Slave, 1 = Master
206267
* slave_addr - I2C Address
207268
* addr_10bit_en - enable slave 10bit address mode.
208-
* clk_speed - SCL Frequency
209269
* */
210270

211271
i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
@@ -226,16 +286,16 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
226286
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST);
227287
}
228288

229-
i2c->dev->ctr.rx_lsb_first = 0 ;
230-
i2c->dev->ctr.tx_lsb_first = 0 ;
289+
i2c->dev->ctr.val = 0;
231290
i2c->dev->ctr.ms_mode = (slave_addr == 0);
232291
i2c->dev->ctr.sda_force_out = 1 ;
233292
i2c->dev->ctr.scl_force_out = 1 ;
234-
i2c->dev->ctr.sample_scl_level = 0 ;
293+
i2c->dev->ctr.clk_en = 1;
235294

236295
i2c->dev->timeout.tout = 2000;
237296
i2c->dev->fifo_conf.nonfifo_en = 0;
238297

298+
i2c->dev->slave_addr.val = 0;
239299
if (slave_addr) {
240300
i2c->dev->slave_addr.addr = slave_addr;
241301
i2c->dev->slave_addr.en_10bit = addr_10bit_en;

0 commit comments

Comments
 (0)