コード例 #1
0
ファイル: flash_lock_block.c プロジェクト: LucidOne/Rovio
int
flash_lock_block(volatile unsigned char *block)
{
    volatile unsigned char *ROM;
    unsigned short stat;
    int timeout = 5000000;
    int cache_on;

    ROM = FLASH_P2V((unsigned long)block & 0xFF800000);

    HAL_DCACHE_IS_ENABLED(cache_on);
    if (cache_on) {
        HAL_DCACHE_SYNC();
        HAL_DCACHE_DISABLE();
    }

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

    // Set lock bit
    FLASH_P2V(block)[0] = FLASH_Set_Lock;
    FLASH_P2V(block)[0] = FLASH_Set_Lock_Confirm;  // Confirmation
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) break;
    }

    // Restore ROM to "normal" mode
    ROM[0] = FLASH_Reset;

    if (cache_on) {
        HAL_DCACHE_ENABLE();
    }

    return stat;
}
コード例 #2
0
/* check block lock configuration and display status of 64 blocks, 1=locked, 0=unlocked */
void check_lock_bit_status (void)
{

	int block;

	volatile FLASH_TYPE *block_addr;

	/* address bit A0 is not used when obtaining identifier codes */

/* 11/01/00 */
/*	unsigned long addr = 0x2<<1; */
	unsigned long addr = 0x4;

	unsigned char block_lock_status[64];

	block_addr = (volatile FLASH_TYPE *) addr; 

/*	printf("Checking lock status of %d blocks, 1=locked, 0=unlocked...\n", block ); */

		/* address bit A0 is not used when obtaining identifier codes */
	for (block=0; block<=63; block++)
	{

		*FLASH_P2V(block_addr) = READ_ID_CMD; 

		block_lock_status[block] = *FLASH_P2V(block_addr);

		*FLASH_P2V(block_addr) = RESET_CMD;
		
		do_nothing();

/* 11/01/00 */
		do_nothing();

		block_lock_status[block] &= 0x01;	/* Checking lock status of block, 1=locked, 0=unlocked */

		block_addr = (volatile FLASH_TYPE *)((unsigned long)block_addr + (unsigned long)FLASH_BLOCK_SIZE); /* block address offset for byte wide data storage */
	}


	for (block=0; block<=63; block++)
	{
		if (block == 32)
		{
			printf("\n\r");
		}
		printf("%d ", block_lock_status[block] );
	}
	printf("\nDone!\n\n" );

/**	return; **/
}
コード例 #3
0
ファイル: flash_erase_block.c プロジェクト: LucidOne/Rovio
int flash_erase_block(volatile unsigned char *block)
{
    volatile unsigned char *ROM;
    unsigned short stat;
    int timeout = 50000;
    int cache_on;
    int len;

    HAL_DCACHE_IS_ENABLED(cache_on);
    if (cache_on) {
        HAL_DCACHE_SYNC();
        HAL_DCACHE_DISABLE();
    }


    // First 4K page of flash at physcial address zero is
    // virtually mapped to address 0xa0000000.
    ROM = FLASH_P2V((unsigned)block & 0xFF800000);

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

    // Erase block
    ROM[0] = FLASH_Block_Erase;
    *FLASH_P2V(block) = FLASH_Confirm;
    timeout = 5000000;
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) break;
    }

    // Restore ROM to "normal" mode
    ROM[0] = FLASH_Reset;

    // If an error was reported, see if the block erased anyway
    if (stat & 0x7E) {
        len = FLASH_BLOCK_SIZE;
        while (len > 0) {
	    if (*FLASH_P2V(block) != 0xFF)
		break;
	    block++;
            len -= sizeof(*block);
        }
        if (len == 0) stat = 0;
    }

    if (cache_on) {
        HAL_DCACHE_ENABLE();
    }

    return stat;
}
コード例 #4
0
int check_program_lock(volatile FLASH_TYPE *flash)
{
    FLASH_TYPE stat;
    flash = FLASH_P2V(flash);
    *flash = READ_STAT_REG;
    stat = *flash;

    /* poll and wait for Write State Machine Ready */
    while (!(stat & WSM_READY))
    	stat = *flash;

    /* now check completion status */
    if (stat & VPP_LOW_DETECT)
    {
		*flash = CLEAR_STAT_REG;
		return VPP_LOW_DETECT;
    }

    if (stat & PROGRAM_LOCK_ERROR)
    {
		*flash = CLEAR_STAT_REG;
		return PROGRAM_LOCK_ERROR;
    }

    if ((stat & ALL_FLASH_STATUS) == (WSM_READY | PROGRAM_LOCK_SUCCESS))
    {
		*flash = CLEAR_STAT_REG;
		return OK;
    }
    else
    {
		*flash = CLEAR_STAT_REG;
		return UNKNOWN_ERR;
    }
}
コード例 #5
0
int check_op_status(int cmd, volatile FLASH_TYPE *flash)
{
    FLASH_TYPE stat;

	flash = FLASH_P2V(flash);

	if (cmd == TRUE)
	{
		*flash = READ_STAT_REG;
	}

    stat = *flash;

    /* poll and wait for Write State Machine Ready */
    while ((stat & WSM_READY) == WSM_BUSY)
    {
        stat = *flash;
    }

    /* now check completion status */
    if ((stat & ALL_FLASH_STATUS) == WSM_READY)
    {
		*flash = CLEAR_STAT_REG;
		return OK;
    }
    else
    {
		*flash = CLEAR_STAT_REG;
		return stat;
    }
}
コード例 #6
0
int check_bstat(int block_num)
{
	volatile FLASH_TYPE *lock_data_addr; 
	FLASH_TYPE lock_data;
	
	/* shut the compiler up */
	lock_data_addr = 0x00000000;

	/* derive the address for block lock configuration data */
	if ((block_num >= 0) && (block_num <= NUM_FLASH_BLOCKS))
		lock_data_addr = (FLASH_TYPE*)(FLASH_ADDR + (FLASH_BLOCK_SIZE * block_num) + 2);
	else if (block_num == -1)
		lock_data_addr = (FLASH_TYPE*)(FLASH_ADDR + 3);
	else 
		return (2);
	
	lock_data_addr = FLASH_P2V(lock_data_addr);
	
	/* read block lock configuration data from address */
	*lock_data_addr = READ_ID_CMD;
	
	lock_data = *lock_data_addr;

	/* reset flash to read mode */
	*lock_data_addr = RESET_CMD;
	delay_and_flush();	/* wait for Flash to re-enter Read Array mode */

	/* now check data to see if block is indeed locked */
	if (lock_data & BLOCK_LOCKED)
		return (BLOCK_LOCKED);
	else
		return (BLOCK_UNLOCKED);
}
コード例 #7
0
ファイル: flash_unlock_block.c プロジェクト: 0xCA5A/dd-wrt
int
flash_unlock_block(volatile unsigned char *block, int block_size, int blocks)
{
    volatile unsigned short *ROM, *bp;
    unsigned short stat;
    int timeout = 5000000;
    unsigned short is_locked[MAX_FLASH_BLOCKS];
    int i;

    ROM = (unsigned short *) FLASH_P2V((unsigned long)block & 0xFF800000);

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

    // Get current block lock state.  This needs to access each block on
    // the device so currently locked blocks can be re-locked.
    bp = (unsigned short *)((unsigned long)block & 0xFF800000);
    for (i = 0;  i < blocks;  i++) {
        if (bp == (unsigned short *) block) {
            is_locked[i] = 0;
        } else {
	    *(volatile unsigned short *)FLASH_P2V(bp) = FLASH_Read_Query;
            is_locked[i] = ((volatile unsigned short *)FLASH_P2V(bp))[2];
        }
        bp += block_size / sizeof(*bp);
    }

    // Clears all lock bits
    FLASH_P2V(block)[0] = FLASH_Clear_Locks;
    FLASH_P2V(block)[0] = FLASH_Clear_Locks_Confirm;  // Confirmation
    timeout = 5000000;
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) goto done;
    }

    // Restore the lock state
    bp = (unsigned short *)((unsigned long)block & 0xFF800000);
    for (i = 0;  i < blocks;  i++) {
        if (is_locked[i]) {
            *FLASH_P2V(bp) = FLASH_Set_Lock;
            *FLASH_P2V(bp) = FLASH_Set_Lock_Confirm;  // Confirmation
            timeout = 5000000;
            while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
                if (--timeout == 0) goto done;
            }
        }
        bp += block_size / sizeof(*bp);
    }

 done:
    // Restore ROM to "normal" mode
    ROM[0] = FLASH_Reset;

    return stat;
}
コード例 #8
0
void init_eeprom()
{
#if 1
	unsigned char MfgCode=MADE_BY_INTEL;
	unsigned char DevCode=I28F640J3A;

	eeprom_size = 0x800000;
#else
	unsigned char MfgCode=0;
	unsigned char DevCode=0;

	flash_addr = FLASH_ADDR;

	flash_base = FLASH_BASE_ADDR;

    /* Set defaults */
    eeprom_size = 0;

    /* Note: the PCI-700 platform has only 1 memory bank */

/*
	*( volatile unsigned char * ) FLASH_BASE_ADDR = RESET_CMD;
	printf( "Wrote 1rst Read Array Command\n");
*/

	*FLASH_P2V(FLASH_BASE_ADDR) = RESET_CMD;	/* issue read array command */	
	delay_and_flush();		  /* wait for Flash to re-enter Read Array mode */

		
	*FLASH_P2V(FLASH_BASE_ADDR) = READ_ID_CMD;	/* issue read id command */	
	
	MfgCode = *FLASH_P2V(FLASH_BASE_ADDR);		/* read a manufacturer code at addr 0, address bit A0 is not used  */
	
	DevCode = *FLASH_P2V(DEV_CODE_ADDR);		/* read a device code at addr 1 */

    if (MfgCode == (MADE_BY_INTEL)) 
    {
		switch ( DevCode )								/* device code stored in addr 1, address bit A0 is not used, must shift 0x00000001<<1=0x00000002 */ 
		{
			case I28F640J3A:
				eeprom_size += 0x800000 * FLASH_WIDTH;		/* I28F640J3A */
				break;
            default:
                break;
        }
	}

	*FLASH_P2V(FLASH_BASE_ADDR) = READ_ID_CMD;	/* issue 2nd read id command */	
	
	*FLASH_P2V(FLASH_BASE_ADDR) = RESET_CMD; /* issue read array command */	
	
	delay_and_flush();	/* wait for Flash to re-enter Read Array mode */
#endif

	printf( "\nManufacturer Code = 0x%x\n", MfgCode);
	printf( "Device Code = %x\n", DevCode);
	printf( "Flash Memory size = 0x%x\n", eeprom_size);

    return;
}
コード例 #9
0
int
flash_lock_block(volatile flash_t *block)
{
    volatile flash_t *ROM;
    flash_t stat;
    int timeout = 5000000;
    int cache_on;
    volatile int j;

    // Get base address and map addresses to virtual addresses
    ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block);
    block = FLASH_P2V(block);

    HAL_DCACHE_IS_ENABLED(cache_on);
    if (cache_on) {
        HAL_DCACHE_SYNC();
        HAL_DCACHE_DISABLE();
    }

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

    // Set lock bit
    block[0] = FLASH_Set_Lock;
    block[0] = FLASH_Set_Lock_Confirm;  // Confirmation
    for (j = 0; j < FLASH_Delay; ++j);
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) break;
    }

    // Restore ROM to "normal" mode
    ROM[0] = FLASH_Reset;
    for (j = 0; j < FLASH_Delay; ++j);

    if (cache_on) {
        HAL_DCACHE_ENABLE();
    }

    return stat;
}
コード例 #10
0
ファイル: flash.c プロジェクト: 0xCA5A/dd-wrt
int check_eeprom(ADDR addr, unsigned long length)
{
    FLASH_TYPE *p, *end;

    if (eeprom_size == 0) {
	cmd_stat = E_NO_FLASH;
	return ERR;
    }

    if (addr == NO_ADDR) {
	addr = FLASH_BLK4_BASE_ADDR;	/* start at base address of block */
	length = eeprom_size - RESERVED_AREA_SIZE;
    } else if (length == 0)
	length = 1;

    p = (FLASH_TYPE *)addr;

    end = (FLASH_TYPE *)FLASH_TOP_ADDR; 
    /* search for first non blank address starting at base address of Flash Block 2 */
    while (p != end) {
	if (*FLASH_P2V(p) != 0xff) {
	    eeprom_prog_first = (ADDR)p;	/* found first non blank memory cell */
	    
	    /* now find last non blank memory cell starting from top of Flash memory */
	    for (p = end - 1; *FLASH_P2V(p) == 0xff; --p)
		;
	    eeprom_prog_last = (ADDR)p;	/* found last non blank memory cell */ 
	    
	    cmd_stat = E_EEPROM_PROG;

	    return ERR;
        }
	p++;
    }
    return OK;
}
コード例 #11
0
ファイル: flash_query.c プロジェクト: JeremyRand/XBC-Firmware
int
flash_query(unsigned char *data)
{
    volatile flash_t *ROM;
    int i, cnt;
    int cache_on;

    HAL_DCACHE_IS_ENABLED(cache_on);
    if (cache_on) {
        HAL_DCACHE_SYNC();
        HAL_DCACHE_DISABLE();
    }

    // Get base address and map addresses to virtual addresses
    ROM = FLASH_P2V( CYGNUM_FLASH_BASE );
#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
    // BootBlock flash does not support full Read_Query - we have do a
    // table oriented thing above, after getting just two bytes of results:
    ROM[0] = FLASH_Read_ID;
    i = 2;
#else
    // StrataFlash supports the full Read_Query op:
    ROM[0] = FLASH_Read_Query;
    i = sizeof(struct FLASH_query);
#endif // Not CYGOPT_FLASH_IS_BOOTBLOCK

    for (cnt = CNT;  cnt > 0;  cnt--) ;
    for ( /* i */;  i > 0;  i-- ) {
        // It is very deliberate that data is chars NOT flash_t:
        // The info comes out in bytes regardless of device.
        *data++ = (unsigned char) (*ROM++);
#ifndef CYGOPT_FLASH_IS_BOOTBLOCK
# if  8 == CYGNUM_FLASH_WIDTH
	// strata flash with 'byte-enable' contains the configuration data
	// at even addresses
	++ROM;
# endif
#endif
    }
    ROM[0] = FLASH_Reset;

    if (cache_on) {
        HAL_DCACHE_ENABLE();
    }

    return 0;
}
コード例 #12
0
int
flash_query(unsigned char *data)
{
    volatile unsigned short *ROM;
    int i, cnt;

    ROM = (unsigned short *) FLASH_P2V(0);
    ROM[0] = FLASH_Read_Query;
    for (cnt = CNT;  cnt > 0;  cnt--) ;
    for (i = 0;  i < sizeof(struct FLASH_query);  i++) {
        *data++ = ROM[i];
    }

    ROM[0] = FLASH_Reset;

    return 0;
}
コード例 #13
0
int check_erase_unlock(volatile FLASH_TYPE *flash)
{
    FLASH_TYPE stat;
    flash = FLASH_P2V(flash);
    *flash = READ_STAT_REG   ;
    stat = *flash;

    /* poll and wait for Write State Machine Ready */
    while ((stat & WSM_READY) == WSM_BUSY)
    {
        stat = *flash;
    }

    /* now check completion status */
    if (stat & VPP_LOW_DETECT)
    {
		*flash = CLEAR_STAT_REG;
		return VPP_LOW_DETECT;
    }
    if ((stat & CMD_SEQ_ERR) == CMD_SEQ_ERR)
    {
		*flash = CLEAR_STAT_REG;
		return CMD_SEQ_ERR;
    }
    if (stat & ERASE_UNLOCK_ERROR)
    {
		*flash = CLEAR_STAT_REG;
		return ERASE_UNLOCK_ERROR;
    }
    if ((stat & ALL_FLASH_STATUS) == WSM_READY)
    {
		*flash = CLEAR_STAT_REG;
		return OK;
    }
    else
    {
		*flash = CLEAR_STAT_REG;
		return UNKNOWN_ERR;
    }
}
コード例 #14
0
ファイル: flash_program_buf.c プロジェクト: LucidOne/Rovio
int
flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
                  unsigned long block_mask, int buffer_size)
{
    volatile flash_t *ROM;
    volatile flash_t *BA;
    flash_t stat = 0;
    int timeout = 50000;
    int cache_on;
#ifdef FLASH_Write_Buffer
    int i, wc;
#endif

    HAL_DCACHE_IS_ENABLED(cache_on);
    if (cache_on) {
        HAL_DCACHE_SYNC();
        HAL_DCACHE_DISABLE();
    }

    // Get base address and map addresses to virtual addresses
    ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr );
    BA = FLASH_P2V( block_mask & (unsigned int)addr );
    addr = FLASH_P2V(addr);

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

