• 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 
15 /*******************************************************************************
16  * NOTICE
17  * The ll is not public api, don't use in application code.
18  * See readme.md in hal/include/hal/readme.md
19  ******************************************************************************/
20 
21 // The Lowlevel layer for SPI Flash
22 
23 #pragma once
24 
25 #include <stdlib.h>
26 #include "soc/spi_periph.h"
27 #include "hal/spi_types.h"
28 #include "hal/spi_flash_types.h"
29 #include <sys/param.h> // For MIN/MAX
30 #include <stdbool.h>
31 #include <string.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 //Supported clock register values
38 #define SPI_FLASH_LL_CLKREG_VAL_5MHZ    ((spi_flash_ll_clock_reg_t){.val=0x0000F1CF})   ///< Clock set to 5 MHz
39 #define SPI_FLASH_LL_CLKREG_VAL_10MHZ   ((spi_flash_ll_clock_reg_t){.val=0x000070C7})   ///< Clock set to 10 MHz
40 #define SPI_FLASH_LL_CLKREG_VAL_20MHZ   ((spi_flash_ll_clock_reg_t){.val=0x00003043})   ///< Clock set to 20 MHz
41 #define SPI_FLASH_LL_CLKREG_VAL_26MHZ   ((spi_flash_ll_clock_reg_t){.val=0x00002002})   ///< Clock set to 26 MHz
42 #define SPI_FLASH_LL_CLKREG_VAL_40MHZ   ((spi_flash_ll_clock_reg_t){.val=0x00001001})   ///< Clock set to 40 MHz
43 #define SPI_FLASH_LL_CLKREG_VAL_80MHZ   ((spi_flash_ll_clock_reg_t){.val=0x80000000})   ///< Clock set to 80 MHz
44 
45 /// Get the start address of SPI peripheral registers by the host ID
46 #define spi_flash_ll_get_hw(host_id) ( ((host_id)==SPI1_HOST) ? &SPI1 :(\
47                                        ((host_id)==SPI2_HOST) ? &SPI2 :(\
48                                        ((host_id)==SPI3_HOST) ? &SPI3 :(\
49                                        {abort();(spi_dev_t*)0;}\
50                                      ))) )
51 #define spi_flash_ll_hw_get_id(dev) ( ((dev) == &SPI1) ? SPI1_HOST :(\
52                                       ((dev) == &SPI2) ? SPI2_HOST :(\
53                                       ((dev) == &SPI3) ? SPI3_HOST :(\
54                                       -1\
55                                     ))) )
56 
57 /// Empty function to be compatible with new version chips.
58 #define spi_flash_ll_set_dummy_out(dev, out_en, out_lev)
59 
60 /// type to store pre-calculated register value in above layers
61 typedef typeof(SPI1.clock) spi_flash_ll_clock_reg_t;
62 
63 /*------------------------------------------------------------------------------
64  * Control
65  *----------------------------------------------------------------------------*/
66 /**
67  * Reset peripheral registers before configuration and starting control
68  *
69  * @param dev Beginning address of the peripheral registers.
70  */
spi_flash_ll_reset(spi_dev_t * dev)71 static inline void spi_flash_ll_reset(spi_dev_t *dev)
72 {
73     dev->user.val = 0;
74     dev->ctrl.val = 0;
75 }
76 
77 /**
78  * Check whether the previous operation is done.
79  *
80  * @param dev Beginning address of the peripheral registers.
81  *
82  * @return true if last command is done, otherwise false.
83  */
spi_flash_ll_cmd_is_done(const spi_dev_t * dev)84 static inline bool spi_flash_ll_cmd_is_done(const spi_dev_t *dev)
85 {
86     return (dev->cmd.val == 0);
87 }
88 
89 /**
90  * Erase the flash chip.
91  *
92  * @param dev Beginning address of the peripheral registers.
93  */
spi_flash_ll_erase_chip(spi_dev_t * dev)94 static inline void spi_flash_ll_erase_chip(spi_dev_t *dev)
95 {
96     dev->cmd.flash_ce = 1;
97 }
98 
99 /**
100  * Erase the sector, the address should be set by spi_flash_ll_set_address.
101  *
102  * @param dev Beginning address of the peripheral registers.
103  */
spi_flash_ll_erase_sector(spi_dev_t * dev)104 static inline void spi_flash_ll_erase_sector(spi_dev_t *dev)
105 {
106     dev->ctrl.val = 0;
107     dev->cmd.flash_se = 1;
108 }
109 
110 /**
111  * Erase the block, the address should be set by spi_flash_ll_set_address.
112  *
113  * @param dev Beginning address of the peripheral registers.
114  */
spi_flash_ll_erase_block(spi_dev_t * dev)115 static inline void spi_flash_ll_erase_block(spi_dev_t *dev)
116 {
117     dev->cmd.flash_be = 1;
118 }
119 
120 /**
121  * Enable/disable write protection for the flash chip.
122  *
123  * @param dev Beginning address of the peripheral registers.
124  * @param wp true to enable the protection, false to disable (write enable).
125  */
spi_flash_ll_set_write_protect(spi_dev_t * dev,bool wp)126 static inline void spi_flash_ll_set_write_protect(spi_dev_t *dev, bool wp)
127 {
128     if (wp) {
129         dev->cmd.flash_wrdi = 1;
130     } else {
131         dev->cmd.flash_wren = 1;
132     }
133 }
134 
135 /**
136  * Get the read data from the buffer after ``spi_flash_ll_read`` is done.
137  *
138  * @param dev Beginning address of the peripheral registers.
139  * @param buffer Buffer to hold the output data
140  * @param read_len Length to get out of the buffer
141  */
spi_flash_ll_get_buffer_data(spi_dev_t * dev,void * buffer,uint32_t read_len)142 static inline void spi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, uint32_t read_len)
143 {
144     if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) {
145         // If everything is word-aligned, do a faster memcpy
146         memcpy(buffer, (void *)dev->data_buf, read_len);
147     } else {
148         // Otherwise, slow(er) path copies word by word
149         int copy_len = read_len;
150         for (size_t i = 0; i < (read_len + 3) / 4; i++) {
151             int word_len = MIN(sizeof(uint32_t), copy_len);
152             uint32_t word = dev->data_buf[i];
153             memcpy(buffer, &word, word_len);
154             buffer = (void *)((intptr_t)buffer + word_len);
155             copy_len -= word_len;
156         }
157     }
158 }
159 
160 /**
161  * Write a word to the data buffer.
162  *
163  * @param dev Beginning address of the peripheral registers.
164  * @param word Data to write at address 0.
165  */
spi_flash_ll_write_word(spi_dev_t * dev,uint32_t word)166 static inline void spi_flash_ll_write_word(spi_dev_t *dev, uint32_t word)
167 {
168     dev->data_buf[0] = word;
169 }
170 
171 /**
172  * Set the data to be written in the data buffer.
173  *
174  * @param dev Beginning address of the peripheral registers.
175  * @param buffer Buffer holding the data
176  * @param length Length of data in bytes.
177  */
spi_flash_ll_set_buffer_data(spi_dev_t * dev,const void * buffer,uint32_t length)178 static inline void spi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *buffer, uint32_t length)
179 {
180     // Load data registers, word at a time
181     int num_words = (length + 3) >> 2;
182     for (int i = 0; i < num_words; i++) {
183         uint32_t word = 0;
184         uint32_t word_len = MIN(length, sizeof(word));
185         memcpy(&word, buffer, word_len);
186         dev->data_buf[i] = word;
187         length -= word_len;
188         buffer = (void *)((intptr_t)buffer + word_len);
189     }
190 }
191 
192 /**
193  * Program a page of the flash chip. Call ``spi_flash_ll_set_address`` before
194  * this to set the address to program.
195  *
196  * @param dev Beginning address of the peripheral registers.
197  * @param buffer Buffer holding the data to program
198  * @param length Length to program.
199  */
spi_flash_ll_program_page(spi_dev_t * dev,const void * buffer,uint32_t length)200 static inline void spi_flash_ll_program_page(spi_dev_t *dev, const void *buffer, uint32_t length)
201 {
202     dev->user.usr_dummy = 0;
203     spi_flash_ll_set_buffer_data(dev, buffer, length);
204     dev->cmd.flash_pp = 1;
205 }
206 
207 /**
208  * Trigger a user defined transaction. All phases, including command, address, dummy, and the data phases,
209  * should be configured before this is called.
210  *
211  * @param dev Beginning address of the peripheral registers.
212  */
spi_flash_ll_user_start(spi_dev_t * dev)213 static inline void spi_flash_ll_user_start(spi_dev_t *dev)
214 {
215     dev->cmd.usr = 1;
216 }
217 
218 /**
219  * Check whether the host is idle to perform new commands.
220  *
221  * @param dev Beginning address of the peripheral registers.
222  *
223  * @return true if the host is idle, otherwise false
224  */
spi_flash_ll_host_idle(const spi_dev_t * dev)225 static inline bool spi_flash_ll_host_idle(const spi_dev_t *dev)
226 {
227     return dev->ext2.st == 0;
228 }
229 
230 /*------------------------------------------------------------------------------
231  * Configs
232  *----------------------------------------------------------------------------*/
233 /**
234  * Select which pin to use for the flash
235  *
236  * @param dev Beginning address of the peripheral registers.
237  * @param pin Pin ID to use, 0-2. Set to other values to disable all the CS pins.
238  */
spi_flash_ll_set_cs_pin(spi_dev_t * dev,int pin)239 static inline void spi_flash_ll_set_cs_pin(spi_dev_t *dev, int pin)
240 {
241     dev->pin.cs0_dis = (pin != 0);
242     dev->pin.cs1_dis = (pin != 1);
243     dev->pin.cs2_dis = (pin != 2);
244 }
245 
246 /**
247  * Set the read io mode.
248  *
249  * @param dev Beginning address of the peripheral registers.
250  * @param read_mode I/O mode to use in the following transactions.
251  */
spi_flash_ll_set_read_mode(spi_dev_t * dev,esp_flash_io_mode_t read_mode)252 static inline void spi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mode_t read_mode)
253 {
254     typeof (dev->ctrl) ctrl = dev->ctrl;
255     ctrl.val &= ~(SPI_FREAD_QIO_M | SPI_FREAD_QUAD_M | SPI_FREAD_DIO_M | SPI_FREAD_DUAL_M);
256     ctrl.val |= SPI_FASTRD_MODE_M;
257     switch (read_mode) {
258     case SPI_FLASH_FASTRD:
259         //the default option
260         break;
261     case SPI_FLASH_QIO:
262         ctrl.fread_qio = 1;
263         break;
264     case SPI_FLASH_QOUT:
265         ctrl.fread_quad = 1;
266         break;
267     case SPI_FLASH_DIO:
268         ctrl.fread_dio = 1;
269         break;
270     case SPI_FLASH_DOUT:
271         ctrl.fread_dual = 1;
272         break;
273     case SPI_FLASH_SLOWRD:
274         ctrl.fastrd_mode = 0;
275         break;
276     default:
277         abort();
278     }
279     dev->ctrl = ctrl;
280 }
281 
282 /**
283  * Set clock frequency to work at.
284  *
285  * @param dev Beginning address of the peripheral registers.
286  * @param clock_val pointer to the clock value to set
287  */
spi_flash_ll_set_clock(spi_dev_t * dev,spi_flash_ll_clock_reg_t * clock_val)288 static inline void spi_flash_ll_set_clock(spi_dev_t *dev, spi_flash_ll_clock_reg_t *clock_val)
289 {
290     dev->clock = *clock_val;
291 }
292 
293 /**
294  * Set the input length, in bits.
295  *
296  * @param dev Beginning address of the peripheral registers.
297  * @param bitlen Length of input, in bits.
298  */
spi_flash_ll_set_miso_bitlen(spi_dev_t * dev,uint32_t bitlen)299 static inline void spi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitlen)
300 {
301     dev->user.usr_miso = bitlen > 0;
302     dev->miso_dlen.usr_miso_dbitlen = bitlen ? (bitlen - 1) : 0;
303 }
304 
305 /**
306  * Set the output length, in bits (not including command, address and dummy
307  * phases)
308  *
309  * @param dev Beginning address of the peripheral registers.
310  * @param bitlen Length of output, in bits.
311  */
spi_flash_ll_set_mosi_bitlen(spi_dev_t * dev,uint32_t bitlen)312 static inline void spi_flash_ll_set_mosi_bitlen(spi_dev_t *dev, uint32_t bitlen)
313 {
314     dev->user.usr_mosi = bitlen > 0;
315     dev->mosi_dlen.usr_mosi_dbitlen = bitlen ? (bitlen - 1) : 0;
316 }
317 
318 /**
319  * Set the command.
320  *
321  * @param dev Beginning address of the peripheral registers.
322  * @param command Command to send
323  * @param bitlen Length of the command
324  */
spi_flash_ll_set_command(spi_dev_t * dev,uint8_t command,uint32_t bitlen)325 static inline void spi_flash_ll_set_command(spi_dev_t *dev, uint8_t command, uint32_t bitlen)
326 {
327     dev->user.usr_command = 1;
328     typeof(dev->user2) user2 = {
329         .usr_command_value = command,
330         .usr_command_bitlen = (bitlen - 1),
331     };
332     dev->user2 = user2;
333 }
334 
335 /**
336  * Get the address length that is set in register, in bits.
337  *
338  * @param dev Beginning address of the peripheral registers.
339  *
340  */
spi_flash_ll_get_addr_bitlen(spi_dev_t * dev)341 static inline int spi_flash_ll_get_addr_bitlen(spi_dev_t *dev)
342 {
343     return dev->user.usr_addr ? dev->user1.usr_addr_bitlen + 1 : 0;
344 }
345 
346 /**
347  * Set the address length to send, in bits. Should be called before commands that requires the address e.g. erase sector, read, write...
348  *
349  * @param dev Beginning address of the peripheral registers.
350  * @param bitlen Length of the address, in bits
351  */
spi_flash_ll_set_addr_bitlen(spi_dev_t * dev,uint32_t bitlen)352 static inline void spi_flash_ll_set_addr_bitlen(spi_dev_t *dev, uint32_t bitlen)
353 {
354     dev->user1.usr_addr_bitlen = (bitlen - 1);
355     dev->user.usr_addr = bitlen ? 1 : 0;
356 }
357 
358 /**
359  * Set the address to send in user command mode. Should be called before commands that requires the address e.g. erase sector, read, write...
360  *
361  * @param dev Beginning address of the peripheral registers.
362  * @param addr Address to send
363  */
spi_flash_ll_set_usr_address(spi_dev_t * dev,uint32_t addr,int bit_len)364 static inline void spi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, int bit_len)
365 {
366     // The blank region should be all ones
367     if (bit_len >= 32) {
368         dev->addr = addr;
369         dev->slv_wr_status = UINT32_MAX;
370     } else {
371         uint32_t padding_ones = (bit_len == 32? 0 : UINT32_MAX >> bit_len);
372         dev->addr = (addr << (32 - bit_len)) | padding_ones;
373     }
374 }
375 
376 /**
377  * Set the address to send. Should be called before commands that requires the address e.g. erase sector, read, write...
378  *
379  * @param dev Beginning address of the peripheral registers.
380  * @param addr Address to send
381  */
spi_flash_ll_set_address(spi_dev_t * dev,uint32_t addr)382 static inline void spi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr)
383 {
384     dev->addr = addr;
385 }
386 
387 /**
388  * Set the length of dummy cycles.
389  *
390  * @param dev Beginning address of the peripheral registers.
391  * @param dummy_n Cycles of dummy phases
392  */
spi_flash_ll_set_dummy(spi_dev_t * dev,uint32_t dummy_n)393 static inline void spi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n)
394 {
395     dev->user.usr_dummy = dummy_n ? 1 : 0;
396     dev->user1.usr_dummy_cyclelen = dummy_n - 1;
397 }
398 
spi_flash_ll_set_hold(spi_dev_t * dev,uint32_t hold_n)399 static inline void spi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
400 {
401     dev->ctrl2.hold_time = hold_n;
402     dev->user.cs_hold = (hold_n > 0? 1: 0);
403 }
404 
spi_flash_ll_set_cs_setup(spi_dev_t * dev,uint32_t cs_setup_time)405 static inline void spi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
406 {
407     dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
408     dev->ctrl2.setup_time = cs_setup_time - 1;
409 }
410 
411 #ifdef __cplusplus
412 }
413 #endif
414