1515#include "esp32-hal-i2c.h"
1616#include "freertos/FreeRTOS.h"
1717#include "freertos/task.h"
18+ #include "freertos/semphr.h"
1819#include "rom/ets_sys.h"
1920#include "soc/i2c_reg.h"
2021#include "soc/dport_reg.h"
2122
22- #define I2C_DEV (i ) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE)
23- //#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i)))
2423#define I2C_SCL_IDX (p ) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0))
2524#define I2C_SDA_IDX (p ) ((p==0)?I2CEXT0_SDA_OUT_IDX:((p==1)?I2CEXT1_SDA_OUT_IDX:0))
2625
26+
27+ struct i2c_struct_t {
28+ i2c_dev_t * dev ;
29+ xSemaphoreHandle lock ;
30+ uint8_t num ;
31+ };
32+
33+ enum {
34+ I2C_CMD_RSTART ,
35+ I2C_CMD_WRITE ,
36+ I2C_CMD_READ ,
37+ I2C_CMD_STOP ,
38+ I2C_CMD_END
39+ };
40+
41+ #define I2C_MUTEX_LOCK () do{} while (xSemaphoreTake(i2c->lock, portMAX_DELAY) != pdPASS)
42+ #define I2C_MUTEX_UNLOCK () xSemaphoreGive(i2c->lock)
43+
44+ static i2c_t _i2c_bus_array [2 ] = {
45+ {(volatile i2c_dev_t * )(DR_REG_I2C_EXT_BASE ), NULL , 0 },
46+ {(volatile i2c_dev_t * )(DR_REG_I2C1_EXT_BASE ), NULL , 1 }
47+ };
48+
2749void i2cAttachSCL (i2c_t * i2c , int8_t scl )
2850{
51+ if (i2c == NULL ){
52+ return ;
53+ }
54+ I2C_MUTEX_LOCK ();
2955pinMode (scl , OUTPUT );
3056pinMatrixOutAttach (scl , I2C_SCL_IDX (i2c -> num ), false, false);
3157pinMatrixInAttach (scl , I2C_SCL_IDX (i2c -> num ), false);
58+ I2C_MUTEX_UNLOCK ();
3259}
3360
3461void i2cDetachSCL (i2c_t * i2c , int8_t scl )
3562{
63+ if (i2c == NULL ){
64+ return ;
65+ }
66+ I2C_MUTEX_LOCK ();
3667pinMatrixOutDetach (scl , false, false);
3768pinMatrixInDetach (I2C_SCL_IDX (i2c -> num ), false, false);
3869pinMode (scl , INPUT );
70+ I2C_MUTEX_UNLOCK ();
3971}
4072
4173void i2cAttachSDA (i2c_t * i2c , int8_t sda )
4274{
75+ if (i2c == NULL ){
76+ return ;
77+ }
78+ I2C_MUTEX_LOCK ();
4379pinMode (sda , OUTPUT_OPEN_DRAIN );
4480pinMatrixOutAttach (sda , I2C_SDA_IDX (i2c -> num ), false, false);
4581pinMatrixInAttach (sda , I2C_SDA_IDX (i2c -> num ), false);
82+ I2C_MUTEX_UNLOCK ();
4683}
4784
4885void i2cDetachSDA (i2c_t * i2c , int8_t sda )
4986{
87+ if (i2c == NULL ){
88+ return ;
89+ }
90+ I2C_MUTEX_LOCK ();
5091pinMatrixOutDetach (sda , false, false);
5192pinMatrixInDetach (I2C_SDA_IDX (i2c -> num ), false, false);
5293pinMode (sda , INPUT );
94+ I2C_MUTEX_UNLOCK ();
5395}
5496
55- enum {
56- I2C_CMD_RSTART ,
57- I2C_CMD_WRITE ,
58- I2C_CMD_READ ,
59- I2C_CMD_STOP ,
60- I2C_CMD_END
61- };
62-
6397/*
6498 * index - command index (0 to 15)
6599 * op_code - is the command
@@ -78,13 +112,27 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo
78112i2c -> dev -> command [index ].op_code = op_code ;
79113}
80114
115+ void i2cResetFiFo (i2c_t * i2c )
116+ {
117+ i2c -> dev -> fifo_conf .tx_fifo_rst = 1 ;
118+ i2c -> dev -> fifo_conf .tx_fifo_rst = 0 ;
119+ i2c -> dev -> fifo_conf .rx_fifo_rst = 1 ;
120+ i2c -> dev -> fifo_conf .rx_fifo_rst = 0 ;
121+ }
122+
81123int i2cWrite (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint8_t len , bool sendStop )
82124{
83125int i ;
84126uint8_t index = 0 ;
85127uint8_t dataLen = len + (addr_10bit ?2 :1 );
86128address = (address << 1 );
87129
130+ if (i2c == NULL ){
131+ return 4 ;
132+ }
133+
134+ I2C_MUTEX_LOCK ();
135+
88136while (dataLen ){
89137uint8_t willSend = (dataLen > 32 )?32 :dataLen ;
90138uint8_t dataSend = willSend ;
@@ -129,18 +177,21 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
129177//Bus failed (maybe check for this while waiting?
130178if (i2c -> dev -> int_raw .arbitration_lost ){
131179//log_e("Bus Fail! Addr: %x", address >> 1);
180+ I2C_MUTEX_UNLOCK ();
132181return 4 ;
133182 }
134183
135184//Bus timeout
136185if (i2c -> dev -> int_raw .time_out ){
137186//log_e("Bus Timeout! Addr: %x", address >> 1);
187+ I2C_MUTEX_UNLOCK ();
138188return 3 ;
139189 }
140190
141191//Transmission did not finish and ACK_ERR is set
142192if (i2c -> dev -> int_raw .ack_err ){
143193//log_e("Ack Error! Addr: %x", address >> 1);
194+ I2C_MUTEX_UNLOCK ();
144195return 1 ;
145196 }
146197
@@ -152,6 +203,7 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
152203 }
153204
154205 }
206+ I2C_MUTEX_UNLOCK ();
155207return 0 ;
156208}
157209
@@ -163,6 +215,12 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
163215uint8_t cmdIdx ;
164216uint8_t willRead ;
165217
218+ if (i2c == NULL ){
219+ return 4 ;
220+ }
221+
222+ I2C_MUTEX_LOCK ();
223+
166224i2cResetFiFo (i2c );
167225
168226//CMD START
@@ -204,18 +262,21 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
204262//Bus failed (maybe check for this while waiting?
205263if (i2c -> dev -> int_raw .arbitration_lost ){
206264//log_e("Bus Fail! Addr: %x", address >> 1);
265+ I2C_MUTEX_UNLOCK ();
207266return -4 ;
208267 }
209268
210269//Bus timeout
211270if (i2c -> dev -> int_raw .time_out ){
212271//log_e("Bus Timeout! Addr: %x", address >> 1);
272+ I2C_MUTEX_UNLOCK ();
213273return -3 ;
214274 }
215275
216276//Transmission did not finish and ACK_ERR is set
217277if (i2c -> dev -> int_raw .ack_err ){
218278//log_e("Ack Error! Addr: %x", address >> 1);
279+ I2C_MUTEX_UNLOCK ();
219280return -1 ;
220281 }
221282if (i2c -> dev -> ctr .trans_start || i2c -> dev -> status_reg .bus_busy || !(i2c -> dev -> int_raw .trans_complete ) || !(i2c -> dev -> command [cmdIdx - 1 ].done )){
@@ -232,22 +293,19 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
232293 }
233294len -= willRead ;
234295 }
296+ I2C_MUTEX_UNLOCK ();
235297return 0 ;
236298}
237299
238- void i2cResetFiFo (i2c_t * i2c )
239- {
240- //TX FIFO
241- i2c -> dev -> fifo_conf .tx_fifo_rst = 1 ;
242- i2c -> dev -> fifo_conf .tx_fifo_rst = 0 ;
243- //RX FIFO
244- i2c -> dev -> fifo_conf .rx_fifo_rst = 1 ;
245- i2c -> dev -> fifo_conf .rx_fifo_rst = 0 ;
246- }
247-
248300void i2cSetFrequency (i2c_t * i2c , uint32_t clk_speed )
249301{
250302uint32_t period = (APB_CLK_FREQ /clk_speed ) / 2 ;
303+
304+ if (i2c == NULL ){
305+ return ;
306+ }
307+
308+ I2C_MUTEX_LOCK ();
251309i2c -> dev -> scl_low_period .scl_low_period = period ;
252310i2c -> dev -> scl_high_period .period = period ;
253311
@@ -259,10 +317,15 @@ void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
259317
260318i2c -> dev -> sda_hold .time = 25 ;
261319i2c -> dev -> sda_sample .time = 25 ;
320+ I2C_MUTEX_UNLOCK ();
262321}
263322
264323uint32_t i2cGetFrequency (i2c_t * i2c )
265324{
325+ if (i2c == NULL ){
326+ return 0 ;
327+ }
328+
266329return APB_CLK_FREQ /(i2c -> dev -> scl_low_period .scl_low_period + i2c -> dev -> scl_high_period .period );
267330}
268331
@@ -274,18 +337,23 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
274337
275338i2c_t * i2cInit (uint8_t i2c_num , uint16_t slave_addr , bool addr_10bit_en )
276339{
277- i2c_t * i2c = (i2c_t * ) malloc (sizeof (i2c_t ));
278- if (i2c == 0 ){
340+ if (i2c_num > 1 ){
279341return NULL ;
280342 }
281343
282- i2c -> num = i2c_num ;
283- i2c -> dev = I2C_DEV (i2c_num );
344+ i2c_t * i2c = & _i2c_bus_array [i2c_num ];
345+
346+ if (i2c -> lock == NULL ){
347+ i2c -> lock = xSemaphoreCreateMutex ();
348+ if (i2c -> lock == NULL ){
349+ return NULL ;
350+ }
351+ }
284352
285- if (i2c -> num == 0 ){
353+ if (i2c_num == 0 ){
286354SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT0_CLK_EN );
287355CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT0_RST );
288- } else if ( i2c -> num == 1 ) {
356+ } else {
289357SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT1_CLK_EN );
290358CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST );
291359 }
0 commit comments