Просмотр исходного кода

更新spi及spi flash驱动,优化传输异常时存在的一些问题(CPU及MCU工程同时更新):
1. 优化spi驱动在传输异常返回时并未将cs拉高问题。
2. 优化sfud驱动0xBB(DUAL_IO)命令dummy数错误问题。
3. 优化部分spi nor flash 个别指令的dummy位存在模式字段,若以dummy传输导致出现低概率切flash模式异常的问题。

helen 1 неделя назад
Родитель
Сommit
9efe915e03

+ 32 - 8
amt630hv160-freertos-beta/ArkmicroFiles/libcpu-amt630hv160/source/dwspi.c

@@ -3,7 +3,9 @@
 #include "board.h"
 #include "pinctrl.h"
 #include "os_adapt.h"
-
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
+#include "sfud_def.h"
+#endif
 #include <string.h>
 
 /* Register offsets */
@@ -629,7 +631,7 @@ static int dw_spi_transfer_one(struct spi_slave *slave, struct spi_message *mess
 	}
 
 end:
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		dw_spi_chipselect(dws, 0);
 	return ret;
 }
@@ -644,9 +646,12 @@ static int dw_qspi_read(struct spi_slave *slave, struct qspi_message *qspi_messa
 	u32 cr0, qspi_cr0, ndf;
 	u32 bits_per_word = 0;
 	u32 addr;
+	u32 dummy_cycles;
+	u8 cmd;
 	unsigned long transfer_timeout;
 	u32 xfer_len = 0;
 	int ret = 0;
+	int hasmode = 0;
 
 	chip->tmode = SPI_TMOD_RO;
 
@@ -685,9 +690,9 @@ xfer_continue:
 
 	spi_set_clk(dws, chip->qspi_clk_div);
 
-	if (dws->current_freq >= 63500000)
+	if (dws->current_qspi_freq >= 63500000)
 		dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, 2);
-	else if (dws->current_freq >= 50000000)
+	else if (dws->current_qspi_freq >= 50000000)
 		dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, 1);
 
 	if (message->cs_take)
@@ -708,9 +713,24 @@ xfer_continue:
 
 	dw_writel(dws, DW_SPI_CTRL1, ndf);
 
-	qspi_cr0 = ((qspi_message->dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
+	cmd = qspi_message->instruction.content;
+	dummy_cycles = qspi_message->dummy_cycles;
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
+	if (((cmd == SFUD_CMD_DUAL_IO_READ_DATA)
+		|| (cmd == (SFUD_CMD_DUAL_IO_READ_DATA + 1)))
+		&& (dummy_cycles >= 4)) {
+		dummy_cycles -= 4;
+		hasmode = 1;
+	} else if (((cmd == SFUD_CMD_QUAD_IO_READ_DATA)
+		|| (cmd == (SFUD_CMD_QUAD_IO_READ_DATA + 1)))
+		&& (dummy_cycles >= 2)) {
+		dummy_cycles -= 2;
+		hasmode = 1;
+	}
+#endif
+	qspi_cr0 = ((dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
 					(2 << SPI_INST_LENGTH_OFFSET) |
-					((qspi_message->address.size >> 2) << SPI_ADDR_LENGTH_OFFSET);
+					(((qspi_message->address.size >> 2) + (hasmode ? 2 : 0)) << SPI_ADDR_LENGTH_OFFSET);
 	if (qspi_message->instruction.qspi_lines == 1 && qspi_message->address.qspi_lines > 1)
 		qspi_cr0 |= 1;
 	else if (qspi_message->instruction.qspi_lines > 1 && qspi_message->address.qspi_lines > 1)
@@ -763,10 +783,14 @@ xfer_continue:
 			(((addr >> 8) & 0xff) << 16) | ((addr & 0xff) << 24);
 	} else {
 		addr = ((addr >> 16) & 0xff) | (((addr >> 8) & 0xff) << 8) | ((addr & 0xff) << 16);
+		if (hasmode)
+			addr |= 0xffU << 24;
 	}
 
-	dw_write_io_reg(dws, DW_SPI_DR, qspi_message->instruction.content);
+	dw_write_io_reg(dws, DW_SPI_DR, cmd);
 	dw_write_io_reg(dws, DW_SPI_DR, addr);
+	if (qspi_message->address.size == 32 && hasmode)
+		dw_write_io_reg(dws, DW_SPI_DR, 0xff);	//send the M7-0 of dummy cycles
 
 	transfer_timeout = dw_spi_calculate_timeout(dws, message->length);
 	if (xQueueReceive(dws->xfer_done, NULL, transfer_timeout) != pdTRUE) {
@@ -816,7 +840,7 @@ xfer_continue:
 	}
 
 end:
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		dw_spi_chipselect(dws, 0);
 	return ret;
 }

+ 1 - 1
amt630hv160-freertos-beta/ArkmicroFiles/libcpu-amt630hv160/source/ecspi.c

@@ -858,7 +858,7 @@ static int ecspi_xfer(struct spi_slave *slave, struct spi_message *message)
 	ret = ark_spi_pio_xfer(aspi, message);
 end:
 #ifndef SPI1_SLAVE_MODE
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		ark_spi_chipselect(aspi, 0);
 #endif
 

+ 1 - 1
amt630hv160-freertos-beta/lib/sfud/src/sfud.c

@@ -234,7 +234,7 @@ sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width)
         break;
     case 2:
         if (read_mode & DUAL_IO) {
-            qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 8, 2);
+            qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 4, 2);
         } else if (read_mode & DUAL_OUTPUT) {
             qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_OUTPUT_READ_DATA, 1, 1, 8, 2);
         } else {

+ 29 - 4
amt630hv160-mcu/amt630hv160-mcu-iram/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_spi.c

@@ -15,6 +15,9 @@
 #include "spi.h"
 #include "amt630hv160_lib.h"
 #include "amt630hv160_dma.h"
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
+#include "sfud_def.h"
+#endif
 
 #if defined(_SPI0) || defined(_SPI2)
 #define SPI0_CS0_GPIO	83
@@ -666,7 +669,7 @@ static int dw_spi_transfer_one(SPISlave *slave, SPIMessage *message)
 	}
 
 end:
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		dw_spi_chipselect(dws, 0);
 	return ret;
 }
