changeset 1738:0801d20c7256

* include/dataflash.h: * src/devs_flash_atmel_dataflash.c: Changed the API to be more consistent, included error reporting and added blocking/non blocking mode of operation. * src/devs_flash_atmel_dataflash_flash_dev_funs.c: Synced with new API and set the block size to DataFlash's native page size.
author asl
date Thu, 07 Oct 2004 19:59:27 +0000
parents dcf02dfe567d
children 1773ef378c6f
files packages/devs/flash/atmel/dataflash/current/ChangeLog packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl packages/devs/flash/atmel/dataflash/current/include/dataflash.h packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
diffstat 5 files changed, 511 insertions(+), 243 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/flash/atmel/dataflash/current/ChangeLog
+++ b/packages/devs/flash/atmel/dataflash/current/ChangeLog
@@ -1,3 +1,13 @@
+2004-10-07  Savin Zlobec  <savin@elatec.si> 
+
+        * include/dataflash.h:
+        * src/devs_flash_atmel_dataflash.c:
+        Changed the API to be more consistent, included error
+        reporting and added blocking/non blocking mode of operation.
+        * src/devs_flash_atmel_dataflash_flash_dev_funs.c:
+        Synced with new API and set the block size to DataFlash's
+        native page size.
+
 2004-10-07  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* cdl/devs_flash_atmel_dataflash.cdl: Remove
--- a/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
+++ b/packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
@@ -51,6 +51,7 @@ cdl_package CYGPKG_DEVS_FLASH_ATMEL_DATA
     display       "Atmel DataFlash parts support"
     description   "Support for Atmel DataFlash"
     active_if	  CYGPKG_IO_SPI
+    requires      CYGPKG_ERROR    
     hardware
     compile       devs_flash_atmel_dataflash.c 
     include_dir   cyg/io
--- a/packages/devs/flash/atmel/dataflash/current/include/dataflash.h
+++ b/packages/devs/flash/atmel/dataflash/current/include/dataflash.h
@@ -59,6 +59,21 @@
 
 //----------------------------------------------------------------------------
 
+enum {
+    CYG_DATAFLASH_ERR_OK         = 0, // No error
+    CYG_DATAFLASH_ERR_INVALID    = 1, // Invalid address error
+    CYG_DATAFLASH_ERR_WRONG_PART = 2, // Unsupported device error
+    CYG_DATAFLASH_ERR_TIMEOUT    = 3, // Operation timeout error
+    CYG_DATAFLASH_ERR_COMPARE    = 4  // Buffer - main memory compare error
+};
+
+enum {
+    CYG_DATAFLASH_STATE_IDLE = 0,
+    CYG_DATAFLASH_STATE_BUSY = 1
+};
+
+//----------------------------------------------------------------------------
+
 typedef struct cyg_dataflash_dev_info_s
 {
     cyg_uint8  device_id;        // Device ID 
@@ -72,10 +87,13 @@ typedef struct cyg_dataflash_dev_info_s
 
 typedef struct cyg_dataflash_device_s
 {
-    const cyg_dataflash_dev_info_t *info;    // DataFlash device info
-    cyg_spi_device                 *spi_dev; // SPI device
-    cyg_bool                        polled;  // Polled mode flag
-    cyg_drv_mutex_t                 lock;    // Access lock 
+    const cyg_dataflash_dev_info_t *info;     // DataFlash device info
+    cyg_spi_device                 *spi_dev;  // SPI device
+    cyg_drv_mutex_t                 lock;     // Access lock 
+    cyg_bool                        polled;   // Polled mode flag
+    cyg_bool                        blocking; // Blocking mode flag 
+    int                             state;    // Current state (IDLE, BUSY, ...)
+    cyg_uint8                       busy_buf; // Current busy buffer number
 } cyg_dataflash_device_t;
 
 //----------------------------------------------------------------------------
@@ -96,7 +114,6 @@ typedef struct cyg_dataflash_flash_dev_p
     cyg_dataflash_device_t dev;            // DataFlash device
     cyg_uint32             start_page;     // Start page of flash driver space
     cyg_uint32             end_page;       // End page of flash driver space
-    cyg_uint32             page_2size_log; // Page (2^n) size log
 } cyg_dataflash_flash_dev_priv_t;
 
 externC struct cyg_flash_dev_funs cyg_dataflash_flash_dev_funs;
@@ -158,68 +175,73 @@ cyg_dataflash_set_polled_operation(cyg_d
     dev->polled = polled;
 }
 
