| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- /******************************************************************************
- 版权所有:
- 文件名称: dspi.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-19
- 功能说明: dspi驱动程序。
- 其它说明:
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "head.h"
- /*------------------------------- 宏定义 --------------------------------------
- */
- //DSPI内部RAM地址
- //四个DSPI模块地址
- #define DSPI0_MODULE_ADDRESS 0xFC05C000
- #define DSPI1_MODULE_ADDRESS 0xFC03C000
- #define DSPI2_MODULE_ADDRESS 0xEC038000
- #define DSPI3_MODULE_ADDRESS 0xEC03C000
- #if (CFG_DSPI_INDEX == 0)
- #define DSPI_PM_REG MCF_PMM_PPMCR0
- #define DSPI_PM_INDEX 23
- #elif (CFG_DSPI_INDEX == 1)
- #define DSPI_PM_REG MCF_PMM_PPMCR0
- #define DSPI_PM_INDEX 15
- #endif
- /*------------------------------ 全局变量 -------------------------------------
- */
- //总线占用状态
- int gh_dspi = 0;
- /*------------------------------ 函数声明 -------------------------------------
- */
- /*------------------------------ 外部函数 -------------------------------------
- */
- /******************************************************************************
- 函数名称: dspi_init
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-19
- 函数说明: qspi初始化。
- 参数说明: 无
- 返回值: 成功返回0.
- 修改记录:
- */
- #define _MCF_DSPI_MCR(x) (*(vuint32*)(0xEC038000 + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- #define _MCF_DSPI_TCR(x) (*(vuint32*)(0xEC038008 + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- #define _MCF_DSPI_RSER(x) (*(vuint32*)(0xEC038030 + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- #define _MCF_DSPI_CTAR1(x) (*(vuint32*)(0xEC038010 + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- #define _MCF_DSPI_SR(x) (*(vuint32*)(0xEC03802C + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- #define _MCF_DSPI_PUSHR(x) (*(vuint32*)(0xEC038034 + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- #define _MCF_DSPI_POPR(x) (*(vuint32*)(0xEC038038 + ((x<2)? (0x10024000 + ((x)*0x4000) - ((x)*0x24000)) : ((x-2)*0x4000))))
- int dspi_init(void)
- {
- #if 0
- // SPI总线初始化前,先打开ESAM模块的电源,解决esam模块有时工作不正常的问题。
- // 上电并延时1ms
- GPIO_ESAM_POWER_INIT();
- ustimer_delay(USTIMER_MS*10);
-
- //模块打开
- DSPI_PM_REG = DSPI_PM_INDEX;
-
- //使用GPIO控制CS
- GPIO_DSPI_CS_ESAM_INIT();
- // 设置为DSPI管脚
- #if (CFG_DSPI_INDEX == 0)
- MCF_PAD_PAR_DSPIOWH = 0xFC;
- MCF_PAD_PAR_DSPIOWL = 0;
- MCF_PAD_SRCR_DSPIOW = 0x01; // 调整管脚驱动能力,2太强,过冲太厉害,改为1
- #elif (CFG_DSPI_INDEX == 1)
- MCF_PAD_PAR_SDHCH |= 0x01;
- MCF_PAD_PAR_SDHCL |= 0X05;
- MCF_PAD_SRCR_SDHC = 0x1; // 调整管脚驱动能力,2太强,过冲太厉害,改为1
- #endif
-
- //初始化TCR寄存器
- _MCF_DSPI_TCR(CFG_DSPI_INDEX) = 0;
-
- //初始化MCR寄存器
- _MCF_DSPI_MCR(CFG_DSPI_INDEX) = 0;
-
- //设置模式寄存器
- _MCF_DSPI_MCR(CFG_DSPI_INDEX) = MCF_DSPI_MCR_MSTR
- //| MCF_DSPI_MCR_SMPL_PT(x)
- //| MCF_DSPI_MCR_SMPL_PT_0CLK
- //| MCF_DSPI_MCR_SMPL_PT_1CLK
- //| MCF_DSPI_MCR_SMPL_PT_2CLK
- | MCF_DSPI_MCR_CLR_RXF
- | MCF_DSPI_MCR_CLR_TXF
- | MCF_DSPI_MCR_DIS_RXF // 禁止接收FIFO,打开后,接收数据前请FIFO会导致出错
- | MCF_DSPI_MCR_DIS_TXF
- //| MCF_DSPI_MCR_MDIS
- //| MCF_DSPI_MCR_PCSIS0;
- // | MCF_DSPI_MCR_ROOE
- //| MCF_DSPI_MCR_MTFE
- //| MCF_DSPI_MCR_FRZ
- //| MCF_DSPI_MCR_DCONF(x)
- //| MCF_DSPI_MCR_CONT_SCKE;
- // | MCF_DSPI_MCR_HALT
- | MCF_DSPI_MCR_PCSIS1;
- //| MCF_DSPI_MCR_PCSIS2;
- // MCF_DSPI_MCR_PCSIS3;
-
- //初始化DMA/中断请求选择和使能寄存器
- _MCF_DSPI_RSER(CFG_DSPI_INDEX) = 0;//MCF_DSPI_RSER_EOQF_RE
- //| MCF_DSPI_RSER_TCF_RE;
- //| MCF_DSPI_RSER_TFFF_DIRS
- //| MCF_DSPI_RSER_RFDF_DIRS
- //| MCF_DSPI_RSER_TFFF_RE
- //| MCF_DSPI_RSER_RFDF_RE;
- // 频率:125M/(4*7)=4.46M.字节与字节之间延时:125M/(1*128)=1.024us.
- _MCF_DSPI_CTAR1(CFG_DSPI_INDEX) = MCF_DSPI_CTAR_BR(1)
- |MCF_DSPI_CTAR_PBR_7CLK
- // |MCF_DSPI_CTAR_PCSSCK(1)
- // |MCF_DSPI_CTAR_CSSCK(1)
- |MCF_DSPI_CTAR_PASC_1CLK
- |MCF_DSPI_CTAR_ASC(3)
- |MCF_DSPI_CTAR_PDT_1CLK
- |MCF_DSPI_CTAR_DT(6)
- //|MCF_DSPI_CTAR_LSBFE
- |MCF_DSPI_CTAR_CPOL // 空闲时,时钟为高
- //|MCF_DSPI_CTAR_DBR
- |MCF_DSPI_CTAR_CPHA // 时钟相位
- |MCF_DSPI_CTAR_FMSZ(7);
-
- _MCF_DSPI_SR(CFG_DSPI_INDEX) = MCF_DSPI_SR_EOQF
- |MCF_DSPI_SR_TCF;
- #endif
- return 0;
- }
- /******************************************************************************
- 函数名称: dspi_open
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-19
- 函数说明: 打开一个DSPI设备,所有的DSPI设备互斥,一次只能打开一个,在这个函数
- 主要是根据设备的属性,设置DSPI的波特率、CLK极性、CLK相位,并使相应
- 的片选有效。
-
- 注意:此函数在资源竞争问题上,有一定的系统要求,如果要求不满足,用户应
- 自己处理资源竞争问题.这个要求为:系统中每个任务(一个中断服务程序也算
- 一个任务)都具有唯一优先级.目前UT800S的系统满足这个条件.
- 参数说明:
- dspi_id: 指定需要打开DSPI设备的标识符(以DSPI_ID_开头)。
- 返回值:
- >=0 : 打开设备的句柄
- <0 : 打开失败。
- 修改记录:
- */
- int dspi_open(int dspi_id)
- {
- //如果QSPI总线空闲,占有它。
- if(gh_dspi == 0)
- gh_dspi = dspi_id;
- else
- return -1;
-
- //解决资源竞争问题,如果两个值不相等,说明在竞争中失败,退出。
- if(gh_dspi != dspi_id)
- {
-
- return -2;
- }
-
- switch(dspi_id)
- {
- case DSPI_ID_ESAM:
- // 片选有效
- //GPIO_DSPI_CS_ESAM_LOW();
- //ustimer_delay(4*USTIMER_US);
-
- break;
- default:
- gh_dspi = 0;
- return -3;
- }
-
- return dspi_id;
- }
- /******************************************************************************
- 函数名称: dspi_close
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-21
- 函数说明: 关闭一个DSPI设备。
- 参数说明:
- h_dspi:关闭设备的句柄。
- 返回值: 成功返回0.
- 修改记录:
- */
- int dspi_close(int h_dspi)
- {
- if(h_dspi != gh_dspi)
- {
-
- return -1;
- }
-
- switch(h_dspi)
- {
- case DSPI_ID_ESAM:
- //片选无效
- //GPIO_DSPI_CS_ESAM_HIGH();
-
- break;
- default:
- return -2;
- }
-
- gh_dspi = 0;
-
- return 0;
- }
- /******************************************************************************
- 函数名称: dspi_read
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-21
- 函数说明: 从DSPI总线上读取数据。
- 参数说明:
- h_dspi(in):DSPI设备句柄。.
- buffer(out):读出数据的buffer。
- length(in): 需要读出数据的长度。
- 返回值: 成功返回0.
- 修改记录:
- */
- int dspi_read(int h_dspi,unsigned char *buffer, uint32_t length)
- {
- if(h_dspi != gh_dspi || buffer == 0)
- {
- return -1;
- }
- #if 0
- // 清空接收buffer
- _MCF_DSPI_MCR(CFG_DSPI_INDEX) |= MCF_DSPI_MCR_CLR_RXF;
-
- while(length)
- {
- //执行命令
- _MCF_DSPI_PUSHR(CFG_DSPI_INDEX) = MCF_DSPI_PUSHR_CTAS(1); // 开始执行
- while (!(_MCF_DSPI_SR(CFG_DSPI_INDEX) & MCF_DSPI_SR_TCF)) ; // 等待结束
- _MCF_DSPI_SR(CFG_DSPI_INDEX) = MCF_DSPI_SR_TCF; // 清除标志
-
- *buffer++ = (unsigned char)_MCF_DSPI_POPR(CFG_DSPI_INDEX);
- //长度减放在这个地方,不放在while条件中,否则由于编译器的bug,
- //会导致程序流程执行不正确。
- length--;
- }
- #endif
- return 0;
- }
- /******************************************************************************
- 函数名称: dspi_write
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-21
- 函数说明: 写数据到QSPI总线。
- 参数说明:
- h_dspi(in):DSPI设备句柄。.
- buffer(in):写入数据的buffer。
- length(in): 需要写入数据的长度。
- 返回值: 成功返回0.
- 修改记录:
- */
- int dspi_write(int h_dspi,unsigned char *buffer, uint32_t length)
- {
- #if 0
- if(h_dspi != gh_dspi || buffer == 0)
- {
- return -1;
- }
-
- while(length)
- {
- _MCF_DSPI_PUSHR(CFG_DSPI_INDEX) = MCF_DSPI_PUSHR_CTAS(1) | (unsigned char)(*buffer++);
- while (!(_MCF_DSPI_SR(CFG_DSPI_INDEX) & MCF_DSPI_SR_TCF)) ; // 等待结束
- _MCF_DSPI_SR(CFG_DSPI_INDEX) = MCF_DSPI_SR_TCF;
-
- //长度减放在这个地方,不放在while条件中,否则由于编译器的bug,
- //会导致程序流程执行不正确。
- length--;
- }
- #endif
- return 0;
- }
- /******************************************************************************
- 函数名称: dspi_dummy_byte
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2008-08-21
- 函数说明: 往SPI总线上发空的CLOCK。
- 参数说明:
- h_dspi(in):DSPI设备句柄。.
- length(in): 需要发空CLOCK的长度,以BYTE为单位。
- 返回值: 成功返回0.
- 修改记录:
- */
- int dspi_dummy_byte(int h_dspi,uint32_t length)
- {
- if(h_dspi != gh_dspi)
- {
-
- return -1;
- }
- #if 0
- while(length)
- {
- //执行命令
- _MCF_DSPI_PUSHR(CFG_DSPI_INDEX) = MCF_DSPI_PUSHR_CTAS(1); // 开始执行
- while (!(_MCF_DSPI_SR(CFG_DSPI_INDEX) & MCF_DSPI_SR_TCF)) ; // 等待结束
- _MCF_DSPI_SR(CFG_DSPI_INDEX) = MCF_DSPI_SR_TCF; // 清除标志
-
-
- //长度减放在这个地方,不放在while条件中,否则由于编译器的bug,
- //会导致程序流程执行不正确。
- length--;
- }
- #endif
- return 0;
- }
- void dspi_esam_cs(int cs)
- {
- #if 0
- if(cs)
- {
- GPIO_DSPI_CS_ESAM_HIGH();
- ustimer_delay(11*USTIMER_US);
- }
- else
- {
- GPIO_DSPI_CS_ESAM_LOW();
- ustimer_delay(51*USTIMER_US);
- }
- #endif
- }
- u8 dspi_esam_send(u8 c)
- {
- #if 0
- u32 flag;
- // 发送数据、接收数据字节间延时至少设为 1μs。
- ustimer_delay(USTIMER_US);
-
- _MCF_DSPI_PUSHR(CFG_DSPI_INDEX) = MCF_DSPI_PUSHR_CTAS(1) | (unsigned char)(c);
- flag = (MCF_DSPI_SR_TCF | MCF_DSPI_SR_RFDF);
- while ((_MCF_DSPI_SR(CFG_DSPI_INDEX) & flag) != flag) ; // 等待结束
- _MCF_DSPI_SR(CFG_DSPI_INDEX) = MCF_DSPI_SR_TCF;
- c = (unsigned char)_MCF_DSPI_POPR(CFG_DSPI_INDEX);
- #endif
- return c;
- }
- u8 dspi_esam_recv(void)
- {
- #if 0
- u8 c;
- u32 flag;
- // 发送数据、接收数据字节间延时至少设为 1μs。
- ustimer_delay(USTIMER_US);
- // 清空接收buffer
- // 以下语句必须屏蔽。在接收FIFO打开的情况下,如果在此处清BUF,在非常罕见的情况下会出错,具体原因未知。
- // _MCF_DSPI_MCR(CFG_DSPI_INDEX) |= MCF_DSPI_MCR_CLR_RXF;
- //执行命令
- _MCF_DSPI_PUSHR(CFG_DSPI_INDEX) = MCF_DSPI_PUSHR_CTAS(1); // 开始执行
- flag = (MCF_DSPI_SR_TCF | MCF_DSPI_SR_RFDF);
- while ((_MCF_DSPI_SR(CFG_DSPI_INDEX) & flag) != flag) ; // 等待结束
- _MCF_DSPI_SR(CFG_DSPI_INDEX) = MCF_DSPI_SR_TCF; // 清除标志
-
- c = (unsigned char)_MCF_DSPI_POPR(CFG_DSPI_INDEX);
- return c;
- #endif
- return 0;
- }
- /*------------------------------ 内部函数 -------------------------------------
- */
- /*------------------------------ 测试函数 -------------------------------------
- */
- /*------------------------------ 文件结束 -------------------------------------
- */
-
|