Skip to content

Commit 95b3557

Browse files
committed
Skip bad blocks on write
1 parent e6cffd8 commit 95b3557

File tree

5 files changed

+129
-70
lines changed

5 files changed

+129
-70
lines changed

firmware/nand_programmer.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ typedef struct __attribute__((__packed__))
7676
np_cmd_t cmd;
7777
uint32_t addr;
7878
uint32_t len;
79+
np_cmd_flags_t flags;
7980
} np_write_start_cmd_t;
8081

8182
typedef struct __attribute__((__packed__))
@@ -172,6 +173,7 @@ typedef struct
172173
np_page_t page;
173174
uint32_t bytes_written;
174175
uint32_t bytes_ack;
176+
int skip_bb;
175177
int nand_wr_in_progress;
176178
uint32_t nand_timeout;
177179
chip_info_t *chip_info;
@@ -415,6 +417,7 @@ static int np_cmd_nand_write_start(np_prog_t *prog)
415417

416418
prog->bytes_written = 0;
417419
prog->bytes_ack = 0;
420+
prog->skip_bb = write_start_cmd->flags.skip_bb;
418421

419422
return np_send_ok_status();
420423
}
@@ -491,13 +494,6 @@ static int np_cmd_nand_write_data(np_prog_t *prog)
491494
return NP_ERR_ADDR_INVALID;
492495
}
493496

494-
if (prog->addr >= prog->chip_info->size)
495-
{
496-
ERROR_PRINT("Write address 0x%lx is more then chip size 0x%lx\r\n",
497-
prog->addr, prog->chip_info->size);
498-
return NP_ERR_ADDR_EXCEEDED;
499-
}
500-
501497
if (prog->page.offset + len > prog->chip_info->page_size)
502498
write_len = prog->chip_info->page_size - prog->page.offset;
503499
else
@@ -508,6 +504,24 @@ static int np_cmd_nand_write_data(np_prog_t *prog)
508504

509505
if (prog->page.offset == prog->chip_info->page_size)
510506
{
507+
while (prog->skip_bb && nand_bad_block_table_lookup(prog->addr))
508+
{
509+
DEBUG_PRINT("Skipped bad block at 0x%lx\r\n", addr);
510+
if (np_send_bad_block_info(prog->addr, prog->chip_info->block_size))
511+
return -1;
512+
513+
prog->addr += prog->chip_info->block_size;
514+
prog->page.page += prog->chip_info->block_size /
515+
prog->chip_info->page_size;
516+
}
517+
518+
if (prog->addr >= prog->chip_info->size)
519+
{
520+
ERROR_PRINT("Write address 0x%lx is more then chip size 0x%lx\r\n",
521+
prog->addr, prog->chip_info->size);
522+
return NP_ERR_ADDR_EXCEEDED;
523+
}
524+
511525
if (np_nand_write(prog, prog->chip_info))
512526
return NP_ERR_NAND_WR;
513527

qt/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef struct __attribute__((__packed__))
4646
Cmd cmd;
4747
uint32_t addr;
4848
uint32_t len;
49+
CmdFlags flags;
4950
} WriteStartCmd;
5051

5152
typedef struct __attribute__((__packed__))

qt/programmer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ void Programmer::writeChip(uint8_t *buf, uint32_t addr, uint32_t len,
181181

182182
/* Serial port object cannot be used in other thread */
183183
serialPortDisconnect();
184-
writer.init(usbDevName, SERIAL_PORT_SPEED, buf, addr, len, pageSize);
184+
writer.init(usbDevName, SERIAL_PORT_SPEED, buf, addr, len, pageSize,
185+
skipBB);
185186
writer.start();
186187
}
187188

qt/writer.cpp

Lines changed: 95 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
Q_DECLARE_METATYPE(QtMsgType)
1515

1616
void Writer::init(const QString &portName, qint32 baudRate, uint8_t *buf,
17-
uint32_t addr, uint32_t len, uint32_t pageSize)
17+
uint32_t addr, uint32_t len, uint32_t pageSize, bool skipBB)
1818
{
1919
this->portName = portName;
2020
this->baudRate = baudRate;
2121
this->buf = buf;
2222
this->addr = addr;
2323
this->len = len;
2424
this->pageSize = pageSize;
25+
this->skipBB = skipBB;
26+
bytesWritten = 0;
27+
bytesAcked = 0;
2528
}
2629

2730
int Writer::write(uint8_t *data, uint32_t dataLen)
@@ -44,110 +47,153 @@ int Writer::write(uint8_t *data, uint32_t dataLen)
4447
return 0;
4548
}
4649

