Other Parts Discussed in Thread: SYSBIOS, , TMS320C6748
TI的工程师,您好,我之前询问过几个有关SPI传输的问题,但有一些很重要的问题始终没有解决,我看了中英文几乎论坛上所有有关这方面的帖子,也分析了TI提供的例程,甚至也分析了有关这方面的底层的源码,依然没有办法实现SPI传输触发EDMA传输。
我查看了芯片手册有关的寄存器,并且在程序中也看到了相关的配置,但是还是没有找到解决方案。
现阶段的情况:
1、能够进行SPI轮询和中断方式传输,时钟频率为48Mhz。
2、不能使用EDMA传输,而所有寄存器都已正确配置,并且读取到的MCSPI_CHxSTAT寄存器的值为0x28,也就是符合触发EDMA的条件却没有触发。
3、使用的库版本为processor_sdk_rtos_am57xx_06_03_02_08。
4、将SPI_dma.c文件中的事件触发改为手动触发能够进行EDMA传输,但是传输的数据为重复的字节。
5、参考例程MCSPI_BasicExample_Dma_idkAM571x_c66TestProject。
6、无论哪种方式传输,使用示波器测试出当调用MCSPI_transfer后,传输迟迟没有开始,间隔了10-20us后开始传输,在传输结束5-10us后CS才拉高,并且传输时每个字节之间有200ns-500ns的间隔,也就是说传输10个字节时整个过程的时间为30-50us。
目前的问题:
1、SPI传输事件不能触发EDMA的原因?
2、传输过程为何延迟会这么大?
部分测试代码如下:
/********************************************************************* * 版权所有 (C)2022, 。 * * 文件名称: // bsp_spi.c * 文件标识: // * 内容摘要: // spi驱动接口程序 * 其它说明: // 其它内容的说明 * 当前版本: // V1.0 * 作 者:// * 完成日期: // 20220208 * * 修改记录1:// 修改历史记录,包括修改日期、修改者及修改内容 * 修改日期: * 修 改 人: * 修改内容: * 修改记录2:… **********************************************************************/ /* XDCtools 头文件 */ #include <xdc/std.h> #include <xdc/cfg/global.h> #include <xdc/runtime/System.h> #include <stdio.h> #include <ti/sysbios/knl/Task.h> /* C libray 头文件 */ #include <string.h> #include <stdio.h> /* BIOS 头文件 */ #include <ti/sysbios/BIOS.h> #include <xdc/runtime/Error.h> #include <ti/sysbios/heaps/HeapMem.h> #include <xdc/runtime/IHeap.h> #include <xdc/runtime/Memory.h> /* TI-RTOS 头文件 */ #include <ti/drv/spi/SPI.h> #include <ti/drv/spi/soc/SPI_soc.h> #include <ti/drv/spi/src/SPI_osal.h> /* Board 头文件 */ #include <ti/drv/gpio/GPIO.h> #include <ti/drv/gpio/soc/GPIO_v1.h> #include <ti/board/board.h> #include <ti/osal/CacheP.h> #include <ti/osal/SemaphoreP.h> #include <ti/csl/soc/am571x/src/cslr_soc.h> /* EDMA3 头文件 */ #include <ti/sdo/edma3/drv/edma3_drv.h> #include <ti/sdo/edma3/rm/edma3_rm.h> #include <ti/sdo/edma3/rm/sample/bios6_edma3_rm_sample.h> #include <bsp_spi.h> /* MCSPI最大的通道实例 */ #define MCSPI_MAX_NUM_CHN (unsigned char)4 /* MCSPI缓冲大小 */ #define MCSPI_DATA_COUNT (unsigned int)1280 /* Mcspi 时钟频率 */ #define MCSPI_OUT_FREQ (unsigned int)48000000 #define MCSPI_IN_CLK (unsigned int)48000000 /* Mcspi 信息结构 */ typedef struct { T_MCSPI_INSTANCE tMcspiInstance; //MCSPI实例 MCSPI_Handle tMcspi; //MCSPI句柄 SemaphoreP_Handle tCbSem; //传输完成信号量 } T_MCSPI_INFO; ///* // * 变量作用:MCSPI发送数据缓冲区 // * 变量范围:无 // * 访问说明:访问函数:xgMcspiTransfer,访问方法:赋值拷贝 // */ //static char __attribute__ ((aligned(128))) s_acTxBuff[MCSPI_DATA_COUNT ] = { "123456789" }; // ///* // * 变量作用:MCSPI接收数据缓冲区 // * 变量范围:无 // * 访问说明:访问函数 xgMcspiTransfer,访问方法:赋值拷贝 // */ //static char __attribute__ ((aligned(128))) s_acRxBuff[MCSPI_DATA_COUNT ] = { 0 }; /* * 变量作用:MCSPI发送数据缓冲区 * 变量范围:无 * 访问说明:访问函数:xgMcspiTransfer,访问方法:赋值拷贝 */ #pragma DATA_ALIGN (s_acTxBuff,32) char s_acTxBuff[MCSPI_DATA_COUNT ] = { "123456789" }; /* * 变量作用:MCSPI接收数据缓冲区 * 变量范围:无 * 访问说明:访问函数 xgMcspiTransfer,访问方法:赋值拷贝 */ #pragma DATA_ALIGN (s_acRxBuff,32) char s_acRxBuff[MCSPI_DATA_COUNT ] = { 0 }; /* * 变量作用:MCSPI结构信息 * 变量范围:无 * 访问说明:访问函数 getMcspiInfo,访问方法:查询tMcspiInstance并指向变量 * 访问函数 MCSPI1_callback,访问方法:释放tCbSem信号量 * 访问函数 MCSPI2_callback,访问方法:释放tCbSem信号量 * 访问函数 MCSPI3_callback,访问方法:释放tCbSem信号量 * 访问函数 MCSPI4_callback,访问方法:释放tCbSem信号量 */ static T_MCSPI_INFO s_atMcspiInfo[MCSPI_MAX_NUM_CHN ] = { { MC_SPI1, NULL, NULL }, { MC_SPI2, NULL, NULL }, { MC_SPI3, NULL, NULL }, { MC_SPI4, NULL, NULL }, }; static T_MCSPI_INFO* getMcspiInfo(T_MCSPI_INSTANCE tInstance); static void MCSPI1_callback(MCSPI_Handle handle, SPI_Transaction *transaction); static void MCSPI2_callback(MCSPI_Handle handle, SPI_Transaction *transaction); static void MCSPI3_callback(MCSPI_Handle handle, SPI_Transaction *transaction); static void MCSPI4_callback(MCSPI_Handle handle, SPI_Transaction *transaction); static EDMA3_RM_Handle mcspiEdmaInit(T_MCSPI_INSTANCE tInstance); /********************************************************************** * 函数名称: // int xgMcspiTransfer(T_MCSPI_INSTANCE tInstance, void *pTxBuff,void *pRxBuff,uint32_t u32Count) * 功能描述: // SPI数据传输 * 访问的表: // * 修改的表: // * 输入参数: // tInstance:SPI实例 * 输入参数: // pTxBuff:数据发送缓冲区 * 输入参数: // pRxBuff:数据接收缓冲区 * 输入参数: // u32Count:数据传输字节数 * 输出参数: // * 返 回 值: // 传输状态 1:失败 0:成功 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ int xgMcspiTransfer(T_MCSPI_INSTANCE tInstance, void *pTxBuff, void *pRxBuff, uint32_t u32Count) { int iRetVal = 0; SemaphoreP_Status tSemStatus = SemaphoreP_OK; SPI_Transaction tTransaction; T_MCSPI_INFO *ptMcspiInfo = NULL; uint32_t u32TransBytes = 0; uint32_t u32RemainBytes = u32Count; uint32_t u32Offset = 0; /* 循环传输,直到SPI传输结束 */ do { if (u32RemainBytes > MCSPI_DATA_COUNT) { u32TransBytes = MCSPI_DATA_COUNT; } else { u32TransBytes = u32RemainBytes; } u32RemainBytes -= u32TransBytes; /* 清空SPI DMA发送接收缓冲区 */ memset(s_acRxBuff, 0, u32TransBytes); memset(s_acTxBuff, 0, u32TransBytes); /* 拷贝发送缓冲区数据到DMA发送缓冲区 */ memcpy(s_acTxBuff, pTxBuff + u32Offset, u32TransBytes); /* 获取MCSPI结构信息 */ ptMcspiInfo = getMcspiInfo(tInstance); if (NULL == ptMcspiInfo) { iRetVal = 1; System_printf("\n Error occurred in getMcspiInfo \n"); return (iRetVal); } else { System_printf("\n Succeed in getMcspiInfo \n"); } if (NULL == ptMcspiInfo->tMcspi) { iRetVal = 1; System_printf("\n ptMcspiInfo->tMcspi is null \n"); return (iRetVal); } else { /* 將cache的内容写入内存中 */ CacheP_wbInv((void*) s_acTxBuff, (int32_t) u32TransBytes); CacheP_wbInv((void*) s_acRxBuff, (int32_t) u32TransBytes); /* 指定MCSPI传输参数 */ tTransaction.status = SPI_TRANSFER_STARTED; tTransaction.count = u32TransBytes; tTransaction.txBuf = &s_acTxBuff[0]; tTransaction.rxBuf = &s_acRxBuff[0]; /* MCSPI传输 */ iRetVal = MCSPI_transfer(ptMcspiInfo->tMcspi, &tTransaction); if (0 == iRetVal) { iRetVal = 1; System_printf("\n Error occurred in MCSPI_transfer \n"); return (iRetVal); } else { iRetVal = 0; System_printf("\n Succeed in MCSPI_transfer \n"); } /* 使指定的Cache无效,读取时从内存中获取 */ CacheP_Inv((void*) s_acTxBuff, (int32_t) u32TransBytes); CacheP_Inv((void*) s_acRxBuff, (int32_t) u32TransBytes); if (NULL == ptMcspiInfo->tCbSem) { iRetVal = 1; System_printf("\n ptMcspiInfo->tCbSem is null \n"); return (iRetVal); } else { /* 等待MCSPI传输完成 */ tSemStatus = SPI_osalPendLock(ptMcspiInfo->tCbSem, SemaphoreP_WAIT_FOREVER); if (SemaphoreP_OK != tSemStatus) { iRetVal = 1; System_printf("\n Error occurred in SPI_osalPendLock \n"); return (iRetVal); } else { /* 拷贝DMA接收缓冲区数据到接收缓冲区 */ memcpy(pRxBuff + u32Offset, s_acRxBuff, u32TransBytes); u32Offset += u32TransBytes; System_printf("\n Succeed in in SPI_osalPendLock \n"); } } /* end of if (NULL == ptMcspiInfo->tCbSem) */ } /* end of if (NULL == ptMcspiInfo->tMcspi) */ } while (u32RemainBytes > 0); return (iRetVal); } /* end of xgMcspiTransfer () */ /********************************************************************** * 函数名称: // int mcspiSocConfig(T_MCSPI_INSTANCE tInstance) * 功能描述: // SPI SOC初始化配置 * 访问的表: // * 修改的表: // * 输入参数: // tInstance:SPI实例 * 输入参数: // * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 初始化状态 1:失败 0:成功 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ int mcspiSocConfig(T_MCSPI_INSTANCE tInstance) { int iRetVal = 0; SPI_HWAttrs tSpiCfg; EDMA3_RM_Handle tEdma = NULL; /* 获取默认的SPI初始化配置 */ iRetVal = SPI_socGetInitCfg(tInstance, &tSpiCfg); if (1 == iRetVal) { System_printf("\n Error occurred in SPI_socGetInitCfg \n"); return (iRetVal); } else { System_printf("\n Succeed in SPI_socGetInitCfg \n"); } /* edma3初始化,获取edma句柄 */ tEdma = mcspiEdmaInit(tInstance); if (NULL == tEdma) { iRetVal = 1; System_printf("\n tEdma is null \n"); return (iRetVal); } else { System_printf("\n Succeed in mcspiEdmaInit \n"); } /* 打开中断 */ tSpiCfg.enableIntr = false; /* 设置与DMA相关的init配置 */ tSpiCfg.edmaHandle = tEdma; tSpiCfg.dmaMode = true; tSpiCfg.inputClkFreq = MCSPI_IN_CLK; tSpiCfg.chnCfg[tInstance].dataLineCommMode = MCSPI_DATA_LINE_COMM_MODE_4; // tSpiCfg.rxTrigLvl = 1; // tSpiCfg.txTrigLvl = 1; // tSpiCfg.edmaRxTC = 1; // tSpiCfg.edmaTxTC = 1; // tSpiCfg.edmaRxTCC = 1; // tSpiCfg.edmaTxTCC = 1; // tSpiCfg.rxDmaEventNumber = CSL_EDMA3_CHA1_MCSPI0_RX; // tSpiCfg.txDmaEventNumber = CSL_EDMA3_CHA1_MCSPI0_TX; // tSpiCfg.chNum = MCSPI_MULTI_CH; /* 设置SPI的初始化配置 */ iRetVal = SPI_socSetInitCfg(tInstance, &tSpiCfg); if (1 == iRetVal) { System_printf("\n Error occurred in SPI_socGetInitCfg \n"); return (iRetVal); } else { System_printf("\n Succeed in SPI_socSetInitCfg \n"); } return (iRetVal); } /********************************************************************** * 函数名称: // int mcspiInitConfig(T_MCSPI_INSTANCE tInstance) * 功能描述: // SPI 初始化配置 * 访问的表: // * 修改的表: // * 输入参数: // tInstance:SPI实例 * 输入参数: // * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 初始化状态 1:失败 0:成功 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ MCSPI_Handle tMcspi = NULL; int mcspiInitConfig(T_MCSPI_INSTANCE tInstance) { int iRetVal = 0; MCSPI_Params tMcSpiParams; SemaphoreP_Params tCbSemParams; T_MCSPI_INFO *ptMcspiInfo = NULL; MCSPI_CallbackFxn atCbFxn[MCSPI_MAX_NUM_CHN ] = { MCSPI1_callback, MCSPI2_callback, MCSPI3_callback, MCSPI4_callback }; /* 设置SPI配置参数 */ MCSPI_Params_init(&tMcSpiParams); tMcSpiParams.frameFormat = SPI_POL0_PHA0; tMcSpiParams.transferTimeout = SemaphoreP_WAIT_FOREVER; tMcSpiParams.bitRate = MCSPI_OUT_FREQ; tMcSpiParams.dataSize = 8; tMcSpiParams.mode = SPI_MASTER; /* 获取MCSPI结构信息 */ ptMcspiInfo = getMcspiInfo(tInstance); if (NULL == ptMcspiInfo) { iRetVal = 1; System_printf("\n Error occurred in getMcspiInfo \n"); return (iRetVal); } else { System_printf("\n Succeed in getMcspiInfo \n"); } /* 创建回调信号量 */ SPI_osalSemParamsInit(&tCbSemParams); tCbSemParams.mode = SemaphoreP_Mode_BINARY; ptMcspiInfo->tCbSem = SPI_osalCreateBlockingLock(0, &tCbSemParams); if (NULL == ptMcspiInfo->tCbSem) { iRetVal = 1; System_printf("\n Error occurred in SPI_osalCreateBlockingLock \n"); return (iRetVal); } else { System_printf("\n Succeed in SPI_osalCreateBlockingLock \n"); } /* 设置MCSPI EDMA传输回调函数 */ // tMcSpiParams.transferCallbackFxn = atCbFxn[tInstance]; // tMcSpiParams.transferMode = SPI_MODE_CALLBACK; tMcSpiParams.transferCallbackFxn = NULL; tMcSpiParams.transferMode = SPI_MODE_BLOCKING; /* 打开MCSPI实例 */ ptMcspiInfo->tMcspi = MCSPI_open(tInstance, tInstance,&tMcSpiParams); if (NULL == ptMcspiInfo->tMcspi) { iRetVal = 1; System_printf("\n Error occurred in MCSPI_open \n"); return (iRetVal); } else { System_printf("\n Succeed in MCSPI_open \n"); } // McSPIStartBitDisable(0x48098000,0); // McSPITurboModeEnable(0x48098000,0); // McSPICSTimeControlSet(0x48098000,); // McSPIStartBitEnable(0x48098000,0); // Task_sleep(1000); tMcspi = ptMcspiInfo->tMcspi; return (iRetVal); } /********************************************************************** * 函数名称: // int mcspiDeInitConfig(T_MCSPI_INSTANCE tInstance) * 功能描述: // SPI 删除初始化配置 * 访问的表: // * 修改的表: // * 输入参数: // tInstance:SPI实例 * 输入参数: // * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 初始化状态 1:失败 0:成功 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ int mcspiDeInitConfig(T_MCSPI_INSTANCE tInstance) { int iRetVal = 0; T_MCSPI_INFO *ptMcspiInfo = NULL; /* 获取MCSPI结构信息 */ ptMcspiInfo = getMcspiInfo(tInstance); if (NULL == ptMcspiInfo) { iRetVal = 1; System_printf("\n Error occurred in getMcspiInfo \n"); return (iRetVal); } else { System_printf("\n Succeed in getMcspiInfo \n"); } /* 关闭MCSPI实例 */ if (NULL == ptMcspiInfo->tMcspi) { iRetVal = 1; System_printf("\n ptMcspiInfo->tMcspi is null \n"); return (iRetVal); } else { MCSPI_close(ptMcspiInfo->tMcspi); ptMcspiInfo->tMcspi = NULL; System_printf("\n Succeed in MCSPI_close \n"); } /* 释放回调信号量 */ if (NULL == ptMcspiInfo->tCbSem) { iRetVal = 1; System_printf("\n ptMcspiInfo->tCbSem is null \n"); return (iRetVal); } else { SPI_osalDeleteBlockingLock(ptMcspiInfo->tCbSem); ptMcspiInfo->tCbSem = NULL; System_printf("\n Succeed in SPI_osalDeleteBlockingLock \n"); } return (iRetVal); } /********************************************************************** * 函数名称: // static T_MCSPI_INFO *getMcspiInfo(T_MCSPI_INSTANCE tInstance) * 功能描述: // 获取MCSPI结构信息 * 访问的表: // * 修改的表: // * 输入参数: // tInstance:SPI实例 * 输入参数: // * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 信息结构 NULL:失败 非空:成功 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ static T_MCSPI_INFO* getMcspiInfo(T_MCSPI_INSTANCE tInstance) { int i = 0; for (i = 0; i < MCSPI_DATA_COUNT ; i++) { if (tInstance == s_atMcspiInfo[i].tMcspiInstance) { break; } else { continue; } } if (i >= MCSPI_DATA_COUNT) { return NULL; } else { return &s_atMcspiInfo[i]; } } /********************************************************************** * 函数名称: // static void MCSPI1_callback(MCSPI_Handle handle, SPI_Transaction *transaction) * 功能描述: // MCSPI1 EDMA回调函数 * 访问的表: // * 修改的表: // * 输入参数: // handle: MCSPI句柄 * 输入参数: // transaction: MCSPI传输参数 * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 无 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ static void MCSPI1_callback(MCSPI_Handle handle, SPI_Transaction *transaction) { /* 释放MCSPI传输完成信号量 */ SPI_osalPostLock(s_atMcspiInfo[MC_SPI1].tCbSem); System_printf("\r\n MCSPI1_callback:%d\r\n", transaction->status); } /********************************************************************** * 函数名称: // static void MCSPI2_callback(MCSPI_Handle handle, SPI_Transaction *transaction) * 功能描述: // MCSPI2 EDMA回调函数 * 访问的表: // * 修改的表: // * 输入参数: // handle: MCSPI句柄 * 输入参数: // transaction: MCSPI传输参数 * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 无 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ static void MCSPI2_callback(MCSPI_Handle handle, SPI_Transaction *transaction) { /* 释放MCSPI传输完成信号量 */ SPI_osalPostLock(s_atMcspiInfo[MC_SPI2].tCbSem); System_printf("\r\n MCSPI2_callback:%d\r\n", transaction->status); } /********************************************************************** * 函数名称: // static void MCSPI3_callback(MCSPI_Handle handle, SPI_Transaction *transaction) * 功能描述: // MCSPI3 EDMA回调函数 * 访问的表: // * 修改的表: // * 输入参数: // handle: MCSPI句柄 * 输入参数: // transaction: MCSPI传输参数 * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 无 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ static void MCSPI3_callback(MCSPI_Handle handle, SPI_Transaction *transaction) { /* 释放MCSPI传输完成信号量 */ SPI_osalPostLock(s_atMcspiInfo[MC_SPI3].tCbSem); System_printf("\r\n MCSPI3_callback:%d\r\n", transaction->status); } /********************************************************************** * 函数名称: // static void MCSPI4_callback(MCSPI_Handle handle, SPI_Transaction *transaction) * 功能描述: // MCSPI4 EDMA回调函数 * 访问的表: // * 修改的表: // * 输入参数: // handle: MCSPI句柄 * 输入参数: // transaction: MCSPI传输参数 * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // 无 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ static void MCSPI4_callback(MCSPI_Handle handle, SPI_Transaction *transaction) { /* 释放MCSPI传输完成信号量 */ SPI_osalPostLock(s_atMcspiInfo[MC_SPI4].tCbSem); System_printf("\r\n MCSPI4_callback:%d\r\n", transaction->status); } /********************************************************************** * 函数名称: // static EDMA3_RM_Handle mcspiEdmaInit(T_MCSPI_INSTANCE tInstance) * 功能描述: // edma3控制器初始化 * 访问的表: // * 修改的表: // * 输入参数: // tInstance: MCSPI实例 * 输入参数: // * 输入参数: // * 输入参数: // * 输出参数: // * 返 回 值: // edma3控制器句柄 * 其它说明: // 其它说明 * 修改日期 修改人 修改内容 * ----------------------------------------------- * 2022/02/16 XXXX ***********************************************************************/ EDMA3_RM_Handle tEdmaHandle = NULL; static EDMA3_RM_Handle mcspiEdmaInit(T_MCSPI_INSTANCE tInstance) { uint32_t u32Edma3Id = 0; EDMA3_DRV_Result tEdmaResult = EDMA3_DRV_E_INVALID_PARAM; /* edma3控制器初始化 */ u32Edma3Id = 1; tEdmaHandle = (EDMA3_RM_Handle) edma3init(u32Edma3Id, &tEdmaResult); if (tEdmaResult != EDMA3_DRV_SOK) { System_printf("\nError occurred in edma3init\n"); return NULL; } else { System_printf("\n Succeed in edma3init \n"); } System_printf("\n tEdmaHandle:%p \n",tEdmaHandle); return (tEdmaHandle); } void spitestInit(void) { int status = 0; T_MCSPI_INSTANCE tInstance = MC_SPI1; status = mcspiSocConfig(tInstance); if (0 != status) return; status = mcspiInitConfig(tInstance); if (0 != status) return; } void spi_lld_test(void) { int status = 0; unsigned int i = 0, timecnt = 0; char *txBuff = NULL; char *rxBuff = NULL; char tmp[10]; uint32_t u32Count = 128; T_MCSPI_INSTANCE tInstance = MC_SPI1; txBuff = malloc(u32Count * 5); rxBuff = malloc(u32Count * 5); memset(tmp, 0, 10); memset(txBuff, 0, u32Count * 5); memset(rxBuff, 0, u32Count * 5); System_printf("\n malloc, txBuff addr:%p,rxBuff addr:%p\n", txBuff, rxBuff); for (i = 0; i < u32Count; i++) { sprintf(tmp, "%x", i & 0xf); strcat(txBuff, tmp); memset(tmp, 0, 10); } sprintf(tmp, " end i:%d\r\n\r\n", i); strcat(txBuff, tmp); status = mcspiSocConfig(tInstance); if (0 != status) return; status = mcspiInitConfig(tInstance); if (0 != status) return; while(1) { spiIntTranstest(); // Task_sleep(1); } // timecnt = 1; // do // { // memset(rxBuff, 0, u32Count + 64); // status = xgMcspiTransfer(tInstance, txBuff, rxBuff, u32Count + 64); // if (0 != status) // return; // System_printf("\r\n txBuff:%s\r\n rxBuff:%s\r\n transCount:%d\r\n", // &txBuff[0], &rxBuff[0], u32Count + 64); // GPIO_toggle(0); // Task_sleep(1); // } // while (timecnt); } SPI_Transaction tTransactions; void spiIntTranstest(void) { T_MCSPI_INFO *ptMcspiInfo = &s_atMcspiInfo[0]; T_MCSPI_INSTANCE tInstance = MC_SPI1; int iRetVal; static unsigned int cnt = 0; unsigned int u32TransBytes = 128; if (NULL == tMcspi) { return; } uint32_t *spirxreg = 0x4809813c; uint32_t *spitxreg = 0x48098138; System_printf("\r\n spirxreg:%x\r\n spitxreg:%x\r\n ", spirxreg[0], spitxreg[0]); tTransactions.status = SPI_TRANSFER_STARTED; tTransactions.count = u32TransBytes; tTransactions.txBuf = &s_acTxBuff[0]; tTransactions.rxBuf = &s_acRxBuff[0]; /* 將cache的内容写入内存中 */ CacheP_wbInv((void*) s_acTxBuff, (int32_t) u32TransBytes); CacheP_wbInv((void*) s_acRxBuff, (int32_t) u32TransBytes); // GPIO_toggle(0); GPIO_write(0, 1); //熄灭 高 uint32_t xferEnable = 1; int isss = 0; // isss = MCSPI_control(tMcspi,32,(void *) &xferEnable); // System_printf("\n MCSPI_control %d\n",isss); /* MCSPI传输 */ iRetVal = MCSPI_transfer(tMcspi, &tTransactions); if (0 == iRetVal) { tMcspi = NULL; System_printf("MCSPI_transfer err!\n"); return; } // xferEnable = 0; // isss = MCSPI_control(tMcspi,32,&xferEnable); // System_printf("\n MCSPI_control %d\n",isss); GPIO_write(0, 0); //点亮低 /* 使指定的Cache无效,读取时从内存中获取 */ CacheP_Inv((void*) s_acTxBuff, (int32_t) u32TransBytes); CacheP_Inv((void*) s_acRxBuff, (int32_t) u32TransBytes); System_printf("\r\n s_acTxBuff:%s\r\n s_acRxBuff:%s\r\n ", &s_acTxBuff[0], &s_acRxBuff[0]); // // System_printf("\r\n spirxreg:%x\r\n spitxreg:%x\r\n ", spirxreg[0], spitxreg[0]); }
cfg文件如下:
//BWC, add Program var /* root of the configuration object model */ var Program = xdc.useModule('xdc.cfg.Program'); /* ================ General configuration ================ */ var Memory = xdc.useModule('xdc.runtime.Memory'); var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem'); var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf'); var Log = xdc.useModule('xdc.runtime.Log'); var Task = xdc.useModule('ti.sysbios.knl.Task'); var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore'); var Hwi = xdc.useModule('ti.sysbios.family.c64p.Hwi'); var ECM = xdc.useModule('ti.sysbios.family.c64p.EventCombiner'); var System = xdc.useModule('xdc.runtime.System'); SysStd = xdc.useModule('xdc.runtime.SysStd'); var IntXbar = xdc.useModule('ti.sysbios.family.shared.vayu.IntXbar'); var halCache = xdc.useModule('ti.sysbios.hal.Cache'); var Idle = xdc.useModule('ti.sysbios.knl.Idle'); var Deh = xdc.useModule('ti.deh.Deh'); var Timer = xdc.useModule('ti.sysbios.hal.Timer'); var Clock = xdc.useModule('ti.sysbios.knl.Clock'); var ti_sysbios_timers_dmtimer_Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer'); /* application uses the following modules and packages */ xdc.useModule('xdc.runtime.Assert'); xdc.useModule('xdc.runtime.Error'); /* Must be placed before pwr mgmt */ Idle.addFunc('&ti_deh_Deh_idleBegin'); System.SupportProxy = SysStd; /* * Enable Event Groups here and registering of ISR for specific GEM INTC is done * using EventCombiner_dispatchPlug() and Hwi_eventMap() APIs */ var exception = xdc.useModule('ti.sysbios.family.c64p.Exception'); exception.enablePrint = true; /* ================ BIOS configuration ================ */ var BIOS = xdc.useModule('ti.sysbios.BIOS'); /* Enable BIOS Task Scheduler */ BIOS.taskEnabled = true; BIOS.heapSize = 0x300000; BIOS.heapSection = "systemHeap"; BIOS.addUserStartupFunction('&IpcMgr_ipcStartup'); /* ================ Task configuration ================ */ /* No runtime stack checking is performed */ Task.checkStackFlag = false; /* Reduce the number of task priorities */ Task.numPriorities = 16; Task.common$.namedInstance = true; /* ================ Driver configuration ================ */ /* Load the Osal package */ var osType = "tirtos"; var Osal = xdc.loadPackage('ti.osal'); Osal.Settings.osType = osType; /*use CSL package*/ var socType = "am571x"; var Csl = xdc.loadPackage('ti.csl'); Csl.Settings.deviceType = socType; /* Load the gpio package */ var GPIO = xdc.loadPackage('ti.drv.gpio'); GPIO.Settings.socType = socType; /* Load the UART package */ var Uart = xdc.loadPackage('ti.drv.uart'); /* Load the I2C package */ var I2c = xdc.loadPackage('ti.drv.i2c'); /* Load the SPI package */ var Spi = xdc.loadPackage('ti.drv.spi'); Spi.Settings.socType = socType; Spi.Settings.useDma = "true"; /* Load the Board package and set the board name */ var Board = xdc.loadPackage('ti.board'); Board.Settings.boardName = "idkAM571x"; /* root of the configuration object model */ var Program = xdc.useModule('xdc.cfg.Program'); /* load the configuration shared across cores */ Program.global.procName = "DSP1"; Program.sectMap[".tracebuf"] = "TRACE_BUF"; Program.sectMap[".errorbuf"] = "EXC_DATA"; /* * ======== IPC Configuration ======== */ xdc.useModule('ti.ipc.ipcmgr.IpcMgr'); var ipc_cfg = xdc.loadCapsule("ipc.cfg.xs"); /* * ======== SYS/BIOS Configuration ======== */ if (Program.build.profile == "debug") { BIOS.libType = BIOS.LibType_Debug; } else { BIOS.libType = BIOS.LibType_Custom; } /* create a heap for MessageQ messages */ var params = new HeapBuf.Params; params.align = 8; params.blockSize = 512; params.numBlocks = 256; var msgHeap = HeapBuf.create(params); var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ'); MessageQ.registerHeapMeta(msgHeap, 0); /* Setup MessageQ transport */ var VirtioSetup = xdc.useModule('ti.ipc.transports.TransportRpmsgSetup'); MessageQ.SetupTransportProxy = VirtioSetup; /* Setup NameServer remote proxy */ var NameServer = xdc.useModule("ti.sdo.utils.NameServer"); var NsRemote = xdc.useModule("ti.ipc.namesrv.NameServerRemoteRpmsg"); NameServer.SetupProxy = NsRemote; /* Enable Memory Translation module that operates on the BIOS Resource Table */ var Resource = xdc.useModule('ti.ipc.remoteproc.Resource'); Resource.loadSegment = "EXT_CODE"; Resource.customTable = true; /* Use SysMin because trace buffer address is required for Linux/QNX * trace debug driver, plus provides better performance. */ var System = xdc.useModule('xdc.runtime.System'); var SysMin = xdc.useModule('ti.trace.SysMin'); System.SupportProxy = SysMin; SysMin.bufSize = 0x8000; /* * ======== Instrumentation Configuration ======== */ /* system logger */ var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys'); var LoggerSysParams = new LoggerSys.Params(); var Defaults = xdc.useModule('xdc.runtime.Defaults'); Defaults.common$.logger = LoggerSys.create(LoggerSysParams); /* enable runtime Diags_setMask() for non-XDC spec'd modules */ var Diags = xdc.useModule('xdc.runtime.Diags'); Diags.setMaskEnabled = true; /* override diags mask for selected modules */ xdc.useModule('xdc.runtime.Main'); Diags.setMaskMeta("xdc.runtime.Main", Diags.ENTRY | Diags.EXIT | Diags.INFO, Diags.RUNTIME_ON); var Registry = xdc.useModule('xdc.runtime.Registry'); Registry.common$.diags_ENTRY = Diags.RUNTIME_OFF; Registry.common$.diags_EXIT = Diags.RUNTIME_OFF; Registry.common$.diags_INFO = Diags.RUNTIME_OFF; Registry.common$.diags_USER1 = Diags.RUNTIME_OFF; Registry.common$.diags_LIFECYCLE = Diags.RUNTIME_OFF; Registry.common$.diags_STATUS = Diags.RUNTIME_OFF; var Main = xdc.useModule('xdc.runtime.Main'); Main.common$.diags_ASSERT = Diags.ALWAYS_ON; Main.common$.diags_INTERNAL = Diags.ALWAYS_ON; /* Override the default resource table with my own */ var Resource = xdc.useModule('ti.ipc.remoteproc.Resource'); Resource.customTable = true; ti_sysbios_timers_dmtimer_Timer.timerSettings[4].intNum = 11; var timer0Params = new Timer.Params(); timer0Params.instance.name = "timer0"; timer0Params.period = 5; timer0Params.periodType = xdc.module("ti.sysbios.interfaces.ITimer").PeriodType_MICROSECS; timer0Params.extFreq.lo = 20000000; timer0Params.runMode = xdc.module("ti.sysbios.interfaces.ITimer").RunMode_CONTINUOUS; timer0Params.arg = 200; Program.global.timer0 = Timer.create(4, "&TimerFxn", timer0Params); Clock.tickSource = Clock.TickSource_USER; Clock.tickPeriod = 1000; /* ================ Driver configuration ================ */ var drv = xdc.loadPackage ("ti.sdo.edma3.drv"); var rm = xdc.loadPackage ("ti.sdo.edma3.rm"); var rm = xdc.loadPackage ("ti.sdo.edma3.drv.sample"); BIOS.cpuFreq.lo = 750000000; ECM.eventGroupHwiNum[0] = 7; ECM.eventGroupHwiNum[1] = 8; ECM.eventGroupHwiNum[2] = 9; ECM.eventGroupHwiNum[3] = 10;
部分测试结果如下:
期待您的回复,谢谢!