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的中断没有产生,这块该如何修改?