1 /**
2 *********************************************************************************
3 *
4 * @file ald_qspi.c
5 * @brief QSPI module driver.
6 *
7 * @version V1.0
8 * @date 09 Nov 2019
9 * @author AE Team
10 * @note
11 * Change Logs:
12 * Date Author Notes
13 * 09 Nov 2019 AE Team The first version
14 *
15 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 *
19 * Licensed under the Apache License, Version 2.0 (the License); you may
20 * not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
22 *
23 * www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 **********************************************************************************
31 */
32 #include "ald_conf.h"
33
34
35 /** @addtogroup ES32FXXX_ALD
36 * @{
37 */
38
39 /** @defgroup QSPI QSPI
40 * @brief QSPI module driver
41 * @{
42 */
43
44 #ifdef ALD_QSPI
45
46 /** @defgroup QSPI_Private_Functions QSPI Private Functions
47 * @brief QSPI Private functions
48 * @{
49 */
50
51 /**
52 * @brief Wait for a flag state until timeout.
53 * @param hperh: QSPI handle
54 * @param timeout: Duration of the time out
55 * @param tickstart: tick start value
56 * @retval Status, see @ref ald_status_t.
57 */
qspi_wait_for_idle(qspi_handle_t * hperh,uint32_t tickstart,uint32_t timeout)58 static ald_status_t qspi_wait_for_idle(qspi_handle_t *hperh, uint32_t tickstart, uint32_t timeout)
59 {
60 /* Wait until flag is in expected state */
61 while (READ_BIT(hperh->perh->CR, QSPI_CR_IDLES_MSK) != QSPI_CR_IDLES_MSK) {
62 /* Check for the Timeout */
63 if (timeout != ALD_MAX_DELAY) {
64 if ((timeout == 0U) || ((ald_get_tick() - tickstart) > timeout)) {
65 return ERROR;
66 }
67 }
68 }
69 return OK;
70 }
71
72 /**
73 * @brief Get indirect read status.
74 * @param hperh: Pointer to a qspi_handle_t structure.
75 * @param status: Indirect status.
76 * @retval Status, see @ref ald_status_t.
77 */
qspi_indrd_get_status(qspi_handle_t * hperh,qspi_indrd_flag_t status)78 static flag_status_t qspi_indrd_get_status(qspi_handle_t *hperh, qspi_indrd_flag_t status)
79 {
80 assert_param(IS_QSPI_ALL(hperh->perh));
81 assert_param(IS_QSPI_INDIRECT_READ_STATUS(status));
82
83 if (hperh->perh->IRTR & status)
84 return SET;
85
86 return RESET;
87 }
88
89 /**
90 * @}
91 */
92
93 /** @defgroup QSPI_Public_Functions QSPI Public Functions
94 * @brief QSPI Public Functions
95 * @{
96 */
97 /** @defgroup QSPI_Public_Functions_Group1 Basic execution functions
98 * @brief QSPI basic execution functions
99 * @{
100 */
101 /**
102 * @brief Initializes the QSPI basic parameters.
103 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
104 * @retval None.
105 */
ald_qspi_init(qspi_handle_t * hperh)106 void ald_qspi_init(qspi_handle_t *hperh)
107 {
108 assert_param(IS_QSPI_CLOCK_PRESCALER(hperh->init.clkdiv));
109 assert_param(IS_QSPI_CLOCK_PHASE(hperh->init.chpa));
110 assert_param(IS_QSPI_CLOCK_POLARITY(hperh->init.cpol));
111
112 MODIFY_REG(hperh->perh->CR, QSPI_CR_BAUD_MSK | QSPI_CR_CPOL_MSK | QSPI_CR_CPHA_MSK | \
113 QSPI_CR_PSL_MSK | QSPI_CR_SWPP_MSK , (hperh->init.clkdiv << QSPI_CR_BAUD_POSS) | \
114 (hperh->init.cpol << QSPI_CR_CPOL_POS) | \
115 (hperh->init.chpa << QSPI_CR_CPHA_POS) | \
116 (hperh->init.chipsel << QSPI_CR_PSL_POSS) | \
117 (hperh->init.wrppin << QSPI_CR_SWPP_POS));
118 }
119
120 /**
121 * @brief DAC read.
122 * @param addr: address.
123 * @retval value
124 */
ald_qspi_dac_rd(uint32_t addr)125 uint32_t ald_qspi_dac_rd(uint32_t addr)
126 {
127 return ((*(volatile uint32_t *)(addr)));
128 }
129
130 /**
131 * @brief DAC write .
132 * @param addr: address.
133 * @param dat: data.
134 * @retval None
135 */
ald_qspi_dac_wr(uint32_t addr,uint32_t dat)136 void ald_qspi_dac_wr(uint32_t addr, uint32_t dat)
137 {
138 (*(volatile uint32_t *)(addr)) = dat;
139 }
140
141 /**
142 * @brief Configure Read Operations.
143 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
144 * @param rdcfg: Pointer to configuration structure for QSPI read operations.
145 * @retval Status, see @ref ald_status_t.
146 */
ald_qspi_read_config(qspi_handle_t * hperh,const qspi_read_cfg_t * rdcfg)147 ald_status_t ald_qspi_read_config(qspi_handle_t * hperh, const qspi_read_cfg_t * rdcfg)
148 {
149 ald_status_t status = ERROR;
150 uint32_t tickstart = ald_get_tick();
151
152 assert_param(IS_QSPI_RD_OPCODE(rdcfg->rdcde));
153 assert_param(IS_QSPI_DCYLES(rdcfg->dcyles));
154 assert_param(IS_QSPI_XFER_TYPE(rdcfg->datxfer));
155 assert_param(IS_QSPI_XFER_TYPE(rdcfg->addxfer));
156 assert_param(IS_QSPI_XFER_TYPE(rdcfg->instxfer));
157
158 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
159
160 if (status != OK)
161 return status;
162
163 MODIFY_REG(hperh->perh->DRIR, QSPI_DRIR_RINST_MSK | QSPI_DRIR_MBEN_MSK | \
164 QSPI_DRIR_DCYC_MSK | QSPI_DRIR_ADMODE_MSK | \
165 QSPI_DRIR_DMODE_MSK | QSPI_DRIR_IMODE_MSK | \
166 QSPI_DRIR_DDRM_MSK, \
167 (rdcfg->rdcde | (rdcfg->dcyles << 24) | \
168 (rdcfg->addxfer << 12) | (rdcfg->instxfer << 8) | \
169 (rdcfg->ddrbit << QSPI_DRIR_DDRM_POS) | (rdcfg->modebit << QSPI_DRIR_MBEN_POS)) | \
170 (rdcfg->datxfer << QSPI_DRIR_DMODE_POSS));
171
172 if (rdcfg->modebit)
173 MODIFY_REG(hperh->perh->MBR, QSPI_MBR_MODEB_MSK, rdcfg->mbitval);
174
175 return status;
176 }
177
178 /**
179 * @brief Configure Write Operations.
180 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
181 * @param wrcfg: Pointer to configuration structure for QSPI write operations.
182 * @retval Status, see @ref ald_status_t.
183 */
ald_qspi_write_config(qspi_handle_t * hperh,const qspi_write_cfg_t * wrcfg)184 ald_status_t ald_qspi_write_config(qspi_handle_t * hperh, const qspi_write_cfg_t * wrcfg)
185 {
186 ald_status_t status = ERROR;
187 uint32_t tickstart = ald_get_tick();
188
189 assert_param(IS_QSPI_WR_OPCODE(wrcfg->wrcde));
190 assert_param(IS_QSPI_DCYLES(wrcfg->dcyles));
191 assert_param(IS_QSPI_XFER_TYPE(wrcfg->datxfer));
192 assert_param(IS_QSPI_XFER_TYPE(wrcfg->addxfer));
193
194 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
195
196 if (status != OK)
197 return status;
198
199 MODIFY_REG(hperh->perh->DWIR, QSPI_DWIR_WINST_MSK | QSPI_DWIR_DCYC_MSK | \
200 QSPI_DWIR_ADMODE_MSK | QSPI_DWIR_DMODE_MSK,
201 wrcfg->wrcde | \
202 (wrcfg->addxfer << 12) | \
203 (wrcfg->datxfer << 16) | \
204 (wrcfg->dcyles << 24));
205 if (wrcfg->autowel)
206 CLEAR_BIT(hperh->perh->DWIR, QSPI_DWIR_WELD_MSK);
207 else
208 SET_BIT(hperh->perh->DWIR, QSPI_DWIR_WELD_MSK);
209
210 return status;
211 }
212
213 /**
214 * @brief QSPI Device Delay Configuration.
215 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
216 * @param dlycfg: Device delay configuration structure.
217 * @retval Status, see @ref ald_status_t.
218 */
ald_qspi_device_delay_config(qspi_handle_t * hperh,qspi_dly_cfg_t * dlycfg)219 ald_status_t ald_qspi_device_delay_config(qspi_handle_t * hperh, qspi_dly_cfg_t *dlycfg)
220 {
221 ald_status_t status = ERROR;
222 uint32_t tickstart = ald_get_tick();
223
224 assert_param(IS_QSPI_ALL(hperh->perh));
225 assert_param(IS_QSPI_DEVICE_DELAY_CCSOT(dlycfg->ccsot));
226 assert_param(IS_QSPI_DEVICE_DELAY_CSEOT(dlycfg->cseot));
227 assert_param(IS_QSPI_DEVICE_DELAY_CSDADS(dlycfg->csdads));
228 assert_param(IS_QSPI_DEVICE_DELAY_CSDA(dlycfg->csda));
229
230 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
231
232 if (status != OK)
233 return status;
234
235 MODIFY_REG(hperh->perh->DDLR, QSPI_DDLR_CSSOT_MSK | QSPI_DDLR_CSEOT_MSK | QSPI_DDLR_CSDADS_MSK | QSPI_DDLR_CSDA_MSK, \
236 dlycfg->ccsot | (dlycfg->cseot << 8) | (dlycfg->csdads << 16) | (dlycfg->csda << 24));
237 return status;
238 }
239
240 /**
241 * @brief QSPI Read Data Capture Configuration.
242 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
243 * @param dtcptcfg: Data capture configuration structure.
244 * @retval Status, see @ref ald_status_t.
245 */
ald_qspi_read_data_capture_config(qspi_handle_t * hperh,qspi_data_capture_cfg_t * dtcptcfg)246 ald_status_t ald_qspi_read_data_capture_config(qspi_handle_t * hperh, qspi_data_capture_cfg_t *dtcptcfg)
247 {
248 ald_status_t status = ERROR;
249 uint32_t tickstart = ald_get_tick();
250
251 assert_param(IS_QSPI_ALL(hperh->perh));
252 assert_param(IS_QSPI_READ_DATA_CAPTURE_DELAY_READ(dtcptcfg->dlydcl));
253 assert_param(IS_QSPI_READ_DATA_SAMPLE_EDGE(dtcptcfg->smpledge));
254 assert_param(IS_QSPI_READ_DATA_DELAY_TRANSMIT(dtcptcfg->dlytd));
255
256 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
257
258 if (status != OK)
259 return status;
260
261 MODIFY_REG(hperh->perh->RDCR, QSPI_RDCR_BYLPC_MSK | QSPI_RDCR_DLYR_MSK | QSPI_RDCR_SMES_MSK | QSPI_RDCR_DLYT_MSK, \
262 0x1U | (dtcptcfg->dlydcl << 1) | (dtcptcfg->smpledge << 5) | (dtcptcfg->dlytd << 16));
263 return status;
264 }
265
266 /**
267 * @brief QSPI Flash memory Configuration.
268 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
269 * @param devcfg: flash parameter configuration structure.
270 * @retval Status, see @ref ald_status_t.
271 */
ald_qspi_device_size_config(qspi_handle_t * hperh,qspi_device_size_t * devcfg)272 ald_status_t ald_qspi_device_size_config(qspi_handle_t *hperh, qspi_device_size_t * devcfg)
273 {
274 ald_status_t status = ERROR;
275 uint32_t tickstart = ald_get_tick();
276
277 assert_param(IS_QSPI_ADDR_SIZE(devcfg->addr));
278 assert_param(IS_QSPI_PAGE_SIZE(devcfg->page));
279 assert_param(IS_QSPI_BLOCK_SIZE(devcfg->blk));
280 assert_param(IS_QSPI_NSS_SIZE(devcfg->cs0));
281 assert_param(IS_QSPI_NSS_SIZE(devcfg->cs1));
282 assert_param(IS_QSPI_NSS_SIZE(devcfg->cs2));
283 assert_param(IS_QSPI_NSS_SIZE(devcfg->cs3));
284
285 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
286
287 if (status != OK)
288 return status;
289
290 MODIFY_REG(hperh->perh->DSCR, QSPI_DSCR_ADSIZE_MSK | QSPI_DSCR_PASIZE_MSK | QSPI_DSCR_BKSIZE_MSK | QSPI_DSCR_CS0SIZE_MSK | \
291 QSPI_DSCR_CS1SIZE_MSK | QSPI_DSCR_CS2SIZE_MSK | QSPI_DSCR_CS3SIZE_MSK, \
292 (devcfg->addr << QSPI_DSCR_ADSIZE_POSS) | \
293 (devcfg->page << QSPI_DSCR_PASIZE_POSS) | \
294 (devcfg->blk << QSPI_DSCR_BKSIZE_POSS) | \
295 (devcfg->cs0 << QSPI_DSCR_CS0SIZE_POSS) | \
296 (devcfg->cs1 << QSPI_DSCR_CS1SIZE_POSS) | \
297 (devcfg->cs2 << QSPI_DSCR_CS2SIZE_POSS) | \
298 (devcfg->cs3 << QSPI_DSCR_CS3SIZE_POSS));
299 return OK;
300 }
301
302 /**
303 * @brief Initializes the QSPI direct access according to the specified parameters
304 * in the associated handle.
305 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
306 * @param dcfg : structure that contains the indirect read command configuration information.
307 * @retval Status, see @ref ald_status_t.
308 */
qspi_dac_config(qspi_handle_t * hperh,qspi_dac_cfg_t * dcfg)309 ald_status_t qspi_dac_config(qspi_handle_t * hperh, qspi_dac_cfg_t * dcfg)
310 {
311 ald_status_t status = ERROR;
312 uint32_t tickstart = ald_get_tick();
313
314 assert_param(IS_QSPI_WR_OPCODE(dcfg->wrinit.wrcde));
315 assert_param(IS_QSPI_DCYLES(dcfg->wrinit.dcyles));
316 assert_param(IS_QSPI_XFER_TYPE(dcfg->wrinit.datxfer));
317 assert_param(IS_QSPI_XFER_TYPE(dcfg->wrinit.addxfer));
318 assert_param(IS_QSPI_XFER_TYPE(dcfg->wrinit.instxfer));
319
320 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
321
322 if (status != OK)
323 return status;
324
325 QSPI_DISABLE(hperh);
326 ald_qspi_init(hperh);
327
328 if (ald_qspi_write_config(hperh, &dcfg->wrinit) != OK)
329 return ERROR;
330 if (ald_qspi_read_config(hperh, &dcfg->rdinit) != OK)
331 return ERROR;
332
333 if (dcfg->addrremap)
334 MODIFY_REG(hperh->perh->RAR, QSPI_RAR_READDR_MSK, dcfg->remapaddr);
335
336 MODIFY_REG(hperh->perh->CR, QSPI_CR_DTRM_MSK | QSPI_CR_ADEN_MSK | QSPI_CR_XIPIM_MSK | \
337 QSPI_CR_XIPNX_MSK | QSPI_CR_AREN_MSK | QSPI_CR_DMAEN_MSK, \
338 dcfg->dtrprtcol << 24 | dcfg->ahbdecoder << 23);
339 QSPI_ENABLE(hperh);
340 return OK;
341 }
342
343 /**
344 * @}
345 */
346
347 /** @defgroup QSPI_Public_Functions_Group2 Indirect and stig access execution functions
348 * @brief QSPI indirect and stig access execution functions
349 * @{
350 */
351 /**
352 * @brief Initializes the QSPI indirect access according to the specified parameters
353 * in the associated handle.
354 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
355 * @param indcfg: Pointer to indirect access initialization structure qspi_indac_config_t.
356 * @retval Status, see @ref ald_status_t.
357 */
ald_qspi_indac_config(qspi_handle_t * hperh,qspi_indac_cfg_t * indcfg)358 ald_status_t ald_qspi_indac_config(qspi_handle_t * hperh, qspi_indac_cfg_t *indcfg)
359 {
360 ald_status_t status = ERROR;
361 uint32_t tickstart = ald_get_tick();
362
363 assert_param(IS_QSPI_ALL(hperh->perh));
364 assert_param(IS_QSPI_SRAM_PARTITION(indcfg->srampt));
365 assert_param(IS_QSPI_INDIRECT_TRIGGER_RANGE(indcfg->trgrng));
366 assert_param(IS_QSPI_INDIRECT_READ_WATERMARK(indcfg->rdwmark));
367
368 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
369
370 if (status != OK)
371 return status;
372
373 QSPI_DISABLE(hperh);
374
375 MODIFY_REG(hperh->perh->SPR, QSPI_SPR_SRAMPS_MSK, indcfg->srampt);
376 MODIFY_REG(hperh->perh->IATR, QSPI_IATR_INDTAD_MSK, indcfg->trgaddr);
377 MODIFY_REG(hperh->perh->ITARR, QSPI_ITARR_RNGW_MSK, indcfg->trgrng);
378 MODIFY_REG(hperh->perh->IWTWR, QSPI_IWTWR_VAULE_MSK, indcfg->wrwmark);
379 MODIFY_REG(hperh->perh->IRTWR, QSPI_IRTWR_VAULE_MSK, indcfg->rdwmark);
380
381 QSPI_ENABLE(hperh);
382
383 return OK;
384 }
385
386 /**
387 * @brief QSPI write data by interrupt.
388 * @param hperh: Pointer to a qspi_handle_t structure.
389 * @param saddr: Write start address.
390 * @param psrc: Pointer to source data buffer.
391 * @param size : Write bytes number.
392 * @retval Status, see @ref ald_status_t.
393 */
ald_qspi_indac_transmit_by_it(qspi_handle_t * hperh,uint32_t saddr,uint8_t * psrc,uint32_t size)394 ald_status_t ald_qspi_indac_transmit_by_it(qspi_handle_t *hperh, uint32_t saddr, uint8_t *psrc, uint32_t size)
395 {
396 uint32_t i = 0;
397 uint32_t tmp = 0, pgsize = 0;
398 assert_param(IS_QSPI_ALL(hperh->perh));
399
400 if ((psrc == NULL) || (size == 0))
401 return ERROR;
402
403 hperh->state = QSPI_STATE_BUSY_TX;
404 hperh->rx_buf = NULL;
405 hperh->rx_cnt = 0;
406 hperh->rx_size = 0;
407 hperh->tx_buf = psrc;
408 hperh->tx_cnt = 0;
409 hperh->tx_size = size;
410
411 tmp = READ_REG(hperh->perh->DSCR);
412 pgsize = (tmp & 0xfff0) >> 4;
413
414 if (size >= pgsize)
415 tmp = pgsize;
416 else
417 tmp = size;
418
419 hperh->tx_cnt += tmp;
420
421 ald_qspi_clear_it_flag(hperh, QSPI_IF_INDCF);
422 MODIFY_REG(hperh->perh->IWTSAR, QSPI_IWTSAR_ADDR_MSK, saddr);
423 MODIFY_REG(hperh->perh->IWTNR, QSPI_IWTNR_NUM_MSK, size);
424 ald_qspi_interrupt_config(hperh, QSPI_IT_INDTWF, ENABLE);
425 ald_qspi_interrupt_config(hperh, QSPI_IT_INDCF, ENABLE);
426
427 /* Trigger indirect write */
428 SET_BIT(hperh->perh->IWTR, QSPI_IWTR_WRST_MSK);
429
430 for (i = 0; i < (tmp / 4); ++i)
431 *(__IO uint32_t *)QSPI_MEMORY_ADDRESS = (*(uint32_t *)(psrc + 4 * i));
432
433 return OK;
434 }
435
436 /**
437 * @brief Transmit data to flash by poll.
438 * @param hperh: Pointer to a qspi_handle_t structure.
439 * @param saddr: Write start address.
440 * @param psrc: Pointer to source data buffer.
441 * @param size: Write bytes number.
442 * @retval Status, see @ref ald_status_t.
443 */
ald_qspi_indac_transmit_by_poll(qspi_handle_t * hperh,uint32_t saddr,uint8_t * psrc,uint32_t size)444 ald_status_t ald_qspi_indac_transmit_by_poll(qspi_handle_t *hperh, uint32_t saddr, uint8_t *psrc, uint32_t size)
445 {
446 uint32_t i, j = 0, cnt = 0;
447 uint32_t tmp = 0;
448 uint32_t idx = 0, txsm = 0;
449 assert_param(IS_QSPI_ALL(hperh->perh));
450
451 if ((psrc == NULL) || (size == 0))
452 return ERROR;
453
454 MODIFY_REG(hperh->perh->IWTSAR, QSPI_IWTSAR_ADDR_MSK, saddr);
455 MODIFY_REG(hperh->perh->IWTNR, QSPI_IWTNR_NUM_MSK, size);
456
457 /* Counter write times totally */
458 if (size % 4)
459 cnt = (size / 4) + 1;
460 else
461 cnt = size / 4;
462 /* Get transmit SRAM partition (unit:4bytes)*/
463 tmp = READ_REG(hperh->perh->SPR);
464 txsm = QSPI_SRAM_SIZE - tmp;
465 if (txsm == 0) return ERROR;
466 if (cnt <= txsm) {
467 /* Trigger indirect write */
468 SET_BIT(hperh->perh->IWTR, QSPI_IWTR_WRST_MSK);
469 for (i = 0; i < cnt; ++i)
470 *(__IO uint32_t *)QSPI_MEMORY_ADDRESS = (*(uint32_t *)(psrc + 4 *i));
471 } else {
472 SET_BIT(hperh->perh->IWTR, QSPI_IWTR_WRST_MSK);
473 for (j = 0; j < (cnt / txsm); ++j) {
474 for (i = 0; i < txsm; ++i) {
475 *(__IO uint32_t *)QSPI_MEMORY_ADDRESS = (*(uint32_t *)(psrc + idx + 4 *i));
476 }
477 idx += txsm * 4;
478 do {
479 tmp = READ_REG(hperh->perh->SFLR);
480 tmp = (tmp >> 16) & 0xffff;
481 } while (tmp != 0);
482 }
483
484 for (j = 0; j < (cnt % txsm); ++j)
485 *(__IO uint32_t *)QSPI_MEMORY_ADDRESS = (*(uint32_t *)(psrc + idx + 4 *j));
486 }
487 /* Wait for indirect read operation completely */
488 do {
489 tmp = READ_REG(hperh->perh->IWTR);
490 } while ( tmp & 0x4);
491
492 return OK;
493 }
494
495 /**
496 * @brief Read data from flash by poll.
497 * @param hperh: Pointer to a qspi_handle_t structure.
498 * @param saddr: Read start address.
499 * @param desbuf: Pointer to data buffer.
500 * @param size: Read bytes number.
501 * @retval Status, see @ref ald_status_t.
502 */
ald_qspi_indac_read_by_poll(qspi_handle_t * hperh,uint32_t saddr,uint8_t * desbuf,uint16_t size)503 ald_status_t ald_qspi_indac_read_by_poll(qspi_handle_t *hperh, uint32_t saddr, uint8_t *desbuf, uint16_t size)
504 {
505
506 uint32_t i = 0, j = 0, cnt = 0;
507 uint32_t tmp = 0;
508 uint32_t idx = 0, rxsm = 1;
509
510 assert_param(IS_QSPI_ALL(hperh->perh));
511
512 if ((desbuf == NULL) || (size == 0))
513 return ERROR;
514
515 MODIFY_REG(hperh->perh->IRTSAR, QSPI_IRTSAR_ADDR_MSK, saddr);
516 MODIFY_REG(hperh->perh->IRTNR, QSPI_IRTNR_NUM_MSK, size);
517 /* Counter read times totally */
518 if (size % 4)
519 cnt = (size / 4) + 1;
520 else
521 cnt = size / 4;
522 /* Get read SRAM partition (unit: 4bytes)*/
523 rxsm = READ_REG(hperh->perh->SPR) + 1;
524 if (cnt <= rxsm) {
525 SET_BIT(hperh->perh->IRTR, QSPI_IRTR_RDST_MSK);
526 do {
527 tmp = READ_REG(hperh->perh->SFLR);
528 tmp = tmp & 0x0000ffffU;
529 } while (tmp != cnt);
530 for (i = 0; i < cnt; ++i)
531 *(uint32_t *)(desbuf + 4 * i) = *(__IO uint32_t *)QSPI_MEMORY_ADDRESS;
532 } else {
533 SET_BIT(hperh->perh->IRTR, QSPI_IRTR_RDST_MSK);
534 for (j = 0; j < (cnt / rxsm); ++j) {
535 do {
536 tmp = READ_REG(hperh->perh->SFLR);
537 tmp = tmp & 0x0000ffffU;
538 } while (tmp != rxsm);
539 for (i = 0; i < rxsm; ++i) {
540 *(uint32_t *)(desbuf + idx + 4 * i) = *(__IO uint32_t *)QSPI_MEMORY_ADDRESS;
541 }
542 idx += rxsm * 4;
543 }
544 do {
545 tmp = READ_REG(hperh->perh->SFLR);
546 tmp = tmp & 0x0000ffffU;
547 } while ( tmp != (cnt % rxsm));
548
549 for (j = 0; j < (cnt % rxsm); ++j) {
550 *(uint32_t *)(desbuf + idx + 4 * i) = *(__IO uint32_t *)QSPI_MEMORY_ADDRESS;
551 }
552 }
553 /* Wait for indirect read operation completely */
554 do {
555 tmp = READ_REG(hperh->perh->IRTR);
556 } while (tmp & 0x04);
557
558 return OK;
559 }
560
561 /**
562 * @brief QSPI read data by interrupt.
563 * @param hperh: Pointer to a qspi_handle_t structure.
564 * @param saddr: Read start address.
565 * @param desbuf: Pointer to destination data buffer.
566 * @param size: Read bytes length.
567 * @retval Status, see @ref ald_status_t.
568 */
569
ald_qspi_indac_read_by_it(qspi_handle_t * hperh,uint32_t saddr,uint8_t * desbuf,uint16_t size)570 ald_status_t ald_qspi_indac_read_by_it(qspi_handle_t *hperh, uint32_t saddr, uint8_t *desbuf, uint16_t size)
571 {
572 assert_param(IS_QSPI_ALL(hperh->perh));
573
574 if ((desbuf == NULL) || (size == 0))
575 return ERROR;
576
577 hperh->state = QSPI_STATE_BUSY_RX;
578 hperh->rx_buf = desbuf;
579 hperh->rx_cnt = 0;
580 hperh->rx_size = size;
581 hperh->tx_buf = NULL;
582 hperh->tx_cnt = 0;
583 hperh->tx_size = 0;
584
585 ald_qspi_clear_it_flag(hperh, QSPI_IF_INDCF);
586 MODIFY_REG(hperh->perh->IRTSAR, QSPI_IRTSAR_ADDR_MSK, saddr);
587 MODIFY_REG(hperh->perh->IRTNR, QSPI_IRTNR_NUM_MSK, size);
588 ald_qspi_interrupt_config(hperh, QSPI_IT_INDTWF, ENABLE);
589 ald_qspi_interrupt_config(hperh, QSPI_IT_INDCF, ENABLE);
590 SET_BIT(hperh->perh->IRTR, QSPI_IRTR_RDST_MSK);
591
592 return OK;
593 }
594
595 /**
596 * @brief Execute a STIG command.
597 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
598 * @param stigcmd: Pointer to a structure that describes the STIG command.
599 * @retval Status, see @ref ald_status_t.
600 */
ald_qspi_execute_stig_cmd(qspi_handle_t * hperh,const qspi_stig_cmd_t * stigcmd)601 ald_status_t ald_qspi_execute_stig_cmd(qspi_handle_t * hperh, const qspi_stig_cmd_t * stigcmd)
602 {
603 uint32_t i;
604 ald_status_t status = ERROR;
605 uint32_t tickstart = ald_get_tick();
606
607 assert_param(IS_QSPI_ALL(hperh->perh));
608 assert_param(stigcmd->addr_len <= 4);
609 assert_param(stigcmd->wr_len <= 8);
610 assert_param(stigcmd->rd_len <= 8);
611 assert_param(stigcmd->d_sycle < 32);
612
613 if (stigcmd->wr_len)
614 assert_param(stigcmd->wr_buf);
615 if (stigcmd->rd_len)
616 assert_param(stigcmd->rd_buf);
617
618 /* wait for Flash idle */
619 status = qspi_wait_for_idle(hperh, tickstart, QSPI_TIMEOUT_DEFAULT_VALUE);
620
621 if (status != OK)
622 return ERROR;
623
624 MODIFY_REG(hperh->perh->FCR, QSPI_FCR_OPCODE_MSK | QSPI_FCR_DUMNUM_MSK , ((stigcmd->code << 24) | (stigcmd->d_sycle << 7)));
625
626 if (stigcmd->wr_len) {
627 uint32_t buffer[2] = {0, 0};
628 uint8_t * dst = (uint8_t *) buffer;
629 uint8_t * src = stigcmd->wr_buf;
630
631 MODIFY_REG(hperh->perh->FCR, QSPI_FCR_WDNUM_MSK, (stigcmd->wr_len - 1) << QSPI_FCR_WDNUM_POSS);
632 SET_BIT(hperh->perh->FCR, QSPI_FCR_WREN_MSK);
633
634 for (i = 0; i < stigcmd->wr_len; i++)
635 dst[i] = src[i];
636
637 hperh->perh->FCWLR = buffer[0];
638 hperh->perh->FCWHR = buffer[1];
639 } else {
640 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_WDNUM_MSK);
641 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_WREN_MSK);
642 }
643
644 if (stigcmd->addr_len) {
645 SET_BIT(hperh->perh->FCR, QSPI_FCR_ADDREN_MSK);
646
647 MODIFY_REG(hperh->perh->FCR, QSPI_FCR_ADNUM_MSK, (stigcmd->addr_len - 1) << QSPI_FCR_ADNUM_POSS);
648 MODIFY_REG(hperh->perh->FCAR, QSPI_FCAR_CMDADR_MSK, stigcmd->addr);
649 } else {
650 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_ADDREN_MSK);
651 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_ADNUM_MSK);
652 CLEAR_BIT(hperh->perh->FCAR, QSPI_FCAR_CMDADR_MSK);
653 }
654
655 if (stigcmd->mode_bit) {
656 SET_BIT(hperh->perh->FCR, QSPI_FCR_MODBEN_MSK);
657 MODIFY_REG(hperh->perh->MBR, QSPI_MBR_MODEB_MSK, stigcmd->val);
658 } else {
659 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_MODBEN_MSK);
660 CLEAR_BIT(hperh->perh->MBR, QSPI_MBR_MODEB_MSK);
661 }
662
663 if (stigcmd->rd_len) {
664 SET_BIT(hperh->perh->FCR, QSPI_FCR_RDEN_MSK);
665 MODIFY_REG(hperh->perh->FCR, QSPI_FCR_RDNUM_MSK, (stigcmd->rd_len - 1) << QSPI_FCR_RDNUM_POSS);
666 } else {
667 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_RDEN_MSK);
668 CLEAR_BIT(hperh->perh->FCR, QSPI_FCR_RDNUM_MSK);
669 }
670
671 /* Start command execution */
672 SET_BIT(hperh->perh->FCR, QSPI_FCR_CMDT_MSK);
673
674 while (hperh->perh->FCR & QSPI_FCR_CMDS_MSK);
675
676 /* Read data if any */
677 if (stigcmd->rd_len) {
678 uint32_t buffer[2] = { 0, 0 };
679 const uint8_t * src = (const uint8_t *)buffer;
680 uint8_t * dst = stigcmd->rd_buf;
681
682 buffer[0] = hperh->perh->FCRLR;
683 buffer[1] = hperh->perh->FCRHR;
684
685 for (i = 0; i < stigcmd->rd_len; i++) {
686 dst[i] = src[i];
687 }
688 }
689
690 return OK;
691 }
692
693 #ifdef ALD_DMA
694 /**
695 * @brief Sends an amount of data with DMA.
696 * @param hperh: Pointer to a qspi_handle_t structure.
697 * @param addr: Write start address.
698 * @param psrc: Pointer to data buffer.
699 * @param size: Write data bytes.
700 * @retval Status, see @ref ald_status_t.
701 */
ald_qspi_indac_transmit_by_dma(qspi_handle_t * hperh,uint32_t addr,uint8_t * psrc,uint16_t size)702 ald_status_t ald_qspi_indac_transmit_by_dma(qspi_handle_t *hperh, uint32_t addr, uint8_t *psrc, uint16_t size)
703 {
704 uint16_t cnt = 0;
705 uint32_t *tmp = (uint32_t*)psrc;
706 /* Get Indirect Read Trigger Address */
707 __IO uint32_t *data_reg = (uint32_t *)hperh->perh->IATR;
708
709 assert_param(IS_QSPI_ALL(hperh->perh));
710
711 if ((psrc == NULL) || (size == 0))
712 return ERROR;
713
714 MODIFY_REG(hperh->perh->IWTSAR, QSPI_IWTSAR_ADDR_MSK, addr);
715 MODIFY_REG(hperh->perh->IWTNR, QSPI_IWTNR_NUM_MSK, size);
716 QSPI_DMA_ENABLE(hperh);
717 if (size % 4)
718 cnt = (size / 4) + 1;
719 else
720 cnt = size / 4;
721
722 __LOCK(hperh);
723
724 hperh->hdma.perh = DMA0;
725 hperh->hdma.cplt_cbk = NULL;
726 ald_dma_config_struct(&hperh->hdma.config);
727
728 hperh->hdma.config.data_width = DMA_DATA_SIZE_WORD;
729 hperh->hdma.config.src = (void *)tmp;
730 hperh->hdma.config.dst = (void *)data_reg;
731 hperh->hdma.config.size = cnt;
732 hperh->hdma.config.src_inc = DMA_DATA_INC_WORD;
733 hperh->hdma.config.dst_inc = DMA_DATA_INC_NONE;
734 hperh->hdma.config.msel = DMA_MSEL_QSPI;
735 hperh->hdma.config.msigsel = DMA_MSIGSEL_QSPI_WRITE;
736 hperh->hdma.config.channel = 0;
737 hperh->hdma.config.R_power = DMA_R_POWER_4;
738 hperh->hdma.config.burst = ENABLE;
739 ald_dma_config_basic(&hperh->hdma);
740
741 /* Trigger indirect write */
742 SET_BIT(hperh->perh->IWTR, QSPI_IWTR_WRST_MSK);
743 __UNLOCK(hperh);
744
745 return OK;
746 }
747
748 /**
749 * @brief Receive an amount of data with DMA.
750 * @param hperh: Pointer to a qspi_handle_t structure.
751 * @param addr: Read start address.
752 * @param pdbuf: Pointer to data buffer.
753 * @param size: Read data bytes.
754 * @retval Status, see @ref ald_status_t.
755 */
ald_qspi_indac_read_by_dma(qspi_handle_t * hperh,uint32_t addr,uint8_t * pdbuf,uint16_t size)756 ald_status_t ald_qspi_indac_read_by_dma(qspi_handle_t *hperh, uint32_t addr, uint8_t *pdbuf, uint16_t size)
757 {
758 uint16_t cnt = 0;
759 ald_status_t status = OK;
760 uint32_t *tmp = (uint32_t *)pdbuf;
761 /* Get Indirect Read Trigger Address */
762 __IO uint32_t *data_reg = (uint32_t *)hperh->perh->IATR;
763
764 assert_param(IS_QSPI_ALL(hperh->perh));
765
766 if ((pdbuf == NULL) || (size == 0))
767 return ERROR;
768
769 MODIFY_REG(hperh->perh->IRTSAR, QSPI_IRTSAR_ADDR_MSK, addr);
770 MODIFY_REG(hperh->perh->IRTNR, QSPI_IRTNR_NUM_MSK, size);
771
772 QSPI_DMA_ENABLE(hperh);
773
774 if (size % 4)
775 cnt = (size / 4) + 1;
776 else
777 cnt = size / 4;
778
779 __LOCK(hperh);
780
781 hperh->hdma.perh = DMA0;
782 hperh->hdma.cplt_cbk = NULL;
783 ald_dma_config_struct(&hperh->hdma.config);
784
785 hperh->hdma.config.data_width = DMA_DATA_SIZE_WORD;
786 hperh->hdma.config.src = (void *)data_reg;
787 hperh->hdma.config.dst = (void *)tmp;
788 hperh->hdma.config.size = cnt;
789 hperh->hdma.config.src_inc = DMA_DATA_INC_NONE;
790 hperh->hdma.config.dst_inc = DMA_DATA_INC_WORD;
791 hperh->hdma.config.msel = DMA_MSEL_QSPI;
792 hperh->hdma.config.msigsel = DMA_MSIGSEL_QSPI_READ;
793 hperh->hdma.config.channel = 0;
794 hperh->hdma.config.R_power = DMA_R_POWER_4;
795 hperh->hdma.config.burst = ENABLE;
796 ald_dma_config_basic(&hperh->hdma);
797
798 /* Trigger indirect write */
799 SET_BIT(hperh->perh->IRTR, QSPI_IRTR_RDST_MSK);
800 __UNLOCK(hperh);
801
802 return status;
803 }
804 #endif
805
806 /**
807 * @}
808 */
809
810 /** @defgroup QSPI_Public_Functions_Group3 Status functions
811 * @brief QSPI status functions
812 * @{
813 */
814 /**
815 * @brief Get the status of QSPI interrupt flag.
816 * @param hperh: Pointer to a qspi_handle_t structure.
817 * @param flag: Specifies the QSPI interrupt flag.
818 * This parameter can be one of the @ref qspi_flag_t.
819 * @retval Status, see @ref flag_status_t.
820 */
qspi_get_flag_status(qspi_handle_t * hperh,qspi_flag_t flag)821 flag_status_t qspi_get_flag_status(qspi_handle_t *hperh, qspi_flag_t flag)
822 {
823 assert_param(IS_QSPI_ALL(hperh->perh));
824 assert_param(IS_QSPI_IF(flag));
825
826 if (hperh->perh->IFR & flag)
827 return SET;
828
829 return RESET;
830 }
831
832 /**
833 * @brief Clear the QSPI interrupt flag.
834 * @param hperh: Pointer to a qspi_handle_t structure.
835 * @param flag: Specifies the QSPI interrupt flag.
836 * This parameter can be one of the @ref qspi_flag_t.
837 * @retval None
838 */
ald_qspi_clear_it_flag(qspi_handle_t * hperh,qspi_flag_t flag)839 void ald_qspi_clear_it_flag(qspi_handle_t *hperh, qspi_flag_t flag)
840 {
841 assert_param(IS_QSPI_ALL(hperh->perh));
842 assert_param(IS_QSPI_IF(flag));
843
844 hperh->perh->IFR = flag;
845
846 return;
847 }
848
849 /**
850 * @brief Read QSPI SRAM fill level.
851 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
852 * @param srt: QSPI embeded SRAM type,the value can be one of @ref qspi_sram_t.
853 * @retval sram fill level value.
854 */
qspi_read_sram_fill_level(qspi_handle_t * hperh,qspi_sram_t srt)855 uint16_t qspi_read_sram_fill_level(qspi_handle_t * hperh, qspi_sram_t srt)
856 {
857 assert_param(IS_QSPI_ALL(hperh->perh));
858 assert_param(IS_QSPI_INDIRECT_SRAM_FILL_TYPE(srt));
859
860 if (srt == QSPI_SRAM_RD)
861 return READ_BITS(hperh->perh->SFLR, QSPI_SFLR_INDRSFL_MSK, QSPI_SFLR_INDRSFL_POSS);
862
863 return READ_BITS(hperh->perh->SFLR, QSPI_SFLR_INDWSFL_MSK, QSPI_SFLR_INDWSFL_POSS);
864 }
865
866 /**
867 * @brief QSPI Write Protect Configuration.
868 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
869 * @param wpcfg: Pointer to the QSPI write protect configuration structer.
870 * @retval None.
871 */
ald_qspi_write_proect_config(qspi_handle_t * hperh,qspi_wr_protect_t * wpcfg)872 void ald_qspi_write_proect_config(qspi_handle_t * hperh, qspi_wr_protect_t * wpcfg)
873 {
874 assert_param(IS_QSPI_ALL(hperh->perh));
875
876 MODIFY_REG(hperh->perh->WPLR, QSPI_WPLR_LBLKNUM_MSK, wpcfg->lowblk);
877 MODIFY_REG(hperh->perh->WPHR, QSPI_WPHR_HBLKNUM_MSK, wpcfg->upblk);
878 QSPI_WRITE_PROTECT_ENABLE(hperh);
879
880 return;
881 }
882
883 /**
884 * @brief QSPI Write Protect Inversion.
885 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
886 * @param state: SRAM protect inversion state.
887 * This parameter can be:
888 * @arg ENABLE
889 * @arg DISABLE
890 * @retval None.
891 */
ald_qspi_write_proect_inverse(qspi_handle_t * hperh,type_func_t state)892 void ald_qspi_write_proect_inverse(qspi_handle_t * hperh, type_func_t state)
893 {
894 assert_param(IS_FUNC_STATE(state));
895 assert_param(IS_QSPI_ALL(hperh->perh));
896
897 if (state) {
898 QSPI_WRITE_PROTECT_DISABLE(hperh);
899 SET_BIT(hperh->perh->WPCR, QSPI_WPCR_WPINV_MSK);
900 QSPI_WRITE_PROTECT_ENABLE(hperh);
901 }
902 else {
903 QSPI_WRITE_PROTECT_DISABLE(hperh);
904 SET_BIT(hperh->perh->WPCR, QSPI_WPCR_WPINV_MSK);
905 QSPI_WRITE_PROTECT_ENABLE(hperh);
906 }
907
908 return;
909 }
910
911 /**
912 * @brief QSPI interrupt handler
913 * @retval None
914 */
ald_qspi_irq_handler(qspi_handle_t * hperh)915 void ald_qspi_irq_handler(qspi_handle_t *hperh)
916 {
917 uint32_t regs = 0;
918 uint32_t tmp = 0, i = 0;
919
920 regs = READ_REG(hperh->perh->DSCR);
921 regs = (regs & 0x0000fff0) >> 4;
922
923 // indirect transmit
924 if (hperh->state == QSPI_STATE_BUSY_TX) {
925
926 //QSPI indirect transmit(xfer length longer than watermark value)
927 if (qspi_get_flag_status(hperh, QSPI_IF_INDTWF) == SET) {
928 ald_qspi_clear_it_flag(hperh, QSPI_IF_INDTWF);
929 tmp = hperh->tx_size - hperh->tx_cnt;
930 if (tmp > regs) {
931 for (i = 0; i < (regs / 4); ++i) {
932 *(__IO uint32_t *)QSPI_MEMORY_ADDRESS = (*(uint32_t *)(hperh->tx_buf + hperh->tx_cnt + 4 * i));
933 }
934 hperh->tx_cnt += regs;
935 } else {
936 for (i = 0; i < (tmp / 4); ++i) {
937 *(__IO uint32_t *)QSPI_MEMORY_ADDRESS = (*(uint32_t *)(hperh->tx_buf + hperh->tx_cnt + 4 * i));
938 }
939 hperh->tx_cnt += tmp;
940 }
941 }
942 //QSPI indirect transmit completely
943 if (qspi_get_flag_status(hperh, QSPI_IF_INDCF) == SET) {
944 ald_qspi_clear_it_flag(hperh, QSPI_IF_INDCF);
945 ald_qspi_interrupt_config(hperh, QSPI_IT_INDTWF, DISABLE);
946 //transmit completely callback
947 }
948
949 }
950
951 // indirect receive
952 if (hperh->state == QSPI_STATE_BUSY_RX) {
953 if (qspi_get_flag_status(hperh, QSPI_IF_INDTWF) == SET) {
954 ald_qspi_clear_it_flag(hperh, QSPI_IF_INDTWF);
955 tmp = READ_REG(hperh->perh->SFLR);
956 tmp = tmp & 0xffff;
957
958 for (i = 0; i < tmp; ++i) {
959 *(uint32_t *)(hperh->rx_buf + hperh->rx_cnt + i*4) = *(__IO uint32_t *)QSPI_MEMORY_ADDRESS;
960 }
961 hperh->rx_cnt += tmp*4;
962 }
963
964 if (qspi_get_flag_status(hperh, QSPI_IF_INDCF) == SET) {
965 ald_qspi_clear_it_flag(hperh, QSPI_IF_INDCF);
966 ald_qspi_interrupt_config(hperh, QSPI_IT_INDTWF, DISABLE);
967
968 tmp = READ_REG(hperh->perh->SFLR);
969 tmp = tmp & 0xffff;
970
971 for (i = 0; i < tmp; ++i) {
972 *(uint32_t *)(hperh->rx_buf + hperh->rx_cnt + i*4) = *(__IO uint32_t *)QSPI_MEMORY_ADDRESS;
973 }
974 }
975 }
976 }
977
978 /**
979 * @brief Enable/disable the specified QSPI interrupts.
980 * @param hperh: Pointer to a qspi_handle_t structure.
981 * @param it: Specifies the QSPI interrupt sources to be enabled or disabled.
982 * This parameter can be one of the @ref qspi_it_t.
983 * @param state: New state of the specified QSPI interrupts.
984 * This parameter can be:
985 * @arg ENABLE
986 * @arg DISABLE
987 * @retval None
988 */
ald_qspi_interrupt_config(qspi_handle_t * hperh,qspi_it_t it,type_func_t state)989 void ald_qspi_interrupt_config(qspi_handle_t *hperh, qspi_it_t it, type_func_t state)
990 {
991 assert_param(IS_QSPI_ALL(hperh->perh));
992 assert_param(IS_QSPI_IT(it));
993 assert_param(IS_FUNC_STATE(state));
994
995 if (state == ENABLE)
996 hperh->perh->IMR |= (uint32_t)it;
997 else
998 hperh->perh->IMR &= (uint32_t)(~it);
999
1000 return;
1001 }
1002
1003 /**
1004 * @brief Configure the QSPI legacy .
1005 * @param hperh: Pointer to a qspi_handle_t structure.
1006 * @param config: structure that contains the legacy configuration information.
1007 * @retval None
1008 */
ald_qspi_legacy_config(qspi_handle_t * hperh,const qspi_legacy_cfg_t * config)1009 void ald_qspi_legacy_config(qspi_handle_t* hperh, const qspi_legacy_cfg_t *config)
1010 {
1011 assert_param(IS_QSPI_ALL(hperh->perh));
1012
1013 MODIFY_REG(hperh->perh->TXHR, QSPI_TXHR_TXTH_MSK, config->tx_thrd);
1014 MODIFY_REG(hperh->perh->RXHR, QSPI_RXHR_RXTH_MSK, config->rx_thrd);
1015 QSPI_LEGACY_SPI_ENABLE(hperh);
1016
1017 return;
1018 }
1019
1020 /**
1021 * @brief Get QSPI indirect write access status.
1022 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
1023 * @param status: qspi indirect write status.
1024 * @retval Status, see @ref ald_status_t.
1025 */
qspi_indwr_get_status(qspi_handle_t * hperh,qspi_indwr_status_t status)1026 flag_status_t qspi_indwr_get_status(qspi_handle_t *hperh, qspi_indwr_status_t status)
1027 {
1028 assert_param(IS_QSPI_ALL(hperh->perh));
1029 assert_param(IS_QSPI_INDIRECT_WRITE_STATUS(status));
1030
1031 if (hperh->perh->IWTR & status)
1032 return SET;
1033
1034 return RESET;
1035 }
1036
1037 /**
1038 * @brief Wait indirect wriet a flag state until time out.
1039 * @param hperh: Pointer to the QSPI qspi_handle_t structure.
1040 * @param flag: Flag checked,the parameter can be one of @ref qspi_indwr_status_t.
1041 * @param status: Value of the flag expected,the parameter can be one of @ref flag_status_t.
1042 * @param timeout: Duration of the time out.
1043 * @retval Status, see @ref ald_status_t.
1044 */
qspi_indwr_wait_flag(qspi_handle_t * hperh,qspi_indwr_status_t flag,flag_status_t status,uint32_t timeout)1045 ald_status_t qspi_indwr_wait_flag(qspi_handle_t *hperh, qspi_indwr_status_t flag, flag_status_t status, uint32_t timeout)
1046 {
1047 uint32_t tick;
1048
1049 if (timeout == 0)
1050 return ERROR;
1051
1052 tick = ald_get_tick();
1053
1054 /* Waiting for flag */
1055 while ((qspi_indwr_get_status(hperh, flag)) != status) {
1056 if (((ald_get_tick()) - tick) > timeout)
1057 return TIMEOUT;
1058 }
1059
1060 return OK;
1061 }
1062
1063 /**
1064 * @brief QSPI Indirect read operation wait for specified status.
1065 * @param hperh: Pointer to a qspi_handle_t structure.
1066 * @param flag: specifies the qspi flag to check.
1067 * @param status: The new Flag status (SET or RESET).
1068 * @param timeout: Timeout duration
1069 * @retval Status, see @ref ald_status_t.
1070 */
qspi_indrd_wait_flag(qspi_handle_t * hperh,qspi_indrd_flag_t flag,flag_status_t status,uint32_t timeout)1071 ald_status_t qspi_indrd_wait_flag(qspi_handle_t *hperh, qspi_indrd_flag_t flag, flag_status_t status, uint32_t timeout)
1072 {
1073 uint32_t tick;
1074
1075 if (timeout == 0)
1076 return ERROR;
1077
1078 tick = ald_get_tick();
1079
1080 /* Waiting for flag */
1081 while ((qspi_indrd_get_status(hperh, flag)) != status) {
1082 if (((ald_get_tick()) - tick) > timeout)
1083 return TIMEOUT;
1084 }
1085 return OK;
1086 }
1087
1088 /**
1089 * @brief Clear the QSPI interrupt flag.
1090 * @param hperh: Pointer to a qspi_handle_t structure.
1091 * @param flag: Specifies the QSPI interrupt flag.
1092 * This parameter can be one of the @ref qspi_flag_t.
1093 * @retval None
1094 */
qspi_clear_flag_status(qspi_handle_t * hperh,qspi_flag_t flag)1095 void qspi_clear_flag_status(qspi_handle_t *hperh, qspi_flag_t flag)
1096 {
1097 assert_param(IS_QSPI_ALL(hperh->perh));
1098 assert_param(IS_QSPI_IF(flag));
1099
1100 hperh->perh->IFR = flag;
1101 return;
1102 }
1103
1104 /**
1105 * @}
1106 */
1107 /**
1108 * @}
1109 */
1110 #endif /* ALD_QSPI */
1111 /**
1112 * @}
1113 */
1114 /**
1115 * @}
1116 */
1117