-externC cyg_bool cyg_dataflash_init(cyg_spi_device         *spi_dev, 
-                                    cyg_bool                polled,
-                                    cyg_dataflash_device_t *dev);
+static inline void
+cyg_dataflash_set_blocking_operation(cyg_dataflash_device_t *dev, cyg_bool block)
+{
+    dev->blocking = block;
+} 
+
+//----------------------------------------------------------------------------
 
-externC void cyg_dataflash_aquire(cyg_dataflash_device_t *dev);
+externC int cyg_dataflash_init(cyg_spi_device         *spi_dev, 
+                               cyg_bool                polled,
+                               cyg_dataflash_device_t *dev);
 
-externC void cyg_dataflash_release(cyg_dataflash_device_t *dev);
+externC int cyg_dataflash_aquire(cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_release(cyg_dataflash_device_t *dev);
 
 externC cyg_uint16 cyg_dataflash_get_sector_start(cyg_dataflash_device_t *dev,
                                                   cyg_uint16 sector_num);
 
-externC void cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
-                                    cyg_uint8               buf_num,
-                                    cyg_uint8              *buf, 
-                                    cyg_uint32              len, 
-                                    cyg_uint32              pos); 
+externC int cyg_dataflash_wait_ready(cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
+                                   cyg_uint8               buf_num,
+                                   cyg_uint8              *buf, 
+                                   cyg_uint32              len, 
+                                   cyg_uint32              pos); 
                        
-externC void cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
+externC int cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
+                                    cyg_uint8               buf_num,
+                                    const cyg_uint8        *buf,
+                                    cyg_uint32              len,
+                                    cyg_uint32              pos);
+
+externC int cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
                                      cyg_uint8               buf_num,
-                                     const cyg_uint8        *buf,
-                                     cyg_uint32              len,
-                                     cyg_uint32              pos);
+                                     cyg_uint32              page_num);
 
-externC void cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
+externC int cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
                                       cyg_uint8               buf_num,
                                       cyg_uint32              page_num,
-                                      cyg_bool                wait); 
+                                      cyg_bool                erase);
 
-externC void cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
-                                       cyg_uint8               buf_num,
-                                       cyg_uint32              page_num,
-                                       cyg_bool                erase,
-                                       cyg_bool                wait);
+externC int cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
+                                      cyg_uint8               buf_num,
+                                      cyg_uint32              page_num);
 
-externC cyg_bool cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
-                                           cyg_uint8               buf_num,
-                                           cyg_uint32              page_num);
+externC int cyg_dataflash_erase(cyg_dataflash_device_t *dev,
+                                cyg_uint32              page_num);
 
-externC void cyg_dataflash_erase(cyg_dataflash_device_t *dev,
-                                 cyg_uint32              page_num,
-                                 cyg_bool                wait);
+externC int cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
+                                      cyg_uint32              block_num);
 
-externC void cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
-                                       cyg_uint32              block_num,
-                                       cyg_bool                wait);
-
-externC void cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
-                                        cyg_uint8               buf_num,
-                                        cyg_uint32              page_num,
-                                        cyg_bool                wait);
+externC int cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
+                                       cyg_uint8               buf_num,
+                                       cyg_uint32              page_num);
 
-externC void cyg_dataflash_read(cyg_dataflash_device_t *dev, 
-                                cyg_uint8              *buf, 
-                                cyg_uint32              len, 
-                                cyg_uint32              pos);
+externC int cyg_dataflash_read(cyg_dataflash_device_t *dev, 
+                               cyg_uint8              *buf, 
+                               cyg_uint32              len, 
+                               cyg_uint32              pos);
 
-externC cyg_bool cyg_dataflash_program(cyg_dataflash_device_t *dev, 
-                                       const cyg_uint8        *buf, 
-                                       cyg_uint32             *len, 
-                                       cyg_uint32              pos,
-                                       cyg_bool                erase,
-                                       cyg_bool                verify);
+externC int cyg_dataflash_program(cyg_dataflash_device_t *dev, 
+                                  const cyg_uint8        *buf, 
+                                  cyg_uint32             *len, 
+                                  cyg_uint32              pos,
+                                  cyg_bool                erase,
+                                  cyg_bool                verify);
 
 //----------------------------------------------------------------------------
 
--- a/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
+++ b/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
@@ -90,6 +90,11 @@
 
 //----------------------------------------------------------------------------
 
