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.

TMS320C6678: 在C6678平台下实现SPI驱动IC功能的疑问。

Part Number: TMS320C6678


我在裸核开发环境下,参考7242.K1_STK_v1.1的SPI驱动代码。

在仿真器环境调试下,没有编写如下RAM与PSC控制代码,依赖了仿真器的GET文件:

/*enable TSC, memory protection interrupts, EDC for internal RAM;
clear cache; protect L1 as cache*/
KeyStone_common_CPU_init();
/*print device information.
Enable memory protection interrupts, EDC for MSMC RAM*/
KeyStone_common_device_init();

//enable exception handling
KeyStone_Exception_cfg(TRUE);

CACHE_setL1PSize(CACHE_L1_32KCACHE);
CACHE_setL1DSize(CACHE_L1_32KCACHE);
CACHE_setL2Size(CACHE_128KCACHE);

/*clear configuration structure to default values*/
memset(&spiCfg, 0, sizeof(spiCfg));
memset(&spiIntCfg, 0, sizeof(spiIntCfg));

仿真器配置信息:

C66xx_0: GEL Output:
Connecting Target...
C66xx_0: GEL Output: DSP core #0
C66xx_0: GEL Output: C6678L GEL file Ver is 2.005
C66xx_0: GEL Output: Global Default Setup...
C66xx_0: GEL Output: Setup Cache...
C66xx_0: GEL Output: L1P = 32K
C66xx_0: GEL Output: L1D = 32K
C66xx_0: GEL Output: L2 = ALL SRAM
C66xx_0: GEL Output: Setup Cache... Done.
C66xx_0: GEL Output: Main PLL (PLL1) Setup ...
C66xx_0: GEL Output: PLL in Bypass ...
C66xx_0: GEL Output: PLL1 Setup for DSP @ 1000.0 MHz.
C66xx_0: GEL Output: SYSCLK2 = 333.3333 MHz, SYSCLK5 = 200.0 MHz.
C66xx_0: GEL Output: SYSCLK8 = 15.625 MHz.
C66xx_0: GEL Output: PLL1 Setup... Done.
C66xx_0: GEL Output: Power on all PSC modules and DSP domains...
C66xx_0: GEL Output: Power on all PSC modules and DSP domains... Done.
C66xx_0: GEL Output: DDR3 PLL (PLL2) Setup ...
C66xx_0: GEL Output: DDR3 PLL Setup... Done.
C66xx_0: GEL Output: DDR begin (1333 auto)
C66xx_0: GEL Output: XMC Setup ... Done
C66xx_0: GEL Output:
DDR3 initialization is complete.
C66xx_0: GEL Output: DDR done
C66xx_0: GEL Output: DDR3 memory test... Started
C66xx_0: GEL Output: DDR3 memory test... Passed
C66xx_0: GEL Output: PLL and DDR Initialization completed(0) ...
C66xx_0: GEL Output: Enabling EDC ...
C66xx_0: GEL Output: L1P error detection logic is enabled.
C66xx_0: GEL Output: L2 error detection/correction logic is enabled.
C66xx_0: GEL Output: MSMC error detection/correction logic is enabled.
C66xx_0: GEL Output: Enabling EDC ...Done
C66xx_0: GEL Output: Global Default Setup... Done.

现在程序运行后,通过DSP的SPI的SCK时钟管脚进行示波器测量,一直没有时钟信号,可测量到CS使能变化信号。

下面SPI的控制代码运行后相关寄存器配置写入或读取的数据信息如下:

[C66xx_0] main_pll_freq = 1000000000

