📄 bootloader.lst
字号:
__text_start:
__start:
FE47 E001 LDI R16,1
FE48 BF05 OUT 0x35,R16
FE49 E002 LDI R16,2
FE4A BF05 OUT 0x35,R16
FE4B EFCF LDI R28,0xFF
FE4C E1D0 LDI R29,0x10
FE4D BFCD OUT 0x3D,R28
FE4E BFDE OUT 0x3E,R29
FE4F 51C0 SUBI R28,0x10
FE50 40D0 SBCI R29,0
FE51 EA0A LDI R16,0xAA
FE52 8308 STD Y+0,R16
FE53 2400 CLR R0
FE54 E0E1 LDI R30,1
FE55 E0F1 LDI R31,1
FE56 E012 LDI R17,2
FE57 30E5 CPI R30,5
FE58 07F1 CPC R31,R17
FE59 F011 BEQ 0xFE5C
FE5A 9201 ST R0,Z+
FE5B CFFB RJMP 0xFE57
FE5C 8300 STD Z+0,R16
FE5D E8EC LDI R30,0x8C
FE5E EFFC LDI R31,0xFC
FE5F E0A0 LDI R26,0
FE60 E0B1 LDI R27,1
FE61 EF1C LDI R17,0xFC
FE62 E001 LDI R16,1
FE63 BF0B OUT 0x3B,R16
FE64 38ED CPI R30,0x8D
FE65 07F1 CPC R31,R17
FE66 F021 BEQ 0xFE6B
FE67 95D8 ELPM
FE68 9631 ADIW R30,1
FE69 920D ST R0,X+
FE6A CFF9 RJMP 0xFE64
FE6B D12E RCALL _main
_exit:
FE6C CFFF RJMP _exit
FILE: C:\DATA\MP3\BootLoader\assembly.s
(0001) .text
(0002)
(0003) SPMCR = 0x68
(0004)
(0005) ; void write_page (unsigned int adr, unsigned char function);
(0006) ; bits 8:15 adr addresses the page...(must setup RAMPZ beforehand!!!)
(0007) _write_page::
(0008) XCALL __WAIT_SPMEN__
_write_page:
FE6D D021 RCALL 0xFE8F
(0009) MOV R31,R17
FE6E 2FF1 MOV R31,R17
(0010) MOV R30,R16 ;move address to z pointer (R31=ZH R30=ZL)
FE6F 2FE0 MOV R30,R16
(0011) STS SPMCR,R18 ;argument 2 decides function
FE70 93200068 STS 0x68,R18
(0012) SPM ;perform pagewrite
FE72 95E8 SPM
(0013) RET
FE73 9508 RET
(0014)
(0015) ; void fill_temp_buffer (unsigned int data, unsigned int adr);
(0016) ; bits 7:1 in adr addresses the word in the page... (2=first word, 4=second word etc..)
(0017) _fill_temp_buffer::
(0018)
(0019) XCALL __WAIT_SPMEN__
_fill_temp_buffer:
FE74 D01A RCALL 0xFE8F
(0020) MOV R31,R19
FE75 2FF3 MOV R31,R19
(0021) MOV R30,R18 ;move adress to z pointer (R31=ZH R30=ZL)
FE76 2FE2 MOV R30,R18
(0022) MOV R1,R17
FE77 2E11 MOV R1,R17
(0023) MOV R0,R16 ;move data to reg 0 and 1
FE78 2E00 MOV R0,R16
(0024) LDI R19,0x01
FE79 E031 LDI R19,1
(0025) STS SPMCR,R19
FE7A 93300068 STS 0x68,R19
(0026) SPM ;Store program memory
FE7C 95E8 SPM
(0027) RET
FE7D 9508 RET
(0028)
(0029) ;unsigned int read_program_memory (unsigned int adr ,unsigned char cmd);
(0030) _read_program_memory::
(0031) MOV R31,R17 ;R31=ZH R30=ZL
_read_program_memory:
FE7E 2FF1 MOV R31,R17
(0032) MOV R30,R16 ;move adress to z pointer
FE7F 2FE0 MOV R30,R16
(0033) SBRC R18,0 ;read lockbits? (second argument=0x09)
FE80 FD20 SBRC R18,0
(0034) STS SPMCR,R18 ;if so, place second argument in SPMEN register
FE81 93200068 STS 0x68,R18
(0035) ELPM ;read LSB
FE83 95D8 ELPM
(0036) MOV R16,R0
FE84 2D00 MOV R16,R0
(0037) INC R30
FE85 95E3 INC R30
(0038) ELPM
FE86 95D8 ELPM
(0039) MOV R17,R0 ;read MSB (ignored when reading lockbits)
FE87 2D10 MOV R17,R0
(0040) RET
FE88 9508 RET
(0041)
(0042) _enableRWW::
(0043) XCALL __WAIT_SPMEN__
_enableRWW:
FE89 D005 RCALL 0xFE8F
(0044) LDI R27,0x11
FE8A E1B1 LDI R27,0x11
(0045) STS SPMCR,R27
FE8B 93B00068 STS 0x68,R27
(0046) SPM
FE8D 95E8 SPM
(0047) RET
FE8E 9508 RET
(0048)
(0049) __WAIT_SPMEN__:
(0050) LDS R27,SPMCR ; load SPMCR to R27
FE8F 91B00068 LDS R27,0x68
(0051) SBRC R27,0 ; check SPMEN flag
FE91 FDB0 SBRC R27,0
(0052) RJMP __WAIT_SPMEN__ ; wait for SPMEN flag cleared
FE92 CFFC RJMP 0xFE8F
(0053) RET
FE93 9508 RET
FILE: C:\DATA\MP3\BootLoader\main.c
(0001) /*********************************************************/
(0002) /* BootLoader for ATMega128 & MP3 Ver:3.0 @ 16Mhz */
(0003) /* Version 1.1 April 2003 */
(0004) /* 1.0 : First Release */
(0005) /* 1.1 : Add auto baud rate, code smaller */
(0006) /* 1.2 : Correct a bug with file larger than 65280 bytes.*/
(0007) /* */
(0008) /* Sylvain.Bissonnette@MicroSyl.com */
(0009) /*********************************************************/
(0010)
(0011) /*********************************************************/
(0012) /* I N C L U D E */
(0013) /*********************************************************/
(0014) #include "main.h"
(0015) #include "assembly.h"
(0016) #include "macros.h"
(0017) #include "iom128v.h"
(0018)
(0019) /*********************************************************/
(0020) /* D E F I N E */
(0021) /*********************************************************/
(0022) //#define DeviceID 'A' // Mega8
(0023) //#define DeviceID 'B' // Mega16
(0024) //#define DeviceID 'C' // Mega64
(0025) #define DeviceID 'D' // Mega128
(0026)
(0027) //#define FlashSize 'l' // Flash 8k
(0028) //#define FlashSize 'm' // Flash 16k
(0029) //#define FlashSize 'n' // Flash 32k
(0030) //#define FlashSize 'o' // Flash 64k
(0031) #define FlashSize 'p' // Flash 128k
(0032)
(0033) //#define BootSize 'a' // 128 word
(0034) //#define BootSize 'b' // 256 word
(0035) #define BootSize 'c' // 512 word
(0036) //#define BootSize 'd' // 1024 word
(0037) //#define BootSize 'e' // 2048 word
(0038) //#define BootSize 'f' // 4096 word
(0039)
(0040) //#define PageSize 'Q' // 32 Bytes
(0041) //#define PageSize 'R' // 64 Bytes
(0042) //#define PageSize 'S' // 128 Bytes
(0043) #define PageSize 'T' // 256 Bytes
(0044) //#define PageSize 'U' // 512 Bytes
(0045)
(0046) //#define PageByte 32 // 32 Bytes
(0047) //#define PageByte 64 // 64 Bytes
(0048) //#define PageByte 128 // 128 Bytes
(0049) #define PageByte 256 // 256 Bytes
(0050) //#define PageByte 512 // 512 Bytes
(0051)
(0052) #define FALSE 0
(0053) #define TRUE 1
(0054)
(0055) #define EXECCODE 0xffff
(0056)
(0057) /*********************************************************/
(0058) /* G L O B A L V A R I A B L E S */
(0059) /*********************************************************/
(0060)
(0061) unsigned char PageBuffer[PageByte];
(0062) unsigned int PageAddress;
(0063) unsigned char PageAddress16 = 0;
(0064) unsigned int RealPageAddress;
(0065)
(0066)
(0067) /*********************************************************/
(0068)
(0069) void BootLoad(void)
(0070) {
(0071) SendDeviceID();
_BootLoad:
FE94 D01E RCALL _SendDeviceID
(0072) TxChar('!');
FE95 E201 LDI R16,0x21
FE96 D0F6 RCALL _TxChar
FE97 C019 RJMP 0xFEB1
(0073) while(1)
(0074) {
(0075) GetPageNumber();
FE98 D023 RCALL _GetPageNumber
(0076) if (RealPageAddress == EXECCODE) ExecCode();
FE99 91800101 LDS R24,_RealPageAddress
FE9B 91900102 LDS R25,_RealPageAddress+1
FE9D 3F8F CPI R24,0xFF
FE9E EFEF LDI R30,0xFF
FE9F 079E CPC R25,R30
FEA0 F409 BNE 0xFEA2
FEA1 D040 RCALL _ExecCode
(0077)
(0078) if (GetPage())
FEA2 D047 RCALL _GetPage
FEA3 2300 TST R16
FEA4 F051 BEQ 0xFEAF
(0079) {
(0080) WriteFlash();
FEA5 D06D RCALL _WriteFlash
(0081) if (CheckFlash()) TxChar('!');
FEA6 D0A7 RCALL _CheckFlash
FEA7 2300 TST R16
FEA8 F019 BEQ 0xFEAC
FEA9 E201 LDI R16,0x21
FEAA D0E2 RCALL _TxChar
FEAB C005 RJMP 0xFEB1
(0082) else TxChar('@');
FEAC E400 LDI R16,0x40
FEAD D0DF RCALL _TxChar
(0083) }
FEAE C002 RJMP 0xFEB1
(0084) else TxChar('@');
FEAF E400 LDI R16,0x40
FEB0 D0DC RCALL _TxChar
FEB1 CFE6 RJMP 0xFE98
(0085) }
(0086) }
FEB2 9508 RET
(0087)
(0088) /*********************************************************/
(0089) void SendDeviceID(void)
(0090) {
(0091) TxChar(DeviceID);
_SendDeviceID:
FEB3 E404 LDI R16,0x44
FEB4 D0D8 RCALL _TxChar
(0092) TxChar(FlashSize);
FEB5 E700 LDI R16,0x70
FEB6 D0D6 RCALL _TxChar
(0093) TxChar(BootSize);
FEB7 E603 LDI R16,0x63
FEB8 D0D4 RCALL _TxChar
(0094) TxChar(PageSize);
FEB9 E504 LDI R16,0x54
FEBA D0D2 RCALL _TxChar
(0095) RxChar();
(0096) }
FEBB C0CF RJMP _RxChar
_GetPageNumber:
PageAddressLow --> R22
PageAddressHigh --> R20
FEBC 940EFFD2 CALL push_gset2
(0097)
(0098) /*********************************************************/
(0099)
(0100) void GetPageNumber(void)
(0101) {
(0102) unsigned char PageAddressHigh;
(0103) unsigned char PageAddressLow;
(0104)
(0105) while(!IsChar());
FEBE D0C6 RCALL _IsChar
FEBF 2300 TST R16
FEC0 F3E9 BEQ 0xFEBE
(0106) PageAddressHigh = RxChar();
FEC1 D0C9 RCALL _RxChar
FEC2 2F40 MOV R20,R16
(0107)
(0108) while(!IsChar());
FEC3 D0C1 RCALL _IsChar
FEC4 2300 TST R16
FEC5 F3E9 BEQ 0xFEC3
(0109) PageAddressLow = RxChar();
FEC6 D0C4 RCALL _RxChar
FEC7 2F60 MOV R22,R16
(0110)
(0111) RealPageAddress = (int)((PageAddressHigh << 8) + PageAddressLow);
FEC8 2E34 MOV R3,R20
FEC9 2E26 MOV R2,R22
FECA 92300102 STS _RealPageAddress+1,R3
FECC 92200101 STS _RealPageAddress,R2
(0112) PageAddress = ((unsigned int)PageAddressLow << 8);
FECE 2E26 MOV R2,R22
FECF 2433 CLR R3
FED0 2C32 MOV R3,R2
FED1 2422 CLR R2
FED2 92300104 STS _PageAddress+1,R3
FED4 92200103 STS _PageAddress,R2
(0113) if (PageAddressHigh) PageAddress16 = 1;
FED6 2344 TST R20
FED7 F021 BEQ 0xFEDC
FED8 E081 LDI R24,1
FED9 93800100 STS 0x100,R24
FEDB C003 RJMP 0xFEDF
(0114) else PageAddress16 = 0;
FEDC 2422 CLR R2
FEDD 92200100 STS 0x100,R2
(0115) }
FEDF 940EFFB7 CALL pop_gset2
FEE1 9508 RET
(0116)
(0117) /*********************************************************/
(0118)
(0119) void ExecCode(void)
(0120) {
(0121) RAMPZ = 0;
_ExecCode:
FEE2 2422 CLR R2
FEE3 BE2B OUT 0x3B,R2
(0122) MCUCR = 0x01; // Enable interrupt vector select
FEE4 E081 LDI R24,1
FEE5 BF85 OUT 0x35,R24
(0123) MCUCR = 0x00; // Move interrupt vector to flash
FEE6 BE25 OUT 0x35,R2
(0124) asm("jmp 0x0000"); // Run application code
FEE7 940C0000 JMP 0x0
(0125) }
FEE9 9508 RET
_GetPage:
CheckSum --> R22
LocalCheckSum --> R10
i --> R20
FEEA 940EFFD5 CALL push_gset3
(0126)
(0127) /*********************************************************/
(0128)
(0129) char GetPage(void)
(0130) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -