Other Parts Discussed in Thread: SYSBIOS
1 cfg文件:
/* ================ Driver configuration ================ */
var Edma = xdc.loadPackage ("ti.sdo.edma3.drv.sample");
var drv = xdc.loadPackage ("ti.sdo.edma3.drv");
var rm = xdc.loadPackage ("ti.sdo.edma3.rm");
/* Load the SPI package */
var Spi = xdc.loadPackage('ti.drv.spi');//其实这里也有一个问题,这里是不是应用使用ti.drv.spi.dma
Spi.Settings.enableProfiling = true;
Spi.Settings.socType = socType;
Spi.Settings.useDma = "true";
var Hwi= xdc.useModule('ti.sysbios.family.c64p.Hwi');
var Ecm= xdc.useModule('ti.sysbios.family.c64p.EventCombiner');
/*
* Enable Event Groups here and registering of ISR for specific GEM INTC is done
* using EventCombiner_dispatchPlug() and Hwi_eventMap() APIs
* 总共128个event可以捆绑在四组,每组32个event。这里设置每组挂接的DSP vector
*/
Ecm.eventGroupHwiNum[0] = 7; //event:0-31
Ecm.eventGroupHwiNum[1] = 8; //event:32-63
Ecm.eventGroupHwiNum[2] = 9; //event:64-95
Ecm.eventGroupHwiNum[3] = 10; //event:96-127
2 makefile文件:
CFLAGS += -D DISTRIBUTE -D LINKSTATE -D SPI_DMA_ENABLE
3 rtos\dsp1\bin\release\configuro\linker.cmd
-l"/root/ti/pdk_am57xx_1_0_17/packages/ti/drv/spi/lib/am571x/c66/release/ti.drv.spi.ae66" ///同样,这里需要使用ti.drv.spi.dma.ae66吗?
-l"/root/ti/edma3_lld_2_12_05_30E/packages/ti/sdo/edma3/drv/sample/lib/tda2xx-evm/66/release/edma3_lld_drv_sample.ae66"
-l"/root/ti/edma3_lld_2_12_05_30E/packages/ti/sdo/edma3/drv/lib/66/release/edma3_lld_drv.ae66"
-l"/root/ti/edma3_lld_2_12_05_30E/packages/ti/sdo/edma3/rm/lib/tda2xx-evm/66/release/edma3_lld_rm.ae66"
#include "w5500_spi.h" #include "socket.h" #include <ti/drv/spi/soc/SPI_soc.h> #ifdef SPI_DMA_ENABLE #include <ti/osal/CacheP.h> /* EDMA3 Header files */ #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> static EDMA3_RM_Handle MCSPIApp_edmaInit(void); #endif static Semaphore_Handle spiSemaphore; SPI_Handle spiHandle; /* SPI handle */ #define W5500_SPI_INDEX 1 #define w5500_SPI_DEBUG 0 //uint8_t txBuffer[16*1024]; //uint8_t rxBuffer[16*1024]; void delay_ms(uint32_t ms) { Task_sleep(ms); } //spi初始化 extern void MCSPI_Board_crossbarInit(void); void W5500_SPI_Init(void) { SPI_Params spiParams; /* SPI params structure */ #if w5500_SPI_DEBUG SPI_Transaction transaction; /* SPI transaction structure */ #endif Board_initCfg boardCfg; PRINTF("W5500_SPI_Init start !\r\n"); /* Init SPI driver */ boardCfg = BOARD_INIT_MODULE_CLOCK; Board_init(boardCfg); PRINTF("spi1 sclk reg:%x ,offset %x +VIRT0:%x !\r\n", CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_SCLK, CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_SCLK, VIRT0); HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_SCLK,0x000c0000); HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_D1,0x000c0000); HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_D0,0x000c0000); HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_SPI1_CS0,0x0002000e); PRINTF("W5500_SPI_Init gpmc_a9:0x%x !\r\n", HW_RD_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_GPMC_A9)); HW_WR_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_GPMC_A9,0x0005010e); PRINTF("W5500_SPI_Init gpmc_a9:0x%x !\r\n", HW_RD_REG32(CSL_MPU_CORE_PAD_IO_REGISTERS_REGS+CSL_CONTROL_CORE_PAD_IO_PAD_GPMC_A9)); CSL_xbarIrqConfigure (1, 91, CSL_XBAR_MCSPI1_IRQ); //CSL_xbarIrqConfigure (1, CSL_XBAR_INST_DSP1_IRQ_91, CSL_XBAR_MCSPI1_IRQ); //CSL_xbarDspIrqConfigure(1,CSL_XBAR_INST_DSP1_IRQ_75, CSL_XBAR_EDMA_TPCC_IRQ_REGION2); //CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_EDMA, 35, 1 + CSL_EDMA3_CHA0_MCSPI0_TX); //CSL_xbarDmaConfigure(CSL_XBAR_DMA_CPU_ID_EDMA, 36, 1 + CSL_EDMA3_CHA0_MCSPI0_RX); SPI_HWAttrs spi_cfg; /* Set the SPI init configurations */ SPI_socGetInitCfg(0, &spi_cfg); /*print spi hw config*/ PRINTF("spi-cfg, baseAddr:0x%x-%d\n", spi_cfg.baseAddr, spi_cfg.intNum); spi_cfg.enableIntr = false; #ifdef SPI_DMA_ENABLE /* Set the DMA related init config */ spi_cfg.edmaHandle = MCSPIApp_edmaInit(); spi_cfg.dmaMode = TRUE; #endif /* Get the default SPI init configurations */ SPI_socSetInitCfg(W5500_SPI_INDEX, &spi_cfg); // 创建SPI信号量 Semaphore_Params semParams; Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_BINARY; spiSemaphore = Semaphore_create(1, &semParams, NULL); /* Open the Board flash NOR device with the test SPI port and use the default SPI configurations */ SPI_Params_init(&spiParams); spiParams.transferMode = SPI_MODE_BLOCKING; spiParams.bitRate = 1000000; // max 30MHz spiParams.dataSize = 8; spiParams.transferTimeout = SemaphoreP_WAIT_FOREVER; spiParams.mode = SPI_MASTER; spiParams.frameFormat = SPI_POL0_PHA0; SPI_init(); spiHandle = (SPI_Handle)SPI_open(W5500_SPI_INDEX, &spiParams); if(spiHandle == NULL) { PRINTF("\nError opening SPI driver\n"); } #if w5500_SPI_DEBUG PRINTF("\n W5500_SPI_Init status:%d. \n",transaction.status); #endif } void SPI_WriteByte(uint32_t addr, uint8_t data) { uint8_t txBuffer[4]; bool transferOK = false; #if w5500_SPI_DEBUG PRINTF("SPI_WriteByte addr:0x%4x data:0x%x !\r\n", addr, data); #endif txBuffer[0] = ((addr & 0xFF0000) >> 16); txBuffer[1] = ((addr & 0x00FF00) >> 8); txBuffer[2] = ((addr & 0x0000FF)|0x04); // Write操作 txBuffer[3] = data; SPI_Transaction transaction; transaction.count = 4; transaction.txBuf = txBuffer; transaction.rxBuf = txBuffer; transferOK=SPI_transfer(spiHandle, &transaction); if (!transferOK) { /* SPI transaction failed */ PRINTF("SPI_WriteByte SPI_transfer falied !\r\n"); } #if w5500_SPI_DEBUG PRINTF("SPI_WriteByte end addr:0x%4x data:0x%x transferOK:%d!\r\n", addr, data, transferOK); #endif } #pragma DATA_SECTION (txBuffer,".l2sram") #pragma DATA_ALIGN (txBuffer,128) #pragma DATA_SECTION (rxBuffer,".l2sram") #pragma DATA_ALIGN (rxBuffer,128) uint8_t txBuffer[2048];// __attribute__((aligned(32))); uint8_t rxBuffer[2048];// __attribute__((aligned(32))); uint8_t SPI_ReadByte(uint32_t addr) { // uint8_t txBuffer[4], rxBuffer[4]; bool transferOK = false; //PRINTF("SPI_ReadByte addr:0x%4x start !\r\n", addr); txBuffer[0] = ((addr & 0xFF0000) >> 16); txBuffer[1] = ((addr & 0xFF00) >> 8); txBuffer[2] = ((addr & 0x0000FF)); // Read txBuffer[3] = 0x00; SPI_Transaction transaction; transaction.count = 4; transaction.txBuf = txBuffer; transaction.rxBuf = rxBuffer; transferOK=SPI_transfer(spiHandle, &transaction); if (!transferOK) { /* SPI transaction failed */ PRINTF("SPI_ReadByte SPI_transfer falied !\r\n"); } uint32_t value = HW_RD_REG32(0x4809813c); //PRINTF("read rx value:0x%x \n", value); //PRINTF("SPI_ReadByte end addr:0x%4x data:0x%x transferOK:%d!\r\n", addr, rxBuffer[3], transferOK); return rxBuffer[3]; } void W5500_WriteBuffer(uint32_t addr, uint8_t *buf, uint16_t len) { uint8_t txHeader[3]; bool transferOK = false; txHeader[0] = ((addr & 0xFF0000) >> 16);//(addr >> 8) & 0xFF; txHeader[1] = ((addr & 0x00FF00) >> 8);//addr & 0xFF; txHeader[2] = ((addr & 0x0000FF)|0x04);//0x04;//0x80; // Write操作 #if w5500_SPI_DEBUG PRINTF("W5500_WriteBuffer addr:0x%4x start !\r\n", addr); PRINTF("W5500_WriteBuffer buf:%s !\r\n", buf); PRINTF("txHeader:0x%2x-0x%2x-0x%2x !\r\n", txHeader[0], txHeader[1], txHeader[2]); #endif SPI_Transaction transaction; transaction.count = 3 + len; // 需要将头和数据合并 // uint8_t *txBuffer = (uint8_t *)malloc(3 + len);//(uint8_t *)xdc_runtime_Memory_alloc(NULL, 3 + len, 0, NULL); memset(txBuffer, 0, sizeof(txBuffer)); memcpy(txBuffer, txHeader, 3); memcpy(txBuffer + 3, buf, len); #if w5500_SPI_DEBUG PRINTF("txBuffer:%s ,len:%d !:\r\n", txBuffer, len); int i =0; for(i =0;i < len+3; i++) PRINTF("0x%2x-", txBuffer[i]); #endif transaction.txBuf = txBuffer; transaction.rxBuf = txBuffer; #ifdef SPI_DMA_ENABLE CacheP_wb((void *)txBuffer, 3 + len); #endif transferOK = SPI_transfer(spiHandle, &transaction); if (!transferOK) { /* SPI transaction failed */ PRINTF("W5500_WriteBuffer SPI_transfer falied !\r\n"); } // if(txBuffer != NULL) free(txBuffer); #if w5500_SPI_DEBUG PRINTF("W5500_WriteBuffer end transferOK:%d!\r\n", transferOK); #endif } #define w5500_SPI_DEBUG_RX 1 void W5500_ReadBuffer(uint32_t addr, uint8_t *buf, uint16_t len) { uint8_t txHeader[3]; //uint8_t rxBuffer[32]; bool transferOK = false; txHeader[0] = ((addr & 0xFF0000) >> 16); txHeader[1] = ((addr & 0xFF00) >> 8); txHeader[2] = ((addr & 0x0000FF)); // Read SPI_Transaction transaction; transaction.count = 3+len; //HW_WR_REG32(0x48098134, 0x1); // 准备接收缓冲区 // uint8_t *rxBuffer = (uint8_t *)malloc(len);//(uint8_t *)xdc_runtime_Memory_alloc(NULL, 3 + len, 0, NULL); memset(rxBuffer, 0, len); memcpy(rxBuffer, txHeader, 3); // 发送部分 #if w5500_SPI_DEBUG_RX PRINTF("txHeader:\r\n"); int i =0; for(i =0;i < 3; i++) PRINTF("%2x-", txHeader[i]); #endif transaction.txBuf = &rxBuffer[0]; // 前3字节是发送的头 transaction.rxBuf = &rxBuffer[0]; // 全部接收 transaction.status = SPI_TRANSFER_STARTED; #ifdef SPI_DMA_ENABLE CacheP_wb((void *)rxBuffer, 3+len); #endif #if w5500_SPI_DEBUG_RX PRINTF("\r\n W5500_ReadBuffer SPI_transfer start !\r\n"); #endif transferOK = SPI_transfer(spiHandle, &transaction); if (!transferOK) { /* SPI transaction failed */ PRINTF("W5500_ReadBuffer SPI_transfer falied !\r\n"); } #ifdef SPI_DMA_ENABLE CacheP_Inv((void *)rxBuffer, 3+len); #endif #if w5500_SPI_DEBUG_RX PRINTF("W5500_ReadBuffer SPI_transfer end transferOK:%d-status:%d!\r\n", transferOK, transaction.status); PRINTF("rxBuffer:"); for(i =0;i < len+3; i++) PRINTF("%2x-", rxBuffer[i]); PRINTF("rxBuffer end"); uint32_t value = HW_RD_REG32(0x4809813c); PRINTF("read rx value:0x%x \n", value); #endif // 复制有效数据 memcpy(buf, rxBuffer+3, len); // if(rxBuffer != NULL)free(rxBuffer); } void SPI_CrisEnter(void) { Semaphore_pend(spiSemaphore, BIOS_WAIT_FOREVER); } void SPI_CrisExit(void) { Semaphore_post(spiSemaphore); } void SPI_CS_Select(void) { W5500_CS_0(); } void SPI_CS_Deselect(void) { W5500_CS_1(); } void W5500_Register(void) { PRINTF("W5500_Register start !\r\n"); //reg_wizchip_cris_cbfunc(SPI_CrisEnter,SPI_CrisExit); reg_wizchip_cs_cbfunc(SPI_CS_Select,SPI_CS_Deselect); reg_wizchip_spi_cbfunc(SPI_ReadByte,SPI_WriteByte); reg_wizchip_spi_bf_cbfunc(W5500_ReadBuffer,W5500_WriteBuffer); } void W5500_Reset(void) { //return; PRINTF("W5500_Reset start !\r\n"); W5500_RST_0(); delay_ms(10); W5500_RST_1(); delay_ms(100); } void W5500_Network_Init(void) { PRINTF("W5500_Network_Init start !\r\n"); uint8_t chipid[6]; int ret = -1; wiz_NetInfo gWIZNETINFO; //Network Information for WIZCHIP wiz_NetTimeout w_NetTimeout; uint8_t mac[6] = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}; uint8_t ip[4] = {192, 168, 86, 140}; uint8_t sn[4] = {255, 255, 255, 0}; uint8_t gw[4] = {192, 168, 86, 1}; uint8_t dns[4] = {8, 8, 8, 8}; memcpy(gWIZNETINFO.mac,mac,6); memcpy(gWIZNETINFO.ip,ip,4); memcpy(gWIZNETINFO.sn,sn,4); memcpy(gWIZNETINFO.gw,gw,4); memcpy(gWIZNETINFO.dns,dns,4); gWIZNETINFO.dhcp = NETINFO_STATIC; PRINTF("set net info: !\r\n"); PRINTF("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",gWIZNETINFO.mac[0],gWIZNETINFO.mac[1],gWIZNETINFO.mac[2], gWIZNETINFO.mac[3],gWIZNETINFO.mac[4],gWIZNETINFO.mac[5]); PRINTF("IP: %d.%d.%d.%d\r\n", gWIZNETINFO.ip[0],gWIZNETINFO.ip[1],gWIZNETINFO.ip[2],gWIZNETINFO.ip[3]); PRINTF("GW: %d.%d.%d.%d\r\n", gWIZNETINFO.gw[0],gWIZNETINFO.gw[1],gWIZNETINFO.gw[2],gWIZNETINFO.gw[3]); PRINTF("SN: %d.%d.%d.%d\r\n", gWIZNETINFO.sn[0],gWIZNETINFO.sn[1],gWIZNETINFO.sn[2],gWIZNETINFO.sn[3]); PRINTF("DNS: %d.%d.%d.%d\r\n",gWIZNETINFO.dns[0],gWIZNETINFO.dns[1],gWIZNETINFO.dns[2],gWIZNETINFO.dns[3]); PRINTF("--------------------\r\n"); ret = ctlnetwork(CN_SET_NETINFO,(void*)&gWIZNETINFO); if(0 != ret) PRINTF("CN_SET_NETINFO failed ret:%d !\r\n",ret); ret = ctlnetwork(CN_GET_NETINFO,(void*)&gWIZNETINFO); if(0 != ret) PRINTF("CN_GET_NETINFO failed !\r\n"); PRINTF("get net info: !\r\n"); ctlwizchip(CW_GET_ID,(void*)chipid); PRINTF("=== %s NET CONF ===\r\n",(char*)chipid); PRINTF("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",gWIZNETINFO.mac[0],gWIZNETINFO.mac[1],gWIZNETINFO.mac[2], gWIZNETINFO.mac[3],gWIZNETINFO.mac[4],gWIZNETINFO.mac[5]); PRINTF("IP: %d.%d.%d.%d\r\n", gWIZNETINFO.ip[0],gWIZNETINFO.ip[1],gWIZNETINFO.ip[2],gWIZNETINFO.ip[3]); PRINTF("GW: %d.%d.%d.%d\r\n", gWIZNETINFO.gw[0],gWIZNETINFO.gw[1],gWIZNETINFO.gw[2],gWIZNETINFO.gw[3]); PRINTF("SN: %d.%d.%d.%d\r\n", gWIZNETINFO.sn[0],gWIZNETINFO.sn[1],gWIZNETINFO.sn[2],gWIZNETINFO.sn[3]); PRINTF("DNS: %d.%d.%d.%d\r\n",gWIZNETINFO.dns[0],gWIZNETINFO.dns[1],gWIZNETINFO.dns[2],gWIZNETINFO.dns[3]); PRINTF("--------------------\r\n"); w_NetTimeout.retry_cnt = 50; w_NetTimeout.time_100us = 1000; wizchip_settimeout(&w_NetTimeout); } //配置socket0收发缓存为16KB uint8_t tx_size[_WIZCHIP_SOCK_NUM_] = {16, 0, 0, 0, 0, 0, 0, 0}; uint8_t rx_size[_WIZCHIP_SOCK_NUM_] = {16, 0, 0, 0, 0, 0, 0, 0}; /* Set socket0 send and receive cache to 16KB */ int W5500_Chip_Init(void) { PRINTF("W5500_Chip_Init start !\r\n"); return wizchip_init(tx_size, rx_size); } void W5500_Phy_Init(void) { PRINTF("W5500_Phy_Init start !\r\n"); wiz_PhyConf phyconf; phyconf.by = PHY_CONFBY_SW; phyconf.duplex = PHY_DUPLEX_FULL; phyconf.mode = PHY_MODE_AUTONEGO; phyconf.speed = PHY_SPEED_10; ctlwizchip(CW_SET_PHYCONF,(void*)&phyconf); } extern Semaphore_Handle w5500_dataSem; void w5500CallbackFxn(void) { PRINTF("~~~~~~come int ++++++\r\n"); Semaphore_post(w5500_dataSem); return; } int W5500_Init(void) { char id[6]; GPIO_init(); W5500_SPI_Init(); W5500_Reset(); W5500_Register(); if(W5500_Chip_Init()!= 0) { PRINTF("W5500_Chip_Init failed !\r\n"); return -1; } ctlwizchip(CW_GET_ID,(void *)id); PRINTF("get chipid :%s !\r\n", id); W5500_Phy_Init(); W5500_Network_Init(); ctlwizchip(CW_GET_ID,(void *)id); CSL_xbarDspIrqConfigure(1, CSL_XBAR_INST_DSP1_IRQ_55, CSL_XBAR_GPIO1_IRQ_1); PRINTF("~~~~~gpio int2~~~~~~"); GPIO_setCallback(SPI1W_INT_INDEX, w5500CallbackFxn); GPIO_enableInt(SPI1W_INT_INDEX); return 0; } void spiw5500_mainTaskFxn(UArg arg0, UArg arg1) { int ret; uint8_t tmp; PRINTF("spiw5500_mainTaskFxn start !\r\n"); ret = W5500_Init(); //enable socket0 resv intr setSIMR(0x01); // enable socket0 interrupt setSn_IMR(0, 0x1f);//enable resv interrupt functions of socket 0. if(ret!=0) { PRINTF("W5500 init fail,ret is %d\r\n",ret); } else { PRINTF("W5500 init success !\r\n"); } PRINTF("W5500 initialization complete.\n"); /* //enable socket0 resv intr setSIMR(0x01); // enable socket0 interrupt tmp = getSn_IMR(0); PRINTF("spiw5500_recvtestTaskFxn getSn_IMR = %d, will set %d\n", tmp, tmp | 0x04); setSn_IMR(0, tmp | 0x04);//enable resv interrupt functions of socket 0. */ System_flush(); } #ifdef SPI_DMA_ENABLE EDMA3_RM_Handle gEdmaHandle = NULL; /** * \brief Function to initialize the edma driver and get the handle to the * edma driver; */ static EDMA3_RM_Handle MCSPIApp_edmaInit(void) { EDMA3_DRV_Result edmaResult = EDMA3_DRV_E_INVALID_PARAM; uint32_t edma3Id; if (gEdmaHandle != NULL) { return (gEdmaHandle); } edma3Id = 1; gEdmaHandle = (EDMA3_RM_Handle)edma3init(edma3Id, &edmaResult); if (edmaResult != EDMA3_DRV_SOK) { /* Report EDMA Error */ PRINTF("\nEDMA driver initialization FAIL\n"); } else { PRINTF("\nEDMA driver initialization PASS.\n"); } return(gEdmaHandle); } #endif
在Makefile中注释掉-D SPI_DMA_ENABLE的情况下,spi读写均正常,一旦打开这个宏,tx抓包看是正常的,但是rx收到的全是0,这个可能是什么问题?
另外,还有一个很关键的问题,我看pdk driver中有提供ti.drv.spi.dma这个lib,如果想使用dma功能是不是需要链接dam的库,而不是单纯spi的驱动,我尝试去链接spi.dma的库,但是发现spi_transfer之后一直没有返回,可能是dma或者spi的中断没有产生,这块该如何修改?