/*H***************************************************************************
*
* $Archive:: /boards/dsk6455_v1/lib/DSK6455BSL/dsk6455_flash_erase.c          $
* $Revision:: 1                                                               $
* $Date:: 4/11/06 9:46a                                                       $
*
* DESCRIPTION: DSK6455_FLASH_erase() implementation.
* 
* NOTES :  BSL Version# 3.20 
*
* (C) Copyright 2005 by Spectrum Digital Incorporated
* All rights reserved
*
*H***************************************************************************/

#include "dsk6455.h"
#include "dsk6455_flash.h"

/* Constant table containing end address of each sector */
static Uint32 sector_end[DSK6455_FLASH_SECTORS] = {
    DSK6455_FLASH_BASE + 0x00ffff, /* Sector  0 */
    DSK6455_FLASH_BASE + 0x01ffff, /* Sector  1 */
    DSK6455_FLASH_BASE + 0x02ffff, /* Sector  2 */
    DSK6455_FLASH_BASE + 0x03ffff, /* Sector  3 */
    DSK6455_FLASH_BASE + 0x04ffff, /* Sector  4 */
    DSK6455_FLASH_BASE + 0x05ffff, /* Sector  5 */
    DSK6455_FLASH_BASE + 0x06ffff, /* Sector  6 */
    DSK6455_FLASH_BASE + 0x07ffff, /* Sector  7 */
	DSK6455_FLASH_BASE + 0x08ffff, /* Sector  8 */
    DSK6455_FLASH_BASE + 0x09ffff, /* Sector  9 */
    DSK6455_FLASH_BASE + 0x0affff, /* Sector 10 */
    DSK6455_FLASH_BASE + 0x0bffff, /* Sector 11 */
    DSK6455_FLASH_BASE + 0x0cffff, /* Sector 12 */
    DSK6455_FLASH_BASE + 0x0dffff, /* Sector 13 */
    DSK6455_FLASH_BASE + 0x0effff, /* Sector 14 */
    DSK6455_FLASH_BASE + 0x0fffff, /* Sector 15 */
    DSK6455_FLASH_BASE + 0x10ffff, /* Sector 16 */
    DSK6455_FLASH_BASE + 0x11ffff, /* Sector 17 */
    DSK6455_FLASH_BASE + 0x12ffff, /* Sector 18 */
    DSK6455_FLASH_BASE + 0x13ffff, /* Sector 19 */
    DSK6455_FLASH_BASE + 0x14ffff, /* Sector 20 */
    DSK6455_FLASH_BASE + 0x15ffff, /* Sector 21 */
    DSK6455_FLASH_BASE + 0x16ffff, /* Sector 22 */
    DSK6455_FLASH_BASE + 0x17ffff, /* Sector 23 */
	DSK6455_FLASH_BASE + 0x18ffff, /* Sector 24 */
    DSK6455_FLASH_BASE + 0x19ffff, /* Sector 25 */
    DSK6455_FLASH_BASE + 0x1affff, /* Sector 26 */
    DSK6455_FLASH_BASE + 0x1bffff, /* Sector 27 */
    DSK6455_FLASH_BASE + 0x1cffff, /* Sector 28 */
    DSK6455_FLASH_BASE + 0x1dffff, /* Sector 29 */
    DSK6455_FLASH_BASE + 0x1effff, /* Sector 30 */
    DSK6455_FLASH_BASE + 0x1fffff, /* Sector 31 */
    DSK6455_FLASH_BASE + 0x20ffff, /* Sector 32 */
    DSK6455_FLASH_BASE + 0x21ffff, /* Sector 33 */
    DSK6455_FLASH_BASE + 0x22ffff, /* Sector 34 */
    DSK6455_FLASH_BASE + 0x23ffff, /* Sector 35 */
    DSK6455_FLASH_BASE + 0x24ffff, /* Sector 36 */
    DSK6455_FLASH_BASE + 0x25ffff, /* Sector 37 */
    DSK6455_FLASH_BASE + 0x26ffff, /* Sector 38 */
    DSK6455_FLASH_BASE + 0x27ffff, /* Sector 39 */
	DSK6455_FLASH_BASE + 0x28ffff, /* Sector 40 */
    DSK6455_FLASH_BASE + 0x29ffff, /* Sector 41 */
    DSK6455_FLASH_BASE + 0x2affff, /* Sector 42 */
    DSK6455_FLASH_BASE + 0x2bffff, /* Sector 43 */
    DSK6455_FLASH_BASE + 0x2cffff, /* Sector 44 */
    DSK6455_FLASH_BASE + 0x2dffff, /* Sector 45 */
    DSK6455_FLASH_BASE + 0x2effff, /* Sector 46 */
    DSK6455_FLASH_BASE + 0x2fffff, /* Sector 47 */
    DSK6455_FLASH_BASE + 0x30ffff, /* Sector 48 */
    DSK6455_FLASH_BASE + 0x31ffff, /* Sector 49 */
    DSK6455_FLASH_BASE + 0x32ffff, /* Sector 50 */
    DSK6455_FLASH_BASE + 0x33ffff, /* Sector 51 */
    DSK6455_FLASH_BASE + 0x34ffff, /* Sector 52 */
    DSK6455_FLASH_BASE + 0x35ffff, /* Sector 53 */
    DSK6455_FLASH_BASE + 0x36ffff, /* Sector 54 */
    DSK6455_FLASH_BASE + 0x37ffff, /* Sector 55 */
	DSK6455_FLASH_BASE + 0x38ffff, /* Sector 56 */
    DSK6455_FLASH_BASE + 0x39ffff, /* Sector 57 */
    DSK6455_FLASH_BASE + 0x3affff, /* Sector 58 */
    DSK6455_FLASH_BASE + 0x3bffff, /* Sector 59 */
    DSK6455_FLASH_BASE + 0x3cffff, /* Sector 60 */
    DSK6455_FLASH_BASE + 0x3dffff, /* Sector 61 */
    DSK6455_FLASH_BASE + 0x3effff, /* Sector 62 */
    DSK6455_FLASH_BASE + 0x3fffff  /* Sector 63 */
};


/* Erase a segment of Flash memory */
void DSK6455_FLASH_erase(Uint32 start, Uint32 length)
{
    Int16 i;
    Uint8 *pdata;
    Uint32 sector_base, end;

    /* Calculate extents of range to erase */
    end = start + length - 1;

    /* Walk through each sector, erase any sectors within range */
    sector_base = DSK6455_FLASH_BASE;
    for (i = 0; i < DSK6455_FLASH_SECTORS; i++)
    {
        if ( ( ( sector_base >= start ) || ( sector_end[i] >= start ) ) &&
             ( ( sector_base <= end )   || ( sector_end[i] <= end ) ) )
        {
            /* Start sector erase sequence */
            *((Uint8 *)DSK6455_FLASH_BASE) = 0xaa;
            *((Uint8 *)DSK6455_FLASH_BASE) = 0x55;
            *((Uint8 *)DSK6455_FLASH_BASE) = 0x80;
            *((Uint8 *)DSK6455_FLASH_BASE) = 0xaa;
            *((Uint8 *)DSK6455_FLASH_BASE) = 0x55;

            /* Start erase at sector address */
            pdata = (Uint8 *)sector_base;
            *pdata = 0x30;

            /* Wait for erase to complete */
            while (1)
                if (*pdata & 0x80)
                    break;

            /* Put back in read mode */
            *((Uint8 *)DSK6455_FLASH_BASE) = 0xf0;
        }

        /* Advance to next sector */
        sector_base = sector_end[i] + 1;
    }
}
