1 /**************************************************************************//**
2  * @file    spim.h
3  * @version V1.00
4  * @brief   M480 series SPIM driver header file
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  * @copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #ifndef __SPIM_H__
10 #define __SPIM_H__
11 
12 /*---------------------------------------------------------------------------------------------------------*/
13 /* Include related headers                                                                                 */
14 /*---------------------------------------------------------------------------------------------------------*/
15 
16 #ifdef __cplusplus
17 extern "C"
18 {
19 #endif
20 
21 
22 /** @addtogroup Standard_Driver Standard Driver
23   @{
24 */
25 
26 /** @addtogroup SPIM_Driver SPIM Driver
27   @{
28 */
29 
30 
31 /** @addtogroup SPIM_EXPORTED_CONSTANTS SPIM Exported Constants
32   @{
33 */
34 
35 #define SPIM_DMM_MAP_ADDR      0x100000UL        /*!< DMM mode memory map base address    \hideinitializer */
36 #define SPIM_DMM_SIZE          0x100000UL        /*!< DMM mode memory mapping size        \hideinitializer */
37 #define SPIM_CCM_ADDR          0x20020000UL      /*!< CCM mode memory map base address    \hideinitializer */
38 #define SPIM_CCM_SIZE          0x8000UL          /*!< CCM mode memory size                \hideinitializer */
39 
40 /*---------------------------------------------------------------------------------------------------------*/
41 /* SPIM_CTL0 constant definitions                                                                          */
42 /*---------------------------------------------------------------------------------------------------------*/
43 #define SPIM_CTL0_RW_IN(x)              ((x) ? 0UL : (0x1UL << SPIM_CTL0_QDIODIR_Pos))      /*!< SPIM_CTL0: SPI Interface Direction Select \hideinitializer */
44 #define SPIM_CTL0_BITMODE_SING          (0UL << SPIM_CTL0_BITMODE_Pos)          /*!< SPIM_CTL0: One bit mode (SPI Interface including DO, DI, HOLD, WP) \hideinitializer */
45 #define SPIM_CTL0_BITMODE_DUAL          (1UL << SPIM_CTL0_BITMODE_Pos)          /*!< SPIM_CTL0: Two bits mode (SPI Interface including D0, D1, HOLD, WP) \hideinitializer */
46 #define SPIM_CTL0_BITMODE_QUAD          (2UL << SPIM_CTL0_BITMODE_Pos)          /*!< SPIM_CTL0: Four bits mode (SPI Interface including D0, D1, D2, D3) \hideinitializer */
47 #define SPIM_CTL0_OPMODE_IO             (0UL << SPIM_CTL0_OPMODE_Pos)           /*!< SPIM_CTL0: I/O Mode \hideinitializer */
48 #define SPIM_CTL0_OPMODE_PAGEWRITE      (1UL << SPIM_CTL0_OPMODE_Pos)           /*!< SPIM_CTL0: Page Write Mode \hideinitializer */
49 #define SPIM_CTL0_OPMODE_PAGEREAD       (2UL << SPIM_CTL0_OPMODE_Pos)           /*!< SPIM_CTL0: Page Read Mode \hideinitializer */
50 #define SPIM_CTL0_OPMODE_DIRECTMAP      (3UL << SPIM_CTL0_OPMODE_Pos)           /*!< SPIM_CTL0: Direct Map Mode \hideinitializer */
51 
52 #define CMD_NORMAL_PAGE_PROGRAM         (0x02UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Page Program (Page Write Mode Use) \hideinitializer */
53 #define CMD_NORMAL_PAGE_PROGRAM_4B      (0x12UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Page Program (Page Write Mode Use) \hideinitializer */
54 #define CMD_QUAD_PAGE_PROGRAM_WINBOND   (0x32UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Quad Page program (for Winbond) (Page Write Mode Use) \hideinitializer */
55 #define CMD_QUAD_PAGE_PROGRAM_MXIC      (0x38UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Quad Page program (for MXIC) (Page Write Mode Use) \hideinitializer */
56 #define CMD_QUAD_PAGE_PROGRAM_EON       (0x40UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Quad Page Program (for EON) (Page Write Mode Use) \hideinitializer */
57 
58 #define CMD_DMA_NORMAL_READ             (0x03UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Read Data (Page Read Mode Use) \hideinitializer */
59 #define CMD_DMA_FAST_READ               (0x0BUL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read (Page Read Mode Use) \hideinitializer */
60 #define CMD_DMA_NORMAL_DUAL_READ        (0x3BUL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read Dual Output (Page Read Mode Use) \hideinitializer */
61 #define CMD_DMA_FAST_READ_DUAL_OUTPUT   (0x3BUL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read Dual Output (Page Read Mode Use) \hideinitializer */
62 #define CMD_DMA_FAST_READ_QUAD_OUTPUT   (0x6BUL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read Dual Output (Page Read Mode Use) \hideinitializer */
63 #define CMD_DMA_FAST_DUAL_READ          (0xBBUL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read Dual Output (Page Read Mode Use) \hideinitializer */
64 #define CMD_DMA_NORMAL_QUAD_READ        (0xE7UL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read Quad I/O (Page Read Mode Use) \hideinitializer */
65 #define CMD_DMA_FAST_QUAD_READ          (0xEBUL << SPIM_CTL0_CMDCODE_Pos)       /*!< SPIM_CTL0: Fast Read Quad I/O (Page Read Mode Use) \hideinitializer */
66 
67 /** @cond HIDDEN_SYMBOLS */
68 
69 typedef enum
70 {
71     MFGID_UNKNOW    = 0x00U,
72     MFGID_SPANSION  = 0x01U,
73     MFGID_EON       = 0x1CU,
74     MFGID_ISSI      = 0x7FU,
75     MFGID_MXIC      = 0xC2U,
76     MFGID_WINBOND   = 0xEFU
77 }
78 E_MFGID;
79 
80 /* Flash opcodes. */
81 #define OPCODE_WREN             0x06U   /* Write enable */
82 #define OPCODE_RDSR             0x05U   /* Read status register #1*/
83 #define OPCODE_WRSR             0x01U   /* Write status register #1 */
84 #define OPCODE_RDSR2            0x35U   /* Read status register #2*/
85 #define OPCODE_WRSR2            0x31U   /* Write status register #2 */
86 #define OPCODE_RDSR3            0x15U   /* Read status register #3*/
87 #define OPCODE_WRSR3            0x11U   /* Write status register #3 */
88 #define OPCODE_PP               0x02U   /* Page program (up to 256 bytes) */
89 #define OPCODE_SE_4K            0x20U   /* Erase 4KB sector */
90 #define OPCODE_BE_32K           0x52U   /* Erase 32KB block */
91 #define OPCODE_CHIP_ERASE       0xc7U   /* Erase whole flash chip */
92 #define OPCODE_BE_64K           0xd8U   /* Erase 64KB block */
93 #define OPCODE_READ_ID          0x90U   /* Read ID */
94 #define OPCODE_RDID             0x9fU   /* Read JEDEC ID */
95 #define OPCODE_BRRD             0x16U   /* SPANSION flash - Bank Register Read command  */
96 #define OPCODE_BRWR             0x17U   /* SPANSION flash - Bank Register write command */
97 #define OPCODE_NORM_READ        0x03U   /* Read data bytes */
98 #define OPCODE_FAST_READ        0x0bU   /* Read data bytes */
99 #define OPCODE_FAST_DUAL_READ   0x3bU   /* Read data bytes */
100 #define OPCODE_FAST_QUAD_READ   0x6bU   /* Read data bytes */
101 
102 /* Used for SST flashes only. */
103 #define OPCODE_BP               0x02U   /* Byte program */
104 #define OPCODE_WRDI             0x04U   /* Write disable */
105 #define OPCODE_AAI_WP           0xadU   /* Auto u32Address increment word program */
106 
107 /* Used for Macronix flashes only. */
108 #define OPCODE_EN4B             0xb7U   /* Enter 4-byte mode */
109 #define OPCODE_EX4B             0xe9U   /* Exit 4-byte mode */
110 
111 #define OPCODE_RDSCUR           0x2bU
112 #define OPCODE_WRSCUR           0x2fU
113 
114 #define OPCODE_RSTEN            0x66U
115 #define OPCODE_RST              0x99U
116 
117 #define OPCODE_ENQPI            0x38U
118 #define OPCODE_EXQPI            0xFFU
119 
120 /* Status Register bits. */
121 #define SR_WIP                  0x1U    /* Write in progress */
122 #define SR_WEL                  0x2U    /* Write enable latch */
123 #define SR_QE                   0x40U   /* Quad Enable for MXIC */
124 /* Status Register #2 bits. */
125 #define SR2_QE                  0x2U    /* Quad Enable for Winbond */
126 /* meaning of other SR_* bits may differ between vendors */
127 #define SR_BP0                  0x4U    /* Block protect 0 */
128 #define SR_BP1                  0x8U    /* Block protect 1 */
129 #define SR_BP2                  0x10U   /* Block protect 2 */
130 #define SR_SRWD                 0x80U   /* SR write protect */
131 #define SR3_ADR                 0x01U   /* 4-byte u32Address mode */
132 
133 #define SCUR_4BYTE              0x04U   /* 4-byte u32Address mode */
134 
135 /** @endcond HIDDEN_SYMBOLS */
136 
137 /* SPIM Define Error Code */
138 #define SPIM_TIMEOUT            SystemCoreClock     /*!< SPIM time-out counter (1 second time-out) */
139 #define SPIM_OK                 ( 0L)               /*!< SPIM operation OK */
140 #define SPIM_ERR_FAIL           (-1L)               /*!< SPIM operation failed */
141 #define SPIM_ERR_TIMEOUT        (-2L)               /*!< SPIM operation abort due to timeout error */
142 
143 
144 /*@}*/ /* end of group SPIM_EXPORTED_CONSTANTS */
145 
146 /** @addtogroup SPIM_EXPORTED_FUNCTIONS SPIM Exported Functions
147   @{
148 */
149 
150 
151 /*---------------------------------------------------------------------------------------------------------*/
152 /*  Define Macros and functions                                                                            */
153 /*---------------------------------------------------------------------------------------------------------*/
154 
155 /**
156  * @details    Enable cipher.
157  * \hideinitializer
158  */
159 #define SPIM_ENABLE_CIPHER()       (SPIM->CTL0 &= ~SPIM_CTL0_CIPHOFF_Msk)
160 
161 /**
162  * @details    Disable cipher.
163  * \hideinitializer
164  */
165 #define SPIM_DISABLE_CIPHER()      (SPIM->CTL0 |= SPIM_CTL0_CIPHOFF_Msk)
166 
167 /**
168  * @details    Enable cipher balance
169  * \hideinitializer
170  */
171 #define SPIM_ENABLE_BALEN()        (SPIM->CTL0 |= SPIM_CTL0_BALEN_Msk)
172 
173 /**
174  * @details    Disable cipher balance
175  * \hideinitializer
176  */
177 #define SPIM_DISABLE_BALEN()       (SPIM->CTL0 &= ~SPIM_CTL0_BALEN_Msk)
178 
179 /**
180  * @details    Set 4-byte address to be enabled/disabled.
181  * \hideinitializer
182  */
183 #define SPIM_SET_4BYTE_ADDR_EN(x) \
184     do {    \
185         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_B4ADDREN_Msk)) | (((x) ? 1UL : 0UL) << SPIM_CTL0_B4ADDREN_Pos); \
186     } while (0)
187 
188 /**
189  * @details    Enable SPIM interrupt
190  * \hideinitializer
191  */
192 #define SPIM_ENABLE_INT()       (SPIM->CTL0 |= SPIM_CTL0_IEN_Msk)
193 
194 /**
195  * @details    Disable SPIM interrupt
196  * \hideinitializer
197  */
198 #define SPIM_DISABLE_INT()      (SPIM->CTL0 &= ~SPIM_CTL0_IEN_Msk)
199 
200 /**
201  * @details    Is interrupt flag on.
202  * \hideinitializer
203  */
204 #define SPIM_IS_IF_ON()    ((SPIM->CTL0 & SPIM_CTL0_IF_Msk) != 0UL)
205 
206 /**
207  * @details    Clear interrupt flag.
208  * \hideinitializer
209  */
210 #define SPIM_CLR_INT() \
211     do {    \
212         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_IF_Msk)) | (1UL << SPIM_CTL0_IF_Pos);  \
213     } while (0)
214 
215 /**
216  * @details    Set transmit/receive bit length
217  * \hideinitializer
218  */
219 #define SPIM_SET_DATA_WIDTH(x)   \
220     do {    \
221         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_DWIDTH_Msk)) | (((x) - 1U) << SPIM_CTL0_DWIDTH_Pos);  \
222     } while (0)
223 
224 /**
225  * @details    Get data transmit/receive bit length setting
226  * \hideinitializer
227  */
228 #define SPIM_GET_DATA_WIDTH()   \
229     (((SPIM->CTL0 & SPIM_CTL0_DWIDTH_Msk) >> SPIM_CTL0_DWIDTH_Pos)+1U)
230 
231 /**
232  * @details    Set data transmit/receive burst number
233  * \hideinitializer
234  */
235 #define SPIM_SET_DATA_NUM(x) \
236     do {    \
237         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_BURSTNUM_Msk)) | (((x) - 1U) << SPIM_CTL0_BURSTNUM_Pos);  \
238     } while (0)
239 
240 /**
241  * @details    Get data transmit/receive burst number
242  * \hideinitializer
243  */
244 #define SPIM_GET_DATA_NUM() \
245     (((SPIM->CTL0 & SPIM_CTL0_BURSTNUM_Msk) >> SPIM_CTL0_BURSTNUM_Pos)+1U)
246 
247 /**
248  * @details    Enable Single Input mode.
249  * \hideinitializer
250  */
251 #define SPIM_ENABLE_SING_INPUT_MODE()  \
252     do {    \
253         SPIM->CTL0 = (SPIM->CTL0 & (~(SPIM_CTL0_BITMODE_Msk | SPIM_CTL0_QDIODIR_Msk))) | (SPIM_CTL0_BITMODE_SING | SPIM_CTL0_RW_IN(1));    \
254     } while (0)
255 
256 /**
257  * @details    Enable Single Output mode.
258  * \hideinitializer
259  */
260 #define SPIM_ENABLE_SING_OUTPUT_MODE() \
261     do {    \
262         SPIM->CTL0 = (SPIM->CTL0 & (~(SPIM_CTL0_BITMODE_Msk | SPIM_CTL0_QDIODIR_Msk))) | (SPIM_CTL0_BITMODE_SING | SPIM_CTL0_RW_IN(0));    \
263     } while (0)
264 
265 /**
266  * @details    Enable Dual Input mode.
267  * \hideinitializer
268  */
269 #define SPIM_ENABLE_DUAL_INPUT_MODE()  \
270     do {    \
271         SPIM->CTL0 = (SPIM->CTL0 & (~(SPIM_CTL0_BITMODE_Msk | SPIM_CTL0_QDIODIR_Msk))) | (SPIM_CTL0_BITMODE_DUAL | SPIM_CTL0_RW_IN(1U));    \
272     } while (0)
273 
274 /**
275  * @details    Enable Dual Output mode.
276  * \hideinitializer
277  */
278 #define SPIM_ENABLE_DUAL_OUTPUT_MODE() \
279     do {    \
280         SPIM->CTL0 = (SPIM->CTL0 & (~(SPIM_CTL0_BITMODE_Msk | SPIM_CTL0_QDIODIR_Msk))) | (SPIM_CTL0_BITMODE_DUAL | SPIM_CTL0_RW_IN(0U));    \
281     } while (0)
282 
283 /**
284  * @details    Enable Quad Input mode.
285  * \hideinitializer
286  */
287 #define SPIM_ENABLE_QUAD_INPUT_MODE()  \
288     do {    \
289         SPIM->CTL0 = (SPIM->CTL0 & (~(SPIM_CTL0_BITMODE_Msk | SPIM_CTL0_QDIODIR_Msk))) | (SPIM_CTL0_BITMODE_QUAD | SPIM_CTL0_RW_IN(1U));    \
290     } while (0)
291 
292 /**
293  * @details    Enable Quad Output mode.
294  * \hideinitializer
295  */
296 #define SPIM_ENABLE_QUAD_OUTPUT_MODE() \
297     do {    \
298         SPIM->CTL0 = (SPIM->CTL0 & (~(SPIM_CTL0_BITMODE_Msk | SPIM_CTL0_QDIODIR_Msk))) | (SPIM_CTL0_BITMODE_QUAD | SPIM_CTL0_RW_IN(0U));    \
299     } while (0)
300 
301 /**
302  * @details    Set suspend interval which ranges between 0 and 15.
303  * \hideinitializer
304  */
305 #define SPIM_SET_SUSP_INTVL(x) \
306     do {    \
307         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_SUSPITV_Msk)) | ((x) << SPIM_CTL0_SUSPITV_Pos);    \
308     } while (0)
309 
310 /**
311  * @details    Get suspend interval setting
312  * \hideinitializer
313  */
314 #define SPIM_GET_SUSP_INTVL() \
315     ((SPIM->CTL0 & SPIM_CTL0_SUSPITV_Msk) >> SPIM_CTL0_SUSPITV_Pos)
316 
317 /**
318  * @details    Set operation mode.
319  * \hideinitializer
320  */
321 #define SPIM_SET_OPMODE(x)  \
322     do {    \
323         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_OPMODE_Msk)) | (x); \
324     } while (0)
325 
326 /**
327  * @details    Get operation mode.
328  * \hideinitializer
329  */
330 #define SPIM_GET_OP_MODE()         (SPIM->CTL0 & SPIM_CTL0_OPMODE_Msk)
331 
332 /**
333  * @details    Set SPIM mode.
334  * \hideinitializer
335  */
336 #define SPIM_SET_SPIM_MODE(x)    \
337     do {    \
338         SPIM->CTL0 = (SPIM->CTL0 & (~SPIM_CTL0_CMDCODE_Msk)) | (x);   \
339     } while (0)
340 
341 /**
342  * @details    Get SPIM mode.
343  * \hideinitializer
344  */
345 #define SPIM_GET_SPIM_MODE()       (SPIM->CTL0 & SPIM_CTL0_CMDCODE_Msk)
346 
347 /**
348  * @details    Start operation.
349  * \hideinitializer
350  */
351 #define SPIM_SET_GO()              (SPIM->CTL1 |= SPIM_CTL1_SPIMEN_Msk)
352 
353 /**
354  * @details    Is engine busy.
355  * \hideinitializer
356  */
357 #define SPIM_IS_BUSY()             (SPIM->CTL1 & SPIM_CTL1_SPIMEN_Msk)
358 
359 /**
360  * @details    Wait for free.
361  * \hideinitializer
362  */
363 #define SPIM_WAIT_FREE()            while (SPIM->CTL1 & SPIM_CTL1_SPIMEN_Msk)
364 
365 /**
366  * @details    Enable cache.
367  * \hideinitializer
368  */
369 #define SPIM_ENABLE_CACHE()        (SPIM->CTL1 &= ~SPIM_CTL1_CACHEOFF_Msk)
370 
371 /**
372  * @details    Disable cache.
373  * \hideinitializer
374  */
375 #define SPIM_DISABLE_CACHE()       (SPIM->CTL1 |= SPIM_CTL1_CACHEOFF_Msk)
376 
377 /**
378  * @details    Is cache enabled.
379  * \hideinitializer
380  */
381 #define SPIM_IS_CACHE_EN()         ((SPIM->CTL1 & SPIM_CTL1_CACHEOFF_Msk) ? 0 : 1)
382 
383 /**
384  * @details    Enable CCM
385  * \hideinitializer
386  */
387 #define SPIM_ENABLE_CCM()          (SPIM->CTL1 |= SPIM_CTL1_CCMEN_Msk)
388 
389 /**
390  * @details    Disable CCM.
391  * \hideinitializer
392  */
393 #define SPIM_DISABLE_CCM()         (SPIM->CTL1 &= ~SPIM_CTL1_CCMEN_Msk)
394 
395 /**
396  * @details    Is CCM enabled.
397  * \hideinitializer
398  */
399 #define SPIM_IS_CCM_EN()           ((SPIM->CTL1 & SPIM_CTL1_CCMEN_Msk) >> SPIM_CTL1_CCMEN_Pos)
400 
401 /**
402  * @details    Invalidate cache.
403  * \hideinitializer
404  */
405 #define SPIM_INVALID_CACHE()       (SPIM->CTL1 |= SPIM_CTL1_CDINVAL_Msk)
406 
407 /**
408  * @details    Set SS(Select Active) to active level.
409  * \hideinitializer
410  */
411 #define SPIM_SET_SS_EN(x) \
412     do {    \
413         (SPIM->CTL1 = (SPIM->CTL1 & (~SPIM_CTL1_SS_Msk)) |  ((! (x) ? 1UL : 0UL) << SPIM_CTL1_SS_Pos)); \
414     } while (0)
415 
416 /**
417  * @details    Is SS(Select Active) in active level.
418  * \hideinitializer
419  */
420 #define SPIM_GET_SS_EN() \
421     (!(SPIM->CTL1 & SPIM_CTL1_SS_Msk))
422 
423 /**
424  * @details    Set active level of slave select to be high/low.
425  * \hideinitializer
426  */
427 #define SPIM_SET_SS_ACTLVL(x) \
428     do {    \
429         (SPIM->CTL1 = (SPIM->CTL1 & (~SPIM_CTL1_SSACTPOL_Msk)) | ((!! (x) ? 1UL : 0UL) << SPIM_CTL1_SSACTPOL_Pos));   \
430     } while (0)
431 
432 /**
433  * @details    Set idle time interval
434  * \hideinitializer
435  */
436 #define SPIM_SET_IDL_INTVL(x) \
437     do {    \
438        SPIM->CTL1 = (SPIM->CTL1 & (~SPIM_CTL1_IDLETIME_Msk)) | ((x) << SPIM_CTL1_IDLETIME_Pos);  \
439     } while (0)
440 
441 /**
442  * @details    Get idle time interval setting
443  * \hideinitializer
444  */
445 #define SPIM_GET_IDL_INTVL() \
446     ((SPIM->CTL1 & SPIM_CTL1_IDLETIME_Msk) >> SPIM_CTL1_IDLETIME_Pos)
447 
448 /**
449  * @details    Set SPIM clock divider
450  * \hideinitializer
451  */
452 #define SPIM_SET_CLOCK_DIVIDER(x)    \
453     do {    \
454        SPIM->CTL1 = (SPIM->CTL1 & (~SPIM_CTL1_DIVIDER_Msk)) | ((x) << SPIM_CTL1_DIVIDER_Pos);    \
455     } while (0)
456 
457 /**
458  * @details    Get SPIM current clock divider setting
459  * \hideinitializer
460  */
461 #define SPIM_GET_CLOCK_DIVIDER()   \
462     ((SPIM->CTL1 & SPIM_CTL1_DIVIDER_Msk) >> SPIM_CTL1_DIVIDER_Pos)
463 
464 /**
465  * @details    Set SPI flash deselect time interval of DMA write mode
466  * \hideinitializer
467  */
468 #define SPIM_SET_RXCLKDLY_DWDELSEL(x) \
469     do {    \
470         (SPIM->RXCLKDLY = (SPIM->RXCLKDLY & (~SPIM_RXCLKDLY_DWDELSEL_Msk)) |  ((x) << SPIM_RXCLKDLY_DWDELSEL_Pos)); \
471     } while (0)
472 
473 /**
474  * @details    Get SPI flash deselect time interval of DMA write mode
475  * \hideinitializer
476  */
477 #define SPIM_GET_RXCLKDLY_DWDELSEL() \
478     ((SPIM->RXCLKDLY & SPIM_RXCLKDLY_DWDELSEL_Msk) >> SPIM_RXCLKDLY_DWDELSEL_Pos)
479 
480 /**
481  * @details    Set sampling clock delay selection for received data
482  * \hideinitializer
483  */
484 #define SPIM_SET_RXCLKDLY_RDDLYSEL(x) \
485     do {    \
486         (SPIM->RXCLKDLY = (SPIM->RXCLKDLY & (~SPIM_RXCLKDLY_RDDLYSEL_Msk)) |  ((x) << SPIM_RXCLKDLY_RDDLYSEL_Pos)); \
487     } while (0)
488 
489 /**
490  * @details    Get sampling clock delay selection for received data
491  * \hideinitializer
492  */
493 #define SPIM_GET_RXCLKDLY_RDDLYSEL() \
494     ((SPIM->RXCLKDLY & SPIM_RXCLKDLY_RDDLYSEL_Msk) >> SPIM_RXCLKDLY_RDDLYSEL_Pos)
495 
496 /**
497  * @details    Set sampling clock edge selection for received data
498  * \hideinitializer
499  */
500 #define SPIM_SET_RXCLKDLY_RDEDGE() \
501     (SPIM->RXCLKDLY |= SPIM_RXCLKDLY_RDEDGE_Msk); \
502 
503 /**
504  * @details    Get sampling clock edge selection for received data
505  * \hideinitializer
506  */
507 #define SPIM_CLR_RXCLKDLY_RDEDGE() \
508     (SPIM->RXCLKDLY &= ~SPIM_RXCLKDLY_RDEDGE_Msk)
509 
510 /**
511  * @details    Set mode bits data for continuous read mode
512  * \hideinitializer
513  */
514 #define SPIM_SET_DMMCTL_CRMDAT(x) \
515     do {    \
516         (SPIM->DMMCTL = (SPIM->DMMCTL & (~SPIM_DMMCTL_CRMDAT_Msk)) |  ((x) << SPIM_DMMCTL_CRMDAT_Pos)) | SPIM_DMMCTL_CREN_Msk; \
517     } while (0)
518 
519 /**
520  * @details    Get mode bits data for continuous read mode
521  * \hideinitializer
522  */
523 #define SPIM_GET_DMMCTL_CRMDAT() \
524     ((SPIM->DMMCTL & SPIM_DMMCTL_CRMDAT_Msk) >> SPIM_DMMCTL_CRMDAT_Pos)
525 
526 /**
527  * @details    Set DMM mode SPI flash deselect time
528  * \hideinitializer
529  */
530 #define SPIM_DMM_SET_DESELTIM(x) \
531     do {    \
532         SPIM->DMMCTL = (SPIM->DMMCTL & ~SPIM_DMMCTL_DESELTIM_Msk) | (((x) & 0x1FUL) << SPIM_DMMCTL_DESELTIM_Pos);   \
533     } while (0)
534 
535 /**
536  * @details    Get current DMM mode SPI flash deselect time setting
537  * \hideinitializer
538  */
539 #define SPIM_DMM_GET_DESELTIM() \
540         ((SPIM->DMMCTL & SPIM_DMMCTL_DESELTIM_Msk) >> SPIM_DMMCTL_DESELTIM_Pos)
541 
542 /**
543  * @details    Enable DMM mode burst wrap mode
544  * \hideinitializer
545  */
546 #define SPIM_DMM_ENABLE_BWEN()         (SPIM->DMMCTL |= SPIM_DMMCTL_BWEN_Msk)
547 
548 /**
549  * @details    Disable DMM mode burst wrap mode
550  * \hideinitializer
551  */
552 #define SPIM_DMM_DISABLE_BWEN()        (SPIM->DMMCTL &= ~SPIM_DMMCTL_BWEN_Msk)
553 
554 /**
555  * @details    Enable DMM mode continuous read mode
556  * \hideinitializer
557  */
558 #define SPIM_DMM_ENABLE_CREN()         (SPIM->DMMCTL |= SPIM_DMMCTL_CREN_Msk)
559 
560 /**
561  * @details    Disable DMM mode continuous read mode
562  * \hideinitializer
563  */
564 #define SPIM_DMM_DISABLE_CREN()        (SPIM->DMMCTL &= ~SPIM_DMMCTL_CREN_Msk)
565 
566 /**
567  * @details    Set DMM mode SPI flash active SCLK time
568  * \hideinitializer
569  */
570 #define SPIM_DMM_SET_ACTSCLKT(x) \
571     do {    \
572         SPIM->DMMCTL = (SPIM->DMMCTL & ~SPIM_DMMCTL_ACTSCLKT_Msk) | (((x) & 0xFUL) << SPIM_DMMCTL_ACTSCLKT_Pos) | SPIM_DMMCTL_UACTSCLK_Msk;   \
573     } while (0)
574 
575 /**
576  * @details    Set SPI flash active SCLK time as SPIM default
577  * \hideinitializer
578  */
579 #define SPIM_DMM_SET_DEFAULT_ACTSCLK()     (SPIM->DMMCTL &= ~SPIM_DMMCTL_UACTSCLK_Msk)
580 
581 /**
582  * @details    Set dummy cycle number (Only for DMM mode and DMA mode)
583  * \hideinitializer
584  */
585 #define SPIM_SET_DCNUM(x) \
586     do {    \
587         SPIM->CTL2 = (SPIM->CTL2 & ~SPIM_CTL2_DCNUM_Msk) | (((x) & 0x1FUL) << SPIM_CTL2_DCNUM_Pos) | SPIM_CTL2_USETEN_Msk;   \
588     } while (0)
589 
590 /**
591  * @details    Set dummy cycle number (Only for DMM mode and DMA mode) as SPIM default
592  * \hideinitializer
593  */
594 #define SPIM_SET_DEFAULT_DCNUM(x)           (SPIM->CTL2 &= ~SPIM_CTL2_USETEN_Msk)
595 
596 
597 
598 /*---------------------------------------------------------------------------------------------------------*/
599 /* Define Function Prototypes                                                                              */
600 /*---------------------------------------------------------------------------------------------------------*/
601 
602 
603 int  SPIM_InitFlash(int clrWP);
604 uint32_t SPIM_GetSClkFreq(void);
605 void SPIM_ReadJedecId(uint8_t idBuf[], uint32_t u32NRx, uint32_t u32NBit);
606 int  SPIM_Enable_4Bytes_Mode(int isEn, uint32_t u32NBit);
607 int  SPIM_Is4ByteModeEnable(uint32_t u32NBit);
608 
609 void SPIM_ChipErase(uint32_t u32NBit, int isSync);
610 void SPIM_EraseBlock(uint32_t u32Addr, int is4ByteAddr, uint8_t u8ErsCmd, uint32_t u32NBit, int isSync);
611 
612 void SPIM_IO_Write(uint32_t u32Addr, int is4ByteAddr, uint32_t u32NTx, uint8_t pu8TxBuf[], uint8_t wrCmd, uint32_t u32NBitCmd, uint32_t u32NBitAddr, uint32_t u32NBitDat);
613 void SPIM_IO_Read(uint32_t u32Addr, int is4ByteAddr, uint32_t u32NRx, uint8_t pu8RxBuf[], uint8_t rdCmd, uint32_t u32NBitCmd, uint32_t u32NBitAddr, uint32_t u32NBitDat, int u32NDummy);
614 
615 void SPIM_DMA_Write(uint32_t u32Addr, int is4ByteAddr, uint32_t u32NTx, uint8_t pu8TxBuf[], uint32_t wrCmd);
616 int32_t SPIM_DMA_Read(uint32_t u32Addr, int is4ByteAddr, uint32_t u32NRx, uint8_t pu8RxBuf[], uint32_t u32RdCmd, int isSync);
617 
618 void SPIM_EnterDirectMapMode(int is4ByteAddr, uint32_t u32RdCmd, uint32_t u32IdleIntvl);
619 void SPIM_ExitDirectMapMode(void);
620 
621 void SPIM_SetQuadEnable(int isEn, uint32_t u32NBit);
622 
623 void SPIM_WinbondUnlock(uint32_t u32NBit);
624 
625 /*@}*/ /* end of group SPIM_EXPORTED_FUNCTIONS */
626 
627 /*@}*/ /* end of group SPIM_Driver */
628 
629 /*@}*/ /* end of group Standard_Driver */
630 
631 #ifdef __cplusplus
632 }
633 #endif
634 
635 #endif /* __SPIM_H__ */
636 
637 /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
638