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.

387 lines
8.8 KiB

  1. ;**** **** **** **** ****
  2. ;
  3. ; BLHeli program for controlling brushless motors in helicopters
  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. ; Device Atmega88P(A)
  26. ;*********************
  27. .include "m88Pdef.inc"
  28. ;**** **** **** **** ****
  29. ; Fuses must be set to external oscillator 8.0- MHz
  30. ;**** **** **** **** ****
  31. ;**** **** **** **** ****
  32. ; Constant definitions
  33. ;**** **** **** **** ****
  34. .equ ADC_LIMIT_L = 180 ; Power supply measurement ADC value for which main motor power is limited (low byte)
  35. .equ ADC_LIMIT_H = 1 ; Power supply measurement ADC value for which main motor power is limited (2 MSBs)
  36. ;*********************
  37. ; PORT D definitions *
  38. ;*********************
  39. .equ Mux_B = 7 ;i Phase B input
  40. .equ Comp_Com = 6 ;i Comparator common input (AIN0)
  41. .equ BnFET = 5 ;o
  42. .equ BpFET = 4 ;o
  43. .equ CpFET = 3 ;o
  44. .equ Rcp_In = 2 ;i RC pulse input
  45. .equ ApFET = 1 ;o
  46. ;.equ = 0 ;i
  47. .equ INIT_PD = 0
  48. .equ DIR_PD = (1<<ApFET)+(1<<BpFET)+(1<<CpFET)+(1<<BnFET)
  49. .MACRO Read_Rcp_Int
  50. in @0, PIND
  51. sbrc Flags2, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  52. com @0 ; Yes - invert
  53. .ENDMACRO
  54. .MACRO Read_Rcp_Icp_Int
  55. in @0, PINB
  56. sbrc Flags2, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  57. com @0 ; Yes - invert
  58. .ENDMACRO
  59. .MACRO Rcp_Int_Enable
  60. ldi @0, (1<<INT0) ; Enable ext0int
  61. out EIMSK, @0
  62. .ENDMACRO
  63. .MACRO Rcp_Int_Disable
  64. ldi @0, 0 ; Disable ext0int
  65. out EIMSK, @0
  66. .ENDMACRO
  67. .MACRO Rcp_Int_First
  68. sbrs Flags2, PGM_RCP_PWM_POL ; Is pwm polarity positive?
  69. ldi @0, (1<<ISC01)+(1<<ISC00) ; Yes - set next int0 to rising
  70. sbrc Flags2, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  71. ldi @0, (1<<ISC01) ; Yes - set next int0 to falling
  72. sts EICRA, @0
  73. .ENDMACRO
  74. .MACRO Rcp_Int_Second
  75. sbrs Flags2, PGM_RCP_PWM_POL ; Is pwm polarity positive?
  76. ldi @0, (1<<ISC01) ; Yes - set next int0 to falling
  77. sbrc Flags2, PGM_RCP_PWM_POL ; Is pwm polarity negative?
  78. ldi @0, (1<<ISC01)+(1<<ISC00) ; Yes - set next int0 to rising
  79. sts EICRA, @0
  80. .ENDMACRO
  81. .MACRO Clear_Int_Flag
  82. clr @0
  83. sbr @0, (1<<INTF0) ; Clear ext0int flag
  84. out EIFR, @0
  85. .ENDMACRO
  86. .MACRO Rcp_Icp_Int_Enable
  87. lds @0, TIMSK1
  88. sbr @0, (1<<ICIE1) ; Enable icp1int
  89. sts TIMSK1, @0
  90. .ENDMACRO
  91. .MACRO Rcp_Icp_Int_Disable
  92. lds @0, TIMSK1
  93. cbr @0, (1<<ICIE1) ; Disable icp1int
  94. sts TIMSK1, @0
  95. .ENDMACRO
  96. .MACRO Rcp_Icp_Int_First
  97. lds @0, TCCR1B
  98. sbrs Flags2, PGM_RCP_PWM_POL ; Is pwm polarity positive
  99. sbr @0, (1<<ICES1) ; Yes - set icp1int to trig on rising edge
  100. sbrc Flags2, PGM_RCP_PWM_POL ; Is pwm polarity negative
  101. cbr @0, (1<<ICES1) ; Yes - set icp1int to trig on falling edge
  102. sts TCCR1B, @0
  103. .ENDMACRO
  104. .MACRO Rcp_Icp_Int_Second
  105. lds @0, TCCR1B
  106. sbrs Flags2, PGM_RCP_PWM_POL ; Is pwm polarity positive
  107. cbr @0, (1<<ICES1) ; Yes - set icp1int to trig on falling edge
  108. sbrc Flags2, PGM_RCP_PWM_POL ; Is pwm polarity negative
  109. sbr @0, (1<<ICES1) ; Yes - set icp1int to trig on rising edge
  110. sts TCCR1B, @0
  111. .ENDMACRO
  112. .MACRO Clear_Icp_Int_Flag
  113. clr @0
  114. sbr @0, (1<<ICF1) ; Clear icp1int flag
  115. out TIFR1, @0
  116. .ENDMACRO
  117. .MACRO ApFET_on
  118. sbi PORTD,1
  119. .ENDMACRO
  120. .MACRO ApFET_off
  121. cbi PORTD,1
  122. .ENDMACRO
  123. .MACRO CpFET_on
  124. sbi PORTD,3
  125. .ENDMACRO
  126. .MACRO CpFET_off
  127. cbi PORTD,3
  128. .ENDMACRO
  129. .MACRO BpFET_on
  130. sbi PORTD,4
  131. .ENDMACRO
  132. .MACRO BpFET_off
  133. cbi PORTD,4
  134. .ENDMACRO
  135. .MACRO All_pFETs_Off
  136. in @0, PORTD
  137. cbr @0, (1<<ApFET)+(1<<BpFET)+(1<<CpFET)
  138. out PORTD, @0
  139. .ENDMACRO
  140. .MACRO All_pFETs_On
  141. in @0, PORTD
  142. sbr @0, (1<<ApFET)+(1<<BpFET)+(1<<CpFET)
  143. out PORTD, @0
  144. .ENDMACRO
  145. ;*********************
  146. ; PORT C definitions *
  147. ;*********************
  148. ;.equ = 7 ; ADC7
  149. ;.equ = 6 ; ADC6
  150. ;.equ = 5 ; ADC5
  151. ;.equ = 4 ; ADC4
  152. .equ Mux_C = 3 ; Phase C input
  153. .equ Mux_A = 2 ; Phase A input
  154. ;.equ = 1 ; ADC1
  155. ;.equ = 0 ; ADC0
  156. .equ INIT_PC = 0
  157. .equ DIR_PC = 0
  158. .MACRO Comp_Init
  159. lds @0, ADCSRA ; Disable ADC
  160. cbr @0, (1<<ADEN)
  161. sts ADCSRA, @0
  162. lds @0, ADCSRB ; Set Analog Comparator Multiplexer Enable
  163. sbr @0, (1<<ACME)
  164. sts ADCSRB, @0
  165. .ENDMACRO
  166. .MACRO Set_Comp_Phase_A
  167. lds @0, ADCSRB ; Set Analog Comparator Multiplexer Enable
  168. sbr @0, (1<<ACME)
  169. sts ADCSRB, @0
  170. ldi @0, Mux_A ; Set comparator multiplexer to phase A
  171. sts ADMUX, @0
  172. .ENDMACRO
  173. .MACRO Set_Comp_Phase_C
  174. lds @0, ADCSRB ; Set Analog Comparator Multiplexer Enable
  175. sbr @0, (1<<ACME)
  176. sts ADCSRB, @0
  177. ldi @0, Mux_C ; Set comparator multiplexer to phase C
  178. sts ADMUX, @0
  179. .ENDMACRO
  180. .MACRO Set_Comp_Phase_B
  181. lds @0, ADCSRB ; Set Analog Comparator Multiplexer Disable
  182. cbr @0, (1<<ACME)
  183. sts ADCSRB, @0
  184. .ENDMACRO
  185. .MACRO Read_Comp_Out
  186. in @0, ACSR ; Read comparator output
  187. .ENDMACRO
  188. ;*********************
  189. ; PORT B definitions *
  190. ;*********************
  191. ;.equ = 7
  192. ;.equ = 6
  193. ;.equ = 5 (sck stk200 interface)
  194. .equ DebugPin = 4 ;(miso stk200 interface)
  195. ;.equ = 3 (mosi stk200 interface)
  196. .equ AnFET = 2
  197. .equ CnFET = 1
  198. .equ Rcp_Icp_In = 0
  199. .equ INIT_PB = 0
  200. .equ DIR_PB = (1<<DebugPin)+(1<<AnFET)+(1<<CnFET)
  201. .MACRO AnFET_on
  202. sbi PORTB,2
  203. .ENDMACRO
  204. .MACRO AnFET_off
  205. cbi PORTB,2
  206. .ENDMACRO
  207. .MACRO CnFET_on
  208. sbi PORTB,1
  209. .ENDMACRO
  210. .MACRO CnFET_off
  211. cbi PORTB,1
  212. .ENDMACRO
  213. .MACRO BnFET_on
  214. sbi PORTD,5
  215. .ENDMACRO
  216. .MACRO BnFET_off
  217. cbi PORTD,5
  218. .ENDMACRO
  219. .MACRO All_nFETs_Off
  220. in @0, PORTB
  221. cbr @0, (1<<AnFET)+(1<<CnFET)
  222. out PORTB, @0
  223. in @0, PORTD
  224. cbr @0, (1<<BnFET)
  225. out PORTD, @0
  226. .ENDMACRO
  227. ;**********************
  228. ; MCU specific macros *
  229. ;**********************
  230. .MACRO Disable_Watchdog
  231. cli ; Disable interrupts
  232. wdr ; Reset watchdog timer
  233. in @0, MCUSR ; Clear WDRF in MCUSR
  234. andi @0, (0xff & (0<<WDRF))
  235. out MCUSR, @0
  236. lds @0, WDTCSR ; Write logical one to WDCE and WDE
  237. ori @0, (1<<WDCE) | (1<<WDE)
  238. sts WDTCSR, @0
  239. ldi @0, (0<<WDE) ; Turn off WDT
  240. sts WDTCSR, @0
  241. .ENDMACRO
  242. .MACRO Enable_Watchdog
  243. ldi @0, (1<<WDE) ; Turn on WDT
  244. sts WDTCSR, @0
  245. .ENDMACRO
  246. .MACRO Initialize_MCU
  247. ldi @0, (1<<CLKPCE) ; Set clock prescaler change enable
  248. sts CLKPR, @0
  249. ldi @0, (1<<CLKPS0) ; Change clock prescaler (to divide by 2)
  250. sts CLKPR, @0
  251. .ENDMACRO
  252. .MACRO Interrupt_Table_Definition
  253. rjmp reset
  254. rjmp ext_int0 ; ext_int0
  255. nop ; ext_int1
  256. nop ; pci0_int
  257. nop ; pci1_int
  258. nop ; pci2_int
  259. nop ; wdt_int
  260. nop ; t2oca_int
  261. nop ; t2ocb_int
  262. rjmp t2ovfl_int; t2ovfl_int
  263. rjmp icp1_int ; icp1_int
  264. rjmp t1oca_int ; t1oca_int
  265. nop ; t1ocb_int
  266. rjmp t1ovfl_int; t1ovfl_int
  267. nop ; t0oca_int
  268. nop ; t0ocb_int
  269. rjmp t0ovfl_int; t0ovfl_int
  270. nop ; spi_int
  271. nop ; urxc
  272. nop ; udre
  273. nop ; utxc
  274. ; nop ; adc_int
  275. ; nop ; eep_int
  276. ; nop ; aci_int
  277. ; nop ; wire2_int
  278. ; nop ; spmc_int
  279. .ENDMACRO
  280. .MACRO Initialize_Interrupts
  281. ldi Temp1, (1<<TOIE0)
  282. out TIFR0, Temp1 ; Clear interrupts
  283. sts TIMSK0, Temp1 ; Enable interrupts
  284. ldi Temp1, (1<<TOIE1)+(1<<OCIE1A)
  285. out TIFR1, Temp1 ; Clear interrupts
  286. sts TIMSK1, Temp1 ; Enable interrupts
  287. ldi Temp1, (1<<TOIE2)
  288. out TIFR2, Temp1 ; Clear interrupts
  289. sts TIMSK2, Temp1 ; Enable interrupts
  290. .ENDMACRO
  291. .MACRO Initialize_Adc
  292. lds Temp1, ADCSRA ; Set ADCSRA register (1MHz clock)
  293. sbr Temp1, (1<<ADPS1)
  294. sbr Temp1, (1<<ADPS0)
  295. sts ADCSRA, Temp1
  296. .ENDMACRO
  297. .MACRO Start_Adc
  298. ldi Temp1, (1<<REFS1)+(1<<REFS0)+(1<<MUX2)+(1<<MUX1)+(1<<MUX0)
  299. sts ADMUX, Temp1 ; Set ADMUX register (1.1V reference, left adj result, input 7)
  300. lds @0, ADCSRA
  301. sbr @0, (1<<ADEN) ; Enable ADC
  302. sbr @0, (1<<ADSC) ; Start ADC conversion
  303. sts ADCSRA, @0
  304. .ENDMACRO
  305. .MACRO Get_Adc_Status
  306. lds @0, ADCSRA
  307. .ENDMACRO
  308. .MACRO Read_Adc_Result
  309. lds @0, ADCL
  310. lds @1, ADCH
  311. .ENDMACRO
  312. .MACRO Stop_Adc
  313. lds @0, ADCSRA
  314. cbr @0, (1<<ADEN) ; Disable ADC
  315. sts ADCSRA, @0
  316. .ENDMACRO
  317. .MACRO Set_Timer0_CS0
  318. out TCCR0B, @0
  319. .ENDMACRO
  320. .MACRO Set_Timer1_CS1
  321. sts TCCR1B, @0
  322. .ENDMACRO
  323. .MACRO Set_Timer2_CS2
  324. sts TCCR2B, @0
  325. .ENDMACRO
  326. .MACRO Read_TCNT1L
  327. lds @0, TCNT1L
  328. .ENDMACRO
  329. .MACRO Read_TCNT1H
  330. lds @0, TCNT1H
  331. .ENDMACRO
  332. .MACRO Read_ICR1L
  333. lds @0, ICR1L
  334. .ENDMACRO
  335. .MACRO Read_ICR1H
  336. lds @0, ICR1H
  337. .ENDMACRO
  338. .MACRO Set_OCR1AL
  339. sts OCR1AL, @0
  340. .ENDMACRO
  341. .MACRO Set_OCR1AH
  342. sts OCR1AH, @0
  343. .ENDMACRO
  344. .MACRO Set_TCNT2
  345. sts TCNT2, @0
  346. .ENDMACRO
  347. .MACRO Check_Eeprom_Ready
  348. sbic EECR, EEPE
  349. .ENDMACRO
  350. .MACRO Set_Eeprom_Address
  351. out EEARL, @0
  352. out EEARH, @1
  353. .ENDMACRO
  354. .MACRO Start_Eeprom_Write
  355. sbi EECR, EEMPE
  356. sbi EECR, EEPE
  357. .ENDMACRO