+#define DATA_BUF_NONE 0x00 // Data buffer number for no buffer
+#define DATA_BUF_ALL  0xFF // Data buffer number for all buffers
+
+//----------------------------------------------------------------------------
+
 typedef struct df_status_s
 {
     cyg_uint8 reserved:2;
@@ -206,15 +211,51 @@ df_read_status(cyg_dataflash_device_t *d
     return *status;    
 }
 
-static void 
-df_wait_ready(cyg_dataflash_device_t *dev)
+static void
+df_set_busy_buf(cyg_dataflash_device_t *dev, cyg_uint8 buf_num)
+{
+    dev->state    = CYG_DATAFLASH_STATE_BUSY;
+    dev->busy_buf = buf_num;
+}
+
+static void
+df_set_busy(cyg_dataflash_device_t *dev)
+{
+    df_set_busy_buf(dev, DATA_BUF_ALL);
+}
+
+static int
+df_wait_ready_buf(cyg_dataflash_device_t *dev, cyg_uint8 buf_num)
 {
     df_status_t status;
-   
-    do 
+  
+    if (CYG_DATAFLASH_STATE_IDLE == dev->state)
+        return CYG_DATAFLASH_ERR_OK;
+    
+    if (DATA_BUF_ALL  == buf_num       || 
+        DATA_BUF_ALL  == dev->busy_buf || 
+        dev->busy_buf == buf_num)
     {
-        status = df_read_status(dev);
-    } while (0 == status.ready); 
+        // REMIND: this loop should have an timeout 
+        // in case of device malfunction
+
+        do 
+        {
+            status = df_read_status(dev);
+        } while (0 == status.ready); 
+
+        dev->state    = CYG_DATAFLASH_STATE_IDLE;
+        dev->busy_buf = DATA_BUF_NONE;
+    }
+    
+    return CYG_DATAFLASH_ERR_OK;  
+   
+}
+
+static int
+df_wait_ready(cyg_dataflash_device_t *dev)
+{
+    return df_wait_ready_buf(dev, DATA_BUF_ALL);
 }
 
 static void 