SPI NOR FLASH test:
KeyStone_SPI_init_debug : gpSPI_regs->SPIGCR0 = 0x1
KeyStone_SPI_init_debug : gpSPI_regs->SPIPC0 = 0x1010e03
SPI_init: SPI PRESCALE= 5
KeyStone_SPI_init_debug : gpSPI_regs->SPIFMT[0] = 0x10508
SPI_init: SPI PRESCALE= 4
KeyStone_SPI_init_debug : gpSPI_regs->SPIFMT[1] = 0x40408
SPI_init: SPI PRESCALE= 3
KeyStone_SPI_init_debug : gpSPI_regs->SPIFMT[2] = 0x10308
SPI_init: SPI PRESCALE= 2
KeyStone_SPI_init_debug : gpSPI_regs->SPIFMT[3] = 0x40210
KeyStone_SPI_init_debug : gpSPI_regs->SPIDELAY = 0x0
KeyStone_SPI_init_debug : gpSPI_regs->SPIDEF = 0x3
KeyStone_SPI_init_debug : gpSPI_regs->SPIGCR1 = 0x1000003SPI NOR FLASH test at 48MHz...
KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIDAT1 = 0x1602009f
KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIBUF&0xFFFF= 0x18
KeyStone_SPI_TxRx_debug : length= 0x4
Read SPI NOR FLASH ID = 0xc8 0x65 0x18 0x32
KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIDAT1 = 0x1602009f
KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIBUF&0xFFFF= 0x18
KeyStone_SPI_TxRx_debug : length= 0x4
Read SPI NOR FLASH ID = 0xc8 0x65 0x18 0x32
KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIDAT1 = 0x1602009f
KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIBUF&0xFFFF= 0x18
KeyStone_SPI_TxRx_debug : length= 0x4
Read SPI NOR FLASH ID = 0xc8 0x65 0x18 0x32

现在确定几个问题:

1.SPI的默认是工作在PLL 的SYSCLK7 时钟频率下吗?

2.我非常疑惑是代码log读取到NOR flash( GD25WQ128E)OX9F信号了,但是在示波器下测量SPI的CLK测量无信号,后来怀疑PSC没有控制原因,现在增加控制代码,现象依旧。

请教下,可以在仿真状态可以测试量SPI端口的信号时序吗?

还有什么原因,可能造成SPI不同工作或时钟不输出吗?

