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.
 
 
 
 

458 lines
10 KiB

;**** **** **** **** ****
;
; BLHeli program for controlling brushless motors in helicopters and multirotors
;
; Copyright 2011, 2012 Steffen Skaug
; This program is distributed under the terms of the GNU General Public License
;
; This file is part of BLHeli.
;
; BLHeli is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; BLHeli is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with BLHeli. If not, see <http://www.gnu.org/licenses/>.
;
;**** **** **** **** ****
;
; YEP 7A hardware definition file
;
;**** **** **** **** ****
;*********************
; Device Atmega168PA
;*********************
.INCLUDE "m168PAdef.inc"
;**** **** **** **** ****
; Fuses must be set to external oscillator = 16Mhz
;**** **** **** **** ****
;**** **** **** **** ****
; Constant definitions
;**** **** **** **** ****
.ESEG ; EEprom segment
.ORG 0x40
Eep_ESC_Layout: .DB "#YEP_7A# " ; ESC layout tag
.ORG 0x50
Eep_ESC_MCU: .DB "#BLHELI#Am168PA#" ; Project and MCU tag (16 Bytes)
.EQU HIGH_BEC_VOLTAGE = 0 ; Set to 1 or more if high BEC voltage is supported
.EQU DAMPED_MODE_ENABLE = 0 ; Set to 1 if fully damped mode is supported
.EQU NFETON_DELAY = 65 ; Wait delay from pfets off to nfets on
.EQU PFETON_DELAY = 5 ; Wait delay from nfets off to pfets on
.EQU ADC_LIMIT_L = 231 ; 2k/22k divider. Power supply measurement ADC value for which motor power is limited (low byte)
.EQU ADC_LIMIT_H = 0 ; 2k/22k divider. Power supply measurement ADC value for which motor power is limited (2 MSBs)
.EQU TEMP_LIMIT = 0 ; No temp sensor. Temperature measurement ADC value for which main motor power is limited
.EQU TEMP_LIMIT_STEP = 0 ; No temp sensor. Temperature measurement ADC value increment for which main motor power is further limited
;**** **** **** **** ****
; ESC specific defaults
;**** **** **** **** ****
.EQU DEFAULT_PGM_MAIN_SPOOLUP_TIME = 7 ; Main motor spoolup time
.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
.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
.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
.EQU DEFAULT_PGM_MAIN_STARTUP_METHOD = 2 ; 1=Stepped 2=Direct
.EQU DEFAULT_PGM_TAIL_STARTUP_METHOD = 2 ; 1=Stepped 2=Direct
.EQU DEFAULT_PGM_MULTI_STARTUP_METHOD = 2 ; 1=Stepped 2=Direct
;*********************
; PORT D definitions *
;*********************
;.EQU = 7 ;i
;.EQU = 6 ;i
;.EQU = 5 ;i
;.EQU = 4 ;i
;.EQU = 3 ;i
.EQU Rcp_In = 2 ;i
;.EQU = 1 ;i
;.EQU = 0 ;i
.equ INIT_PD = 0x00
.equ DIR_PD = 0x00
.MACRO Get_Rcp_Capture_Values
lds @0, TCNT1L
lds @1, TCNT1H
.ENDMACRO
.MACRO Read_Rcp_Int
in @0, PIND
sbrc Flags3, PGM_RCP_PWM_POL ; Is pwm polarity negative?
com @0 ; Yes - invert
.ENDMACRO
.MACRO Get_Rcp_Int_Enable_State
in @0, EIMSK ; Get int0 enable state (giving 0 is off, anything else is on)
andi @0, (1<<INT0)
.ENDMACRO
.MACRO Rcp_Int_Enable
ldi @0, (1<<INT0) ; Enable int0
out EIMSK, @0
.ENDMACRO
.MACRO Rcp_Int_Disable
ldi @0, 0 ; Disable int0
out EIMSK, @0
.ENDMACRO
.MACRO Rcp_Int_First
ldi @0, (1<<ISC01)+(1<<ISC00); Default - set next int0 to rising
sbrc Flags3, PGM_RCP_PWM_POL ; Is pwm polarity negative?
ldi @0, (1<<ISC01) ; Yes - set next int0 to falling
sts EICRA, @0
.ENDMACRO
.MACRO Rcp_Int_Second
ldi @0, (1<<ISC01) ; Default - set next int0 to falling
sbrc Flags3, PGM_RCP_PWM_POL ; Is pwm polarity negative?
ldi @0, (1<<ISC01)+(1<<ISC00); Yes - set next int0 to rising
sts EICRA, @0
.ENDMACRO
.MACRO Rcp_Clear_Int_Flag
clr @0
sbr @0, (1<<INTF0) ; Clear ext0int flag
out EIFR, @0
.ENDMACRO
.MACRO T0_Int_Disable
lds @0, TIMSK0 ; Disable timer0 interrupts
cbr @0, (1<<TOIE0)
sts TIMSK0, @0
.ENDMACRO
.MACRO T0_Int_Enable
lds @0, TIMSK0 ; Enable timer0 interrupts
sbr @0, (1<<TOIE0)
sts TIMSK0, @0
.ENDMACRO
.MACRO T1oca_Clear_Int_Flag
ldi @0, (1<<OCF1A) ; Clear oc1a flag
out TIFR1, @0
.ENDMACRO
.MACRO T1oca_Int_Disable
lds @0, TIMSK1 ; Disable oc1a interrupts
cbr @0, (1<<OCIE1A)
sts TIMSK1, @0
.ENDMACRO
.MACRO T1oca_Int_Enable
lds @0, TIMSK1 ; Enable oc1a interrupts
sbr @0, (1<<OCIE1A)
sts TIMSK1, @0
.ENDMACRO
.MACRO T2_Clear_Int_Flag
clr @0
sbr @0, (1<<TOV2) ; Clear tov2 flag
out TIFR2, @0
.ENDMACRO
;*********************
; PORT C definitions *
;*********************
;.EQU = 7 ; i
;.EQU = 6 ; i
.EQU Mux_A = 5 ; i
.EQU Mux_B = 4 ; i
.EQU Mux_C = 3 ; i
;.EQU = 2 ; i
;.EQU = 1 ; i
.EQU Volt_Ip = 0 ; i
.equ INIT_PC = 0x00
.equ DIR_PC = 0x00
.MACRO AnFET_on
sbi PORTB, AnFET
.ENDMACRO
.MACRO AnFET_off
cbi PORTB, AnFET
.ENDMACRO
.MACRO BnFET_on
sbi PORTB, BnFET
.ENDMACRO
.MACRO BnFET_off
cbi PORTB, BnFET
.ENDMACRO
.MACRO CnFET_on
sbi PORTB, CnFET
.ENDMACRO
.MACRO CnFET_off
cbi PORTB, CnFET
.ENDMACRO
.MACRO All_nFETs_Off
cbi PORTB, AnFET
cbi PORTB, BnFET
cbi PORTB, CnFET
.ENDMACRO
.MACRO ApFET_on
sbi PORTB, ApFET
.ENDMACRO
.MACRO ApFET_off
cbi PORTB, ApFET
.ENDMACRO
.MACRO BpFET_on
sbi PORTB, BpFET
.ENDMACRO
.MACRO BpFET_off
cbi PORTB, BpFET
.ENDMACRO
.MACRO CpFET_on
sbi PORTB, CpFET
.ENDMACRO
.MACRO CpFET_off
cbi PORTB, CpFET
.ENDMACRO
.MACRO All_pFETs_Off
cbi PORTB, ApFET
cbi PORTB, BpFET
cbi PORTB, CpFET
.ENDMACRO
.MACRO Brake_FETs_On
AnFET_on
BnFET_on
CnFET_on
.ENDMACRO
.MACRO Damping_FET_On
lds @0, DampingFET
sbrc @0, 0
sbi PORTB, ApFET
sbrc @0, 1
sbi PORTB, BpFET
sbrc @0, 2
sbi PORTB, CpFET
.ENDMACRO
.MACRO Comp_Init
lds @0, ADCSRB ; Toggle Analog Comparator Multiplexer Enable
cbr @0, (1<<ACME)
sts ADCSRB, @0
Read_Comp_Out @0
lds @0, ADCSRB
sbr @0, (1<<ACME)
sts ADCSRB, @0
.ENDMACRO
.MACRO Set_Comp_Phase_A
ldi @0, Mux_A ; Set comparator multiplexer to phase A
ori @0, (1<<REFS1)+(1<<REFS0)
sts ADMUX, @0
.ENDMACRO
.MACRO Set_Comp_Phase_B
ldi @0, Mux_B ; Set comparator multiplexer to phase B
ori @0, (1<<REFS1)+(1<<REFS0)
sts ADMUX, @0
.ENDMACRO
.MACRO Set_Comp_Phase_C
ldi @0, Mux_C ; Set comparator multiplexer to phase C
ori @0, (1<<REFS1)+(1<<REFS0)
sts ADMUX, @0
.ENDMACRO
.MACRO Read_Comp_Out
in @0, ACSR ; Read comparator output
.ENDMACRO
;*********************
; PORT B definitions *
;*********************
;.EQU = 7 ; i
;.EQU = 6 ; i
.EQU CnFET = 5 ; o
.EQU BnFET = 4 ; o
.EQU AnFET = 3 ; o
.EQU ApFET = 2 ; o
.EQU CpFET = 1 ; o
.EQU BpFET = 0 ; o
.EQU INIT_PB = 0
.EQU DIR_PB = (1<<AnFET)+(1<<BnFET)+(1<<CnFET)+(1<<ApFET)+(1<<BpFET)+(1<<CpFET)
;**********************
; MCU specific macros *
;**********************
.MACRO Interrupt_Table_Definition
jmp reset
rjmp rcp_int ; ext_int0
nop
nop ; ext_int1
nop
nop ; pci0_int
nop
nop ; pci1_int
nop
nop ; pci2_int
nop
nop ; wdt_int
nop
nop ; t2oca_int
nop
nop ; t2ocb_int
nop
rjmp t2_int ; t2ovfl_int
nop
nop ; icp1_int
nop
rjmp t1oca_int ; t1oca_int
nop
nop ; t1ocb_int
nop
nop ; t1ovfl_int
nop
nop ; t0oca_int
nop
nop ; t0ocb_int
nop
rjmp t0_int ; t0ovfl_int
nop
nop ; spi_int
nop
nop ; urxc
nop
nop ; udre
nop
nop ; utxc
nop
; nop ; adc_int
; nop ; eep_int
; nop ; aci_int
; nop ; wire2_int
; nop ; spmc_int
.ENDMACRO
.MACRO Disable_Watchdog
cli ; Disable interrupts
wdr ; Reset watchdog timer
in @0, MCUSR ; Clear WDRF in MCUSR
andi @0, (0xFF & (0<<WDRF))
out MCUSR, @0
lds @0, WDTCSR ; Write logical one to WDCE and WDE
ori @0, (1<<WDCE) | (1<<WDE)
sts WDTCSR, @0
ldi @0, (0<<WDE) ; Turn off WDT
sts WDTCSR, @0
.ENDMACRO
.MACRO Enable_Watchdog
ldi @0, (1<<WDE) ; Turn on WDT
sts WDTCSR, @0
.ENDMACRO
.MACRO Initialize_MCU
.ENDMACRO
.MACRO Initialize_Interrupts
ldi @0, (1<<TOIE0)
out TIFR0, @0 ; Clear interrupts
sts TIMSK0, @0 ; Enable interrupts
ldi @0, (1<<OCIE1A)
out TIFR1, @0 ; Clear interrupts
sts TIMSK1, @0 ; Enable interrupts
ldi @0, (1<<TOIE2)
out TIFR2, @0 ; Clear interrupts
sts TIMSK2, @0 ; Enable interrupts
.ENDMACRO
.MACRO Initialize_Adc
ldi @0, Volt_Ip
ori @0, (1<<REFS1)+(1<<REFS0)
sts ADMUX, @0 ; Set ADMUX register
lds @0, ADCSRA ; Set ADCSRA register (1MHz clock)
sbr @0, (1<<ADPS2)
sbr @0, (1<<ADEN) ; Enable ADC
sts ADCSRA, @0
.ENDMACRO
.MACRO Set_Adc_Ip_Volt
cbr Flags1, (1<<ADC_READ_TEMP)
.ENDMACRO
.MACRO Set_Adc_Ip_Temp
sbr Flags1, (1<<ADC_READ_TEMP)
.ENDMACRO
.MACRO Start_Adc
ldi @0, Volt_Ip
sbrc Flags1, ADC_READ_TEMP
ldi @0, Volt_Ip
ori @0, (1<<REFS1)+(1<<REFS0)
sts ADMUX, @0 ; Set ADMUX register (1.1V reference, selected input)
lds @0, ADCSRA
sbr @0, (1<<ADEN) ; Enable ADC
sbr @0, (1<<ADSC) ; Start ADC conversion
sts ADCSRA, @0
.ENDMACRO
.MACRO Get_Adc_Status
lds @0, ADCSRA
.ENDMACRO
.MACRO Read_Adc_Result
lds @0, ADCL
lds @1, ADCH
.ENDMACRO
.MACRO Stop_Adc
lds @0, ADCSRA
cbr @0, (1<<ADEN) ; Disable ADC
sts ADCSRA, @0
.ENDMACRO
.MACRO Set_Timer0_CS0
out TCCR0B, @0
.ENDMACRO
.MACRO Set_Timer1_CS1
sts TCCR1B, @0
.ENDMACRO
.MACRO Set_Timer2_CS2
sts TCCR2B, @0
.ENDMACRO
.MACRO Read_TCNT1L
lds @0, TCNT1L
.ENDMACRO
.MACRO Read_TCNT1H
lds @0, TCNT1H
.ENDMACRO
.MACRO Set_OCR1AL
sts OCR1AL, @0
.ENDMACRO
.MACRO Set_OCR1AH
sts OCR1AH, @0
.ENDMACRO
.MACRO Read_TCNT2
lds @0, TCNT2
.ENDMACRO
.MACRO Set_TCNT2
sts TCNT2, @0
.ENDMACRO
.MACRO Check_Eeprom_Ready
sbic EECR, EEPE
.ENDMACRO
.MACRO Set_Eeprom_Address
out EEARL, @0
out EEARH, @1
.ENDMACRO
.MACRO Start_Eeprom_Write
sbi EECR, EEMPE
sbi EECR, EEPE
.ENDMACRO
.MACRO Prepare_Lock_Or_Fuse_Read
ldi @0, ((1<<BLBSET)+(1<<SELFPRGEN))
out SPMCSR, @0
.ENDMACRO
.MACRO xcall
call @0
.ENDMACRO
.MACRO Set_RPM_Out
.ENDMACRO
.MACRO Clear_RPM_Out
.ENDMACRO