1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "sdkconfig.h"
15
16 #include "hal/spi_flash_hal.h"
17 #if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
18 void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host);
19 void spi_flash_hal_disable_auto_resume_mode(spi_flash_host_inst_t *host);
20 void spi_flash_hal_disable_auto_suspend_mode(spi_flash_host_inst_t *host);
21 void spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t *host);
22 #endif //SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
23
24 #ifndef CONFIG_SPI_FLASH_ROM_IMPL
25
26 #include "spi_flash_hal_common.inc"
27
28 // HAL for
29 // - MEMSPI
30 // - SPI1~3 on ESP32/S2/S3/C3
31 // The common part is in spi_flash_hal_common.inc
32
spi_flash_hal_erase_chip(spi_flash_host_inst_t * host)33 void spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
34 {
35 spi_dev_t *dev = get_spi_dev(host);
36 spi_flash_ll_erase_chip(dev);
37 #if SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
38 if((((spi_flash_hal_context_t*)host)->flags & SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND) == 0) {
39 host->driver->poll_cmd_done(host);
40 }
41 #else
42 host->driver->poll_cmd_done(host);
43 #endif
44 }
45
46 // Only support 24bit address
spi_flash_hal_erase_sector(spi_flash_host_inst_t * host,uint32_t start_address)47 void spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
48 {
49 spi_dev_t *dev = get_spi_dev(host);
50 spi_flash_ll_set_addr_bitlen(dev, 24);
51 spi_flash_ll_set_address(dev, start_address & ADDRESS_MASK_24BIT);
52 spi_flash_ll_erase_sector(dev);
53
54 #if SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
55 if((((spi_flash_hal_context_t*)host)->flags & SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND) == 0) {
56 host->driver->poll_cmd_done(host);
57 }
58 #else
59 host->driver->poll_cmd_done(host);
60 #endif
61 }
62
63 // Only support 24bit address
spi_flash_hal_erase_block(spi_flash_host_inst_t * host,uint32_t start_address)64 void spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
65 {
66 spi_dev_t *dev = get_spi_dev(host);
67 spi_flash_ll_set_addr_bitlen(dev, 24);
68 spi_flash_ll_set_address(dev, start_address & ADDRESS_MASK_24BIT);
69 spi_flash_ll_erase_block(dev);
70 #if SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
71 if((((spi_flash_hal_context_t*)host)->flags & SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND) == 0) {
72 host->driver->poll_cmd_done(host);
73 }
74 #else
75 host->driver->poll_cmd_done(host);
76 #endif
77 }
78
79 // Only support 24bit address
spi_flash_hal_program_page(spi_flash_host_inst_t * host,const void * buffer,uint32_t address,uint32_t length)80 void spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
81 {
82 spi_dev_t *dev = get_spi_dev(host);
83 spi_flash_ll_set_addr_bitlen(dev, 24);
84 spi_flash_ll_set_address(dev, (address & ADDRESS_MASK_24BIT) | (length << 24));
85 spi_flash_ll_program_page(dev, buffer, length);
86 host->driver->poll_cmd_done(host);
87 }
88
spi_flash_hal_set_write_protect(spi_flash_host_inst_t * host,bool wp)89 esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
90 {
91 spi_dev_t *dev = get_spi_dev(host);
92 spi_flash_ll_set_write_protect(dev, wp);
93 host->driver->poll_cmd_done(host);
94 return ESP_OK;
95 }
96
97 #else // defined CONFIG_SPI_FLASH_ROM_IMPL
98
get_spi_dev(spi_flash_host_inst_t * host)99 static inline spi_dev_t *get_spi_dev(spi_flash_host_inst_t *host)
100 {
101 return ((spi_flash_hal_context_t*)host)->spi;
102 }
103
get_host_id(spi_flash_host_inst_t * host)104 static inline int get_host_id(spi_flash_host_inst_t* host)
105 {
106 spi_dev_t *dev = get_spi_dev(host);
107 return spi_flash_ll_hw_get_id(dev);
108 }
109
110 #endif // !CONFIG_SPI_FLASH_ROM_IMPL
111
spi_flash_hal_check_status(spi_flash_host_inst_t * host)112 uint32_t spi_flash_hal_check_status(spi_flash_host_inst_t *host)
113 {
114 spi_dev_t *dev = get_spi_dev(host);
115 uint32_t status = spi_flash_ll_host_idle(dev);
116 #if SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
117 uint32_t sus_status = spimem_flash_ll_sus_status((spi_mem_dev_t*)dev) << 1;
118 #else
119 uint32_t sus_status = 0;
120 #endif
121 // Not clear if this is necessary, or only necessary if
122 // chip->spi == SPI1. But probably doesn't hurt...
123 if ((void*) dev == spi_flash_ll_get_hw(SPI1_HOST)) {
124 #if CONFIG_IDF_TARGET_ESP32
125 status &= spi_flash_ll_host_idle(&SPI0);
126 #endif
127 }
128
129 //status and sus_status should be mutual exclusion
130 return (status | sus_status);
131 }
132
spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t * host,const spi_flash_sus_cmd_conf * sus_conf)133 esp_err_t spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
134 {
135 #if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
136 spi_mem_dev_t *dev = (spi_mem_dev_t *)spi_flash_ll_get_hw(SPI1_HOST);
137 spi_flash_hal_context_t* ctx = (spi_flash_hal_context_t*)host;
138 memcpy(&(ctx->sus_cfg), sus_conf, sizeof(spi_flash_sus_cmd_conf));
139 spimem_flash_ll_set_read_sus_status(dev, sus_conf->sus_mask);
140 spimem_flash_ll_suspend_cmd_setup(dev, sus_conf->sus_cmd);
141 spimem_flash_ll_resume_cmd_setup(dev, sus_conf->res_cmd);
142 spimem_flash_ll_rd_sus_cmd_setup(dev, sus_conf->cmd_rdsr);
143 #endif // SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
144 return ESP_OK;
145 }
146
147 #if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t * host)148 void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host)
149 {
150 spi_mem_dev_t *dev = (spi_mem_dev_t*)spi_flash_ll_get_hw(SPI1_HOST);
151 spimem_flash_ll_auto_wait_idle_init(dev, true);
152 spimem_flash_ll_auto_suspend_init(dev, true);
153 #if SOC_SPI_MEM_SUPPORT_CHECK_SUS
154 spimem_flash_ll_sus_check_sus_setup(dev, true);
155 #endif
156 }
157
spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t * host)158 void spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t *host)
159 {
160 spi_mem_dev_t *dev = (spi_mem_dev_t*)spi_flash_ll_get_hw(SPI1_HOST);
161 spimem_flash_ll_auto_resume_init(dev, true);
162 #if SOC_SPI_MEM_SUPPORT_CHECK_SUS
163 spimem_flash_ll_res_check_sus_setup(dev, true);
164 #endif
165 }
166
spi_flash_hal_disable_auto_suspend_mode(spi_flash_host_inst_t * host)167 void spi_flash_hal_disable_auto_suspend_mode(spi_flash_host_inst_t *host)
168 {
169 spi_mem_dev_t *dev = (spi_mem_dev_t *)spi_flash_ll_get_hw(SPI1_HOST);
170 spimem_flash_ll_auto_wait_idle_init(dev, false);
171 spimem_flash_ll_auto_suspend_init(dev, false);
172 #if SOC_SPI_MEM_SUPPORT_CHECK_SUS
173 spimem_flash_ll_sus_check_sus_setup(dev, false);
174 #endif
175 }
176
spi_flash_hal_disable_auto_resume_mode(spi_flash_host_inst_t * host)177 void spi_flash_hal_disable_auto_resume_mode(spi_flash_host_inst_t *host)
178 {
179 spi_mem_dev_t *dev = (spi_mem_dev_t*)spi_flash_ll_get_hw(SPI1_HOST);
180 spimem_flash_ll_auto_resume_init(dev, false);
181 #if SOC_SPI_MEM_SUPPORT_CHECK_SUS
182 spimem_flash_ll_res_check_sus_setup(dev, false);
183 #endif
184 }
185 #endif // SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
186
spi_flash_hal_resume(spi_flash_host_inst_t * host)187 void spi_flash_hal_resume(spi_flash_host_inst_t *host)
188 {
189 #if SOC_SPI_MEM_SUPPORT_SW_SUSPEND
190 spimem_flash_ll_resume((spi_mem_dev_t*)(((spi_flash_hal_context_t *)host)->spi));
191 #else
192 abort();
193 #endif
194 }
195
spi_flash_hal_suspend(spi_flash_host_inst_t * host)196 void spi_flash_hal_suspend(spi_flash_host_inst_t *host)
197 {
198 #if SOC_SPI_MEM_SUPPORT_SW_SUSPEND
199 spimem_flash_ll_suspend((spi_mem_dev_t *)(((spi_flash_hal_context_t *)host)->spi));
200 #else
201 abort();
202 #endif
203 }
204