@@ -681,9 +684,12 @@ static int dw_qspi_read(SPISlave *slave, QSPIMessage *qspi_message)
 	u32 cr0, qspi_cr0, ndf;
 	u32 bits_per_word = 0;
 	u32 addr;
+	u32 dummy_cycles;
+	u8 cmd;
 	unsigned long transfer_timeout;
 	u32 xfer_len = 0;
 	int ret = 0;
+	int hasmode = 0;
 
 	chip->tmode = SPI_TMOD_RO;
 
@@ -749,9 +755,24 @@ xfer_continue:
 
 	dws->regs->CTLR1 = ndf;
 
-	qspi_cr0 = ((qspi_message->dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
+	cmd = qspi_message->instruction.content;
+	dummy_cycles = qspi_message->dummy_cycles;
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
+	if (((cmd == SFUD_CMD_DUAL_IO_READ_DATA)
+		|| (cmd == (SFUD_CMD_DUAL_IO_READ_DATA + 1)))
+		&& (dummy_cycles >= 4)) {
+		dummy_cycles -= 4;	//remove the M7-0 of dummy cycles
+		hasmode = 1;
+	} else if (((cmd == SFUD_CMD_QUAD_IO_READ_DATA)
+		|| (cmd == (SFUD_CMD_QUAD_IO_READ_DATA + 1)))
+		&& (dummy_cycles >= 2)) {
+		dummy_cycles -= 2;	//remove the M7-0 of dummy cycles
+		hasmode = 1;
+	}
+#endif
+	qspi_cr0 = ((dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
 					(2 << SPI_INST_LENGTH_OFFSET) |
-					((qspi_message->address.size >> 2) << SPI_ADDR_LENGTH_OFFSET);
+					(((qspi_message->address.size >> 2) + (hasmode ? 2 : 0)) << SPI_ADDR_LENGTH_OFFSET);	//addon the M7-0 of dummy cycles
 	if (qspi_message->instruction.qspi_lines == 1 && qspi_message->address.qspi_lines > 1)
 		qspi_cr0 |= 1;
 	else if (qspi_message->instruction.qspi_lines > 1 && qspi_message->address.qspi_lines > 1)
@@ -810,9 +831,13 @@ xfer_continue:
 			(((addr >> 8) & 0xff) << 16) | ((addr & 0xff) << 24);
 	} else {
 		addr = ((addr >> 16) & 0xff) | (((addr >> 8) & 0xff) << 8) | ((addr & 0xff) << 16);
+		if (hasmode)
+			addr |= 0xffU << 24;	//addon the M7-0 of dummy cycles
 	}
 	dws->regs->DR = qspi_message->instruction.content;
 	dws->regs->DR = addr;
+	if (qspi_message->address.size == 32 && hasmode)
+		dws->regs->DR = 0xff;		//send the M7-0 of dummy cycles
 
 	transfer_timeout = dw_spi_calculate_timeout(dws, message->length);
 	if (xQueueReceive(dws->xfer_done, NULL, transfer_timeout) != pdTRUE) {
@@ -844,7 +869,7 @@ xfer_continue:
 	}
 
 end:
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		dw_spi_chipselect(dws, 0);
 	return ret;
 }

+ 1 - 1
amt630hv160-mcu/amt630hv160-mcu-iram/src/lib/sfud/src/sfud.c

@@ -224,7 +224,7 @@ sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width)
         break;
     case 2:
         if (read_mode & DUAL_IO) {
-            qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 8, 2);
+            qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 4, 2);
         } else if (read_mode & DUAL_OUTPUT) {
             qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_OUTPUT_READ_DATA, 1, 1, 8, 2);
         } else {

+ 29 - 4
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/ArkmicroFiles/libcpu-amt630hv160/source/amt630hv160_spi.c

@@ -15,6 +15,9 @@
 #include "spi.h"
 #include "amt630hv160_lib.h"
 #include "amt630hv160_dma.h"
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
+#include "sfud_def.h"
+#endif
 
 #if defined(_SPI0) || defined(_SPI2)
 #define SPI0_CS0_GPIO	83
@@ -666,7 +669,7 @@ static int dw_spi_transfer_one(SPISlave *slave, SPIMessage *message)
 	}
 
 end:
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		dw_spi_chipselect(dws, 0);
 	return ret;
 }