@@ -234,9 +275,6 @@ df_detect_device(cyg_dataflash_device_t 
     {
         if (status.device_id == dev_info->device_id)
         {
-//            diag_printf("Detected DataFlash id = %d page_size=%d page_count=%d\n", 
-//                        status.device_id, dev_info->page_size, dev_info->page_count); 
-
             dev->info = dev_info;
             return;
         }
@@ -248,22 +286,50 @@ df_detect_device(cyg_dataflash_device_t 
 //----------------------------------------------------------------------------
 // cyg_dataflash_init()
 
-cyg_bool 
+int
 cyg_dataflash_init(cyg_spi_device         *spi_dev, 
                    cyg_bool                polled,
                    cyg_dataflash_device_t *dev)
 {
-    dev->spi_dev = spi_dev;
-    dev->polled  = polled;
-    
+    dev->spi_dev  = spi_dev;
+    dev->polled   = polled;
+    dev->blocking = false;
+    dev->state    = CYG_DATAFLASH_STATE_IDLE;
+    dev->busy_buf = DATA_BUF_NONE;
+
     cyg_drv_mutex_init(&dev->lock);
 
     df_detect_device(dev);
 
     if (NULL == dev->info)
-        return false;
+        return CYG_DATAFLASH_ERR_WRONG_PART;
     else
-        return true;
+        return CYG_DATAFLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_aquire()
+
+int
+cyg_dataflash_aquire(cyg_dataflash_device_t *dev)
+{
+    while (!cyg_drv_mutex_lock(&dev->lock));
+    return CYG_DATAFLASH_ERR_OK; 
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_release()
+
+int
+cyg_dataflash_release(cyg_dataflash_device_t *dev)
+{
+    int err;
+
+    err = df_wait_ready(dev); 
+        
+    cyg_drv_mutex_unlock(&dev->lock);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
@@ -286,27 +352,18 @@ cyg_dataflash_get_sector_start(cyg_dataf
 }
 
 //----------------------------------------------------------------------------
-// cyg_dataflash_aquire()
-
-void
-cyg_dataflash_aquire(cyg_dataflash_device_t *dev)
-{
-    while (!cyg_drv_mutex_lock(&dev->lock));
-}
+// cyg_dataflash_wait_ready()
 
-//----------------------------------------------------------------------------
-// cyg_dataflash_release()
-
-void
-cyg_dataflash_release(cyg_dataflash_device_t *dev)
+int 
+cyg_dataflash_wait_ready(cyg_dataflash_device_t *dev)
 {
-    cyg_drv_mutex_unlock(&dev->lock);
+    return df_wait_ready(dev);
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_read_buf()
 
-void
+int
 cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
                        cyg_uint8               buf_num,
                        cyg_uint8              *buf, 
@@ -315,27 +372,44 @@ cyg_dataflash_read_buf(cyg_dataflash_dev
                        
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[5];
 
-    pos %= dev->info->page_size;
+    // Check if the position is inside the page 
+    if (pos >= dev->info->page_size)
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
 
     if (1 == buf_num)      cmd_buf[0] = DF_BUF1_READ_CMD;
     else if (2 == buf_num) cmd_buf[0] = DF_BUF2_READ_CMD;
     else 
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
 
     df_compose_addr(dev, cmd_buf, 0, pos);
 
     cyg_spi_transaction_begin(spi_dev);
-    cyg_spi_transaction_transfer(spi_dev, true, 5, cmd_buf, NULL, false);
-    cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+
+    // Wait for the target buffer to become ready
+    err = df_wait_ready_buf(dev, buf_num);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send command and read data
+
+        cyg_spi_transaction_transfer(spi_dev, true, 5, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+    }
+    
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_write_buf()
 
-void
+int
 cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
                         cyg_uint8               buf_num,
                         const cyg_uint8        *buf,
@@ -343,259 +417,387 @@ cyg_dataflash_write_buf(cyg_dataflash_de
                         cyg_uint32              pos)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
+ 
+    // Check if the position is inside the page 
+    if (pos >= dev->info->page_size)
+        return CYG_DATAFLASH_ERR_INVALID;
 
-    pos %= dev->info->page_size;
+    // Compose DataFlash command
 
     if (1 == buf_num)      cmd_buf[0] = DF_BUF1_WRITE_CMD;
     else if (2 == buf_num) cmd_buf[0] = DF_BUF2_WRITE_CMD;
     else 
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
 
     df_compose_addr(dev, cmd_buf, 0, pos);
 
     cyg_spi_transaction_begin(spi_dev);
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
-    cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, NULL, true);
+
+    // Wait for the target buffer to become ready
+    err = df_wait_ready_buf(dev, buf_num);
+    
+    if (CYG_DATAFLASH_ERR_OK == err)
+    { 
+        // Send command and data
+
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, 
+                                     len, buf, NULL, true);
+    }
+
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_mem_to_buf()
 
-void
+int
 cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
                          cyg_uint8               buf_num,
-                         cyg_uint32              page_num,
-                         cyg_bool                wait) 
+                         cyg_uint32              page_num)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
-
+    
+    // Check if the page number is inside the flash
     if (page_num >= dev->info->page_count)
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
     
+    // Compose DataFlash command
+
     if (1 == buf_num)      cmd_buf[0] = DF_TRANSFER_TO_BUF1_CMD;
     else if (2 == buf_num) cmd_buf[0] = DF_TRANSFER_TO_BUF2_CMD;
     else 
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
 
     df_compose_addr(dev, cmd_buf, page_num, 0);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
 
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+        // Mark the target buffer as busy
+        df_set_busy_buf(dev, buf_num);
 
-    if (wait)
-        df_wait_ready(dev);
+        // Wait if in blocking mode     
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
 
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_program_buf()
 
-void
+int
 cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
                           cyg_uint8               buf_num,
                           cyg_uint32              page_num,
-                          cyg_bool                erase,
-                          cyg_bool                wait)
+                          cyg_bool                erase)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
-
+    
+    // Check if the page number is inside the flash
     if (page_num >= dev->info->page_count)
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
     
+    // Compose DataFlash command
+
     if (erase)
     {
         if (1 == buf_num)      cmd_buf[0] = DF_BUF1_PROG_W_ERASE_CMD;
         else if (2 == buf_num) cmd_buf[0] = DF_BUF2_PROG_W_ERASE_CMD; 
         else 
-            return;
+            return CYG_DATAFLASH_ERR_INVALID;
     }
     else
     {
         if (1 == buf_num)      cmd_buf[0] = DF_BUF1_PROG_WO_ERASE_CMD;
         else if (2 == buf_num) cmd_buf[0] = DF_BUF2_PROG_WO_ERASE_CMD; 
         else 
-            return;
+            return CYG_DATAFLASH_ERR_INVALID;
     }
     
     df_compose_addr(dev, cmd_buf, page_num, 0);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
-
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
     
-    if (wait)
-        df_wait_ready(dev);
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Mark the target buffer as busy    
+        df_set_busy_buf(dev, buf_num);
 
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+    
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_compare_buf()
 
-cyg_bool
+int
 cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
                           cyg_uint8               buf_num,
                           cyg_uint32              page_num)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
     df_status_t     status;
 
+    // Check if the page number is inside the flash
     if (page_num >= dev->info->page_count)
-        return false;
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
 
     if (1 == buf_num)      cmd_buf[0] = DF_BUF1_COMPARE_CMD;
     else if (2 == buf_num) cmd_buf[0] = DF_BUF2_COMPARE_CMD; 
     else 
-        return false;
+        return CYG_DATAFLASH_ERR_INVALID;
 
     df_compose_addr(dev, cmd_buf, page_num, 0);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
-    df_wait_ready(dev);
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+   
+    if (CYG_DATAFLASH_ERR_OK == err)
+    { 
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Wait for the device to become ready
+        df_set_busy(dev);
+        err = df_wait_ready(dev);
     
-    status = df_read_status(dev);
+        // Read the result of memory compare
+
+        if (CYG_DATAFLASH_ERR_OK == err)
+        {
+            status = df_read_status(dev);
+            if (status.compare_err)
+                err = CYG_DATAFLASH_ERR_COMPARE;
+        }
+    }
 
     cyg_spi_transaction_end(spi_dev);
 
-    return (!status.compare_err);
+    return err; 
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_erase()
 
-void
+int
 cyg_dataflash_erase(cyg_dataflash_device_t *dev,
-                    cyg_uint32              page_num,
-                    cyg_bool                wait)
+                    cyg_uint32              page_num)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
 