#ifdef FLASH_Write_Buffer
    // Write any big chunks first
    while (len >= buffer_size) {
        wc = buffer_size;
        if (wc > len) wc = len;
        len -= wc;
	// convert 'wc' in bytes to 'wc' in 'flash_t' 
        wc = wc / sizeof(flash_t);  // Word count
        *BA = FLASH_Write_Buffer;
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) {
                goto bad;
            }
            *BA = FLASH_Write_Buffer;
        }
        *BA = FLASHWORD(wc-1);  // Count is 0..N-1
        for (i = 0;  i < wc;  i++) {
#ifdef CYGHWR_FLASH_WRITE_ELEM
            CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i);
#else
            *(addr+i) = *(data+i);
#endif
        }
        *BA = FLASH_Confirm;
    
        ROM[0] = FLASH_Read_Status;
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) {
                goto bad;
            }
        }
        // Jump out if there was an error
        if (stat & FLASH_ErrorMask) {
            goto bad;
        }
        // And verify the data - also increments the pointers.
        *BA = FLASH_Reset;            
        for (i = 0;  i < wc;  i++) {
            if ( *addr++ != *data++ ) {
                stat = FLASH_ErrorNotVerified;
                goto bad;
            }
        }
    }
#endif

    while (len > 0) {
        ROM[0] = FLASH_Program;
#ifdef CYGHWR_FLASH_WRITE_ELEM
        CYGHWR_FLASH_WRITE_ELEM(addr, data);
#else
        *addr = *data;
#endif
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) {
                goto bad;
            }
        }
        if (stat & FLASH_ErrorMask) {
            break;
        }
        ROM[0] = FLASH_Reset;            
        if (*addr++ != *data++) {
            stat = FLASH_ErrorNotVerified;
            break;
        }
        len -= sizeof( flash_t );
    }

    // Restore ROM to "normal" mode
 bad:
    ROM[0] = FLASH_Reset;            

    if (cache_on) {
        HAL_DCACHE_ENABLE();
    }

    return stat;
}
コード例 #15
0
ファイル: flash_unlock_block.c プロジェクト: 0xCA5A/dd-wrt
int
flash_unlock_block(volatile flash_t *block, int block_size, int blocks)
{
    volatile flash_t *ROM;
    flash_t stat;
    int timeout = 5000000;
#ifndef CYGOPT_FLASH_IS_SYNCHRONOUS
    int i;
    volatile flash_t *bp, *bpv;
    unsigned char is_locked[CYGNUM_DEVS_FLASH_STRATA_MAX_BLOCKS];
#endif

    // Get base address and map addresses to virtual addresses
    ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block );
    block = FLASH_P2V(block);

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

