TMS320F28335: F28335MCBSP配置SPI模式数据读取发生移位问题

Part Number: TMS320F28335

近期我在Ti F28335DSP芯片上使用McBSP作为SPI MASTER使用,和对端FLASH芯片进行通信,通过读取FLASH ID来验证软件读写配置,但是发现无论怎么改配置包括但不限于CLKSTP,SPI MODE等寄存器,回读到的Bit位相较于正确值总是发生移位(左右都会有,根据软件配置不一样),例如正确要读到的FLASH ID值为 C2 20 1B,但实际读到的值为:E1 10 0D。已经困扰很久,可否还有其他思路,万分感谢

CODE:

#include "ext_flash.h"

// ========== GPIO 初始化(CS/WP/HOLD 用普通 GPIO)==========
static void Flash_GpioInit(void)
{
    EALLOW;

    // CS (GPIO23) - 普通 GPIO 输出
#if 1
    GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO23 = 1;
#else
    GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0;   // 使能上拉
    GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 0;   // GPIO 模式
    GpioCtrlRegs.GPADIR.bit.GPIO24 = 1;    // 输出
#endif
    // WP (GPIO25) - 输出高
    GpioCtrlRegs.GPAPUD.bit.GPIO25 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO25 = 1;

    // HOLD (GPIO26) - 输出高
    GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO26 = 1;

    EDIS;

    FLASH_WP_H();
    FLASH_HOLD_H();
    FLASH_CS_H();
}

// ========== McBSP-A GPIO 复用配置 ==========
static void Mcbspa_GpioInit(void)
{
    EALLOW;

    // MDXA (GPIO20) - 发送数据 → Flash DI
    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2;

    // MDRA (GPIO21) - 接收数据 ← Flash DO
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 2;

    // MCLKXA (GPIO22) - 发送时钟
    GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2;

//    GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;
//    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 2;   // McBSP-A FSX

    EDIS;
}

// ========== 延时函数(复制 TI 官方)==========
static void delay_loop(void)
{
    volatile long i;
    for (i = 0; i < 1000; i++)
    {
        asm(" NOP");
    }
}

// ========== McBSP-A 配置为 SPI 主模式(Mode 0, 32-bit)==========
// 完全复制回环测试通过的配置,只改 DLB=0
static void Mcbspa_SpiInit(void)
{
    EALLOW;

    // 使能 McBSP-A 时钟
    SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 1;

    // 软件复位
    McbspaRegs.SPCR2.all = 0x0000;
    McbspaRegs.SPCR1.all = 0x0000;
    //asm(" RPT #2 || NOP");
    DELAY_US(10);

    McbspaRegs.PCR.all = 0x0F08;

    // 关闭数字回环(外部模式)
    McbspaRegs.SPCR1.bit.DLB = 0;

    // SPI Mode 0: CLKSTP = 2 (bit12:11)
    McbspaRegs.SPCR1.bit.CLKSTP = 3;
    McbspaRegs.PCR.bit.CLKXP = 1;
    McbspaRegs.PCR.bit.CLKRP = 1;

    // 数据延迟
    McbspaRegs.RCR2.bit.RDATDLY = 1;
    McbspaRegs.XCR2.bit.XDATDLY = 1;

    // ========== 32-bit 字长(和回环测试一致)==========
    McbspaRegs.RCR1.bit.RWDLEN1 = 0;
    McbspaRegs.XCR1.bit.XWDLEN1 = 0;

    // 采样率发生器
    McbspaRegs.SRGR2.all = 0x2000;
    McbspaRegs.SRGR1.all = 0x0008;

    // 退出复位(和回环测试完全一致)
    McbspaRegs.SPCR2.bit.GRST = 1;

    // Enable the sample rate generator
    DELAY_US(10);
    McbspaRegs.SPCR2.bit.XRST = 1;
    McbspaRegs.SPCR1.bit.RRST = 1;
    McbspaRegs.SPCR2.bit.FRST = 1;

    EDIS;
}

Uint8 ExtFlash_SwapByte(Uint8 txData)
{
    // 等 XRDY
    while(McbspaRegs.SPCR2.bit.XRDY == 0);

    McbspaRegs.DXR1.all = (Uint16)txData;

    // 等 RRDY
    while(McbspaRegs.SPCR1.bit.RRDY == 0);

    volatile Uint16 dummy = McbspaRegs.DRR2.all;
    return (Uint8)(McbspaRegs.DRR1.all & 0xFF);
}

// ========== 初始化入口 ==========
void ExtFlash_Init(void)
{
    Flash_GpioInit();
    Mcbspa_GpioInit();
    Mcbspa_SpiInit();
}

// ========== 读 JEDEC ID ==========
void ExtFlash_ReadID(Uint8 *pBuf, Uint8 len)
{
    Uint8 i;
    char buf[64];

    FLASH_CS_L();
    DELAY_US(10);

    ExtFlash_SwapByte(FLASH_CMD_RDID);
    //ExtFlash_SwapByte(0xFF);
    for(i = 0; i < len; i++)
        pBuf[i] = ExtFlash_SwapByte(0xFF);

    FLASH_CS_H();

    sprintf(buf, "JEDEC ID: %02X %02X %02X\r\n", pBuf[0], pBuf[1], pBuf[2]);
    UARTa_SendString(buf);
}