+    // Check if the page number is inside the flash
     if (page_num >= dev->info->page_count)
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
 
     cmd_buf[0] = DF_PAGE_ERASE_CMD;
     df_compose_addr(dev, cmd_buf, page_num, 0);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+    
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
 
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
-
-    if (wait)
-        df_wait_ready(dev);
+        // Set device state to busy
+        df_set_busy_buf(dev, DATA_BUF_NONE);
+        
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
     
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_erase_block()
 
-void
+int
 cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
-                          cyg_uint32              block_num,
-                          cyg_bool                wait)
+                          cyg_uint32              block_num)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
 
+    // Check if the block number is inside the flash
     if (block_num >= (dev->info->page_count >> 3))
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
 
     cmd_buf[0] = DF_BLOCK_ERASE_CMD;
     df_compose_addr(dev, cmd_buf, block_num << 3, 0);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
 
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
 
-    if (wait)
-        df_wait_ready(dev);
+        // Set device state to busy
+        df_set_busy_buf(dev, DATA_BUF_NONE);
+ 
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
 
-    cyg_spi_transaction_end(spi_dev);
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_auto_rewrite()
 
-void
+int
 cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
                            cyg_uint8               buf_num,
-                           cyg_uint32              page_num,
-                           cyg_bool                wait)
+                           cyg_uint32              page_num)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
 
+    // Check if the page number is inside the flash
     if (page_num >= dev->info->page_count)
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
 
     if (1 == buf_num)      cmd_buf[0] = DF_AUTO_REWRITE_THROUGH_BUF1_CMD;
     else if (2 == buf_num) cmd_buf[0] = DF_AUTO_REWRITE_THROUGH_BUF2_CMD; 
     else 
-        return;
+        return CYG_DATAFLASH_ERR_INVALID;
 
     df_compose_addr(dev, cmd_buf, page_num, 0);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
 
-    cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+        // Mark the target buffer as busy
+        df_set_busy_buf(dev, buf_num);
 
-    if (wait)
-        df_wait_ready(dev);
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
     
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_read()
 
-void
+int
 cyg_dataflash_read(cyg_dataflash_device_t *dev, 
                    cyg_uint8              *buf, 
                    cyg_uint32              len, 
                    cyg_uint32              pos)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[8];
     cyg_uint32      page_num, page_pos;
 
+    // Calculate page number and position from given absolute position
+
     page_num = pos / dev->info->page_size;
     page_pos = pos % dev->info->page_size;
 
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count) 
+        return CYG_DATAFLASH_ERR_INVALID;
+    
+    // Compose DataFlash command
+
     cmd_buf[0] = DF_CONT_ARRAY_READ_CMD;
     df_compose_addr(dev, cmd_buf, page_num, page_pos);
 
     cyg_spi_transaction_begin(spi_dev);
-    df_wait_ready(dev);
-    cyg_spi_transaction_transfer(spi_dev, true, 8, cmd_buf, NULL, false);
-    cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {    
+        // Send the command and read data from DataFlash main memory
+        
+        cyg_spi_transaction_transfer(spi_dev, true, 8, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+    }
+    
     cyg_spi_transaction_end(spi_dev);
+
+    return err;
 }
 
 //----------------------------------------------------------------------------
 // cyg_dataflash_program()
 
