diff options
author | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-03-01 20:57:34 +0000 |
---|---|---|
committer | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-03-01 20:57:34 +0000 |
commit | 10edfff05a2fc8c3ae161a7684482d001f6b576a (patch) | |
tree | f86d0e57f51774cf0ca95ffffb304a7665e7387a /src | |
parent | 2e8f1911d68bdc3035f392f93fdc9e14a3136e72 (diff) |
Nicolas Pitre nico at cam.org support for NAND controllers without explicit busy signal
git-svn-id: svn://svn.berlios.de/openocd/trunk@1387 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src')
-rw-r--r-- | src/flash/nand.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/src/flash/nand.c b/src/flash/nand.c index 8708ef3c..1d0766d6 100644 --- a/src/flash/nand.c +++ b/src/flash/nand.c @@ -372,6 +372,27 @@ int nand_read_status(struct nand_device_s *device, u8 *status) return ERROR_OK; } +int nand_poll_ready(struct nand_device_s *device, int timeout) +{ + u8 status; + + device->controller->command(device, NAND_CMD_STATUS); + do { + if (device->device->options & NAND_BUSWIDTH_16) { + u16 data; + device->controller->read_data(device, &data); + status = data & 0xff; + } else { + device->controller->read_data(device, &status); + } + if (status & NAND_STATUS_READY) + break; + alive_sleep(1); + } while (timeout--); + + return (status & NAND_STATUS_READY) != 0; +} + int nand_probe(struct nand_device_s *device) { u8 manufacturer_id, device_id; @@ -648,9 +669,11 @@ int nand_erase(struct nand_device_s *device, int first_block, int last_block) /* Send erase confirm command */ device->controller->command(device, NAND_CMD_ERASE2); - - if (!device->controller->nand_ready(device, 1000)) - { + + retval = device->controller->nand_ready ? + device->controller->nand_ready(device, 1000) : + nand_poll_ready(device, 1000); + if (!retval) { LOG_ERROR("timeout waiting for NAND flash block erase to complete"); return ERROR_NAND_OPERATION_TIMEOUT; } @@ -823,8 +846,12 @@ int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 dat device->controller->command(device, NAND_CMD_READSTART); } - if (!device->controller->nand_ready(device, 100)) - return ERROR_NAND_OPERATION_TIMEOUT; + if (device->controller->nand_ready) { + if (!device->controller->nand_ready(device, 100)) + return ERROR_NAND_OPERATION_TIMEOUT; + } else { + alive_sleep(1); + } if (data) { @@ -977,7 +1004,10 @@ int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 da device->controller->command(device, NAND_CMD_PAGEPROG); - if (!device->controller->nand_ready(device, 100)) + retval = device->controller->nand_ready ? + device->controller->nand_ready(device, 100) : + nand_poll_ready(device, 100); + if (!retval) return ERROR_NAND_OPERATION_TIMEOUT; if ((retval = nand_read_status(device, &status)) != ERROR_OK) |