Skip to content

Commit 06c931d

Browse files
committed
Use dedicated command to read spare area
1 parent c1360c6 commit 06c931d

File tree

9 files changed

+115
-17
lines changed

9 files changed

+115
-17
lines changed

firmware/chip_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ typedef struct
2222
uint8_t col_cycles;
2323
uint8_t read1_cmd;
2424
uint8_t read2_cmd;
25+
uint8_t read_spare_cmd;
2526
uint8_t read_id_cmd;
2627
uint8_t reset_cmd;
2728
uint8_t write1_cmd;

firmware/fsmc_nand.c

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
#define ROW_ADDRESS (addr.page + (addr.block + (addr.zone * NAND_ZONE_SIZE)) * \
1313
NAND_BLOCK_SIZE)
1414

15+
#define UNDEFINED_CMD 0xFF
16+
1517
typedef struct
1618
{
1719
uint8_t row_cycles;
1820
uint8_t col_cycles;
1921
uint8_t read1_cmd;
2022
uint8_t read2_cmd;
23+
uint8_t read_spare_cmd;
2124
uint8_t read_id_cmd;
2225
uint8_t reset_cmd;
2326
uint8_t write1_cmd;
@@ -93,6 +96,7 @@ static void nand_cmd_init(chip_info_t *chip_info)
9396
fsmc_cmd.col_cycles = chip_info->col_cycles;
9497
fsmc_cmd.read1_cmd = chip_info->read1_cmd;
9598
fsmc_cmd.read2_cmd = chip_info->read2_cmd;
99+
fsmc_cmd.read_spare_cmd = chip_info->read_spare_cmd;
96100
fsmc_cmd.read_id_cmd = chip_info->read_id_cmd;
97101
fsmc_cmd.reset_cmd = chip_info->reset_cmd;
98102
fsmc_cmd.write1_cmd = chip_info->write1_cmd;
@@ -183,7 +187,7 @@ void nand_write_page_async(uint8_t *buf, uint32_t page, uint32_t page_size)
183187
for(i = 0; i < page_size; i++)
184188
*(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = buf[i];
185189

186-
if (fsmc_cmd.write2_cmd != 0xFF)
190+
if (fsmc_cmd.write2_cmd != UNDEFINED_CMD)
187191
*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = fsmc_cmd.write2_cmd;
188192
}
189193

@@ -258,7 +262,7 @@ uint32_t nand_read_data(uint8_t *buf, uint32_t page, uint32_t page_offset,
258262
break;
259263
}
260264

261-
if (fsmc_cmd.read2_cmd != 0xFF)
265+
if (fsmc_cmd.read2_cmd != UNDEFINED_CMD)
262266
*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = fsmc_cmd.read2_cmd;
263267

264268
for (i = 0; i < data_size; i++)
@@ -272,6 +276,79 @@ uint32_t nand_read_page(uint8_t *buf, uint32_t page, uint32_t page_size)
272276
return nand_read_data(buf, page, 0, page_size);
273277
}
274278