-cyg_bool
+int
 cyg_dataflash_program(cyg_dataflash_device_t *dev, 
                       const cyg_uint8        *buf, 
                       cyg_uint32             *len, 
@@ -604,80 +806,119 @@ cyg_dataflash_program(cyg_dataflash_devi
                       cyg_bool                verify)
 {
     cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
     cyg_uint8       cmd_buf[4];
     cyg_uint32      count, page_num, page_pos;
-    cyg_bool        res = true;
-    
+   
+    // Calculate page number and position from given absolute position
+
     page_num = pos / dev->info->page_size;
     page_pos = pos % dev->info->page_size;
     count    = *len;
-    
-//    diag_printf("\nWrite start at page=%d pos=%d size=%d\n", page_num, page_pos, *len);
 
     cyg_spi_transaction_begin(spi_dev);
 
-    df_wait_ready(dev);
+    // Wait for device to become ready
+    err = df_wait_ready(dev);
+    if (CYG_DATAFLASH_ERR_OK != err)
+        goto out;
+   
+    // Loop until count bytes written
 
     while (count > 0)
     { 
         df_status_t status;
         cyg_uint32  size;
 
+        // Check if the current page number is inside the flash 
+        if (page_num >= dev->info->page_count)
+        {
+            err = CYG_DATAFLASH_ERR_INVALID;
+            goto out;
+        }
+       
+        // Calculate the number of bytes to write to the current page
         if ((page_pos + count) > dev->info->page_size)
             size = dev->info->page_size - page_pos;
         else
             size = count;
         
-//        diag_printf("Writing page=%d size=%d [%02X]\n", page_num, size, *buf);
-    
+        // Compose DataFlash command address
         df_compose_addr(dev, cmd_buf, page_num, page_pos);
-        
+       
+        // If we are not rewritting the whole page, then first 
+        // read the old data from main memory to the target buffer
+
         if (page_pos > 0 || size < dev->info->page_size)
         {
             cmd_buf[0] = DF_TRANSFER_TO_BUF1_CMD;
             cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
-            df_wait_ready(dev);
+            df_set_busy(dev);
+            err = df_wait_ready(dev);
+            if (CYG_DATAFLASH_ERR_OK != err)
+                goto out;
         }
-        
+       
+        // Write data to the target buffer
+
         cmd_buf[0] = DF_BUF1_WRITE_CMD;
         cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
-        cyg_spi_transaction_transfer(spi_dev, dev->polled, size, buf, NULL, true);
-        df_wait_ready(dev);
-
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, 
+                                     size, buf, NULL, true);
+        df_set_busy(dev);
+        err = df_wait_ready(dev);
+        if (CYG_DATAFLASH_ERR_OK != err)
+            goto out;
+       
+        // Program data from the target buffer to main memory 
+        // and perform an erase before if requested
+        
         if (erase)
             cmd_buf[0] = DF_BUF1_PROG_W_ERASE_CMD;
         else
             cmd_buf[0] = DF_BUF1_PROG_WO_ERASE_CMD;
 
         cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
-        df_wait_ready(dev);
-   
+        df_set_busy(dev);
+        err = df_wait_ready(dev);
+        if (CYG_DATAFLASH_ERR_OK != err)
+            goto out;
+        
+        // Compare the target buffer contents with the freshly 
+        // written main memory page (if requested)
+        
         if (verify)
         { 
             cmd_buf[0] = DF_BUF1_COMPARE_CMD;
             cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
-            df_wait_ready(dev);
-    
+            df_set_busy(dev);
+            err = df_wait_ready(dev);
+            if (CYG_DATAFLASH_ERR_OK != err)
+                goto out;
+            
             status = df_read_status(dev);
 
             if (status.compare_err)
             {
-                res = false;
-                break;
+                err = CYG_DATAFLASH_ERR_COMPARE;
+                goto out;
             }
         }
 
+        // Adjust running values
+
         page_pos  = 0;
         page_num += 1;
         count    -= size;
         buf      += size;
     }
 
+out:
     cyg_spi_transaction_end(spi_dev);
 
     *len -= count;
     
-    return res; 
+    return err; 
 }
 
 //----------------------------------------------------------------------------
--- a/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
+++ b/packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
@@ -62,20 +62,12 @@
 
 // -------------------------------------------------------------------------- 
 
-static cyg_uint32
-get_page_2size_log(cyg_uint32 size)
-{
-    cyg_uint32 i;
+#define RETURN_ON_ERROR(_op_) \
+    if (CYG_DATAFLASH_ERR_OK != (err = _op_)) return err
 
-    i = 0;
-    while (size != 0)
-    {
-        size >>= 1;
-        i++;
-    } 
-    return (i-1);
-}
-
+#define GOTO_ON_ERROR(_op_) \
+    if (CYG_DATAFLASH_ERR_OK != (err = _op_)) goto on_error
+    
 // -------------------------------------------------------------------------- 
 
 static int 
