int
flash_unlock_block(volatile unsigned long *block, int block_size, int blocks)
{
    volatile unsigned long *ROM, *bp;
    unsigned long stat;
    int timeout = 5000000;
    unsigned char is_locked[MAX_FLASH_BLOCKS];
    int i;

    FLASH_WRITE_ENABLE();

    block = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)block);
    ROM = (volatile unsigned long *)((unsigned long)block & FLASH_BASE_MASK);

    // 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 = ROM;
    for (i = 0;  i < (blocks/2);  i++) {
        if (bp == block) {
            is_locked[i] = 0;
        } else {
	    *bp = FLASH_Read_Query;
            is_locked[i] = bp[2];
        }
        bp += block_size / sizeof(*bp);
    }

    // Clears all lock bits
    block[0] = FLASH_Clear_Locks;
    block[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/2);  i++) {
        if (is_locked[i]) {
            *bp = FLASH_Set_Lock;
            *bp = 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);
    }

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

    FLASH_WRITE_DISABLE();

    return stat;
}
Esempio n. 2
0
int
flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len)
{
    volatile unsigned long *ROM;
    unsigned long stat = 0;
    int timeout = 50000;

    FLASH_WRITE_ENABLE();

    addr = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)addr);
    ROM = (volatile unsigned long *)((unsigned long)addr & FLASH_BASE_MASK);

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

    while (len > 0) {
        ROM[0] = FLASH_Program;
        *addr = *data;
        timeout = 5000000;
        while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
            if (--timeout == 0) {
                goto bad;
            }
        }
        if (stat & 0x007E007E) {
            break;
        }
        ROM[0] = FLASH_Reset;            
        if (*addr++ != *data++) {
            stat = 0x99109910;
            break;
        }
        len -= 4;
    }

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

    FLASH_WRITE_DISABLE();

    return stat;
}
Esempio n. 3
0
int flash_erase_block(volatile unsigned long *block)
{
    volatile unsigned long *ROM;
    unsigned long stat;
    int timeout = 50000;
    int len;

    FLASH_WRITE_ENABLE();

    block = (volatile unsigned long *)CYGARC_UNCACHED_ADDRESS((unsigned long)block);
    ROM = (volatile unsigned long *)((unsigned long)block & FLASH_BASE_MASK);

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

    // Erase block
    ROM[0] = FLASH_Block_Erase;
    *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 & 0x007E007E) {
        len = FLASH_BLOCK_SIZE;
        while (len > 0) {
            if (*block++ != 0xFFFFFFFF) break;
            len -= sizeof(*block);
        }
        if (len == 0) stat = 0;
    }

    FLASH_WRITE_DISABLE();

    return stat;
}