Skip to content

Commit ebba020

Browse files
committed
Implemented skip bad block functionality for read operation
1 parent f3e203b commit ebba020

File tree

7 files changed

+85
-47
lines changed

7 files changed

+85
-47
lines changed

firmware/nand_programmer.c

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ typedef struct __attribute__((__packed__))
9595
np_cmd_t cmd;
9696
uint32_t addr;
9797
uint32_t len;
98+
np_cmd_flags_t flags;
9899
} np_read_cmd_t;
99100

100101
typedef struct __attribute__((__packed__))
@@ -134,6 +135,7 @@ typedef struct __attribute__((__packed__))
134135
{
135136
np_resp_t header;
136137
uint32_t addr;
138+
uint32_t size;
137139
} np_resp_bad_block_t;
138140

139141
typedef struct __attribute__((__packed__))
@@ -208,10 +210,10 @@ static int np_send_error(uint8_t err_code)
208210
return 0;
209211
}
210212

211-
static int np_send_bad_block_info(uint32_t addr)
213+
static int np_send_bad_block_info(uint32_t addr, uint32_t size)
212214
{
213215
np_resp_t resp_header = { NP_RESP_STATUS, NP_STATUS_BAD_BLOCK };
214-
np_resp_bad_block_t bad_block = { resp_header, addr };
216+
np_resp_bad_block_t bad_block = { resp_header, addr, size };
215217

216218
if (np_comm_cb->send((uint8_t *)&bad_block, sizeof(bad_block)))
217219
return -1;
@@ -260,7 +262,7 @@ static int np_nand_erase(np_prog_t *prog, uint32_t page)
260262
case NAND_READY:
261263
break;
262264
case NAND_ERROR:
263-
if (np_send_bad_block_info(addr))
265+
if (np_send_bad_block_info(addr, prog->chip_info->block_size))
264266
return -1;
265267
break;
266268
case NAND_TIMEOUT_ERROR:
@@ -327,7 +329,7 @@ static int _np_cmd_nand_erase(np_prog_t *prog)
327329
if (skip_bb && (is_bad = nand_bad_block_table_lookup(addr)))
328330
{
329331
DEBUG_PRINT("Skipped bad block at 0x%lx\r\n", addr);
330-
if (np_send_bad_block_info(addr))
332+
if (np_send_bad_block_info(addr, prog->chip_info->block_size))
331333
return -1;
332334
}
333335

@@ -422,7 +424,7 @@ static int np_nand_handle_status(np_prog_t *prog)
422424
switch (nand_read_status())
423425
{
424426
case NAND_ERROR:
425-
if (np_send_bad_block_info(prog->addr))
427+
if (np_send_bad_block_info(prog->addr, prog->chip_info->block_size))
426428
return -1;
427429
case NAND_READY:
428430
prog->nand_wr_in_progress = 0;
@@ -592,7 +594,7 @@ static int np_nand_read(uint32_t addr, np_page_t *page,
592594
case NAND_READY:
593595
break;
594596
case NAND_ERROR:
595-
if (np_send_bad_block_info(addr))
597+
if (np_send_bad_block_info(addr, chip_info->block_size))
596598
return -1;
597599
break;
598600
case NAND_TIMEOUT_ERROR:
@@ -608,15 +610,16 @@ static int np_nand_read(uint32_t addr, np_page_t *page,
608610

609611
static int _np_cmd_nand_read(np_prog_t *prog)
610612
{
611-
uint32_t addr, len, write_len;
613+
uint32_t addr, len, send_len;
612614
static np_page_t page;
613615
uint32_t resp_header_size = offsetof(np_resp_t, data);
614616
uint32_t tx_data_len = sizeof(np_packet_send_buf) - resp_header_size;
615617
np_read_cmd_t *read_cmd = (np_read_cmd_t *)prog->rx_buf;
618+
bool skip_bb = read_cmd->flags.skip_bb;
616619
np_resp_t *resp = (np_resp_t *)np_packet_send_buf;
617620

618621
addr = read_cmd->addr;
619-
len = read_cmd->len;
622+
len = read_cmd->len;
620623
DEBUG_PRINT("Read at 0x%lx 0x%lx bytes command\r\n", addr, len);
621624

622625
if (addr + len > prog->chip_info->size)
@@ -653,46 +656,59 @@ static int _np_cmd_nand_read(np_prog_t *prog)
653656

654657
while (len)
655658
{
659+
if (addr >= prog->chip_info->size)
660+
{
661+
ERROR_PRINT("Read address 0x%lx is more then chip size 0x%lx",
662+
addr, prog->chip_info->page_size);
663+
return NP_ERR_ADDR_EXCEEDED;
664+
}
665+
666+
if (skip_bb && nand_bad_block_table_lookup(addr))
667+
{
668+
DEBUG_PRINT("Skipped bad block at 0x%lx\r\n", addr);
669+
if (np_send_bad_block_info(addr, prog->chip_info->block_size))
670+
return -1;
671+
672+
/* On partial read do not count bad blocks */
673+
if (read_cmd->len == prog->chip_info->size)
674+
len -= prog->chip_info->block_size;
675+
addr += prog->chip_info->block_size;
676+
page.page += prog->chip_info->block_size /
677+
prog->chip_info->page_size;
678+
continue;
679+
}
680+
656681
if (np_nand_read(addr, &page, prog->chip_info))
657682
return NP_ERR_NAND_RD;
658683

659684
while (page.offset < prog->chip_info->page_size && len)
660685
{
661686
if (prog->chip_info->page_size - page.offset >= tx_data_len)
662-
write_len = tx_data_len;
687+
send_len = tx_data_len;
663688
else
664-
write_len = prog->chip_info->page_size - page.offset;
689+
send_len = prog->chip_info->page_size - page.offset;
690+
691+
if (send_len > len)
692+
send_len = len;
665693

666-
if (write_len > len)
667-
write_len = len;
668-
669-
memcpy(resp->data, page.buf + page.offset, write_len);
694+
memcpy(resp->data, page.buf + page.offset, send_len);
670695

671696
while (!np_comm_cb->send_ready());
672697

673-
resp->info = write_len;
698+
resp->info = send_len;
674699
if (np_comm_cb->send(np_packet_send_buf,
675-
resp_header_size + write_len))
700+
resp_header_size + send_len))
676701
{
677702
return -1;
678703
}
679704

680-
page.offset += write_len;
681-
len -= write_len;
705+
page.offset += send_len;
706+
len -= send_len;
682707
}
683708

684-
if (len)
685-
{
686-
addr += prog->chip_info->page_size;
687-
if (addr >= prog->chip_info->size)
688-
{
689-
ERROR_PRINT("Read address 0x%lx is more then chip size 0x%lx",
690-
addr, prog->chip_info->page_size);
691-
return NP_ERR_ADDR_EXCEEDED;
692-
}
693-
page.page++;
694-
page.offset = 0;
695-
}
709+
addr += prog->chip_info->page_size;
710+
page.offset = 0;
711+
page.page++;
696712
}
697713

698714
return 0;
@@ -758,7 +774,7 @@ static int np_read_bad_block_info_from_page(np_prog_t *prog, uint32_t block,
758774
if (bad_block_data != NP_NAND_GOOD_BLOCK_MARK)
759775
{
760776
*is_bad = true;
761-
if (np_send_bad_block_info(addr))
777+
if (np_send_bad_block_info(addr, prog->chip_info->block_size))
762778
return -1;
763779
if (nand_bad_block_table_add(addr))
764780
return -1;

qt/cmd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ typedef struct __attribute__((__packed__))
3838
Cmd cmd;
3939
uint32_t addr;
4040
uint32_t len;
41+
CmdFlags flags;
4142
} ReadCmd;
4243

4344
typedef struct __attribute__((__packed__))
@@ -106,6 +107,7 @@ typedef struct __attribute__((__packed__))
106107
{
107108
RespHeader header;
108109
uint32_t addr;
110+
uint32_t size;
109111
} RespBadBlock;
110112

111113
typedef struct __attribute__((__packed__))

qt/main_window.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ void MainWindow::slotProgRead()
254254
return;
255255
}
256256

257-
prog->readChip(buffer, START_ADDRESS, readSize);
257+
prog->readChip(buffer, START_ADDRESS, readSize, true);
258258
}
259259

260260
void MainWindow::slotProgWriteCompleted(int status)

qt/programmer.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ void Programmer::readChipId(ChipId *chipId)
110110
writeData.clear();
111111
writeData.append((const char *)&cmd, sizeof(cmd));
112112
reader.init(usbDevName, SERIAL_PORT_SPEED, (uint8_t *)chipId,
113-
sizeof(ChipId), (uint8_t *)writeData.constData(), writeData.size());
113+
sizeof(ChipId), (uint8_t *)writeData.constData(), writeData.size(),
114+
false, false);
114115
reader.start();
115116
}
116117