static void psc_init(void)
{
/* Set psc as Always on state */
CSL_PSC_enablePowerDomain(CSL_PSC_PD_ALWAYSON);

/* Start state change */
CSL_PSC_startStateTransition(CSL_PSC_PD_ALWAYSON);

/* Wait until the status change is completed */
while(!CSL_PSC_isStateTransitionDone(CSL_PSC_PD_ALWAYSON));

/*
* SRIO power domain is turned OFF by default. It needs to be turned on before doing any
* SRIO device register access. This not required for the simulator
*/

/* Set SRIO Power domain to ON */
CSL_PSC_enablePowerDomain(CSL_PSC_PD_SRIO);

/* Enable the clocks too for SRIO */
CSL_PSC_setModuleNextState(CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE);

/* Start the state transition */
CSL_PSC_startStateTransition(CSL_PSC_PD_SRIO);

/* Wait until the state transition process is completed. */
while(!CSL_PSC_isStateTransitionDone(CSL_PSC_PD_SRIO));

}

  • SPI的默认是工作在PLL 的SYSCLK7 时钟频率下吗?

    是的。

    SYSCLKOUT是有输出的吗?可以先做一下回环测试看看。

    可以在仿真状态可以测试量SPI端口的信号时序吗

    可以测到。

  • hi,nancy.

    1.C6678处理器的sysclk7 可以通过什么方法测试吗?

    2.回环测试:

    回环测试设置如下 :

    结构定义:

    typedef struct {
    /*Delay between transmissions in ns. Idle time that will be
    applied at the end of the current transmission if the bit
    WDEL is set in the current buffer*/
    Uint32 delayBetweenTrans_ns; ////SPIFMTn.WDELAY
    SPI_Shift_Direction ShifDirection;
    /*No C2TDELAY or T2CDELAY is inserted in the chip select timings.*/
    Uint8 disable_CS_timing;
    SPI_Clock_Polarity clockPolarity;
    Uint8 clockPhase;
    /*SPI external clock speed in KHz < 66,000KHz*/
    Uint32 clockSpeedKHz;
    /*SPI data word length. Legal values are 2h (data word length = 2 bit)
    to 10h (data word length = 16).*/
    Uint8 wordLength;
    } SPI_Data_Format;


    /*SPI transfer parameters*/
    typedef struct {
    Uint32 CS_select; /*Chip select number*/
    Uint32 formatSelect; /*select one of the 4 formats*/
    SPI_CS_Hold CS_hold; /*hold CS between multiple words*/
    Bool delayEnable; /*Enable the delay counter at the end of the current transaction*/
    Uint32 byteOfWord; /*number of bytes per SPI word*/
    }SPI_Transfer_Param;

    代码中SPI的参数配置:

    /*data format for loopback test*/
    SPI_Data_Format loopbackDataFormat =
    {
    /*.delayBetweenTrans_ns = */0,
    /*.ShifDirection = */SPI_MSB_SHIFT_FIRST,
    /*.disable_CS_timing (C2TDELAY or T2CDELAY is inserted) = */1,
    /*.clockPolarity = */SPI_CLOCK_LOW_INACTIVE,
    /*.clockPhase = */0,
    /*.clockSpeedKHz 66000 = */ 66000 ,
    /*.wordLength defaul:16 = */16
    };

    SPI_Transfer_Param loopbackTransferParam =
    {
    0, /*Chip select number*/
    3, /*select one of the 4 SPI formats*/
    SPI_CS_NO_LAST_HOLD, /*hold CS between multiple words*/
    FALSE, /*Enable the delay counter at the end of the current transaction*/
    1 /*number of bytes per SPI word defaul:2*/
    };

    帮我看下,我SPI数据格式理解对吗? 

    2.1因SPI的分频参数计算:clockPreScale= gDSP_Core_Speed_Hz/6/(1000*datFmt->clockSpeedKHz);

    其中,clockSpeedKHz —>66000,表示SPI始终频率设置了66M,每次传输一个字节,一个字节是数据位长为16BIT吗?

    我的回环测试中,控制台输出信号如下:

    SPI internal loopback test at 66MHz...
    KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIDAT1 = 0x13020000
    KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIBUF&0xFFFF= 0x0
    KeyStone_SPI_TxRx_debug : length= 0x10
    TSCL=2693678. startTSC= 2653912. cycles=39754
    SPI loopback test ok at word 0: TX =0x0, RX= 0x0
    SPI loopback test ok at word 1: TX =0x0, RX= 0x0
    SPI loopback test ok at word 2: TX =0x0, RX= 0x0
    SPI loopback test ok at word 3: TX =0x0, RX= 0x0
    SPI loopback test ok at word 4: TX =0x0, RX= 0x0
    SPI loopback test ok at word 5: TX =0x0, RX= 0x0
    SPI loopback test ok at word 6: TX =0x0, RX= 0x0
    SPI loopback test ok at word 7: TX =0x0, RX= 0x0
    TSCL=2792568. startTSC= 2653912. cycles=39754
    SPI_LOOP_TEST_BUF_SIZE=8. gDSP_Core_Speed_Hz= 1000000000. throughput=39754
    SPI loopback test passed with data pattern 0x0. Throughput= 3Mbps
    KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIDAT1 = 0x130200ff
    KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIBUF&0xFFFF= 0xff
    KeyStone_SPI_TxRx_debug : length= 0x10
    TSCL=2870477. startTSC= 2830670. cycles=39795
    SPI loopback test ok at word 0: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 1: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 2: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 3: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 4: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 5: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 6: TX =0xffff, RX= 0xffff
    SPI loopback test ok at word 7: TX =0xffff, RX= 0xffff
    TSCL=2973449. startTSC= 2830670. cycles=39795
    SPI_LOOP_TEST_BUF_SIZE=8. gDSP_Core_Speed_Hz= 1000000000. throughput=39795
    SPI loopback test passed with data pattern 0xffff. Throughput= 3Mbps
    KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIDAT1 = 0x13020055
    KeyStone_SPI_TxRx_debug : gpSPI_regs->SPIBUF&0xFFFF= 0x55
    KeyStone_SPI_TxRx_debug : length= 0x10
    TSCL=3051575. startTSC= 3011769. cycles=39794
    SPI loopback test ok at word 0: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 1: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 2: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 3: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 4: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 5: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 6: TX =0x5555, RX= 0x5555
    SPI loopback test ok at word 7: TX =0x5555, RX= 0x5555
    TSCL=3154547. startTSC= 3011769. cycles=39794
    SPI_LOOP_TEST_BUF_SIZE=8. gDSP_Core_Speed_Hz= 1000000000. throughput=39794
    SPI loopback test passed with data pattern 0x5555. Throughput= 3Mbps

    2.2我咨询下:clockSpeedKHz —>66000,表示SPI始终频率设置了66M,为何计算的传输速率只有3Mbps?

    另在别实验中,进行NOR FLASH来固化程序测试时序,其中clockSpeedKHz —>48M,测量中发现SPI的时钟周期1.0160us,频率计算在984251hz=984khz这样正常?什么原因?

    回环测试中传输速率计算代码如下:

    int SPI_loopback_test_one_time(Uint16 dataPattern)
    {
    int i, iByteSuccess;
    Uint32 startTSC, cycles, throughput;

    for(i=0; i<SPI_LOOP_TEST_BUF_SIZE/2; i++)
    {
    spiTxBuf[i]= dataPattern;
    spiRxBuf[i]= ~dataPattern;
    }

    startTSC= TSCL;
    iByteSuccess= KeyStone_SPI_TxRx((Uint8 *) spiTxBuf, 0, SPI_LOOP_TEST_BUF_SIZE,
    (Uint8 *) spiRxBuf, 0, SPI_LOOP_TEST_BUF_SIZE, &loopbackTransferParam);
    cycles= TSC_count_cycle_from(startTSC);

    printf("TSCL=%d. startTSC= %d. cycles=%d\n",TSCL, startTSC, cycles);

    if(iByteSuccess!=SPI_LOOP_TEST_BUF_SIZE)
    {
    printf("SPI loopback test failed. TX %d bytes, RX %d bytes!\n",
    SPI_LOOP_TEST_BUF_SIZE, iByteSuccess);
    return iByteSuccess;
    }

    for(i=0; i<SPI_LOOP_TEST_BUF_SIZE/2; i++)
    {

    if(spiTxBuf[i]!=spiRxBuf[i])
    {
    printf("SPI loopback test failed at word %d: TX 0x%x, RX 0x%x\n",
    i, spiTxBuf[i], spiRxBuf[i]);
    return i;
    }
    printf("SPI loopback test ok at word %d: TX =0x%x, RX= 0x%x\n",
    i, spiTxBuf[i], spiRxBuf[i]);
    }
    printf("TSCL=%d. startTSC= %d. cycles=%d\n",TSCL, startTSC, cycles);
    throughput = (unsigned long long)SPI_LOOP_TEST_BUF_SIZE*8*gDSP_Core_Speed_Hz/
    ((unsigned long long)cycles*1000000);
    printf("SPI_LOOP_TEST_BUF_SIZE=%d. gDSP_Core_Speed_Hz= %d. throughput=%d\n",
    SPI_LOOP_TEST_BUF_SIZE/2, gDSP_Core_Speed_Hz);
    printf("SPI loopback test passed with data pattern 0x%x. Throughput= %dMbps\n",
    dataPattern, throughput);

    return SPI_LOOP_TEST_BUF_SIZE;
    }

  • C6678处理器的sysclk7 可以通过什么方法测试吗?

    输出到SYSCLKOUT看一下。需要使能DEVCFG。

    clockSpeedKHz —>66000,表示SPI始终频率设置了66M,为何计算的传输速率只有3Mbps?

    这是在evm板上测出来的数据。

  • 关于输出到SYSCLKOUT看一下。需要使能DEVCFG。

    7242.K1_STK_v1.1的SPI的主函数初始化代码如下:

    void main()
    {
    Uint32 tscl, tsch;
    int iFLASH_size_KB;
    int iFLASH_addres_width;

    /*enable TSC, memory protection interrupts, EDC for internal RAM;
    clear cache; protect L1 as cache*/
    KeyStone_common_CPU_init();
    /*print device information.
    Enable memory protection interrupts, EDC for MSMC RAM*/
    KeyStone_common_device_init();

    //enable exception handling
    KeyStone_Exception_cfg(TRUE);

    CACHE_setL1PSize(CACHE_L1_32KCACHE);
    CACHE_setL1DSize(CACHE_L1_32KCACHE);
    CACHE_setL2Size(CACHE_128KCACHE);

    /*clear configuration structure to default values*/
    memset(&spiCfg, 0, sizeof(spiCfg));
    memset(&spiIntCfg, 0, sizeof(spiIntCfg));


    if(C6678_EVM==gDSP_board_type)
    {
    printf("\nSPI EDMA test at %dMHz...\n",C6678_EVM);
    //DSP core speed: 100*10/1=1000MHz
    KeyStone_main_PLL_init(100, 10, 1);

    //On Shannon, SPI belong to clock domain 3 which need be enabled
    KeyStone_enable_PSC_module(CSL_PSC_PD_ALWAYSON, 3);
    }

    tscl= TSCL;
    tsch= TSCH;
    printf("SPI test complete at %lld cycle\n", _itoll(tsch, tscl));
    CACHE_invAllL1p(CACHE_WAIT);
    CACHE_wbInvAllL1d(CACHE_WAIT);
    CSL_XMC_invalidatePrefetchBuffer();
    _mfence();
    _mfence();
    }

    因本人刚接触DSP,技术方面比较白。查下说明书,DEVCFG是CSL_BOOT_CFG_REGS (0x02620000)结构的成员。

    我也没有在主函数找到 CSL_BOOT_CFG_REGS .DEVCFG的控制代码,请问Main函数中那个函数是控制DEVCFG的吗?

    这边使用7242.K1_STK_v1.1的SPI代码,控制台输出:

    SPI internal loopback test at 66MHz...
    SPI loopback test passed with data pattern 0x0. Throughput= 28Mbps
    SPI loopback test passed with data pattern 0xffff. Throughput= 28Mbps
    SPI loopback test passed with data pattern 0x5555. Throughput=28Mbps
    SPI interrupt test: manually generate RX overrun error...
    SPI test complete at 1003485114615 cycle

    因功能原因没有采用TI MVN平台,公司购买创龙TL 6678平台运行DDR3 初始化失败了,屏蔽了如下代码:

    //DDR init 66.66667*20/1= 1333
    // KeyStone_DDR_init (66.66667, 20, 1, NULL);

    // SPI_Interrupts_Init();

    请教下,如果我们系统功能不使用DDR功能和SPI中断,这些代码屏蔽后,不会影响SPI的功能吧。

  • 因本人刚接触DSP,技术方面比较白。查下说明书,DEVCFG是CSL_BOOT_CFG_REGS (0x02620000)结构的成员。

    我也没有在主函数找到 CSL_BOOT_CFG_REGS .DEVCFG的控制代码,请问Main函数中那个函数是控制DEVCFG的吗?

    这个问题自己应该知道怎么解决了,不用回答了。

  • 如果我们系统功能不使用DDR功能和SPI中断,

    不使用的话不影响。

  • 你好。咨询下,在我们的开发板上我跑相同SPI回环程序,如果吞吐率只有28Mbps,是程序增加了一些LOG输出的原因,还是硬件损耗的原因吗?

  • 是程序增加了一些LOG输出的原因

    看您log加在哪里,如果影响cycle计数的话,也是会影响最终计算的吞吐率的。

  • 是的 ,LOG和数据大小都会影响吞吐率。

    我请教下,下面控制台输出信息:

    JTAG ID= 0x1009e02f. This is C6678/TCI6608 device, version variant = 1.
    DEVSTAT= 0x00000001. little endian, No boot or EMIF16(NOR FLASH) or UART boot, PLL configuration implies the input clock for core is 50MHz.SmartReflex VID= 57, required core voltage= 1.065V.
    Die ID= 0x0400800a, 0x04046c58, 0xa0000000, 0x6aa80021
    Device speed grade = 1000MHz.

    其中,PLL configuration implies the input clock for core is 50MHz. 我使用的是DSP6678 SOC平台核心输PLL 50MHZ正常吗?小白一个不知道具体代表什么,能给说明下吗 ?

  • 如果您有新的问题,建议另起新帖,方便其他客户查看,谢谢配合!