@@ -681,9 +684,12 @@ static int dw_qspi_read(SPISlave *slave, QSPIMessage *qspi_message)
 	u32 cr0, qspi_cr0, ndf;
 	u32 bits_per_word = 0;
 	u32 addr;
+	u32 dummy_cycles;
+	u8 cmd;
 	unsigned long transfer_timeout;
 	u32 xfer_len = 0;
 	int ret = 0;
+	int hasmode = 0;
 
 	chip->tmode = SPI_TMOD_RO;
 
@@ -749,9 +755,24 @@ xfer_continue:
 
 	dws->regs->CTLR1 = ndf;
 
-	qspi_cr0 = ((qspi_message->dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
+	cmd = qspi_message->instruction.content;
+	dummy_cycles = qspi_message->dummy_cycles;
+#if DEVICE_TYPE_SELECT == SPI_NOR_FLASH
+	if (((cmd == SFUD_CMD_DUAL_IO_READ_DATA)
+		|| (cmd == (SFUD_CMD_DUAL_IO_READ_DATA + 1)))
+		&& (dummy_cycles >= 4)) {
+		dummy_cycles -= 4;	//remove the M7-0 of dummy cycles
+		hasmode = 1;
+	} else if (((cmd == SFUD_CMD_QUAD_IO_READ_DATA)
+		|| (cmd == (SFUD_CMD_QUAD_IO_READ_DATA + 1)))
+		&& (dummy_cycles >= 2)) {
+		dummy_cycles -= 2;	//remove the M7-0 of dummy cycles
+		hasmode = 1;
+	}
+#endif
+	qspi_cr0 = ((dummy_cycles & 0xf) << SPI_WAIT_CYCLES_OFFSET) |
 					(2 << SPI_INST_LENGTH_OFFSET) |
-					((qspi_message->address.size >> 2) << SPI_ADDR_LENGTH_OFFSET);
+					(((qspi_message->address.size >> 2) + (hasmode ? 2 : 0)) << SPI_ADDR_LENGTH_OFFSET);	//addon the M7-0 of dummy cycles
 	if (qspi_message->instruction.qspi_lines == 1 && qspi_message->address.qspi_lines > 1)
 		qspi_cr0 |= 1;
 	else if (qspi_message->instruction.qspi_lines > 1 && qspi_message->address.qspi_lines > 1)
@@ -810,9 +831,13 @@ xfer_continue:
 			(((addr >> 8) & 0xff) << 16) | ((addr & 0xff) << 24);
 	} else {
 		addr = ((addr >> 16) & 0xff) | (((addr >> 8) & 0xff) << 8) | ((addr & 0xff) << 16);
+		if (hasmode)
+			addr |= 0xffU << 24;	//addon the M7-0 of dummy cycles
 	}
 	dws->regs->DR = qspi_message->instruction.content;
 	dws->regs->DR = addr;
+	if (qspi_message->address.size == 32 && hasmode)
+		dws->regs->DR = 0xff;		//send the M7-0 of dummy cycles
 
 	transfer_timeout = dw_spi_calculate_timeout(dws, message->length);
 	if (wait_flag(&dws->xfer_done, transfer_timeout)) {
@@ -844,7 +869,7 @@ xfer_continue:
 	}
 
 end:
-	if (message->cs_release)
+	if (message->cs_release || ret)
 		dw_spi_chipselect(dws, 0);
 	return ret;
 }

+ 1 - 1
amt630hv160-mcu/amt630hv160-mcu-sram-nos/src/lib/sfud/src/sfud.c

@@ -224,7 +224,7 @@ sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width)
         break;
     case 2:
         if (read_mode & DUAL_IO) {
-            qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 8, 2);
+            qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 4, 2);
         } else if (read_mode & DUAL_OUTPUT) {
             qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_OUTPUT_READ_DATA, 1, 1, 8, 2);
         } else {