File indexing completed on 2025-05-11 08:23:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp/nand-mlc.h>
0037
0038 #include <string.h>
0039
0040 static const uint32_t ones_spare [MLC_LARGE_SPARE_WORD_COUNT] = {
0041 0xffffffff,
0042 0xffffffff,
0043 0xffffffff,
0044 0xffffffff,
0045 0xffffffff,
0046 0xffffffff,
0047 0xffffffff,
0048 0xffffffff,
0049 0xffffffff,
0050 0xffffffff,
0051 0xffffffff,
0052 0xffffffff,
0053 0xffffffff,
0054 0xffffffff,
0055 0xffffffff,
0056 0xffffffff
0057 };
0058
0059 rtems_status_code lpc32xx_mlc_write_blocks(
0060 uint32_t block_begin,
0061 uint32_t block_end,
0062 const void *src,
0063 size_t src_size,
0064 uint32_t *page_data_buffer
0065 )
0066 {
0067 rtems_status_code sc = RTEMS_SUCCESSFUL;
0068 uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
0069 uint32_t block_count = lpc32xx_mlc_block_count();
0070 uint32_t page_size = lpc32xx_mlc_page_size();
0071 uint32_t block = 0;
0072 const uint8_t *current = src;
0073 const uint8_t *last = current;
0074 const uint8_t *end = current + src_size;
0075
0076 if (block_begin > block_end || block_end > block_count) {
0077 return RTEMS_INVALID_ID;
0078 }
0079
0080 for (block = block_begin; block != block_end; ++block) {
0081 uint32_t page_begin = block * pages_per_block;
0082 uint32_t page_end = page_begin + pages_per_block;
0083 uint32_t page = 0;
0084
0085 sc = lpc32xx_mlc_erase_block_safe_3(block, page_begin, page_end);
0086 if (sc != RTEMS_SUCCESSFUL) {
0087 continue;
0088 }
0089
0090 for (page = page_begin; page < page_end; ++page) {
0091 uintptr_t remainder = (uintptr_t) end - (uintptr_t) current;
0092 size_t delta = remainder < page_size ? remainder : page_size;
0093
0094 if (remainder > 0) {
0095 memcpy(page_data_buffer, current, delta);
0096 sc = lpc32xx_mlc_write_page_with_ecc(
0097 page,
0098 page_data_buffer,
0099 ones_spare
0100 );
0101 if (sc != RTEMS_SUCCESSFUL) {
0102 lpc32xx_mlc_erase_block(block);
0103 lpc32xx_mlc_zero_pages(page_begin, page_end);
0104 current = last;
0105 continue;
0106 }
0107
0108 current += delta;
0109 } else {
0110 goto done;
0111 }
0112 }
0113
0114 last = current;
0115 }
0116
0117 done:
0118
0119 if (current != end) {
0120 return RTEMS_IO_ERROR;
0121 }
0122
0123 return RTEMS_SUCCESSFUL;
0124 }