1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** LevelX Component */
17 /** */
18 /** NAND Flash */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define LX_SOURCE_CODE
24
25
26 /* Disable ThreadX error checking. */
27
28 #ifndef LX_DISABLE_ERROR_CHECKING
29 #define LX_DISABLE_ERROR_CHECKING
30 #endif
31
32
33 /* Include necessary system files. */
34
35 #include "lx_api.h"
36
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _lx_nand_flash_metadata_write PORTABLE C */
43 /* 6.2.1 */
44 /* AUTHOR */
45 /* */
46 /* Xiuwen Cai, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function writes metadata pages into current metadata block and */
51 /* allocates new blocks for metadata. */
52 /* */
53 /* INPUT */
54 /* */
55 /* nand_flash NAND flash instance */
56 /* main_buffer Main page buffer */
57 /* spare_value Value for spare bytes */
58 /* */
59 /* OUTPUT */
60 /* */
61 /* return status */
62 /* */
63 /* CALLS */
64 /* */
65 /* lx_nand_flash_driver_pages_write Driver pages write */
66 /* _lx_nand_flash_metadata_allocate Allocate blocks for metadata */
67 /* _lx_nand_flash_system_error Internal system error handler */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* Internal LevelX */
72 /* */
73 /* RELEASE HISTORY */
74 /* */
75 /* DATE NAME DESCRIPTION */
76 /* */
77 /* 03-08-2023 Xiuwen Cai Initial Version 6.2.1 */
78 /* */
79 /**************************************************************************/
_lx_nand_flash_metadata_write(LX_NAND_FLASH * nand_flash,UCHAR * main_buffer,ULONG spare_value)80 UINT _lx_nand_flash_metadata_write(LX_NAND_FLASH *nand_flash, UCHAR* main_buffer, ULONG spare_value)
81 {
82
83 ULONG block;
84 ULONG page;
85 UINT status;
86 UCHAR *spare_buffer_ptr;
87
88
89 /* Setup spare buffer pointer. */
90 spare_buffer_ptr = nand_flash -> lx_nand_flash_page_buffer + nand_flash -> lx_nand_flash_bytes_per_page;
91
92 /* Initialize the spare buffer. */
93 LX_MEMSET(spare_buffer_ptr, 0xFF, nand_flash -> lx_nand_flash_spare_total_length);
94
95 /* Check if there is enough spare data for metadata block number. */
96 if (nand_flash -> lx_nand_flash_spare_data2_length >= 2)
97 {
98
99 /* Save metadata block number in spare bytes. */
100 LX_UTILITY_SHORT_SET(&spare_buffer_ptr[nand_flash -> lx_nand_flash_spare_data2_offset], nand_flash -> lx_nand_flash_metadata_block_number);
101 }
102
103 /* Save metadata type data in spare bytes. */
104 LX_UTILITY_LONG_SET(&spare_buffer_ptr[nand_flash -> lx_nand_flash_spare_data1_offset], spare_value);
105
106 /* Get current metadata block number. */
107 block = nand_flash -> lx_nand_flash_metadata_block_number_current;
108
109 /* Get current metadata page number. */
110 page = nand_flash -> lx_nand_flash_metadata_block_current_page;
111
112 /* Write the page. */
113 #ifdef LX_NAND_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
114 status = (nand_flash -> lx_nand_flash_driver_pages_write)(nand_flash, block, page, main_buffer, spare_buffer_ptr, 1);
115 #else
116 status = (nand_flash -> lx_nand_flash_driver_pages_write)(block, page, main_buffer, spare_buffer_ptr, 1);
117 #endif
118
119 /* Check for an error from flash driver. */
120 if (status)
121 {
122
123 /* Call system error handler. */
124 _lx_nand_flash_system_error(nand_flash, status, block, 0);
125
126 /* Return an error. */
127 return(status);
128 }
129
130 /* Increase current page for metadata block. */
131 nand_flash -> lx_nand_flash_metadata_block_current_page++;
132
133 /* Get current backup metadata block number. */
134 block = nand_flash -> lx_nand_flash_backup_metadata_block_number_current;
135
136 /* Get current backup metadata page number. */
137 page = nand_flash -> lx_nand_flash_backup_metadata_block_current_page;
138
139 /* Write the page. */
140 #ifdef LX_NAND_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
141 status = (nand_flash -> lx_nand_flash_driver_pages_write)(nand_flash, block, page, main_buffer, spare_buffer_ptr, 1);
142 #else
143 status = (nand_flash -> lx_nand_flash_driver_pages_write)(block, page, main_buffer, spare_buffer_ptr, 1);
144 #endif
145
146 /* Check for an error from flash driver. */
147 if (status)
148 {
149
150 /* Call system error handler. */
151 _lx_nand_flash_system_error(nand_flash, status, block, 0);
152
153 /* Return an error. */
154 return(status);
155 }
156
157 /* Increase current page for backup metadata block. */
158 nand_flash -> lx_nand_flash_backup_metadata_block_current_page++;
159
160 /* Allocate new block for metadata if necessary. */
161 _lx_nand_flash_metadata_allocate(nand_flash);
162
163 /* Return sector not found status. */
164 return(status);
165 }
166
167