1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #ifndef FSL_SPIFI_H_
9 #define FSL_SPIFI_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup spifi
15 * @{
16 */
17
18 /*******************************************************************************
19 * Definitions
20 ******************************************************************************/
21
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief SPIFI driver version 2.0.3. */
25 #define FSL_SPIFI_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
26 /*! @} */
27
28 /*! @brief Status structure of SPIFI.*/
29 enum
30 {
31 kStatus_SPIFI_Idle = MAKE_STATUS(kStatusGroup_SPIFI, 0), /*!< SPIFI is in idle state */
32 kStatus_SPIFI_Busy = MAKE_STATUS(kStatusGroup_SPIFI, 1), /*!< SPIFI is busy */
33 kStatus_SPIFI_Error = MAKE_STATUS(kStatusGroup_SPIFI, 2), /*!< Error occurred during SPIFI transfer */
34 };
35
36 /*! @brief SPIFI interrupt source */
37 typedef enum _spifi_interrupt_enable
38 {
39 kSPIFI_CommandFinishInterruptEnable = SPIFI_CTRL_INTEN_MASK, /*!< Interrupt while command finished */
40 } spifi_interrupt_enable_t;
41
42 /*! @brief SPIFI SPI mode select */
43 typedef enum _spifi_spi_mode
44 {
45 kSPIFI_SPISckLow = 0x0U, /*!< SCK low after last bit of command, keeps low while CS high */
46 kSPIFI_SPISckHigh = 0x1U /*!< SCK high after last bit of command and while CS high */
47 } spifi_spi_mode_t;
48
49 /*! @brief SPIFI dual mode select */
50 typedef enum _spifi_dual_mode
51 {
52 kSPIFI_QuadMode = 0x0U, /*!< SPIFI uses IO3:0 */
53 kSPIFI_DualMode = 0x1U /*!< SPIFI uses IO1:0 */
54 } spifi_dual_mode_t;
55
56 /*! @brief SPIFI data direction */
57 typedef enum _spifi_data_direction
58 {
59 kSPIFI_DataInput = 0x0U, /*!< Data input from serial flash. */
60 kSPIFI_DataOutput = 0x1U /*!< Data output to serial flash. */
61 } spifi_data_direction_t;
62
63 /*! @brief SPIFI command opcode format */
64 typedef enum _spifi_command_format
65 {
66 kSPIFI_CommandAllSerial = 0x0, /*!< All fields of command are serial. */
67 kSPIFI_CommandDataQuad = 0x1U, /*!< Only data field is dual/quad, others are serial. */
68 kSPIFI_CommandOpcodeSerial = 0x2U, /*!< Only opcode field is serial, others are quad/dual. */
69 kSPIFI_CommandAllQuad = 0x3U /*!< All fields of command are dual/quad mode. */
70 } spifi_command_format_t;
71
72 /*! @brief SPIFI command type */
73 typedef enum _spifi_command_type
74 {
75 kSPIFI_CommandOpcodeOnly = 0x1U, /*!< Command only have opcode, no address field */
76 kSPIFI_CommandOpcodeAddrOneByte = 0x2U, /*!< Command have opcode and also one byte address field */
77 kSPIFI_CommandOpcodeAddrTwoBytes = 0x3U, /*!< Command have opcode and also two bytes address field */
78 kSPIFI_CommandOpcodeAddrThreeBytes = 0x4U, /*!< Command have opcode and also three bytes address field. */
79 kSPIFI_CommandOpcodeAddrFourBytes = 0x5U, /*!< Command have opcode and also four bytes address field */
80 kSPIFI_CommandNoOpcodeAddrThreeBytes = 0x6U, /*!< Command have no opcode and three bytes address field */
81 kSPIFI_CommandNoOpcodeAddrFourBytes = 0x7U /*!< Command have no opcode and four bytes address field */
82 } spifi_command_type_t;
83
84 /*! @brief SPIFI status flags */
85 enum
86 {
87 kSPIFI_MemoryCommandWriteFinished = SPIFI_STAT_MCINIT_MASK, /*!< Memory command write finished */
88 kSPIFI_CommandWriteFinished = SPIFI_STAT_CMD_MASK, /*!< Command write finished */
89 kSPIFI_InterruptRequest = SPIFI_STAT_INTRQ_MASK /*!< CMD flag from 1 to 0, means command execute finished */
90 };
91
92 /*! @brief SPIFI command structure */
93 typedef struct _spifi_command
94 {
95 uint16_t dataLen; /*!< How many data bytes are needed in this command. */
96 bool isPollMode; /*!< For command need to read data from serial flash */
97 spifi_data_direction_t direction; /*!< Data direction of this command. */
98 uint8_t intermediateBytes; /*!< How many intermediate bytes needed */
99 spifi_command_format_t format; /*!< Command format */
100 spifi_command_type_t type; /*!< Command type */
101 uint8_t opcode; /*!< Command opcode value */
102 } spifi_command_t;
103
104 /*!
105 * @brief SPIFI region configuration structure.
106 */
107 typedef struct _spifi_config
108 {
109 uint16_t timeout; /*!< SPI transfer timeout, the unit is SCK cycles */
110 uint8_t csHighTime; /*!< CS high time cycles */
111 bool disablePrefetch; /*!< True means SPIFI will not attempt a speculative prefetch. */
112 bool disableCachePrefech; /*!< Disable prefetch of cache line */
113 bool isFeedbackClock; /*!< Is data sample uses feedback clock. */
114 spifi_spi_mode_t spiMode; /*!< SPIFI spi mode select */
115 bool isReadFullClockCycle; /*!< If enable read full clock cycle. */
116 spifi_dual_mode_t dualMode; /*!< SPIFI dual mode, dual or quad. */
117 } spifi_config_t;
118
119 /*! @brief Transfer structure for SPIFI */
120 typedef struct _spifi_transfer
121 {
122 uint8_t *data; /*!< Pointer to data to transmit */
123 size_t dataSize; /*!< Bytes to be transmit */
124 } spifi_transfer_t;
125
126 /*******************************************************************************
127 * API
128 ******************************************************************************/
129
130 #if defined(__cplusplus)
131 extern "C" {
132 #endif /* _cplusplus */
133
134 /*!
135 * @name Initialization and deinitialization
136 * @{
137 */
138
139 /*!
140 * @brief Get the SPIFI instance from peripheral base address.
141 *
142 * @param base SPIFI peripheral base address.
143 * @return SPIFI instance.
144 */
145 uint32_t SPIFI_GetInstance(SPIFI_Type *base);
146
147 /*!
148 * @brief Initializes the SPIFI with the user configuration structure.
149 *
150 * This function configures the SPIFI module with the user-defined configuration.
151 *
152 * @param base SPIFI peripheral base address.
153 * @param config The pointer to the configuration structure.
154 */
155 void SPIFI_Init(SPIFI_Type *base, const spifi_config_t *config);
156
157 /*!
158 * @brief Get SPIFI default configure settings.
159 *
160 * @param config SPIFI config structure pointer.
161 */
162 void SPIFI_GetDefaultConfig(spifi_config_t *config);
163
164 /*!
165 * @brief Deinitializes the SPIFI regions.
166 *
167 * @param base SPIFI peripheral base address.
168 */
169 void SPIFI_Deinit(SPIFI_Type *base);
170
171 /*! @} */
172
173 /*!
174 * @name Basic Control Operations
175 * @{
176 */
177
178 /*!
179 * @brief Set SPIFI flash command.
180 *
181 * @param base SPIFI peripheral base address.
182 * @param cmd SPIFI command structure pointer.
183 */
184 void SPIFI_SetCommand(SPIFI_Type *base, spifi_command_t *cmd);
185
186 /*!
187 * @brief Set SPIFI command address.
188 *
189 * @param base SPIFI peripheral base address.
190 * @param addr Address value for the command.
191 */
SPIFI_SetCommandAddress(SPIFI_Type * base,uint32_t addr)192 static inline void SPIFI_SetCommandAddress(SPIFI_Type *base, uint32_t addr)
193 {
194 base->ADDR = addr;
195 }
196
197 /*!
198 * @brief Set SPIFI intermediate data.
199 *
200 * Before writing a command wihch needs specific intermediate value, users shall call this function to write it.
201 * The main use of this function for current serial flash is to select no-opcode mode and cancelling this mode. As
202 * dummy cycle do not care about the value, no need to call this function.
203 *
204 * @param base SPIFI peripheral base address.
205 * @param val Intermediate data.
206 */
SPIFI_SetIntermediateData(SPIFI_Type * base,uint32_t val)207 static inline void SPIFI_SetIntermediateData(SPIFI_Type *base, uint32_t val)
208 {
209 base->IDATA = val;
210 }
211
212 /*!
213 * @brief Set SPIFI Cache limit value.
214 *
215 * SPIFI includes caching of prevously-accessed data to improve performance. Software can write an address to this
216 * function, to prevent such caching at and above the address.
217 *
218 * @param base SPIFI peripheral base address.
219 * @param val Zero-based upper limit of cacheable memory.
220 */
SPIFI_SetCacheLimit(SPIFI_Type * base,uint32_t val)221 static inline void SPIFI_SetCacheLimit(SPIFI_Type *base, uint32_t val)
222 {
223 base->CLIMIT = val;
224 }
225
226 /*!
227 * @brief Reset the command field of SPIFI.
228 *
229 * This function is used to abort the current command or memory mode.
230 *
231 * @param base SPIFI peripheral base address.
232 */
SPIFI_ResetCommand(SPIFI_Type * base)233 static inline void SPIFI_ResetCommand(SPIFI_Type *base)
234 {
235 base->STAT = SPIFI_STAT_RESET_MASK;
236 /* Wait for the RESET flag cleared by HW */
237 while ((base->STAT & SPIFI_STAT_RESET_MASK) != 0x00U)
238 {
239 }
240 }
241
242 /*!
243 * @brief Set SPIFI flash AHB read command.
244 *
245 * Call this function means SPIFI enters to memory mode, while users need to use command, a SPIFI_ResetCommand shall
246 * be called.
247 *
248 * @param base SPIFI peripheral base address.
249 * @param cmd SPIFI command structure pointer.
250 */
251 void SPIFI_SetMemoryCommand(SPIFI_Type *base, spifi_command_t *cmd);
252
253 /*!
254 * @brief Enable SPIFI interrupt.
255 *
256 * The interrupt is triggered only in command mode, and it means the command now is finished.
257 *
258 * @param base SPIFI peripheral base address.
259 * @param mask SPIFI interrupt enable mask. It is a logic OR of members the
260 * enumeration :: spifi_interrupt_enable_t
261 */
SPIFI_EnableInterrupt(SPIFI_Type * base,uint32_t mask)262 static inline void SPIFI_EnableInterrupt(SPIFI_Type *base, uint32_t mask)
263 {
264 base->CTRL |= mask;
265 }
266
267 /*!
268 * @brief Disable SPIFI interrupt.
269 *
270 * The interrupt is triggered only in command mode, and it means the command now is finished.
271 *
272 * @param base SPIFI peripheral base address.
273 * @param mask SPIFI interrupt enable mask. It is a logic OR of members the
274 * enumeration :: spifi_interrupt_enable_t
275 */
SPIFI_DisableInterrupt(SPIFI_Type * base,uint32_t mask)276 static inline void SPIFI_DisableInterrupt(SPIFI_Type *base, uint32_t mask)
277 {
278 base->CTRL &= ~mask;
279 }
280
281 /*!
282 * @name Status
283 * @{
284 */
285
286 /*!
287 * @brief Get the status of all interrupt flags for SPIFI.
288 *
289 * @param base SPIFI peripheral base address.
290 * @return SPIFI flag status
291 */
SPIFI_GetStatusFlag(SPIFI_Type * base)292 static inline uint32_t SPIFI_GetStatusFlag(SPIFI_Type *base)
293 {
294 return base->STAT;
295 }
296
297 /*! @} */
298
299 /*!
300 * @brief Enable or disable DMA request for SPIFI.
301 *
302 * @param base SPIFI peripheral base address.
303 * @param enable True means enable DMA and false means disable DMA.
304 */
SPIFI_EnableDMA(SPIFI_Type * base,bool enable)305 static inline void SPIFI_EnableDMA(SPIFI_Type *base, bool enable)
306 {
307 if (enable)
308 {
309 base->CTRL |= SPIFI_CTRL_DMAEN_MASK;
310 }
311 else
312 {
313 base->CTRL &= ~SPIFI_CTRL_DMAEN_MASK;
314 }
315 }
316
317 /*!
318 * @brief Gets the SPIFI data register address.
319 *
320 * This API is used to provide a transfer address for the SPIFI DMA transfer configuration.
321 *
322 * @param base SPIFI base pointer
323 * @return data register address
324 */
SPIFI_GetDataRegisterAddress(SPIFI_Type * base)325 static inline uint32_t SPIFI_GetDataRegisterAddress(SPIFI_Type *base)
326 {
327 return (uint32_t)(&(base->DATA));
328 }
329
330 /*!
331 * @brief Write a word data in address of SPIFI.
332 *
333 * Users can write a page or at least a word data into SPIFI address.
334 *
335 * @param base SPIFI peripheral base address.
336 * @param data Data need be write.
337 */
SPIFI_WriteData(SPIFI_Type * base,uint32_t data)338 static inline void SPIFI_WriteData(SPIFI_Type *base, uint32_t data)
339 {
340 base->DATA = data;
341 }
342
343 /*!
344 * @brief Write a byte data in address of SPIFI.
345 *
346 * Users can write a byte data into SPIFI address.
347 *
348 * @param base SPIFI peripheral base address.
349 * @param data Data need be write.
350 */
SPIFI_WriteDataByte(SPIFI_Type * base,uint8_t data)351 static inline void SPIFI_WriteDataByte(SPIFI_Type *base, uint8_t data)
352 {
353 *((volatile uint8_t *)(&(base->DATA))) = data;
354 }
355
356 /*!
357 * @brief Write a halfword data in address of SPIFI.
358 *
359 * Users can write a halfword data into SPIFI address.
360 *
361 * @param base SPIFI peripheral base address.
362 * @param data Data need be write.
363 */
364 void SPIFI_WriteDataHalfword(SPIFI_Type *base, uint16_t data);
365
366 /*!
367 * @brief Read data from serial flash.
368 *
369 * Users should notice before call this function, the data length field in command register shall larger
370 * than 4, otherwise a hardfault will happen.
371 *
372 * @param base SPIFI peripheral base address.
373 * @return Data input from flash.
374 */
SPIFI_ReadData(SPIFI_Type * base)375 static inline uint32_t SPIFI_ReadData(SPIFI_Type *base)
376 {
377 return base->DATA;
378 }
379
380 /*!
381 * @brief Read a byte data from serial flash.
382 *
383 * @param base SPIFI peripheral base address.
384 * @return Data input from flash.
385 */
SPIFI_ReadDataByte(SPIFI_Type * base)386 static inline uint8_t SPIFI_ReadDataByte(SPIFI_Type *base)
387 {
388 return *((volatile uint8_t *)(&(base->DATA)));
389 }
390
391 /*!
392 * @brief Read a halfword data from serial flash.
393 *
394 * @param base SPIFI peripheral base address.
395 * @return Data input from flash.
396 */
397 uint16_t SPIFI_ReadDataHalfword(SPIFI_Type *base);
398
399 /*! @} */
400
401 #if defined(__cplusplus)
402 }
403 #endif
404
405 /*! @}*/
406
407 #endif /* FSL_SPIFI_H_ */
408