📄 flasher.s
字号:
//****************************************************************************//// FLASHER.S - Code which is loaded into the EP72XX and EP73XX via the boot// ROM to program the FLASH.//// Copyright (c) 2001 Cirrus Logic, Inc.////****************************************************************************#include "../asmdefs.h"//****************************************************************************//// The read-only code area.////**************************************************************************** _TEXT_ // // This is the entry point of the program. // _ENTRY_ // // The processor is in ARM mode when we are called, but we want to run in // Thumb mode. So, switch to thumb mode. Note that this code sequence // will not work if any code or data is inserted between the "orr" and the // "thumb_entry" label. // orr r0, pc, _CONST_ 0x01 bx r0 // // Switch the assembler into Thumb mode. // _CODE16_ // // Now we're in thumb mode. //_THUMB_LABEL_thumb_entry _LABEL_ // // Set up the stack pointer. // mov r0, _CONST_ 0x10 lsl r0, r0, _CONST_ 16 mov r1, _CONST_ 0x96 orr r0, r0, r1 lsl r0, r0, _CONST_ 8 mov r13, r0 // // Check the FLASH to see if it is something that we recognize and can // program. // bl check_flash // // See if we recognize the FLASH. // mov r1, _CONST_ 0x01 cmp r0, r1 beq loop // // Send a 'X' to the host to indicate that we will not be able to program // the FLASH. // mov r0, _CONST_ 0x58 // 'X' bl SendChar // // Loop forever. // b . // // Loop forever reading commands from the host and performing them. //_THUMB_LABEL_loop _LABEL_ // // Write the command prompt to the host. // mov r0, _CONST_ 0x3f // '?' bl SendChar // // Read a command from the host. // bl ReceiveChar // // Determine how to handle this command. Is this a 'B'? // cmp r0, _CONST_ 0x42 // 'B' bne loop1 // // Change the baud rate of the serial port. // bl SetBaud b loop // // Is this a 'F'? //_THUMB_LABEL_loop1 _LABEL_ cmp r0, _CONST_ 0x46 // 'F' bne loop // // Program data into the on-board FLASH. // bl ProgramFlash b loop//****************************************************************************//// Waits for an internal erase or program operation to complete on a 16-bit// wide Intel FLASH (B3, C3, or J3).////****************************************************************************_THUMB_LABEL_intel_wait_16 _LABEL_ // // Load the bit mask for which we are waiting. // mov r1, _CONST_ 0x80 // // Read from the FLASH memory until bit 7 is one. //_THUMB_LABEL_intel_wait_16_loop _LABEL_ ldrh r2, [r0] and r2, r2, r1 cmp r2, r1 bne intel_wait_16_loop // // Clear the status register in the FLASH. // mov r1, _CONST_ 0x50 strh r1, [r0] // // Return to the caller. // mov pc, lr//****************************************************************************//// Waits for an internal erase or program operation to complete on a 16-bit// wide Intel FLASH (B3, C3, or J3) with a reversed data bus.////****************************************************************************_THUMB_LABEL_intel_wait_16_rev _LABEL_ // // Load the bit mask for which we are waiting. // mov r1, _CONST_ 0x01 lsl r1, r1, _CONST_ 8 // // Read from the FLASH memory until bit 7 is one. //_THUMB_LABEL_intel_wait_16_rev_loop _LABEL_ ldrh r2, [r0] and r2, r2, r1 cmp r2, r1 bne intel_wait_16_rev_loop // // Clear the status register in the FLASH. // mov r1, _CONST_ 0x0a lsl r1, r1, _CONST_ 8 strh r1, [r0] // // Return to the caller. // mov pc, lr//****************************************************************************//// Waits for an internal erase or program operation to complete on a 32-bit// wide Intel FLASH (B3, C3, or J3).////****************************************************************************_THUMB_LABEL_intel_wait_32 _LABEL_ // // Load the bit mask for which we are waiting. // mov r2, _CONST_ 0x80 mov r1, r2 lsl r1, r1, _CONST_ 16 orr r1, r1, r2 // // Read from the FLASH memory until bit 7 is one. //_THUMB_LABEL_intel_wait_32_loop _LABEL_ ldr r2, [r0] and r2, r2, r1 cmp r2, r1 bne intel_wait_32_loop // // Clear the status register in the FLASH. // mov r2, _CONST_ 0x50 mov r1, r2 lsl r1, r1, _CONST_ 16 orr r1, r1, r2 str r1, [r0] // // Return to the caller. // mov pc, lr//****************************************************************************//// The routine to erase a Intel B3 FLASH. This must be a branch to the routine// for a single 16-bit wide FLASH, immediately followed by the routine for a// 32-bit wide FLASH (i.e. two 16-bit wide FLASHes).////****************************************************************************_THUMB_LABEL_intel_b3_erase _LABEL_ b intel_b3_erase_16//****************************************************************************//// The routine for erasing a pair of 16-bit wide Intel B3 FLASHes in a 32-bit// configuration.////****************************************************************************_THUMB_LABEL_intel_b3_erase_32 _LABEL_ // // Save the link register to the stack. // push {r4-r7, lr} // // Save the length of the FLASH to be erased. // mov r4, r0 // // Load a pointer to the FLASH. // mov r0, _CONST_ 0x70 lsl r0, r0, _CONST_ 24 // // Get the commands to erase a block of the FLASH. // mov r5, _CONST_ 0x20 mov r6, r5 lsl r6, r6, _CONST_ 16 orr r6, r6, r5 mov r5, _CONST_ 0xd0 mov r7, r5 lsl r7, r7, _CONST_ 16 orr r7, r7, r5 // // Start erasing the FLASH from block zero. // mov r5, _CONST_ 0x00_THUMB_LABEL_intel_b3_erase_32_block _LABEL_ // // See if we have erased all the required blocks. // cmp r5, r4 bge intel_b3_erase_32_done // // Erase this block. // str r6, [r0, r5] str r7, [r0, r5] // // Wait until the erase has completed. // bl intel_wait_32 // // Increment the block address. The first 8 blocks of the FLASH have a // block size of 16K and the remaining blocks have a size of 128K. So, // if the offset is less than 128K, increment it by 16K, otherwise // increment it by 128K. // mov r1, _CONST_ 0x02 lsl r1, r1, _CONST_ 16 cmp r5, r1 blt intel_b3_erase_32_small mov r1, _CONST_ 0x20 b intel_b3_erase_32_increment_THUMB_LABEL_intel_b3_erase_32_small _LABEL_ mov r1, _CONST_ 0x04_THUMB_LABEL_intel_b3_erase_32_increment _LABEL_ lsl r1, r1, _CONST_ 12 add r5, r5, r1 // // Loop back. // b intel_b3_erase_32_block // // We're done erasing the FLASH, so return to the caller. //_THUMB_LABEL_intel_b3_erase_32_done _LABEL_ pop {r4-r7, pc}//****************************************************************************//// The routine for erasing a single 16-bit wide Intel B3 FLASH.////****************************************************************************_THUMB_LABEL_intel_b3_erase_16 _LABEL_ // // Save the link register to the stack. // push {r4-r7, lr} // // Save the length of the FLASH to be erased. // mov r4, r0 // // Load a pointer to the FLASH. // mov r0, _CONST_ 0x70 lsl r0, r0, _CONST_ 24 // // Get the commands to erase a block of the FLASH. // mov r6, _CONST_ 0x20 mov r7, _CONST_ 0xd0 // // Start erasing the FLASH from block zero. // mov r5, _CONST_ 0x00_THUMB_LABEL_intel_b3_erase_16_block _LABEL_ // // See if we have erased all the required blocks. // cmp r5, r4 bge intel_b3_erase_16_done // // Erase this block. // strh r6, [r0, r5] strh r7, [r0, r5] // // Wait until the erase has completed. // bl intel_wait_16 // // Increment the block address. The first 8 blocks of the FLASH have a // block size of 8K and the remaining blocks have a size of 64K. So, // if the offset is less than 64K, increment it by 8K, otherwise // increment it by 64K. // mov r1, _CONST_ 0x01 lsl r1, r1, _CONST_ 16 cmp r5, r1 blt intel_b3_erase_16_small mov r1, _CONST_ 0x10 b intel_b3_erase_16_increment_THUMB_LABEL_intel_b3_erase_16_small _LABEL_ mov r1, _CONST_ 0x02_THUMB_LABEL_intel_b3_erase_16_increment _LABEL_ lsl r1, r1, _CONST_ 12 add r5, r5, r1 // // Loop back. // b intel_b3_erase_16_block // // We're done erasing the FLASH, so return to the caller. //_THUMB_LABEL_intel_b3_erase_16_done _LABEL_ pop {r4-r7, pc}//****************************************************************************//// The routine to program a Intel B3/C3 FLASH. This must be a branch to the// routine for a single 16-bit wide FLASH, immediately followed by the routine// for a 32-bit wide FLASH (i.e. two 16-bit wide FLASHes).////****************************************************************************_THUMB_LABEL_intel_b3_c3_program _LABEL_ b intel_b3_c3_program_16//****************************************************************************//// The routine for programming a pair of 16-bit wide Intel B3/C3 FLASHes in a// 32-bit configuration.////****************************************************************************_THUMB_LABEL_intel_b3_c3_program_32 _LABEL_ // // Save the link register to the stack. // push {r4-r7, lr} // // Save the offset, length, and pointer to the data to be programmed into // the FLASH. // mov r4, r0 mov r5, r1 mov r6, r2 // // Load a pointer to the FLASH. // mov r0, _CONST_ 0x70 lsl r0, r0, _CONST_ 24 // // Get the command to program a block of the FLASH. // mov r1, _CONST_ 0x40 mov r7, r1 lsl r7, r7, _CONST_ 16 orr r7, r7, r1 // // Program the FLASH a word at a time. //_THUMB_LABEL_intel_b3_c3_program_32_word _LABEL_ // // See if we have programmed all the required words. // cmp r6, _CONST_ 0 beq intel_b3_c3_program_32_done // // Load the next word to be programmed. // ldr r1, [r4] add r4, r4, _CONST_ 4 // // Program the next word. // str r7, [r0, r5] str r1, [r0, r5] // // Wait until the word has been programmed. // bl intel_wait_32 // // Increment the address to be programmed. // add r5, r5, _CONST_ 4 // // Decrement the count of words to be programmed. // sub r6, r6, _CONST_ 4 // // Loop back. // b intel_b3_c3_program_32_word // // We're done programming the FLASH, so put the FLASH into read array mode. //_THUMB_LABEL_intel_b3_c3_program_32_done _LABEL_ mov r2, _CONST_ 0xff mov r1, r2 lsl r1, r1, _CONST_ 16 orr r1, r1, r2 str r1, [r0] // // Return to the caller. // pop {r4-r7, pc}//****************************************************************************//// The routine for programming a 16-bit wide Intel B3/C3 FLASH.////****************************************************************************_THUMB_LABEL_intel_b3_c3_program_16 _LABEL_ // // Save the link register to the stack. // push {r4-r7, lr} // // Save the offset, length, and pointer to the data to be programmed into // the FLASH. // mov r4, r0 mov r5, r1 mov r6, r2 // // Load a pointer to the FLASH. // mov r0, _CONST_ 0x70 lsl r0, r0, _CONST_ 24 // // Get the command to program a block of the FLASH. // mov r7, _CONST_ 0x40 // // Program the FLASH a word at a time. //_THUMB_LABEL_intel_b3_c3_program_16_word _LABEL_ // // See if we have programmed all the required words. // cmp r6, _CONST_ 0 beq intel_b3_c3_program_16_done // // Load the next word to be programmed. // ldrh r1, [r4] add r4, r4, _CONST_ 2 // // Program the next word. // strh r7, [r0, r5] strh r1, [r0, r5] // // Wait until the word has been programmed. // bl intel_wait_16 // // Increment the address to be programmed. // add r5, r5, _CONST_ 2 // // Decrement the count of words to be programmed. // sub r6, r6, _CONST_ 2 // // Loop back. // b intel_b3_c3_program_16_word // // We're done programming the FLASH, so put the FLASH into read array mode. //_THUMB_LABEL_intel_b3_c3_program_16_done _LABEL_ mov r1, _CONST_ 0xff str r1, [r0] // // Return to the caller. // pop {r4-r7, pc}//****************************************************************************//// The routine to erase a Intel C3 FLASH. This must be a branch to the routine// for a single 16-bit wide FLASH, immediately followed by the routine for a// 32-bit wide FLASH (i.e. two 16-bit wide FLASHes).////****************************************************************************_THUMB_LABEL_intel_c3_erase _LABEL_ b intel_c3_erase_16//****************************************************************************//// The routine for erasing a pair of 16-bit wide Intel C3 FLASHes in a 32-bit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -