;***************************************************************************************** ;Telescope Mount Controller IV ;(c) Martin Cibulski ; ;CPU........: Atmel AVR mega128, 16 MHz ;Stepper ICs: Allegro A3973SB ; ;(Formatted for editor tab witdth of 18 characters) ; ;**************************************************************************************** ;TO DO LIST ;---------- ; ;PROGRAM: ;-------- ;Message when Z3 cannot be found ;label tab for object_db.asm ;push/pop in lcd_print_z1... ; ;TEST: ;----- ;variables for last_goto_db, last_goto_index ;key repeat acceleration 1.5 ;key repeat delays ;**************************************************************************************** ; ;#define SIMULATE ;for simulation in AVR Studio ;#define EXCLUDE_DB ;no NGC/IC list #define LCD_IRQ_ACT 1 ;handbox LCD active (1) or test mode (0) #define MESSAGES_ENGLISH ;language for terminal and handbox messages ;#define MESSAGES_GERMAN ;.EQU USART0_BAUDRATE = 103 ; 9600 at 16 MHz (terminal program) ;.EQU USART0_BAUDRATE = 51 ;19200 at 16 MHz .EQU USART0_BAUDRATE = 25 ;38400 at 16 MHz .EQU USART1_BAUDRATE = 103 ; 9600 at 16 MHz (reserved) ;***************************************************************************************** .LISTMAC .INCLUDE "m128def.inc" .DSEG .ORG 0x100 ram_start: ;***************************************************************************************** ;Vector Table (Reset, Interrupts) ; ;Timer 1 8889 per second Motor A microstepping / halfstepping ;Timer 3 8889 per second Motor B microstepping / halfstepping ;Timer 0 128 per second Real time clock (external 32768 Hz quartz) ; Speed ramping of both motors ; Handbox menu (key input and LCD output) ;USART0 receive complete Serial communication .CSEG .ORG 0x0000 jmp main ;Reset jmp to_reti ;External Tnterrupt 0 jmp to_reti ;External Tnterrupt 1 jmp to_reti ;External Tnterrupt 2 jmp to_reti ;External Tnterrupt 3 jmp to_reti ;External Tnterrupt 4 jmp to_reti ;External Tnterrupt 5 jmp to_reti ;External Tnterrupt 6 jmp to_reti ;External Tnterrupt 7 jmp to_reti ;Timer/Counter 2 Compare Match jmp irq_timer_2 ;Timer/Counter 2 Overflow jmp to_reti ;Timer/Counter 1 Capture Event jmp to_reti ;Timer/Counter 1 Compare Match A jmp to_reti ;Timer/Counter 1 Compare Match B jmp to_reti ;Timer/Counter 1 Overflow #ifdef SIMULATE jmp irq_timer_0;to_reti #else jmp irq_timer_0 ;Timer/Counter 0 Compare Match #endif jmp to_reti ;Timer/Counter 0 Overflow jmp to_reti ;SPI Serial Transfer Complete jmp usart0_rx ;USART0, RX Complete jmp to_reti ;USART0, Data Register Empty jmp to_reti ;USART0, RX Complete jmp to_reti ;ADC conversion complete jmp to_reti ;EEPROM ready jmp to_reti ;Analog comparator jmp to_reti ;Timer/Counter 1 Compare Match C jmp to_reti ;Timer/Counter 3 Capture Event jmp to_reti ;Timer/Counter 3 Compare Match A jmp to_reti ;Timer/Counter 3 Compare Match B jmp to_reti ;Timer/Counter 3 Compare Match C jmp to_reti ;Timer/Counter 3 Overflow jmp usart1_rx ;USART1, RX Complete jmp to_reti ;USART1, Data Register Empty jmp to_reti ;USART1, RX Complete jmp to_reti ;Two-wire Serial Interface jmp to_reti ;Store Program Memory Ready to_reti: reti ;***************************************************************************************** ;Message Strings .equ LANGUAGE = 1 .include "messages.asm" ;***************************************************************************************** ;Serial Communication .include "serial_com.asm" ;***************************************************************************************** ;Internal EEPROM access routines .include "eeprom.asm" ;***************************************************************************************** ;External EEPROM access routines .include "twi_drv.asm" ;***************************************************************************************** ;Utilities .include "utils.asm" ;***************************************************************************************** ;Floating Point Math ; ;IEEE double precision routines and stack engine ;add, sub, mul, div, sqrt, sin, cos, atan ;some 3x3 matrix and vector functions .include "float.asm" ;***************************************************************************************** ;Alignment and Coordinate Transformation ; ;first implementation without precession and refraction .include "alignment.asm" ;two star alignment .include "coordinates.asm" ;conversion mount > sky coordinates .include "tracking_goto.asm" ;target tracking and goto .include "mount_coords.asm" ;transformations in mount coordinates .include "xyz_goto.asm" ;control in XYZ coordinates ;.include "precession.asm" ;.include "refraction.asm" ;***************************************************************************************** ;High Level Motor Control ; ;Speed ramping .EQU MOT_INIT_POS_A = 0 ;position .EQU MOT_INIT_POS_B = 0 .EQU MOT_INIT_SP_A = 0x000000 ;speed .EQU MOT_INIT_SP_B = 0x000000 .EQU MOT_INIT_GSP_A = 0x000000 ;goto/tracking speed .EQU MOT_INIT_GSP_B = 0x000000 .include "motor_ramp.asm" ;***************************************************************************************** ;Low Level Motor Control ; ;Microstepping via PWM ;Halfstepping .EQU MOT_PORT = PORTB ;motor control port .EQU MOT_DDR = DDRB ;data direction register .EQU MOT_DDR_VALUE = 0b11111100 ;set motor control pins to output .EQU MOT_BIT_STROBE = 6 ;port bit for STROBE to both motors .EQU MOT_BIT_CLOCK = 5 ;port bit for CLOCK to both motors .EQU MOT_BIT_SLEEP_A = 7 ;port bit for SLEEP to motor A .EQU MOT_BIT_SLEEP_B = 2 ;port bit for SLEEP to motor B .EQU MOT_BIT_DATA_A = 3 ;port bit for DATA to motor A .EQU MOT_BIT_DATA_B = 4 ;port bit for DATA to motor B .include "motor_a3973.asm" ;***************************************************************************************** ;Monitor program for debugging monitor_test_command: .db "ml motapos 1234 " .db 0,0 .include "Monitor.asm" ;***************************************************************************************** ;LX200 command support .include "lx200.asm" ;***************************************************************************************** ;Interrupt Helper Routines ; ;was planned as a simple multitasking kernel ;but fortunately no multitasking is needed for this application :) .include "multitask.asm" ;***************************************************************************************** ;Handbox Key and Display ; .equ LCD_PORT = porta .equ LCD_PINS = pina .equ LCD_DDR = ddra .equ LCD_PIN_RS_DS = 0 .equ LCD_PIN_RW_CLK = 1 .equ LCD_PIN_E_STCP = 2 .equ LCD_PIN_LOAD = 4 .equ LCD_PIN_INPUT = 5 ;#define HANDBOX_2 = 1 ;key connections changed ;will be configurable some day #ifdef HANDBOX_2 .equ LCD_KEY_MENU = 0b11110111 .equ LCD_KEY_MOVE = 0b11111011 .equ LCD_KEY_PLUS = 0b01111111 .equ LCD_KEY_MINUS = 0b10111111 .equ LCD_KEY_UP = 0b11111110 .equ LCD_KEY_DOWN = 0b11101111 .equ LCD_KEY_LEFT = 0b11111101 .equ LCD_KEY_RIGHT = 0b11011111 #else .equ LCD_KEY_MENU = 0b11111101 .equ LCD_KEY_MOVE = 0b11111011 .equ LCD_KEY_PLUS = 0b11101111 .equ LCD_KEY_MINUS = 0b11011111 .equ LCD_KEY_UP = 0b11111110 .equ LCD_KEY_DOWN = 0b01111111 .equ LCD_KEY_LEFT = 0b11110111 .equ LCD_KEY_RIGHT = 0b10111111 #endif .equ LCD_LENGTH = 8 .include "menu_irq.asm" .include "handbox_drv.asm" ;***************************************************************************************** ;Menue Tree ; ;The menue is defined as a tree structure with display texts and subroutine adresses. ;It is navigated in the Timer0 interrupt routine. .include "menu.asm" ;***************************************************************************************** ;MAIN ; ;The program starts from here. .CSEG ;**************************************************************************************** ;Init Stackpointer, clear RAM main: ldi xh ,high(RAMEND) ;set stackpointer to end of RAM ldi xl ,low(RAMEND) out SPH ,xh out SPL ,xl ldi r16 ,0x00 ;clear RAM (fill with zero) main_01: st X ,r16 sbiw xh:xl ,1 cpi xh ,0x01 brcc main_01 ldi zh ,high(eep_prof_default) ;read default profile number from eeprom ldi zl ,low(eep_prof_default) call eep_read sts eep_cur_profile ,r16 main_new_profile: ;start from here after profile change ldi xh ,high(RAMEND) ;set stackpointer to end of RAM ldi xl ,low(RAMEND) out SPH ,xh out SPL ,xl ldi r16 ,0xFF sts util_minstack ,r16 ;start value for stack check routine sts util_minstack+1 ,r16 ;**************************************************************************************** ;Start Serial Communication ; call uart0_init call uart1_init PUTS_ROM msg_start1 PUTS_ROM msg_release PUTS_ROM msg_start2 ;**************************************************************************************** ;Handbox Display ; ldi r16 ,LCD_IRQ_ACT sts lcd_irq_active ,r16 call hbx_init_port lds r0 ,lcd_irq_active ;IRQ handler on ? sbrs r0 ,0 rjmp main_no_lcd PUTS_ROM msg_init_hbx call lcd_init ;LCD character buffer call hbx_init_lcd ;handbox hardware driver call hbx_read_keys ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms ldi r16 ,LCD_HOME rcall hbx_write_command ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms ldi r16 ,'M' rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms ldi r16 ,'C' rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms ldi r16 ,'-' rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms ldi r16 ,'4' rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms ldi r16 ,LCD_HOME2 rcall hbx_write_command ldi zl ,low(msg_release<<1) ldi zh ,high(msg_release<<1) adiw zh:zl ,3 ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data ldi r16 ,10 ;minimum 0.1 ms call util_delay_ms lpm r16 ,Z+ rcall hbx_write_data main_no_lcd: ;**************************************************************************************** ;start two wire interface PUTS_ROM msg_init_twi call twi_init ;**************************************************************************************** ;read configuration from default profile PUTS_ROM msg_init_default_profile lds r16 ,eep_cur_profile call eep_load_profile ;**************************************************************************************** ; #ifndef SIMULATE call a39_fill_sin_table #endif PUTS_ROM msg_init_motor_controllers ldi r16 ,MOT_DDR_VALUE ;initialize motor control port out MOT_DDR ,r16 ldi r16 ,(1< 388 days maximum sts clock+3 ,r16 sts tgo_counter ,r16 ;calculation loop counter sts tgo_counter+1 ,r16 sts tgo_counter+2 ,r16 sts tgo_counter+3 ,r16 ldi r16 ,1 ;start real time clock sts clock_step ,r16 ;**************************************************************************************** ;Start Interrupt Timers PUTS_ROM msg_init_motor_timer ldi r16 ,0b00000010 ;clock prescaler = 8 out TCCR2 ,r16 ldi r16 ,0 out TCNT2 ,r16 ldi r16 ,(1<