@@ -136,7 +137,7 @@ void Programmer::eraseChip(uint32_t addr, uint32_t len)
136137
writeData.clear();
137138
writeData.append((const char *)&eraseCmd, sizeof(eraseCmd));
138139
reader.init(usbDevName, SERIAL_PORT_SPEED, NULL, 0,
139-
(uint8_t *)writeData.constData(), writeData.size());
140+
(uint8_t *)writeData.constData(), writeData.size(), skipBB, false);
140141
reader.start();
141142
}
142143

@@ -147,10 +148,12 @@ void Programmer::readCb(int ret)
147148
emit readChipCompleted(ret);
148149
}
149150

150-
void Programmer::readChip(uint8_t *buf, uint32_t addr, uint32_t len)
151+
void Programmer::readChip(uint8_t *buf, uint32_t addr, uint32_t len,
152+
bool isReadLess)
151153
{
152154
Cmd cmd = { .code = CMD_NAND_READ };
153-
ReadCmd readCmd = { .cmd = cmd, .addr = addr, .len = len };
155+
ReadCmd readCmd = { .cmd = cmd, .addr = addr, .len = len,
156+
.flags = { .skipBB = skipBB} };
154157

155158
QObject::connect(&reader, SIGNAL(result(int)), this, SLOT(readCb(int)));
156159

@@ -159,7 +162,8 @@ void Programmer::readChip(uint8_t *buf, uint32_t addr, uint32_t len)
159162
writeData.clear();
160163
writeData.append((const char *)&readCmd, sizeof(readCmd));
161164
reader.init(usbDevName, SERIAL_PORT_SPEED, buf, len,
162-
(uint8_t *)writeData.constData(), writeData.size());
165+
(uint8_t *)writeData.constData(), writeData.size(), skipBB,
166+
isReadLess);
163167
reader.start();
164168
}
165169

