Browse Source

projects/riscv_usb: Improve and add flash write support to the SPI driver

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Sylvain Munaut 5 years ago
parent
commit
66a84a317a
2 changed files with 103 additions and 7 deletions
  1. 94 3
      projects/riscv_usb/fw/spi.c
  2. 9 4
      projects/riscv_usb/fw/spi.h

+ 94 - 3
projects/riscv_usb/fw/spi.c

@@ -104,6 +104,23 @@ spi_xfer(unsigned cs, struct spi_xfer_chunk *xfer, unsigned n)
 }
 }
 
 
 
 
+#define FLASH_CMD_DEEP_POWER_DOWN	0xb9
+#define FLASH_CMD_WAKE_UP		0xab
+#define FLASH_CMD_WRITE_ENABLE		0x06
+#define FLASH_CMD_WRITE_ENABLE_VOLATILE	0x50
+#define FLASH_CMD_WRITE_DISABLE		0x04
+
+#define FLASH_CMD_READ_MANUF_ID		0x9f
+#define FLASH_CMD_READ_UNIQUE_ID	0x4b
+
+#define FLASH_CMD_READ_SR1		0x05
+#define FLASH_CMD_WRITE_SR1		0x01
+
+#define FLASH_CMD_READ_DATA		0x03
+#define FLASH_CMD_PAGE_PROGRAM		0x02
+#define FLASH_CMD_CHIP_ERASE		0x60
+#define FLASH_CMD_SECTOR_ERASE		0x20
+
 void
 void
 flash_cmd(uint8_t cmd)
 flash_cmd(uint8_t cmd)
 {
 {
@@ -114,9 +131,39 @@ flash_cmd(uint8_t cmd)
 }
 }
 
 
 void
 void
