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.

466 lines
11 KiB

11 years ago
11 years ago
11 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. ; Afro 12A hardware definition file
  26. ;
  27. ; Notes:
  28. ; - Uses ICP1 as input
  29. ; - High side is slow to go on (10s of us) but fast to go off
  30. ;
  31. ;**** **** **** **** ****
  32. ;*********************
  33. ; Device Atmega8A
  34. ;*********************
  35. .INCLUDE "m8Adef.inc"
  36. ;**** **** **** **** ****
  37. ; Fuses must be set to external oscillator = 16Mhz
  38. ;**** **** **** **** ****
  39. ;**** **** **** **** ****
  40. ; Constant definitions
  41. ;**** **** **** **** ****
  42. .ESEG ; EEprom segment
  43. .ORG 0x40
  44. Eep_ESC_Layout: .DB "#AFRO_12A# " ; ESC layout tag
  45. .ORG 0x50
  46. Eep_ESC_MCU: .DB "#BLHELI#Am8A# " ; Project and MCU tag (16 Bytes)
  47. .EQU CLK_8M = 0 ; Set to 0 for 16MHz clock, and 1 if 8MHz clock
  48. .EQU HIGH_BEC_VOLTAGE = 0 ; Set to 1 or more if high BEC voltage is supported
  49. .EQU DAMPED_MODE_ENABLE = 1 ; Set to 1 if fully damped mode is supported
  50. .EQU NFETON_DELAY = 5 ; Wait delay from pfets off to nfets on
  51. .EQU PFETON_DELAY = 5 ; Wait delay from nfets off to pfets on
  52. .EQU COMP_PWM_HIGH_ON_DELAY = 10 ; Wait delay from pwm on until comparator can be read (for high pwm frequency)
  53. .EQU COMP_PWM_HIGH_OFF_DELAY = 20 ; Wait delay from pwm off until comparator can be read (for high pwm frequency)
  54. .EQU COMP_PWM_LOW_ON_DELAY = 10 ; Wait delay from pwm on until comparator can be read (for low pwm frequency)
  55. .EQU COMP_PWM_LOW_OFF_DELAY = 20 ; Wait delay from pwm off until comparator can be read (for low pwm frequency)
  56. .EQU HIGH_DRIVER_PRECHG_TIME = 6 ; Time between commutations use to precharge the high side driver (for all nfet ESCs)
  57. .EQU ADC_LIMIT_L = 186 ; 3k3/18k divider. Power supply measurement ADC value for which motor power is limited (low byte)
  58. .EQU ADC_LIMIT_H = 0 ; 3k3/18k divider. Power supply measurement ADC value for which motor power is limited (2 MSBs)
  59. .EQU TEMP_LIMIT = 185 ; 3k3/10kNTC. Temperature measurement ADC value for which main motor power is limited
  60. .EQU TEMP_LIMIT_STEP = 15 ; 3k3/10kNTC. Temperature measurement ADC value increment for which main motor power is further limited
  61. ;**** **** **** **** ****
  62. ; ESC specific defaults
  63. ;**** **** **** **** ****
  64. .EQU DEFAULT_PGM_MAIN_SPOOLUP_TIME = 7 ; Main motor spoolup time
  65. .EQU DEFAULT_PGM_MAIN_STARTUP_PWR = 11 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50
  66. .EQU DEFAULT_PGM_TAIL_STARTUP_PWR = 11 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50
  67. .EQU DEFAULT_PGM_MULTI_STARTUP_PWR = 11 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50
  68. ;*********************
  69. ; PORT D definitions *
  70. ;*********************
  71. ;.EQU = 7 ;i
  72. ;.EQU = 6 ;i
  73. .EQU CnFET = 5 ;o
  74. .EQU BnFET = 4 ;o
  75. .EQU AnFET = 3 ;o
  76. .EQU ApFET = 2 ;o
  77. ;.EQU = 1 ;i
  78. ;.EQU = 0 ;i
  79. .equ INIT_PD = (1<<ApFET)
  80. .equ DIR_PD = (1<<AnFET)+(1<<BnFET)+(1<<CnFET)+(1<<ApFET)
  81. .MACRO Get_Rcp_Capture_Values
  82. in @0, ICR1L
  83. in @1, ICR1H
  84. .ENDMACRO
  85. .MACRO Read_Rcp_Int
  86. in @0, PINB
  87. sbrc Flags3, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  88. com @0 ; Yes - invert
  89. .ENDMACRO
  90. .MACRO Get_Rcp_Int_Enable_State
  91. in @0, TIMSK ; Get icp1int enable state (giving 0 is off, anything else is on)
  92. andi @0, (1<<TICIE1)
  93. .ENDMACRO
  94. .MACRO Rcp_Int_Enable
  95. in @0, TIMSK
  96. sbr @0, (1<<TICIE1) ; Enable icp1int
  97. out TIMSK, @0
  98. .ENDMACRO
  99. .MACRO Rcp_Int_Disable
  100. in @0, TIMSK
  101. cbr @0, (1<<TICIE1) ; Disable icp1int
  102. out TIMSK, @0
  103. .ENDMACRO
  104. .MACRO Rcp_Int_First
  105. in @0, TCCR1B
  106. sbrs Flags3, PGM_RCP_PWM_POL ; Is pwm polarity positive?
  107. sbr @0, (1<<ICES1) ; Yes - set icp1int to trig on rising edge
  108. sbrc Flags3, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  109. cbr @0, (1<<ICES1) ; Yes - set icp1int to trig on falling edge
  110. out TCCR1B, @0
  111. .ENDMACRO
  112. .MACRO Rcp_Int_Second
  113. in @0, TCCR1B
  114. sbrs Flags3, PGM_RCP_PWM_POL ; Is pwm polarity positive?
  115. cbr @0, (1<<ICES1) ; Yes - set icp1int to trig on falling edge
  116. sbrc Flags3, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  117. sbr @0, (1<<ICES1) ; Yes - set icp1int to trig on rising edge
  118. out TCCR1B, @0
  119. .ENDMACRO
  120. .MACRO Rcp_Clear_Int_Flag
  121. clr @0
  122. sbr @0, (1<<ICF1) ; Clear icp1int flag
  123. out TIFR, @0
  124. .ENDMACRO
  125. .MACRO T0_Int_Disable
  126. in @0, TIMSK ; Disable timer0 interrupts
  127. cbr @0, (1<<TOIE0)
  128. out TIMSK, @0
  129. .ENDMACRO
  130. .MACRO T0_Int_Enable
  131. in @0, TIMSK ; Enable timer0 interrupts
  132. sbr @0, (1<<TOIE0)
  133. out TIMSK, @0
  134. .ENDMACRO
  135. .MACRO T1oca_Clear_Int_Flag
  136. ldi @0, (1<<OCF1A) ; Clear oc1a flag
  137. out TIFR, @0
  138. .ENDMACRO
  139. ;*********************
  140. ; PORT C definitions *
  141. ;*********************
  142. .EQU Volt_Ip = 7 ; i
  143. .EQU Temp_Ip = 6 ; i
  144. ;.EQU = 5 ; i
  145. ;.EQU = 4 ; i
  146. ;.EQU = 3 ; i
  147. ;.EQU = 2 ; i
  148. .EQU Mux_B = 1 ; i
  149. .EQU Mux_A = 0 ; i
  150. .equ INIT_PC = 0x00
  151. .equ DIR_PC = 0x00
  152. .MACRO AnFET_on
  153. tst Current_Pwm_Limited
  154. breq PC+5
  155. sbrs Flags3, PGM_DIR_REV
  156. sbi PORTD, AnFET
  157. sbrc Flags3, PGM_DIR_REV
  158. sbi PORTD, CnFET
  159. .ENDMACRO
  160. .MACRO AnFET_off
  161. sbrs Flags3, PGM_DIR_REV
  162. cbi PORTD, AnFET
  163. sbrc Flags3, PGM_DIR_REV
  164. cbi PORTD, CnFET
  165. .ENDMACRO
  166. .MACRO BnFET_on
  167. tst Current_Pwm_Limited
  168. breq PC+2
  169. sbi PORTD, BnFET
  170. .ENDMACRO
  171. .MACRO BnFET_off
  172. cbi PORTD, BnFET
  173. .ENDMACRO
  174. .MACRO CnFET_on
  175. tst Current_Pwm_Limited
  176. breq PC+5
  177. sbrs Flags3, PGM_DIR_REV
  178. sbi PORTD, CnFET
  179. sbrc Flags3, PGM_DIR_REV
  180. sbi PORTD, AnFET
  181. .ENDMACRO
  182. .MACRO CnFET_off
  183. sbrs Flags3, PGM_DIR_REV
  184. cbi PORTD, CnFET
  185. sbrc Flags3, PGM_DIR_REV
  186. cbi PORTD, AnFET
  187. .ENDMACRO
  188. .MACRO All_nFETs_Off
  189. cbi PORTD, AnFET
  190. cbi PORTD, BnFET
  191. cbi PORTD, CnFET
  192. .ENDMACRO
  193. .MACRO ApFET_on
  194. sbrs Flags3, PGM_DIR_REV
  195. cbi PORTD, ApFET
  196. sbrc Flags3, PGM_DIR_REV
  197. cbi PORTB, CpFET
  198. .ENDMACRO
  199. .MACRO ApFET_off
  200. sbrs Flags3, PGM_DIR_REV
  201. sbi PORTD, ApFET
  202. sbrc Flags3, PGM_DIR_REV
  203. sbi PORTB, CpFET
  204. .ENDMACRO
  205. .MACRO BpFET_on
  206. cbi PORTB, BpFET
  207. .ENDMACRO
  208. .MACRO BpFET_off
  209. sbi PORTB, BpFET
  210. .ENDMACRO
  211. .MACRO CpFET_on
  212. sbrs Flags3, PGM_DIR_REV
  213. cbi PORTB, CpFET
  214. sbrc Flags3, PGM_DIR_REV
  215. cbi PORTD, ApFET
  216. .ENDMACRO
  217. .MACRO CpFET_off
  218. sbrs Flags3, PGM_DIR_REV
  219. sbi PORTB, CpFET
  220. sbrc Flags3, PGM_DIR_REV
  221. sbi PORTD, ApFET
  222. .ENDMACRO
  223. .MACRO All_pFETs_On
  224. cbi PORTD, ApFET
  225. cbi PORTB, BpFET
  226. cbi PORTB, CpFET
  227. .ENDMACRO
  228. .MACRO All_pFETs_Off
  229. sbi PORTD, ApFET
  230. sbi PORTB, BpFET
  231. sbi PORTB, CpFET
  232. .ENDMACRO
  233. .MACRO Comp_Init
  234. in @0, SFIOR ; Set Analog Comparator Multiplexer Enable
  235. sbr @0, (1<<ACME)
  236. out SFIOR, @0
  237. .ENDMACRO
  238. .MACRO Set_Comp_Phase_A
  239. sbrs Flags3, PGM_DIR_REV
  240. rjmp set_comp_phase_muxa
  241. in @0, SFIOR ; Set Analog Comparator Multiplexer Disable
  242. cbr @0, (1<<ACME)
  243. out SFIOR, @0
  244. rjmp set_comp_phase_a_exit
  245. set_comp_phase_muxa:
  246. in @0, SFIOR ; Set Analog Comparator Multiplexer Enable
  247. sbr @0, (1<<ACME)
  248. out SFIOR, @0
  249. ldi @0, Mux_A ; Set comparator multiplexer to phase A
  250. sbr @0, (1<<REFS1)
  251. sbr @0, (1<<REFS0)
  252. out ADMUX, @0
  253. set_comp_phase_a_exit:
  254. .ENDMACRO
  255. .MACRO Set_Comp_Phase_B
  256. in @0, SFIOR ; Set Analog Comparator Multiplexer Enable
  257. sbr @0, (1<<ACME)
  258. out SFIOR, @0
  259. ldi @0, Mux_B ; Set comparator multiplexer to phase B
  260. sbr @0, (1<<REFS1)
  261. sbr @0, (1<<REFS0)
  262. out ADMUX, @0
  263. .ENDMACRO
  264. .MACRO Set_Comp_Phase_C
  265. sbrs Flags3, PGM_DIR_REV
  266. rjmp set_comp_phase_c_ain1
  267. in @0, SFIOR ; Set Analog Comparator Multiplexer Enable
  268. sbr @0, (1<<ACME)
  269. out SFIOR, @0
  270. ldi @0, Mux_A ; Set comparator multiplexer to phase A
  271. sbr @0, (1<<REFS1)
  272. sbr @0, (1<<REFS0)
  273. out ADMUX, @0
  274. rjmp set_comp_phase_c_exit
  275. set_comp_phase_c_ain1:
  276. in @0, SFIOR ; Set Analog Comparator Multiplexer Disable
  277. cbr @0, (1<<ACME)
  278. out SFIOR, @0
  279. set_comp_phase_c_exit:
  280. .ENDMACRO
  281. .MACRO Read_Comp_Out
  282. in @0, ACSR ; Read comparator output
  283. .ENDMACRO
  284. ;*********************
  285. ; PORT B definitions *
  286. ;*********************
  287. ;.EQU = 7 ; i
  288. ;.EQU = 6 ; i
  289. ;.EQU = 5 ; i
  290. .EQU DebugPin = 4 ; o
  291. ;.EQU = 3 ; i
  292. .EQU BpFET = 2 ; o
  293. .EQU CpFET = 1 ; o
  294. .EQU Rcp_In = 0 ; i
  295. .EQU INIT_PB = (1<<BpFET)+(1<<CpFET)
  296. .EQU DIR_PB = (1<<BpFET)+(1<<CpFET)+(1<<DebugPin)
  297. ;**********************
  298. ; MCU specific macros *
  299. ;**********************
  300. .MACRO Interrupt_Table_Definition
  301. rjmp reset
  302. nop ; ext_int0
  303. nop ; ext_int1
  304. nop ; t2oc_int
  305. rjmp t2_int ; t2ovfl_int
  306. rjmp rcp_int ; icp1_int
  307. rjmp t1oca_int ; t1oca_int
  308. nop ; t1ocb_int
  309. nop ; t1ovfl_int
  310. rjmp t0_int ; t0ovfl_int
  311. nop ; spi_int
  312. nop ; urxc
  313. nop ; udre
  314. nop ; utxc
  315. ; nop ; adc_int
  316. ; nop ; eep_int
  317. ; nop ; aci_int
  318. ; nop ; wire2_int
  319. ; nop ; spmc_int
  320. .ENDMACRO
  321. .MACRO Disable_Watchdog
  322. cli ; Disable interrupts
  323. wdr ; Reset watchdog timer
  324. in @0, WDTCR ; Write logical one to WDCE and WDE
  325. ori @0, (1<<WDCE)|(1<<WDE)
  326. out WDTCR, @0
  327. ldi @0, (0<<WDE) ; Turn off WDT
  328. out WDTCR, @0
  329. .ENDMACRO
  330. .MACRO Enable_Watchdog
  331. ldi @0, (1<<WDE) ; Turn on WDT
  332. out WDTCR, @0
  333. .ENDMACRO
  334. .MACRO Initialize_MCU
  335. .ENDMACRO
  336. .MACRO Initialize_Interrupts
  337. ldi @0, (1<<TOIE0)+(1<<OCIE1A)+(1<<TOIE2)
  338. out TIFR, @0 ; Clear interrupts
  339. out TIMSK, @0 ; Enable interrupts
  340. .ENDMACRO
  341. .MACRO Initialize_Adc
  342. in @0, ADCSRA ; Set ADCSRA register (1MHz clock)
  343. sbr @0, (1<<ADPS2)
  344. out ADCSRA, @0
  345. .ENDMACRO
  346. .MACRO Set_Adc_Ip_Volt
  347. cbr Flags1, (1<<ADC_READ_TEMP)
  348. .ENDMACRO
  349. .MACRO Set_Adc_Ip_Temp
  350. sbr Flags1, (1<<ADC_READ_TEMP)
  351. .ENDMACRO
  352. .MACRO Start_Adc
  353. sbrs Flags1, ADC_READ_TEMP
  354. ldi @0, Volt_Ip
  355. sbrc Flags1, ADC_READ_TEMP
  356. ldi @0, Temp_Ip
  357. sbr @0, (1<<REFS1)
  358. sbr @0, (1<<REFS0)
  359. out ADMUX, @0 ; Set ADMUX register (2.56V reference, selected input)
  360. in @0, ADCSRA
  361. sbr @0, (1<<ADEN) ; Enable ADC
  362. sbr @0, (1<<ADSC) ; Start ADC conversion
  363. out ADCSRA, @0
  364. .ENDMACRO
  365. .MACRO Get_Adc_Status
  366. in @0, ADCSRA
  367. .ENDMACRO
  368. .MACRO Read_Adc_Result
  369. in @0, ADCL
  370. in @1, ADCH
  371. .ENDMACRO
  372. .MACRO Stop_Adc
  373. in @0, ADCSRA
  374. cbr @0, (1<<ADEN) ; Disable ADC
  375. out ADCSRA, @0
  376. .ENDMACRO
  377. .MACRO Set_Timer0_CS0
  378. out TCCR0, @0
  379. .ENDMACRO
  380. .MACRO Set_Timer1_CS1
  381. out TCCR1B, @0
  382. .ENDMACRO
  383. .MACRO Set_Timer2_CS2
  384. out TCCR2, @0
  385. .ENDMACRO
  386. .MACRO Read_TCNT1L
  387. in @0, TCNT1L
  388. .ENDMACRO
  389. .MACRO Read_TCNT1H
  390. in @0, TCNT1H
  391. .ENDMACRO
  392. .MACRO Set_OCR1AL
  393. out OCR1AL, @0
  394. .ENDMACRO
  395. .MACRO Set_OCR1AH
  396. out OCR1AH, @0
  397. .ENDMACRO
  398. .MACRO Read_TCNT2
  399. in @0, TCNT2
  400. .ENDMACRO
  401. .MACRO Set_TCNT2
  402. out TCNT2, @0
  403. .ENDMACRO
  404. .MACRO Check_Eeprom_Ready
  405. sbic EECR, EEWE
  406. .ENDMACRO
  407. .MACRO Set_Eeprom_Address
  408. out EEARL, @0
  409. out EEARH, @1
  410. .ENDMACRO
  411. .MACRO Start_Eeprom_Write
  412. sbi EECR, EEMWE
  413. sbi EECR, EEWE
  414. .ENDMACRO
  415. .MACRO Prepare_Lock_Or_Fuse_Read
  416. ldi @0, ((1<<BLBSET)+(1<<SPMEN))
  417. out SPMCR, @0
  418. .ENDMACRO
  419. .MACRO xcall
  420. rcall @0
  421. .ENDMACRO
  422. .MACRO Set_RPM_Out
  423. .ENDMACRO
  424. .MACRO Clear_RPM_Out
  425. .ENDMACRO