lx_nand_flash_256byte_ecc_compute.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************************************************** | ||
| 2 | * Copyright (c) 2024 Microsoft Corporation | ||
| 3 | * Copyright (c) 2026-present Eclipse ThreadX contributors | ||
| 4 | * | ||
| 5 | * This program and the accompanying materials are made available under the | ||
| 6 | * terms of the MIT License which is available at | ||
| 7 | * https://opensource.org/licenses/MIT. | ||
| 8 | * | ||
| 9 | * SPDX-License-Identifier: MIT | ||
| 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_256byte_ecc_compute PORTABLE C */ | ||
| 43 | /* 6.2.1 */ | ||
| 44 | /* AUTHOR */ | ||
| 45 | /* */ | ||
| 46 | /* William E. Lamie, Microsoft Corporation */ | ||
| 47 | /* */ | ||
| 48 | /* DESCRIPTION */ | ||
| 49 | /* */ | ||
| 50 | /* This function computes the ECC for 256 bytes of a NAND flash page. */ | ||
| 51 | /* The resulting ECC code is returned in 3 bytes. */ | ||
| 52 | /* */ | ||
| 53 | /* INPUT */ | ||
| 54 | /* */ | ||
| 55 | /* page_buffer Page buffer */ | ||
| 56 | /* ecc_buffer Returned ECC buffer */ | ||
| 57 | /* */ | ||
| 58 | /* OUTPUT */ | ||
| 59 | /* */ | ||
| 60 | /* return status */ | ||
| 61 | /* */ | ||
| 62 | /* CALLS */ | ||
| 63 | /* */ | ||
| 64 | /* None */ | ||
| 65 | /* */ | ||
| 66 | /* CALLED BY */ | ||
| 67 | /* */ | ||
| 68 | /* _lx_nand_flash_page_ecc_compute NAND page ECC compute */ | ||
| 69 | /* _lx_nand_flash_256byte_ecc_check Check 256 bytes and ECC */ | ||
| 70 | /* */ | ||
| 71 | /**************************************************************************/ | ||
| 72 | 13924190 | UINT _lx_nand_flash_256byte_ecc_compute(UCHAR *page_buffer, UCHAR *ecc_buffer) | |
| 73 | { | ||
| 74 | |||
| 75 | USHORT i, j; | ||
| 76 | USHORT *data; | ||
| 77 | USHORT bits, mask; | ||
| 78 | USHORT bit_parity; | ||
| 79 | USHORT even_bit_parity; | ||
| 80 | USHORT odd_bit_parity; | ||
| 81 | USHORT even_byte_parity; | ||
| 82 | USHORT odd_byte_parity; | ||
| 83 | |||
| 84 | |||
| 85 | /* Initialize local variables. */ | ||
| 86 | 13924190 | bit_parity = 0; | |
| 87 | 13924190 | even_bit_parity = 0; | |
| 88 | 13924190 | odd_bit_parity = 0; | |
| 89 | 13924190 | even_byte_parity = 0; | |
| 90 | 13924190 | odd_byte_parity = 0; | |
| 91 | |||
| 92 | /* Initialize the return ECC code area. */ | ||
| 93 | 13924190 | ecc_buffer[0]= 0; | |
| 94 | 13924190 | ecc_buffer[1]= 0; | |
| 95 | 13924190 | ecc_buffer[2]= 0; | |
| 96 | |||
| 97 | /* Setup a 16-bit pointer to the buffer area. */ | ||
| 98 | 13924190 | data = (USHORT *) page_buffer; | |
| 99 | |||
| 100 | /* Loop through the 256 byte buffer, 16 bits at a time. */ | ||
| 101 |
2/2✓ Branch 11 → 3 taken 1782296320 times.
✓ Branch 11 → 12 taken 13924190 times.
|
1796220510 | for (i = 0; i < 128; i++) |
| 102 | { | ||
| 103 | |||
| 104 | /* Compute the ECC value. */ | ||
| 105 | 1782296320 | bit_parity = bit_parity ^ data[i]; | |
| 106 | |||
| 107 | /* Now count the bits in the current data word. */ | ||
| 108 | 1782296320 | bits = 0; | |
| 109 | 1782296320 | mask = 1; | |
| 110 |
2/2✓ Branch 7 → 4 taken 28516741120 times.
✓ Branch 7 → 8 taken 1782296320 times.
|
30299037440 | for (j = 0; j < 16; j++) |
| 111 | { | ||
| 112 | |||
| 113 | /* Is the bit set? */ | ||
| 114 |
2/2✓ Branch 4 → 5 taken 27895621390 times.
✓ Branch 4 → 6 taken 621119730 times.
|
28516741120 | if (data[i] & mask) |
| 115 | { | ||
| 116 | |||
| 117 | /* Yes, increment the bit count. */ | ||
| 118 | 27895621390 | bits++; | |
| 119 | } | ||
| 120 | |||
| 121 | /* Move the mask to the next bit. */ | ||
| 122 | 28516741120 | mask = (USHORT) ((mask << 1) & 0xFFFF); | |
| 123 | } | ||
| 124 | |||
| 125 | /* Determine if the number of bits is odd. */ | ||
| 126 |
2/2✓ Branch 8 → 9 taken 31550850 times.
✓ Branch 8 → 10 taken 1750745470 times.
|
1782296320 | if ((bits & 1) == 1) |
| 127 | { | ||
| 128 | |||
| 129 | /* Odd number of bits. Adjust the odd/even byte parity. */ | ||
| 130 | 31550850 | even_byte_parity = (USHORT) ((even_byte_parity ^ (0xffff - i)) & 0xFFFF); | |
| 131 | 31550850 | odd_byte_parity = odd_byte_parity ^ i; | |
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | /* Now look for bits set in the bit parity. */ | ||
| 136 |
2/2✓ Branch 16 → 13 taken 222787040 times.
✓ Branch 16 → 17 taken 13924190 times.
|
236711230 | for (i = 0; i < 16; i++) |
| 137 | { | ||
| 138 | |||
| 139 | /* Is the bit set? */ | ||
| 140 |
2/2✓ Branch 13 → 14 taken 57774750 times.
✓ Branch 13 → 15 taken 165012290 times.
|
222787040 | if (bit_parity & 1) |
| 141 | { | ||
| 142 | |||
| 143 | /* Yes, adjust the odd even byte parity. */ | ||
| 144 | 57774750 | even_bit_parity = (USHORT) ((even_bit_parity ^ (15 - i)) & 0xFFFF); | |
| 145 | 57774750 | odd_bit_parity = odd_bit_parity ^ i; | |
| 146 | } | ||
| 147 | |||
| 148 | /* Look at next bit position. */ | ||
| 149 | 222787040 | bit_parity = bit_parity >> 1; | |
| 150 | } | ||
| 151 | |||
| 152 | /* At this point, we need to pack the 22 ECC bits into the 3 byte return area. */ | ||
| 153 | |||
| 154 | /* Pack bit 21. */ | ||
| 155 | 13924190 | ecc_buffer[(21+2)/8] = ((UCHAR)(ecc_buffer[(21+2)/8] | ((odd_byte_parity >> 6) & 1) << (21+2)%8) & 0xFF); | |
| 156 | |||
| 157 | /* Pack bit 20. */ | ||
| 158 | 13924190 | ecc_buffer[(20+2)/8] = ((UCHAR)(ecc_buffer[(20+2)/8] | ((even_byte_parity >> 6) & 1) << (20+2)%8) & 0xFF); | |
| 159 | |||
| 160 | /* Pack bit 19. */ | ||
| 161 | 13924190 | ecc_buffer[(19+2)/8] = ((UCHAR)(ecc_buffer[(19+2)/8] | ((odd_byte_parity >> 5) & 1) << (19+2)%8) & 0xFF); | |
| 162 | |||
| 163 | /* Pack bit 18. */ | ||
| 164 | 13924190 | ecc_buffer[(18+2)/8] = ((UCHAR)(ecc_buffer[(18+2)/8] | ((even_byte_parity >> 5) & 1) << (18+2)%8) & 0xFF); | |
| 165 | |||
| 166 | /* Pack bit 17. */ | ||
| 167 | 13924190 | ecc_buffer[(17+2)/8] = ((UCHAR)(ecc_buffer[(17+2)/8] | ((odd_byte_parity >> 4) & 1) << (17+2)%8) & 0xFF); | |
| 168 | |||
| 169 | /* Pack bit 16. */ | ||
| 170 | 13924190 | ecc_buffer[(16+2)/8] = ((UCHAR)(ecc_buffer[(16+2)/8] | ((even_byte_parity >> 4) & 1) << (16+2)%8) & 0xFF); | |
| 171 | |||
| 172 | /* Pack bit 15. */ | ||
| 173 | 13924190 | ecc_buffer[(15+2)/8] = ((UCHAR)(ecc_buffer[(15+2)/8] | ((odd_byte_parity >> 3) & 1) << (15+2)%8) & 0xFF); | |
| 174 | |||
| 175 | /* Pack bit 14. */ | ||
| 176 | 13924190 | ecc_buffer[(14+2)/8] = ((UCHAR)(ecc_buffer[(14+2)/8] | ((even_byte_parity >> 3) & 1) << (14+2)%8) & 0xFF); | |
| 177 | |||
| 178 | /* Pack bit 13. */ | ||
| 179 | 13924190 | ecc_buffer[(13+2)/8] = ((UCHAR)(ecc_buffer[(13+2)/8] | ((odd_byte_parity >> 2) & 1) << (13+2)%8) & 0xFF); | |
| 180 | |||
| 181 | /* Pack bit 12. */ | ||
| 182 | 13924190 | ecc_buffer[(12+2)/8] = ((UCHAR)(ecc_buffer[(12+2)/8] | ((even_byte_parity >> 2) & 1) << (12+2)%8) & 0xFF); | |
| 183 | |||
| 184 | /* Pack bit 11. */ | ||
| 185 | 13924190 | ecc_buffer[(11+2)/8] = ((UCHAR)(ecc_buffer[(11+2)/8] | ((odd_byte_parity >> 1) & 1) << (11+2)%8) & 0xFF); | |
| 186 | |||
| 187 | /* Pack bit 10. */ | ||
| 188 | 13924190 | ecc_buffer[(10+2)/8] = ((UCHAR)(ecc_buffer[(10+2)/8] | ((even_byte_parity >> 1) & 1) << (10+2)%8) & 0xFF); | |
| 189 | |||
| 190 | /* Pack bit 9. */ | ||
| 191 | 13924190 | ecc_buffer[(9+2)/8] = ((UCHAR)(ecc_buffer[(9+2)/8] | ((odd_byte_parity >> 0) & 1) << (9+2)%8) & 0xFF); | |
| 192 | |||
| 193 | /* Pack bit 8. */ | ||
| 194 | 13924190 | ecc_buffer[(8+2)/8] = ((UCHAR)(ecc_buffer[(8+2)/8] | ((even_byte_parity >> 0) & 1) << (8+2)%8) & 0xFF); | |
| 195 | |||
| 196 | /* Pack bit 7. */ | ||
| 197 | 13924190 | ecc_buffer[(7+2)/8] = ((UCHAR)(ecc_buffer[(7+2)/8] | ((odd_bit_parity >> 3) & 1) << (7+2)%8) & 0xFF); | |
| 198 | |||
| 199 | /* Pack bit 6. */ | ||
| 200 | 13924190 | ecc_buffer[(6+2)/8] = ((UCHAR)(ecc_buffer[(6+2)/8] | ((even_bit_parity >> 3) & 1) << (6+2)%8) & 0xFF); | |
| 201 | |||
| 202 | /* Pack bit 5. */ | ||
| 203 | 13924190 | ecc_buffer[(5+2)/8] = ((UCHAR)(ecc_buffer[(5+2)/8] | ((odd_bit_parity >> 2) & 1) << (5+2)%8) & 0xFF); | |
| 204 | |||
| 205 | /* Pack bit 4. */ | ||
| 206 | 13924190 | ecc_buffer[(4+2)/8] = ((UCHAR)(ecc_buffer[(4+2)/8] | ((even_bit_parity >> 2) & 1) << (4+2)%8) & 0xFF); | |
| 207 | |||
| 208 | /* Pack bit 3. */ | ||
| 209 | 13924190 | ecc_buffer[(3+2)/8] = ((UCHAR)(ecc_buffer[(3+2)/8] | ((odd_bit_parity >> 1) & 1) << (3+2)%8) & 0xFF); | |
| 210 | |||
| 211 | /* Pack bit 2. */ | ||
| 212 | 13924190 | ecc_buffer[(2+2)/8] = ((UCHAR)(ecc_buffer[(2+2)/8] | ((even_bit_parity >> 1) & 1) << (2+2)%8) & 0xFF); | |
| 213 | |||
| 214 | /* Pack bit 1. */ | ||
| 215 | 13924190 | ecc_buffer[(1+2)/8] = ((UCHAR)(ecc_buffer[(1+2)/8] | ((odd_bit_parity >> 0) & 1) << (1+2)%8) & 0xFF); | |
| 216 | |||
| 217 | /* Pack bit 0. */ | ||
| 218 | 13924190 | ecc_buffer[(0+2)/8] = ((UCHAR)(ecc_buffer[(0+2)/8] | ((even_bit_parity >> 0) & 1) << (0+2)%8) & 0xFF); | |
| 219 | |||
| 220 | 13924190 | ecc_buffer[0] = (UCHAR)~ecc_buffer[0]; | |
| 221 | 13924190 | ecc_buffer[1] = (UCHAR)~ecc_buffer[1]; | |
| 222 | 13924190 | ecc_buffer[2] = (UCHAR)~ecc_buffer[2]; | |
| 223 | |||
| 224 | /* Return success! */ | ||
| 225 | 13924190 | return(LX_SUCCESS); | |
| 226 | } | ||
| 227 | |||
| 228 |