2806
- 收藏
- 点赞
- 分享
- 举报
【Hi3516DV300】之SPI的实现
1 查询SPI相关的寄存器
《用户指南.pdf》和《3516DV300_PINOUT_EN.xlsx》查询如下
/*
SPI0 基地址是 0x120C_0000
SPI1 基地址是 0x120C_1000
SPI2 基地址是 0x120C_2000
*/
#define SSP_BASE (0x120c1000)
/*
SPI1 pinmux
*/
#define SPI1_SCLK (0x112F0020)
#define SPI1_SDO (0x112F0024)
#define SPI1_CSN0 (0x112f0028)
#define SPI1_SDI (0x112F002C)
/*
PERI_CRG111 - SPI Clock Control
*/
#define PERI_CRG111 (0x120101BC)
/*
MISC_CTRL0 - SP1_CSN0 Check
*/
#define MISC_CTRL0 (0x12030000+0x0000)
#define SSP_SIZE 0x1000 // 4KB
#define DEFAULT_MD_LEN (128)
#define IO_ADDRESS_VERIFY(x) (x)
/* SSP register definition .*/
#define SSP_CR0 IO_ADDRESS_VERIFY(SSP_BASE + 0x00)
#define SSP_CR1 IO_ADDRESS_VERIFY(SSP_BASE + 0x04)
#define SSP_DR IO_ADDRESS_VERIFY(SSP_BASE + 0x08)
#define SSP_SR IO_ADDRESS_VERIFY(SSP_BASE + 0x0C)
#define SSP_CPSR IO_ADDRESS_VERIFY(SSP_BASE + 0x10)
#define SSP_IMSC IO_ADDRESS_VERIFY(SSP_BASE + 0x14)
#define SSP_RIS IO_ADDRESS_VERIFY(SSP_BASE + 0x18)
#define SSP_MIS IO_ADDRESS_VERIFY(SSP_BASE + 0x1C)
#define SSP_ICR IO_ADDRESS_VERIFY(SSP_BASE + 0x20)
#define SSP_DMACR IO_ADDRESS_VERIFY(SSP_BASE + 0x24)
#define SSP_SPITXFIFOCR IO_ADDRESS_VERIFY(SSP_BASE + 0x28)
#define SSP_SPIRXFIFOCR IO_ADDRESS_VERIFY(SSP_BASE + 0x2C)
#define SPI_SR_BSY (0x1 << 4)/* spi busy flag */
#define SPI_SR_TFE (0x1 << 0)/* Whether to send fifo is empty */
#define SPI_DATA_WIDTH (9)
#define SPI_SPO (1)/* 极性 */
#define SPI_SPH (1)/* 相性 */
#define SPI_SCR (0)//(8)
#define SPI_CPSDVSR (2)//(8)
#define SPI_FRAMEMODE (0)
#define MAX_WAIT 10000
2 SPI的管脚复用
static void spi1_pinmux()
{
ssp_writew(SPI1_SCLK, 0x4f1);
ssp_writew(SPI1_SDO, 0x4f1);
ssp_writew(SPI1_SDI, 0x4f1);
spi1_csn0_pinmux();
printf("spi1_pinmux\n");
}
3 SPI的时钟开启
独立软复位:由寄存器 PERI_CRG111 的 bit[17:15] 控制。相应位写“ 0 ”, SPI 退出软复位;相应位写“ 1 ”, SPI 进入软复位。上电缺省值为 0 。
时钟门控:由寄存器 PERI_CRG111 的 bit[14:12] 控制。相应位写“ 0 ”,关闭时钟;相应位写“ 1 ”,打开时钟。上电缺省值为 1 。
PERI_CRG111的第13bit为SPI1始终们控配置寄存器
0: 关闭时钟
1: 打开时钟
static void spi1_open_clock()
{
unsigned int peri_cfg111;
ssp_readw(PERI_CRG111, peri_cfg111);
ssp_writew(PERI_CRG111, peri_cfg111|0x1<<13);
printf("spi1_open_clock\n");
}
4 SPI1_CSN0启用和配置
MISC_CTRL0的第2bit为SPI1信号输出片选选择
0: SPI1_CSN0
1: SPI1_CSN1
MISC_CTRL0的第3bit为SPI1片选信号0极性控制
0: SPI1_CSN0低有效
1: SPI1_CSN0高有效
static void spi1_csn0_pinmux()
{
// 复选spi_csn0
ssp_writew(SPI1_CSN0, 0x0501);
// 配置csn0低有效 且选择片选0
unsigned int misc_ctrl0;
ssp_readw(MISC_CTRL0, misc_ctrl0);
misc_ctrl0 &= ~(0x1<<3); // 低有效
misc_ctrl0 &= ~(0x1<<2); // 片选0
ssp_writew(MISC_CTRL0, misc_ctrl0);
}
5 实现读写寄存器函数
#ifdef __HuaweiLite__
#define ssp_readw(addr,ret) (ret =(*(volatile unsigned int *)(addr)))
#define ssp_writew(addr,value) ((*(volatile unsigned int *)(addr)) = (value))
#else
static const char dev[]="/dev/mem";
static void write_reg(unsigned int Addr, unsigned int Value)
{
int fd = open (dev, O_RDWR | O_SYNC);
if (fd < 0)
{
printf("open %s error!\n", dev);
return ;
}
/* addr align in page_size(4K) */
unsigned long phy_addr_in_page;
unsigned long page_diff;
phy_addr_in_page = Addr & PAGE_SIZE_MASK;
page_diff = Addr - phy_addr_in_page;
/* size in page_size */
unsigned long size_in_page;
unsigned long size = PAGE_SIZE;
size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
void *addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page);
if (addr == MAP_FAILED)
{
printf("mmap @ 0x%x error!\n", phy_addr_in_page);
close(fd);
return;
}
unsigned int *addr_cur = (unsigned int *)(addr+page_diff);
*addr_cur = Value;
/* munmap */
if(munmap(addr, size_in_page) != 0 )
{
printf("munmap failed!\n");
}
close(fd);
//printf("ssp_write_reg %x %d\n", Addr, Value);
}
static unsigned int read_reg(unsigned int Addr)
{
unsigned int Value = 0;
int fd = open (dev, O_RDWR | O_SYNC);
if (fd < 0)
{
printf("open %s error!\n", dev);
return -1;
}
/* addr align in page_size(4K) */
unsigned long phy_addr_in_page;
unsigned long page_diff;
phy_addr_in_page = Addr & PAGE_SIZE_MASK;
page_diff = Addr - phy_addr_in_page;
/* size in page_size */
unsigned long size_in_page;
unsigned long size = PAGE_SIZE;
size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
void *addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page);
if (addr == MAP_FAILED)
{
printf("mmap @ 0x%x error!\n", phy_addr_in_page);
close(fd);
return -1;
}
unsigned int *addr_cur = (unsigned int *)(addr+page_diff);
Value = *addr_cur;
/* munmap */
if(munmap(addr, size_in_page) != 0 )
{
printf("munmap failed!\n");
}
close(fd);
//printf("ssp_read_reg %x %d\n", Addr, Value);
return Value;
}
#define ssp_readw(addr,ret) (ret=read_reg(addr))
#define ssp_writew(addr,value) (write_reg(addr, value))
#endif
未完待续……
《用户指南.pdf》和《3516DV300_PINOUT_EN.xlsx》查询如下
/*
SPI0 基地址是 0x120C_0000
SPI1 基地址是 0x120C_1000
SPI2 基地址是 0x120C_2000
*/
#define SSP_BASE (0x120c1000)
/*
SPI1 pinmux
*/
#define SPI1_SCLK (0x112F0020)
#define SPI1_SDO (0x112F0024)
#define SPI1_CSN0 (0x112f0028)
#define SPI1_SDI (0x112F002C)
/*
PERI_CRG111 - SPI Clock Control
*/
#define PERI_CRG111 (0x120101BC)
/*
MISC_CTRL0 - SP1_CSN0 Check
*/
#define MISC_CTRL0 (0x12030000+0x0000)
#define SSP_SIZE 0x1000 // 4KB
#define DEFAULT_MD_LEN (128)
#define IO_ADDRESS_VERIFY(x) (x)
/* SSP register definition .*/
#define SSP_CR0 IO_ADDRESS_VERIFY(SSP_BASE + 0x00)
#define SSP_CR1 IO_ADDRESS_VERIFY(SSP_BASE + 0x04)
#define SSP_DR IO_ADDRESS_VERIFY(SSP_BASE + 0x08)
#define SSP_SR IO_ADDRESS_VERIFY(SSP_BASE + 0x0C)
#define SSP_CPSR IO_ADDRESS_VERIFY(SSP_BASE + 0x10)
#define SSP_IMSC IO_ADDRESS_VERIFY(SSP_BASE + 0x14)
#define SSP_RIS IO_ADDRESS_VERIFY(SSP_BASE + 0x18)
#define SSP_MIS IO_ADDRESS_VERIFY(SSP_BASE + 0x1C)
#define SSP_ICR IO_ADDRESS_VERIFY(SSP_BASE + 0x20)
#define SSP_DMACR IO_ADDRESS_VERIFY(SSP_BASE + 0x24)
#define SSP_SPITXFIFOCR IO_ADDRESS_VERIFY(SSP_BASE + 0x28)
#define SSP_SPIRXFIFOCR IO_ADDRESS_VERIFY(SSP_BASE + 0x2C)
#define SPI_SR_BSY (0x1 << 4)/* spi busy flag */
#define SPI_SR_TFE (0x1 << 0)/* Whether to send fifo is empty */
#define SPI_DATA_WIDTH (9)
#define SPI_SPO (1)/* 极性 */
#define SPI_SPH (1)/* 相性 */
#define SPI_SCR (0)//(8)
#define SPI_CPSDVSR (2)//(8)
#define SPI_FRAMEMODE (0)
#define MAX_WAIT 10000
2 SPI的管脚复用
static void spi1_pinmux()
{
ssp_writew(SPI1_SCLK, 0x4f1);
ssp_writew(SPI1_SDO, 0x4f1);
ssp_writew(SPI1_SDI, 0x4f1);
spi1_csn0_pinmux();
printf("spi1_pinmux\n");
}
3 SPI的时钟开启
独立软复位:由寄存器 PERI_CRG111 的 bit[17:15] 控制。相应位写“ 0 ”, SPI 退出软复位;相应位写“ 1 ”, SPI 进入软复位。上电缺省值为 0 。
时钟门控:由寄存器 PERI_CRG111 的 bit[14:12] 控制。相应位写“ 0 ”,关闭时钟;相应位写“ 1 ”,打开时钟。上电缺省值为 1 。
PERI_CRG111的第13bit为SPI1始终们控配置寄存器
0: 关闭时钟
1: 打开时钟
static void spi1_open_clock()
{
unsigned int peri_cfg111;
ssp_readw(PERI_CRG111, peri_cfg111);
ssp_writew(PERI_CRG111, peri_cfg111|0x1<<13);
printf("spi1_open_clock\n");
}
4 SPI1_CSN0启用和配置
MISC_CTRL0的第2bit为SPI1信号输出片选选择
0: SPI1_CSN0
1: SPI1_CSN1
MISC_CTRL0的第3bit为SPI1片选信号0极性控制
0: SPI1_CSN0低有效
1: SPI1_CSN0高有效
static void spi1_csn0_pinmux()
{
// 复选spi_csn0
ssp_writew(SPI1_CSN0, 0x0501);
// 配置csn0低有效 且选择片选0
unsigned int misc_ctrl0;
ssp_readw(MISC_CTRL0, misc_ctrl0);
misc_ctrl0 &= ~(0x1<<3); // 低有效
misc_ctrl0 &= ~(0x1<<2); // 片选0
ssp_writew(MISC_CTRL0, misc_ctrl0);
}
5 实现读写寄存器函数
#ifdef __HuaweiLite__
#define ssp_readw(addr,ret) (ret =(*(volatile unsigned int *)(addr)))
#define ssp_writew(addr,value) ((*(volatile unsigned int *)(addr)) = (value))
#else
static const char dev[]="/dev/mem";
static void write_reg(unsigned int Addr, unsigned int Value)
{
int fd = open (dev, O_RDWR | O_SYNC);
if (fd < 0)
{
printf("open %s error!\n", dev);
return ;
}
/* addr align in page_size(4K) */
unsigned long phy_addr_in_page;
unsigned long page_diff;
phy_addr_in_page = Addr & PAGE_SIZE_MASK;
page_diff = Addr - phy_addr_in_page;
/* size in page_size */
unsigned long size_in_page;
unsigned long size = PAGE_SIZE;
size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
void *addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page);
if (addr == MAP_FAILED)
{
printf("mmap @ 0x%x error!\n", phy_addr_in_page);
close(fd);
return;
}
unsigned int *addr_cur = (unsigned int *)(addr+page_diff);
*addr_cur = Value;
/* munmap */
if(munmap(addr, size_in_page) != 0 )
{
printf("munmap failed!\n");
}
close(fd);
//printf("ssp_write_reg %x %d\n", Addr, Value);
}
static unsigned int read_reg(unsigned int Addr)
{
unsigned int Value = 0;
int fd = open (dev, O_RDWR | O_SYNC);
if (fd < 0)
{
printf("open %s error!\n", dev);
return -1;
}
/* addr align in page_size(4K) */
unsigned long phy_addr_in_page;
unsigned long page_diff;
phy_addr_in_page = Addr & PAGE_SIZE_MASK;
page_diff = Addr - phy_addr_in_page;
/* size in page_size */
unsigned long size_in_page;
unsigned long size = PAGE_SIZE;
size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
void *addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page);
if (addr == MAP_FAILED)
{
printf("mmap @ 0x%x error!\n", phy_addr_in_page);
close(fd);
return -1;
}
unsigned int *addr_cur = (unsigned int *)(addr+page_diff);
Value = *addr_cur;
/* munmap */
if(munmap(addr, size_in_page) != 0 )
{
printf("munmap failed!\n");
}
close(fd);
//printf("ssp_read_reg %x %d\n", Addr, Value);
return Value;
}
#define ssp_readw(addr,ret) (ret=read_reg(addr))
#define ssp_writew(addr,value) (write_reg(addr, value))
#endif
未完待续……
我来回答
回答0个
时间排序
认可量排序
暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2020-01-16 20:24:15
-
2022-03-31 15:45:30
-
2019-10-16 14:59:34
-
2020-10-30 14:11:30
-
2019-11-25 20:18:36
-
2020-08-15 21:14:41
-
2019-10-16 10:50:21
-
2020-08-05 16:48:26
-
2020-08-27 15:49:02
-
2020-08-08 22:18:33
-
2020-04-17 17:28:00
-
2019-12-30 22:22:45
-
2024-04-19 21:04:38
-
2021-11-11 09:41:24
-
2019-06-03 11:16:42
-
2020-09-10 17:52:03
-
2020-08-19 17:17:03
-
2020-06-11 16:40:05
-
2019-05-08 09:35:42
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认