Refactored the write page raw function into two new functions for writing data
to a NAND device and then another function to finish up a write to a NAND
device.  This includes some new updates to introduce more error checking to
existing code.
---
 src/flash/nand/core.c |  116 ++++++++++++++++++++++++++-----------------------
 src/flash/nand/core.h |    3 +
 2 files changed, 64 insertions(+), 55 deletions(-)

diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c
index de601b4..7535247 100644
--- a/src/flash/nand/core.c
+++ b/src/flash/nand/core.c
@@ -643,7 +643,8 @@ static int nand_write_plain(struct nand_device *nand, 
uint32_t address, uint8_t
 }
 #endif
 
-int nand_write_page(struct nand_device *nand, uint32_t page, uint8_t *data, 
uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+int nand_write_page(struct nand_device *nand, uint32_t page, uint8_t *data,
+    uint32_t data_size, uint8_t *oob, uint32_t oob_size)
 {
        uint32_t block;
 
@@ -781,66 +782,43 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t 
page,
        return ERROR_OK;
 }
 
-int nand_write_page_raw(struct nand_device *nand, uint32_t page, uint8_t 
*data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+int nand_write_data_page(struct nand_device *nand, uint8_t *data, uint32_t 
size)
 {
+       int retval = ERROR_NAND_OPERATION_FAILED;
        uint32_t i;
-       int retval;
-       uint8_t status;
 
-       retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
-       if (ERROR_OK != retval)
-               return retval;
+       if (nand->controller->write_block_data != NULL) {
+               retval = (nand->controller->write_block_data)(nand, data, size);
+       }
 
-       if (data)
-       {
-               if (nand->controller->write_block_data != NULL)
-                       (nand->controller->write_block_data)(nand, data, 
data_size);
-               else
-               {
-                       for (i = 0; i < data_size;)
-                       {
-                               if (nand->device->options & NAND_BUSWIDTH_16)
-                               {
-                                       uint16_t data_buf = le_to_h_u16(data);
-                                       nand->controller->write_data(nand, 
data_buf);
-                                       data += 2;
-                                       i += 2;
-                               }
-                               else
-                               {
-                                       nand->controller->write_data(nand, 
*data);
-                                       data += 1;
-                                       i += 1;
-                               }
+       if (ERROR_NAND_NO_BUFFER == retval) {
+               bool is16bit = nand->device->options & NAND_BUSWIDTH_16;
+               uint32_t incr = (is16bit) ? 2 : 1;
+               uint16_t write_data;
+               for (i = 0; i < size; i += incr) {
+                       if (is16bit) {
+                               write_data = le_to_h_u16(data);
+                       } else {
+                               write_data = *data;
                        }
-               }
-       }
 
-       if (oob)
-       {
-               if (nand->controller->write_block_data != NULL)
-                       (nand->controller->write_block_data)(nand, oob, 
oob_size);
-               else
-               {
-                       for (i = 0; i < oob_size;)
-                       {
-                               if (nand->device->options & NAND_BUSWIDTH_16)
-                               {
-                                       uint16_t oob_buf = le_to_h_u16(data);
-                                       nand->controller->write_data(nand, 
oob_buf);
-                                       oob += 2;
-                                       i += 2;
-                               }
-                               else
-                               {
-                                       nand->controller->write_data(nand, 
*oob);
-                                       oob += 1;
-                                       i += 1;
-                               }
+                       retval = nand->controller->write_data(nand, write_data);
+                       if (ERROR_OK != retval) {
+                               break;
                        }
+
+                       data += incr;
                }
        }
 
+       return retval;
+}
+
+int nand_write_finish(struct nand_device *nand)
+{
+       int retval;
+       uint8_t status;
+
        nand->controller->command(nand, NAND_CMD_PAGEPROG);
 
        retval = nand->controller->nand_ready ?
@@ -849,14 +827,13 @@ int nand_write_page_raw(struct nand_device *nand, 
uint32_t page, uint8_t *data,
        if (!retval)
                return ERROR_NAND_OPERATION_TIMEOUT;
 
-       if ((retval = nand_read_status(nand, &status)) != ERROR_OK)
-       {
+       retval = nand_read_status(nand, &status);
+       if (ERROR_OK != retval) {
                LOG_ERROR("couldn't read status");
                return ERROR_NAND_OPERATION_FAILED;
        }
 
-       if (status & NAND_STATUS_FAIL)
-       {
+       if (status & NAND_STATUS_FAIL) {
                LOG_ERROR("write operation didn't pass, status: 0x%2.2x", 
status);
                return ERROR_NAND_OPERATION_FAILED;
        }
@@ -864,3 +841,32 @@ int nand_write_page_raw(struct nand_device *nand, uint32_t 
page, uint8_t *data,
        return ERROR_OK;
 }
 
+int nand_write_page_raw(struct nand_device *nand, uint32_t page, uint8_t 
*data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+{
+       int retval;
+
+       retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
+       if (ERROR_OK != retval)
+               return retval;
+
+       if (data) {
+               retval = nand_write_data_page(nand, data, data_size);
+               if (ERROR_OK != retval) {
+                       LOG_ERROR("Unable to write data to NAND device");
+                       return retval;
+               }
+       }
+
+       if (oob) {
+               retval = nand_write_data_page(nand, oob, oob_size);
+               if (ERROR_OK != retval) {
+                       LOG_ERROR("Unable to write OOB data to NAND device");
+                       return retval;
+               }
+       }
+
+       retval = nand_write_finish(nand);
+
+       return retval;
+}
+
diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h
index 990114a..88b20e0 100644
--- a/src/flash/nand/core.h
+++ b/src/flash/nand/core.h
@@ -212,6 +212,9 @@ int nand_page_command(struct nand_device *nand, uint32_t 
page,
                uint8_t cmd, bool oob_only);
 
 int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t 
size);
+int nand_write_data_page(struct nand_device *nand, uint8_t *data, uint32_t 
size);
+
+int nand_write_finish(struct nand_device *nand);
 
 int nand_read_page_raw(struct nand_device *nand, uint32_t page,
                uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t 
oob_size);
-- 
1.6.5.2

_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to