source: rtems/c/src/lib/libbsp/arm/lpc32xx/misc/nand-mlc-write-blocks.c @ 03d2108

4.11
Last change on this file since 03d2108 was 03d2108, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 1, 2011 at 1:05:06 PM

2011-07-01 Stephan Hoffmann <sho@…>

Sebastian Huber <sebastian.huber@…>

  • misc/nand-mlc-erase-block-safe.c: New file
  • Makefile.am: Reflect change from above.
  • misc/nand-mlc-write-blocks.c: Use lpc32xx_mlc_erase_block_safe_3().
  • include/nand-mlc.h: Bad block handling.
  • Property mode set to 100644
File size: 2.4 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 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.com/license/LICENSE.
21 */
22
23#include <bsp/nand-mlc.h>
24
25static const uint32_t ones_spare [MLC_LARGE_SPARE_WORD_COUNT] = {
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  0xffffffff,
39  0xffffffff,
40  0xffffffff,
41  0xffffffff
42};
43
44rtems_status_code lpc32xx_mlc_write_blocks(
45  uint32_t block_begin,
46  uint32_t block_end,
47  const void *src,
48  size_t src_size,
49  uint32_t *page_data_buffer
50)
51{
52  rtems_status_code sc = RTEMS_SUCCESSFUL;
53  uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
54  uint32_t block_count = lpc32xx_mlc_block_count();
55  uint32_t page_size = lpc32xx_mlc_page_size();
56  uint32_t block = 0;
57  const uint8_t *current = src;
58  const uint8_t *last = current;
59  const uint8_t *end = current + src_size;
60
61  if (block_begin > block_end || block_end > block_count) {
62    return RTEMS_INVALID_ID;
63  }
64
65  for (block = block_begin; block != block_end; ++block) {
66    uint32_t first_page_of_block = block * pages_per_block;
67    uint32_t page = 0;
68
69    sc = lpc32xx_mlc_erase_block_safe_3(
70      block,
71      first_page_of_block,
72      pages_per_block
73    );
74    if (sc != RTEMS_SUCCESSFUL) {
75      continue;
76    }
77
78    for (page = 0; page < pages_per_block; ++page) {
79      uintptr_t remainder = (uintptr_t) end - (uintptr_t) current;
80      size_t delta = remainder < page_size ? remainder : page_size;
81
82      if (remainder > 0) {
83        memcpy(page_data_buffer, current, delta);
84        sc = lpc32xx_mlc_write_page_with_ecc(
85          first_page_of_block + page,
86          page_data_buffer,
87          ones_spare
88        );
89        if (sc != RTEMS_SUCCESSFUL) {
90          erase_block(block, first_page_of_block, pages_per_block);
91          zero_block(first_page_of_block, pages_per_block);
92          current = last;
93          continue;
94        }
95
96        current += delta;
97      } else {
98        goto done;
99      }
100    }
101
102    last = current;
103  }
104
105done:
106
107  if (current != end) {
108    return RTEMS_IO_ERROR;
109  }
110
111  return RTEMS_SUCCESSFUL;
112}
Note: See TracBrowser for help on using the repository browser.