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.

[参考译文] TDA3XEVM:请检查 DMA SPI 模式设置。

Guru**** 2979400 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/679081/tda3xevm-please-check-the-dma-spi-mode-setting

器件型号:TDA3XEVM

您好!

我知道 FIFO SPI 模式 总共只有128字节的 TX、Rx 缓冲区。

因此、我尝试使用主器件测试 DMA SPI 模式。

当我测试低于源时、DMA SPI 模式停止并且不运行。

我参考以下来源。(mcspiSample_io.c、mcspiSample_main.c)

tda3x 为从器件、SPI TX、Rx 数据各为154字节。

请检查 DMA SPI 模式设置以确保正常运行。

此致、

Lee

============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

/*缓冲区大小*/
#define BUFLEN         (154)
/*使用 L2缓存的缓冲区对齐*/
#define BUFALIGN       128
/*迭代次数*/
#define iteration_CNT  100
/*要发布和回收的数字 bufs */
#define NUM_BUFS       3.

#define debugs_on      1.

/* MCSPI 初始配置*/
void USER_mcspi_init (void)
{
   Mcspi_init();

   mcspiPrms.opMode = MCSPI_OPMODE_DMAINTERRUPT;//MCSPI_OPMODE_INTERRUPT;
   mcspiPrms.instNum        = 0;
   mcspiPrms.hwiNumber      = 7;
   mcspiPrms.enableCache    =(uint32) true;
   mcspiPrms.edma3EventQueue = 0;
   mcspiPrms.enableErrIntr  =(uint32) false;

   mcspiPrms.spiHWCfgData.masterOrSlave        = MCSPI_COMMMODE_SLAVE;
   mcspiPrms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
   mcspiPrms.spiHWCfgData.pinOpModes   = MCSPI_PINOPMODE_4引脚;
   mcspiPrms.spiHWCfgData.fifoRxTrigLevel = 154;
   mcspiPrms.spiHWCfgData.fifoTxTrigLevel = 154;
   mcspiPrms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_8位;
   mcspiPrms.spiHWCfgData.configChfmt[0]。multiWordAccessEnable =
       (uint32) false;

   mcspiPrms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
           (uint32) false;

   mcspiPrms.spiHWCfgData.configChfmt[0].clockMode          = MCSPI_MODE0;
   mcspiPrms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
   mcspiPrms.spiHWCfgData.configChfmt[0].spiWordInitDelay   = MCSPI_NO_DELAY;
   mcspiPrms.spiHWCfgData.configChfmt[0].trasReceiveMode = MCSPI_BLE_RxTx;
   mcspiPrms.spiHWCfgData.configChfmt[0].granularityEnable  =(uint32) true;
   mcspiPrms.spiHWCfgData.configChfmt[0].busFreq            = 2500000;
   mcspiPrms.spiHWCfgData.configChfmt[0].spienHighPolarity  =(uint32) false;
   mcspiPrms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEn_0;
   mcspiPrms.spiHWCfgData.configChfmt[0].spiDat0Dir         = MCSPI_OUT;
   mcspiPrms.spiHWCfgData.configChfmt[0].spiDat1Dir         = MCSPI_IN;

   if (MCSPI_OPMODE_Polled => mcspiPrms.opMode)
   {
       vps_printf ("\r\nMcspi 配置为轮询模式\r\n");
   }
   否则、如果(MCSPI_OPMODE_INTERRUPT = mcspiPrms.opMode)
   {
       vps_printf ("\r\nMcspi 配置为中断模式\r\n");
   }
   否则、如果(MCSPI_OPMODE_DMAINTERRUPT = mcspiPrms.opMode)
   {
       vps_printf ("\r\nMcspi 配置为 DMA 模式\r\n");
   }
   其他
   {
       vps_printf ("\r\n 错误:未知的操作模式!!!!!!!!!!!!!! \r\n");
   }
}

/*将 MCSPI 处理程序与驱动程序绑定*/
void SPI_init (void)
{
   gio_addDevice ("/mcspi0"、(XDC_ptr)&Mcspi_IOMFXNS、&USER_mcspi_init、0、(XDC_ptr)& mcspiPrms);
}

/*系统初始化和电路板多路复用*/
静态空 spiSampleTask (空)
{
   /*设置引脚多路复用器*/
   bsp_boardSetPinMux (bsp_DRV_ID_MCSPI、bsp_device_mspi_INST_ID_0、
                      bsp_Board_mode_default);

   /*设置电路板多路复用器*/
   bsp_boardSelectDevice (bsp_DRV_ID_MCSPI、bsp_device_mspi_INST_ID_0);
}

