• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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