TI中文支持网
TI专业的中文技术问题搜集分享网站

6678 SPI 连接nor flash 的问题

本人正在调试6678 spi boot,参照http://www.deyisupport.com/question_answer/f/53/t/7411.aspx 帖子中的方法。遇到一系列问题如下:

希望高手指导:

我的 思路是首先将SPI 调通,即可读写外挂的nor flash,然后再研究如何形成烧写文件,但现在卡在第一步无法进行下去:

我是同时在开发板和自己画的板子上进行调试的,现在状态相同。

1.

开发板上使用的nor flash 型号为NUMONYX_N25Q128A11BSF40F  

 而我板子上的型号为N25Q128A11ESF

 区别在于B型的 在bottom处有8个boot sectors,而E型没有。不知道这个boot sector有什么作用,在系统中是否有影响

2.

bootmode 配置为SPI boot模式,程序调试时才可以看到0x20bf0000启示的 spi 模块配置寄存器的值,如果不是spi boot模式,则全为0.

按照那个帖子中的说法,bootmode配置为0b0101000000110 但是我感觉按照我的理解应该配位 1011000000110才对啊。

3.  我配置的部分如下:

uint32_t scalar;

PLIBSPILOCK()

KICK0 = KICK0_UNLOCK;
KICK1 = KICK1_UNLOCK;

/* Enable the SPI hardware */
SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_IN_RESET;
spi_delay (2000);
SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_OUT_OF_RESET;

/* Set master mode, powered up and not activated */
SPI_SPIGCR1 = (CSL_SPI_SPIGCR1_MASTER_MASTER << CSL_SPI_SPIGCR1_MASTER_SHIFT) |
(CSL_SPI_SPIGCR1_CLKMOD_INTERNAL << CSL_SPI_SPIGCR1_CLKMOD_SHIFT);
/* CS0, CS1, CLK, Slave in and Slave out are functional pins */
if (cs == 0) {
SPI_SPIPC0 = (CSL_SPI_SPIPC0_SCS0FUN0_SPI << CSL_SPI_SPIPC0_SCS0FUN0_SHIFT) |
(CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT) |
(CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT) |
(CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT);
} else if (cs == 1) {
SPI_SPIPC0 = ((CSL_SPI_SPIPC0_SCS0FUN1_SPI << CSL_SPI_SPIPC0_SCS0FUN1_SHIFT) |
(CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT) |
(CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT) |
(CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT)) & 0xFFFF;
}
/* setup format */
scalar = ((SPI_MODULE_CLK / freq) – 1 ) & 0xFF;

if ( cs == 0) {
SPI_SPIFMT0 = (8 << CSL_SPI_SPIFMT_CHARLEN_SHIFT) |
(scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT) |
(CSL_SPI_SPIFMT_PHASE_NO_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT) |
(CSL_SPI_SPIFMT_POLARITY_HIGH << CSL_SPI_SPIFMT_POLARITY_SHIFT) |
(CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);
}else if ( cs == 1) {
SPI_SPIFMT0 = (16 << CSL_SPI_SPIFMT_CHARLEN_SHIFT) |
(scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT) |
(CSL_SPI_SPIFMT_PHASE_NO_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT) |
(CSL_SPI_SPIFMT_POLARITY_HIGH << CSL_SPI_SPIFMT_POLARITY_SHIFT) |
(CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);
}

这里polarity 和phase的配置是根据芯片手册如下的描述:

Data are shifted out on
the falling edge of Serial Clock (C). When used as an Input, It is latched on the rising edge
of the Serial Clock (C).

/* hold cs active at end of transfer until explicitly de-asserted */
data1_reg_val = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) |
(0x01 << CSL_SPI_SPIDAT1_CSNR_SHIFT);
if (cs == 0) {
SPI_SPIDAT1 = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) |
(0x01 << CSL_SPI_SPIDAT1_CSNR_SHIFT);
}

