通信设计应用





| FLASHQueue[ ] | |
| Queue Index | Data Flash Address |
| 31 | 0xC1F0-0xC1FF |
| 30 | 0xC1E0-0xC1EF |
| 29 | 0xC1D0-0xC1DF |
| . . . . | . . . . |
| 2 | 0xC020-0xC05F |
| 1 | 0xC010-0xC03F |
| 0 | 0xC000-0xC00F |

u16 flashErasePage(void *); u16 flashEraseSector(void *); u16 flashEraseAll(void); u16 dataFlashWrite(u16 *pAddress, u16 iData); u16 dataFlashErasePage(void *); u16 dataFlashEraseSector(void *); u16 dataFlashEraseAll(void);Next, add linker defines to assign the appropriate address for each routine. For the IAR linker file, the added lines would look like this:
-DflashEraseSector=0x8XXX -DflashErasePage=0x8XXX -DflashEraseAll=0x8XXXReplace 0x8XXX with the appropriate memory address for each routine. Other compilers may use a different method for adding these references.
| Routine Number | Routine Name | Entry Point ROMTable = ROM[800Dh] | Entry Point Physical Address |
| 1 | flashWrite | ROM[ROMTable] | 0x8XXX |
| 2 | flashErasePage | ROM[ROMTable + 1] | 0x8XXX |
| 3 | flashEraseAll | ROM[ROMTable + 2] | 0x8XXX |
| 4 | moveDP0 | ROM[ROMTable + 3] | 0x8XXX |
| 16 | flashEraseSector | ROM[ROMTable + 15] | 0x8XXX |
| 17 | dataFlashWrite | ROM[ROMTable + 16] | 0x8XXX |
| 19 | dataFlashErasePage | ROM[ROMTable + 18] | 0x8XXX |
| 20 | dataFlashEraseSector | ROM[ROMTable + 19] | 0x8XXX |
| 21 | dataFlashEraseAll | ROM[ROMTable + 20] | 0x8XXX |
| Routine: | u16 flashWrite(u16 *pDest, u16 *pSrc) |
| Summary: | Programs a single page (32 words) of program-flash memory. |
| Inputs: | DP[0]—Destination address in flash memory. DP[1]—Source address in SRAM holding 32 words of data to write. |
| Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; u16 flashWrite(u16 *pDest, u16 *pSrc);
;
flashWrite:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #2 ; Set ACC to A[2].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #14 ; Add the index to the flashWrite routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
push DP[1] ; Save Frame Pointer on the stack.
move DP[0],A[0] ; Move argument 0(dest address) to DP[0].
move DP[1],A[1] ; Move argument 1(src address) to DP[1].
call ACC ; Execute the routine.
pop DP[1] ; Restore Frame Pointer.
ret ; Status returned in A[0].
FlashErasePage()
| Routine: | u16 flashErasePage(void *pAddress) |
| Summary: | Erases a two-page block of program-flash memory. |
| Inputs: | A[0]—Address located in the two-page block to erase, i.e., to erase pages 0 and 1, A[0] can contain any address from 0x0000 to 0x001F. |
| Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; u16 flashErasePage(void *pAddress);
;
flashErasePage:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #1 ; Set ACC to A[1].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #1 ; Add the index to the flashEraseSector routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret ; Status returned in A[0].
FlashEraseAll()
| Routine: | Void flashEraseAll(void) |
| Summary: | Erases the entire program and data-flash memory. This routine can only be called from RAM. |
| Inputs: | None |
| Outputs: | Carry: Set on error and cleared on success. SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; void flashEraseAll(void);
;
flashEraseAll:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #0 ; Set ACC to A[0].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #2 ; Add the index to the flashEraseAll routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret
moveDP0
| Routine: | moveDP0 |
| Summary: | Reads a single word of flash memory. |
| Inputs: | DP[0]—Source address in flash memory. Add 0x8000 to read program flash. |
| Outputs: | GR will contain the data at specified address. |
| Notes: | This function cannot be called directly from C because the argument and return register are not compatible with C calling conventions. |
; This routine is callable by C code using the following prototype
; u16 flashRead(u16 *pAddress);
;
flashRead:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #1 ; Set ACC to A[1].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #3 ; Add the index to the moveDP0 routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
push DP[1] ; Save Frame Pointer on the stack.
move DP[0],A[0] ; Move argument 0(src address) to DP[0].
call ACC ; Execute the routine.
pop DP[1] ; Restore Frame Pointer.
move A[0],GR
ret ; Data word returned in A[0].
FlashEraseSector()
| Routine: | u16 flashEraseSector(void *pAddress) |
| Summary: | Erases a single sector of program-flash memory. |
| Inputs: | A[0]—Address located in the sector to erase. |
| Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; u16 flashEraseSector(void *pAddress);
;
flashEraseSector:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #1 ; Set ACC to A[1].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #15 ; Add the index to the flashEraseSector routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret ; Status returned in A[0].
DataFlashWrite()
| Routine: | u16 dataFlashWrite(void *pAddress, u16 *pData) |
| Summary: | Programs a single word of data-flash memory. |
| Inputs: | A[0]—Word address in flash memory to which to write. A[1] —Word value to write to flash memory. |
| Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FER —Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; u16 dataFlashWrite(void *pAddress, u16 iData);
;
dataFlashWrite:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #2 ; Set ACC to A[2].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #16 ; Add the index to the flashWrite routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret ; Status returned in A[0].
DataFlashErasePage()
| Routine: | u16 dataFlashErasePage(void *pAddress) |
| Summary: | Erases two pages of data-flash memory. |
| Inputs: | A[0]—Address located in the two-page block to erase, i.e., to erase pages 0 and 1, A[0] can contain address 0x4000 or 0x4001. |
| Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; u16 dataFlashErasePage(void *pAddress);
;
dataFlashErasePage:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #1 ; Set ACC to A[1].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #18 ; Add the index to the dataFlashErasePage routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret ; Status returned in A[0].
DataFlashEraseSector()
| Routine: | u16 dataFlashEraseSector(void *pAddress) |
| Summary: | Erases a single sector of data-flash memory. |
| Inputs: | A[0]—Address located in the sector to erase. |
| Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; u16 dataFlashEraseSector(void *pAddress);
;
dataFlashEraseSector:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #1 ; Set ACC to A[1].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #19 ; Add the index to the dataFlashEraseSector routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret ; Status returned in A[0].
dataFlashEraseAll
| Routine: | void dataFlashEraseAll(void) |
| Summary: | Erases the entire data flash memory. |
| Inputs: | None |
| Outputs: | Carry: Set on error and cleared on success. SW_FERR—Set on error, cleared on success. |
| Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype
; void dataFlashEraseAll(void);
;
dataFlashEraseAll:
move APC, #0 ; No auto inc/dec of accumulator.
move AP, #0 ; Set ACC to A[0].
move DP[0], #0800Dh ; This is where the address of the table is stored.
move ACC, @DP[0] ; Get the location of the routine table.
add #20 ; Add the index to the flashEraseAll routine.
move DP[0], ACC
move ACC, @DP[0] ; Retrieve the address of the routine.
call ACC ; Execute the routine.
ret
| You cannot erase or program from the same flash page from which you are executing code. This is not normally a problem since the flash boot-loader application should never be erased during IAP. |
| The watchdog must not be enabled, or the watchdog timeout must be set long enough to complete this routine without triggering a reset before calling the flashEraseSector() or flashErasePage() routine. If the watchdog time out occurs before the erase is complete, it will reset the part. |
| Because the System Control Register bit, SC.UPA, must be set to 0 to access the Utility ROM, a Utility ROM routine cannot be called directly from program memory addresses ≥ 0x8000. If access to a Utility ROM routine is required from a program in upper memory (≥ 0x8000), the program must indirectly call the ROM routine through a routine residing in lower memory (< 0x8000). This restriction effectively limits the boot loader to = 64KB (32KB x 16). |

typedef struct {
u16 iSize; // The size of the application in words
u32 iCRC; // The CRC of the application
u8 ID[8]; // ID string for current application
} APPLICATION_HEADER;
Using the information from this header, the boot loader can check the validity of the main application program and report the version identification if requested.
/*
// VerySimpleReFlash()
// As simple as it gets.
// Step 1. Wait for erase command, then erase flash.
// Step 2. Wait for program command, program flash one word at a time.
*/
void VerySimpleReFlash()
{
u16 iStatus; // The status returned from flash utility ROM calls
s32 iSize; // The size of the main code to program
u16 *pAddress = 0x2000; // The starting address of the main application
u16 i;
InitializeCOMM(); // Can be CAN or UART.
WaitForEraseCommand();
// Assume that application starts at the beginning of a sector.
for (i=C_START_SECTOR;i 0)
{
u16 iData[32];
Get32WordsFromCOMM(iData);
iStatus = flashWrite(pAddress, iData);
if (iStatus)
break;
pAddress += 32;
iSize -= 32;
UpdateWatchdog(); // Prevent timeout
}
SendFlashWriteResponse(iStatus);
ResetMicro();
}

全部0条评论
快来发表一下你的评论吧 !