This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
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;
部分测试结果如下:
期待您的回复,谢谢!
感谢回复,使用的自己的板子,我将SPI1D0连接的SPI1D1,配置为SPI_Master模式进行传输无法触发EDMA,但是我不使用SPI时单独测试EDMA使用手动触发能够在两块内存之间进行EDMA传输。
您好,我在查看芯片用户手册时注意到AM5718的SPI并没有内部自环模式,而TMS320C6748的SPI有loopback自环模式,好像AM5718对SPI裁剪了些什么。
您好,请问有任何进展吗?我再次使用CSL的方式SPI事件也无法触发EDMA。
以下是CSL方式的部分程序:
/* * bsp_spi_csl.c * * Created on: 2022年3月4日 * Author: */ /* ========================================================================== */ /* Include Files */ /* ========================================================================== */ #include "stdint.h" #include <stdio.h> #include <ti/csl/csl_mcspi.h> #include <ti/csl/csl_i2c.h> #include <ti/csl/example/utils/uart_console/inc/uartConfig.h> #include <ti/csl/csl_types.h> #include <ti/csl/soc.h> #include <ti/csl/hw_types.h> #include <ti/csl/csl_edma.h> #include <ti/csl/arch/csl_arch.h> #include <ti/csl/example/utils/common/inc/app_utils.h> #include <xdc/runtime/System.h> /* ========================================================================== */ /* Macros */ /* ========================================================================== */ #define HSI2C_SLAVE_ADDR 0x21 #define SEL_UART3_SPI2 0x0E #define UART_SEL1_3 0x0C #define I2C_INT_NUM 56 #define MCSPI_POLLED_MODE 0 #define HSI2C_EN_SPI2 ((uint8_t) 0x40U) #define HSI2C_ZERO ((uint8_t) 0x00U) #define MCSPI_OUT_FREQ (1000000U) #define MCSPI_IN_CLK (48000000U) #define McSPI_DATA_COUNT 256U // Data Count Transaction #if (defined (SOC_AM574x) || defined (SOC_AM572x)) || (defined (SOC_AM571x)) #define MCSPI1_BASE_ADDRESS (CSL_MPU_MCSPI1_REGS) #define MCSPI2_BASE_ADDRESS (CSL_MPU_MCSPI2_REGS) #undef SOC_I2C1_BASE #define SOC_I2C1_BASE CSL_MPU_I2C1_REGS #endif #if defined (SOC_TDA2XX) || defined (SOC_TDA2PX) || defined (SOC_TDA2EX) || defined (SOC_DRA72x) || defined (SOC_DRA75x) || defined (SOC_TDA3XX) || defined (SOC_DRA78x) #define MCSPI1_BASE_ADDRESS (SOC_MCSPI1_BASE) #define MCSPI2_BASE_ADDRESS (SOC_MCSPI2_BASE) #endif /** \brief EDMA3 channel for SPI1 Channel 0 Tx and Rx*/ #define MCSPI1_TX_EVENT (34U) #define MCSPI1_RX_EVENT (35U) /** \brief EDMA3 channel for SPI2 Channel 0 Tx and Rx*/ #define MCSPI2_TX_EVENT (42U) #define MCSPI2_RX_EVENT (43U) /** \brief MCSPI Tx/Rx buffer base address */ #define MCSPI1_TX0_REG (SOC_MCSPI1_BASE + (0x138U)) #define MCSPI1_RX0_REG (SOC_MCSPI1_BASE + (0x13CU)) #define MCSPI2_TX0_REG (SOC_MCSPI2_BASE + (0x138U)) #define MCSPI2_RX0_REG (SOC_MCSPI2_BASE + (0x13CU)) /** \brief MCSPI Channel number*/ #define MCSPI_CH_NUM (0U) #define EVT_QUEQUE_NUM (0U) #define DUMMY_CH_NUM (5U) #define EDMA_TDA2XX_U_BASE CSL_DSP_DSP_EDMA_CC_REGS//(SOC_EDMA_TPCC_BASE_VIRT) #define EDMA3CC_PaRAM_BASE (0x4000) #define EDMA3CC_OPT(n) (EDMA3CC_PaRAM_BASE + 0x0 + (0x20 * n)) #define EDMA3_CC_XFER_COMPLETION_INT_A15 (12U) #define EDMA3_CC_XFER_COMPLETION_INT_M4 (35U) #define EDMA3_ERROR_INT_A15 (14) #define EDMA3_ERROR_INT_A15_1 (15) #define EDMA3_ERROR_INT_M4 (36) #define EDMA3_ERROR_INT_M4_1 (37) #define EDMA3_CC_REGION_A15 (0U) #define EDMA3_CC_REGION_M4 (1U) #define MCSPI_MASTERSLAVE_POLLED_MODE_TEST ('1') #define MCSPI_MASTERSLAVE_DMA_MODE_TEST ('2') #define EXIT(opt) (('x' == opt) || ('X' == opt)) /* ========================================================================== */ /* Global Variables */ /* ========================================================================== */ uint32_t dataToSlave; uint32_t gChNum = 0; uint32_t length = 0; uint8_t dataFromSlave; uint8_t rxBuffer[McSPI_DATA_COUNT + 10]; uint8_t txBuffer[McSPI_DATA_COUNT + 10]; uint8_t txSlvBuffer[McSPI_DATA_COUNT + 10]; uint8_t rxSlvBuffer[McSPI_DATA_COUNT + 10]; static void (*cb_Fxn[EDMA3_NUM_TCC])(uint32_t tcc, uint32_t status); volatile uint8_t flagTx = 0; volatile uint8_t flagRx = 0; volatile uint8_t flagSlvTx = 0; volatile uint8_t flagSlvRx = 0; char gMainMenuOption = MCSPI_MASTERSLAVE_DMA_MODE_TEST; /*To use UARTConfigPuts function for prints*/ #if defined (SOC_AM574x) || defined (SOC_AM572x) || defined (SOC_AM571x) uint32_t uartBaseAddr = CSL_MPU_UART1_REGS; #endif #if defined (SOC_TDA2XX) || defined (SOC_TDA2PX) || defined (SOC_TDA2EX) || defined (SOC_DRA72x) || defined (SOC_DRA75x) uint32_t uartBaseAddr = SOC_UART1_BASE; #endif #if defined (SOC_TDA3XX) || defined (SOC_DRA78x) uint32_t uartBaseAddr = SOC_UART1_BASE; #endif /* ========================================================================== */ /* Function Declarations */ /* ========================================================================== */ static void McSPI1SetUp(void); static void McSPI2SetUp(void); static void McSPIMSTransfer(uint16_t length); static void McSPIVerifyData(void); static void McSPIInitializeBuffers(void); static void sampleDelay(int32_t delay); static void McSPIMSPolledModeTransfer(uint16_t length); static void McSPIMasterSlaveAppTest(void); static void mainMenu(char *option); static void McSPIConfigureDma(uint32_t length); static void McSpi1TxEdmaParamSet(uint32_t tccNum, uint32_t chNum, volatile uint8_t *buffer, uint16_t buffLength); static void McSpi1RxEdmaParamSet(uint32_t tccNum, uint32_t chNum, volatile uint8_t *buffer, uint16_t buffLength, uint32_t destBidxFlag); static void McSpi2TxEdmaParamSet(uint32_t tccNum, uint32_t chNum, volatile uint8_t *buffer, uint16_t buffLength); static void McSpi2RxEdmaParamSet(uint32_t tccNum, uint32_t chNum, volatile uint8_t *buffer, uint16_t buffLength, uint32_t destBidxFlag); static void CallBack_McSPI1(uint32_t tccNum, uint32_t status); static void CallBack_McSPI2(uint32_t tccNum, uint32_t status); static void TxDummyPaRAMConfEnable(void); static void Edma3ErrorHandlerIsr_McSPI1(void *dummy); static void Edma3ErrorHandlerIsr_McSPI2(void *dummy); void Edma3ComplHandlerIsr(void *dummy); static void RequestEDMA3Channels(void); static void EDMA3IntConfigure(void); static void EDMA3Initialize(void); void padConfig_prcmEnable(); void SetupI2C(void); void SetupI2CTransmit(void); uint32_t I2CRead(); void configure_board_mux(); /* ========================================================================== */ /* Function Definitions */ /* ========================================================================== */ static void sampleDelay(int32_t delay) { volatile int32_t i, j; for (i = 0; i < delay; i++) { for (j = 0; j < 100; j++) ; } } int main_spi_csl(void) { while (1) { mainMenu(&gMainMenuOption); if ((MCSPI_MASTERSLAVE_POLLED_MODE_TEST == gMainMenuOption) || (MCSPI_MASTERSLAVE_DMA_MODE_TEST == gMainMenuOption)) { System_printf("McSPIMasterSlaveAppTest...\r\n"); McSPIMasterSlaveAppTest(); } else { break; } } return 0; } static void McSPIMasterSlaveAppTest(void) { if (MCSPI_MASTERSLAVE_POLLED_MODE_TEST == gMainMenuOption) { System_printf("MCSPI_MASTERSLAVE_POLLED_MODE_TEST...\r\n"); } if (MCSPI_MASTERSLAVE_DMA_MODE_TEST == gMainMenuOption) { System_printf("MCSPI_MASTERSLAVE_DMA_MODE_TEST...\r\n"); EDMA3Init(EDMA_TDA2XX_U_BASE, 0); System_printf("EDMA3Init success...\r\n"); /* Initialize the EDMA3 instance.*/ EDMA3Initialize(); System_printf("EDMA3Initialize success...\r\n"); /* Request EDMA3CC for Tx and Rx channels for SPI0. */ RequestEDMA3Channels(); System_printf("RequestEDMA3Channels success...\r\n"); } /* Do the necessary set up configurations for McSPI.*/ McSPI1SetUp(); System_printf("McSPI1SetUp success...\r\n"); McSPIInitializeBuffers(); System_printf("McSPIInitializeBuffers success...\r\n"); if (MCSPI_MASTERSLAVE_DMA_MODE_TEST == gMainMenuOption) { McSPIConfigureDma(McSPI_DATA_COUNT); System_printf("McSPIConfigureDma success...\r\n"); } McSPIMSTransfer(McSPI_DATA_COUNT); System_printf("McSPIMSTransfer success...\r\n"); /* Verify whether the data written by Master and the one read by * Slave are Equal */ McSPIVerifyData(); System_printf("McSPIVerifyData success...\r\n"); } /* ** This function will call the necessary McSPI APIs which will configure the ** McSPI controller. */ static void McSPI1SetUp(void) { uint32_t status = 1U; // FALSE /* Reset the McSPI instance.*/ McSPIReset(MCSPI1_BASE_ADDRESS); /* CLOCKACTIVITY bit - OCP and Functional clocks are maintained */ /* SIDLEMODE bit - Ignore the idle request and configure in normal mode */ /* AUTOIDLE bit - Disable (OCP clock is running free, no gating) */ MCSPISysConfigSetup(MCSPI1_BASE_ADDRESS, MCSPI_CLOCKS_OCP_ON_FUNC_ON, MCSPI_SIDLEMODE_NO, MCSPI_WAKEUP_DISABLE, MCSPI_AUTOIDLE_OFF); /* Enable chip select pin.*/ McSPICSEnable(MCSPI1_BASE_ADDRESS); /* Enable master mode of operation.*/ McSPIMasterModeEnable(MCSPI1_BASE_ADDRESS); /* Perform the necessary configuration for master mode. */ status = McSPIMasterModeConfig(MCSPI1_BASE_ADDRESS, MCSPI_SINGLE_CH, MCSPI_TX_RX_MODE, MCSPI_DATA_LINE_COMM_MODE_6, gChNum); if (0 == status) { } /* Configure the McSPI bus clock depending on clock mode. */ McSPIClkConfig(MCSPI1_BASE_ADDRESS, MCSPI_IN_CLK, MCSPI_OUT_FREQ, gChNum, MCSPI_CLK_MODE_0); /* Configure the word length.*/ McSPIWordLengthSet(MCSPI1_BASE_ADDRESS, MCSPI_WORD_LENGTH(8), gChNum); /* Set polarity of SPIEN to low.*/ McSPICSPolarityConfig(MCSPI1_BASE_ADDRESS, (MCSPI_CH0CONF_EPOL_ACTIVELOW << MCSPI_CH0CONF_EPOL_SHIFT), gChNum); /* Enable the transmitter FIFO of McSPI peripheral.*/ McSPITxFIFOConfig(MCSPI1_BASE_ADDRESS, MCSPI_TX_FIFO_ENABLE, gChNum); /* Enable the receiver FIFO of McSPI peripheral.*/ McSPIRxFIFOConfig(MCSPI1_BASE_ADDRESS, MCSPI_RX_FIFO_ENABLE, gChNum); } static void McSPIConfigureDma(uint32_t length) { /* DMA PaRAM Configuration for McSPI1 */ /* Configure the read data parameters of McSPI for Edma transmit.*/ McSpi1TxEdmaParamSet(MCSPI1_TX_EVENT, MCSPI1_TX_EVENT, txBuffer, length); /* Configure the read data parameters of McSPI for Edma receive.*/ McSpi1RxEdmaParamSet(MCSPI1_RX_EVENT, MCSPI1_RX_EVENT, rxBuffer, length, TRUE); /* Register the call-back function for Tx/Rx edma events of McSPI.*/ cb_Fxn[MCSPI1_TX_EVENT] = &CallBack_McSPI1; cb_Fxn[MCSPI1_RX_EVENT] = &CallBack_McSPI1; /* Set the word count field with the data length to be transferred.*/ McSPIWordCountSet(MCSPI1_BASE_ADDRESS, length); /* Enable the Tx/Rx DMA events for McSPI. */ McSPIDMAEnable(MCSPI1_BASE_ADDRESS, (MCSPI_DMA_RX_EVENT | MCSPI_DMA_TX_EVENT), MCSPI_CH_NUM); } static void McSPIInitializeBuffers(void) { uint32_t index = 0; for (index = 0; index < McSPI_DATA_COUNT; index++) { /* Initialize the txBuffer McSPI1 with a known pattern of data */ txBuffer[index] = (uint8_t) index; /* Initialize the rxBuffer McSPI1 with 0 */ rxBuffer[index] = (uint8_t) 0; } for (index = 0; index < McSPI_DATA_COUNT; index++) { /* Initialize the txBuffer McSPI1 with a known pattern of data */ txSlvBuffer[index] = (uint8_t) index; /* Initialize the rxBuffer McSPI1 with 0 */ rxSlvBuffer[index] = 0; } } static void McSPIMSTransfer(uint16_t length) { /* Enable the McSPI channel for communication.*/ McSPIChannelEnable(MCSPI1_BASE_ADDRESS, gChNum); /* SPIEN line is forced to low state.*/ McSPICSAssert(MCSPI1_BASE_ADDRESS, gChNum); if (MCSPI_MASTERSLAVE_DMA_MODE_TEST == gMainMenuOption) { /* For DMA mode wait for EDMA ISR to happen */ while ((0 == flagTx) || (flagRx == 0) || (0 == flagSlvTx) || (flagSlvRx == 0)) ; } else { } /* Force SPIEN line to the inactive state.*/ McSPICSDeAssert(MCSPI1_BASE_ADDRESS, gChNum); /* Disable the McSPI channel.*/ McSPIChannelDisable(MCSPI1_BASE_ADDRESS, gChNum); } /* ** This function will verify the data written to and read from flash and print ** the appropriate message. */ static void McSPIVerifyData(void) { uint32_t index = 0; uint32_t error = 0; for (index = 0; index < McSPI_DATA_COUNT; index++) { if ((rxSlvBuffer[index] != txBuffer[index]) || (txSlvBuffer[index] != rxBuffer[index])) { error = 1; break; } } if (error == 0) { } } /* ** This function configures the power supply for EDMA3 Channel Controller 0 ** and Transfer Controller 0, registers the EDMA interrupts in AINTC. */ static void EDMA3Initialize(void) { /* Configuring the AINTC to receive EDMA3 Interrupts */ EDMA3IntConfigure(); } /* ** EDMA3 completion Interrupt Service Routine(ISR). */ void Edma3ComplHandlerIsr(void *dummy) { uint32_t pendingIrqs; volatile uint32_t isIPR = 0; volatile uint32_t isIPRH = 0; uint32_t indexl; uint32_t Cnt = 0; indexl = 1; System_printf("Edma3ComplHandlerIsr...\r\n"); isIPR = EDMA3GetIntrStatus(EDMA_TDA2XX_U_BASE); isIPRH = EDMA3IntrStatusHighGet(EDMA_TDA2XX_U_BASE); if (isIPR) { while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT) && (indexl != 0)) { indexl = 0; pendingIrqs = EDMA3GetIntrStatus(EDMA_TDA2XX_U_BASE); while (pendingIrqs) { if ((pendingIrqs & 1) == TRUE) { /** * If the user has not given any callback function * while requesting the TCC, its TCC specific bit * in the IPR register will NOT be cleared. */ /* Here write to ICR to clear the corresponding IPR bits. */ EDMA3ClrIntr(EDMA_TDA2XX_U_BASE, indexl); (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE); } ++indexl; pendingIrqs >>= 1; } Cnt++; } } indexl = 32; if (isIPRH) { while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT) && (indexl != 0)) { indexl = 32; pendingIrqs = EDMA3IntrStatusHighGet(EDMA_TDA2XX_U_BASE); while (pendingIrqs) { if ((pendingIrqs & 1) == TRUE) { /** * If the user has not given any callback function * while requesting the TCC, its TCC specific bit * in the IPR register will NOT be cleared. */ /* Here write to ICR to clear the corresponding IPR bits. */ EDMA3ClrIntr(EDMA_TDA2XX_U_BASE, indexl); (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE); } ++indexl; pendingIrqs >>= 1; } Cnt++; } } } void Edma3ErrorHandlerIsr(void *dummy) { Edma3ErrorHandlerIsr_McSPI1(dummy); } /* EDMA3 Error Handler */ static void Edma3ErrorHandlerIsr_McSPI1(void *dummy) { volatile uint32_t pendingIrqs = 0; volatile uint32_t pendingHIrqs = 0; uint32_t txEventHighNo = 0; uint32_t rxEventHighNo = 0; System_printf("Edma3ErrorHandlerIsr_McSPI1...\r\n"); pendingIrqs = EDMA3GetErrIntrStatus(EDMA_TDA2XX_U_BASE); pendingHIrqs = EDMA3ErrIntrHighStatusGet(EDMA_TDA2XX_U_BASE); if (pendingIrqs) { txEventHighNo = MCSPI1_TX_EVENT & 0x1F; rxEventHighNo = MCSPI1_RX_EVENT & 0x1F; if ((pendingIrqs & (0x01 << txEventHighNo))) { /* clear the pending error interrupt */ EDMA3ClrMissEvt(EDMA_TDA2XX_U_BASE, MCSPI1_TX_EVENT); /* Disable McSPI Transmit event */ McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAW_MASK, MCSPI_CH_NUM); /* Disable Edma Transfer */ EDMA3DisableTransfer(EDMA_TDA2XX_U_BASE, MCSPI1_TX_EVENT, EDMA3_TRIG_MODE_EVENT); flagTx = 1; } else if ((pendingIrqs & (0x01 << rxEventHighNo))) { /* clear the pending error interrupt */ EDMA3ClrMissEvt(EDMA_TDA2XX_U_BASE, MCSPI1_RX_EVENT); /* Disable McSPI Receive event */ McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAR_MASK, MCSPI_CH_NUM); /* Disable Edma Transfer */ EDMA3DisableTransfer(EDMA_TDA2XX_U_BASE, MCSPI1_RX_EVENT, EDMA3_TRIG_MODE_EVENT); flagRx = 1; } } else if (pendingHIrqs) { txEventHighNo = MCSPI1_TX_EVENT - 32; rxEventHighNo = MCSPI1_RX_EVENT - 32; if ((pendingHIrqs & (0x01 << txEventHighNo))) { /* clear the pending error interrupt */ EDMA3ClrMissEvt(EDMA_TDA2XX_U_BASE, MCSPI1_TX_EVENT); /* Disable McSPI Transmit event */ McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAW_MASK, MCSPI_CH_NUM); /* Disable Edma Transfer */ EDMA3DisableTransfer(EDMA_TDA2XX_U_BASE, MCSPI1_TX_EVENT, EDMA3_TRIG_MODE_EVENT); flagTx = 1; } else if ((pendingIrqs & (0x01 << rxEventHighNo))) { /* clear the pending error interrupt */ EDMA3ClrMissEvt(EDMA_TDA2XX_U_BASE, MCSPI1_RX_EVENT); /* Disable McSPI Receive event */ McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAR_MASK, MCSPI_CH_NUM); /* Disable Edma Transfer */ EDMA3DisableTransfer(EDMA_TDA2XX_U_BASE, MCSPI1_RX_EVENT, EDMA3_TRIG_MODE_EVENT); flagRx = 1; } } else { /* Events has to be cross bar mapped */ } } /* ** Call back function. Here we disable the Tx/Rx DMA events of McSPI ** peripheral. */ static void CallBack_McSPI1(uint32_t tccNum, uint32_t status) { if (tccNum == MCSPI1_TX_EVENT) { flagTx = 1; /* Disable McSPI Transmit event */ McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAW_MASK, MCSPI_CH_NUM); } if (tccNum == MCSPI1_RX_EVENT) { flagRx = 1; /* Disable McSPI Receive event */ McSPIDMADisable(MCSPI1_BASE_ADDRESS, MCSPI_CH0CONF_DMAR_MASK, MCSPI_CH_NUM); } } /* ** This function is used to set the PaRAM entries of EDMA3 for the Receive ** event of channel 0 of McSPI1 instance. The corresponding EDMA3 channel ** is also enabled for reception. */ static void McSpi1RxEdmaParamSet(uint32_t tccNum, uint32_t chNum, volatile uint8_t *buffer, uint16_t buffLength, uint32_t destBidxFlag) { EDMA3CCPaRAMEntry paramSet = { 0 }; /* Fill the PaRAM Set with Receive specific information.*/ /* srcAddr holds address of SPI Rx FIFO.*/ paramSet.srcAddr = (uint32_t) (MCSPI1_RX0_REG); /* destAddr is address of memory location named buffer.*/ paramSet.destAddr = (uint32_t) buffer; /* aCnt holds the number of bytes in an array.*/ paramSet.aCnt = 1; /* bCnt holds the number of such arrays to be transferred.*/ paramSet.bCnt = buffLength; /* cCnt holds the number of frames of aCnt*bBcnt bytes to be transferred.*/ paramSet.cCnt = 1; /* The srcBidx should not be incremented since it is a h/w register.*/ paramSet.srcBIdx = 0; if (TRUE == destBidxFlag) { /* The destBidx should be incremented for every byte.*/ paramSet.destBIdx = 1; } else { /* The destBidx should not be incremented.*/ paramSet.destBIdx = 0; } /* A sync Transfer Mode. */ /* srCIdx and destCIdx set to zero since ASYNC Mode is used.*/ paramSet.srcCIdx = 0; paramSet.destCIdx = 0; /* Linking transfers in EDMA3 are not used.*/ paramSet.linkAddr = 0xFFFF; paramSet.bCntReload = 0; paramSet.opt = 0x00000000; /* Set TCC field in OPT with the tccNum.*/ paramSet.opt |= ((tccNum << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK); /* EDMA3 Interrupt is enabled and Intermediate Interrupt Disabled.*/ paramSet.opt |= (1 << EDMA_TPCC_OPT_TCINTEN_SHIFT); /* Now write the PaRam Set to EDMA3.*/ EDMA3SetPaRAM(EDMA_TDA2XX_U_BASE, chNum, ¶mSet); /* EDMA3 Transfer is Enabled.*/ EDMA3EnableTransfer(EDMA_TDA2XX_U_BASE, chNum, EDMA3_TRIG_MODE_EVENT); } /* ** This function is used to set the PaRAM entries of EDMA3 for the Transmit ** Channel 0 of SPI1 instance. The corresponding EDMA3 channel is also enabled ** for transmission. */ static void McSpi1TxEdmaParamSet(uint32_t tccNum, uint32_t chNum, volatile uint8_t *buffer, uint16_t buffLength) { EDMA3CCPaRAMEntry paramSet = { 0 }; /* Fill the PaRAM Set with transfer specific information. */ /* srcAddr holds address of memory location buffer. */ paramSet.srcAddr = (uint32_t) buffer; /* destAddr holds address of McSPI_TX register. */ paramSet.destAddr = (uint32_t) (MCSPI1_TX0_REG); /* aCnt holds the number of bytes in an array. */ paramSet.aCnt = 1; /* bCnt holds the number of such arrays to be transferred. */ paramSet.bCnt = buffLength; /* cCnt holds the number of frames of aCnt*bBcnt bytes to be transferred. */ paramSet.cCnt = 1; /* ** The srcBidx should be incremented by aCnt number of bytes since the ** source used here is memory. */ paramSet.srcBIdx = 1; paramSet.destBIdx = 0; /* Async Transfer Mode is set in OPT.*/ /* srCIdx and destCIdx set to zero since ASYNC Mode is used. */ paramSet.srcCIdx = 0; paramSet.destCIdx = 0; /* Linking transfers in EDMA3 are not used. */ paramSet.linkAddr = (EDMA3CC_OPT(DUMMY_CH_NUM)); paramSet.bCntReload = 0; paramSet.opt = 0x00000000; /* SAM and DAM fields both are set to 0 */ /* Set TCC field in OPT with the tccNum. */ paramSet.opt |= ((tccNum << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK); /* EDMA3 Interrupt is enabled and Intermediate Interrupt Disabled.*/ paramSet.opt |= (1 << EDMA_TPCC_OPT_TCINTEN_SHIFT); /* Now write the PaRam Set to EDMA3.*/ EDMA3SetPaRAM(EDMA_TDA2XX_U_BASE, chNum, ¶mSet); /* Dummy param set is enabled */ TxDummyPaRAMConfEnable(); /* EDMA3 Transfer is Enabled. */ EDMA3EnableTransfer(EDMA_TDA2XX_U_BASE, chNum, EDMA3_TRIG_MODE_EVENT); } /* ** This function allocates EDMA3 channels to McSPI0 for trasmisssion and ** reception purposes. */ static void RequestEDMA3Channels(void) { /* Request DMA Channel and TCC for SPI Transmit*/ EDMA3RequestChannel(EDMA_TDA2XX_U_BASE, EDMA3_CHANNEL_TYPE_DMA, MCSPI1_TX_EVENT, MCSPI1_TX_EVENT, EVT_QUEQUE_NUM); /* Request DMA Channel and TCC for SPI Receive*/ EDMA3RequestChannel(EDMA_TDA2XX_U_BASE, EDMA3_CHANNEL_TYPE_DMA, MCSPI1_RX_EVENT, MCSPI1_RX_EVENT, EVT_QUEQUE_NUM); } /* ** This function configures the AINTC to receive EDMA3 interrupts. */ static void EDMA3IntConfigure(void) { /* Initialize DSP interrupt controller and enable interrupts */ // IntDSPINTCInit(); // IntGlobalEnable(); // // /* Map EDMA events to DSP interrupts */ // IntRegister(4, Edma3ComplHandlerIsr); // IntEventMap(4, SYS_INT_EDMACOMPINT); // IntEnable(4); // // IntRegister(5, Edma3ErrorHandlerIsr); // IntEventMap(5, SYS_INT_EDMAERRINT); // IntEnable(5); Error_Block eb; Error_init(&eb); Hwi_Handle myHwi1 = NULL, myHwi2 = NULL; Hwi_Params myhwiParams; Hwi_Params_init(&myhwiParams); myhwiParams.eventId = 16; myHwi1 = Hwi_create(12, Edma3ComplHandlerIsr, &myhwiParams, &eb); if (NULL == myHwi1) { System_printf("Hwi create failed!\n"); } Hwi_enableInterrupt(12); myhwiParams.eventId = 27; myHwi2 = Hwi_create(13, Edma3ErrorHandlerIsr, &myhwiParams, &eb); if (NULL == myHwi2) { System_printf("Hwi create failed!\n"); } Hwi_enableInterrupt(13); } /* ** This configures the PaRAM set for the Dummy Transfer. */ static void TxDummyPaRAMConfEnable(void) { EDMA3CCPaRAMEntry dummyPaRAMSet; EDMA3GetPaRAM(EDMA_TDA2XX_U_BASE, DUMMY_CH_NUM, &dummyPaRAMSet); dummyPaRAMSet.aCnt = 1; dummyPaRAMSet.bCnt = 0; dummyPaRAMSet.cCnt = 0; dummyPaRAMSet.srcAddr = 0; dummyPaRAMSet.destAddr = 0; dummyPaRAMSet.srcBIdx = 0; dummyPaRAMSet.destBIdx = 0; dummyPaRAMSet.srcCIdx = 0; dummyPaRAMSet.destCIdx = 0; dummyPaRAMSet.linkAddr = 0xFFFFU; dummyPaRAMSet.bCntReload = 0; dummyPaRAMSet.opt = 0; EDMA3SetPaRAM(EDMA_TDA2XX_U_BASE, DUMMY_CH_NUM, &dummyPaRAMSet); } static void mainMenu(char *option) { while (1) { if ((MCSPI_MASTERSLAVE_POLLED_MODE_TEST == *option) || (MCSPI_MASTERSLAVE_DMA_MODE_TEST == *option) || EXIT(*option)) { break; } else { } } } /********************************* End Of File ******************************/
感谢回复,要传输的数据是一个放在全局数组里面,并且设置32字节对齐和128字节对齐都测试过
数据是放在片上RAM还是片外DDR里的?
EDMA还是能传输数据的,只是有延时,我觉得基本配置是正确的。
感谢回复,我在调试时看到rxbuff的地址是0x951827c0,tx的地址是0x95182cc0。
rsc_table_vayu_dsp如下:
/* * Copyright (c) 2017, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== rsc_table_dsp.h ======== * * Define the resource table entries for all DSP cores. This will be * incorporated into corresponding base images, and used by the remoteproc * on the host-side to allocated/reserve resources. * */ #ifndef _RSC_TABLE_DSP_H_ #define _RSC_TABLE_DSP_H_ #include <ti/ipc/remoteproc/rsc_types.h> /* DSP Memory Map */ #define L4_DRA7XX_BASE 0x4A000000 #define L4_PERIPHERAL_L4CFG (L4_DRA7XX_BASE) #define DSP_PERIPHERAL_L4CFG 0x4A000000 #define L4_PERIPHERAL_L4PER1 0x48000000 #define DSP_PERIPHERAL_L4PER1 0x48000000 #define L4_PERIPHERAL_L4PER2 0x48400000 #define DSP_PERIPHERAL_L4PER2 0x48400000 #define L4_PERIPHERAL_L4PER3 0x48800000 #define DSP_PERIPHERAL_L4PER3 0x48800000 #define L4_PERIPHERAL_L4EMU 0x54000000 #define DSP_PERIPHERAL_L4EMU 0x54000000 #define L3_PERIPHERAL_DMM 0x4E000000 #define DSP_PERIPHERAL_DMM 0x4E000000 #define L3_TILER_MODE_0_1 0x60000000 #define DSP_TILER_MODE_0_1 0x60000000 #define L3_TILER_MODE_2 0x70000000 #define DSP_TILER_MODE_2 0x70000000 #define L3_TILER_MODE_3 0x78000000 #define DSP_TILER_MODE_3 0x78000000 #define DSP_MEM_TEXT 0x95000000 /* Co-locate alongside TILER region for easier flushing */ #define DSP_MEM_IOBUFS 0x80000000 #define DSP_MEM_DATA 0x95100000 #define DSP_MEM_HEAP 0x95200000 #define DSP_MEM_IPC_DATA 0x9F000000 #define DSP_MEM_IPC_VRING 0x99000000 #define DSP_MEM_RPMSG_VRING0 0x99000000 #define DSP_MEM_RPMSG_VRING1 0x99004000 #define DSP_MEM_VRING_BUFS0 0x99040000 #define DSP_MEM_VRING_BUFS1 0x99080000 #define DSP_MEM_IPC_VRING_SIZE SZ_1M #define DSP_MEM_IPC_DATA_SIZE SZ_1M #define DSP_MEM_TEXT_SIZE SZ_1M #define DSP_MEM_DATA_SIZE SZ_1M #define DSP_MEM_HEAP_SIZE (SZ_1M * 3) #define DSP_MEM_IOBUFS_SIZE (SZ_1M * 90) /* NOTE: Make sure this matches what is configured in the linux device tree */ #define DSP_CMEM_IOBUFS 0xA0000000 #define PHYS_CMEM_IOBUFS 0xA0000000 #define DSP_CMEM_IOBUFS_SIZE (SZ_1M * 192) /* * Assign fixed RAM addresses to facilitate a fixed MMU table. */ #define VAYU_DSP_1 /* See CMA BASE addresses in Linux side: arch/arm/mach-omap2/remoteproc.c */ #if defined (VAYU_DSP_1) #define PHYS_MEM_IPC_VRING 0x99000000 #elif defined (VAYU_DSP_2) #define PHYS_MEM_IPC_VRING 0x9F000000 #endif /* Need to be identical to that of IPU */ #define PHYS_MEM_IOBUFS 0xBA300000 /* * Sizes of the virtqueues (expressed in number of buffers supported, * and must be power of 2) */ #define DSP_RPMSG_VQ0_SIZE 256 #define DSP_RPMSG_VQ1_SIZE 256 /* flip up bits whose indices represent features we support */ #define RPMSG_DSP_C0_FEATURES 1 struct my_resource_table { struct resource_table base; UInt32 offset[18]; /* Should match 'num' in actual definition */ /* rpmsg vdev entry */ struct fw_rsc_vdev rpmsg_vdev; struct fw_rsc_vdev_vring rpmsg_vring0; struct fw_rsc_vdev_vring rpmsg_vring1; /* text carveout entry */ struct fw_rsc_carveout text_cout; /* data carveout entry */ struct fw_rsc_carveout data_cout; /* heap carveout entry */ struct fw_rsc_carveout heap_cout; /* ipcdata carveout entry */ struct fw_rsc_carveout ipcdata_cout; /* trace entry */ struct fw_rsc_trace trace; /* devmem entry */ struct fw_rsc_devmem devmem0; /* devmem entry */ struct fw_rsc_devmem devmem1; /* devmem entry */ struct fw_rsc_devmem devmem2; /* devmem entry */ struct fw_rsc_devmem devmem3; /* devmem entry */ struct fw_rsc_devmem devmem4; /* devmem entry */ struct fw_rsc_devmem devmem5; /* devmem entry */ struct fw_rsc_devmem devmem6; /* devmem entry */ struct fw_rsc_devmem devmem7; /* devmem entry */ struct fw_rsc_devmem devmem8; /* devmem entry */ struct fw_rsc_devmem devmem9; /* devmem entry */ struct fw_rsc_devmem devmem10; /* devmem entry */ struct fw_rsc_devmem devmem11; }; extern char ti_trace_SysMin_Module_State_0_outbuf__A; #define TRACEBUFADDR (UInt32)&ti_trace_SysMin_Module_State_0_outbuf__A #pragma DATA_SECTION(ti_ipc_remoteproc_ResourceTable, ".resource_table") #pragma DATA_ALIGN(ti_ipc_remoteproc_ResourceTable, 4096) struct my_resource_table ti_ipc_remoteproc_ResourceTable = { 1, /* we're the first version that implements this */ 18, /* number of entries in the table */ 0, 0, /* reserved, must be zero */ /* offsets to entries */ { offsetof(struct my_resource_table, rpmsg_vdev), offsetof(struct my_resource_table, text_cout), offsetof(struct my_resource_table, data_cout), offsetof(struct my_resource_table, heap_cout), offsetof(struct my_resource_table, ipcdata_cout), offsetof(struct my_resource_table, trace), offsetof(struct my_resource_table, devmem0), offsetof(struct my_resource_table, devmem1), offsetof(struct my_resource_table, devmem2), offsetof(struct my_resource_table, devmem3), offsetof(struct my_resource_table, devmem4), offsetof(struct my_resource_table, devmem5), offsetof(struct my_resource_table, devmem6), offsetof(struct my_resource_table, devmem7), offsetof(struct my_resource_table, devmem8), offsetof(struct my_resource_table, devmem9), offsetof(struct my_resource_table, devmem10), offsetof(struct my_resource_table, devmem11), }, /* rpmsg vdev entry */ { TYPE_VDEV, VIRTIO_ID_RPMSG, 0, RPMSG_DSP_C0_FEATURES, 0, 0, 0, 2, { 0, 0 }, /* no config data */ }, /* the two vrings */ { DSP_MEM_RPMSG_VRING0, 4096, DSP_RPMSG_VQ0_SIZE, 1, 0 }, { DSP_MEM_RPMSG_VRING1, 4096, DSP_RPMSG_VQ1_SIZE, 2, 0 }, { TYPE_CARVEOUT, DSP_MEM_TEXT, 0, DSP_MEM_TEXT_SIZE, 0, 0, "DSP_MEM_TEXT", }, { TYPE_CARVEOUT, DSP_MEM_DATA, 0, DSP_MEM_DATA_SIZE, 0, 0, "DSP_MEM_DATA", }, { TYPE_CARVEOUT, DSP_MEM_HEAP, 0, DSP_MEM_HEAP_SIZE, 0, 0, "DSP_MEM_HEAP", }, { TYPE_CARVEOUT, DSP_MEM_IPC_DATA, 0, DSP_MEM_IPC_DATA_SIZE, 0, 0, "DSP_MEM_IPC_DATA", }, { TYPE_TRACE, TRACEBUFADDR, 0x8000, 0, "trace:dsp", }, { TYPE_DEVMEM, DSP_MEM_IPC_VRING, PHYS_MEM_IPC_VRING, DSP_MEM_IPC_VRING_SIZE, 0, 0, "DSP_MEM_IPC_VRING", }, { TYPE_DEVMEM, DSP_MEM_IOBUFS, PHYS_MEM_IOBUFS, DSP_MEM_IOBUFS_SIZE, 0, 0, "DSP_MEM_IOBUFS", }, { TYPE_DEVMEM, DSP_TILER_MODE_0_1, L3_TILER_MODE_0_1, SZ_256M, 0, 0, "DSP_TILER_MODE_0_1", }, { TYPE_DEVMEM, DSP_TILER_MODE_2, L3_TILER_MODE_2, SZ_128M, 0, 0, "DSP_TILER_MODE_2", }, { TYPE_DEVMEM, DSP_TILER_MODE_3, L3_TILER_MODE_3, SZ_128M, 0, 0, "DSP_TILER_MODE_3", }, { TYPE_DEVMEM, DSP_PERIPHERAL_L4CFG, L4_PERIPHERAL_L4CFG, SZ_16M, 0, 0, "DSP_PERIPHERAL_L4CFG", }, { TYPE_DEVMEM, DSP_PERIPHERAL_L4PER1, L4_PERIPHERAL_L4PER1, SZ_2M, 0, 0, "DSP_PERIPHERAL_L4PER1", }, { TYPE_DEVMEM, DSP_PERIPHERAL_L4PER2, L4_PERIPHERAL_L4PER2, SZ_4M, 0, 0, "DSP_PERIPHERAL_L4PER2", }, { TYPE_DEVMEM, DSP_PERIPHERAL_L4PER3, L4_PERIPHERAL_L4PER3, SZ_8M, 0, 0, "DSP_PERIPHERAL_L4PER3", }, { TYPE_DEVMEM, DSP_PERIPHERAL_L4EMU, L4_PERIPHERAL_L4EMU, SZ_16M, 0, 0, "DSP_PERIPHERAL_L4EMU", }, { TYPE_DEVMEM, DSP_PERIPHERAL_DMM, L3_PERIPHERAL_DMM, SZ_1M, 0, 0, "DSP_PERIPHERAL_DMM", }, { TYPE_DEVMEM, DSP_CMEM_IOBUFS, PHYS_CMEM_IOBUFS, DSP_CMEM_IOBUFS_SIZE, 0, 0, "DSP_CMEM_IOBUFS", }, }; #endif /* _RSC_TABLE_DSP_H_ */
config.bld如下:
/* * Copyright (c) 2013-2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== config.bld ======== * */ var Build = xdc.useModule('xdc.bld.BuildEnvironment'); /* Memory Map for ti.platforms.evmDRA7XX:dsp1 and ti.platforms.evmDRA7XX:dsp2 * * --- External Memory --- * Virtual Physical Size Comment * ------------------------------------------------------------------------ * 9500_4000 ????_???? 10_0000 ( ~1 MB) EXT_CODE * 9510_0000 ????_???? 10_0000 ( 1 MB) EXT_DATA * 9520_0000 ????_???? 30_0000 ( 3 MB) EXT_HEAP * 9F00_0000 9F00_0000 6_0000 ( 384 kB) TRACE_BUF * 9F06_0000 9F06_0000 1_0000 ( 64 kB) EXC_DATA * 9F07_0000 9F07_0000 2_0000 ( 128 kB) PM_DATA (Power mgmt) */ var evmDRA7XX_ExtMemMapDsp = { EXT_CODE: { name: "EXT_CODE", base: 0x95000000, len: 0x00100000, space: "code", access: "RWX" }, EXT_DATA: { name: "EXT_DATA", base: 0x95100000, len: 0x00100000, space: "data", access: "RW" }, EXT_HEAP: { name: "EXT_HEAP", base: 0x95200000, len: 0x00300000, space: "data", access: "RW" }, TRACE_BUF: { name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW" }, EXC_DATA: { name: "EXC_DATA", base: 0x9F060000, len: 0x00010000, space: "data", access: "RW" }, PM_DATA: { name: "PM_DATA", base: 0x9F070000, len: 0x00020000, space: "data", access: "RWX" /* should this have execute perm? */ }, }; Build.platformTable["ti.platforms.evmDRA7XX:dsp1"] = { externalMemoryMap: [ [ "EXT_CODE", evmDRA7XX_ExtMemMapDsp.EXT_CODE ], [ "EXT_DATA", evmDRA7XX_ExtMemMapDsp.EXT_DATA ], [ "EXT_HEAP", evmDRA7XX_ExtMemMapDsp.EXT_HEAP ], [ "TRACE_BUF", evmDRA7XX_ExtMemMapDsp.TRACE_BUF ], [ "EXC_DATA", evmDRA7XX_ExtMemMapDsp.EXC_DATA ], [ "PM_DATA", evmDRA7XX_ExtMemMapDsp.PM_DATA ], ], codeMemory: "EXT_CODE", dataMemory: "EXT_DATA", stackMemory: "EXT_DATA", }; Build.platformTable["ti.platforms.evmDRA7XX:dsp2"] = Build.platformTable["ti.platforms.evmDRA7XX:dsp1"]; /* Memory Map for ti.platforms.evmDRA7XX:ipu2 * * --- External Memory --- * Virtual Physical Size Comment * ------------------------------------------------------------------------ * 0000_4000 ????_???? 5F_C000 ( ~6 MB) EXT_CODE * 8000_0000 ????_???? 60_0000 ( 6 MB) EXT_DATA * 8060_0000 ????_???? 960_0000 ( 86 MB) EXT_HEAP * 9F00_0000 9F00_0000 6_0000 ( 384 kB) TRACE_BUF * 9F06_0000 9F06_0000 1_0000 ( 64 kB) EXC_DATA * 9F07_0000 9F07_0000 2_0000 ( 128 kB) PM_DATA (Power mgmt) */ var evmDRA7XX_ExtMemMapIpu2 = { EXT_CODE: { name: "EXT_CODE", base: 0x00004000, len: 0x005FC000, space: "code", access: "RWX" }, EXT_DATA: { name: "EXT_DATA", base: 0x80000000, len: 0x00600000, space: "data", access: "RW" }, EXT_HEAP: { name: "EXT_HEAP", base: 0x80600000, len: 0x09600000, space: "data", access: "RW" }, TRACE_BUF: { name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW" }, EXC_DATA: { name: "EXC_DATA", base: 0x9F060000, len: 0x00010000, space: "data", access: "RW" }, PM_DATA: { name: "PM_DATA", base: 0x9F070000, len: 0x00020000, space: "data", access: "RWX" /* should this have execute perm? */ } }; Build.platformTable["ti.platforms.evmDRA7XX:ipu2"] = { externalMemoryMap: [ [ "EXT_CODE", evmDRA7XX_ExtMemMapIpu2.EXT_CODE ], [ "EXT_DATA", evmDRA7XX_ExtMemMapIpu2.EXT_DATA ], [ "EXT_HEAP", evmDRA7XX_ExtMemMapIpu2.EXT_HEAP ], [ "TRACE_BUF", evmDRA7XX_ExtMemMapIpu2.TRACE_BUF ], [ "EXC_DATA", evmDRA7XX_ExtMemMapIpu2.EXC_DATA ], [ "PM_DATA", evmDRA7XX_ExtMemMapIpu2.PM_DATA ] ], codeMemory: "EXT_CODE", dataMemory: "EXT_DATA", stackMemory: "EXT_DATA", }; /* Memory Map for ti.platforms.evmDRA7XX:ipu1 * * --- External Memory --- * Virtual Physical Size Comment * ------------------------------------------------------------------------ * 0000_4000 ????_???? F_C000 ( ~1 MB) EXT_CODE * 8000_0000 ????_???? 20_0000 ( 2 MB) EXT_DATA * 8020_0000 ????_???? 30_0000 ( 3 MB) EXT_HEAP * 9F00_0000 9F00_0000 6_0000 ( 384 kB) TRACE_BUF * 9F06_0000 9F06_0000 1_0000 ( 64 kB) EXC_DATA * 9F07_0000 9F07_0000 2_0000 ( 128 kB) PM_DATA (Power mgmt) */ var evmDRA7XX_ExtMemMapIpu1 = { EXT_CODE: { name: "EXT_CODE", base: 0x00004000, len: 0x000FC000, space: "code", access: "RWX" }, EXT_DATA: { name: "EXT_DATA", base: 0x80000000, len: 0x00200000, space: "data", access: "RW" }, EXT_HEAP: { name: "EXT_HEAP", base: 0x80200000, len: 0x00300000, space: "data", access: "RW" }, TRACE_BUF: { name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW" }, EXC_DATA: { name: "EXC_DATA", base: 0x9F060000, len: 0x00010000, space: "data", access: "RW" }, PM_DATA: { name: "PM_DATA", base: 0x9F070000, len: 0x00020000, space: "data", access: "RWX" /* should this have execute perm? */ } }; Build.platformTable["ti.platforms.evmDRA7XX:ipu1"] = { externalMemoryMap: [ [ "EXT_CODE", evmDRA7XX_ExtMemMapIpu1.EXT_CODE ], [ "EXT_DATA", evmDRA7XX_ExtMemMapIpu1.EXT_DATA ], [ "EXT_HEAP", evmDRA7XX_ExtMemMapIpu1.EXT_HEAP ], [ "TRACE_BUF", evmDRA7XX_ExtMemMapIpu1.TRACE_BUF ], [ "EXC_DATA", evmDRA7XX_ExtMemMapIpu1.EXC_DATA ], [ "PM_DATA", evmDRA7XX_ExtMemMapIpu1.PM_DATA ] ], codeMemory: "EXT_CODE", dataMemory: "EXT_DATA", stackMemory: "EXT_DATA", };
linker.cmd如下:
/* * Do not modify this file; it is automatically generated from the template * linkcmd.xdt in the ti.targets.elf package and will be overwritten. */ /* * put '"'s around paths because, without this, the linker * considers '-' as minus operator, not a file name character. */ -l"R:\tmpdesktop\A390_C6000_Project\Debug\configPkg\package\cfg\A390_pe66.oe66" -l"R:\tmpdesktop\A390_C6000_Project\TiConfig\source\src\ipc\ipc.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\ipc_3_50_04_08\packages\ti\pm\lib\release\ti.pm_null.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\edma3_lld_2_12_05_30E\packages\ti\sdo\edma3\drv\sample\lib\tda2xx-evm\66\release\edma3_lld_drv_sample.ae66" -l"R:\tmpdesktop\A390_C6000_Project\TiConfig\source\src\utils\utils.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\board\lib\idkAM571x\c66\release\ti.board.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\drv\i2c\lib\c66\release\ti.drv.i2c.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\drv\uart\lib\c66\release\ti.drv.uart.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\drv\gpio\lib\am571x\c66\release\ti.drv.gpio.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\osal\lib\tirtos\c66\release\ti.osal.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\pdk_am57xx_1_0_18\packages\ti\csl\lib\am571x\c66\release\ti.csl.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\ipc_3_50_04_08\packages\ti\deh\lib\release\ti.deh_vayu.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\bios_6_76_03_01\packages\ti\targets\rts6000\lib\ti.targets.rts6000.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\bios_6_76_03_01\packages\ti\targets\rts6000\lib\boot.ae66" -l"R:\tmpdesktop\A390_C6000_Project\TiConfig\source\src\sysbios\sysbios.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\ipc_3_50_04_08\packages\ti\trace\lib\release\ti.trace.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\edma3_lld_2_12_05_30E\packages\ti\sdo\edma3\drv\lib\66\release\edma3_lld_drv.ae66" -l"D:\ti\processor_sdk_rtos_am57xx_06_03_02_08\edma3_lld_2_12_05_30E\packages\ti\sdo\edma3\rm\lib\tda2xx-evm\66\release\edma3_lld_rm.ae66" --retain="*(xdc.meta)" --args 0x0 -heap 0x0 -stack 0x1000 MEMORY { L2SRAM (RWX) : org = 0x800000, len = 0x48000 OCMC_RAM1 (RWX) : org = 0x40300000, len = 0x80000 OCMC_RAM2 (RWX) : org = 0x40400000, len = 0x100000 OCMC_RAM3 (RWX) : org = 0x40500000, len = 0x100000 EXT_CODE (RWX) : org = 0x95000000, len = 0x100000 EXT_DATA (RW) : org = 0x95100000, len = 0x100000 EXT_HEAP (RW) : org = 0x95200000, len = 0x300000 TRACE_BUF (RW) : org = 0x9f000000, len = 0x60000 EXC_DATA (RW) : org = 0x9f060000, len = 0x10000 PM_DATA (RWX) : org = 0x9f070000, len = 0x20000 } /* * Linker command file contributions from all loaded packages: */ /* Content from xdc.services.global (null): */ /* Content from xdc (null): */ /* Content from xdc.corevers (null): */ /* Content from xdc.rov (null): */ /* Content from xdc.shelf (null): */ /* Content from xdc.services.spec (null): */ /* Content from xdc.services.intern.xsr (null): */ /* Content from xdc.services.intern.gen (null): */ /* Content from xdc.services.intern.cmd (null): */ /* Content from xdc.bld (null): */ /* Content from ti.targets (null): */ /* Content from ti.targets.elf (null): */ /* Content from xdc.services.getset (null): */ /* Content from ti.sdo.ipc.family (null): */ /* Content from ti.sdo.edma3.rm (null): */ /* Content from ti.sdo.edma3.drv (null): */ /* Content from ti.catalog.c6000 (null): */ /* Content from ti.catalog (null): */ /* Content from ti.catalog.peripherals.hdvicp2 (null): */ /* Content from xdc.platform (null): */ /* Content from xdc.cfg (null): */ /* Content from ti.catalog.arp32 (null): */ /* Content from ti.catalog.arm.cortexm4 (null): */ /* Content from ti.catalog.arm.cortexa15 (null): */ /* Content from ti.platforms.evmDRA7XX (null): */ /* Content from ti.trace (null): */ /* Content from ti.sysbios.hal (null): */ /* Content from ti.sysbios.interfaces (null): */ /* Content from xdc.runtime (null): */ /* Content from ti.sysbios.knl (null): */ /* Content from ti.sysbios (null): */ /* Content from ti.sysbios.family.c64p (ti/sysbios/family/c64p/linkcmd.xdt): */ /* Content from ti.sysbios.family.c66 (ti/sysbios/family/c66/linkcmd.xdt): */ ti_sysbios_family_c66_Cache_l1dSize = 32768; ti_sysbios_family_c66_Cache_l1pSize = 32768; ti_sysbios_family_c66_Cache_l2Size = 0; /* Content from ti.sysbios.rts (null): */ /* Content from ti.sysbios.rts.ti (ti/sysbios/rts/ti/linkcmd.xdt): */ /* Content from ti.sysbios.family (null): */ /* Content from xdc.rov.runtime (null): */ /* Content from ti.targets.rts6000 (null): */ /* Content from ti.deh (null): */ /* Content from ti.sysbios.timers.dmtimer (null): */ /* Content from ti.sysbios.family.shared.vayu (null): */ /* Content from ti.csl (null): */ /* Content from ti.osal (null): */ /* Content from ti.drv.gpio (null): */ /* Content from ti.drv.uart (null): */ /* Content from ti.drv.i2c (null): */ /* Content from ti.board (null): */ /* Content from ti.sysbios.gates (null): */ /* Content from ti.sysbios.heaps (null): */ /* Content from xdc.runtime.knl (null): */ /* Content from ti.sdo.utils (null): */ /* Content from ti.sdo.ipc.interfaces (null): */ /* Content from ti.sysbios.syncs (null): */ /* Content from ti.sdo.edma3.drv.sample (null): */ /* Content from ti.sysbios.family.c62 (null): */ /* Content from ti.sysbios.xdcruntime (null): */ /* Content from ti.pm (null): */ /* Content from ti.sysbios.utils (null): */ /* Content from ti.ipc.remoteproc (ti/ipc/remoteproc/linkcmd.xdt): */ /* * Set entry point to the HWI reset vector 0 to automatically satisfy * any alignment constraints for the boot vector. */ -eti_sysbios_family_c64p_Hwi0 /* * We just modified the entry point, so suppress "entry point symbol other * than _c_int00 specified" warning. */ --diag_suppress=10063 /* Content from ti.sdo.ipc.family.vayu (null): */ /* Content from ti.sdo.ipc.notifyDrivers (null): */ /* Content from ti.sdo.ipc (ti/sdo/ipc/linkcmd.xdt): */ SECTIONS { ti_sdo_ipc_init: load > EXT_DATA, type = NOINIT } /* Content from ti.ipc.ipcmgr (null): */ /* Content from ti.ipc.transports (null): */ /* Content from ti.ipc.rpmsg (null): */ /* Content from ti.ipc.family.vayu (null): */ /* Content from ti.ipc.namesrv (null): */ /* Content from ti.sdo.ipc.heaps (null): */ /* Content from ti.sdo.ipc.gates (null): */ /* Content from configPkg (null): */ /* Content from xdc.services.io (null): */ /* Content from ti.sdo.ipc.family.ti81xx (null): */ /* * symbolic aliases for static instance objects */ xdc_runtime_Startup__EXECFXN__C = 1; xdc_runtime_Startup__RESETFXN__C = 1; xdc_rov_runtime_Mon__checksum = 1; xdc_rov_runtime_Mon__write = 1; SECTIONS { .text: load >> EXT_CODE .ti.decompress: load > EXT_CODE .stack: load > EXT_DATA GROUP: load > EXT_DATA { .bss: .neardata: .rodata: } .cinit: load > EXT_DATA .pinit: load >> EXT_DATA .init_array: load > EXT_DATA .const: load >> EXT_DATA .data: load >> EXT_DATA .fardata: load >> EXT_DATA .switch: load >> EXT_DATA .sysmem: load > EXT_DATA .far: load >> EXT_DATA .args: load > EXT_DATA align = 0x4, fill = 0 {_argsize = 0x0; } .cio: load >> EXT_DATA .ti.handler_table: load > EXT_DATA .c6xabi.exidx: load > EXT_DATA .c6xabi.extab: load >> EXT_DATA .tracebuf: load > TRACE_BUF .errorbuf: load > EXC_DATA .resource_table: load > 0x95000000, type = NOINIT .vecs: load > EXT_CODE xdc.meta: load > EXT_DATA, type = COPY }
我不太能确认是在片上RAM还是DDR,但看起来应该是在片上RAM区间。
您好,您用我的测试程序运行EDMA能传输数据吗?传输延迟也是很大吗?
另外,我重新配置了DSP核的内存结构,使用了L2SRAM,因为我看到L2SRAM直接连接的EDMA,因此,我将数据放在L2SRAM中,但程序无法运行,运行结果如下:
cat /sys/kernel/debug/remoteproc/remoteproc2/trace0
cat: can't open '/sys/kernel/debug/remoteproc/remoteproc2/trace0': No such file or directory
config.bld配置如下:
/* * Copyright (c) 2013-2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== config.bld ======== * */ var Build = xdc.useModule('xdc.bld.BuildEnvironment'); var evmDRA7XX_L2SRAM = { name: "DSPL2SRAM", space: "data", access: "RWX", base: 0x40808000, len: 0x40000, comment: "sram Memory (256 KB)" }; /* Memory Map for ti.platforms.evmDRA7XX:dsp1 and ti.platforms.evmDRA7XX:dsp2 * * --- External Memory --- * Virtual Physical Size Comment * ------------------------------------------------------------------------ * 9500_4000 ????_???? 10_0000 ( ~1 MB) EXT_CODE * 9510_0000 ????_???? 10_0000 ( 1 MB) EXT_DATA * 9520_0000 ????_???? 30_0000 ( 3 MB) EXT_HEAP * 9F00_0000 9F00_0000 6_0000 ( 384 kB) TRACE_BUF * 9F06_0000 9F06_0000 1_0000 ( 64 kB) EXC_DATA * 9F07_0000 9F07_0000 2_0000 ( 128 kB) PM_DATA (Power mgmt) */ var evmDRA7XX_ExtMemMapDsp = { EXT_CODE: { name: "EXT_CODE", base: 0x95000000, len: 0x00100000, space: "code", access: "RWX" }, EXT_DATA: { name: "EXT_DATA", base: 0x95100000, len: 0x00100000, space: "data", access: "RW" }, EXT_HEAP: { name: "EXT_HEAP", base: 0x95200000, len: 0x00300000, space: "data", access: "RW" }, TRACE_BUF: { name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW" }, EXC_DATA: { name: "EXC_DATA", base: 0x9F060000, len: 0x00010000, space: "data", access: "RW" }, PM_DATA: { name: "PM_DATA", base: 0x9F070000, len: 0x00020000, space: "data", access: "RWX" /* should this have execute perm? */ }, DSPL2SRAM: { name: evmDRA7XX_L2SRAM.name, base: evmDRA7XX_L2SRAM.base, len: evmDRA7XX_L2SRAM.len, space: "data", access: "RW" } }; Build.platformTable["ti.platforms.evmDRA7XX:dsp1"] = { externalMemoryMap: [ [ "EXT_CODE", evmDRA7XX_ExtMemMapDsp.EXT_CODE ], [ "EXT_DATA", evmDRA7XX_ExtMemMapDsp.EXT_DATA ], [ "EXT_HEAP", evmDRA7XX_ExtMemMapDsp.EXT_HEAP ], [ "TRACE_BUF", evmDRA7XX_ExtMemMapDsp.TRACE_BUF ], [ "EXC_DATA", evmDRA7XX_ExtMemMapDsp.EXC_DATA ], [ "PM_DATA", evmDRA7XX_ExtMemMapDsp.PM_DATA ], [ evmDRA7XX_L2SRAM.name, evmDRA7XX_ExtMemMapDsp.DSPL2SRAM ], ], codeMemory: "EXT_CODE", dataMemory: "EXT_DATA", stackMemory: "EXT_DATA", }; Build.platformTable["ti.platforms.evmDRA7XX:dsp2"] = Build.platformTable["ti.platforms.evmDRA7XX:dsp1"]; /* Memory Map for ti.platforms.evmDRA7XX:ipu2 * * --- External Memory --- * Virtual Physical Size Comment * ------------------------------------------------------------------------ * 0000_4000 ????_???? 5F_C000 ( ~6 MB) EXT_CODE * 8000_0000 ????_???? 60_0000 ( 6 MB) EXT_DATA * 8060_0000 ????_???? 960_0000 ( 86 MB) EXT_HEAP * 9F00_0000 9F00_0000 6_0000 ( 384 kB) TRACE_BUF * 9F06_0000 9F06_0000 1_0000 ( 64 kB) EXC_DATA * 9F07_0000 9F07_0000 2_0000 ( 128 kB) PM_DATA (Power mgmt) */ var evmDRA7XX_ExtMemMapIpu2 = { EXT_CODE: { name: "EXT_CODE", base: 0x00004000, len: 0x005FC000, space: "code", access: "RWX" }, EXT_DATA: { name: "EXT_DATA", base: 0x80000000, len: 0x00600000, space: "data", access: "RW" }, EXT_HEAP: { name: "EXT_HEAP", base: 0x80600000, len: 0x09600000, space: "data", access: "RW" }, TRACE_BUF: { name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW" }, EXC_DATA: { name: "EXC_DATA", base: 0x9F060000, len: 0x00010000, space: "data", access: "RW" }, PM_DATA: { name: "PM_DATA", base: 0x9F070000, len: 0x00020000, space: "data", access: "RWX" /* should this have execute perm? */ } }; Build.platformTable["ti.platforms.evmDRA7XX:ipu2"] = { externalMemoryMap: [ [ "EXT_CODE", evmDRA7XX_ExtMemMapIpu2.EXT_CODE ], [ "EXT_DATA", evmDRA7XX_ExtMemMapIpu2.EXT_DATA ], [ "EXT_HEAP", evmDRA7XX_ExtMemMapIpu2.EXT_HEAP ], [ "TRACE_BUF", evmDRA7XX_ExtMemMapIpu2.TRACE_BUF ], [ "EXC_DATA", evmDRA7XX_ExtMemMapIpu2.EXC_DATA ], [ "PM_DATA", evmDRA7XX_ExtMemMapIpu2.PM_DATA ] ], codeMemory: "EXT_CODE", dataMemory: "EXT_DATA", stackMemory: "EXT_DATA", }; /* Memory Map for ti.platforms.evmDRA7XX:ipu1 * * --- External Memory --- * Virtual Physical Size Comment * ------------------------------------------------------------------------ * 0000_4000 ????_???? F_C000 ( ~1 MB) EXT_CODE * 8000_0000 ????_???? 20_0000 ( 2 MB) EXT_DATA * 8020_0000 ????_???? 30_0000 ( 3 MB) EXT_HEAP * 9F00_0000 9F00_0000 6_0000 ( 384 kB) TRACE_BUF * 9F06_0000 9F06_0000 1_0000 ( 64 kB) EXC_DATA * 9F07_0000 9F07_0000 2_0000 ( 128 kB) PM_DATA (Power mgmt) */ var evmDRA7XX_ExtMemMapIpu1 = { EXT_CODE: { name: "EXT_CODE", base: 0x00004000, len: 0x000FC000, space: "code", access: "RWX" }, EXT_DATA: { name: "EXT_DATA", base: 0x80000000, len: 0x00200000, space: "data", access: "RW" }, EXT_HEAP: { name: "EXT_HEAP", base: 0x80200000, len: 0x00300000, space: "data", access: "RW" }, TRACE_BUF: { name: "TRACE_BUF", base: 0x9F000000, len: 0x00060000, space: "data", access: "RW" }, EXC_DATA: { name: "EXC_DATA", base: 0x9F060000, len: 0x00010000, space: "data", access: "RW" }, PM_DATA: { name: "PM_DATA", base: 0x9F070000, len: 0x00020000, space: "data", access: "RWX" /* should this have execute perm? */ } }; Build.platformTable["ti.platforms.evmDRA7XX:ipu1"] = { externalMemoryMap: [ [ "EXT_CODE", evmDRA7XX_ExtMemMapIpu1.EXT_CODE ], [ "EXT_DATA", evmDRA7XX_ExtMemMapIpu1.EXT_DATA ], [ "EXT_HEAP", evmDRA7XX_ExtMemMapIpu1.EXT_HEAP ], [ "TRACE_BUF", evmDRA7XX_ExtMemMapIpu1.TRACE_BUF ], [ "EXC_DATA", evmDRA7XX_ExtMemMapIpu1.EXC_DATA ], [ "PM_DATA", evmDRA7XX_ExtMemMapIpu1.PM_DATA ] ], codeMemory: "EXT_CODE", dataMemory: "EXT_DATA", stackMemory: "EXT_DATA", };
rsc_table_vayu_dsp增加如下行:
#define L2_RAM_BASE 0x40808000
#define DSP_L2_RAM_BASE 0x40808000
#define DSP_L2_RAM_SIZE 0x40000
{
TYPE_DEVMEM,
L2_RAM_BASE, DSP_L2_RAM_BASE,
DSP_L2_RAM_SIZE, 0, 0, "DSP_L2_RAM_BASE",
},
cfg文件增加如下行:
Program.sectMap[".l2sram"] = "DSPL2SRAM";
缓冲区更改如下:
/*
* 变量作用:MCSPI发送数据缓冲区
* 变量范围:无
* 访问说明:访问函数:xgMcspiTransfer,访问方法:赋值拷贝
*/
#pragma DATA_SECTION (s_acTxBuff,".l2sram")
#pragma DATA_ALIGN (s_acTxBuff,128)
char s_acTxBuff[MCSPI_DATA_COUNT ] = { "123456789" };
/*
* 变量作用:MCSPI接收数据缓冲区
* 变量范围:无
* 访问说明:访问函数 xgMcspiTransfer,访问方法:赋值拷贝
*/
#pragma DATA_SECTION (s_acRxBuff,".l2sram")
#pragma DATA_ALIGN (s_acRxBuff,128)
char s_acRxBuff[MCSPI_DATA_COUNT ] = { 0 };
我不确定是不是内存区域的问题,但我也正在尝试各种办法,如果您有任何参考意见都请告诉我,感谢!
抱歉,我手头没有板子。您可以到e2e英文论坛上问一下产品线工程师。
https://e2e.ti.com/support/processors-group/
0x951827c0这块地址是DDR3,可以尝试打开cache,看速度是否能加快。
感谢回复,我没有e2e论坛发帖的权限,您能把我的情况发给产品线工程师吗?
我目前是没有触发EDMA传输,还在查找问题在哪里,而我使用L2SRAM作为存储区依然没有成功。
您可以用公司或者学校邮箱注册登录英文e2e。
把您的问题转到e2e了,请关注下面帖子的回复。
https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1082545/am5718-spi-transfer-delay-when-using-edma
您好,我想到了一个可能性,由于是AM5718的DSP核,而不是单独的DSP,因此没有调用Board_init(),否则A15无法正常运行,所以只是初始化了SPI时钟和引脚模式,这有可能导致EDMA无法触发吗?EDMA也需要硬件初始化吗?
初始化SPI时钟和引脚程序如下:
void PinmuxMCSPIConfig()
{
/* Power on SPI1*/
HW_WR_REG32(0x4a0097f0, 0x02);
while (HW_RD_REG32(0x4a0097f0) != 0x02U)
{
;
}
/* SPI1_SCLK */
HW_WR_REG32((CSL_MPU_CORE_PAD_IO_REGISTERS_REGS + CTRL_CORE_PAD_SPI1_SCLK),0x000C0000);
/* SPI1_D0 */
HW_WR_REG32((CSL_MPU_CORE_PAD_IO_REGISTERS_REGS + CTRL_CORE_PAD_SPI1_D0),0x000C0000);
/* SPI1_D1 */
HW_WR_REG32((CSL_MPU_CORE_PAD_IO_REGISTERS_REGS + CTRL_CORE_PAD_SPI1_D1),0x000C0000);
/* SPI1_CS0 */
HW_WR_REG32((CSL_MPU_CORE_PAD_IO_REGISTERS_REGS + CTRL_CORE_PAD_SPI1_CS0),0x00060000);
}
感谢回复,我只能通过手动触发EDMA传输SPI的数据,但无法使用事件触发EDMA,这样说也对,EDMA确实工作了,只是不能通过事件触发以及延时较大。
最新进展:测试出的延迟主要来自于开关SPI的EDMA传输通道。
感谢关注问题,我通过手动触发EDMA,但是我把回调函数中的关闭通道屏蔽,发现传输的波形很连续(虽然数据是错的),但是我取消屏蔽关闭通道时,波形就不再连续了。
虽然手动能够传输数据,但是数据始终是错误的,最多只能重复传输4个字节的内容,也就是SPI配置的传输字长32bit,其实就是将TX寄存器32bit的数据一直重复传输出去,接收方收到的始终是这4个字节。
我在尝试修改底层的SPI_DMA.c的代码,希望能实现手动快速且正确地传输数据(事件实在想不到办法触发EDMA了)。
您好,在我换方案使用mcasp来替代SPI的时候发现了一个问题,我没有配置SPI的资源表和EDMA的资源表。
解决方案如下帖子:
https://e2echina.ti.com/support/processors/f/processors-forum/218129/am5718-mcasp
https://e2echina.ti.com/support/processors/f/processors-forum/218724/am5718-dsp-mcasp-edma
再次感谢!