@@ -92,28 +84,24 @@ df_flash_init(struct cyg_flash_dev *dev)
     priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv; 
     df_dev = &priv->dev;
    
-//    diag_printf("\nDF INIT\n");
-
 #ifdef CYGPKG_REDBOOT    
-    if (!cyg_dataflash_init(*(config->spi_dev), true, df_dev))
+    if (cyg_dataflash_init(*(config->spi_dev), true, df_dev))
 #else
-    if (!cyg_dataflash_init(*(config->spi_dev), false, df_dev))
+    if (cyg_dataflash_init(*(config->spi_dev), false, df_dev))
 #endif        
-        return CYG_FLASH_ERR_DRV_WRONG_PART; 
-   
+        return CYG_DATAFLASH_ERR_WRONG_PART; 
+  
+    cyg_dataflash_set_blocking_operation(df_dev, true);
+
     sector_cnt = cyg_dataflash_get_sector_count(df_dev);
 
-//    diag_printf("\nDF INIT sector cnt = %d\n", sector_cnt);
-    
     if (config->end_sector < 0)
        config->end_sector = sector_cnt - 1; 
     
-//    diag_printf("\nDF INIT end sector = %d\n", config->end_sector);
-
     if (config->start_sector >= sector_cnt ||
         config->end_sector   >= sector_cnt ||
         config->end_sector   <  config->start_sector)
-        return CYG_FLASH_ERR_INVALID;        
+        return CYG_DATAFLASH_ERR_INVALID;        
     
     priv->start_page = cyg_dataflash_get_block_size(df_dev) *
         cyg_dataflash_get_sector_start(df_dev, config->start_sector);
@@ -122,30 +110,17 @@ df_flash_init(struct cyg_flash_dev *dev)
         (cyg_dataflash_get_sector_start(df_dev, config->end_sector) +
          cyg_dataflash_get_sector_size(df_dev, config->end_sector));
     
-//    diag_printf("\nDF INIT start page = %d end page = %d\n", 
-//            priv->start_page, priv->end_page);
-    
-    priv->page_2size_log = 
-        get_page_2size_log(cyg_dataflash_get_page_size(df_dev));
-            
-//    diag_printf("\nDF INIT page_2size_log = %d\n", priv->page_2size_log);
-    
     dev->start = (cyg_flashaddr_t)config->address;
     dev->end   = (cyg_flashaddr_t)(config->address + 
-        ((priv->end_page - priv->start_page) << priv->page_2size_log));
-
-//    diag_printf("\nDF INIT start = %x end = %x\n", 
-//            dev->start, dev->end);
+        ((priv->end_page - priv->start_page) *
+         cyg_dataflash_get_page_size(df_dev)) - 1);
 
     dev->num_block_infos     = 1;
     dev->block_info          = block_info;
-    block_info[0].block_size = 1 << priv->page_2size_log;
+    block_info[0].block_size = cyg_dataflash_get_page_size(df_dev);
     block_info[0].blocks     = priv->end_page - priv->start_page;
 
-//    diag_printf("\nDF INIT block_size = %d blocks = %d\n",
-//           block_info[0].block_size, block_info[0].blocks); 
-    
-    return CYG_FLASH_ERR_OK;
+    return CYG_DATAFLASH_ERR_OK;
 }
 
 static size_t 
@@ -161,20 +136,23 @@ df_flash_erase_block(struct cyg_flash_de
     cyg_dataflash_flash_dev_config_t *config;
     cyg_dataflash_flash_dev_priv_t   *priv;
     cyg_uint32 page;
-
+    int        err;
+    
     config = (cyg_dataflash_flash_dev_config_t *) dev->config;
     priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
     
-    page = priv->start_page + 
-        ((base - config->address) >> priv->page_2size_log); 
+    page = priv->start_page + ((base - config->address) / 
+           cyg_dataflash_get_page_size(&priv->dev)); 
    
-//    diag_printf("\nDF ERASE base = %x page = %d\n", base, page);
-
-    cyg_dataflash_aquire(&priv->dev);    
-    cyg_dataflash_erase(&priv->dev, page, true); 
+    RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev)                       );
+    GOTO_ON_ERROR(   cyg_dataflash_erase(&priv->dev, page)                  ); 
+    RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev)                      );
+    
+    return CYG_DATAFLASH_ERR_OK;
+    
+on_error:
     cyg_dataflash_release(&priv->dev);
-    
-    return CYG_FLASH_ERR_OK;
+    return err;
 }
 
 static int