@@ -201,7 +205,7 @@ void Programmer::readChipBadBlocks()
201205
writeData.clear();
202206
writeData.append((const char *)&cmd, sizeof(cmd));
203207
reader.init(usbDevName, SERIAL_PORT_SPEED, NULL, 0,
204-
(uint8_t *)writeData.constData(), writeData.size());
208+
(uint8_t *)writeData.constData(), writeData.size(), false, false);
205209
reader.start();
206210
}
207211

@@ -226,7 +230,7 @@ void Programmer::selectChip(uint32_t chipNum)
226230
writeData.clear();
227231
writeData.append((const char *)&selectCmd, sizeof(SelectCmd));
228232
reader.init(usbDevName, SERIAL_PORT_SPEED, NULL, 0,
229-
(uint8_t *)writeData.constData(), writeData.size());
233+
(uint8_t *)writeData.constData(), writeData.size(), false, false);
230234
reader.start();
231235
}
232236

qt/programmer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Programmer : public QObject
4444
void setSkipBB(bool skip);
4545
void readChipId(ChipId *chipId);
4646
void eraseChip(uint32_t addr, uint32_t len);
47-
void readChip(uint8_t *buf, uint32_t addr, uint32_t len);
47+
void readChip(uint8_t *buf, uint32_t addr, uint32_t len, bool isReadLess);
4848
void writeChip(uint8_t *buf, uint32_t addr, uint32_t len,
4949
uint32_t pageSize);
5050
void readChipBadBlocks();

