source: rtems/bsps/arm/lpc32xx/nand/nand-mlc-write-blocks.c @ ba619b7f

Last change on this file since ba619b7f was ba619b7f, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 21:38:20

bsps/arm/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 2.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc32xx_nand_mlc
5 *
6 * @brief lpc32xx_mlc_write_blocks() implementation.
7 */
8
9/*
10 * Copyright (c) 2010-2011 embedded brains GmbH.  All rights reserved.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#include <bsp/nand-mlc.h>
18
19#include <string.h>
20
21static const uint32_t ones_spare [MLC_LARGE_SPARE_WORD_COUNT] = {
22  0xffffffff,
23  0xffffffff,
24  0xffffffff,
25  0xffffffff,
26  0xffffffff,
27  0xffffffff,
28  0xffffffff,
29  0xffffffff,
30  0xffffffff,
31  0xffffffff,
32  0xffffffff,
33  0xffffffff,
34  0xffffffff,
35  0xffffffff,
36  0xffffffff,
37  0xffffffff
38};
39
40rtems_status_code lpc32xx_mlc_write_blocks(
41  uint32_t block_begin,
42  uint32_t block_end,
43  const void *src,
44  size_t src_size,
45  uint32_t *page_data_buffer
46)
47{
48  rtems_status_code sc = RTEMS_SUCCESSFUL;
49  uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
50  uint32_t block_count = lpc32xx_mlc_block_count();
51  uint32_t page_size = lpc32xx_mlc_page_size();
52  uint32_t block = 0;
53  const uint8_t *current = src;
54  const uint8_t *last = current;
55  const uint8_t *end = current + src_size;
56
57  if (block_begin > block_end || block_end > block_count) {
58    return RTEMS_INVALID_ID;
59  }
60
61  for (block = block_begin; block != block_end; ++block) {
62    uint32_t page_begin = block * pages_per_block;
63    uint32_t page_end = page_begin + pages_per_block;
64    uint32_t page = 0;
65
66    sc = lpc32xx_mlc_erase_block_safe_3(block, page_begin, page_end);
67    if (sc != RTEMS_SUCCESSFUL) {
68      continue;
69    }
70
71    for (page = page_begin; page < page_end; ++page) {
72      uintptr_t remainder = (uintptr_t) end - (uintptr_t) current;
73      size_t delta = remainder < page_size ? remainder : page_size;
74
75      if (remainder > 0) {
76        memcpy(page_data_buffer, current, delta);
77        sc = lpc32xx_mlc_write_page_with_ecc(
78          page,
79          page_data_buffer,
80          ones_spare
81        );
82        if (sc != RTEMS_SUCCESSFUL) {
83          lpc32xx_mlc_erase_block(block);
84          lpc32xx_mlc_zero_pages(page_begin, page_end);
85          current = last;
86          continue;
87        }
88
89        current += delta;
90      } else {
91        goto done;
92      }
93    }
94
95    last = current;
96  }
97
98done:
99
100  if (current != end) {
101    return RTEMS_IO_ERROR;
102  }
103
104  return RTEMS_SUCCESSFUL;
105}
Note: See TracBrowser for help on using the repository browser.