#ifdef CYGOPT_FLASH_IS_SYNCHRONOUS
    // Clear lock bit
    block[0] = FLASH_Clear_Locks;
    block[0] = FLASH_Clear_Locks_Confirm;  // Confirmation
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) break;
    }
#else
    // Get current block lock state.  This needs to access each block on
    // the device so currently locked blocks can be re-locked.
    bp = ROM;
    for (i = 0;  i < blocks;  i++) {
        bpv = FLASH_P2V( bp );
        *bpv = FLASH_Read_Query;
        if (bpv == block) {
            is_locked[i] = 0;
        } else {
#if 8 == CYGNUM_FLASH_WIDTH
            is_locked[i] = bpv[4] & FLASH_LOCK_MASK;
#else
            is_locked[i] = bpv[2] & FLASH_LOCK_MASK;
# endif
        }
        bp += block_size / sizeof(*bp);
    }

    // Clears all lock bits
    ROM[0] = FLASH_Clear_Locks;
    ROM[0] = FLASH_Clear_Locks_Confirm;  // Confirmation
    timeout = 5000000;
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) break;
    }

    // Restore the lock state
    bp = ROM;
    for (i = 0;  i < blocks;  i++) {
        bpv = FLASH_P2V( bp );
        if (is_locked[i]) {
            *bpv = FLASH_Set_Lock;
            *bpv = FLASH_Set_Lock_Confirm;  // Confirmation
            timeout = 5000000;
            while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
                if (--timeout == 0) break;
            }
        }
        bp += block_size / sizeof(*bp);
    }
