(0)TMS320C6455的SRIO模块搞定
【整理者】TIchinese.com
【提供者】花花黑黑
【详细说明】TMS320C6455的SRIO模块搞定
这个模块搞了半个月了,终于把它的4p1x模式搞定,通讯速度有效单通道可以到100MB/s。总结一下,记个流水帐吧。
1
测试TI的demo程序,是4x模式的,可以顺利的执行;
2
修改关键寄存器,配置不成功,可以通过0port的测试,但是其余三个总是调试不通过;
3
于是仔细读spru976,发现配置两个关键寄存器即可,但是其中一个是只读模式的。于是大惊,心想,莫非TI的这款C6455的rapid
IO模块有问题,怎么能对这种只读存储器进行配置呢。
4
于是再仔细阅读,找到一个SW_PORT的寄存器在文档上有代码参考,但是这款DSP没有这个寄存器,于是找到相关感觉有问题的地方总结一下,通过各种渠道联系到了TI技术支持的回应,回应中一句话,有可能文档有些问题,但是配置两个寄存器即可切换
4 port模式和 1port 模式。这些话当时真是无用的,后来发现给了我一些启示,还是解决了这个模式切换的问题。
5
然后尝试srio user guide上的代码,发现可以配置4p1x成功,但是传输数据用lsu是不能全部成功的
6
自己决心写配置初始化的代码,繁琐的寄存器一个个配置完成,调试之后发现,还是不能实现lsu的正确传输,结果是0
port有问题,1,2,3 port都可以正确传输,但是传输一定数据后 3 port 就会出问题。
7
于是又返回头来折腾了demo的代码和 user guide 上的代码,二者结合后,终于实现了
4p1x的传输模式,数据100%正确。在evm上速度很高,但是担心在自己的板子上达不到这么高的速度。
8
总结发现,最后解决问题的竟然还是利用了TI给的CSL库,不过现在知道这个方法后,自己可以写出来SRIO的初始化和LSU数据传输代码了。这也是这个采集卡上最关键的技术了,到此,告一段落。
(1)===================引无剑忍的博客的内容
TMS320C6474(六核)使用经验总结
作者:无剑忍的… 文章来源:无剑忍的博客 点击数:45 更新时间:2011-4-9
1.main函数中一般不能等待信号量,可能会被无视
2.使用SRIO在2CPU之间相互交换数据时,数据如果在L2(2级内存,6474为1M)内,则两CPU的L2地址都应设为global地址。即不能为0x08XXXXXX。
3.6474
EVM开发板,用ccs中的SRIO示例程序在2个CPU间传递数据时,最多一次传4K,最少目前设为16个,4个不稳定,建议设为256个。原因应该是每次传输一个双字,寄存器可设。4K时为512个双字。
4.1个CPU的core0运行程序中如有printf语句,自己运行速度无影响,但如果此时core1或core2空转,core0速度会变慢为大约1/4。如无printf语句,则各核速度暂无影响。
5.一些数据初始化的步骤避免放在main中,可以创建一个最高优先级的初始化任务。否则程序运行一次后,再次运行时可能崩溃。(崩溃应该发生在main运行完转到其他任务时,如在main中加一中断则不会崩溃,原因不明,应该是BIOS操作系统的BUG,貌似可以配置一选项解决(绕过)此问题。)
6.volatile只能保证读取数据时不读取cache直接读取内存。如果写入后立刻通过SRIO或DMA传输,应用BCACHE_wb立刻把cache中的数据写回内存。BCACHE_inv可使cache无效,可用于读取非volatile数据。
7.在simulater模式下,同一个CPU的core之间是不能访问对方的L2的。比如core0的L2是0x10800000起始,core1的L2是0x11800000起始,core0不能访问0x11800000起始的长度为0x100000的空间。
(2)调试时的速度:125Mx4 6 8 10都可以。
(3)传输数据一次最多4kByte,或者说是1kInt数据。
(4)测试代码来源:
http://focus.ti.com/docs/prod/folders/print/tms320c6455.html
在下面的地址下载csl
http://focus.ti.com/docs/toolsw/folders/print/sprc234.html
6455的csl即在片支持库支持的部件有如下:
Features
Supported Modules:
-
CHIP and DEVice registers
-
Interrupt Controller (NTC)
-
DDR2
-
EMIF
-
TCP2
-
VCP2
-
I2C
-
EDMA
-
McBSP
-
UHPI
-
GPIO
-
TIMER64
-
DAT
-
IDMA
-
CACHE
-
Time Stamp Counter (TSC)
-
UTOPIA2
-
SRIO
-
Ethernet MAC
-
PCI
-
POWERDOWN
-
BW MNGMT
-
MEMPROT
-
PLL Controller
可以看到上面有srio的csl历程。但是这和不是很爽。建议参考下面的例程:
#include
#include
#include
#include
#include
#define SRIO_SET_DEVICE_ID(base_dev_id,
large_base_dev_id) \
CSL_FMK(SRIO_BASE_ID_BASE_DEVICEID,
base_dev_id)
| \
CSL_FMK(SRIO_BASE_ID_LARGE_BASE_DEVICEID,
large_base_dev_id)
#define LARGE_DEV_ID 0xBEEF
#define SMALL_DEV_ID 0xAB
#define SRIO_PKT_TYPE_NWRITE 0x54
#define
SRIO_PKT_TYPE_NREAD 0x24
#define SELECTED_LSU 0
#define TRANSFER_SIZE 256
static CSL_SrioHwSetup setup = CSL_SRIO_HWSETUP_DEFAULTS;
CSL_SrioContext context;
CSL_Status status;
CSL_SrioHandle hSrio;
CSL_SrioObj srioObj;
CSL_InstNum srioNum
= 0;
CSL_SrioParam srioParam;
CSL_SrioPortData response;
void srio_Create_Setup (
CSL_SrioHwSetup
*pSetup,
int bootcomplete,
int blken
)
{
Uint32
index;
pSetup->perEn
= 1;
pSetup->periCntlSetup.swMemSleepOverride
= 1;
pSetup->periCntlSetup.loopback
= 0;
pSetup->periCntlSetup.bootComplete
= bootcomplete;
pSetup->periCntlSetup.txPriority2Wm
= CSL_SRIO_TX_PRIORITY_WM_0;
pSetup->periCntlSetup.txPriority1Wm
= CSL_SRIO_TX_PRIORITY_WM_0;
pSetup->periCntlSetup.txPriority0Wm
= CSL_SRIO_TX_PRIORITY_WM_0;
pSetup->periCntlSetup.busTransPriority
= CSL_SRIO_BUS_TRANS_PRIORITY_1;
pSetup->periCntlSetup.bufferMode
= CSL_SRIO_1X_MODE_PRIORITY;
pSetup->periCntlSetup.prescalar
= CSL_SRIO_CLK_PRESCALE_6;
pSetup->periCntlSetup.pllEn
= CSL_SRIO_PLL1_ENABLE;
pSetup->gblEn
= 1;
pSetup->blkEn[0]
=
1;
for
(index=1; index<9; index++) {
pSetup->blkEn[index]
=
blken;
}
pSetup->deviceId1
= SRIO_SET_DEVICE_ID(SMALL_DEV_ID, LARGE_DEV_ID);
pSetup->deviceId2
= SRIO_SET_DEVICE_ID(SMALL_DEV_ID, LARGE_DEV_ID);
pSetup->serDesPllCfg[0].pllEnable =
TRUE;
pSetup->serDesPllCfg[0].pllMplyFactor =
CSL_SRIO_SERDES_PLL_MPLY_BY_12_5;
pSetup->serDesRxChannelCfg[0].enRx
= TRUE;
pSetup->serDesRxChannelCfg[0].symAlign
= CSL_SRIO_SERDES_SYM_ALIGN_COMMA;
pSetup->serDesRxChannelCfg[0].los =
CSL_SRIO_SERDES_LOS_DET_DISABLE;
pSetup->serDesRxChannelCfg[0].clockDataRecovery
= 0x00;
pSetup->serDesRxChannelCfg[0].equalizer
= 0x01;
pSetup->serDesTxChannelCfg[0].enTx
= TRUE;
pSetup->serDesTxChannelCfg[0].commonMode
= CSL_SRIO_SERDES_COMMON_MODE_RAISED;
pSetup->serDesTxChannelCfg[0].outputSwing
= CSL_SRIO_SERDES_SWING_AMPLITUDE_1000;
pSetup->serDesTxChannelCfg[0].enableFixedPhase
= TRUE;
pSetup->serDesRxChannelCfg[1].enRx
= TRUE;
pSetup->serDesRxChannelCfg[1].symAlign
= CSL_SRIO_SERDES_SYM_ALIGN_COMMA;
pSetup->serDesRxChannelCfg[1].los =
CSL_SRIO_SERDES_LOS_DET_DISABLE;
pSetup->serDesRxChannelCfg[1].clockDataRecovery
= 0x00;
pSetup->serDesRxChannelCfg[1].equalizer
= 0x01;
pSetup->serDesTxChannelCfg[1].enTx
= TRUE;
pSetup->serDesTxChannelCfg[1].commonMode
= CSL_SRIO_SERDES_COMMON_MODE_RAISED;
pSetup->serDesTxChannelCfg[1].outputSwing
= CSL_SRIO_SERDES_SWING_AMPLITUDE_1000;
pSetup->serDesTxChannelCfg[1].enableFixedPhase
= TRUE;
pSetup->serDesRxChannelCfg[2].enRx
= TRUE;
pSetup->serDesRxChannelCfg[2].symAlign
= CSL_SRIO_SERDES_SYM_ALIGN_COMMA;
pSetup->serDesRxChannelCfg[2].los =
CSL_SRIO_SERDES_LOS_DET_DISABLE;
pSetup->serDesRxChannelCfg[2].clockDataRecovery
= 0x00;
pSetup->serDesRxChannelCfg[2].equalizer
= 0x01;
pSetup->serDesTxChannelCfg[2].enTx
= TRUE;
pSetup->serDesTxChannelCfg[2].commonMode
= CSL_SRIO_SERDES_COMMON_MODE_RAISED;
pSetup->serDesTxChannelCfg[2].outputSwing
= CSL_SRIO_SERDES_SWING_AMPLITUDE_1000;
pSetup->serDesTxChannelCfg[2].enableFixedPhase
= TRUE;
pSetup->serDesRxChannelCfg[3].enRx
= TRUE;
pSetup->serDesRxChannelCfg[3].symAlign
= CSL_SRIO_SERDES_SYM_ALIGN_COMMA;
pSetup->serDesRxChannelCfg[3].los =
CSL_SRIO_SERDES_LOS_DET_DISABLE;
pSetup->serDesRxChannelCfg[3].clockDataRecovery
= 0x00;
pSetup->serDesRxChannelCfg[3].equalizer
= 0x01;
pSetup->serDesTxChannelCfg[3].enTx
= TRUE;
pSetup->serDesTxChannelCfg[3].commonMode
= CSL_SRIO_SERDES_COMMON_MODE_RAISED;
pSetup->serDesTxChannelCfg[3].outputSwing
= CSL_SRIO_SERDES_SWING_AMPLITUDE_1000;
pSetup->serDesTxChannelCfg[3].enableFixedPhase
= TRUE;
pSetup->flowCntlIdLen[0]
= 1;
pSetup->flowCntlId[0]
= LARGE_DEV_ID;
pSetup->peLlAddrCtrl
= CSL_SRIO_ADDR_SELECT_34BIT;
pSetup->devIdSetup.smallTrBaseDevId
= SMALL_DEV_ID;
pSetup->devIdSetup.largeTrBaseDevId
= LARGE_DEV_ID;
pSetup->devIdSetup.hostBaseDevId
= LARGE_DEV_ID;
pSetup->portGenSetup.portLinkTimeout
= 0xFFFFF;
pSetup->portGenSetup.portRespTimeout
= 0xFFFFF;
pSetup->portGenSetup.hostEn
=
1;
pSetup->portGenSetup.masterEn
=
1;
pSetup->portCntlSetup[0].portDis
=
0;
pSetup->portCntlSetup[0].outPortEn
=
1;
pSetup->portCntlSetup[0].inPortEn
=
1;
pSetup->portCntlSetup[0].portWidthOverride
=
CSL_SRIO_PORT_WIDTH_NO_OVERRIDE;
pSetup->portCntlSetup[0].errCheckDis
=
0;
pSetup->portCntlSetup[0].multicastRcvEn
= 1;
pSetup->portCntlSetup[0].stopOnPortFailEn
= 1;
pSetup->portCntlSetup[0].dropPktEn
=
1;
pSetup->portCntlSetup[0].portLockoutEn
= 0;
pSetup->lgclTransErrEn
= CSL_SRIO_IO_ERR_RESP_ENABLE |
CSL_SRIO_ILL_TRANS_DECODE_ENABLE
|
CSL_SRIO_ILL_TRANS_TARGET_ERR_ENABLE
|
CSL_SRIO_PKT_RESP_TIMEOUT_ENABLE
|
CSL_SRIO_UNSOLICITED_RESP_ENABLE
|
CSL_SRIO_UNSUPPORTED_TRANS_ENABLE;
pSetup->portErrSetup[0].portErrRateEn
=
CSL_SRIO_ERR_IMP_SPECIFIC_ENABLE
|
CSL_SRIO_CORRUPT_CNTL_SYM_ENABLE
|
CSL_SRIO_CNTL_SYM_UNEXPECTED_ACKID_ENABLE
|
CSL_SRIO_RCVD_PKT_NOT_ACCPT_ENABLE
|
CSL_SRIO_PKT_UNEXPECTED_ACKID_ENABLE
|
CSL_SRIO_RCVD_PKT_WITH_BAD_CRC_ENABLE
|
CSL_SRIO_RCVD_PKT_OVER_276B_ENABLE
|
CSL_SRIO_NON_OUTSTANDING_ACKID_ENABLE
|