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.

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