47-
int Writer::handleWriteAck(RespHeader *header, uint32_t len, void *ackData)
50+
int Writer::read(uint8_t *data, uint32_t dataLen)
4851
{
49-
if (len != sizeof(RespWriteAck))
52+
int ret;
53+
54+
if (!serialPort->waitForReadyRead(READ_ACK_TIMEOUT))
5055
{
51-
logErr(QString("Write ack response is too short %1").arg(len));
56+
logErr("Write ACK was not received");
5257
return -1;
5358
}
5459

55-
*((uint32_t *)ackData) = ((RespWriteAck *)header)->ackBytes;
60+
ret = serialPort->read((char *)data, dataLen);
61+
if (ret < 0)
62+
{
63+
logErr("Failed to read ACK");
64+
return -1;
65+
}
5666

57-
return 0;
67+
return ret;
5868
}
5969

60-
int Writer::handleBadBlock(RespHeader *header, uint32_t len)
70+
int Writer::handleWriteAck(RespHeader *header, uint32_t len)
6171
{
62-
RespBadBlock *badBlock = (RespBadBlock *)header;
72+
int size = sizeof(RespWriteAck);
73+
74+
if (len < (uint32_t)size)
75+
{
76+
logErr(QString("Write ack response is too short %1").arg(len));
77+
return -1;
78+
}
6379

64-
if (len != sizeof(RespBadBlock))
80+
bytesAcked = ((RespWriteAck *)header)->ackBytes;
81+
82+
if (bytesAcked != bytesWritten)
6583
{
66-
logErr(QString("Bad block response is too short %1").arg(len));
84+
logErr(QString("Received wrong ack %1, expected %2 ").arg(bytesAcked)
85+
.arg(bytesWritten));
6786
return -1;
6887
}
6988

89+
return size;
90+
}
91+
92+
int Writer::handleBadBlock(RespHeader *header, uint32_t len)
93+
{
94+
int size = sizeof(RespBadBlock);
95+
RespBadBlock *badBlock = (RespBadBlock *)header;
96+
97+
if (len < (uint32_t)size)
98+
return 0;
99+
70100
logInfo(QString("Bad block at 0x%1").arg(badBlock->addr, 8, 16,
71101
QLatin1Char('0')));
72102

73-
return 0;
103+
return size;
74104
}
75105

76106
int Writer::handleError(RespHeader *header, uint32_t len)
77107
{
78108
RespError *err = (RespError *)header;
79-
size_t size = sizeof(RespError);
109+
int size = sizeof(RespError);
80110

81-
if (len < size)
111+
if (len < (uint32_t)size)
82112
return 0;
83113

84114
logErr(QString("Programmer sent error: %1").arg(err->errCode));
85115

86116
return -1;
87117
}
88118

89-
int Writer::handleStatus(RespHeader *header, uint32_t len, void *ackData)
119+
int Writer::handleStatus(uint8_t *pbuf, uint32_t len)
90120
{
121+
RespHeader *header = (RespHeader *)pbuf;
91122
uint8_t status = header->info;
92123

93124
switch (status)
94125
{
95126
case STATUS_OK:
96-
break;
127+
return sizeof(RespHeader);
97128
case STATUS_ERROR:
98129
return handleError(header, len);
99130
case STATUS_BAD_BLOCK:
100-
handleBadBlock(header, len);
101-
return -1;
131+
return handleBadBlock(header, len);
102132
case STATUS_WRITE_ACK:
103-
if (handleWriteAck(header, len, ackData))
104-
return -1;
105-
break;
106-
default:
107-
logErr(QString("Wrong status received %1").arg(status));
108-
return -1;
133+
return handleWriteAck(header, len);
109134
}
110135

111-
return 0;
136+
logErr(QString("Wrong status received %1").arg(status));
137+
return -1;
112138
}
113139

114-
int Writer::handleAck(RespHeader *header, uint32_t len, void *ackData)
140+
int Writer::handlePacket(uint8_t *pbuf, uint32_t len)
115141
{
142+
RespHeader *header = (RespHeader *)pbuf;
143+
144+
if (len < sizeof(RespHeader))
145+
return 0;
146+
116147
if (header->code != RESP_STATUS)
117148
{
118-
logErr(QString("Wrong response code %1").arg(header->code));
149+
logErr(QString("Programmer returned wrong response code: %1")
150+
.arg(header->code));
119151
return -1;
120152
}
121153

122-
return handleStatus(header, len, ackData);
154+
return handleStatus(pbuf, len);
123155
}
124156

