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; }
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; }
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; }