/* including a minor delay. No science here. Should be good even with
* no delay
*/
if (cs == 0) {
SPI_SPIDELAY = (8 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |
(8 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);
/* default chip select register */
SPI_SPIDEF = CSL_SPI_SPIDEF_RESETVAL; } else if (cs == 1) { SPI_SPIDELAY = (6 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |
(3 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);
}
/* no interrupts */
SPI_SPIINT0 = CSL_SPI_SPIINT0_RESETVAL;
SPI_SPILVL = CSL_SPI_SPILVL_RESETVAL;

/* enable SPI */
SPI_SPIGCR1 |= ( CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT );

if (cs == 1) {
SPI_SPIDAT0 = 1 << 15; spi_delay (10000); /* Read SPIFLG, wait untill the RX full interrupt */
if ( (SPI_SPIFLG & (CSL_SPI_SPIFLG_RXINTFLG_FULL<<CSL_SPI_SPIFLG_RXINTFLG_SHIFT)) ) { /* Read one byte data */
scalar = SPI_SPIBUF & 0xFF;
/* Clear the Data */
SPI_SPIBUF = 0;
}
else {
/* Read one byte data */
scalar = SPI_SPIBUF & 0xFF;
return SPI_EFAIL;
}
}
KICK0 = 0;
KICK1 = 0;

其中时钟输入100Mhz,倍频至1000MHz,按照宏定义里的SPI_MODULE_CLK (200M) freq 为25M  

按照程序里的说法,spi module clock 是由SYSCLK7提供的,及core_clk/6 实际工作应该spi clk 为20.8M。(这个理解正确么?)

现在可以在确定寄存器是按照上述的配置写进去了,并且有测到 偶尔的时钟脉冲(8个时钟,是否因为配置的charlen为8bit?),时钟确实为20.8M。但是晚上老测不到,不知道是不是因为没有点好。

之后发送ID读取命令,读上来的数 都是0,断点进去,实际上,收上来的三个字节都是ff,而不是正确的20h bbh 18b。

所以一直是 fail to initiate

我断点到具体程序中,可以看到发送的9f命令,已经写到SPIBUF寄存器中,但是为什么后续的读取一直读不上来呢?

请问我有什么关键地方没做到么?

/* Read the ID codes */
ret = spi_cmd(SPI_NOR_CMD_RDID, idcode, sizeof(idcode));

xing wang1:

我很想知道现在这种情况,最可能的是SPI没有正常工作还是 SPI controller没有配置正确

或者有什么思路让我来继续查下去

xing wang1:

今天早上测量的结果是:

刚上电的时候,由于配置为SPI启动模式,可以在 nor flash 的SPI  CLK 与 输入D0上看到时钟脉冲 与持续的0x3命令(read data bytes)

貌似与我猜测的一直,但是时钟只有505kHz。 是否与配置的问题也有关系。

然后检测程序跑起来的nor flash SPI clk 和DO管脚,主要想看到RPID 命令0x9f,是否写下去了。

一直没抓到,不知道是不是我的测量方法有问题。

我的主程序是这样的:

unsigned int i,index; unsigned int *pDdr3Data; int errcnt=0; KeyStone_main_PLL_init (10, 1); //for 100MHz input clock KeyStone_DDR_PLL_init (20, 1); Shannon_EVM_DDR_Init(666.667); //for 1333Mbps

//test ddr3 wander pDdr3Data = (unsigned int *)DDR3BASEADDRESS; for (index = 0; index <10; index++)//0x7FFFFFFF/4 {

pDdr3Data[index]=index;

}

Init_val = nor_init();// Init_val = nor_init_2(); if(!Init_val) printf("Success to initiate.\n"); else printf("Fail to initiate.\n"); //Read_val = nor_read(&gDeviceNor,0x0,0x20404,(uint8_t *)0x820000);

//Erase_val = nor_erase(&gDeviceNor,-1); //整个擦除 Erase_val = nor_SerialErase_sectors(0,0,31); if(!Erase_val) printf("Success to erase.\n"); else printf("Fail to erase.\n");

//Writes data to the NOR flash Write_val = nor_write(&gDeviceNor,0x0,0x6f40,(uint8_t *)Write_data1);//Write_data0

if(!Write_val) printf("Success to write data to NOR Flash.\n"); else printf("Fail to write data to NOR Flash.\n");

//Read data from the NOR Flash Read_val = nor_read(&gDeviceNor,0x0000,0x6f40,(uint8_t *)Read_data0);

for(i=0;i<7120;i++) { if(Read_data0[i]!=Write_data0[i]) errcnt++; } printf("the err cnt is %d.\n",errcnt); while(1);

不断点检测两个管脚看到的稳定波形如下:(断点的时候总看不到输出)

这个是05命令,即RDSR命令,定位到程序中是已经跑到擦除flash 的时候,一直等待WIP为0,即擦除成功之后标志的部分。

xing wang1:

回复 xing wang1:

这个是我的工程

xing wang1:

回复 xing wang1:

找到问题所在了,

/* hold cs active at end of transfer until explicitly de-asserted */ data1_reg_val = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) | (0x01 << CSL_SPI_SPIDAT1_CSNR_SHIFT);//0x02 if (cs == 0) { SPI_SPIDAT1 = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) | (0x01 << CSL_SPI_SPIDAT1_CSNR_SHIFT);//0x02 }

这里配置CSNR的时候,我将原来的0x02 改为了0x01,我以为是配置我用了哪个cs管脚呢~改为0x02就可以通信了,虽然在后面的读写中发生了11次错误(有待进一步找问题)

对于这个寄存器的CSNR的解释如下:

CSNR Chip select number (value = 0-FFh). The CSNR field defines the chip select that will be activated during the data transfer.In slave mode, this field must be written as 00h; in master mode, the value of this field is driven on the chip select pins, i.e.bit[(16+n):16] are put out on SPISCS[n] to SPISCS[0] respectively during a transfer. Please see the device-specific datamanual for the supported number of the chip select pins.

但是我不明白一个问题:

我用来连接NOR FLASH的cs管脚是cs0, 而cs1是和开发板一样连到了控制FPGA上,开发板的解释是读取寄存器。

可这里这种配置是什么意思呢?

对于SPIDA0与SPIDAT1两个寄存器中都有的TXDATA位,都可以作为tx buffer,该程序中使用的是SPIDAT1,那么这两个TXDATA有什么区别?

yang long:

回复 xing wang1:

楼主你好,你的问题解决了吗?408713975,我的QQ,想和你交流一下,谢谢了

Junye Wang:

回复 xing wang1:

您好,我现在调试SPI BOOT遇到了和您一样的情况!

开发板上使用的nor flash 型号为NUMONYX_N25Q128A11BSF40F,而我板子上的型号为N25Q128A11ESF。

现在我能对SPI 的 NOR FLASH进行正常的读写。用TI 官方的NOR writer工程也能正常的烧写进nor flash。

但是重新上电后,拨成SPI BOOT方式后还是BOOT不起来,不知道是什么原因呢?

谢谢!

赞(0)
未经允许不得转载:TI中文支持网 » 6678 SPI 连接nor flash 的问题
分享到: 更多 (0)