@@ -185,23 +163,27 @@ df_flash_program(struct cyg_flash_dev *d
 {
     cyg_dataflash_flash_dev_config_t *config;
     cyg_dataflash_flash_dev_priv_t   *priv;
-    cyg_uint32 page;
+    cyg_uint32 page, pos;
+    int        err;
  
     config = (cyg_dataflash_flash_dev_config_t *) dev->config;
     priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
     
-    page = priv->start_page + 
-        ((base - config->address) >> priv->page_2size_log); 
- 
-//    diag_printf("\nDF PROGRAM base = %x page = %d len = %d\n", base, page, len);
+    page = priv->start_page + ((base - config->address) / 
+           cyg_dataflash_get_page_size(&priv->dev)); 
+    pos  = (base - config->address) % cyg_dataflash_get_page_size(&priv->dev);
+    
+    RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev)                       );
+    GOTO_ON_ERROR(   cyg_dataflash_mem_to_buf(&priv->dev, 1, page)          );
+    GOTO_ON_ERROR(   cyg_dataflash_write_buf(&priv->dev, 1, data, len, pos) );
+    GOTO_ON_ERROR(   cyg_dataflash_program_buf(&priv->dev, 1, page, true)   );
+    RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev)                      );
 
-    cyg_dataflash_aquire(&priv->dev);    
-    cyg_dataflash_mem_to_buf(&priv->dev, 1, page, true);
-    cyg_dataflash_write_buf(&priv->dev, 1, data, len, 0);
-    cyg_dataflash_program_buf(&priv->dev, 1, page, true, true);    
+    return CYG_DATAFLASH_ERR_OK;
+
+on_error:
     cyg_dataflash_release(&priv->dev);
-
-    return CYG_FLASH_ERR_OK;
+    return err;
 }
 
 static int 
@@ -212,42 +194,54 @@ df_flash_read(struct cyg_flash_dev   *de
 {
     cyg_dataflash_flash_dev_config_t *config;
     cyg_dataflash_flash_dev_priv_t   *priv;
-    cyg_uint32 page;
+    cyg_uint32 page, pos;
+    int        err;
  
     config = (cyg_dataflash_flash_dev_config_t *) dev->config;
     priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
     
-    page = priv->start_page + 
-        ((base - config->address) >> priv->page_2size_log); 
+    page = priv->start_page + ((base - config->address) / 
+           cyg_dataflash_get_page_size(&priv->dev)); 
+    pos  = (base - config->address) % cyg_dataflash_get_page_size(&priv->dev);
  
-//    diag_printf("\nDF READ base = %x page = %d len = %d\n", base, page, len);
+    RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev)                       );
+    GOTO_ON_ERROR(   cyg_dataflash_mem_to_buf(&priv->dev, 1, page)          );
+    GOTO_ON_ERROR(   cyg_dataflash_read_buf(&priv->dev, 1, data, len, pos)  );
+    RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev)                      );
+    
+    return CYG_DATAFLASH_ERR_OK;
 
-    cyg_dataflash_aquire(&priv->dev);    
-    cyg_dataflash_mem_to_buf(&priv->dev, 1, page, true);
-    cyg_dataflash_read_buf(&priv->dev, 1, data, len, 0);
+on_error:
     cyg_dataflash_release(&priv->dev);
-    
-    return CYG_FLASH_ERR_OK;
+    return err;    
 }
 
 static int 
 df_flash_hwr_map_error(struct cyg_flash_dev *dev, int err)
 {
-    return err;
+    switch (err)
+    {
+        case CYG_DATAFLASH_ERR_OK:         return CYG_FLASH_ERR_OK; 
+        case CYG_DATAFLASH_ERR_INVALID:    return CYG_FLASH_ERR_INVALID;  
+        case CYG_DATAFLASH_ERR_WRONG_PART: return CYG_FLASH_ERR_DRV_WRONG_PART; 
+        case CYG_DATAFLASH_ERR_TIMEOUT:    return CYG_FLASH_ERR_DRV_TIMEOUT;
+        case CYG_DATAFLASH_ERR_COMPARE:    return CYG_FLASH_ERR_DRV_VERIFY; 
+        default:                           return CYG_FLASH_ERR_INVALID;
+    }
 }
 
 static int 
 df_flash_block_lock(struct cyg_flash_dev   *dev, 
                     const  cyg_flashaddr_t  block_base)
 {
-    return CYG_FLASH_ERR_INVALID;
+    return CYG_DATAFLASH_ERR_INVALID;
 }
 
 static int 
 df_flash_block_unlock(struct cyg_flash_dev  *dev, 
                       const cyg_flashaddr_t  block_base)
 {
-    return CYG_FLASH_ERR_INVALID;
+    return CYG_DATAFLASH_ERR_INVALID;
 }
 
 // --------------------------------------------------------------------------