利用DM6437的McBSP配置SPI与ARM_S2440通信
时间:11-21
来源:互联网
点击:
McBSP是多通道缓冲串行口,DM6437提供了McBSP0&McBSP1两个串行口,每个串行口有7个管脚,可以支持多通道串行数据通信。
MCBSP的内部框图:
这两个端口也支持时钟停止模式,内部FSR与FSX、CLKX与CLKR连接在一起,这时候DX为MOSI,,DR为MISO,CLKX为SCK和FSX为nSS。
配置SPI口要注意的地方:通信模式选择要一致;SPI提供了四种通信模式:SPI0、SPI1、SPI2、SPI3。
McBSP通过配置CLKSTP与CLKXP来设置这四种模式:
一般而言SPI0模式采用的多一些。
SPI初始化步骤:
在这之前还有两个操作必须完成,DM6437的管脚复用设置为McBSP模式、McBSP的IO上电。(可以直接写相关寄存器、或者调用CSL函数),管脚复用只是设置DSP芯片管脚的引出方式,McBSP会有一个特殊情况,需要检测第一个帧同步信号;这个时候就可以复用FSX脚为GPIO脚,用GPIO来检测信号的变化,因此我们有理由相信无论用户采用配置出来是什么形态,内部这些脚其实是连在一起的。另外还申明一个误区:管脚复用和接口寄存器配置并没有关系,用户可以随时配置McBSP接口的相关寄存器,而不需要指定这些脚已经映射为McBSP管脚;当然还是得满足IO上拉的条件。
DM6437 SPI Master Config
DM6437 SPI Slaver Config
编写程序可以根据CSL库提供的函数,可能看到TI针对DM6437不再提供CSL驱动了,而是提供PSP驱动;但是这话不绝对,TI还是有DM6437可用的CSL库函数可以用,但是对我而言采用的是CSL提供的定义,自己编写函数;因为我找到了CSL支持的寄存器数据结构,但是没有找到相应的CSL函数说明,没有看到函数原型。
配置SPI口其实是很简单的,虽然我花费了太多的时间,这个最后我会说明,自己配置寄存器,可以很简单的直接给寄存器赋值,只要计算好该寄存器最后的值是什么直接赋值就可以了,但是需要注意复位脚设置什么的。。。该延时的要延时。这种寄存器配置一般而言没有什么先后顺序,没有什么要求;有要求的文档会有标注。如果不是一次性设定寄存器的值,那么在设置寄存器的时候一定要很小心取与取或的时候不要覆盖了前面的设置;这个因为我第一次是一位一位设置的,没有注意;到得到的和自己想要的完成是两回事。推荐一次性设置,当然可读性不就会这么好,可读性可以在程序跑通了再追求。
PSP_103什么版本的,如果自己电脑上面正好有这个驱动,那么直接调用,那就可以很简单了,和填空差不多了。LLC提供了底层驱动的,这个部分和自己配置寄存器一样的道理,DDC为驱动核心层,提供了OS与底层的交互,也就是我们常说的PSP驱动了;BIOS是上层系统层调用了。如果对PSP熟悉,那么可以自己决定程序写在哪一层,这个就是DM6437与DM642最大的不同。一般而言,我喜欢直接操作底层,从DM642养成的习惯。
另外说一下SPI数据通信的能力:
如果主设备采用内部时钟,则SPI内部时钟为CPU时钟/6,因为主设备和从设备要保持同步,却又采用各自的时钟,所以必须保证从设备拥有同步能力,从设备的时钟必须大于主设备时钟8倍,从设备通常默认设置到最大时钟能力、即CLKDVG=1。
另外数据的传输方式也会对数据通信能力有很大引向,McBSP提供了三种方式:CPU查询模式、CPU中断模式、EDMA3模式。采用EDMA3模式可以获得最大的数据通信能力,当然驱动编写就复杂一些,如果采用PSP倒也罢了。
最后说一下在调试中遇到的问题:
1) 配置寄存器,一位一位配置,得到很意外的结果,最后一步一步跟踪才找到原因。
2) 根据文档配置SPI口,但是就是不能正常通信。后来查找SPI协议,了解了SPI口相关知识,才知道CLKXP并不能随意配置
3) 配置好SPI口,左看右看程序没有问题,但是就是不能正常通信,逐个检测管脚状态,发现DR脚,没有连接时,都有波形输出,倒是数据采样不对,换另一个端口,终于正常通信了。
void SPI_Slave_Init ( unsigned long Bits )
{
unsigned long i;
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_FRST,RESET); //frame sync reset
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_XRST,DISABLE); //transmitter reset
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_RRST,DISABLE); //receiver reset
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_GRST,CLKG); //SRGR reset
//serial port control register SPCR
mcbsp0Regs->SPCR = CSL_FMKT(MCBSP_SPCR_CLKSTP,DELAY); //In SPI mode, data sampled on rising edge with delay
//pin control register
mcbsp0Regs->PCR = CSL_FMKT(MCBSP_PCR_FSXM,EXTERNAL) //external frame sync
| CSL_FMKT(MCBSP_PCR_CLKXM,INPUT) //trans clock mode
| CSL_FMKT(MCBSP_PCR_FSXP,ACTIVELOW); //active low
//sample rate generator SRGR
mcbsp0Regs->SRGR = CSL_FMKT(MCBSP_SRGR_CLKSM,INTERNAL) //internal clock
| CSL_FMK(MCBSP_SRGR_CLKGDV,1); //clock divider value
switch ( Bits )
{
case SPI_8BIT:
// receive control register
mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,8BIT); //receive word 8bit
//transmit control register
mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,8BIT); //trans word 8bit
break;
case SPI_12BIT:
// receive control register
mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,12BIT); //receive word 12bit
//transmit control register
mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,12BIT); //trans word 12bit
break;
case SPI_16BIT:
// receive control register
mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,16BIT); //receive word 16bit
//transmit control register
mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,16BIT); //trans word 16bit
break;
case SPI_20BIT:
// receive control register
mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,20BIT); //receive word 20bit
//transmit control register
mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,20BIT); //trans word 20bit
break;
case SPI_24BIT:
// receive control register
mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,24BIT); //receive word 24bit
//transmit control register
mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,24BIT); //trans word 24bit
break;
case SPI_32BIT:
// receive control register
mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,32BIT); //receive word 32bit
//transmit control register
mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,32BIT); //trans word 32bit
break;
default:;
}
//start the mcbsp running
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_GRST,CLKG); //SRGR out of reset
for ( i = 0; i < 200; i++ ) { i++; }
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_RRST,ENABLE); //receiver enable
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_XRST,ENABLE); //transmitter enable
for ( i = 0; i < 200; i++ ) { i++; }
CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_FRST,FSG); //enable frame sync
}
MCBSP的内部框图:
这两个端口也支持时钟停止模式,内部FSR与FSX、CLKX与CLKR连接在一起,这时候DX为MOSI,,DR为MISO,CLKX为SCK和FSX为nSS。
配置SPI口要注意的地方:通信模式选择要一致;SPI提供了四种通信模式:SPI0、SPI1、SPI2、SPI3。
McBSP通过配置CLKSTP与CLKXP来设置这四种模式:
一般而言SPI0模式采用的多一些。
SPI初始化步骤:
在这之前还有两个操作必须完成,DM6437的管脚复用设置为McBSP模式、McBSP的IO上电。(可以直接写相关寄存器、或者调用CSL函数),管脚复用只是设置DSP芯片管脚的引出方式,McBSP会有一个特殊情况,需要检测第一个帧同步信号;这个时候就可以复用FSX脚为GPIO脚,用GPIO来检测信号的变化,因此我们有理由相信无论用户采用配置出来是什么形态,内部这些脚其实是连在一起的。另外还申明一个误区:管脚复用和接口寄存器配置并没有关系,用户可以随时配置McBSP接口的相关寄存器,而不需要指定这些脚已经映射为McBSP管脚;当然还是得满足IO上拉的条件。
DM6437
DM6437
编写程序可以根据CSL库提供的函数,可能看到TI针对DM6437不再提供CSL驱动了,而是提供PSP驱动;但是这话不绝对,TI还是有DM6437可用的CSL库函数可以用,但是对我而言采用的是CSL提供的定义,自己编写函数;因为我找到了CSL支持的寄存器数据结构,但是没有找到相应的CSL函数说明,没有看到函数原型。
配置SPI口其实是很简单的,虽然我花费了太多的时间,这个最后我会说明,自己配置寄存器,可以很简单的直接给寄存器赋值,只要计算好该寄存器最后的值是什么直接赋值就可以了,但是需要注意复位脚设置什么的。。。该延时的要延时。这种寄存器配置一般而言没有什么先后顺序,没有什么要求;有要求的文档会有标注。如果不是一次性设定寄存器的值,那么在设置寄存器的时候一定要很小心取与取或的时候不要覆盖了前面的设置;这个因为我第一次是一位一位设置的,没有注意;到得到的和自己想要的完成是两回事。推荐一次性设置,当然可读性不就会这么好,可读性可以在程序跑通了再追求。
PSP_103什么版本的,如果自己电脑上面正好有这个驱动,那么直接调用,那就可以很简单了,和填空差不多了。LLC提供了底层驱动的,这个部分和自己配置寄存器一样的道理,DDC为驱动核心层,提供了OS与底层的交互,也就是我们常说的PSP驱动了;BIOS是上层系统层调用了。如果对PSP熟悉,那么可以自己决定程序写在哪一层,这个就是DM6437与DM642最大的不同。一般而言,我喜欢直接操作底层,从DM642养成的习惯。
另外说一下SPI数据通信的能力:
如果主设备采用内部时钟,则SPI内部时钟为CPU时钟/6,因为主设备和从设备要保持同步,却又采用各自的时钟,所以必须保证从设备拥有同步能力,从设备的时钟必须大于主设备时钟8倍,从设备通常默认设置到最大时钟能力、即CLKDVG=1。
另外数据的传输方式也会对数据通信能力有很大引向,McBSP提供了三种方式:CPU查询模式、CPU中断模式、EDMA3模式。采用EDMA3模式可以获得最大的数据通信能力,当然驱动编写就复杂一些,如果采用PSP倒也罢了。
最后说一下在调试中遇到的问题:
1)
2)
3)
void SPI_Slave_Init ( unsigned long Bits )
{
}
DM6437McBSPSPIARMS2440通 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)