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);
}