#endif  // CYGOPT_FLASH_IS_SYNCHRONOUS

    // Restore ROM to "normal" mode
    ROM[0] = FLASH_Reset;

    return stat;
}
コード例 #16
0
int flash_erase_block(volatile flash_t *block, unsigned int block_size)
{
    volatile flash_t *ROM;
    flash_t stat = 0;
    int timeout = 50000;
    int cache_on;
    int len, block_len, erase_block_size;
    volatile flash_t *eb;

    HAL_DCACHE_IS_ENABLED(cache_on);
    if (cache_on) {
        HAL_DCACHE_SYNC();
        HAL_DCACHE_DISABLE();
    }

    // Get base address and map addresses to virtual addresses
    ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block);
    eb = block = FLASH_P2V(block);
    block_len = block_size;

#ifdef CYGOPT_FLASH_IS_BOOTBLOCK
#define BLOCKSIZE (0x10000*CYGNUM_FLASH_DEVICES)
#define ERASE_BLOCKSIZE (0x2000*CYGNUM_FLASH_DEVICES)
    if ((eb - ROM) < BLOCKSIZE) {
// FIXME - Handle 'boot' blocks
        erase_block_size = ERASE_BLOCKSIZE;
    } else {
        erase_block_size = block_size;
    }
#else
    erase_block_size = block_size;
