Skip to content

Commit b5d115e

Browse files
author
Chuck Todd
committed
cleanup
Get my dirty fingers out of the SDK. This commit should return the SDK files (i2c_struct.h,i2c_reg.h) back to factory defaults. The required typedef's were duplicated in esp32-hal-i2c.h instead. With this Commit, the only changes are in Wire.h, Wire.cpp, esp32-hal-i2c.h, esp32-hal-i2c.c
1 parent abeb0c2 commit b5d115e

File tree

4 files changed

+179
-115
lines changed

4 files changed

+179
-115
lines changed

cores/esp32/esp32-hal-i2c.c

+17-9
Original file line numberDiff line numberDiff line change
@@ -1001,9 +1001,9 @@ while(!needMoreCmds&&(qp < i2c->queueCount)){ // check if more possible cmds
10011001
//log_e("needMoreCmds=%d",needMoreCmds);
10021002
done=(!needMoreCmds)||(cmdIdx>14);
10031003

1004-
while(!done){ // fill the command[] until either 0..14 or out of cmds
1004+
while(!done){ // fill the command[] until either 0..14 filled or out of cmds and last cmd is STOP
10051005
//CMD START
1006-
I2C_DATA_QUEUE_t *tdq=&i2c->dq[qp]; // simpler
1006+
I2C_DATA_QUEUE_t *tdq=&i2c->dq[qp]; // simpler coding
10071007

10081008
if(!tdq->ctrl.startCmdSent){// has this dq element's START command been added?
10091009
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_RSTART, 0, false, false, false);
@@ -1023,9 +1023,12 @@ while(!done){ // fill the command[] until either 0..14 or out of cmds
10231023

10241024
/* Can I have another Sir?
10251025
ALL CMD queues must be terminated with either END or STOP.
1026-
if END is used, when refilling the cmd[] next time, no entries from END to [15] can be used.
1027-
AND the END continue. The END command does not complete until the the
1028-
ctr->trans_start=1 has executed.
1026+
1027+
If END is used, when refilling the cmd[] next time, no entries from END to [15] can be used.
1028+
AND the cmd[] must be filled starting at [0] with commands. Either fill all 15 [0]..[14] and leave the
1029+
END in [15] or include a STOP in one of the positions [0]..[14]. Any entries after a STOP are IGNORED byte the StateMachine.
1030+
The END operation does not complete until ctr->trans_start=1 has been issued.
1031+
10291032
So, only refill from [0]..[14], leave [15] for a continuation if necessary.
10301033
As a corrilary, once END exists in [15], you do not need to overwrite it for the
10311034
next continuation. It is never modified. But, I update it every time because it might
@@ -1093,7 +1096,7 @@ while(!done){ // fill the command[] until either 0..14 or out of cmds
10931096
}
10941097

10951098
}// while(!done)
1096-
if(INTS){
1099+
if(INTS){ // don't want to prematurely enable fifo ints until ISR is ready to handle it.
10971100
if(ena_rx) i2c->dev->int_ena.rx_fifo_full = 1;
10981101
if(ena_tx) i2c->dev->int_ena.tx_fifo_empty = 1;
10991102
}
@@ -1146,7 +1149,7 @@ uint8_t cnt;
11461149
while((a < i2c->queueCount)&&!(full || readEncountered)){
11471150
I2C_DATA_QUEUE_t *tdq = &i2c->dq[a];
11481151
cnt=0;
1149-
// add to address to fifo
1152+
// add to address to fifo ctrl.addr already has R/W bit positioned correctly
11501153
if(tdq->ctrl.addrSent < tdq->ctrl.addrReq){ // need to send address bytes
11511154
if(tdq->ctrl.addrReq==2){ //10bit
11521155
if(tdq->ctrl.addrSent==0){ //10bit highbyte needs sent
@@ -1178,6 +1181,8 @@ while((a < i2c->queueCount)&&!(full || readEncountered)){
11781181
}
11791182
full=!(i2c->dev->status_reg.tx_fifo_cnt<31);
11801183
// add write data to fifo
1184+
//21NOV2017 might want to look into using local capacity counter instead of reading status_reg
1185+
// a double while loop, like emptyRxFifo()
11811186
if(tdq->ctrl.mode==0){ // write
11821187
if(tdq->ctrl.addrSent == tdq->ctrl.addrReq){ //address has been sent, is Write Mode!
11831188
while((!full)&&(tdq->position < tdq->length)){
@@ -1190,9 +1195,11 @@ while((a < i2c->queueCount)&&!(full || readEncountered)){
11901195
else readEncountered = true;
11911196

11921197
if(full) readEncountered =false; //tx possibly needs more
1193-
1198+
1199+
// update debug buffer tx counts
11941200
cnt += intBuff[intPos][1]>>16;
11951201
intBuff[intPos][1] = (intBuff[intPos][1]&0xFFFF)|(cnt<<16);
1202+
11961203
if(!(full||readEncountered)) a++; // check next buffer for tx
11971204
}
11981205

@@ -1230,6 +1237,7 @@ if(tdq->ctrl.mode==1) { // read
12301237
moveCnt = (tdq->length - tdq->position);
12311238
}
12321239
}
1240+
// update Debug rxCount
12331241
cnt += (intBuff[intPos][1])&&0xffFF;
12341242
intBuff[intPos][1] = (intBuff[intPos][1]&0xFFFF0000)|cnt;
12351243
}
@@ -1656,4 +1664,4 @@ if(i2c->intr_handle){
16561664
i2c->intr_handle=NULL;
16571665
}
16581666
return I2C_ERROR_OK;
1659-
}
1667+
}

cores/esp32/esp32-hal-i2c.h

+52-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
14+
// modified Nov 2017 by Chuck Todd <StickBreaker> to support Interrupt Driven I/O
1415

1516
#ifndef _ESP32_HAL_I2C_H_
1617
#define _ESP32_HAL_I2C_H_
@@ -25,7 +26,41 @@ extern "C" {
2526
#include "freertos/FreeRTOS.h"
2627
#include "freertos/event_groups.h"
2728

28-
29+
// start from tools/sdk/include/soc/soc/i2c_struct.h
30+
31+
typedef union {
32+
struct {
33+
uint32_t byte_num: 8; /*Byte_num represent the number of data need to be send or data need to be received.*/
34+
uint32_t ack_en: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/
35+
uint32_t ack_exp: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/
36+
uint32_t ack_val: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/
37+
uint32_t op_code: 3; /*op_code is the command 0:RSTART 1:WRITE 2:READ 3:STOP . 4:END.*/
38+
uint32_t reserved14: 17;
39+
uint32_t done: 1; /*When command0 is done in I2C Master mode this bit changes to high level.*/
40+
};
41+
uint32_t val;
42+
} I2C_COMMAND_t;
43+
44+
typedef union {
45+
struct {
46+
uint32_t rx_fifo_full_thrhd: 5;
47+
uint32_t tx_fifo_empty_thrhd:5; //Config tx_fifo empty threhd value when using apb fifo access * /
48+
uint32_t nonfifo_en: 1; //Set this bit to enble apb nonfifo access. * /
49+
uint32_t fifo_addr_cfg_en: 1; //When this bit is set to 1 then the byte after address represent the offset address of I2C Slave's ram. * /
50+
uint32_t rx_fifo_rst: 1; //Set this bit to reset rx fifo when using apb fifo access. * /
51+
// chuck while this bit is 1, the RX fifo is held in REST, Toggle it * /
52+
uint32_t tx_fifo_rst: 1; //Set this bit to reset tx fifo when using apb fifo access. * /
53+
// chuck while this bit is 1, the TX fifo is held in REST, Toggle it * /
54+
uint32_t nonfifo_rx_thres: 6; //when I2C receives more than nonfifo_rx_thres data it will produce rx_send_full_int_raw interrupt and update the current offset address of the receiving data.* /
55+
uint32_t nonfifo_tx_thres: 6; //when I2C sends more than nonfifo_tx_thres data it will produce tx_send_empty_int_raw interrupt and update the current offset address of the sending data. * /
56+
uint32_t reserved26: 6;
57+
};
58+
uint32_t val;
59+
} I2C_FIFO_CONF_t;
60+
61+
// end from tools/sdk/include/soc/soc/i2c_struct.h
62+
63+
// External Wire.h equivalent error Codes
2964
typedef enum {
3065
I2C_ERROR_OK=0,
3166
I2C_ERROR_DEV,
@@ -38,6 +73,7 @@ typedef enum {
3873
I2C_ERROR_NO_BEGIN
3974
} i2c_err_t;
4075

76+
// sync between dispatch(i2cProcQueue) and worker(i2c_isr_handler_default)
4177
typedef enum {
4278
//I2C_NONE=0,
4379
I2C_STARTUP=1,
@@ -52,7 +88,7 @@ typedef enum {
5288
I2C_MASTERSLAVE
5389
}I2C_MODE_t;
5490

55-
91+
// internal Error condition
5692
typedef enum {
5793
// I2C_NONE=0,
5894
I2C_OK=1,
@@ -63,22 +99,26 @@ typedef enum {
6399
I2C_TIMEOUT
64100
}I2C_ERROR_t;
65101

66-
// i2c_event bits
102+
// i2c_event bits for EVENTGROUP bits
103+
// needed to minimize change events, FreeRTOS Daemon overload, so ISR will only set values
104+
// on Exit. Dispatcher will set bits for each dq before/after ISR completion
67105
#define EVENT_ERROR_NAK (BIT(0))
68106
#define EVENT_ERROR (BIT(1))
69-
//#define EVENT_RUNNING (BIT(3))
107+
#define EVENT_RUNNING (BIT(3))
70108
#define EVENT_DONE (BIT(4))
71109
#define EVENT_IN_END (BIT(5))
72110
#define EVENT_ERROR_PREV (BIT(6))
73111
#define EVENT_ERROR_TIMEOUT (BIT(7))
74112
#define EVENT_ERROR_ARBITRATION (BIT(8))
75113
#define EVENT_ERROR_DATA_NAK (BIT(9))
76114
#define EVENT_MASK 0x3F
115+
116+
// control record for each dq entry
77117
typedef union{
78118
struct {
79119
uint32_t addr: 16; // I2C address, if 10bit must have 0x7800 mask applied, else 8bit
80-
uint32_t mode: 1; // 0 write, 1 read
81-
uint32_t stop: 1; // 0 no, 1 yes
120+
uint32_t mode: 1; // transaction direction 0 write, 1 read
121+
uint32_t stop: 1; // sendStop 0 no, 1 yes
82122
uint32_t startCmdSent: 1; // START cmd has been added to command[]
83123
uint32_t addrCmdSent: 1; // addr WRITE cmd has been added to command[]
84124
uint32_t dataCmdSent: 1; // all necessary DATA(READ/WRITE) cmds added to command[]
@@ -89,15 +129,17 @@ typedef union{
89129
};
90130
uint32_t val;
91131
}I2C_DATA_CTRL_t;
92-
132+
133+
// individual dq element
93134
typedef struct {
94135
uint8_t *data; // datapointer for read/write buffer
95136
uint16_t length; // size of data buffer
96137
uint16_t position; // current position for next char in buffer (<length)
97-
uint16_t cmdBytesNeeded; // number of data bytes needing (READ/WRITE)Command[]
98-
uint16_t queueLength;
138+
uint16_t cmdBytesNeeded; // used to control number of I2C_COMMAND_t blocks added to queu
139+
uint16_t queueLength; // number of data bytes needing moved, used to control
140+
// current queuePos for fifo fills
99141
I2C_DATA_CTRL_t ctrl;
100-
EventGroupHandle_t queueEvent;
142+
EventGroupHandle_t queueEvent; // optional user supplied for Async feedback EventBits
101143
}I2C_DATA_QUEUE_t;
102144

103145
struct i2c_struct_t;

tools/sdk/include/soc/soc/i2c_reg.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "soc.h"
1919

2020
#define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 )
21-
#define REG_I2C_BASEO(i,o) (DR_REG_I2C_EXT_BASE +(i) *0x14000+(o)*4)
21+
2222
#define I2C_SCL_LOW_PERIOD_REG(i) (REG_I2C_BASE(i) + 0x0000)
2323
/* I2C_SCL_LOW_PERIOD : R/W ;bitpos:[13:0] ;default: 14'b0 ; */
2424
/*description: This register is used to configure the low level width of SCL clock.*/

0 commit comments

Comments
 (0)