1 /**
2   *********************************************************************************
3   *
4   * @file    ald_nor_lcd.c
5   * @brief   EBI_NOR_LCD module driver.
6   *
7   * @version V1.0
8   * @date    25 Dec 2019
9   * @author  AE Team
10   * @note
11   *          Change Logs:
12   *          Date            Author          Notes
13   *          25 Dec 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 
33 #include "ald_conf.h"
34 
35 
36 /** @addtogroup ES32FXXX_ALD
37   * @{
38   */
39 
40 /** @defgroup NOR_LCD NOR_LCD
41   * @brief NOR_LCD driver modules
42   * @{
43   */
44 #ifdef ALD_NOR
45 
46 /** @defgroup NOR_LCD_Private_Variables NOR_LCD Private Variables
47   * @{
48   */
49 static uint32_t NORMEMDATWIDTH = NOR_MEMORY_8B;
50 /**
51   * @}
52   */
53 
54 /** @defgroup NOR_LCD_Public_Functions NOR_LCD Public Functions
55   * @brief NOR_LCD public functions
56   * @{
57   */
58 /** @defgroup NOR_LCD_Public_Functions_Group1 Initialization functions
59   * @brief NOR_LCD Initialization functions
60   * @{
61  */
62 /**
63   * @brief  Perform the NOR memory Initialization sequence
64   * @param  hperh: pointer to a nor_handle_t structure
65   * @param  timing: pointer to NOR control timing structure
66   * @param  ext_timing: pointer to NOR extended mode timing structure
67   * @retval ald status
68   */
ald_nor_init(nor_handle_t * hperh,ald_ebi_nor_sram_timing_t * timing,ald_ebi_nor_sram_timing_t * ext_timing)69 ald_status_t ald_nor_init(nor_handle_t *hperh, ald_ebi_nor_sram_timing_t *timing, ald_ebi_nor_sram_timing_t *ext_timing)
70 {
71 	if (hperh == NULL)
72 		return ERROR;
73 	if (hperh->state == ALD_NOR_STATE_RESET)
74 		hperh->lock = UNLOCK;
75 
76 	/* Initialize NOR control Interface */
77 	ald_ebi_nor_sram_init(hperh->instance, &(hperh->init));
78 	/* Initialize NOR timing Interface */
79 	ald_ebi_nor_sram_timing_init(hperh->instance, timing, hperh->init.bank);
80 	/* Initialize NOR extended mode timing Interface */
81 	ald_ebi_nor_sram_ext_timing_init(hperh->ext, ext_timing, hperh->init.bank, hperh->init.ext_mode);
82 	/* Enable the NORSRAM device */
83 	ald_ebi_nor_sram_enable(hperh->instance, hperh->init.bank);
84 
85 	/* Initialize NOR Memory Data Width*/
86 	if (hperh->init.width == EBI_NORSRAM_MEM_BUS_WIDTH_8)
87 		NORMEMDATWIDTH = NOR_MEMORY_8B;
88 	else
89 		NORMEMDATWIDTH = NOR_MEMORY_16B;
90 
91 	hperh->state = ALD_NOR_STATE_READY;
92 	return OK;
93 }
94 
95 /**
96   * @brief  Perform NOR memory De-Initialization sequence
97   * @param  hperh: pointer to a nor_handle_t structure
98   * @retval ald status
99   */
ald_nor_deinit(nor_handle_t * hperh)100 ald_status_t ald_nor_deinit(nor_handle_t *hperh)
101 {
102 	ald_ebi_nor_sram_deinit(hperh->instance, hperh->ext, hperh->init.bank);
103 	hperh->state = ALD_NOR_STATE_RESET;
104 	__UNLOCK(hperh);
105 
106 	return OK;
107 }
108 /**
109   * @}
110   */
111 
112 /** @defgroup NOR_LCD_Public_Functions_Group2 I/O operation functions
113   * @brief NOR_LCD I/O operation functions
114   * @{
115   */
116 /**
117   * @brief  Read NOR flash IDs
118   * @param  hperh: pointer to a nor_handle_t structure
119   * @param  id : pointer to NOR ID structure
120   * @retval ald status
121   */
ald_nor_read_id(nor_handle_t * hperh,nor_id_t * id)122 ald_status_t ald_nor_read_id(nor_handle_t *hperh, nor_id_t *id)
123 {
124 	uint32_t devaddr = 0;
125 
126 	__LOCK(hperh);
127 
128 	if (hperh->state == ALD_NOR_STATE_BUSY)
129 		return BUSY;
130 
131 	/* Select the NOR device address */
132 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
133 		devaddr = NOR_MEMORY_ADRESS1;
134 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
135 		devaddr = NOR_MEMORY_ADRESS2;
136 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
137 		devaddr = NOR_MEMORY_ADRESS3;
138 	else
139 		devaddr = NOR_MEMORY_ADRESS4;
140 
141 	hperh->state = ALD_NOR_STATE_BUSY;
142 
143 	/* Send read ID command */
144 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
145 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
146 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
147 
148 	/* Read the NOR IDs */
149 	id->m_code       = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, MC_ADDRESS);
150 	id->device_code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, DEVICE_CODE1_ADDR);
151 	id->device_code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, DEVICE_CODE2_ADDR);
152 	id->device_code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, DEVICE_CODE3_ADDR);
153 
154 	hperh->state = ALD_NOR_STATE_READY;
155 	__UNLOCK(hperh);
156 
157 	return OK;
158 }
159 
160 /**
161   * @brief  Returns the NOR memory to Read mode.
162   * @param  hperh: pointer to a nor_handle_t structure
163   * @retval ald status
164   */
ald_nor_return_readmode(nor_handle_t * hperh)165 ald_status_t ald_nor_return_readmode(nor_handle_t *hperh)
166 {
167 	uint32_t devaddr = 0;
168 
169 	__LOCK(hperh);
170 
171 	if (hperh->state == ALD_NOR_STATE_BUSY)
172 		return BUSY;
173 
174 	/* Select the NOR device address */
175 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
176 		devaddr = NOR_MEMORY_ADRESS1;
177 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
178 		devaddr = NOR_MEMORY_ADRESS2;
179 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
180 		devaddr = NOR_MEMORY_ADRESS3;
181 	else
182 		devaddr = NOR_MEMORY_ADRESS4;
183 
184 	NOR_WRITE(devaddr, NOR_CMD_DATA_READ_RESET);
185 	hperh->state = ALD_NOR_STATE_READY;
186 	__UNLOCK(hperh);
187 
188 	return OK;
189 }
190 
191 /**
192   * @brief  Read data from NOR memory
193   * @param  hperh: pointer to a nor_handle_t structure
194   * @param  addr: pointer to Device address
195   * @param  data: pointer to read data
196   * @retval ald status
197   */
ald_nor_read(nor_handle_t * hperh,uint32_t * addr,uint16_t * data)198 ald_status_t ald_nor_read(nor_handle_t *hperh, uint32_t *addr, uint16_t *data)
199 {
200 	uint32_t devaddr = 0;
201 
202 	__LOCK(hperh);
203 
204 	if (hperh->state == ALD_NOR_STATE_BUSY)
205 		return BUSY;
206 
207 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
208 		devaddr = NOR_MEMORY_ADRESS1;
209 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
210 		devaddr = NOR_MEMORY_ADRESS2;
211 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
212 		devaddr = NOR_MEMORY_ADRESS3;
213 	else
214 		devaddr = NOR_MEMORY_ADRESS4;
215 
216 	hperh->state = ALD_NOR_STATE_BUSY;
217 
218 	/* Send read data command */
219 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
220 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
221 	NOR_WRITE((uint32_t)addr, NOR_CMD_DATA_READ_RESET);
222 
223 	*data = *(__IO uint32_t *)(uint32_t)addr;
224 	hperh->state = ALD_NOR_STATE_READY;
225 	__UNLOCK(hperh);
226 
227 	return OK;
228 }
229 
230 /**
231   * @brief  Program data to NOR memory
232   * @param  hperh: pointer to a nor_handle_t structure
233   * @param  addr: device address
234   * @param  data: pointer to the data to write
235   * @retval ald status
236   */
ald_nor_program(nor_handle_t * hperh,uint32_t * addr,uint16_t * data)237 ald_status_t ald_nor_program(nor_handle_t *hperh, uint32_t *addr, uint16_t *data)
238 {
239 	uint32_t devaddr = 0;
240 
241 	__LOCK(hperh);
242 
243 	if (hperh->state == ALD_NOR_STATE_BUSY)
244 		return BUSY;
245 
246 	/* Select the NOR device address */
247 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
248 		devaddr = NOR_MEMORY_ADRESS1;
249 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
250 		devaddr = NOR_MEMORY_ADRESS2;
251 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
252 		devaddr = NOR_MEMORY_ADRESS3;
253 	else /* EBI_NORSRAM_BANK4 */
254 		devaddr = NOR_MEMORY_ADRESS4;
255 
256 	hperh->state = ALD_NOR_STATE_BUSY;
257 
258 	/* Send program data command */
259 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
260 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
261 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
262 
263 	/* Write the data */
264 	NOR_WRITE(addr, *data);
265 	hperh->state = ALD_NOR_STATE_READY;
266 	__UNLOCK(hperh);
267 
268 	return OK;
269 }
270 
271 /**
272   * @brief  Reads a block of data from the EBI NOR memory
273   * @param  hperh: pointer to a nor_handle_t structure
274   * @param  addr: nor memory internal address to read from
275   * @param  data: pointer to the buffer that receives the data read from the
276   *         NOR memory
277   * @param  size : number of Half word to read
278   * @retval ald status
279   */
ald_nor_read_buffer(nor_handle_t * hperh,uint32_t addr,uint16_t * data,uint32_t size)280 ald_status_t ald_nor_read_buffer(nor_handle_t *hperh, uint32_t addr, uint16_t *data, uint32_t size)
281 {
282 	uint32_t devaddr = 0;
283 
284 	/* Process Locked */
285 	__LOCK(hperh);
286 
287 	if (hperh->state == ALD_NOR_STATE_BUSY)
288 		return BUSY;
289 
290 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
291 		devaddr = NOR_MEMORY_ADRESS1;
292 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
293 		devaddr = NOR_MEMORY_ADRESS2;
294 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
295 		devaddr = NOR_MEMORY_ADRESS3;
296 	else
297 		devaddr = NOR_MEMORY_ADRESS4;
298 
299 	hperh->state = ALD_NOR_STATE_BUSY;
300 
301 	/* Send read data command */
302 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
303 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
304 	NOR_WRITE(addr, NOR_CMD_DATA_READ_RESET);
305 
306 	/* Read buffer */
307 	while (size > 0) {
308 		*data++ = *(__IO uint16_t *)addr;
309 		addr += 2U;
310 		size--;
311 	}
312 
313 	hperh->state = ALD_NOR_STATE_READY;
314 	__UNLOCK(hperh);
315 
316 	return OK;
317 }
318 
319 /**
320   * @brief  Writes a half-word buffer to the EBI NOR memory
321   * @param  hperh: pointer to a nor_handle_t structure
322   * @param  addr: nor memory internal address from which the data
323   * @param  data: pointer to source data buffer
324   * @param  size: number of Half words to write
325   * @retval ald status
326   */
ald_nor_program_buffer(nor_handle_t * hperh,uint32_t addr,uint16_t * data,uint32_t size)327 ald_status_t ald_nor_program_buffer(nor_handle_t *hperh, uint32_t addr, uint16_t *data, uint32_t size)
328 {
329 	uint16_t * p_currentaddr = (uint16_t *)NULL;
330 	uint16_t * p_endaddr = (uint16_t *)NULL;
331 	uint32_t lastloadedaddr = 0, devaddr = 0;
332 
333 	__LOCK(hperh);
334 
335 	if (hperh->state == ALD_NOR_STATE_BUSY)
336 		return BUSY;
337 
338 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
339 		devaddr = NOR_MEMORY_ADRESS1;
340 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
341 		devaddr = NOR_MEMORY_ADRESS2;
342 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
343 		devaddr = NOR_MEMORY_ADRESS3;
344 	else
345 		devaddr = NOR_MEMORY_ADRESS4;
346 
347 	hperh->state = ALD_NOR_STATE_BUSY;
348 
349 	/* Initialize variables */
350 	p_currentaddr  = (uint16_t*)((uint32_t)(addr));
351 	p_endaddr      = p_currentaddr + (size - 1U);
352 	lastloadedaddr = (uint32_t)(addr);
353 
354 	/* Issue unlock command sequence */
355 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
356 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
357 	/* Write Buffer Load Command */
358 	NOR_WRITE((uint32_t)(p_currentaddr), NOR_CMD_DATA_BUFFER_AND_PROG);
359 	NOR_WRITE((uint32_t)(p_currentaddr), (size - 1U));
360 
361 	/* Load Data into NOR Buffer */
362 	while (p_currentaddr <= p_endaddr) {
363 		lastloadedaddr = (uint32_t)p_currentaddr;
364 		NOR_WRITE(p_currentaddr, *data++);
365 		p_currentaddr++;
366 	}
367 
368 	NOR_WRITE((uint32_t)(lastloadedaddr), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
369 	hperh->state = ALD_NOR_STATE_READY;
370 	__UNLOCK(hperh);
371 
372 	return OK;
373 }
374 
375 /**
376   * @brief  Erase the specified block of the NOR memory
377   * @param  hperh: pointer to a nor_handle_t structure
378   * @param  blkaddr : block to erase address
379   * @param  addr: device address
380   * @retval ald status
381   */
ald_nor_erase_block(nor_handle_t * hperh,uint32_t blkaddr,uint32_t addr)382 ald_status_t ald_nor_erase_block(nor_handle_t *hperh, uint32_t blkaddr, uint32_t addr)
383 {
384 	uint32_t devaddr = 0;
385 
386 	__LOCK(hperh);
387 
388 	if (hperh->state == ALD_NOR_STATE_BUSY)
389 		return BUSY;
390 
391 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
392 		devaddr = NOR_MEMORY_ADRESS1;
393 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
394 		devaddr = NOR_MEMORY_ADRESS2;
395 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
396 		devaddr = NOR_MEMORY_ADRESS3;
397 	else
398 		devaddr = NOR_MEMORY_ADRESS4;
399 
400 	hperh->state = ALD_NOR_STATE_BUSY;
401 
402 	/* Send block erase command sequence */
403 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
404 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
405 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
406 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
407 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
408 	NOR_WRITE((uint32_t)(blkaddr + addr), NOR_CMD_DATA_BLOCK_ERASE);
409 
410 	hperh->state = ALD_NOR_STATE_READY;
411 	__UNLOCK(hperh);
412 
413 	return OK;
414 
415 }
416 
417 /**
418   * @brief  Erase the entire NOR chip.
419   * @param  hperh: pointer to a nor_handle_t structure
420   * @retval ald status
421   */
ald_nor_erase_chip(nor_handle_t * hperh)422 ald_status_t ald_nor_erase_chip(nor_handle_t *hperh)
423 {
424 	uint32_t devaddr = 0;
425 
426 	__LOCK(hperh);
427 
428 	if (hperh->state == ALD_NOR_STATE_BUSY)
429 		return BUSY;
430 
431 	/* Select the NOR device address */
432 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
433 		devaddr = NOR_MEMORY_ADRESS1;
434 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
435 		devaddr = NOR_MEMORY_ADRESS2;
436 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
437 		devaddr = NOR_MEMORY_ADRESS3;
438 	else
439 		devaddr = NOR_MEMORY_ADRESS4;
440 
441 	hperh->state = ALD_NOR_STATE_BUSY;
442 
443 	/* Send NOR chip erase command sequence */
444 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
445 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
446 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
447 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
448 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
449 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
450 
451 	hperh->state = ALD_NOR_STATE_READY;
452 	__UNLOCK(hperh);
453 
454 	return OK;
455 }
456 
457 /**
458   * @brief  Read NOR flash CFI IDs
459   * @param  hperh: pointer to a nor_handle_t structure
460   * @param  cfi: pointer to NOR CFI IDs structure
461   * @retval ald status
462   */
ald_nor_read_cfi(nor_handle_t * hperh,nor_cfi_t * cfi)463 ald_status_t ald_nor_read_cfi(nor_handle_t *hperh, nor_cfi_t *cfi)
464 {
465 	uint32_t devaddr = 0;
466 
467 	__LOCK(hperh);
468 
469 	if (hperh->state == ALD_NOR_STATE_BUSY)
470 		return BUSY;
471 
472 	/* Select the NOR device address */
473 	if (hperh->init.bank == EBI_NORSRAM_BANK1)
474 		devaddr = NOR_MEMORY_ADRESS1;
475 	else if (hperh->init.bank == EBI_NORSRAM_BANK2)
476 		devaddr = NOR_MEMORY_ADRESS2;
477 	else if (hperh->init.bank == EBI_NORSRAM_BANK3)
478 		devaddr = NOR_MEMORY_ADRESS3;
479 	else
480 		devaddr = NOR_MEMORY_ADRESS4;
481 
482 	hperh->state = ALD_NOR_STATE_BUSY;
483 	NOR_WRITE(NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
484 
485 	cfi->cfi_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, CFI1_ADDRESS);
486 	cfi->cfi_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, CFI2_ADDRESS);
487 	cfi->cfi_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, CFI3_ADDRESS);
488 	cfi->cfi_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(devaddr, NORMEMDATWIDTH, CFI4_ADDRESS);
489 
490 	hperh->state = ALD_NOR_STATE_READY;
491 	__UNLOCK(hperh);
492 
493 	return OK;
494 }
495 /**
496   * @}
497   */
498 
499 /** @defgroup NOR_LCD_Public_Functions_Group3 Control functions
500   * @brief NOR_LCD Control functions
501   * @{
502   */
503 /**
504   * @brief  Enables dynamically NOR write operation.
505   * @param  hperh: pointer to a nor_handle_t structure
506   * @retval ald status
507   */
ald_nor_write_enable(nor_handle_t * hperh)508 ald_status_t ald_nor_write_enable(nor_handle_t *hperh)
509 {
510 	__LOCK(hperh);
511 	/* Enable write operation */
512 	ald_ebi_nor_sram_write_enable(hperh->instance, hperh->init.bank);
513 	hperh->state = ALD_NOR_STATE_READY;
514 	__UNLOCK(hperh);
515 
516 	return OK;
517 }
518 
519 /**
520   * @brief  Disables dynamically NOR write operation.
521   * @param  hperh: pointer to a nor_handle_t structure
522   * @retval ald status
523   */
ald_nor_write_disable(nor_handle_t * hperh)524 ald_status_t ald_nor_write_disable(nor_handle_t *hperh)
525 {
526 	__LOCK(hperh);
527 	hperh->state = ALD_NOR_STATE_BUSY;
528 	/* Disable write operation */
529 	ald_ebi_nor_sram_write_disable(hperh->instance, hperh->init.bank);
530 	hperh->state = ALD_NOR_STATE_PROTECTED;
531 	__UNLOCK(hperh);
532 
533 	return OK;
534 }
535 /**
536   * @}
537   */
538 
539 /** @defgroup NOR_LCD_Public_Functions_Group4 State functions
540   * @brief NOR_LCD State functions
541   * @{
542   */
543 /**
544   * @brief  return the NOR controller state
545   * @param  hperh: pointer to a nor_handle_t structure
546   * @retval nor controller state
547   */
ald_nor_get_state(nor_handle_t * hperh)548 ald_nor_state_t ald_nor_get_state(nor_handle_t *hperh)
549 {
550 	return hperh->state;
551 }
552 
553 /**
554   * @brief  Returns the NOR operation status.
555   * @param  hperh: pointer to a nor_handle_t structure
556   * @param  addr: device address
557   * @param  timeout: nor progamming timeout
558   * @retval nor status
559   */
ald_nor_get_status(nor_handle_t * hperh,uint32_t addr,uint32_t timeout)560 nor_status_t ald_nor_get_status(nor_handle_t *hperh, uint32_t addr, uint32_t timeout)
561 {
562 	nor_status_t status = ALD_NOR_STATUS_ONGOING;
563 	uint16_t tmp_sr1 = 0, tmp_sr2 = 0;
564 	uint32_t tickstart = 0;
565 
566 	/* Get tick */
567 	tickstart = ald_get_tick();
568 	while ((status != ALD_NOR_STATUS_SUCCESS) && (status != ALD_NOR_STATUS_TIMEOUT)) {
569 		/* Check for the Timeout */
570 		if (timeout != ALD_MAX_DELAY) {
571 			if ((timeout == 0) || ((ald_get_tick() - tickstart ) > timeout))
572 				status = ALD_NOR_STATUS_TIMEOUT;
573 		}
574 
575 		/* Read NOR status register (DQ6 and DQ5) */
576 		tmp_sr1 = *(__IO uint16_t *)addr;
577 		tmp_sr2 = *(__IO uint16_t *)addr;
578 
579 		/* If DQ6 did not toggle between the two reads then return NOR_Success */
580 		if ((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
581 			return ALD_NOR_STATUS_SUCCESS;
582 
583 		if ((tmp_sr1 & NOR_MASK_STATUS_DQ5) != NOR_MASK_STATUS_DQ5)
584 			status = ALD_NOR_STATUS_ONGOING;
585 
586 		tmp_sr1 = *(__IO uint16_t *)addr;
587 		tmp_sr2 = *(__IO uint16_t *)addr;
588 
589 		/* If DQ6 did not toggle between the two reads then return NOR_Success */
590 		if ((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
591 			return ALD_NOR_STATUS_SUCCESS;
592 		else if ((tmp_sr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
593 			return ALD_NOR_STATUS_ERROR;
594 	}
595 
596 	return status;
597 }
598 /**
599   * @}
600   */
601 /**
602   * @}
603   */
604 #endif
605 /**
606   * @}
607   */
608 /**
609   * @}
610   */
611