#endif

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

    // Erase block
    while (block_len > 0) {
        ROM[0] = FLASH_Block_Erase;
        *eb = FLASH_Confirm;
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) break;
        }
        block_len -= erase_block_size;
        eb = FLASH_P2V((unsigned int)eb + erase_block_size);
    }

    // Restore ROM to "normal" mode
    ROM[0] = FLASH_Reset;

    // If an error was reported, see if the block erased anyway
    if (stat & FLASH_ErrorMask ) {
        len = block_size;
        while (len > 0) {
            if (*block++ != FLASH_BlankValue ) break;
            len -= sizeof(*block);
        }
        if (len == 0) stat = 0;
    }

    if (cache_on) {
        HAL_DCACHE_ENABLE();
    }

    return stat;
}
コード例 #17
0
ファイル: flash_program_buf.c プロジェクト: 0xCA5A/dd-wrt
int
flash_program_buf(volatile unsigned char *addr, unsigned char *data, int len)
{
    volatile unsigned char *ROM;
    volatile unsigned char *BA;
    unsigned short stat;
    int timeout = 5000000;
    int i, wc;

    ROM = FLASH_P2V((unsigned long)addr & 0xFF800000);
    BA  = FLASH_P2V((unsigned long)addr & 0xFFFE0000);

    // Clear any error conditions
    ROM[0] = FLASH_Clear_Status;

    wc = 32;
    while (len >= wc) {
        len -= wc;

	// The IQ803010 has a hole in flash which must be avoided.
	if (((unsigned char *)0x1000) <= addr && addr < ((unsigned char *)0x2000)) {
	    addr += wc;
	    data += wc;
	    continue;
	}

        *BA = FLASH_Write_Buffer;
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) {
                stat |= 0x0100;
                goto bad;
            }
            *BA = FLASH_Write_Buffer;
        }
        *BA = wc-1;  // Count is 0..N-1
	if (FLASH_P2V(addr) != addr) {
	    volatile unsigned char *tmp;

	    tmp = FLASH_P2V(addr);
	    for (i = 0;  i < wc;  i++)
		*tmp++ = *data++;
	    addr += wc;
	} else {
	    for (i = 0;  i < wc;  i++)
		*addr++ = *data++;
	}
        *BA = FLASH_Confirm;
	stat = *BA;
    }
    
    ROM[0] = FLASH_Read_Status;
    timeout = 5000000;
    while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
        if (--timeout == 0) {
            stat |= 0x0200;
            goto bad;
        }
    }

    while (len > 0) {
        ROM[0] = FLASH_Program;
	
        *FLASH_P2V(addr) = *data++;
	addr++;
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) {
                stat |= 0x0300;
                goto bad;
            }
        }
        --len;
    }

    // Restore ROM to "normal" mode
 bad:
    ROM[0] = FLASH_Reset;            

    return stat;
}