Index: devs/flash/atmel/dataflash/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/Attic/ChangeLog,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 ChangeLog --- devs/flash/atmel/dataflash/current/ChangeLog 7 Oct 2004 07:47:04 -0000 1.1.2.2 +++ devs/flash/atmel/dataflash/current/ChangeLog 7 Oct 2004 19:58:12 -0000 @@ -1,3 +1,13 @@ +2004-10-07 Savin Zlobec + + * 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 * cdl/devs_flash_atmel_dataflash.cdl: Remove Index: devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/cdl/Attic/devs_flash_atmel_dataflash.cdl,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 devs_flash_atmel_dataflash.cdl --- devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl 7 Oct 2004 07:47:05 -0000 1.1.2.2 +++ devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl 7 Oct 2004 19:58:12 -0000 @@ -51,6 +51,7 @@ 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 Index: devs/flash/atmel/dataflash/current/include/dataflash.h =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/include/Attic/dataflash.h,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 dataflash.h --- devs/flash/atmel/dataflash/current/include/dataflash.h 5 Oct 2004 09:19:16 -0000 1.1.2.1 +++ devs/flash/atmel/dataflash/current/include/dataflash.h 7 Oct 2004 19:58:12 -0000 @@ -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_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 @@ 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 @@ 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 int 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_program_buf(cyg_dataflash_device_t *dev, +externC int cyg_dataflash_erase_block(cyg_dataflash_device_t *dev, + cyg_uint32 block_num); + +externC int cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev, cyg_uint8 buf_num, - cyg_uint32 page_num, - cyg_bool erase, - cyg_bool wait); - -externC cyg_bool cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev, - cyg_uint8 buf_num, - cyg_uint32 page_num); - -externC void cyg_dataflash_erase(cyg_dataflash_device_t *dev, - cyg_uint32 page_num, - cyg_bool wait); - -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 void 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); + cyg_uint32 page_num); + +externC int cyg_dataflash_read(cyg_dataflash_device_t *dev, + cyg_uint8 *buf, + cyg_uint32 len, + cyg_uint32 pos); + +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); //---------------------------------------------------------------------------- Index: devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/src/Attic/devs_flash_atmel_dataflash.c,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 devs_flash_atmel_dataflash.c --- devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c 5 Oct 2004 09:19:16 -0000 1.1.2.1 +++ devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c 7 Oct 2004 19:58:13 -0000 @@ -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 @@ 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 @@ { 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 @@ //---------------------------------------------------------------------------- // 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_aquire() - -void -cyg_dataflash_aquire(cyg_dataflash_device_t *dev) -{ - while (!cyg_drv_mutex_lock(&dev->lock)); -} - -//---------------------------------------------------------------------------- -// cyg_dataflash_release() +// cyg_dataflash_wait_ready() -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_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_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); - 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); + + // 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); - - 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 (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); + + 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 (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); + // 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_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); - 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); + + // 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_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; } //---------------------------------------------------------------------------- Index: devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/atmel/dataflash/current/src/Attic/devs_flash_atmel_dataflash_flash_dev_funs.c,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 devs_flash_atmel_dataflash_flash_dev_funs.c --- devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c 5 Oct 2004 09:19:16 -0000 1.1.2.1 +++ devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c 7 Oct 2004 19:58:14 -0000 @@ -62,20 +62,12 @@ // -------------------------------------------------------------------------- -static cyg_uint32 -get_page_2size_log(cyg_uint32 size) -{ - cyg_uint32 i; - - i = 0; - while (size != 0) - { - size >>= 1; - i++; - } - return (i-1); -} +#define RETURN_ON_ERROR(_op_) \ + if (CYG_DATAFLASH_ERR_OK != (err = _op_)) return err +#define GOTO_ON_ERROR(_op_) \ + if (CYG_DATAFLASH_ERR_OK != (err = _op_)) goto on_error + // -------------------------------------------------------------------------- static int @@ -92,28 +84,24 @@ 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 @@ (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 @@ 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); - cyg_dataflash_release(&priv->dev); + 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_FLASH_ERR_OK; + return CYG_DATAFLASH_ERR_OK; + +on_error: + cyg_dataflash_release(&priv->dev); + return err; } static int @@ -185,23 +163,27 @@ { 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); - cyg_dataflash_release(&priv->dev); + return CYG_DATAFLASH_ERR_OK; - return CYG_FLASH_ERR_OK; +on_error: + cyg_dataflash_release(&priv->dev); + return err; } static int @@ -212,42 +194,54 @@ { 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; } // --------------------------------------------------------------------------