GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nand_flash_256byte_ecc_check.c Lines: 11 35 31.4 %
Date: 2026-03-06 18:45:40 Branches: 4 12 33.3 %

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_check                    PORTABLE C      */
43
/*                                                           6.1.7        */
44
/*  AUTHOR                                                                */
45
/*                                                                        */
46
/*    William E. Lamie, Microsoft Corporation                             */
47
/*                                                                        */
48
/*  DESCRIPTION                                                           */
49
/*                                                                        */
50
/*    This function checks 256 bytes of a NAND flash and ECC and          */
51
/*    attempts to correct any single bit errors.                          */
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
/*    _lx_nand_flash_256byte_ecc_compute    Compute ECC for 256 bytes     */
65
/*                                                                        */
66
/*  CALLED BY                                                             */
67
/*                                                                        */
68
/*    _lx_nand_flash_page_ecc_check         NAND page check               */
69
/*                                                                        */
70
/**************************************************************************/
71
590564
UINT  _lx_nand_flash_256byte_ecc_check(UCHAR *page_buffer, UCHAR *ecc_buffer)
72
{
73
74
INT     i, j;
75
UCHAR   mask;
76
UCHAR   new_ecc_buffer[3];
77
UCHAR   ecc_errors[3];
78
INT     error_count;
79
USHORT  *data;
80
USHORT  byte;
81
USHORT  bit;
82
ULONG   correction_code;
83
84
85
    /* Clear the error count.  */
86
590564
    ecc_errors[0] = 0;
87
590564
    ecc_errors[1] = 0;
88
590564
    ecc_errors[2] = 0;
89
90
    /* Calculate a new ECC for the 256 byte buffer.  */
91
590564
    _lx_nand_flash_256byte_ecc_compute(page_buffer, new_ecc_buffer);
92
93
    /* Clear error count.  */
94
590564
    error_count =  0;
95
96
    /* Loop through the ECC bytes to determine if there is an error in the page.  */
97
2362256
    for (i = 0; i < 3; i++)
98
    {
99
100
        /* Check for differences in the ECCs.  */
101
1771692
        ecc_errors[i] =  new_ecc_buffer[i] ^ ecc_buffer[i];
102
103
        /* Are there any errors?  */
104
1771692
        if (ecc_errors[i])
105
        {
106
107
            /* Accumulate the count of set bits.  */
108
            mask = 1;
109
            for (j = 0; j < 8; j++)
110
            {
111
112
                /* Is this bit set?  */
113
                if (ecc_errors[i] & mask)
114
                {
115
116
                    /* Yes, increment the count.  */
117
                    error_count++;
118
                }
119
120
                /* Move mask to next bit.  */
121
                mask = (UCHAR) ((mask << 1) & 0xFF);
122
            }
123
        }
124
    }
125
126
    /* Determine if there are any errors.  */
127
590564
    if (error_count == 0)
128
    {
129
130
        /* Everything is okay, return success.  */
131
590564
        return(LX_SUCCESS);
132
    }
133
134
    /* Was a correctable error discovered?  */
135
    else if (error_count == 11)
136
    {
137
138
        /* Initialize bit and byte offset values.  */
139
        bit = 0;
140
        byte = 0;
141
142
        /* Setup the data pointer.  */
143
        data =  (USHORT *) page_buffer;
144
145
        /* Calculate the 32-bit correction code.  */
146
        correction_code = (ULONG) (ecc_errors[2] << 16) | (ULONG)(ecc_errors[1] << 8) | (ULONG)ecc_errors[0];
147
148
        /* Unpack the correction code.  */
149
        byte = (USHORT) ((byte | ((correction_code >> (21+2)) & 1) << 6) & 0xFFFF);
150
        byte = (USHORT) ((byte | ((correction_code >> (19+2)) & 1) << 5) & 0xFFFF);
151
        byte = (USHORT) ((byte | ((correction_code >> (17+2)) & 1) << 4) & 0xFFFF);
152
        byte = (USHORT) ((byte | ((correction_code >> (15+2)) & 1) << 3) & 0xFFFF);
153
        byte = (USHORT) ((byte | ((correction_code >> (13+2)) & 1) << 2) & 0xFFFF);
154
        byte = (USHORT) ((byte | ((correction_code >> (11+2)) & 1) << 1) & 0xFFFF);
155
        byte = (USHORT) ((byte | ((correction_code >> (9+2))  & 1) << 0) & 0xFFFF);
156
        bit  = (USHORT) ((bit | ((correction_code >> (7+2))  & 1) << 3) & 0xFFFF);
157
        bit  = (USHORT) ((bit | ((correction_code >> (5+2))  & 1) << 2) & 0xFFFF);
158
        bit  = (USHORT) ((bit | ((correction_code >> (3+2))  & 1) << 1) & 0xFFFF);
159
        bit  = (USHORT) ((bit | ((correction_code >> (1+2))  & 1) << 0) & 0xFFFF);
160
161
        /* Fix the error.  */
162
        data[byte] = (USHORT) ((data[byte] ^ (1 << bit)) & 0xFFFF);
163
164
        /* Return an error corrected status.  */
165
      return(LX_NAND_ERROR_CORRECTED);
166
    }
167
168
    /* Otherwise, an unrecoverable ECC or data error is present.  */
169
    else
170
    {
171
172
        /* Return an error.  */
173
        return(LX_NAND_ERROR_NOT_CORRECTED);
174
    }
175
}
176