Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
天中雨水
rt-thread
提交
8d908671
R
rt-thread
项目概览
天中雨水
/
rt-thread
该项目与 Fork 源项目分叉
Fork自
RT-Thread / rt-thread
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8d908671
编写于
9月 06, 2017
作者:
勤
勤为本
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加龙芯1c硬件I2C接口
上级
2da0eae8
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
555 addition
and
2 deletion
+555
-2
bsp/ls1cdev/libraries/ls1c_gpio.c
bsp/ls1cdev/libraries/ls1c_gpio.c
+5
-2
bsp/ls1cdev/libraries/ls1c_i2c.c
bsp/ls1cdev/libraries/ls1c_i2c.c
+373
-0
bsp/ls1cdev/libraries/ls1c_i2c.h
bsp/ls1cdev/libraries/ls1c_i2c.h
+134
-0
bsp/ls1cdev/libraries/ls1c_public.c
bsp/ls1cdev/libraries/ls1c_public.c
+22
-0
bsp/ls1cdev/libraries/ls1c_public.h
bsp/ls1cdev/libraries/ls1c_public.h
+16
-0
bsp/ls1cdev/libraries/ls1c_regs.h
bsp/ls1cdev/libraries/ls1c_regs.h
+5
-0
未找到文件。
bsp/ls1cdev/libraries/ls1c_gpio.c
浏览文件 @
8d908671
...
...
@@ -211,8 +211,8 @@ unsigned int gpio_get(unsigned int gpio)
*/
void
gpio_set_irq_type
(
unsigned
int
gpio
,
gpio_irq_type_t
type
)
{
volatile
unsigned
int
*
int_pol
;
// 中断极性选择寄存器
volatile
unsigned
int
*
int_edge
;
// 中断边沿选择寄存器
volatile
unsigned
int
*
int_pol
=
NULL
;
// 中断极性选择寄存器
volatile
unsigned
int
*
int_edge
=
NULL
;
// 中断边沿选择寄存器
unsigned
int
port
=
GPIO_GET_PORT
(
gpio
);
unsigned
int
pin
=
GPIO_GET_PIN
(
gpio
);
...
...
@@ -257,6 +257,9 @@ void gpio_set_irq_type(unsigned int gpio, gpio_irq_type_t type)
*
int_pol
&=
~
(
1
<<
pin
);
*
int_edge
&=
~
(
1
<<
pin
);
break
;
default:
break
;
}
return
;
...
...
bsp/ls1cdev/libraries/ls1c_i2c.c
0 → 100644
浏览文件 @
8d908671
/*
* File : ls1c_i2c.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-09-06 勤为本 first version
*/
// 封装硬件i2c接口
#include "ls1c_public.h"
#include "ls1c_regs.h"
#include "ls1c_clock.h"
#include "ls1c_i2c.h"
#include "ls1c_delay.h"
/*
* I2C各个寄存器相对基地址的偏移
* 发送数据寄存器和接收数据寄存器的偏移是相同的
* 命令寄存器和状态寄存器的偏移是相同的,不同的是命令寄存器只写,状态寄存器只读
*/
#define LS1C_I2C_PRER_LOW_OFFSET (0) // 分频锁存器低字节寄存器偏移
#define LS1C_I2C_PRER_HIGH_OFFSET (1) // 分频锁存器高字节寄存器偏移
#define LS1C_I2C_CONTROL_OFFSET (2) // 控制寄存器偏移
#define LS1C_I2C_DATA_OFFSET (3) // 发送数据寄存器和接收数据寄存器的偏移是相同的
#define LS1C_I2C_CMD_OFFSET (4) // 命令寄存器偏移,只写
#define LS1C_I2C_STATUS_OFFSET (4) // 状态寄存器偏移,只读
// 控制寄存器的位域
#define LS1C_I2C_CONTROL_EN (0x80) // i2c模块使能
#define LS1C_I2C_CONTROL_IEN (0x40) // 中断使能
// 命令寄存器的位域
#define LS1C_I2C_CMD_START (0x90) // 产生START信号
#define LS1C_I2C_CMD_STOP (0x40) // 产生STOP信号
#define LS1C_I2C_CMD_READ (0x20) // 产生读信号,即产生ACK信号
#define LS1C_I2C_CMD_WRITE (0x10) // 产生写信号
#define LS1C_I2C_CMD_READ_ACK (0x20) // 产生ACK信号,与读信号相同
#define LS1C_I2C_CMD_READ_NACK (0x28) // 产生NACK信号
#define LS1C_I2C_CMD_IACK (0x00) // 产生中断应答信号
// 状态寄存器的位域
#define LS1C_I2C_STATUS_IF (0x01) // 中断标志位
#define LS1C_I2C_STATUS_TIP (0x02) // 指示传输的过程。1,正在传输;0,传输完成
#define LS1C_I2C_STATUS_ARBLOST (0x20) // I2C核失去I2C总线的控制权
#define LS1C_I2C_STATUS_BUSY (0x40) // I2C总线忙标志
#define LS1C_I2C_STATUS_NACK (0x80) // 应答位标志。1,没收到应答位;0,收到应答位
/*
* 获取指定i2c模块的基地址
* @I2Cx I2C模块的编号
*/
void
*
i2c_get_base
(
ls1c_i2c_t
I2Cx
)
{
void
*
base
=
NULL
;
switch
(
I2Cx
)
{
case
LS1C_I2C_0
:
base
=
(
void
*
)
LS1C_I2C0_BASE
;
break
;
case
LS1C_I2C_1
:
base
=
(
void
*
)
LS1C_I2C1_BASE
;
break
;
case
LS1C_I2C_2
:
base
=
(
void
*
)
LS1C_I2C2_BASE
;
break
;
default:
base
=
NULL
;
break
;
}
return
base
;
}
/*
* 向命令寄存器写命令
* @i2c_info_p i2c模块信息
* @cmd 命令
*/
void
i2c_cmd
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
cmd
)
{
void
*
i2c_base
=
i2c_get_base
(
i2c_info_p
->
I2Cx
);
reg_write_8
(
cmd
,
i2c_base
+
LS1C_I2C_CMD_OFFSET
);
return
;
}
/*
* 执行START命令,发送START信号
* @i2c_info_p i2c模块信息
*/
void
i2c_cmd_start
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd
(
i2c_info_p
,
LS1C_I2C_CMD_START
);
return
;
}
/*
* 执行STOP命令,发送STOP信号
* @i2c_info_p i2c模块信息
*/
void
i2c_cmd_stop
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd
(
i2c_info_p
,
LS1C_I2C_CMD_STOP
);
return
;
}
/*
* 执行写命令
* @i2c_info_p i2c模块信息
*/
void
i2c_cmd_write
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd
(
i2c_info_p
,
LS1C_I2C_CMD_WRITE
);
return
;
}
/*
* 执行读ack命令,发送读ack信号
* @i2c_info_p i2c模块信息
*/
void
i2c_cmd_read_ack
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd
(
i2c_info_p
,
LS1C_I2C_CMD_READ_ACK
);
return
;
}
/*
* 执行读nack命令,发送读nack信号
* @i2c_info_p i2c模块信息
*/
void
i2c_cmd_read_nack
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd
(
i2c_info_p
,
LS1C_I2C_CMD_READ_NACK
);
return
;
}
/*
* 发送中断应答信号
* @i2c_info_p i2c模块信息
*/
void
i2c_cmd_iack
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd
(
i2c_info_p
,
LS1C_I2C_CMD_IACK
);
return
;
}
/*
* 获取状态寄存器的值
* @i2c_info_p i2c模块信息
* @ret 状态寄存器的值
*/
unsigned
char
i2c_get_status
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
void
*
i2c_base
=
i2c_get_base
(
i2c_info_p
->
I2Cx
);
return
reg_read_8
(
i2c_base
+
LS1C_I2C_STATUS_OFFSET
);
}
/*
* Poll the i2c status register until the specified bit is set.
* Returns 0 if timed out (100 msec).
* @i2c_info_p i2c模块信息
* @bit 寄存器的某一位
* @ret true or false
*/
int
i2c_poll_status
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
long
bit
)
{
int
loop_cntr
=
20000
;
do
{
delay_us
(
1
);
}
while
((
i2c_get_status
(
i2c_info_p
)
&
bit
)
&&
(
0
<
--
loop_cntr
));
return
(
0
<
loop_cntr
);
}
/*
* 初始化指定i2c模块
* @i2c_info_p 某个i2c模块的信息
*/
void
i2c_init
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
void
*
i2c_base
=
i2c_get_base
(
i2c_info_p
->
I2Cx
);
unsigned
long
i2c_clock
=
i2c_info_p
->
clock
;
unsigned
char
ctrl
=
reg_read_8
(
i2c_base
+
LS1C_I2C_CONTROL_OFFSET
);
unsigned
long
prescale
=
0
;
/* make sure the device is disabled */
ctrl
=
ctrl
&
~
(
LS1C_I2C_CONTROL_EN
|
LS1C_I2C_CONTROL_IEN
);
reg_write_8
(
ctrl
,
i2c_base
+
LS1C_I2C_CONTROL_OFFSET
);
// 设置时钟
i2c_clock
=
MIN
(
i2c_clock
,
LS1C_I2C_CLOCK_MAX
);
// 限制在最大允许范围内
prescale
=
clk_get_apb_rate
();
prescale
=
(
prescale
/
(
5
*
i2c_clock
))
-
1
;
reg_write_8
(
prescale
&
0xff
,
i2c_base
+
LS1C_I2C_PRER_LOW_OFFSET
);
reg_write_8
(
prescale
>>
8
,
i2c_base
+
LS1C_I2C_PRER_HIGH_OFFSET
);
// 使能
i2c_cmd_iack
(
i2c_info_p
);
ctrl
=
ctrl
|
LS1C_I2C_CONTROL_EN
;
reg_write_8
(
ctrl
,
i2c_base
+
LS1C_I2C_CONTROL_OFFSET
);
return
;
}
/*
* (再发送一个字节数据之后)接收从机发送的ACK信号
* @i2c_info_p i2c模块信息
* @ret LS1C_I2C_ACK or LS1C_I2C_NACK
*/
ls1c_i2c_ack_t
i2c_receive_ack
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
ls1c_i2c_ack_t
ret
=
LS1C_I2C_NACK
;
if
(
LS1C_I2C_STATUS_NACK
&
i2c_get_status
(
i2c_info_p
))
{
ret
=
LS1C_I2C_NACK
;
}
else
{
ret
=
LS1C_I2C_ACK
;
}
return
ret
;
}
/*
* 接收数据
* @i2c_info_p i2c模块信息
* @buf 数据缓存
* @len 待接收数据的长度
*/
ls1c_i2c_ret_t
i2c_receive_data
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
*
buf
,
int
len
)
{
void
*
i2c_base
=
i2c_get_base
(
i2c_info_p
->
I2Cx
);
int
i
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
// 开始接收
if
(
i
!=
(
len
-
1
))
i2c_cmd_read_ack
(
i2c_info_p
);
else
i2c_cmd_read_nack
(
i2c_info_p
);
// 等待,直到接收完成
if
(
!
i2c_poll_status
(
i2c_info_p
,
LS1C_I2C_STATUS_TIP
))
return
LS1C_I2C_RET_TIMEOUT
;
// 读取数据,并保存
*
buf
++
=
reg_read_8
(
i2c_base
+
LS1C_I2C_DATA_OFFSET
);
}
return
LS1C_I2C_RET_OK
;
}
/*
* 发送START信号和地址
* @i2c_info_p i2c模块信息
* @slave_addr 从机地址
* @direction 数据传输方向(读、写)
*/
ls1c_i2c_ret_t
i2c_send_start_and_addr
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
slave_addr
,
ls1c_i2c_direction_t
direction
)
{
void
*
i2c_base
=
i2c_get_base
(
i2c_info_p
->
I2Cx
);
unsigned
char
data
=
0
;
// 等待i2c总线空闲
if
(
!
i2c_poll_status
(
i2c_info_p
,
LS1C_I2C_STATUS_BUSY
))
return
LS1C_I2C_RET_TIMEOUT
;
// 填充地址到数据寄存器
data
=
(
slave_addr
<<
1
)
|
((
LS1C_I2C_DIRECTION_READ
==
direction
)
?
1
:
0
);
reg_write_8
(
data
,
i2c_base
+
LS1C_I2C_DATA_OFFSET
);
// 开始发送
i2c_cmd_start
(
i2c_info_p
);
// 等待,直到发送完成
if
(
!
i2c_poll_status
(
i2c_info_p
,
LS1C_I2C_STATUS_TIP
))
return
LS1C_I2C_RET_TIMEOUT
;
return
LS1C_I2C_RET_OK
;
}
/*
* 发送数据
* @i2c_info_p i2c模块信息
* @data 待发送的数据
* @len 待发送数据的长度
*/
ls1c_i2c_ret_t
i2c_send_data
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
*
data
,
int
len
)
{
void
*
i2c_base
=
i2c_get_base
(
i2c_info_p
->
I2Cx
);
int
i
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
// 将一个字节数据写入数据寄存器
reg_write_8
(
*
data
++
,
i2c_base
+
LS1C_I2C_DATA_OFFSET
);
// 开始发送
reg_write_8
(
LS1C_I2C_CMD_WRITE
,
i2c_base
+
LS1C_I2C_CMD_OFFSET
);
// 等待,直到发送完成
if
(
!
i2c_poll_status
(
i2c_info_p
,
LS1C_I2C_STATUS_TIP
))
return
LS1C_I2C_RET_TIMEOUT
;
// 读取应答信号
if
(
LS1C_I2C_ACK
!=
i2c_receive_ack
(
i2c_info_p
))
return
len
;
}
return
LS1C_I2C_RET_OK
;
}
/*
* 发送STOP信号
* @i2c_info_p i2c模块信息
*/
void
i2c_send_stop
(
ls1c_i2c_info_t
*
i2c_info_p
)
{
i2c_cmd_stop
(
i2c_info_p
);
return
;
}
bsp/ls1cdev/libraries/ls1c_i2c.h
0 → 100644
浏览文件 @
8d908671
/*
* File : ls1c_i2c.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-09-06 勤为本 first version
*/
// 硬件i2c接口的头文件
#ifndef __OPENLOONGSON_I2C_H
#define __OPENLOONGSON_I2C_H
// I2C的时钟频率
#define LS1C_I2C_CLOCK_DEFAULT (100000) // Hz. 默认频率
#define LS1C_I2C_CLOCK_MAX (400000) // Hz, max 400 Kbits/sec
// I2C模块编号
typedef
enum
{
LS1C_I2C_0
=
0
,
LS1C_I2C_1
,
LS1C_I2C_2
}
ls1c_i2c_t
;
// I2C数据传输方向
typedef
enum
{
LS1C_I2C_DIRECTION_WRITE
=
0
,
// 主机向从机写信息
LS1C_I2C_DIRECTION_READ
,
// 主机向从机读信息
}
ls1c_i2c_direction_t
;
// 硬件I2C信息
typedef
struct
{
ls1c_i2c_t
I2Cx
;
// i2c模块编号
unsigned
long
clock
;
// i2c时钟频率,单位hz
}
ls1c_i2c_info_t
;
// I2C应答
typedef
enum
{
LS1C_I2C_ACK
=
0
,
// 收到应答
LS1C_I2C_NACK
=
1
,
// 没收到应答
}
ls1c_i2c_ack_t
;
// 函数返回值
typedef
enum
{
LS1C_I2C_RET_OK
=
0
,
// OK
LS1C_I2C_RET_TIMEOUT
,
// 超时
}
ls1c_i2c_ret_t
;
/*
* 初始化指定i2c模块
* @i2c_info_p 某个i2c模块的信息
*/
void
i2c_init
(
ls1c_i2c_info_t
*
i2c_info_p
);
/*
* (再发送一个字节数据之后)接收从机发送的ACK信号
* @i2c_info_p i2c模块信息
* @ret LS1C_I2C_ACK or LS1C_I2C_NACK
*/
ls1c_i2c_ack_t
i2c_receive_ack
(
ls1c_i2c_info_t
*
i2c_info_p
);
/*
* 接收数据
* @i2c_info_p i2c模块信息
* @buf 数据缓存
* @len 待接收数据的长度
*/
ls1c_i2c_ret_t
i2c_receive_data
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
*
buf
,
int
len
);
/*
* 发送START信号和地址
* @i2c_info_p i2c模块信息
* @slave_addr 从机地址
* @direction 数据传输方向(读、写)
*/
ls1c_i2c_ret_t
i2c_send_start_and_addr
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
slave_addr
,
ls1c_i2c_direction_t
direction
);
/*
* 发送数据
* @i2c_info_p i2c模块信息
* @data 待发送的数据
* @len 待发送数据的长度
*/
ls1c_i2c_ret_t
i2c_send_data
(
ls1c_i2c_info_t
*
i2c_info_p
,
unsigned
char
*
data
,
int
len
);
/*
* 发送STOP信号
* @i2c_info_p i2c模块信息
*/
void
i2c_send_stop
(
ls1c_i2c_info_t
*
i2c_info_p
);
#endif
bsp/ls1cdev/libraries/ls1c_public.c
浏览文件 @
8d908671
...
...
@@ -54,6 +54,28 @@ unsigned int reg_get_bit(volatile unsigned int *reg, unsigned int bit)
}
/*
* 向寄存器中写入8bit(一个字节)数据
* @data 待写入的数据
* @addr 寄存器地址
*/
void
reg_write_8
(
unsigned
char
data
,
volatile
unsigned
char
*
addr
)
{
*
addr
=
data
;
}
/*
* 从寄存器读出8bit(一个字节)数据
* @addr 寄存器地址
* @ret 读出的数据
*/
unsigned
char
reg_read_8
(
volatile
unsigned
char
*
addr
)
{
return
(
*
addr
);
}
/*
* 向寄存器中写一个32bit的数据
* @data 待写入的数据
...
...
bsp/ls1cdev/libraries/ls1c_public.h
浏览文件 @
8d908671
...
...
@@ -57,6 +57,22 @@ void reg_clr_one_bit(volatile unsigned int *reg, unsigned int bit);
unsigned
int
reg_get_bit
(
volatile
unsigned
int
*
reg
,
unsigned
int
bit
);
/*
* 向寄存器中写入8bit(一个字节)数据
* @data 待写入的数据
* @addr 寄存器地址
*/
void
reg_write_8
(
unsigned
char
data
,
volatile
unsigned
char
*
addr
);
/*
* 从寄存器读出8bit(一个字节)数据
* @addr 寄存器地址
* @ret 读出的数据
*/
unsigned
char
reg_read_8
(
volatile
unsigned
char
*
addr
);
/*
* 向寄存器中写一个32bit的数据
* @data 待写入的数据
...
...
bsp/ls1cdev/libraries/ls1c_regs.h
浏览文件 @
8d908671
...
...
@@ -111,6 +111,11 @@
#define LS1C_INT4_EDGE (0xbfd010b4)
// I2C寄存器
#define LS1C_I2C0_BASE (0xbfe58000)
#define LS1C_I2C1_BASE (0xbfe68000)
#define LS1C_I2C2_BASE (0xbfe70000)
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录