+flash_deep_power_down(void)
+{
+	flash_cmd(FLASH_CMD_DEEP_POWER_DOWN);
+}
+
+void
+flash_wake_up(void)
+{
+	flash_cmd(FLASH_CMD_WAKE_UP);
+}
+
+void
+flash_write_enable(void)
+{
+	flash_cmd(FLASH_CMD_WRITE_ENABLE);
+}
+
+void
+flash_write_enable_volatile(void)
+{
+	flash_cmd(FLASH_CMD_WRITE_ENABLE_VOLATILE);
+}
+
+void
+flash_write_disable(void)
+{
+	flash_cmd(FLASH_CMD_WRITE_DISABLE);
+}
+
+void
 flash_manuf_id(void *manuf)
 flash_manuf_id(void *manuf)
 {
 {
-	uint8_t cmd = 0x9f;
+	uint8_t cmd = FLASH_CMD_READ_MANUF_ID;
 	struct spi_xfer_chunk xfer[2] = {
 	struct spi_xfer_chunk xfer[2] = {
 		{ .data = (void*)&cmd,  .len = 1, .read = false, .write = true,  },
 		{ .data = (void*)&cmd,  .len = 1, .read = false, .write = true,  },
 		{ .data = (void*)manuf, .len = 3, .read = true,  .write = false, },
 		{ .data = (void*)manuf, .len = 3, .read = true,  .write = false, },
@@ -127,7 +174,7 @@ flash_manuf_id(void *manuf)
 void
 void
 flash_unique_id(void *id)
 flash_unique_id(void *id)
 {
 {
-	uint8_t cmd = 0x4b;
+	uint8_t cmd = FLASH_CMD_READ_UNIQUE_ID;
 	struct spi_xfer_chunk xfer[3] = {
 	struct spi_xfer_chunk xfer[3] = {
 		{ .data = (void*)&cmd, .len = 1, .read = false, .write = true,  },
 		{ .data = (void*)&cmd, .len = 1, .read = false, .write = true,  },
 		{ .data = (void*)0,    .len = 4, .read = false, .write = false, },
 		{ .data = (void*)0,    .len = 4, .read = false, .write = false, },
@@ -136,13 +183,57 @@ flash_unique_id(void *id)
 	spi_xfer(SPI_CS_FLASH, xfer, 3);
 	spi_xfer(SPI_CS_FLASH, xfer, 3);
 }
 }
 
 
+uint8_t
+flash_read_sr(void)
+{
+	uint8_t cmd = FLASH_CMD_READ_SR1;
+	uint8_t rv;
+	struct spi_xfer_chunk xfer[2] = {
+		{ .data = (void*)&cmd, .len = 1, .read = false, .write = true,  },
+		{ .data = (void*)&rv,  .len = 1, .read = true,  .write = false, },
+	};
+	spi_xfer(SPI_CS_FLASH, xfer, 2);
+	return rv;
+}
+
+void
+flash_write_sr(uint8_t sr)
+{
+	uint8_t cmd[2] = { FLASH_CMD_WRITE_SR1, sr };
+	struct spi_xfer_chunk xfer[1] = {
+		{ .data = (void*)cmd, .len = 2, .read = false, .write = true,  },
+	};
+	spi_xfer(SPI_CS_FLASH, xfer, 1);
+}
+
 void
 void
 flash_read(void *dst, uint32_t addr, unsigned len)
 flash_read(void *dst, uint32_t addr, unsigned len)
 {
 {
-	uint8_t cmd[4] = { 0x03, ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff)  };
+	uint8_t cmd[4] = { FLASH_CMD_READ_DATA, ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff)  };
 	struct spi_xfer_chunk xfer[2] = {
 	struct spi_xfer_chunk xfer[2] = {
 		{ .data = (void*)cmd, .len = 4,   .read = false, .write = true,  },
 		{ .data = (void*)cmd, .len = 4,   .read = false, .write = true,  },
 		{ .data = (void*)dst, .len = len, .read = true,  .write = false, },
 		{ .data = (void*)dst, .len = len, .read = true,  .write = false, },
 	};
 	};
 	spi_xfer(SPI_CS_FLASH, xfer, 2);
 	spi_xfer(SPI_CS_FLASH, xfer, 2);
 }
 }
+
+void
+flash_page_program(void *src, uint32_t addr, unsigned len)
+{
+	uint8_t cmd[4] = { FLASH_CMD_PAGE_PROGRAM, ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff)  };
+	struct spi_xfer_chunk xfer[2] = {
+		{ .data = (void*)cmd, .len = 4,   .read = false, .write = true, },
+		{ .data = (void*)src, .len = len, .read = false, .write = true, },
+	};
+	spi_xfer(SPI_CS_FLASH, xfer, 2);
+}
+
+void
+flash_sector_erase(uint32_t addr)
+{
+	uint8_t cmd[4] = { FLASH_CMD_SECTOR_ERASE, ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff)  };
+	struct spi_xfer_chunk xfer[1] = {
+		{ .data = (void*)cmd, .len = 4,   .read = false, .write = true,  },
+	};
+	spi_xfer(SPI_CS_FLASH, xfer, 1);
+}

+ 9 - 4
projects/riscv_usb/fw/spi.h

@@ -29,7 +29,7 @@ struct spi_xfer_chunk {
 	uint8_t *data;
 	uint8_t *data;
 	unsigned len;
 	unsigned len;
 	bool write;
 	bool write;
-	bool read; 
+	bool read;
 };
 };
 
 
 #define SPI_CS_FLASH	0
 #define SPI_CS_FLASH	0
@@ -39,9 +39,14 @@ void spi_init(void);
 void spi_xfer(unsigned cs, struct spi_xfer_chunk *xfer, unsigned n);
 void spi_xfer(unsigned cs, struct spi_xfer_chunk *xfer, unsigned n);
 
 
 void flash_cmd(uint8_t cmd);
 void flash_cmd(uint8_t cmd);
+void flash_deep_power_down(void);
+void flash_wake_up(void);
+void flash_write_enable(void);
+void flash_write_disable(void);
 void flash_manuf_id(void *manuf);
 void flash_manuf_id(void *manuf);
 void flash_unique_id(void *id);
 void flash_unique_id(void *id);
+uint8_t flash_read_sr(void);
+void flash_write_sr(uint8_t sr);
 void flash_read(void *dst, uint32_t addr, unsigned len);
 void flash_read(void *dst, uint32_t addr, unsigned len);
-
-static inline void flash_power_up(void)   { flash_cmd(0xab); };
-static inline void flash_power_down(void) { flash_cmd(0xb9); };
+void flash_page_program(void *src, uint32_t addr, unsigned len);
+void flash_sector_erase(uint32_t addr);