diff packages/io/flash/current/src/flash.c @ 115:6ed91473a1cd ecos-sw-2000-08-21

Merge from eCos master repository on 2000-08-21-22:40:54-BST
author jlarmour
date Fri, 25 Aug 2000 17:32:38 +0000
parents
children bd1a71e3e476
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/io/flash/current/src/flash.c
@@ -0,0 +1,208 @@
+//==========================================================================
+//
+//      flash.c
+//
+//      Flash programming
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         2000-07-26
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+
+#define  _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+struct flash_info flash_info;
+
+int
+flash_init(void *work_space, int work_space_size)
+{
+    int err;
+
+    if (flash_info.init) return FLASH_ERR_OK;
+    flash_info.work_space = work_space;
+    flash_info.work_space_size = flash_info.work_space_size;
+    if ((err = flash_hwr_init()) != FLASH_ERR_OK) {
+        return err;
+    }
+    flash_info.block_mask = ~(flash_info.block_size-1);
+    flash_info.init = 1;
+    return FLASH_ERR_OK;
+}
+
+int
+flash_verify_addr(void *target)
+{
+    if (!flash_info.init) {
+        return FLASH_ERR_NOT_INIT;
+    }
+    if (((unsigned long)target >= (unsigned long)flash_info.start) &&
+        ((unsigned long)target < (unsigned long)flash_info.end)) {
+        return FLASH_ERR_OK;
+    } else {
+        return FLASH_ERR_INVALID;
+    }
+}
+
+int
+flash_get_limits(void *target, void **start, void **end)
+{
+    if (!flash_info.init) {
+        return FLASH_ERR_NOT_INIT;
+    }
+    *start = flash_info.start;
+    *end = flash_info.end;
+    return FLASH_ERR_OK;
+}
+
+int
+flash_get_block_info(int *block_size, int *blocks)
+{
+    if (!flash_info.init) {
+        return FLASH_ERR_NOT_INIT;
+    }
+    *block_size = flash_info.block_size;
+    *blocks = flash_info.blocks;
+    return FLASH_ERR_OK;
+}
+
+int
+flash_erase(void *addr, int len, void **err_addr)
+{
+    unsigned short *block, *end_addr;
+    int stat = 0;
+    extern char flash_erase_block, flash_erase_block_end;
+    int code_len;
+    typedef int code_fun(unsigned short *);
+    code_fun *_flash_erase_block;
+
+    if (!flash_info.init) {
+        return FLASH_ERR_NOT_INIT;
+    }
+
+    // Copy 'erase' code to RAM for execution
+    code_len = (unsigned long)&flash_erase_block_end - (unsigned long)&flash_erase_block;
+    _flash_erase_block = (code_fun *)flash_info.work_space;
+    memcpy(_flash_erase_block, &flash_erase_block, code_len);
+    HAL_DCACHE_SYNC();  // Should guarantee this code will run
+
+    block = (unsigned short *)((unsigned long)addr & flash_info.block_mask);
+    end_addr = (unsigned short *)((unsigned long)addr+len);
+
+    printf("... Erase from %p-%p: ", block, end_addr);
+
+    while (block < end_addr) {
+        stat = (*_flash_erase_block)(block);
+        stat = flash_hwr_map_error(stat);
+        if (stat) {
+            *err_addr = (void *)block;
+            break;
+        }
+        block += flash_info.block_size / sizeof(*block);
+        printf(".");
+    }
+    printf("\n");
+    return (stat);
+}
+
+int
+flash_program(void *_addr, void *_data, int len, void **err_addr)
+{
+    int stat = 0;
+    int code_len, size;
+    extern char flash_program_buf, flash_program_buf_end;
+    typedef int code_fun(unsigned short *, unsigned short *, int);
+    code_fun *_flash_program_buf;
+    unsigned short *addr = (unsigned short *)_addr;
+    unsigned short *data = (unsigned short *)_data;
+
+    if (!flash_info.init) {
+        return FLASH_ERR_NOT_INIT;
+    }
+
+    // Copy 'program' code to RAM for execution
+    code_len = (unsigned long)&flash_program_buf_end - (unsigned long)&flash_program_buf;
+    _flash_program_buf = (code_fun *)flash_info.work_space;
+    memcpy(_flash_program_buf, &flash_program_buf, code_len);
+    HAL_DCACHE_SYNC();  // Should guarantee this code will run
+
+    printf("... Program from %p-%p at %p: ", data, ((unsigned long)data)+len, addr);
+
+    while (len > 0) {
+        size = len;
+        if (size > flash_info.block_size) size = flash_info.block_size;
+        stat = (*_flash_program_buf)(addr, data, size);
+        stat = flash_hwr_map_error(stat);
+        if (stat) {
+            *err_addr = (void *)addr;
+            break;
+        }
+        printf(".");
+        len -= size;
+        addr += size/sizeof(*addr);
+        data += size/sizeof(*data);
+    }
+    printf("\n");
+    return (stat);
+}
+
+char *
+flash_errmsg(int err)
+{
+    switch (err) {
+    case FLASH_ERR_OK:
+        return "No error - operation complete";
+    case FLASH_ERR_INVALID:
+        return "Invalid FLASH address";
+    case FLASH_ERR_ERASE:
+        return "Error trying to erase";
+    case FLASH_ERR_LOCK:
+        return "Error trying to lock/unlock";
+    case FLASH_ERR_PROGRAM:
+        return "Error trying to program";
+    case FLASH_ERR_PROTOCOL:
+        return "Generic error";
+    case FLASH_ERR_PROTECT:
+        return "Device/region is write-protected";
+    case FLASH_ERR_NOT_INIT:
+        return "FLASH sub-system not initialized";
+    default:
+        return "Unknown error";
+    }
+}