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.

670 lines
15 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. ;**** **** **** **** ****
  2. ;
  3. ; BLHeli program for controlling brushless motors in helicopters and multirotors
  4. ;
  5. ; Copyright 2011, 2012 Steffen Skaug
  6. ; This program is distributed under the terms of the GNU General Public License
  7. ;
  8. ; This file is part of BLHeli.
  9. ;
  10. ; BLHeli is free software: you can redistribute it and/or modify
  11. ; it under the terms of the GNU General Public License as published by
  12. ; the Free Software Foundation, either version 3 of the License, or
  13. ; (at your option) any later version.
  14. ;
  15. ; BLHeli is distributed in the hope that it will be useful,
  16. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ; GNU General Public License for more details.
  19. ;
  20. ; You should have received a copy of the GNU General Public License
  21. ; along with BLHeli. If not, see <http://www.gnu.org/licenses/>.
  22. ;
  23. ;**** **** **** **** ****
  24. ;
  25. ; BLHeliTxPgm SiLabs
  26. ;
  27. ; EEPROM is not available in SiLabs MCUs
  28. ; Therefore a segment of the flash is used as "EEPROM"
  29. ;
  30. ;**** **** **** **** ****
  31. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  32. ;
  33. ; Read all eeprom parameters routine
  34. ;
  35. ; No assumptions
  36. ;
  37. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  38. read_all_eeprom_parameters:
  39. ; Check initialized signature
  40. mov DPTR, #Eep_Initialized_L
  41. mov Temp1, #Bit_Access
  42. call read_eeprom_byte
  43. mov A, Bit_Access
  44. IF MODE == 0
  45. cjne A, #0A5h, read_eeprom_store_defaults
  46. ENDIF
  47. IF MODE == 1
  48. cjne A, #05Ah, read_eeprom_store_defaults
  49. ENDIF
  50. IF MODE == 2
  51. cjne A, #055h, read_eeprom_store_defaults
  52. ENDIF
  53. inc DPTR ; Now Eep_Initialized_H
  54. call read_eeprom_byte
  55. mov A, Bit_Access
  56. IF MODE == 0
  57. cjne A, #05Ah, read_eeprom_store_defaults
  58. ENDIF
  59. IF MODE == 1
  60. cjne A, #0A5h, read_eeprom_store_defaults
  61. ENDIF
  62. IF MODE == 2
  63. cjne A, #0AAh, read_eeprom_store_defaults
  64. ENDIF
  65. jmp read_eeprom_read
  66. read_eeprom_store_defaults:
  67. mov Flash_Key_1, #0A5h
  68. mov Flash_Key_2, #0F1h
  69. call set_default_parameters
  70. call erase_and_store_all_in_eeprom
  71. mov Flash_Key_1, #0
  72. mov Flash_Key_2, #0
  73. jmp read_eeprom_exit
  74. read_eeprom_read:
  75. ; Read eeprom
  76. IF MODE == 0 OR MODE == 2 ;Main or multi
  77. mov DPTR, #Eep_Pgm_Gov_P_Gain
  78. ENDIF
  79. IF MODE == 1 ; Tail
  80. mov DPTR, #_Eep_Pgm_Gov_P_Gain
  81. ENDIF
  82. mov Temp1, #Pgm_Gov_P_Gain
  83. mov Temp4, #10
  84. read_eeprom_block1:
  85. call read_eeprom_byte
  86. inc DPTR
  87. inc Temp1
  88. djnz Temp4, read_eeprom_block1
  89. mov DPTR, #Eep_Enable_TX_Program
  90. mov Temp1, #Pgm_Enable_TX_Program
  91. mov Temp4, #25 ; 25 parameters
  92. read_eeprom_block2:
  93. call read_eeprom_byte
  94. inc DPTR
  95. inc Temp1
  96. djnz Temp4, read_eeprom_block2
  97. mov DPTR, #Eep_Dummy ; Set pointer to uncritical area
  98. read_eeprom_exit:
  99. ret
  100. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  101. ;
  102. ; Erase flash and store all parameter value in EEPROM routine
  103. ;
  104. ; No assumptions
  105. ;
  106. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  107. erase_and_store_all_in_eeprom:
  108. clr EA ; Disable interrupts
  109. call read_tags
  110. call erase_flash ; Erase flash
  111. mov DPTR, #Eep_FW_Main_Revision ; Store firmware main revision
  112. mov A, #EEPROM_FW_MAIN_REVISION
  113. call write_eeprom_byte_from_acc
  114. inc DPTR ; Now firmware sub revision
  115. mov A, #EEPROM_FW_SUB_REVISION
  116. call write_eeprom_byte_from_acc
  117. inc DPTR ; Now layout revision
  118. mov A, #EEPROM_LAYOUT_REVISION
  119. call write_eeprom_byte_from_acc
  120. ; Write eeprom
  121. IF MODE == 0 OR MODE == 2 ;Main or multi
  122. mov DPTR, #Eep_Pgm_Gov_P_Gain
  123. ENDIF
  124. IF MODE == 1 ; Tail
  125. mov DPTR, #_Eep_Pgm_Gov_P_Gain
  126. ENDIF
  127. mov Temp1, #Pgm_Gov_P_Gain
  128. mov Temp4, #10
  129. write_eeprom_block1:
  130. call write_eeprom_byte
  131. inc DPTR
  132. inc Temp1
  133. djnz Temp4, write_eeprom_block1
  134. mov DPTR, #Eep_Enable_TX_Program
  135. mov Temp1, #Pgm_Enable_TX_Program
  136. mov Temp4, #25 ; 25 parameters
  137. write_eeprom_block2:
  138. call write_eeprom_byte
  139. inc DPTR
  140. inc Temp1
  141. djnz Temp4, write_eeprom_block2
  142. call write_tags
  143. call write_eeprom_signature
  144. mov DPTR, #Eep_Dummy ; Set pointer to uncritical area
  145. ret
  146. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  147. ;
  148. ; Read eeprom byte routine
  149. ;
  150. ; Gives data in A and in address given by Temp1. Assumes address in DPTR
  151. ; Also assumes address high byte to be zero
  152. ;
  153. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  154. read_eeprom_byte:
  155. clr A
  156. movc A, @A+DPTR ; Read from flash
  157. mov @Temp1, A
  158. ret
  159. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  160. ;
  161. ; Write eeprom byte routine
  162. ;
  163. ; Assumes data in address given by Temp1, or in accumulator. Assumes address in DPTR
  164. ; Also assumes address high byte to be zero
  165. ;
  166. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  167. write_eeprom_byte:
  168. mov A, @Temp1
  169. write_eeprom_byte_from_acc:
  170. orl PSCTL, #01h ; Set the PSWE bit
  171. anl PSCTL, #0FDh ; Clear the PSEE bit
  172. mov Temp8, A
  173. clr C
  174. mov A, DPH ; Check that address is not in bootloader area
  175. subb A, #1Ch
  176. jc ($+3)
  177. ret
  178. mov A, Temp8
  179. mov FLKEY, Flash_Key_1 ; First key code
  180. mov FLKEY, Flash_Key_2 ; Second key code
  181. movx @DPTR, A ; Write to flash
  182. anl PSCTL, #0FEh ; Clear the PSWE bit
  183. ret
  184. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  185. ;
  186. ; Erase flash routine (erases the flash segment used for "eeprom" variables)
  187. ;
  188. ; No assumptions
  189. ;
  190. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  191. erase_flash:
  192. orl PSCTL, #02h ; Set the PSEE bit
  193. orl PSCTL, #01h ; Set the PSWE bit
  194. mov FLKEY, Flash_Key_1 ; First key code
  195. mov FLKEY, Flash_Key_2 ; Second key code
  196. mov DPTR, #Eep_Initialized_L
  197. movx @DPTR, A
  198. anl PSCTL, #0FCh ; Clear the PSEE and PSWE bits
  199. ret
  200. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  201. ;
  202. ; Write eeprom signature routine
  203. ;
  204. ; No assumptions
  205. ;
  206. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  207. write_eeprom_signature:
  208. IF MODE == 0
  209. mov DPTR, #Eep_Initialized_L
  210. mov A, #0A5h
  211. call write_eeprom_byte_from_acc
  212. mov DPTR, #Eep_Initialized_H
  213. mov A, #05Ah
  214. call write_eeprom_byte_from_acc
  215. ENDIF
  216. IF MODE == 1
  217. mov DPTR, #Eep_Initialized_L
  218. mov A, #05Ah
  219. call write_eeprom_byte_from_acc
  220. mov DPTR, #Eep_Initialized_H
  221. mov A, #0A5h
  222. call write_eeprom_byte_from_acc
  223. ENDIF
  224. IF MODE == 2
  225. mov DPTR, #Eep_Initialized_L
  226. mov A, #055h
  227. call write_eeprom_byte_from_acc
  228. mov DPTR, #Eep_Initialized_H
  229. mov A, #0AAh
  230. call write_eeprom_byte_from_acc
  231. ENDIF
  232. ret
  233. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  234. ;
  235. ; Read all tags from flash and store in temporary storage
  236. ;
  237. ; No assumptions
  238. ;
  239. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  240. read_tags:
  241. mov Temp3, #48 ; Number of tags
  242. mov Temp2, #Tag_Temporary_Storage ; Set RAM address
  243. mov Temp1, #Bit_Access
  244. mov DPTR, #Eep_ESC_Layout ; Set flash address
  245. read_tag:
  246. call read_eeprom_byte
  247. mov A, Bit_Access
  248. mov @Temp2, A ; Write to RAM
  249. inc Temp2
  250. inc DPTR
  251. djnz Temp3, read_tag
  252. ret
  253. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  254. ;
  255. ; Write all tags from temporary storage and store in flash
  256. ;
  257. ; No assumptions
  258. ;
  259. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  260. write_tags:
  261. mov Temp3, #48 ; Number of tags
  262. mov Temp2, #Tag_Temporary_Storage ; Set RAM address
  263. mov DPTR, #Eep_ESC_Layout ; Set flash address
  264. write_tag:
  265. mov A, @Temp2 ; Read from RAM
  266. call write_eeprom_byte_from_acc
  267. inc Temp2
  268. inc DPTR
  269. djnz Temp3, write_tag
  270. ret
  271. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  272. ;
  273. ; Store new parameter value in ram routine
  274. ;
  275. ; No assumptions
  276. ;
  277. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  278. store_new_value_in_ram:
  279. mov Temp4, Tx_Pgm_Func_No ; Function no
  280. mov Temp1, Tx_Pgm_Paraval_No ; Parameter value no
  281. IF MODE == 0
  282. store_main_func_1:
  283. cjne Temp4, #1, store_main_func_2
  284. mov Temp2, #Pgm_Gov_P_Gain
  285. store_main_func_2:
  286. cjne Temp4, #2, store_main_func_3
  287. mov Temp2, #Pgm_Gov_I_Gain
  288. store_main_func_3:
  289. cjne Temp4, #3, store_main_func_4
  290. mov Temp2, #Pgm_Gov_Mode
  291. store_main_func_4:
  292. cjne Temp4, #4, store_main_func_5
  293. mov Temp2, #Pgm_Gov_Range
  294. store_main_func_5:
  295. cjne Temp4, #5, store_main_func_6
  296. mov Temp2, #Pgm_Low_Voltage_Lim
  297. store_main_func_6:
  298. cjne Temp4, #6, store_main_func_7
  299. mov Temp2, #Pgm_Startup_Pwr
  300. store_main_func_7:
  301. cjne Temp4, #7, store_main_func_8
  302. mov Temp2, #Pgm_Comm_Timing
  303. store_main_func_8:
  304. cjne Temp4, #8, store_main_func_9
  305. mov Temp2, #Pgm_Pwm_Freq
  306. store_main_func_9:
  307. cjne Temp4, #9, store_main_func_10
  308. mov Temp2, #Pgm_Demag_Comp
  309. store_main_func_10:
  310. cjne Temp4, #10, store_main_func_11
  311. mov Temp2, #Pgm_Direction
  312. store_main_func_11:
  313. cjne Temp4, #11, store_in_ram_exit
  314. mov Temp2, #Pgm_Input_Pol
  315. ENDIF
  316. IF MODE == 1
  317. store_tail_func_1:
  318. cjne Temp4, #1, store_tail_func_2
  319. mov Temp2, #Pgm_Motor_Gain
  320. store_tail_func_2:
  321. cjne Temp4, #2, store_tail_func_3
  322. mov Temp2, #Pgm_Motor_Idle
  323. store_tail_func_3:
  324. cjne Temp4, #3, store_tail_func_4
  325. mov Temp2, #Pgm_Startup_Pwr
  326. store_tail_func_4:
  327. cjne Temp4, #4, store_tail_func_5
  328. mov Temp2, #Pgm_Comm_Timing
  329. store_tail_func_5:
  330. cjne Temp4, #5, store_tail_func_6
  331. mov Temp2, #Pgm_Pwm_Freq
  332. store_tail_func_6:
  333. cjne Temp4, #6, store_tail_func_7
  334. mov Temp2, #Pgm_Pwm_Dither
  335. store_tail_func_7:
  336. cjne Temp4, #7, store_tail_func_8
  337. mov Temp2, #Pgm_Demag_Comp
  338. store_tail_func_8:
  339. cjne Temp4, #8, store_tail_func_9
  340. mov Temp2, #Pgm_Direction
  341. store_tail_func_9:
  342. cjne Temp4, #9, store_in_ram_exit
  343. mov Temp2, #Pgm_Input_Pol
  344. ENDIF
  345. IF MODE == 2
  346. store_multi_func_1:
  347. cjne Temp4, #1, store_multi_func_2
  348. mov Temp2, #Pgm_Gov_P_Gain
  349. store_multi_func_2:
  350. cjne Temp4, #2, store_multi_func_3
  351. mov Temp2, #Pgm_Gov_I_Gain
  352. store_multi_func_3:
  353. cjne Temp4, #3, store_multi_func_4
  354. mov Temp2, #Pgm_Gov_Mode
  355. store_multi_func_4:
  356. cjne Temp4, #4, store_multi_func_5
  357. mov Temp2, #Pgm_Motor_Gain
  358. store_multi_func_5:
  359. cjne Temp4, #5, store_multi_func_6
  360. mov Temp2, #Pgm_Startup_Pwr
  361. store_multi_func_6:
  362. cjne Temp4, #6, store_multi_func_7
  363. mov Temp2, #Pgm_Comm_Timing
  364. store_multi_func_7:
  365. cjne Temp4, #7, store_multi_func_8
  366. mov Temp2, #Pgm_Pwm_Freq
  367. store_multi_func_8:
  368. cjne Temp4, #8, store_multi_func_9
  369. mov Temp2, #Pgm_Pwm_Dither
  370. store_multi_func_9:
  371. cjne Temp4, #9, store_multi_func_10
  372. mov Temp2, #Pgm_Demag_Comp
  373. store_multi_func_10:
  374. cjne Temp4, #10, store_multi_func_11
  375. mov Temp2, #Pgm_Direction
  376. store_multi_func_11:
  377. cjne Temp4, #11, store_in_ram_exit
  378. mov Temp2, #Pgm_Input_Pol
  379. ENDIF
  380. store_in_ram_exit:
  381. mov A, Temp1
  382. mov @Temp2, A
  383. ret
  384. ;**;**** **** **** **** **** **** **** **** **** **** **** **** ****
  385. ;
  386. ; Wait 1 second routine
  387. ;
  388. ; No assumptions
  389. ;
  390. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  391. wait1s:
  392. mov Temp5, #5
  393. wait1s_loop:
  394. call wait200ms
  395. djnz Temp5, wait1s_loop
  396. ret
  397. ;**;**** **** **** **** **** **** **** **** **** **** **** **** ****
  398. ;
  399. ; Success beep routine
  400. ;
  401. ; No assumptions
  402. ;
  403. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  404. success_beep:
  405. clr EA ; Disable all interrupts
  406. call beep_f1
  407. call beep_f2
  408. call beep_f3
  409. call beep_f4
  410. call wait10ms
  411. call beep_f1
  412. call beep_f2
  413. call beep_f3
  414. call beep_f4
  415. call wait10ms
  416. call beep_f1
  417. call beep_f2
  418. call beep_f3
  419. call beep_f4
  420. setb EA ; Enable all interrupts
  421. ret
  422. ;**;**** **** **** **** **** **** **** **** **** **** **** **** ****
  423. ;
  424. ; Success beep inverted routine
  425. ;
  426. ; No assumptions
  427. ;
  428. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  429. success_beep_inverted:
  430. clr EA ; Disable all interrupts
  431. call beep_f4
  432. call beep_f3
  433. call beep_f2
  434. call beep_f1
  435. call wait10ms
  436. call beep_f4
  437. call beep_f3
  438. call beep_f2
  439. call beep_f1
  440. call wait10ms
  441. call beep_f4
  442. call beep_f3
  443. call beep_f2
  444. call beep_f1
  445. setb EA ; Enable all interrupts
  446. ret
  447. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  448. ;
  449. ; Function and parameter value beep routine
  450. ;
  451. ; No assumptions
  452. ;
  453. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  454. function_paraval_beep:
  455. mov Temp7, Tx_Pgm_Func_No ; Function no
  456. mov Temp8, Tx_Pgm_Paraval_No ; Parameter value no
  457. clr EA ; Disable all interrupts
  458. function_beep:
  459. call beep_f1
  460. call beep_f1
  461. call beep_f1
  462. call wait10ms
  463. djnz Temp7, function_beep
  464. paraval_beep:
  465. call beep_f4
  466. call wait10ms
  467. djnz Temp8, paraval_beep
  468. setb EA ; Enable all interrupts
  469. ret
  470. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  471. ;
  472. ; Program by TX routine
  473. ;
  474. ; No assumptions
  475. ;
  476. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  477. program_by_tx:
  478. ; Programming mode entry beeps
  479. call success_beep
  480. call wait1s
  481. call wait1s
  482. ; Start at function 1, parameter value 1
  483. mov Tx_Pgm_Func_No, #1
  484. paraval_no_entry:
  485. mov Tx_Pgm_Paraval_No, #1
  486. beep_no_entry:
  487. mov Tx_Pgm_Beep_No, #0
  488. func_paraval:
  489. call function_paraval_beep
  490. mov Temp5, #5 ; Wait is 5x 200ms
  491. func_paraval_wait:
  492. mov Temp6, New_Rcp ; Load RC pulse
  493. call wait200ms
  494. clr C
  495. mov A, Temp6
  496. subb A, New_Rcp ; Is RC pulse stable? (Avoid issues from 3in1 interference)
  497. jnz func_paraval_wait ; No - branch
  498. clr C
  499. mov A, New_Rcp ; Load new RC pulse value
  500. subb A, #RCP_STOP ; Below stop?
  501. jc func_paraval_store ; Yes - branch
  502. clr C
  503. mov A, New_Rcp ; Load new RC pulse value
  504. subb A, #RCP_MAX ; Below max?
  505. jc function_next ; Yes - branch
  506. ljmp func_paraval_cont_wait ; No - branch
  507. func_paraval_store:
  508. call store_new_value_in_ram ; Yes - store new value in RAM
  509. call erase_and_store_all_in_eeprom ; Store all values in EEPROM
  510. call success_beep ; Beep success
  511. clr EA ; Disable all interrupts
  512. IF ONE_S_CAPABLE == 0
  513. mov RSTSRC, #16h ; Generate hardware reset and set missing clock and VDD monitor
  514. ELSE
  515. mov RSTSRC, #14h ; Generate hardware reset and disable VDD monitor
  516. ENDIF
  517. call wait1s
  518. func_paraval_cont_wait:
  519. djnz Temp5, func_paraval_wait
  520. inc Tx_Pgm_Beep_No ; Check number of beeps
  521. clr C
  522. mov A, Tx_Pgm_Beep_No
  523. subb A, #3 ; Three beeps done?
  524. jnc paraval_next ; Yes - Next parameter value
  525. jmp func_paraval ; No - go back
  526. paraval_next:
  527. call wait1s
  528. inc Tx_Pgm_Paraval_No ; Parameter value no
  529. IF MODE == 0
  530. mov A, Tx_Pgm_Func_No ; Decode number of parameters
  531. dec A
  532. mov DPTR, #TX_PGM_PARAMS_MAIN
  533. movc A, @A+DPTR
  534. mov Temp1, A
  535. ENDIF
  536. IF MODE == 1
  537. mov A, Tx_Pgm_Func_No ; Decode number of parameters
  538. dec A
  539. mov DPTR, #TX_PGM_PARAMS_TAIL
  540. movc A, @A+DPTR
  541. mov Temp1, A
  542. ENDIF
  543. IF MODE == 2
  544. mov A, Tx_Pgm_Func_No ; Decode number of parameters
  545. dec A
  546. mov DPTR, #TX_PGM_PARAMS_MULTI
  547. movc A, @A+DPTR
  548. mov Temp1, A
  549. ENDIF
  550. inc Temp1
  551. clr C
  552. mov A, Tx_Pgm_Paraval_No
  553. subb A, Temp1
  554. jnc function_next ; Last parameter value?
  555. jmp beep_no_entry ; No - go back
  556. function_next: ; Yes - Next function value
  557. call wait1s
  558. call wait1s
  559. inc Tx_Pgm_Func_No ; Function value no
  560. IF MODE == 0
  561. clr C
  562. mov A, Tx_Pgm_Func_No
  563. subb A, #12 ; Main has 11 functions
  564. ENDIF
  565. IF MODE == 1
  566. clr C
  567. mov A, Tx_Pgm_Func_No
  568. subb A, #10 ; Tail has 9 functions
  569. ENDIF
  570. IF MODE == 2
  571. clr C
  572. mov A, Tx_Pgm_Func_No
  573. subb A, #12 ; Multi has 11 functions
  574. ENDIF
  575. jnc program_by_tx_exit ; Last function value?
  576. jmp paraval_no_entry ; No - go back
  577. program_by_tx_exit:
  578. call set_default_parameters ; Load all defaults
  579. call erase_and_store_all_in_eeprom ; Erase flash and program
  580. clr EA ; Disable all interrupts
  581. IF ONE_S_CAPABLE == 0
  582. mov RSTSRC, #16h ; Generate hardware reset and set missing clock and VDD monitor
  583. ELSE
  584. mov RSTSRC, #14h ; Generate hardware reset and disable VDD monitor
  585. ENDIF
  586. call wait1s