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