Fork from bluejay at github and modified for my custom ESC. I need to modify it because some mistake design on my ESC hardware.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

385 lines
7.9 KiB

  1. ; BLHeli bootloader for SiLabs MCUs. Based upon AVRootloader (copyright HR)
  2. XTAL EQU 25000000
  3. BOOT_START EQU 1C00h ; Bootloader segment address
  4. BOOT_DELAY EQU XTAL/4 ; About 250ms (don't set to fast to avoid connection problems)
  5. BOOT_BAUDRATE EQU 19200 ; Only used if no baudrate detection activated, XTAL is than important
  6. BOOT_VERSION EQU 6 ; Version 6 (must be not changed)
  7. BOOT_PAGES EQU 1 ; Number of flash segments for bootloader
  8. UART_LOOP EQU 26 ; Depends upon timing of putc, getc
  9. BAUDTIME EQU ((XTAL/BOOT_BAUDRATE)/3)-UART_LOOP
  10. SUCCESS EQU 030h
  11. ERRORVERIFY EQU 0C0h
  12. ERRORCOMMAND EQU 0C1h
  13. ERRORCRC EQU 0C2h
  14. ERRORPROG EQU 0C5h
  15. POLYNOM EQU 0A001h ; CRC Polynom
  16. Xl EQU R0 ; Temporary X
  17. Xh EQU R1
  18. Paral EQU R2 ; Params for UART
  19. Parah EQU R3
  20. Cmdl EQU R4 ; Commands
  21. Cmdh EQU R5
  22. Cntl EQU R6 ; Baudtime
  23. Cnth EQU R7
  24. DSEG AT 20h
  25. Bit_Reg: DS 1 ; Bit storage register
  26. Byte_Reg: DS 1 ; Byte storage register
  27. Crcl: DS 1 ; CRC 16Bit
  28. Crch: DS 1
  29. Baudl: DS 1 ; Baudtime
  30. Baudh: DS 1
  31. Bit_Cnt: DS 1 ; Counter in UART loops
  32. Byte_Cntl: DS 1 ; Generic counter
  33. Byte_Cnth: DS 1
  34. BL_Flash_Key_1: DS 1 ; Flash keys
  35. BL_Flash_Key_2: DS 1
  36. CSEG AT BOOT_START ; Bootloader start
  37. init:clr IE_EA
  38. ; Select register bank 0 for main program routines
  39. clr PSW.3 ; Select register bank 0 for main program routines
  40. ; Disable the WDT.
  41. mov WDTCN, #0DEh ; Disable watchdog
  42. mov WDTCN, #0ADh
  43. ; Initialize stack
  44. mov SP, #0c0h ; Stack = 64 upper bytes of RAM
  45. ; Initialize clock
  46. mov CLKSEL, #00h ; Set clock divider to 1
  47. ; Initialize VDD monitor
  48. orl VDM0CN, #080h ; Enable the VDD monitor
  49. mov Baudl, #38h ; Wait 100us
  50. mov Baudh, #03h
  51. acall waitf
  52. ; Initialize flash keys
  53. mov BL_Flash_Key_1, #0A5h ; First key code
  54. mov BL_Flash_Key_2, #0F1h ; Second key code
  55. ; Initialize ports
  56. orl RTX_MDIN, #(1 SHL RTX_PIN) ; Set digital
  57. anl RTX_MDOUT, #NOT(1 SHL RTX_PIN) ; Disable pushpull
  58. setb RTX_PORT.RTX_PIN ; Set data high
  59. mov RTX_SKIP, #0FFh
  60. mov XBR2, #40h; ; Enable crossbar
  61. ; Set number of connect attempts before exiting bootloader
  62. mov Cmdh, #250
  63. ; Identifier scanning
  64. abd: mov Xl, #(low(BOOT_DELAY / 6)+1)
  65. mov Xh, #(high(BOOT_DELAY / 6)+1)
  66. mov Cmdl, #(high((BOOT_DELAY / 6) SHR 8)+1)
  67. mov Crcl, #0
  68. mov Crch, #0
  69. mov DPTR, #BOOT_SIGN
  70. mov Parah, #(BOOT_MSG - BOOT_SIGN)
  71. mov Baudl, #low(BAUDTIME)
  72. mov Baudh, #high(BAUDTIME)
  73. wait_for_low:
  74. jnb RTX_PORT.RTX_PIN, ($+5)
  75. ajmp wait_for_low
  76. ; Identifier (BOOT_SIGN) scanning with timeout and checksum
  77. id1: jb RTX_PORT.RTX_PIN, id3 ; Look for high
  78. djnz Xl, id1 ; Subtract 1 from X (BOOT_DELAY)
  79. djnz Xh, id1
  80. djnz Cmdl, id1
  81. ajmp exit
  82. id3: jnb RTX_PORT.RTX_PIN, id4 ; Look for low
  83. djnz Xl, id3 ; Subtract 1 from X (BOOT_DELAY)
  84. djnz Xh, id3
  85. djnz Cmdl, id3
  86. ajmp exit
  87. id4: acall getx ; Read character
  88. clr A
  89. movc A, @A+DPTR ; Load BOOT_SIGN character
  90. inc DPTR
  91. clr C
  92. subb A, Paral ; Compare with read character
  93. jz id5
  94. djnz Cmdh, abd ; Retry if not last connect attempt
  95. ajmp exit
  96. id5:
  97. djnz Parah, id1
  98. acall getw ; Read CRC
  99. jz ($+4) ; Check CRC
  100. ajmp abd
  101. ; Send info about chip/bootloader (BOOT_MSG + BOOT_INFO)
  102. mov Parah, #((BOOT_INFO - BOOT_MSG) + 4)
  103. in1: clr A
  104. movc A, @A+DPTR ; Load character
  105. mov Paral, A
  106. inc DPTR
  107. acall putc
  108. djnz Parah, in1
  109. ; Main commandloop
  110. ; 0=Run/restart
  111. ; 1=Program flash, 2=Erase flash, 3=Read flash
  112. ; 0xFF=Set address, 0xFE=Set buffer, 0xFD=Keep alive
  113. main:mov Paral, #SUCCESS
  114. mai1:acall putc
  115. mov Crcl, #0 ; Reset CRC
  116. mov Crch, #0
  117. acall getw ; Get command
  118. mov A, Paral
  119. mov Cmdl, A
  120. mov A, Parah
  121. mov Cmdh, A
  122. clr C
  123. mov A, Cmdh
  124. subb A, #0FEh
  125. jc mai2 ; Jump if not set address or set buffer
  126. acall getw ; Address or number of bytes
  127. mov Byte_Cntl, Paral ; Store number of bytes for set buffer
  128. mov Byte_Cnth, Parah
  129. mov A, Cmdh
  130. jnb ACC.0, mai2 ; Jump if set buffer
  131. mov DPL, Paral ; Store flash address (for set address)
  132. mov DPH, Parah
  133. mai2:acall getw ; Get CRC
  134. mov Paral, #ERRORCRC
  135. jnz mai1
  136. clr C
  137. mov A, Cmdh
  138. subb A, #0FEh
  139. jz setbuf ; If command is set buffer, receive data
  140. jnc main
  141. cjne Cmdh, #0, mai4 ; Jump if command != 0 (and not set buffer)
  142. ; Run application/restart bootloader
  143. mov A, Cmdl
  144. jz rst
  145. exit:mov Bit_Access, #0 ; Clear variable used by flash lock detect
  146. mov Bit_Access_Int, #0FFh ; Set variable to indicate that program execution came from bootloader
  147. mov BL_Flash_Key_1, #0 ; Set flash keys to invalid values
  148. mov BL_Flash_Key_2, #0
  149. ljmp 0000h
  150. rst: ajmp init
  151. ; Set buffer
  152. setbuf:mov Xl, Byte_Cntl ; Set number of bytes
  153. mov Xh, Byte_Cnth
  154. inc Xl
  155. inc Xh
  156. set4:djnz Xl, set5
  157. djnz Xh, set5
  158. ajmp set6
  159. set5:acall getc ; Receive data
  160. mov A, Paral
  161. movx @Xl, A ; Store data in XRAM
  162. ajmp set4
  163. set6:inc Cmdh
  164. ajmp mai2
  165. mai4:clr C
  166. mov A, Cmdh
  167. subb A, #3
  168. jnc mai5 ; Jump if command >= 3
  169. ; Program/erase
  170. mov A, Cmdh
  171. mov C, ACC.0
  172. mov Bit_Reg.0, C
  173. mov Paral, #ERRORPROG
  174. clr C
  175. mov A, DPL
  176. subb A, #low(BOOT_START)
  177. mov A, DPH
  178. subb A, #high(BOOT_START)
  179. jnc mai1 ; Jump if in bootloader segment
  180. jb Bit_Reg.0, pro3 ; Jump if program command
  181. ; Erase flash
  182. orl PSCTL, #02h ; Set the PSEE bit
  183. orl PSCTL, #01h ; Set the PSWE bit
  184. mov FLKEY, BL_Flash_Key_1 ; First key code
  185. mov FLKEY, BL_Flash_Key_2 ; Second key code
  186. movx @DPTR, A
  187. jnb Bit_Reg.0, pro6 ; Jump if erase command
  188. ; Program flash
  189. pro3:mov Xl, Byte_Cntl ; Set number of bytes
  190. mov Xh, Byte_Cnth
  191. inc Xl
  192. inc Xh
  193. orl PSCTL, #01h ; Set the PSWE bit
  194. anl PSCTL, #0FDh ; Clear the PSEE bit
  195. pro4:djnz Xl, pro5
  196. djnz Xh, pro5
  197. ajmp pro6
  198. pro5:
  199. clr C
  200. mov A, DPH ; Check that address is not in bootloader area
  201. subb A, #1Ch
  202. jc ($+5)
  203. inc DPTR ; Increment flash address
  204. ajmp pro4
  205. movx A, @Xl ; Read from XRAM
  206. mov FLKEY, BL_Flash_Key_1 ; First key code
  207. mov FLKEY, BL_Flash_Key_2 ; Second key code
  208. movx @DPTR, A ; Write to flash
  209. inc DPTR ; Increment flash address
  210. ajmp pro4
  211. pro6:anl PSCTL, #0FCh ; Clear the PSEE and PSWE bits
  212. ajmp main ; Successfully done erase or program
  213. ; Read flash
  214. mai5:mov Paral, #ERRORCOMMAND ; Illegal command
  215. cjne Cmdh, #3, mai6 ; Jump if not read flash command
  216. rd1: clr A
  217. movc A, @A+DPTR ; Read from flash
  218. inc DPTR ; Increment flash address
  219. mov Paral, A
  220. acall putp
  221. djnz Cmdl, rd1 ; Decrement bytes to read
  222. acall putw ; CRC
  223. ajmp main
  224. mai6:ajmp mai1
  225. ; Send char with crc
  226. putw:mov Paral, Crcl
  227. mov Parah, Crch
  228. acall putc
  229. mov A, Parah
  230. mov Paral, A
  231. putp:mov A, Paral
  232. xrl Crcl, A
  233. mov Bit_Cnt, #8
  234. put1:clr C
  235. mov A, Crch
  236. rrc A
  237. mov Crch, A
  238. mov A, Crcl
  239. rrc A
  240. mov Crcl, A
  241. jnc put2
  242. xrl Crch, #high(POLYNOM)
  243. xrl Crcl, #low(POLYNOM)
  244. put2:djnz Bit_Cnt, put1
  245. ; Send char
  246. putc:acall waitf
  247. acall waitf
  248. mov Bit_Cnt, #10
  249. mov A, Paral
  250. cpl A
  251. put3:jb Bit_Reg.1, ($+5)
  252. setb RTX_PORT.RTX_PIN ; Set pin high
  253. jnb Bit_Reg.1, ($+5)
  254. clr RTX_PORT.RTX_PIN ; Set pin low
  255. acall waitf
  256. clr C
  257. rrc A
  258. jc put4
  259. clr Bit_Reg.1
  260. put4:djnz Bit_Cnt, put3
  261. ret
  262. ; Receive char/word
  263. getw:acall getc
  264. mov A, Paral
  265. mov Parah, A
  266. getc:jb RTX_PORT.RTX_PIN, ($+5) ; Wait for high
  267. ajmp getc
  268. get1:jnb RTX_PORT.RTX_PIN, ($+5) ; Wait for low
  269. ajmp get1
  270. getx:mov Bit_Cnt, #8
  271. mov Cntl, Baudl
  272. mov Cnth, Baudh
  273. clr C
  274. mov A, Cnth ; Wait half a baud
  275. rrc A
  276. mov Cnth, A
  277. mov A, Cntl
  278. rrc A
  279. mov Cntl, A
  280. acall waith
  281. get2:acall waitf ; Wait one baud
  282. clr C
  283. mov A, Paral
  284. rrc A
  285. jnb RTX_PORT.RTX_PIN, ($+5)
  286. orl A, #080h
  287. mov Paral, A
  288. jnb ACC.7, ($+6)
  289. xrl Crcl, #low(POLYNOM)
  290. clr C
  291. mov A, Crch
  292. rrc A
  293. mov Crch, A
  294. mov A, Crcl
  295. rrc A
  296. mov Crcl, A
  297. jnc get3
  298. xrl Crch, #high(POLYNOM)
  299. xrl Crcl, #low(POLYNOM)
  300. get3:djnz Bit_Cnt, get2
  301. mov A, Crcl
  302. xrl A, Crch
  303. xrl A, Crch
  304. mov Crcl, A
  305. ret
  306. ; UART delays
  307. waitf:mov Cntl, Baudl
  308. mov Cnth, Baudh
  309. waith:inc Cntl
  310. inc Cnth
  311. wait1:djnz Cntl, wait1
  312. djnz Cnth, wait1
  313. setb Bit_Reg.1
  314. ret
  315. BOOT_SIGN: DB "BLHeli"
  316. BOOT_MSG: DB "471d" ; Interface-MCU_BootlaoderRevision
  317. BOOT_INFO: DB SIGNATURE_001, SIGNATURE_002, BOOT_VERSION, BOOT_PAGES