125-
int Writer::readAck(void *ackData)
157+
int Writer::handlePackets(uint8_t *pbuf, uint32_t len)
126158
{
127159
int ret;
128-
uint8_t pbuf[BUF_SIZE];
129-
unsigned int dataLen = sizeof(RespHeader);
160+
uint32_t offset = 0;
130161

131-
if (!serialPort->waitForReadyRead(READ_ACK_TIMEOUT))
162+
do
132163
{
133-
logErr("Write ACK was not received");
134-
return -1;
135-
}
164+
if ((ret = handlePacket(pbuf + offset, len - offset)) < 0)
165+
return -1;
136166

137-
ret = serialPort->read((char *)pbuf, BUF_SIZE);
138-
if (ret < 0)
139-
{
140-
logErr("Failed to read ACK");
141-
return -1;
167+
if (ret)
168+
offset += ret;
169+
else
170+
{
171+
memmove(pbuf, pbuf + offset, len - offset);
172+
break;
173+
}
142174
}
143-
else if ((uint32_t)ret < dataLen)
175+
while (offset < len);
176+
177+
return len - offset;
178+
}
179+
180+
int Writer::readData()
181+
{
182+
uint8_t pbuf[BUF_SIZE];
183+
int len, offset = 0;
184+
185+
do
144186
{
145-
logErr(QString("Response is too short, expected %1, received %2")
146-
.arg(dataLen).arg(ret));
147-
return -1;
187+
if ((len = read(pbuf + offset, BUF_SIZE - offset)) < 0)
188+
return -1;
189+
len += offset;
190+
191+
if ((offset = handlePackets(pbuf, len)) < 0)
192+
return -1;
148193
}
194+
while (offset);
149195

150-
return handleAck((RespHeader *)pbuf, ret, ackData);
196+
return 0;
151197
}
152198

153199
int Writer::writeStart()
@@ -157,11 +203,12 @@ int Writer::writeStart()
157203
writeStartCmd.cmd.code = CMD_NAND_WRITE_S;
158204
writeStartCmd.addr = addr;
159205
writeStartCmd.len = len;
206+
writeStartCmd.flags.skipBB = skipBB;
160207

161208
if (write((uint8_t *)&writeStartCmd, sizeof(WriteStartCmd)))
162209
return -1;
163210

164-
if (readAck(NULL))
211+
if (readData())
165212
return -1;
166213

167214
return 0;
@@ -171,8 +218,7 @@ int Writer::writeData()
171218
{
172219
uint8_t pbuf[BUF_SIZE];
173220
WriteDataCmd *writeDataCmd = (WriteDataCmd *)pbuf;
174-
uint32_t dataLen, dataLenMax, headerLen, pageLim, ack,
175-
bytesWritten = 0, bytesAcked = 0;
221+
uint32_t dataLen, dataLenMax, headerLen, pageLim;
176222

177223
writeDataCmd->cmd.code = CMD_NAND_WRITE_D;
178224
headerLen = sizeof(WriteDataCmd);
@@ -197,16 +243,8 @@ int Writer::writeData()
197243
if (len && bytesWritten != pageLim)
198244
continue;
199245

200-
if (readAck(&ack))
246+
if (readData())
201247
return -1;
202-
203-
if (ack != bytesWritten)
204-
{
205-
logErr(QString("Received wrong ack %1, expected%2 ").arg(ack)
206-
.arg(bytesWritten));
207-
return -1;
208-
}
209-
bytesAcked = ack;
210248
}
211249

212250
return 0;
@@ -221,7 +259,7 @@ int Writer::writeEnd()
221259
if (write((uint8_t *)&writeEndCmd, sizeof(WriteEndCmd)))
222260
return -1;
223261

224-
if (readAck(NULL))
262+
if (readData())
225263
return -1;
226264

227265
return 0;

qt/writer.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,19 @@ class Writer : public QThread
2020
uint32_t addr;
2121
uint32_t len;
2222
uint32_t pageSize;
23+
uint32_t bytesAcked;
24+
uint32_t bytesWritten;
25+
bool skipBB;
2326

2427
int write(uint8_t *data, uint32_t dataLen);
25-
int handleWriteAck(RespHeader *header, uint32_t len, void *ackData);
28+
int read(uint8_t *data, uint32_t dataLen);
29+
int handleWriteAck(RespHeader *header, uint32_t len);
2630
int handleBadBlock(RespHeader *header, uint32_t len);
2731
int handleError(RespHeader *header, uint32_t len);
28-
int handleStatus(RespHeader *header, uint32_t len, void *ackData);
29-
int handleAck(RespHeader *header, uint32_t len, void *ackData);
30-
int readAck(void *ackData);
32+
int handleStatus(uint8_t *pbuf, uint32_t len);
33+
int handlePacket(uint8_t *pbuf, uint32_t len);
34+
int handlePackets(uint8_t *pbuf, uint32_t len);
35+
int readData();
3136
int writeStart();
3237
int writeData();
3338
int writeEnd();
@@ -39,7 +44,7 @@ class Writer : public QThread
3944

4045
public:
4146
void init(const QString &portName, qint32 baudRate, uint8_t *buf,
42-
uint32_t addr, uint32_t len, uint32_t pageSize);
47+
uint32_t addr, uint32_t len, uint32_t pageSize, bool skipBB);
4348
signals:
4449
void result(int ret);
4550
void log(QtMsgType msgType, QString msg);

0 commit comments

Comments
 (0)