MeterLogger
ext_spi_flash.c
Go to the documentation of this file.
1 #include <esp8266.h>
2 #include "driver/spi.h"
3 #include "driver/ext_spi_flash.h"
4 
5 #include <limits.h>
6 
8 void ext_spi_init() {
9 #ifdef DEBUG
10  uint16_t flash_id;
11 #endif
12 
14  spi_clock(HSPI, 4, 2); //10MHz
17 
20 
21 
22 #ifdef DEBUG
23  flash_id = ext_spi_flash_id();
24  os_printf("manufacturer ID: 0x%x, device ID: 0x%x\n", (flash_id >> 8), (flash_id & 0xff));
25 #endif
26 }
27 
29 uint16_t ext_spi_flash_id() {
30  return spi_transaction(HSPI, 8, 0x90, 24, 0, 0, 0, 16, 0); // read manufacturer ID / device ID
31 }
32 
35  sec = sec << 12; // 4 kB per sector in NAND FLASH RAM
36  spi_transaction(HSPI, 8, 0x06, 0, 0, 0, 0, 0, 0); // write enable
37  spi_transaction(HSPI, 8, 0x20, 24, sec, 0, 0, 0, 0); // sector erase
38 
39  while (spi_transaction(HSPI, 8, 0x05, 0, 0, 0, 0, 16, 0) & 0x100) { // read status register
40  // wait while BUSY flag is set
41  }
42 
43  return true;
44 }
45 
47 bool ext_spi_flash_read(uint32_t src_addr, uint32_t *dst_addr, uint32_t size) {
48  uint16_t i;
49 
50  if (size <= sizeof(uint32_t)) {
51 #ifdef EXT_SPI_RAM_IS_NAND
52  *dst_addr = spi_transaction(HSPI, 8, 0x03, 24, src_addr, 0, 0, size * CHAR_BIT, 0);
53 #else
54  *dst_addr = spi_transaction(HSPI, 8, 0x03, 16, src_addr, 0, 0, size * CHAR_BIT, 0);
55 #endif
56  }
57  else {
58  for (i = 0; i < (size / sizeof(uint32_t)); i++) {
59 #ifdef EXT_SPI_RAM_IS_NAND
60  *(dst_addr + i) = spi_transaction(HSPI, 8, 0x03, 24, src_addr + sizeof(uint32_t) * i, 0, 0, sizeof(uint32_t) * CHAR_BIT, 0);
61 #else
62  *(dst_addr + i) = spi_transaction(HSPI, 8, 0x03, 16, src_addr + sizeof(uint32_t) * i, 0, 0, sizeof(uint32_t) * CHAR_BIT, 0);
63 #endif
64  }
65  if (size % sizeof(uint32_t)) {
66 #ifdef EXT_SPI_RAM_IS_NAND
67  *(dst_addr + i) = spi_transaction(HSPI, 8, 0x03, 24, src_addr + sizeof(uint32_t) * i, 0, 0, (size % sizeof(uint32_t)) * CHAR_BIT, 0);
68 #else
69  *(dst_addr + i) = spi_transaction(HSPI, 8, 0x03, 16, src_addr + sizeof(uint32_t) * i, 0, 0, (size % sizeof(uint32_t)) * CHAR_BIT, 0);
70 #endif
71  }
72  }
73 
74  return true;
75 }
76 
78 bool ext_spi_flash_write(uint32_t dst_addr, uint32_t *src_addr, uint32_t size) {
79  uint16_t i;
80 
81  if (size <= sizeof(uint32_t)) {
82  spi_transaction(HSPI, 8, 0x06, 0, 0, 0, 0, 0, 0); // write enable
83 #ifdef EXT_SPI_RAM_IS_NAND
84  spi_transaction(HSPI, 8, 0x02, 24, dst_addr, size * CHAR_BIT, *src_addr, 0, 0); // page program, 8 * size bit data
85 #else
86  spi_transaction(HSPI, 8, 0x02, 16, dst_addr, size * CHAR_BIT, *src_addr, 0, 0); // page program, 8 * size bit data
87 #endif
88 
89 #ifdef EXT_SPI_RAM_IS_NAND
90  while (spi_transaction(HSPI, 8, 0x05, 0, 0, 0, 0, 16, 0) & 0x100) { // read status register
91  // wait while BUSY flag is set
92  }
93 #endif
94  }
95  else {
96  for (i = 0; i < (size / sizeof(uint32_t)); i++) {
97  spi_transaction(HSPI, 8, 0x06, 0, 0, 0, 0, 0, 0); // write enable
98 #ifdef EXT_SPI_RAM_IS_NAND
99  spi_transaction(HSPI, 8, 0x02, 24, dst_addr + sizeof(uint32_t) * i, sizeof(uint32_t) * CHAR_BIT, *(src_addr + i), 0, 0); // page program, 8 * size bit data
100 #else
101  spi_transaction(HSPI, 8, 0x02, 16, dst_addr + sizeof(uint32_t) * i, sizeof(uint32_t) * CHAR_BIT, *(src_addr + i), 0, 0); // page program, 8 * size bit data
102 #endif
103 
104 #ifdef EXT_SPI_RAM_IS_NAND
105  while (spi_transaction(HSPI, 8, 0x05, 0, 0, 0, 0, 16, 0) & 0x100) { // read status register
106  // wait while BUSY flag is set
107  }
108 #endif
109  }
110  if (size % sizeof(uint32_t)) {
111  spi_transaction(HSPI, 8, 0x06, 0, 0, 0, 0, 0, 0); // write enable
112 #ifdef EXT_SPI_RAM_IS_NAND
113  spi_transaction(HSPI, 8, 0x02, 24, dst_addr + sizeof(uint32_t) * i, (size % sizeof(uint32_t)) * CHAR_BIT, *(src_addr + i) & ((1 << (size % sizeof(uint32_t)) * CHAR_BIT) - 1), 0, 0); // page program, 8 * size bit data
114 #else
115  spi_transaction(HSPI, 8, 0x02, 16, dst_addr + sizeof(uint32_t) * i, (size % sizeof(uint32_t)) * CHAR_BIT, *(src_addr + i) & ((1 << (size % sizeof(uint32_t)) * CHAR_BIT) - 1), 0, 0); // page program, 8 * size bit data
116 #endif
117 
118 #ifdef EXT_SPI_RAM_IS_NAND
119  while (spi_transaction(HSPI, 8, 0x05, 0, 0, 0, 0, 16, 0) & 0x100) { // read status register
120  // wait while BUSY flag is set
121  }
122 #endif
123  }
124  }
125 
126  return true;
127 }
128 
130 void ext_spi_flash_hexdump(uint32_t addr) {
131 #ifdef DEBUG
132  uint32_t flash_data_buf;
133  uint32_t byte_count;
134 
135  os_printf("%08x ", addr);
136  for (byte_count = 0; byte_count < 15; byte_count++) {
137  ext_spi_flash_read(addr, &flash_data_buf, sizeof(flash_data_buf));
138  os_printf("%02x ", (flash_data_buf & 0xff));
139  addr++;
140  }
141  ext_spi_flash_read(addr, &flash_data_buf, sizeof(flash_data_buf));
142  os_printf("%02x\n", (flash_data_buf & 0xff));
143  addr++;
144 #endif
145 }
ICACHE_FLASH_ATTR uint32 spi_transaction(uint8 spi_no, uint8 cmd_bits, uint16 cmd_data, uint32 addr_bits, uint32 addr_data, uint32 dout_bits, uint32 dout_data, uint32 din_bits, uint32 dummy_bits)
Definition: spi.c:241
ICACHE_FLASH_ATTR bool ext_spi_flash_read(uint32_t src_addr, uint32_t *dst_addr, uint32_t size)
Definition: ext_spi_flash.c:47
#define SPI_USER(i)
Definition: spi_register.h:107
#define SPI_FLASH_MODE
Definition: spi_register.h:137
ICACHE_FLASH_ATTR void spi_init_gpio(uint8 spi_no, uint8 sysclk_as_spiclk)
Definition: spi.c:97
ICACHE_FLASH_ATTR void spi_tx_byte_order(uint8 spi_no, uint8 byte_order)
Definition: spi.c:176
#define ICACHE_FLASH_ATTR
Definition: c_types.h:99
#define os_printf
Definition: osapi.h:62
#define HSPI
Definition: spi.h:36
#define SPI_CS_SETUP
Definition: spi_register.h:134
ICACHE_FLASH_ATTR void ext_spi_init()
Definition: ext_spi_flash.c:8
#define CLEAR_PERI_REG_MASK(reg, mask)
Definition: eagle_soc.h:70
#define SPI_BYTE_ORDER_LOW_TO_HIGH
Definition: spi.h:42
#define SPI_CLK_USE_DIV
Definition: spi.h:38
ICACHE_FLASH_ATTR void ext_spi_flash_hexdump(uint32_t addr)
ICACHE_FLASH_ATTR bool ext_spi_flash_write(uint32_t dst_addr, uint32_t *src_addr, uint32_t size)
Definition: ext_spi_flash.c:78
ICACHE_FLASH_ATTR void spi_clock(uint8 spi_no, uint16 prediv, uint8 cntdiv)
Definition: spi.c:136
#define SPI_CS_HOLD
Definition: spi_register.h:135
ICACHE_FLASH_ATTR bool ext_spi_flash_erase_sector(uint16_t sec)
Definition: ext_spi_flash.c:34
os_time_t sec
#define SET_PERI_REG_MASK(reg, mask)
Definition: eagle_soc.h:71
ICACHE_FLASH_ATTR void spi_rx_byte_order(uint8 spi_no, uint8 byte_order)
Definition: spi.c:207
ICACHE_FLASH_ATTR uint16_t ext_spi_flash_id()
Definition: ext_spi_flash.c:29