279+
uint32_t nand_read_spare_data(uint8_t *buf, uint32_t page, uint32_t offset,
280+
uint32_t data_size)
281+
{
282+
uint32_t i;
283+
284+
if (fsmc_cmd.read_spare_cmd == UNDEFINED_CMD)
285+
return NAND_INVALID_CMD;
286+
287+
*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = fsmc_cmd.read_spare_cmd;
288+
289+
switch (fsmc_cmd.col_cycles)
290+
{
291+
case 1:
292+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
293+
ADDR_1st_CYCLE(offset);
294+
break;
295+
case 2:
296+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
297+
ADDR_1st_CYCLE(offset);
298+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
299+
ADDR_2nd_CYCLE(offset);
300+
break;
301+
case 3:
302+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
303+
ADDR_1st_CYCLE(offset);
304+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
305+
ADDR_2nd_CYCLE(offset);
306+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
307+
ADDR_3rd_CYCLE(offset);
308+
break;
309+
case 4:
310+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
311+
ADDR_1st_CYCLE(offset);
312+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
313+
ADDR_2nd_CYCLE(offset);
314+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
315+
ADDR_3rd_CYCLE(offset);
316+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) =
317+
ADDR_4th_CYCLE(offset);
318+
default:
319+
break;
320+
}
321+
322+
switch (fsmc_cmd.row_cycles)
323+
{
324+
case 1:
325+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(page);
326+
break;
327+
case 2:
328+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(page);
329+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(page);
330+
break;
331+
case 3:
332+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(page);
333+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(page);
334+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(page);
335+
break;
336+
case 4:
337+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(page);
338+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(page);
339+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(page);
340+
*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(page);
341+
break;
342+
default:
343+
break;
344+
}
345+
346+
for (i = 0; i < data_size; i++)
347+
buf[i] = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
348+
349+
return nand_get_status();
350+
}
351+
275352
#if 0
276353
/**
277354
* @brief This routine write the spare area information for the specified
@@ -421,7 +498,7 @@ uint32_t nand_erase_block(uint32_t page)
421498
break;
422499
}
423500

424-
if (fsmc_cmd.erase2_cmd != 0xFF)
501+
if (fsmc_cmd.erase2_cmd != UNDEFINED_CMD)
425502
*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = fsmc_cmd.erase2_cmd;
426503

427504
return nand_get_status();

firmware/fsmc_nand.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef struct
2525
#define NAND_VALID_ADDRESS ((uint32_t)0x00000100)
2626
#define NAND_INVALID_ADDRESS ((uint32_t)0x00000200)
2727
#define NAND_TIMEOUT_ERROR ((uint32_t)0x00000400)
28+
#define NAND_INVALID_CMD ((uint32_t)0x00000800)
2829
#define NAND_BUSY ((uint32_t)0x00000000)
2930
#define NAND_ERROR ((uint32_t)0x00000001)
3031
#define NAND_READY ((uint32_t)0x00000040)
@@ -42,6 +43,8 @@ void nand_write_page_async(uint8_t *buf, uint32_t page, uint32_t page_size);
4243
uint32_t nand_read_data(uint8_t *buf, uint32_t page, uint32_t page_offset,
4344
uint32_t data_size);
4445
uint32_t nand_read_page(uint8_t *buf, uint32_t page, uint32_t page_size);
46+
uint32_t nand_read_spare_data(uint8_t *buf, uint32_t page, uint32_t offset,
47+
uint32_t data_size);
4548
#if 0
4649
uint32_t nand_write_spare_area(uint8_t *buf, nand_addr_t addr,
4750
uint32_t num_spare_area_to_write);

firmware/nand_programmer.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ typedef struct __attribute__((__packed__))
119119
uint8_t col_cycles;
120120
uint8_t read1_cmd;
121121
uint8_t read2_cmd;
122+
uint8_t read_spare_cmd;
122123
uint8_t read_id_cmd;
123124
uint8_t reset_cmd;
124125
uint8_t write1_cmd;
@@ -323,8 +324,14 @@ static int np_read_bad_block_info_from_page(np_prog_t *prog, uint32_t block,
323324
{
324325
uint32_t status, addr = block * prog->chip_info.block_size;
325326

326-
status = nand_read_data(prog->page.buf, page, 0, prog->chip_info.page_size
327-
+ prog->chip_info.spare_size);
327+
status = nand_read_spare_data(prog->page.buf, page,
328+
prog->chip_info.bb_mark_off, 1);
329+
if (status == NAND_INVALID_CMD)
330+
{
331+
status = nand_read_data(prog->page.buf, page,
332+
prog->chip_info.bb_mark_off, 1);
333+
}
334+
328335
switch (status)
329336
{
330337
case NAND_READY:
@@ -340,8 +347,7 @@ static int np_read_bad_block_info_from_page(np_prog_t *prog, uint32_t block,
340347
return NP_ERR_NAND_RD;
341348
}
342349

343-
*is_bad = prog->page.buf[prog->chip_info.page_size +
344-
prog->chip_info.bb_mark_off] != NP_NAND_GOOD_BLOCK_MARK;
350+
*is_bad = prog->page.buf[0] != NP_NAND_GOOD_BLOCK_MARK;
345351

346352
return 0;
347353
}
@@ -994,6 +1000,7 @@ static void np_fill_chip_info(np_conf_cmd_t *conf_cmd, np_prog_t *prog)
9941000
prog->chip_info.col_cycles = conf_cmd->col_cycles;
9951001
prog->chip_info.read1_cmd = conf_cmd->read1_cmd;
9961002
prog->chip_info.read2_cmd = conf_cmd->read2_cmd;
1003+
prog->chip_info.read_spare_cmd = conf_cmd->read_spare_cmd;
9971004
prog->chip_info.read_id_cmd = conf_cmd->read_id_cmd;
9981005
prog->chip_info.reset_cmd = conf_cmd->reset_cmd;
9991006
prog->chip_info.write1_cmd = conf_cmd->write1_cmd;
@@ -1021,6 +1028,7 @@ static void np_print_chip_info(np_prog_t *prog)
10211028
DEBUG_PRINT("Col. cycles: %d\r\n", prog->chip_info.col_cycles);
10221029
DEBUG_PRINT("Read command 1: %d\r\n", prog->chip_info.read1_cmd);
10231030
DEBUG_PRINT("Read command 2: %d\r\n", prog->chip_info.read2_cmd);
1031+
DEBUG_PRINT("Read spare command: %d\r\n", prog->chip_info.read_spare_cmd);
10241032
DEBUG_PRINT("Read ID command: %d\r\n", prog->chip_info.read_id_cmd);
10251033
DEBUG_PRINT("Reset command: %d\r\n", prog->chip_info.reset_cmd);
10261034
DEBUG_PRINT("Write 1 command: %d\r\n", prog->chip_info.write1_cmd);

qt/chip_db.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum
4444
CHIP_PARAM_COL_CYCLES,
4545
CHIP_PARAM_READ1_CMD,
4646
CHIP_PARAM_READ2_CMD,
47+
CHIP_PARAM_READ_SPARE_CMD,
4748
CHIP_PARAM_READ_ID_CMD,
4849
CHIP_PARAM_RESET_CMD,
4950
CHIP_PARAM_WRITE1_CMD,

qt/chip_db_table_model.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ QVariant ChipDbTableModel::data(const QModelIndex &index, int role) const
6868
paramStr);
6969
return paramStr;
7070
case CHIP_PARAM_READ2_CMD:
71+
case CHIP_PARAM_READ_SPARE_CMD:
7172
case CHIP_PARAM_WRITE2_CMD:
7273
case CHIP_PARAM_ERASE2_CMD:
7374
chipDb->getHexStringFromOptParam(chipDb->getChipParam(index.row(),
@@ -108,6 +109,7 @@ QVariant ChipDbTableModel::headerData(int section, Qt::Orientation orientation,
108109
case CHIP_PARAM_COL_CYCLES: return tr("Col. cycles");
109110
case CHIP_PARAM_READ1_CMD: return tr("Read 1 com.");
110111
case CHIP_PARAM_READ2_CMD: return tr("Read 2 com.");
112+
case CHIP_PARAM_READ_SPARE_CMD: return tr("Read spr. com.");
111113
case CHIP_PARAM_READ_ID_CMD: return tr("Read ID com.");
112114
case CHIP_PARAM_RESET_CMD: return tr("Reset com.");
113115
case CHIP_PARAM_WRITE1_CMD: return tr("Write 1 com.");
@@ -168,21 +170,23 @@ QVariant ChipDbTableModel::headerData(int section, Qt::Orientation orientation,
168170
return tr("Number of cycles required for addresing column "
169171
"(page offset) during read/write operation");
170172
case CHIP_PARAM_READ1_CMD:
171-
return tr("Read 1 command");
173+
return tr("Read 1 cycle command");
172174
case CHIP_PARAM_READ2_CMD:
173-
return tr("Read 2 command");
175+
return tr("Read 2 cycle command");
176+
case CHIP_PARAM_READ_SPARE_CMD:
177+
return tr("Read spare area command");
174178
case CHIP_PARAM_READ_ID_CMD:
175179
return tr("Read ID command");
176180
case CHIP_PARAM_RESET_CMD:
177181
return tr("Reset command");
178182
case CHIP_PARAM_WRITE1_CMD:
179-
return tr("Write 1 command");
183+
return tr("Write 1 cycle command");
180184
case CHIP_PARAM_WRITE2_CMD:
181-
return tr("Write 2 command");
185+
return tr("Write 2 cycle command");
182186
case CHIP_PARAM_ERASE1_CMD:
183-
return tr("Erase 1 command");
187+
return tr("Erase 1 cycle command");
184188
case CHIP_PARAM_ERASE2_CMD:
185-
return tr("Erase 2 command");
189+
return tr("Erase 2 cycle command");
186190
case CHIP_PARAM_STATUS_CMD:
187191
return tr("Status command");
188192
case CHIP_PARAM_BB_MARK_OFF:
@@ -262,6 +266,7 @@ bool ChipDbTableModel::setData(const QModelIndex &index, const QVariant &value,
262266
chipDb->setChipParam(index.row(), index.column(), paramVal);
263267
return true;
264268
case CHIP_PARAM_READ2_CMD:
269+
case CHIP_PARAM_READ_SPARE_CMD:
265270
case CHIP_PARAM_WRITE2_CMD:
266271
case CHIP_PARAM_ERASE2_CMD:
267272
if (chipDb->getOptParamFromHexString(value.toString(), paramVal))

qt/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ typedef struct __attribute__((__packed__))
8080
uint8_t colCycles;
8181
uint8_t read1Cmd;
8282
uint8_t read2Cmd;
83+
uint8_t readSpareCmd;
8384
uint8_t readIdCmd;
8485
uint8_t resetCmd;
8586
uint8_t write1Cmd;

qt/nando_chip_db.csv

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# name, page size, block size, total size, spare size, tCS, tCLS, tALS, tCLR, tAR, tWP, tRP, tDS, tCH, tCLH, tALH, tWC, tRC, tREA, row cycles, col. cycles, read 1 com., read 2 com., read ID com., reset com., write 1 com., write 2 com., erase 1 com., erase 2 com., status com., bad block mark off.
2-
K9F2G08U0C, 2048, 131072, 268435456, 64, 20, 12, 12, 10, 10, 12, 12, 12, 5, 5, 5, 25, 25, 20, 3, 2, 0, 48, 144, 255, 128, 16, 96, 208, 112, 0
3-
K9F1G08U0E, 2048, 131072, 134217728, 64, 20, 12, 12, 10, 10, 12, 12, 12, 5, 5, 5, 25, 25, 20, 3, 2, 0, 48, 144, 255, 128, 16, 96, 208, 112, 0
4-
HY27US08561A, 512, 16384, 33554432, 16, 0, 0, 0, 10, 10, 25, 25, 20, 10, 10, 10, 50, 50, 30, 2, 1, 0, -, 144, 255, 128, 16, 96, 208, 112, 5
1+
# name, page size, block size, total size, spare size, tCS, tCLS, tALS, tCLR, tAR, tWP, tRP, tDS, tCH, tCLH, tALH, tWC, tRC, tREA, row cycles, col. cycles, read 1 cycle com., read 2 cycle com., read spare com., read ID com., reset com., write 1 cycle com., write 2 cycle com., erase 1 cycle com., erase 2 cycle com., status com., bad block mark off.
2+
K9F2G08U0C, 2048, 131072, 268435456, 64, 20, 12, 12, 10, 10, 12, 12, 12, 5, 5, 5, 25, 25, 20, 3, 2, 0, 48, -, 144, 255, 128, 16, 96, 208, 112, 0
3+
K9F1G08U0E, 2048, 131072, 134217728, 64, 20, 12, 12, 10, 10, 12, 12, 12, 5, 5, 5, 25, 25, 20, 3, 2, 0, 48, -, 144, 255, 128, 16, 96, 208, 112, 0
4+
HY27US08561A, 512, 16384, 33554432, 16, 0, 0, 0, 10, 10, 25, 25, 20, 10, 10, 10, 50, 50, 30, 2, 1, 0, -, 80, 144, 255, 128, 16, 96, 208, 112, 5

qt/programmer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ void Programmer::confChip(ChipInfo *chipInfo)
321321
(chipInfo->params[CHIP_PARAM_READ1_CMD]);
322322
confCmd.read2Cmd = static_cast<uint8_t>
323323
(chipInfo->params[CHIP_PARAM_READ2_CMD]);
324+
confCmd.readSpareCmd = static_cast<uint8_t>
325+
(chipInfo->params[CHIP_PARAM_READ_SPARE_CMD]);
324326
confCmd.readIdCmd = static_cast<uint8_t>
325327
(chipInfo->params[CHIP_PARAM_READ_ID_CMD]);
326328
confCmd.resetCmd = static_cast<uint8_t>

0 commit comments

Comments
 (0)