qt/reader.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
1515
Q_DECLARE_METATYPE(QtMsgType)
1616

1717
void Reader::init(const QString &portName, qint32 baudRate, uint8_t *rbuf,
18-
uint32_t rlen, uint8_t *wbuf, uint32_t wlen)
18+
uint32_t rlen, uint8_t *wbuf, uint32_t wlen, bool isSkipBB, bool isReadLess)
1919
{
2020
this->portName = portName;
2121
this->baudRate = baudRate;
2222
this->rbuf = rbuf;
2323
this->rlen = rlen;
2424
this->wbuf = wbuf;
2525
this->wlen = wlen;
26+
this->isSkipBB = isSkipBB;
27+
this->isReadLess = isReadLess;
2628
readOffset = 0;
29+
bytesRead = 0;
2730
}
2831

2932
int Reader::write(uint8_t *data, uint32_t len)
@@ -79,8 +82,16 @@ int Reader::handleBadBlock(uint8_t *pbuf, uint32_t len)
7982
if (len < size)
8083
return 0;
8184

82-
logInfo(QString("Bad block at 0x%1").arg(badBlock->addr, 8, 16,
83-
QLatin1Char('0')));
85+
logInfo(QString("Bad block at 0x%1 size 0x%2").arg(badBlock->addr, 8, 16,
86+
QLatin1Char('0')).arg(badBlock->size, 8, 16, QLatin1Char('0')));
87+
88+
if (rlen && isSkipBB && isReadLess)
89+
{
90+
if (bytesRead + badBlock->size > rlen)
91+
bytesRead = rlen;
92+
else
93+
bytesRead += badBlock->size;
94+
}
8495

8596
return size;
8697
}
@@ -111,7 +122,7 @@ int Reader::handleStatus(uint8_t *pbuf, uint32_t len)
111122
case STATUS_OK:
112123
// Exit read loop
113124
if (!rlen)
114-
readOffset = 1;
125+
bytesRead = 1;
115126
break;
116127
default:
117128
logErr(QString("Wrong response header info %1").arg(header->info));
@@ -145,6 +156,7 @@ int Reader::handleData(uint8_t *pbuf, uint32_t len)
145156

146157
memcpy(rbuf + readOffset, header->data, dataSize);
147158
readOffset += dataSize;
159+
bytesRead += dataSize;
148160

149161
return packetSize;
150162
}
@@ -207,10 +219,10 @@ int Reader::readData()
207219
if ((offset = handlePackets(pbuf, len)) < 0)
208220
return -1;
209221

210-
if (!readOffset)
222+
if (!bytesRead)
211223
continue;
212224
}
213-
while (rlen && rlen != readOffset);
225+
while (rlen && rlen != bytesRead);
214226

215227
return 0;
216228
}

qt/reader.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class Reader : public QThread
2121
uint8_t *wbuf;
2222
uint32_t wlen;
2323
uint32_t readOffset;
24+
uint32_t bytesRead;
25+
bool isSkipBB;
26+
bool isReadLess;
2427

2528
int serialPortCreate();
2629
void serialPortDestroy();
@@ -40,7 +43,8 @@ class Reader : public QThread
4043

4144
public:
4245
void init(const QString &portName, qint32 baudRate, uint8_t *rbuf,
43-
uint32_t rlen, uint8_t *wbuf, uint32_t wlen);
46+
uint32_t rlen, uint8_t *wbuf, uint32_t wlen, bool isSkipBB,
47+
bool isReadLess);
4448
signals:
4549
void result(int ret);
4650
void log(QtMsgType msgType, QString msg);

0 commit comments

Comments
 (0)