📄 main.s90
字号:
.include "m163def.inc"
.CSEG
main:
; 1. /*****************************************************************************
; 2. *
; 3. * Copyright (C) 1996-1998 Atmel Corporation
; 4. *
; 5. * File : main.c
; 6. * Compiler : IAR 1.51B
; 7. * Output size : 505 bytes (size optimized)
; 8. * Created : 16-jun-99
; 9. * Modified : 5-jan-2000
; 10. * Last modified : 16-August-2001 by AS
; 11. *
; 12. * Support mail : avr@atmel.com
; 13. *
; 14. * Description : This Program allows an AVR with bootloader capabilities to
; 15. * Read/write its own Flash/EEprom. To enter Programming mode
; 16. * PD2 is checked, it this pin is pulled low, programming mode
; 17. * is entered. If not, normal execution is done from $0000
; 18. * "reset" vector in Application area.
; 19. * The PD2 pin should be pulled HIGH by an external Pull-up
; 20. * resistor.
; 21. *
; 22. * Other info : Code must be modified to use this specific code with devices
; 23. * other than ATmega161. Following change should be made:
; 24. * -Specify device in define list (e.g. _ATMEGA163)
; 25. *
; 26. * When using this code with (future) parts other than ATmega32,
; 27. * ATmega161 and ATmega163, it will be necessary to change more
; 28. * than the device name. The changes that should be made is:
; 29. * -Device name
; 30. * -Device signature and memory settings (defines.h)
; 31. * -Device code
; 32. * -Linker file
; 33. *
; 34. * In general the linker file should always be verifyed to match
; 35. * the used part's boot address and size. Note that memory size
; 36. * is specified in bytes in the linker file.
; 37. ****************************************************************************/
; 38. #include "defines.h"
; 39. #include "serial.h"
; 40. #include "assembly.h"
; 41.
; 42. C_task void main(void)
; 43. {
; 44. void (*funcptr)( void ) = 0x0000; // Set up function pointer
CLR R30
CLR R31
; 45.
; 46. unsigned int intval,address,data;
; 47. unsigned char val, ldata;
; 48.
; 49. #ifdef _ATMEGA32
; 50. UBRRL = 1; // 115200bps @ 3.69 MHz
; 51. // UBRRL = 11; // 19200bps @ 3.69 MHz
; 52. UCSRB = (1<<RXEN) | (1<<TXEN); // Enable recieve and transmit UART1
; 53. #endif
; 54.
; 55. #ifdef _ATMEGA161
; 56. UBRR0 = 11; // 19200bps @ 3.69 MHz
LDI R16,11
OUT LOW(9),R16
; 57. UCSR0B = (1<<RXEN0) | (1<<TXEN0); // Enable recieve and transmit UART1
LDI R16,24
OUT LOW(10),R16
; 58. #endif
; 59.
; 60. #ifdef _ATMEGA163
; 61. UBRRLO = 11; // 19200bps @ 3.69 MHz
; 62. UCSRB = (1<<RXEN) | (1<<TXEN); // Enable recieve and transmit
; 63. #endif
; 64.
; 65. #ifdef _ATMEGA128
; 66. UBRR1L = 1; // 115200bps @ 3.69 MHz
; 67. // UBRR1L = 11; // 19200bps @ 3.69 MHz
; 68. UCSR1B = (1<<RXEN) | (1<<TXEN); // Enable recieve and transmit
; 69. #endif
; 70.
; PROGDDR =0 added as reset on stk500 does not seem to clear port???
CBI LOW(17),4
; 71. PROGPORT |= PROGCTRL; //enable pull-up on PROGCTRL line on PROGPORT
SBI LOW(18),LOW(4)
; 72. if(PROGMODE) //If PROGPIN is pulled low: programmingmode.
SBIC LOW(16),LOW(4)
RJMP X_0003
X_0002:
; 73. {
; 74. for(;;)
; 75. {
; 76. val=recchar();
rcall recchar
; 77.
; 78. if(val=='a') //AutoincrementX_
CPI R16,LOW(97)
BRNE X_0007
; 79. {
; 80. sendchar('Y'); //Autoincrement is quicker
LDI R16,89
RJMP X_0096
X_0007:
; 81. }
; 82.
; 83. else if(val=='A') //write address
CPI R16,LOW(65)
BRNE X_0010
; 84. {
; 85. address=recchar(); //read address 8 MSB
rcall recchar
; 86. address=(address<<8)|recchar();
MOV R25,R16
rcall recchar
MOV R24,R16
; 93.
; 94. address=address<<1; //convert from word address to byte address
LSL R24
ROL R25
; 95. sendchar('\r');
RJMP X_0101
X_0010:
; 96. }
; 97.
; 98. else if(val=='c') //Write program memory, low byte
CPI R16,LOW(99)
BRNE X_0013
; 99. {
; 100. ldata=recchar();
rcall recchar
MOV R4,R16
; 101. sendchar('\r');
RJMP X_0101
X_0013:
; 102. }
; 103.
; 104. else if(val== 'C') //Write program memory, high byte
CPI R16,LOW(67)
BRNE X_0016
; 105. {
; 106. data=ldata|(recchar()<<8);
rcall recchar
MOV R21,R16
MOV R20,R4
; 107. fill_temp_buffer(address,data); //rcall asm routine.
MOVW R16,R24
;MOV R17,R25
rcall fill_temp_buffer
; 108. address+=2;
ADIW R24,LWRD(2)
; 109. sendchar('\r');
RJMP X_0101
X_0016:
; 110. }
; 111.
; 112. else if(val=='e') //Chip erase
CPI R16,LOW(101)
BRNE X_0019
; 113. {
; 114.
; 130. for(address=0;address < APP_END;address += PAGESIZE) //Application section = 60 pages
CLR R24
CLR R25
X_0021:
CPI R25,LOW(60)
BRCS PC+2
RJMP X_0101
; 131. {
; 132. write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase
LDI R20,3
Rcall X_0108
SUBI R24,LOW(128)
SBCI R25,LOW(255)
RJMP X_0021
; 133. #ifndef _ATMEGA161
; 134. write_page(address, (1<<ASRE) + (1<<SPMEN)); //Re-enable the RWW section
; 135. #endif
; 136. }
; 137. #endif
; 138. sendchar('\r');
X_0019:
; 139.
; 140. }
; 141.
; 142. else if(val=='l') // write lockbits
CPI R16,LOW(108)
BRNE X_0026
; 143. {
; 144. write_lock_bits(recchar());
rcall recchar
rcall write_lock_bits
; 145. sendchar('\r');
RJMP X_0101
X_0026:
; 146. }
; 147.
; 148. else if(val== 'm') // write page
CPI R16,LOW(109)
BRNE X_0029
; 149. {
; 150. write_page(address, (1<<PGWRT) + (1<<SPMEN)); //Perform page write
LDI R20,5
Rcall X_0108
; 151. #ifndef _ATMEGA161
; 152. write_page(address, (1<<ASRE) + (1<<SPMEN)); //Re-enable the RWW section
; 153. #endif
; 154.
; 155. sendchar('\r');
RJMP X_0101
X_0029:
; 156. }
; 157.
; 158. else if((val=='P')||(val=='L')) // Enter programming mode
CPI R16,LOW(80)
BRNE PC+2
RJMP X_0101
CPI R16,LOW(76)
BRNE X_0032
X_0033:
; 159. {
; 160. sendchar('\r');
RJMP X_0101
X_0032:
; 161. }
; 162.
; 163. else if (val=='p')
CPI R16,LOW(112)
BRNE X_0037
; 164. {
; 165. sendchar('S');
LDI R16,83
RJMP X_0096
X_0037:
; 166. }
; 167.
; 168. else if(val=='R') //Read program memory
CPI R16,LOW(82)
BRNE X_0040
; 169. {
; 170. intval=read_program_memory(address,0x00);
CLR R20
MOVW R16,R24
;MOV R17,R25
rcall read_program_memory
ADIW R24,LWRD(2)
MOV R26,R16
; 171. sendchar((char)(intval>>8)); //send MSB
MOV R16,R17
rcall sendchar
; 172. sendchar((char)intval); //send LSB
MOV R16,R26
; 173.
; 174. address+=2; //SPM uses Z pointer but the pointer is only 16bit
RJMP X_0096
X_0040:
; 182.
; 183. }
; 184. else if (val == 'D')
CPI R16,LOW(68)
BRNE X_0043
; 185. {
; 186. EEARL = address;
OUT LOW(30),R24
; 187. EEARH = (address >> 8);
OUT LOW(31),R25
; 188. address++;
ADIW R24,LWRD(1)
; 189. EEDR = recchar();
rcall recchar
OUT LOW(29),R16
; 190. EECR |= (1<<EEMWE);
SBI LOW(28),LOW(2)
; 191. EECR |= (1<<EEWE);
SBI LOW(28),LOW(1)
X_0045:
; 192. while (EECR & (1<<EEWE))
SBIC LOW(28),LOW(1)
RJMP X_0045
; 193. ;
; 194. sendchar('\r');
X_0100:
RJMP X_0101
X_0043:
; 195. }
; 196.
; 197. else if (val == 'd')
CPI R16,LOW(100)
BRNE X_0049
; 198. {
; 199. EEARL = address;
OUT LOW(30),R24
; 200. EEARH = (address >> 8);
OUT LOW(31),R25
; 201. address++;
ADIW R24,LWRD(1)
; 202. EECR |= (1<<EERE);
SBI LOW(28),LOW(0)
; 203. sendchar(EEDR);
IN R16,LOW(29)
RJMP X_0096
X_0049:
; 204. }
; 205. else if(val=='F') // read fuse bits
CPI R16,LOW(70)
BRNE X_0052
; 206. {
; 210. sendchar(read_program_memory(0x0000,0x09));
CLR R16
RJMP X_0107A
X_0052:
; 211. }
; 212.
; 213. else if(val=='r') // read lock bits
CPI R16,LOW(114)
BRNE X_0055
; 214. {
; 218. sendchar(read_program_memory(0x0001,0x09));
LDI R16,LOW(1)
RJMP X_0107A
X_0055:
; 219. }
; 220.
; 221. else if(val=='N') // read high fuse bits
CPI R16,LOW(78)
BRNE X_0058
; 222. {
; 226. sendchar(read_program_memory(0x0003,0x09));
LDI R16,LOW(3)
X_0107A:
LDI R20,9
X_0107:
LDI R17,0
X_0102:
rcall read_program_memory
RJMP X_0096
X_0058:
; 227. }
; 228.
; 229. else if(val=='t') // Return programmer type
CPI R16,LOW(116)
BRNE X_0061
; 230. {
; 231. sendchar(PARTCODE);
LDI R16,0x66
rcall sendchar
; 232. sendchar(0);
CLR R16
RJMP X_0096
X_0061:
; 233. }
; 234.
; 235. else if ((val=='x')||(val=='y')||(val=='T'))
CPI R16,LOW(120)
BREQ X_0065
CPI R16,LOW(121)
BREQ X_0065
CPI R16,LOW(84)
BRNE X_0064
X_0065:
; 236. {
; 237. recchar();
rcall recchar
; 238. sendchar('\r');
X_0101:
LDI R16,13
RJMP X_0096
X_0064:
; 239. }
; 240.
; 241. else if (val=='S') // Return software identifier
CPI R16,LOW(83)
BRNE X_0069
ldi R30,LOW(ID<<1)
ldi R31,HIGH(ID<<1)
RJMP PC+2
IDLP:
RCALL sendchar
LPM R16,Z+
TST R16
BRNE IDLP
RJMP X_0002
ID:
.DB "AVRBOOT",0
X_0069:
; 250. }
; 251.
; 252. else if (val=='V') // Return Software Version
CPI R16,LOW(86)
BRNE X_0072
; 253. {
; 254. sendchar('1');
LDI R16,49
rcall sendchar
; 255. sendchar('0');
LDI R16,48
RJMP X_0096
X_0072:
; 256. }
; 257.
; 258. else if (val=='s') // Return Signature Byte
CPI R16,LOW(115)
BRNE X_0075
; 259. {
; 260. sendchar(sig_byte3);
LDI R16,0x02
rcall sendchar
; 261. sendchar(sig_byte2);
LDI R16,0x94
rcall sendchar
; 262. sendchar(sig_byte1);
LDI R16,0x1E
RJMP X_0096
X_0075:
; 263. }
; 264.
; 265. else if(val!=0x1b) // if not esc
CPI R16,LOW(27)
BRNE PC+2
RJMP X_0002
; 266. {
; 267. sendchar('X_');
LDI R16,63
X_0096:
rcall sendchar
; 268. }
; 269. }
; 270. }
RJMP X_0002
X_0003:
; 271. else
; 272. {
; 273. funcptr(); // Jump to Reset vector 0x0000 in Application Section
IJMP
; 274. }
; 275. }
X_0108:
MOVW R16,R24
; MOV R17,R25
JMP write_page
; intval R26-R27
; data R16-R17
; ldata R4
; address R24-R25
; val R16
; funcptr R30-R31
; .END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -