sisp.S 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. ;
  2. ; Copyright (C) 2002-2003 by egnite Software GmbH. All rights reserved.
  3. ;
  4. ; Redistribution and use in source and binary forms, with or without
  5. ; modification, are permitted provided that the following conditions
  6. ; are met:
  7. ;
  8. ; 1. Redistributions of source code must retain the above copyright
  9. ; notice, this list of conditions and the following disclaimer.
  10. ; 2. Redistributions in binary form must reproduce the above copyright
  11. ; notice, this list of conditions and the following disclaimer in the
  12. ; documentation and/or other materials provided with the distribution.
  13. ; 3. All advertising materials mentioning features or use of this
  14. ; software must display the following acknowledgement:
  15. ;
  16. ; This product includes software developed by egnite Software GmbH
  17. ; and its contributors.
  18. ;
  19. ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. ; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. ; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. ; COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. ; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. ; OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. ; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. ; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. ; THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. ; SUCH DAMAGE.
  31. ;
  32. ; For additional information see http://www.ethernut.de/
  33. ;
  34. ; $Log$
  35. ; Revision 1.1 2003/11/03 15:51:31 haraldkipp
  36. ; First check in
  37. ;
  38. ;
  39. .nolist
  40. #include "avr/io.h"
  41. .list
  42. ; This program implements a minimalist STK500 compatible programming
  43. ; adapter for the serial port on an AT90S2313 MCU. It had been
  44. ; originally written for AVR Studio, but then ported to AVR-GCC and
  45. ; will no longer build with AVR Studio. However, the resulting
  46. ; programmer had been successfully tested with AVR Studio 4.07 and
  47. ; uisp version 20030827cvs on ATmega128 and ATmega13 targets.
  48. ;
  49. ; *********************************************************************
  50. ; Protocol definitions
  51. ; Initially the STK500 protocol had been evaluated by re-engineering.
  52. ; Some months later Atmel decided to publish it. See
  53. ; http://www.atmel.com/atmel/acrobat/doc2525.pdf
  54. #define STK_OK 0x10
  55. #define STK_INSYNC 0x14
  56. #define STK_NOSYNC 0x15
  57. #define CRC_EOP 0x20
  58. ; *********************************************************************
  59. ; General configurations
  60. ; Baudrate factor. AVR Studio uses a fixed rate of 115,200 Baud, which
  61. ; results in a baudrate register factor of 1 on a 3.6864 MHz MCU. See
  62. ; the AT90S2313 datasheet for further details.
  63. #define BRFACTOR 1
  64. ; *********************************************************************
  65. ; Port Usage
  66. ; PB0: Unused
  67. ; PB1: Unused
  68. ; PB2: ISP-LED (out)
  69. ; PB3: LED (out)
  70. ; PB4: ISP-RESET (out)
  71. ; PB5: ISP-MOSI (out)
  72. ; PB6: ISP-MISO (in)
  73. ; PB7: ISP-SCK (out)
  74. ;
  75. ; PD0: RXD (in)
  76. ; PD1: TXD (out)
  77. ; PD2: HSIN/INT0 (in)
  78. ; PD3: HSOUT (out)
  79. ; PD4: unused
  80. ; PD5: unused
  81. ; PD6: unused
  82. ;
  83. #define ISPLED 2
  84. #define LEDIND 3
  85. #define ISPRST 4
  86. #define ISPMOSI 5
  87. #define ISPMISO 6
  88. #define ISPSCK 7
  89. #define HSIN 2
  90. #define HSOUT 3
  91. ; *********************************************************************
  92. ; Register usage
  93. #define r_temp r16
  94. #define r_data r17
  95. #define r_isp r18
  96. #define r_shift r19
  97. #define r_delay r20
  98. #define r_retry r21
  99. #define r_size r22
  100. #define r_parm r23
  101. ; *********************************************************************
  102. ; RAM variables
  103. .section .bss
  104. paddrl: .space 1
  105. paddrh: .space 1
  106. unicmd1: .space 1
  107. unicmd2: .space 1
  108. unicmd3: .space 1
  109. unicmd4: .space 1
  110. pm_devicecode: .space 1 ; device code
  111. pm_revision: .space 1 ; device revision
  112. pm_progtype: .space 1 ; "0" both, "1" par only
  113. pm_parmode: .space 1 ; "0" pseudo, "1" full
  114. pm_polling: .space 1 ; "0" no, "1" yes
  115. pm_selftimed: .space 1 ; "0" no, "1" yes
  116. pm_lockbytes: .space 1 ; # of lock bytes
  117. pm_fusebytes: .space 1 ; # of fuse bytes
  118. pm_flpollval1: .space 1 ; Flash polling value
  119. pm_flpollval2: .space 1 ; Flash polling value
  120. pm_eepollval1: .space 1 ; EEPROM polling value
  121. pm_eepollval2: .space 1 ; EEPROM polling value
  122. pm_pagesizeh: .space 1 ; Page size high byte
  123. pm_pagesizel: .space 1 ; Page size low byte
  124. pm_eesizeh: .space 1 ; EEPROM size high byte
  125. pm_eesizel: .space 1 ; EEPROM size low byte
  126. pm_flsize4: .space 1 ; Flash size MSB
  127. pm_flsize3: .space 1 ; Flash size
  128. pm_flsize2: .space 1 ; Flash size
  129. pm_flsize1: .space 1 ; Flash size LSB
  130. ; *********************************************************************
  131. ; Vector table
  132. .section .text
  133. .global sisp
  134. sisp:
  135. rjmp main
  136. ; *********************************************************************
  137. ; Constant data
  138. .type signon_msg, @object
  139. .global signon_msg
  140. signon_msg:
  141. .string "\x14\x41VR STK\x10"
  142. .type version_msg, @object
  143. .global version_msg
  144. version_msg:
  145. .string "SISP 1.1.1 Copyright 2002-2003 by egnite Software GmbH\r\n"
  146. ; *********************************************************************
  147. ; Main program entry
  148. .global main
  149. main:
  150. ;
  151. ; Set stack pointer
  152. ldi r_temp, lo8(RAMEND)
  153. out _SFR_IO_ADDR(SPL), r_temp
  154. ;
  155. ; Initialize Port B
  156. ; PB2: ISP-LED z-state
  157. ; PB3: LED output low
  158. ; PB4: ISP-RESET z-state
  159. ; PB5: ISP-MOSI z-state
  160. ; PB6: ISP-MISO input
  161. ; PB7: ISP-SCK z-state
  162. clr r_temp
  163. out _SFR_IO_ADDR(PORTB), r_temp
  164. out _SFR_IO_ADDR(DDRB), r_temp
  165. sbi _SFR_IO_ADDR(DDRB), LEDIND
  166. ldi r_retry, 3
  167. blink:
  168. rcall xdelay
  169. rcall xdelay
  170. cbi _SFR_IO_ADDR(PORTB), LEDIND ; LED on
  171. ldi r_delay, 64
  172. rcall xdelay
  173. sbi _SFR_IO_ADDR(PORTB), LEDIND ; LED off
  174. dec r_retry
  175. brne blink
  176. ;
  177. ; Init UART
  178. ldi r_temp, BRFACTOR
  179. out _SFR_IO_ADDR(UBRR), r_temp
  180. ldi r_temp, (1<<RXEN) | (1<<TXEN)
  181. out _SFR_IO_ADDR(UCR), r_temp
  182. ;
  183. ; Set handshake line
  184. sbi _SFR_IO_ADDR(PORTD), HSOUT
  185. sbi _SFR_IO_ADDR(DDRD), HSOUT
  186. ; *********************************************************************
  187. ; Command handler
  188. cmdnxt:
  189. sbi _SFR_IO_ADDR(PORTB), LEDIND ; LED off
  190. rcall getc
  191. cbi _SFR_IO_ADDR(PORTB), LEDIND ; LED on
  192. ; *********************************************************************
  193. ; Version output
  194. cpi r_data, 0x18 ; Ctrl-X
  195. brne c30
  196. ldi r30, lo8(version_msg)
  197. ldi r31, hi8(version_msg)
  198. rjmp c31a
  199. ; *********************************************************************
  200. ; PC command: Get synchronization.
  201. ;
  202. ; The PC uses this command to regain synchronization with the
  203. ; programmer. The command may be send several times until the
  204. ; programmer responds with STK_INSYNC.
  205. c30:
  206. cpi r_data, 0x30 ; '0'
  207. brne c31
  208. ; Receive last character of a command. If it's an EOP, then
  209. ; respond with INSYNC. Otherwise send back NOSYNC.
  210. cmdend:
  211. rcall getc
  212. cpi r_data, CRC_EOP
  213. breq cmdok
  214. ldi r_data, STK_NOSYNC
  215. rcall putc
  216. rjmp cmdnxt ; Wait for next command
  217. ; Send back positive response.
  218. cmdok:
  219. ldi r_data, STK_INSYNC
  220. rcall putc
  221. cmdfirm:
  222. ldi r_data, STK_OK
  223. rcall putc
  224. rjmp cmdnxt ; Wait for next command
  225. ; *********************************************************************
  226. ; PC command: Check if starterkit present.
  227. ;
  228. ; The programmer responds with a sign-on message.
  229. ;
  230. c31:
  231. cpi r_data, 0x31 ; '1'
  232. brne c41
  233. rcall getc ; Ignore CRC_EOP
  234. ldi r30, lo8(signon_msg)
  235. ldi r31, hi8(signon_msg)
  236. c31a:
  237. lpm
  238. tst r0
  239. breq cmdnxt ; Done, wait for next command
  240. mov r_data, r0
  241. rcall putc
  242. adiw r30, 1
  243. rjmp c31a
  244. ; *********************************************************************
  245. ; PC command: Get parameter value
  246. c41:
  247. cpi r_data, 0x41 ; 'A'
  248. brne c42
  249. rcall getc ; Receive parameter id
  250. mov r_parm, r_data
  251. rcall getc ; Ignore CRC_EOP
  252. ldi r_data, STK_INSYNC
  253. rcall putc
  254. rcall getparm
  255. rcall putc
  256. rjmp cmdfirm
  257. ; *********************************************************************
  258. ; PC command: Set device programming parameters
  259. ;
  260. ; We ignore these parameters.
  261. c42:
  262. cpi r_data, 0x42 ; 'B'
  263. brne c45
  264. ldi r_size, 20
  265. _c42nxt:
  266. rcall getc
  267. dec r_size
  268. brne _c42nxt
  269. rjmp cmdend
  270. ; *********************************************************************
  271. ; PC command: Set extended device programming parameters
  272. ;
  273. ; We ignore these parameters.
  274. c45:
  275. cpi r_data, 0x45 ; 'E'
  276. brne c50
  277. ldi r_size, 5
  278. _c45nxt:
  279. rcall getc
  280. dec r_size
  281. brne _c45nxt
  282. rjmp cmdend
  283. ; *********************************************************************
  284. ; PC command: Enter Program Mode
  285. c50:
  286. cpi r_data, 0x50 ; 'P'
  287. brne c51
  288. rcall getc ; Ignore CRC_EOP
  289. ;
  290. ; Enable ISP interface.
  291. ; PB2: ISP-LED output low
  292. ; PB3: LED output low
  293. ; PB4: ISP-RESET output low
  294. ; PB5: ISP-MOSI output high
  295. ; PB6: ISP-MISO input
  296. ; PB7: ISP-SCK output low
  297. ldi r_temp, (1<<ISPMISO)
  298. out _SFR_IO_ADDR(PORTB), r_temp
  299. ldi r_temp, (1<<ISPLED)|(1<<LEDIND)|(1<<ISPRST)|(1<<ISPMOSI)|(1<<ISPSCK)
  300. out _SFR_IO_ADDR(DDRB), r_temp
  301. rcall xdelay
  302. ldi r_retry, 32
  303. ;
  304. ; Send programming enable
  305. c50a:
  306. ldi r_isp, 0xAC
  307. rcall ispxcg
  308. ldi r_isp, 0x53
  309. rcall ispxcg
  310. rcall ispget
  311. cpi r_isp, 0x53 ; Are we in sync
  312. breq c50z ; Yes, jump
  313. ;
  314. ; Handle sync failure
  315. rcall ispget ; Read last SPI byte
  316. sbi _SFR_IO_ADDR(PORTB), ISPRST ; Toggle target's reset line
  317. rcall xdelay
  318. cbi _SFR_IO_ADDR(PORTB), ISPRST
  319. rcall xdelay
  320. dec r_retry ; Loop for retries
  321. brne c50a
  322. rjmp cmdok ; Send positive resopnse
  323. c50z:
  324. rcall ispget
  325. rjmp cmdok ; Send positive resopnse
  326. ; *********************************************************************
  327. ; PC command: Leave program mode
  328. c51:
  329. cpi r_data, 0x51 ; 'Q'
  330. brne c52
  331. rcall getc ; Ignore CRC_EOP
  332. ;
  333. ; Disable ISP interface.
  334. ; PB2: ISP-LED z-state
  335. ; PB3: LED output low
  336. ; PB4: ISP-RESET z-state
  337. ; PB5: ISP-MOSI z-state
  338. ; PB6: ISP-MISO input
  339. ; PB7: ISP-SCK z-state
  340. clr r_temp
  341. out _SFR_IO_ADDR(PORTB), r_temp
  342. out _SFR_IO_ADDR(DDRB), r_temp
  343. sbi _SFR_IO_ADDR(DDRB), LEDIND
  344. rjmp cmdok ; Send positive resopnse
  345. ; *********************************************************************
  346. ; PC command: Chip erase
  347. c52:
  348. cpi r_data, 0x52 ; 'R'
  349. brne c55
  350. rcall getc
  351. ldi r_isp, 0xAC
  352. rcall ispxcg
  353. ldi r_isp, 0x80
  354. rcall ispxcg
  355. ldi r_isp, 0x04
  356. rcall ispxcg
  357. rcall ispget
  358. rcall xdelay ; Very long delay. May be reduced
  359. rcall xdelay ; but who really cares?
  360. rjmp cmdok ; Send positive resopnse
  361. ; *********************************************************************
  362. ; PC command: Load address
  363. c55:
  364. cpi r_data, 0x55 ; 'U'
  365. brne c56
  366. rcall getc
  367. sts paddrl, r_data
  368. rcall getc
  369. sts paddrh, r_data
  370. rjmp cmdend
  371. ; *********************************************************************
  372. ; PC command: Universal
  373. c56:
  374. cpi r_data, 0x56 ; 'V'
  375. brne c64
  376. rcall getc
  377. sts unicmd1, r_data
  378. rcall getc
  379. sts unicmd2, r_data
  380. rcall getc
  381. sts unicmd3, r_data
  382. rcall getc
  383. sts unicmd4, r_data
  384. rcall getc ; EOP
  385. ldi r_data, STK_INSYNC
  386. rcall putc
  387. lds r_isp, unicmd1
  388. rcall ispxcg
  389. lds r_isp, unicmd2
  390. rcall ispxcg
  391. lds r_isp, unicmd3
  392. rcall ispxcg
  393. lds r_isp, unicmd4
  394. rcall ispxcg
  395. ldi r_delay, 64
  396. rcall delay
  397. mov r_data, r_isp
  398. rcall putc
  399. rjmp cmdfirm
  400. ; *********************************************************************
  401. ; PC command: Program page
  402. ; This is a very tricky routine. The STK500 insists on sending
  403. ; data with 115,200 Baud. We hope, that the target MCU will be
  404. ; fast enough.
  405. c64:
  406. cpi r_data, 0x64 ; 'd'
  407. brne c72
  408. rcall getc ; Size of this block to Y-register
  409. mov r29, r_data
  410. rcall getc
  411. mov r28, r_data
  412. rcall getc ; Memory type (F)lash or (E)eprom
  413. cpi r_data, 'F'
  414. brne c64ee
  415. clr r30
  416. c64a:
  417. ldi r_isp, 0x40 ; Send low byte
  418. rcall ispput
  419. clr r_isp
  420. rcall ispput
  421. mov r_isp, r30
  422. rcall ispput
  423. c64b:
  424. sbis _SFR_IO_ADDR(USR), RXC
  425. rjmp c64b
  426. in r_isp, _SFR_IO_ADDR(UDR)
  427. rcall ispput
  428. ldi r_isp, 0x48 ; Send high byte
  429. rcall ispput
  430. clr r_isp
  431. rcall ispput
  432. mov r_isp, r30
  433. rcall ispput
  434. c64c:
  435. sbis _SFR_IO_ADDR(USR), RXC
  436. rjmp c64c
  437. in r_isp, _SFR_IO_ADDR(UDR)
  438. rcall ispput
  439. inc r30 ; Increment address
  440. sbiw r28, 2 ; Decrement length
  441. brne c64a
  442. rcall getc
  443. ldi r_isp, 0x4C ; Write memory page
  444. rcall ispxcg
  445. lds r_isp, paddrh
  446. rcall ispxcg
  447. lds r_isp, paddrl
  448. rcall ispxcg
  449. rcall ispget
  450. ldi r_delay, 168 ; Target requires delay after each write
  451. rcall delay ; We use 35 milliseconds, OK for most targets
  452. rjmp cmdok ; Send positive resopnse
  453. c64ee:
  454. c64ea:
  455. sbis _SFR_IO_ADDR(USR), RXC
  456. rjmp c64ea
  457. in r_isp, _SFR_IO_ADDR(UDR)
  458. c64ec:
  459. sbis _SFR_IO_ADDR(USR), RXC
  460. rjmp c64ec
  461. in r_isp, _SFR_IO_ADDR(UDR)
  462. sbiw r28, 2
  463. brne c64a
  464. rjmp cmdend
  465. ; *********************************************************************
  466. ; PC command: Read Fuse Bits
  467. c72:
  468. cpi r_data, 0x72 ; 'r'
  469. brne c73
  470. rcall getc ; EOP
  471. ldi r_data, STK_INSYNC ; INSYNC
  472. rcall putc
  473. ldi r_isp, 0x50 ; Read fuse bits command
  474. rcall ispxcg
  475. ldi r_isp, 0x00 ; Must be zero, don't care on mega103
  476. rcall ispxcg
  477. rcall ispget ; Don't care
  478. rcall ispget ; These are the bits
  479. mov r_data, r_isp
  480. rcall putc
  481. ; ATmega128 only
  482. ldi r_isp, 0x58 ; Read high fuses bits command
  483. rcall ispxcg
  484. ldi r_isp, 0x08 ; Must be 8
  485. rcall ispxcg
  486. rcall ispget ; Don't care
  487. rcall ispget ; Here we get them
  488. mov r_data, r_isp
  489. rcall putc
  490. rjmp cmdfirm
  491. ; *********************************************************************
  492. ; PC command: Read Lock Bits
  493. c73:
  494. cpi r_data, 0x73 ; 's'
  495. brne c74
  496. rcall getc ; EOP
  497. ldi r_data, STK_INSYNC ; INSYNC
  498. rcall putc
  499. ldi r_isp, 0x58
  500. rcall ispxcg
  501. ldi r_isp, 0x00
  502. rcall ispxcg
  503. rcall ispget
  504. rcall ispget
  505. mov r_data, r_isp
  506. rcall putc
  507. rjmp cmdfirm
  508. ; *********************************************************************
  509. ; PC command: Read Page
  510. c74:
  511. cpi r_data, 0x74 ; 't'
  512. brne c75
  513. rcall getc
  514. mov r29, r_data
  515. rcall getc
  516. mov r28, r_data
  517. rcall getc ; 'F' or 'E'
  518. cpi r_data, 'F'
  519. brne c74ee
  520. rcall getc ; EOP
  521. ldi r_data, STK_INSYNC ; INSYNC
  522. rcall putc
  523. lds r30, paddrl
  524. lds r31, paddrh
  525. c74a:
  526. ldi r_isp, 0x20
  527. rcall ispxcg
  528. mov r_isp, r31
  529. rcall ispxcg
  530. mov r_isp, r30
  531. rcall ispxcg
  532. rcall ispget
  533. mov r_data, r_isp
  534. rcall putc
  535. ldi r_isp, 0x28
  536. rcall ispxcg
  537. mov r_isp, r31
  538. rcall ispxcg
  539. mov r_isp, r30
  540. rcall ispxcg
  541. rcall ispget
  542. mov r_data, r_isp
  543. rcall putc
  544. adiw r30, 1
  545. sbiw r28, 2
  546. brne c74a
  547. rjmp cmdfirm
  548. c74ee:
  549. rcall getc ; EOP
  550. ldi r_data, STK_INSYNC ; INSYNC
  551. rcall putc
  552. lds r30, paddrl
  553. lds r31, paddrh
  554. c74ea:
  555. ldi r_isp, 0xA0
  556. rcall ispxcg
  557. mov r_isp, r31
  558. rcall ispxcg
  559. mov r_isp, r30
  560. rcall ispxcg
  561. rcall ispget
  562. mov r_data, r_isp
  563. rcall putc
  564. adiw r30, 1
  565. sbiw r28, 1
  566. brne c74ea
  567. rjmp cmdfirm
  568. ; *********************************************************************
  569. ; PC command: Read Signature
  570. c75:
  571. cpi r_data, 0x75 ; 'u'
  572. brne c76
  573. rcall getc
  574. ldi r_data, STK_INSYNC
  575. rcall putc
  576. ldi r_isp, 0x30
  577. rcall ispxcg
  578. rcall ispget
  579. rcall ispget
  580. rcall ispget
  581. mov r_data, r_isp
  582. rcall putc
  583. ldi r_isp, 0x30
  584. rcall ispxcg
  585. rcall ispget
  586. ldi r_isp, 0x01
  587. rcall ispxcg
  588. rcall ispget
  589. mov r_data, r_isp
  590. rcall putc
  591. ldi r_isp, 0x30
  592. rcall ispxcg
  593. rcall ispget
  594. ldi r_isp, 0x02
  595. rcall ispxcg
  596. rcall ispget
  597. mov r_data, r_isp
  598. rcall putc
  599. rjmp cmdfirm
  600. ; *********************************************************************
  601. ; PC command: Read Oscillator Calibration Byte
  602. c76:
  603. cpi r_data, 0x76 ; 'v'
  604. brne c77
  605. rcall getc ; EOP
  606. ldi r_data, STK_INSYNC ; INSYNC
  607. rcall putc
  608. ldi r_isp, 0x38
  609. rcall ispxcg
  610. rcall ispget
  611. rcall ispget
  612. rcall ispget
  613. mov r_data, r_isp
  614. rcall putc
  615. rjmp cmdfirm
  616. ; *********************************************************************
  617. ; PC command: Read Fuse Bits Extended
  618. c77:
  619. cpi r_data, 0x77 ; 'w'
  620. brne c78
  621. rcall getc ; EOP
  622. ldi r_data, STK_INSYNC ; INSYNC
  623. rcall putc
  624. ldi r_isp, 0x50
  625. rcall ispxcg
  626. ldi r_isp, 0x00
  627. rcall ispxcg
  628. rcall ispget
  629. rcall ispget
  630. mov r_data, r_isp
  631. rcall putc
  632. ldi r_isp, 0x58
  633. rcall ispxcg
  634. ldi r_isp, 0x08
  635. rcall ispxcg
  636. rcall ispget
  637. rcall ispget
  638. mov r_data, r_isp
  639. rcall putc
  640. ldi r_isp, 0x50
  641. rcall ispxcg
  642. ldi r_isp, 0x08
  643. rcall ispxcg
  644. rcall ispget
  645. rcall ispget
  646. mov r_data, r_isp
  647. rcall putc
  648. rjmp cmdfirm
  649. ; *********************************************************************
  650. ; PC command: Read Oscillator Calibration Byte Extended
  651. c78:
  652. cpi r_data, 0x78 ; 'x'
  653. brne cbad
  654. rcall getc
  655. mov r30, r_data
  656. rcall getc ; EOP
  657. ldi r_data, STK_INSYNC ; INSYNC
  658. rcall putc
  659. ldi r_isp, 0x38
  660. rcall ispxcg
  661. rcall ispget
  662. mov r_isp, r30
  663. rcall ispxcg
  664. rcall ispget
  665. mov r_data, r_isp
  666. rcall putc
  667. rjmp cmdfirm
  668. ; *********************************************************************
  669. ; PC command: Unknown
  670. cbad:
  671. rjmp cmdend
  672. ; *********************************************************************
  673. ; *** GetParm
  674. getparm:
  675. ;
  676. ; Hardware version
  677. cpi r_parm, 0x80
  678. brne _gp81
  679. ldi r_data, 2
  680. ret
  681. ;
  682. ; Software version major
  683. _gp81:
  684. cpi r_parm, 0x81
  685. brne _gp82
  686. ldi r_data, 1
  687. ret
  688. ;
  689. ; Software version minor
  690. _gp82:
  691. cpi r_parm, 0x82
  692. brne _gp83
  693. ldi r_data, 14
  694. ret
  695. ;
  696. ; LEDs
  697. _gp83:
  698. cpi r_parm, 0x83
  699. brne _gp84
  700. ldi r_data, 1
  701. ret
  702. ;
  703. ; Target voltage
  704. _gp84:
  705. cpi r_parm, 0x84
  706. brne _gp85
  707. ldi r_data, 50
  708. ret
  709. ;
  710. ; Adjustable Voltage
  711. _gp85:
  712. cpi r_parm, 0x85
  713. brne _gp86
  714. ldi r_data, 50
  715. ret
  716. ;
  717. ; Oscillator timer prescaler value
  718. _gp86:
  719. cpi r_parm, 0x86
  720. brne _gp87
  721. ldi r_data, 0
  722. ret
  723. ;
  724. ; Oscillator timer compare match value
  725. _gp87:
  726. cpi r_parm, 0x87
  727. brne _gp88
  728. ldi r_data, 0
  729. ret
  730. ;
  731. ; Reset duration
  732. _gp88:
  733. cpi r_parm, 0x88
  734. brne _gp89
  735. ldi r_data, 0x30
  736. ret
  737. ;
  738. ; SCK duration
  739. _gp89:
  740. cpi r_parm, 0x89
  741. brne _gp90
  742. ldi r_data, 0x30
  743. ret
  744. ;
  745. ; Bufsiz low
  746. _gp90:
  747. cpi r_parm, 0x90
  748. brne _gp91
  749. ldi r_data, 64
  750. ret
  751. ;
  752. ; Bufsiz high
  753. _gp91:
  754. cpi r_parm, 0x91
  755. brne _gp92
  756. ldi r_data, 0
  757. ret
  758. ;
  759. ; Device
  760. _gp92:
  761. cpi r_parm, 0x92
  762. brne _gp93
  763. lds r_data, pm_devicecode
  764. ret
  765. ;
  766. ; Progmode
  767. _gp93:
  768. cpi r_parm, 0x93
  769. brne _gp94
  770. lds r_data, pm_progtype
  771. ret
  772. ;
  773. ; Para mode
  774. _gp94:
  775. cpi r_parm, 0x94
  776. brne _gp95
  777. lds r_data, pm_parmode
  778. ret
  779. ;
  780. ; Polling
  781. _gp95:
  782. cpi r_parm, 0x95
  783. brne _gp96
  784. lds r_data, pm_polling
  785. ret
  786. ;
  787. ; Self timed
  788. _gp96:
  789. cpi r_parm, 0x96
  790. brne _gpuk
  791. lds r_data, pm_selftimed
  792. ret
  793. ;
  794. ; Unknown
  795. _gpuk:
  796. clr r_data
  797. ret
  798. ;
  799. ; *********************************************************************
  800. ; UART routines
  801. ; The UART is used in polling mode.
  802. ; Receive a single byte into register r_data.
  803. ;
  804. ; This routine will not return until a byte is available.
  805. ;
  806. getc:
  807. sbis _SFR_IO_ADDR(USR), RXC
  808. rjmp getc
  809. in r_data, _SFR_IO_ADDR(UDR)
  810. ret
  811. ; Send a single byte passed in register r_data.
  812. ;
  813. putc:
  814. sbis _SFR_IO_ADDR(USR), UDRE
  815. rjmp putc
  816. out _SFR_IO_ADDR(UDR), r_data
  817. ret
  818. ; *********************************************************************
  819. ; Exchange ISP Byte
  820. ispget:
  821. clr r_isp
  822. ispxcg:
  823. ldi r_temp, 8
  824. clr r_shift
  825. ;
  826. ; Start of 8-bit loop
  827. _ispa:
  828. rol r_isp ; (1)
  829. brcc _ispb ; (2/1)
  830. sbi _SFR_IO_ADDR(PORTB), ISPMOSI ; (2)
  831. rjmp _ispc ; (2)
  832. _ispb:
  833. cbi _SFR_IO_ADDR(PORTB), ISPMOSI ; (2)
  834. _ispc:
  835. nop ; (1)
  836. sbi _SFR_IO_ADDR(PORTB), ISPSCK ; (2)
  837. lsl r_shift ; (1)
  838. sbic _SFR_IO_ADDR(PINB), ISPMISO ; (2/1)
  839. ori r_shift, 1 ; (1)
  840. cbi _SFR_IO_ADDR(PORTB), ISPSCK ; (2)
  841. ;
  842. ; End of 8-bit loop
  843. dec r_temp ; (1)
  844. brne _ispa ; (2/1)
  845. mov r_isp, r_shift ; (1)
  846. ret ; (4)
  847. ; *********************************************************************
  848. ; Send out a byte to ISP as fast as possible.
  849. ;
  850. ; Runtime calculation:
  851. ; + 7 cycles for rcall/return
  852. ; + 1 cycle to initially read the port status
  853. ; + 4 cycle to set the final port status
  854. ; + 48 cycles for output, 6 cycles per bit
  855. ; The total of 60 cycles takes 16.276 microseconds on a 3.6864 MHz MCU.
  856. ; At 115 kBaud a new character is received every 86.8 microsecond.
  857. ; The SCK low time is 814 nanoseconds and the high time is 543 nanoseconds.
  858. ; Following the datasheet, the target requires a minimum SCK low and
  859. ; high time of 2 clock cycles. So we may not be able to program targets
  860. ; running with same or higher crystals than our own.
  861. ; Tests with an ATmega128 showed, that it was possible to program the
  862. ; chip while running on its internal oscillator down to 2 MHz.
  863. ;
  864. ispput: ; (3) Costly call
  865. in r_temp, _SFR_IO_ADDR(PORTB) ; (1) Load current port status
  866. bst r_isp, 7 ; (1) Bit7 -> T
  867. bld r_temp, ISPMOSI ; (1) T -> MOSI
  868. out _SFR_IO_ADDR(PORTB), r_temp ; (1) Output, SCK still low
  869. sbi _SFR_IO_ADDR(PORTB), ISPSCK ; (2) SCK high
  870. bst r_isp, 6 ; (1)
  871. bld r_temp, ISPMOSI ; (1)
  872. out _SFR_IO_ADDR(PORTB), r_temp ; SCK back to low after about 3 cycles
  873. nop
  874. sbi _SFR_IO_ADDR(PORTB), ISPSCK ; SCK high again after about 2 cycles
  875. bst r_isp, 5
  876. bld r_temp, ISPMOSI
  877. out _SFR_IO_ADDR(PORTB), r_temp
  878. nop
  879. sbi _SFR_IO_ADDR(PORTB), ISPSCK
  880. bst r_isp, 4
  881. bld r_temp, ISPMOSI
  882. out _SFR_IO_ADDR(PORTB), r_temp
  883. nop
  884. sbi _SFR_IO_ADDR(PORTB), ISPSCK
  885. bst r_isp, 3
  886. bld r_temp, ISPMOSI
  887. out _SFR_IO_ADDR(PORTB), r_temp
  888. nop
  889. sbi _SFR_IO_ADDR(PORTB), ISPSCK
  890. bst r_isp, 2
  891. bld r_temp, ISPMOSI
  892. out _SFR_IO_ADDR(PORTB), r_temp
  893. nop
  894. sbi _SFR_IO_ADDR(PORTB), ISPSCK
  895. bst r_isp, 1
  896. bld r_temp, ISPMOSI
  897. out _SFR_IO_ADDR(PORTB), r_temp
  898. nop
  899. sbi _SFR_IO_ADDR(PORTB), ISPSCK
  900. bst r_isp, 0
  901. bld r_temp, ISPMOSI
  902. out _SFR_IO_ADDR(PORTB), r_temp
  903. nop
  904. sbi _SFR_IO_ADDR(PORTB), ISPSCK
  905. nop
  906. nop
  907. nop
  908. out _SFR_IO_ADDR(PORTB), r_temp ; (1) SCK low
  909. ret ; (4) Costly return
  910. ; *********************************************************************
  911. ; Delay
  912. ;
  913. ; xdelay takes about 53.6 ms
  914. xdelay: ; (3)
  915. clr r_delay ; (1)
  916. delay:
  917. clr r_temp ; (1) Outer loop with r_delay * 772 cycles
  918. dl:
  919. dec r_temp ; (1) Inner loop with 3 cycles
  920. brne dl ; (2/1)
  921. dec r_delay ; (1)
  922. brne delay ; (2/1)
  923. ret ; (4)
  924. #ifdef SISPDEBUG
  925. ; *********************************************************************
  926. ; Debug
  927. ;
  928. puthexb:
  929. push r_data
  930. swap r_data
  931. rcall puthexc
  932. pop r_data
  933. puthexc:
  934. push r_temp
  935. mov r_temp, r_data
  936. andi r_temp, 0x0f
  937. subi r_temp, -'0'
  938. cpi r_temp, 0x3a
  939. brlo _putx1
  940. subi r_temp, -7
  941. _putx1:
  942. push r_data
  943. mov r_data, r_temp
  944. rcall putc
  945. pop r_data
  946. pop r_temp
  947. ret
  948. #endif