/*初始化通道属性*/
静态空 createStream (空)
{
   Gio_Params      ioParams;
   Mcspi_ChanParams;
   ERROR_Block     EB;

   ERROR_INIT (&EB);

   /*
    *初始化通道属性。
    *
   Gio_Params_init (ioParams);

   /*初始化通道参数*/
   Mcspi_ChanParams_init (&chanParams);

   /*更新 EDMA 句柄                                                */
   chanParams.hEdma = gEdmaHandle;
   chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
   chanParams.fifoEnable        =(uint32) true;
   chanParams.spiChipSelectHold =(uint32) true;
   chanParams.chanNum = 0;

   /*横线设备已禁用*/
   chanParams.crossBarEvtParam.isCrossBarIntEn =(UINT32) false;
   chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF; /*无效数字*/

   ioParams.chanParams =(PTR)& chanParams;
   ioParams.model     = GIO_Model_ISSUERECLAIM;
   ioParams.numPackets = NUM_BUFS + 1;

   chanParams.useAppSpecifiedDmaEvtNumbers = true;
   chanParams.rxDmaEventNumber =(uint32) CSL_EDMA3_CHA0_MCSPI0_RX;
   chanParams.txDmaEventNumber =(uint32) CSL_EDMA3_CHA0_MCSPI0_TX;

   mcspiHandle = GIO_create ("/mcspi0"、GIO_INOUT、&ioParams、&EB);
   if (mcspiHandle == NULL)
   {
       vps_printf ("\r\n 创建输入流失败。\r\n);
       BIOS_exit (0);
   }
   vps_printf ("\r\n 创建输入流已完成。\r\n);
}

/*将内存分配给 Rx 和 Tx 缓冲区*/
静态空 initial_mcspi0_buf (void)
{
   ERROR_Block EB;
   int32       计数= 0;
   IHeap_handle iheap;

   iheap = HeapMem_Handle_TO_XDC_Runtime_IHeap (myHeap);
   ERROR_INIT (&EB);

   /*为 GIO 缓冲区交换分配缓冲                         区*/
   对于(count = 0;count <(NUM_bufs);count++)
   {
       rxbuf[count]=(ptr) Memory_calloc (iheap、BUFLEN、BUFALIGN、&EB);
       if (NULL =rxbuf[count])
       {
           vps_printf ("\r\nMEM_calloc 失败。\r\n");
       }
       txbuf[count]=(ptr) Memory_calloc (iheap、BUFLEN、BUFALIGN、&EB);
       if (NULL =txbuf[count])
       {
           vps_printf ("\r\nMEM_calloc 失败。\r\n");
       }
   }
}

/*主函数向驱动程序发出缓冲区。 *
静态空灌注(空)
{

   int32       计数= 0;
   uint32      tempCount = 0;
   uint32      大小     = 0;
   int         status   = IOM _已完成;
   uint8       dummyDataCount;
   
   vps_printf ("在主函数中\n");
   /*要从 SOC 传输到 MCU 的虚拟数据*/
   uint8 dummyData[BUFLEN];

   memset (spiDummyData、0、BUFLEN);

   对于(count = 0;count <(NUM_bufs);count++)
   {
       dummyDataCount = 0;

       对于(tempCount = 0;tempCount < BUFLEN;tempCount++)
       {
           (((uint8 *) txbuf[count])[tempCount]= spiDummyData[spiDummyDataCount++];
       }
   }

   /*缓存写回在缓存初始化后进行 CPU 访问*/
   bspOsal_cacheWbInvAll();

   /*调用'gio_isse' API 向驱动程序发出缓冲区*/
   对于(count = 0;count < NUM_BUFS;count++)
   {
       issueDataparam[count].bufLen   = BUFLEN;
       issueDataparam[count].inBuffer = rxbuf[count];
       issueDataparam[count].outBuffer = txbuf[count];

       size = issueDataparam[count].bufLen;

       /*向输入流发出第一个和第二个空缓冲        区*/
       status = GIO_Issue (mcspiHandle、&issueDataparam[count]、size、NULL);

       if (status!= IOM_PENDING && status!= IOM_Completed)
       {
           vps_printf ("\r\nsatus =%d\r\n"、status);
           vps_printf ("\r\n\t 发出空缓冲区进行流式传输);
       }

       #if debugs_on
       vps_printf ("打印主函数中的数据\n");
       vps_printf ("SPI TDA2x->MCU 写入帧应答\r\n");
       for (spidmyDataCount=0;spiDummyDataCount<10/*BUFLEN*/;spiDummyDataCount++)
       {
           vps_printf ("SPI Data[%d byte]= 0x%x\r\n"、spiDummyDataCount、issueDataparam[count].outBuffer[spiDummyDataCount]);
       }
       #endif
   }
}

/*主 SPI 函数*/
void CreateSpiTask()
{
   uint32 i=0、tempCount      = 0;
   #if debugs_on
   uint32 j=0;
   #endif

   /*保存 SPI 数据*/
   UINT8 SPIdata[BUFLEN]      ={0};
   volatile Int32  i32Count  = 0;
   int status                = IOM _已完成;
   static int Claim _count     = 0;

   /* SPI 的一次性初始化和内存分配*/
   spi_init();
   spiSampleTask();
   createStream();
   initialize_mcspi0_buf();
   while (1)
   {
       vps_printf (" SpiTask...Start \n");

       PRIME ();
       对于(i = 0;i < NUM_BUFS;i++)
       {
           #if debugs_on
           vps_printf ("申索计数为%d\r\n、Claim_count);
           #endif
         
        状态= GIO_REBLET (mcspiHandle、(PTR *)&issueDataparam[i]、NULL、NULL);

           if (IOM _已完成!=状态)
           {
               vps_printf (
                   "从流%x 重新获取空缓冲区时出错"
                   "错误= 0x%d\r\n"、
                   (((uint8)(issueDataparam[i].outBuffer[i32Count]))、
                   状态);
               中断;
           }
           Claim _count++;
           对于(tempCount = 0;tempCount < BUFLEN;)
           {
               if (mcspiPrms.spiHWCfgData.configChfmt[0].charLength <= 8)
               {                   
                   memcpy (SPIdata、issueDataparam[i]。inBuffer、BUFLEN * sizeof (uint8));
                       
                   #if debugs_on
                   vps_printf ("SPI 读取帧\r\n");

                   for (j=0;j<10/* BUFLEN*/;j++)
                   {
                       vps_printf ("SPI 数据[%d 字节]=%x\r\n"、j、SPIdata[j]);
                   }
                   #endif
               }
               其他
               {
                   vps_printf ("无效帧\r\n);
               }
               tempCount++;
           }
         }

       vps_printf (" SpiTask...end \n");
   }
}