Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
过眠
arduino-esp32
提交
9ec43898
A
arduino-esp32
项目概览
过眠
/
arduino-esp32
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
arduino-esp32
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9ec43898
编写于
10月 11, 2016
作者:
M
me-no-dev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement thread-safe i2c
上级
50b060ab
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
96 addition
and
32 deletion
+96
-32
cores/esp32/esp32-hal-i2c.c
cores/esp32/esp32-hal-i2c.c
+94
-26
cores/esp32/esp32-hal-i2c.h
cores/esp32/esp32-hal-i2c.h
+2
-6
未找到文件。
cores/esp32/esp32-hal-i2c.c
浏览文件 @
9ec43898
...
...
@@ -15,51 +15,85 @@
#include "esp32-hal-i2c.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "rom/ets_sys.h"
#include "soc/i2c_reg.h"
#include "soc/dport_reg.h"
#define I2C_DEV(i) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE)
//#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i)))
#define I2C_SCL_IDX(p) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0))
#define I2C_SDA_IDX(p) ((p==0)?I2CEXT0_SDA_OUT_IDX:((p==1)?I2CEXT1_SDA_OUT_IDX:0))
struct
i2c_struct_t
{
i2c_dev_t
*
dev
;
xSemaphoreHandle
lock
;
uint8_t
num
;
};
enum
{
I2C_CMD_RSTART
,
I2C_CMD_WRITE
,
I2C_CMD_READ
,
I2C_CMD_STOP
,
I2C_CMD_END
};
#define I2C_MUTEX_LOCK() do {} while (xSemaphoreTake(i2c->lock, portMAX_DELAY) != pdPASS)
#define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock)
static
i2c_t
_i2c_bus_array
[
2
]
=
{
{(
volatile
i2c_dev_t
*
)(
DR_REG_I2C_EXT_BASE
),
NULL
,
0
},
{(
volatile
i2c_dev_t
*
)(
DR_REG_I2C1_EXT_BASE
),
NULL
,
1
}
};
void
i2cAttachSCL
(
i2c_t
*
i2c
,
int8_t
scl
)
{
if
(
i2c
==
NULL
){
return
;
}
I2C_MUTEX_LOCK
();
pinMode
(
scl
,
OUTPUT
);
pinMatrixOutAttach
(
scl
,
I2C_SCL_IDX
(
i2c
->
num
),
false
,
false
);
pinMatrixInAttach
(
scl
,
I2C_SCL_IDX
(
i2c
->
num
),
false
);
I2C_MUTEX_UNLOCK
();
}
void
i2cDetachSCL
(
i2c_t
*
i2c
,
int8_t
scl
)
{
if
(
i2c
==
NULL
){
return
;
}
I2C_MUTEX_LOCK
();
pinMatrixOutDetach
(
scl
,
false
,
false
);
pinMatrixInDetach
(
I2C_SCL_IDX
(
i2c
->
num
),
false
,
false
);
pinMode
(
scl
,
INPUT
);
I2C_MUTEX_UNLOCK
();
}
void
i2cAttachSDA
(
i2c_t
*
i2c
,
int8_t
sda
)
{
if
(
i2c
==
NULL
){
return
;
}
I2C_MUTEX_LOCK
();
pinMode
(
sda
,
OUTPUT_OPEN_DRAIN
);
pinMatrixOutAttach
(
sda
,
I2C_SDA_IDX
(
i2c
->
num
),
false
,
false
);
pinMatrixInAttach
(
sda
,
I2C_SDA_IDX
(
i2c
->
num
),
false
);
I2C_MUTEX_UNLOCK
();
}
void
i2cDetachSDA
(
i2c_t
*
i2c
,
int8_t
sda
)
{
if
(
i2c
==
NULL
){
return
;
}
I2C_MUTEX_LOCK
();
pinMatrixOutDetach
(
sda
,
false
,
false
);
pinMatrixInDetach
(
I2C_SDA_IDX
(
i2c
->
num
),
false
,
false
);
pinMode
(
sda
,
INPUT
);
I2C_MUTEX_UNLOCK
();
}
enum
{
I2C_CMD_RSTART
,
I2C_CMD_WRITE
,
I2C_CMD_READ
,
I2C_CMD_STOP
,
I2C_CMD_END
};
/*
* index - command index (0 to 15)
* op_code - is the command
...
...
@@ -78,6 +112,14 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo
i2c
->
dev
->
command
[
index
].
op_code
=
op_code
;
}
void
i2cResetFiFo
(
i2c_t
*
i2c
)
{
i2c
->
dev
->
fifo_conf
.
tx_fifo_rst
=
1
;
i2c
->
dev
->
fifo_conf
.
tx_fifo_rst
=
0
;
i2c
->
dev
->
fifo_conf
.
rx_fifo_rst
=
1
;
i2c
->
dev
->
fifo_conf
.
rx_fifo_rst
=
0
;
}
int
i2cWrite
(
i2c_t
*
i2c
,
uint16_t
address
,
bool
addr_10bit
,
uint8_t
*
data
,
uint8_t
len
,
bool
sendStop
)
{
int
i
;
...
...
@@ -85,6 +127,12 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
uint8_t
dataLen
=
len
+
(
addr_10bit
?
2
:
1
);
address
=
(
address
<<
1
);
if
(
i2c
==
NULL
){
return
4
;
}
I2C_MUTEX_LOCK
();
while
(
dataLen
)
{
uint8_t
willSend
=
(
dataLen
>
32
)
?
32
:
dataLen
;
uint8_t
dataSend
=
willSend
;
...
...
@@ -129,18 +177,21 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
//Bus failed (maybe check for this while waiting?
if
(
i2c
->
dev
->
int_raw
.
arbitration_lost
)
{
//log_e("Bus Fail! Addr: %x", address >> 1);
I2C_MUTEX_UNLOCK
();
return
4
;
}
//Bus timeout
if
(
i2c
->
dev
->
int_raw
.
time_out
)
{
//log_e("Bus Timeout! Addr: %x", address >> 1);
I2C_MUTEX_UNLOCK
();
return
3
;
}
//Transmission did not finish and ACK_ERR is set
if
(
i2c
->
dev
->
int_raw
.
ack_err
)
{
//log_e("Ack Error! Addr: %x", address >> 1);
I2C_MUTEX_UNLOCK
();
return
1
;
}
...
...
@@ -152,6 +203,7 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
}
}
I2C_MUTEX_UNLOCK
();
return
0
;
}
...
...
@@ -163,6 +215,12 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
uint8_t
cmdIdx
;
uint8_t
willRead
;
if
(
i2c
==
NULL
){
return
4
;
}
I2C_MUTEX_LOCK
();
i2cResetFiFo
(
i2c
);
//CMD START
...
...
@@ -204,18 +262,21 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
//Bus failed (maybe check for this while waiting?
if
(
i2c
->
dev
->
int_raw
.
arbitration_lost
)
{
//log_e("Bus Fail! Addr: %x", address >> 1);
I2C_MUTEX_UNLOCK
();
return
-
4
;
}
//Bus timeout
if
(
i2c
->
dev
->
int_raw
.
time_out
)
{
//log_e("Bus Timeout! Addr: %x", address >> 1);
I2C_MUTEX_UNLOCK
();
return
-
3
;
}
//Transmission did not finish and ACK_ERR is set
if
(
i2c
->
dev
->
int_raw
.
ack_err
)
{
//log_e("Ack Error! Addr: %x", address >> 1);
I2C_MUTEX_UNLOCK
();
return
-
1
;
}
if
(
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
}
len
-=
willRead
;
}
I2C_MUTEX_UNLOCK
();
return
0
;
}
void
i2cResetFiFo
(
i2c_t
*
i2c
)
{
//TX FIFO
i2c
->
dev
->
fifo_conf
.
tx_fifo_rst
=
1
;
i2c
->
dev
->
fifo_conf
.
tx_fifo_rst
=
0
;
//RX FIFO
i2c
->
dev
->
fifo_conf
.
rx_fifo_rst
=
1
;
i2c
->
dev
->
fifo_conf
.
rx_fifo_rst
=
0
;
}
void
i2cSetFrequency
(
i2c_t
*
i2c
,
uint32_t
clk_speed
)
{
uint32_t
period
=
(
APB_CLK_FREQ
/
clk_speed
)
/
2
;
if
(
i2c
==
NULL
){
return
;
}
I2C_MUTEX_LOCK
();
i2c
->
dev
->
scl_low_period
.
scl_low_period
=
period
;
i2c
->
dev
->
scl_high_period
.
period
=
period
;
...
...
@@ -259,10 +317,15 @@ void i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
i2c
->
dev
->
sda_hold
.
time
=
25
;
i2c
->
dev
->
sda_sample
.
time
=
25
;
I2C_MUTEX_UNLOCK
();
}
uint32_t
i2cGetFrequency
(
i2c_t
*
i2c
)
{
if
(
i2c
==
NULL
){
return
0
;
}
return
APB_CLK_FREQ
/
(
i2c
->
dev
->
scl_low_period
.
scl_low_period
+
i2c
->
dev
->
scl_high_period
.
period
);
}
...
...
@@ -274,18 +337,23 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
i2c_t
*
i2cInit
(
uint8_t
i2c_num
,
uint16_t
slave_addr
,
bool
addr_10bit_en
)
{
i2c_t
*
i2c
=
(
i2c_t
*
)
malloc
(
sizeof
(
i2c_t
));
if
(
i2c
==
0
)
{
if
(
i2c_num
>
1
){
return
NULL
;
}
i2c
->
num
=
i2c_num
;
i2c
->
dev
=
I2C_DEV
(
i2c_num
);
i2c_t
*
i2c
=
&
_i2c_bus_array
[
i2c_num
];
if
(
i2c
->
lock
==
NULL
){
i2c
->
lock
=
xSemaphoreCreateMutex
();
if
(
i2c
->
lock
==
NULL
)
{
return
NULL
;
}
}
if
(
i2c
->
num
==
0
)
{
if
(
i2c
_
num
==
0
)
{
SET_PERI_REG_MASK
(
DPORT_PERIP_CLK_EN_REG
,
DPORT_I2C_EXT0_CLK_EN
);
CLEAR_PERI_REG_MASK
(
DPORT_PERIP_RST_EN_REG
,
DPORT_I2C_EXT0_RST
);
}
else
if
(
i2c
->
num
==
1
)
{
}
else
{
SET_PERI_REG_MASK
(
DPORT_PERIP_CLK_EN_REG
,
DPORT_I2C_EXT1_CLK_EN
);
CLEAR_PERI_REG_MASK
(
DPORT_PERIP_RST_EN_REG
,
DPORT_I2C_EXT1_RST
);
}
...
...
cores/esp32/esp32-hal-i2c.h
浏览文件 @
9ec43898
...
...
@@ -22,18 +22,14 @@ extern "C" {
#include "esp32-hal.h"
#include "soc/i2c_struct.h"
typedef
struct
{
i2c_dev_t
*
dev
;
uint8_t
num
;
}
i2c_t
;
struct
i2c_struct_t
;
typedef
struct
i2c_struct_t
i2c_t
;
i2c_t
*
i2cInit
(
uint8_t
i2c_num
,
uint16_t
slave_addr
,
bool
addr_10bit_en
);
void
i2cSetFrequency
(
i2c_t
*
i2c
,
uint32_t
clk_speed
);
uint32_t
i2cGetFrequency
(
i2c_t
*
i2c
);
void
i2cResetFiFo
(
i2c_t
*
i2c
);
void
i2cAttachSCL
(
i2c_t
*
i2c
,
int8_t
scl
);
void
i2cDetachSCL
(
i2c_t
*
i2c
,
int8_t
scl
);
void
i2cAttachSDA
(
i2c_t
*
i2c
,
int8_t
sda
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录