; ; File Name :'INIT.asm" ; Title :8515 Machine initialization ; Date : ; Version : ; Support telephone :765 287 1987 David B. VanHorn ; Support fax :765 287 1989 ; Support Email :dvanhorn@cedar.net ; Target MCU :AT90S8515 ; ; DESCRIPTION ; This module contains the machine initialization ; ;***************************************************************************; ; M O D I F I C A T I O N H I S T O R Y ; ; ; rev. date who why ; ---- -------- --- ------------------------------------------ ; 0.01 98.07.29 dvh Creation ; 0.02 98.08.05 dvh Fixed bit inits for demo board. ; 0.03 98.08.06 dvh Documented better :) ; 0,04 98.08.20 dvh Added servo inits ; 0.05 98.08.20 dvh Added FRAME_DELAY init for SERVO.ASM frame rate ; Changed Frame_Delay to SRAM rather than register ; 0.06 98.08.30 dvh Added watchdog timer support ; 0.07 98.10.19 dvh Added DS1602 and DS1820 support ; minor cleanups to the servo and stepper inits. ; 0.08 98.10.29 dvh documentation cleanup re databook pages ; ;*************************************************************************** ;* ;* Initialize the machine ;* ;*************************************************************************** ; ; INIT_Machine: ;Set Watchdog Inactive Databook 5-43 ;Gotta handle this before it gets a chance to bite me. ; ldi TEMP,$1F ;00011011 out WDTCR,TEMP ; ldi TEMP,$17 ;00010111 ;XXX1XXXX Watch dog turn off enable, must be 1 to wrt D3 ;XXXX0XXX WDE 0=disable 1=enable ;XXXXX111 000 = 16mS WD prescaler bits ; 001 = 32mS ; 010 = 64mS ; 011 = 128mS ; 100 = 256mS ; 101 = 512mS ; 110 = 1024mS ; 111 = 2048mS out WDTCR,TEMP ; ldi TEMP,Dog_Chow ;Stock up on dog food sts Dog_Food,Temp ;Decremented by Timer 0 ISR ; ;Set the stack pointer to 025F, stack grows down. ;Databook 5-24 ;Can't call any subroutines till we have a stack! ; ldi TEMP,0x5f ; out SPL,TEMP ;init Stack Pointer Low ldi temp,0x02 ; out SPL+1,TEMP ;init Stack Pointer High ;This section allows ints which are apparently ;caused by reset, to occur harmlessly. ;Databook 5-23, 5-29 ldi TEMP,$40 ; ;0XXXXXXX 1= enable int 1 ;X1XXXXXX 1= enable int 0 out GIMSK,TEMP ;Enable int 0,1 ldi TEMP,$02 ; ;0XXXXXXX TC1 overflow int enable ;X0XXXXXX TC1 OCA Match int enable ;XX0XXXXX TC1 OCB Match int enable ;XXX0XXXX Reserved =0 ;XXXX0XXX TC1 input capture int enable ;XXXXX0XX Reserved =0 ;XXXXXX1X TC0 overflow int enable ;XXXXXXX0 Reserved =0 out TIMSK,TEMP ;Enable all timer ints in TEMP,SREG ;(5-23) ori TEMP,$80 ;Global int enable out SREG,TEMP ; nop nop nop ;Let the ints happen, so they nop ;clear out nop nop nop ;NOTE: I have not exhaustively researched the need nop ;for this EI-NOP-DI section, but it is working well. nop in TEMP,SREG ; andi TEMP,$7F ;Turn off all ints (5-23) out SREG,TEMP ; ldi TEMP,$00 ;Disable all timer ints (5-29) out TIMSK,TEMP ; ldi TEMP,$00 ;Disable all ints. (5-29) ;1XXXXXXX enable int 1 ;X1XXXXXX enable int 0 out GIMSK,TEMP ; ; ;At this point, we should have a clean machine, in that there ;are no bogus pending ints from powerup. Later, when we enable ;various ints for real, they will only trigger after an event ;has occured, rather than because the int logic was scrambled ;at powerup. ;******************************************************************* ; ;Set the I/O pins to their appropriate state. ;Mung as needed for your app, this is all set to the dev board ;Always a good idea to set unused pins to be outputs. ; ;DD PORT I/O Pullup Comment ;0 0 In No Tristate ;0 1 in Yes Will source if pulled low ;1 0 Out No Push-Pull Zero out ;1 1 Out No Push-Pull One out ;On the development board, port A is the open header ldi TEMP,$7F ;IOOOXXXX out DDRA,TEMP ;Set port A data direction (5-59) ;Bit 7 is used for Dallas DS1820 thermometer and external WDC (DS1820.ASM) ;Bits 6,5,4 are used for the Dallas DS1602 RTC chip (DS1602.ASM) ;Bits 3,2,1,0 are used for the stepper motor (STEPPER.ASM) ;On the development board, port B is the LEDS ;Databook 5-61 ;LEDs are lit by outputting a low level ldi TEMP,$FF ;OOOOOOOO out DDRB,TEMP ;Set port B data direction (5-61) ;On the development board, port C is the open header ;Databook 5-66 ldi TEMP,$FF ;OOOOOOOO (All servo outputs) out DDRC,TEMP ;Set port C data direction (5-66) ;On the development board, port D is the buttons ;Databook 5-68 ;Buttons pressed present a LOW to the AVR ldi TEMP,$00 ;IIIIIIII out DDRD,TEMP ;Set port D data direction (5-68) out PORTD,TEMP ;De-Activate the pullups (supplied on board) ; ; ;******************************************************************* ; ;Set up the analog comparator to disabled (5-57) ; ldi TEMP,$90 ;10010000 Comparator Disabled ;1XXXXXXX Comparator disable, 1=off ;X0XXXXXX Reserved =0 ;XX0XXXXX Analog comp output ;XXX1XXXX Int flag, writing 1 clears it ;XXXX0XXX Int enable, 0=disable ;XXXXX0XX Input capture enable 0=disable ;XXXXXX00 Input mode select ; 00 = int on output toggle ; 01 = Reserved ; 10 = int on falling edge ; 11 = int on rising edge ;NOTE disable comp ints before changing XXXXXX00 out ACSR,TEMP ; ; ;******************************************************************* ; ;Set up uart (5-54) ; ldi TEMP,$D8 ;11011000 ;1XXXXXXX RX complete int enable ;X1XXXXXX TX complete int enable ;XX0XXXXX DR Empty int enable (CONSTANT INT WHILE EMPTY!) ;XXX1XXXX RX Enable ;XXXX1XXX TX Enable ;XXXXX0XX 9 bit chars 1=enable ;XXXXXX0X RX DB8 ;XXXXXXX0 TX DB8 out UCR,TEMP ; ; ;******************************************************************* ; ;Set SPI inactive (5-49) ; ldi TEMP,$1B ;00011011 ;0XXXXXXX SPI int enable 1=enable ;X0XXXXXX SPI enable 1=enable ;XX0XXXXX Data order 1=LSB first ;XXX1XXXX Master/slave 1=master ;XXXX1XXX Clock polarity 1=SCK high at idle ;XXXXX0XX Clock phase (see 5-48) ;XXXXXX11 Clock rate select ; 00 = Fcl/4 ; 01 = Fcl/16 ; 10 = Fcl/64 ; 11 = Fcl/128 out SPCR,TEMP ; ; ;******************************************************************* ; ;Set EEProm Inactive (5-44) ; ldi TEMP,$00 ;00000000 ;0XXXXXXX Reserved =0 ;X0XXXXXX Reserved =0 ;XX0XXXXX Reserved =0 ;XXX0XXXX Reserved =0 ;XXXX0XXX Reserved =0 ;XXXXX0XX Master Write enable ;XXXXXX0X Write enable ;XXXXXXX0 Read enable out EECR,TEMP ; ; ;***************************************************************** ; ;Set up the MCU Control register (5-31) ; ldi TEMP,$02 ;0XXXXXXX External Sram enable if 1 ;X0XXXXXX External Sram wait state if 1 ;XX0XXXXX Sleep Enable if 1 ;XXX0XXXX Sleep Mode ;XXXX00XX INT1 activates on: ; 00 = Low level ; 01 = Reserved ; 10 = Falling Edge ; 11 = Rising edge ;XXXXXX10 INT0 activates on: ; 01 = Reserved ; 10 = Falling Edge ; 11 = Rising edge out MCUCR,TEMP ;INT1 on low level, INT0 on falling edge ; ;******************************************************************* ; ;Set timer zero running (5-34) ;ldi TEMP,T0_DIV1024 ; ;ldi TEMP,T0_DIV256 ; ldi TEMP,T0_DIV64 ;This plus reloading T0 to 255-(T0DIV) gives us 1ms with an 8M rock ;ldi TEMP,T0_DIV8 ; ;ldi TEMP,T0_DIV1 ; out TCCR0,TEMP ;Set the prescaler ;Databook 5-35 ldi TEMP,T0DIV ;Define the reload value out TCNT0,TEMP ;Put that in T0 ; ;******************************************************************* ; ;Set timer one for servo use (5-38) ; ldi TEMP,$00 ;Disable PWM modes out TCCR1A,TEMP ;00XXXXXX Select output pin action after compare match ; 00 = Disconnected from OC1A ; 01 = Toggle OC1A ; 10 = Clear OC1A ; 11 = Set OC1A ;XX00XXXX Select output action for pin B ; 00 = Disconnected from OC1B ; 01 = Toggle OC1B ; 10 = Clear OC1B ; 11 = Set OC1B ;XXXX00XX Reserved ;XXXXXX00 PWM Select bits ; 00 = No PWM ; 01 = 8 bit PWM ; 10 = 9 bit PWM ; 11 = 10 bit PWM ldi TEMP,$00 ;0XXXXXXX Disable noise canceler out TCCR1B,TEMP ;X0XXXXXX Input capture edge 0=fall 1=rise ;XX00XXXX Reserved ;XXXX0XXX 1=clear counter on compareA match ;XXXXX000 Prescaler select ; 000 = Stop ; 001 = CK ; 010 = CK/8 ; 011 = CK/64 ; 100 = CK/256 ; 101 = CK/1024 ; 110 = External pin T1 falling edge ; 111 = External pin T1 rising edge ;******************************************************************* ; ;Go clean up the ram area. This isn't STRICTLY needed, but it makes ;debugging easier, since it loads the buffers with recognizable data. ; cli rcall Ram_Init ;Clean up the ram, and flag buffers ; ;******************************************************************* ; ;Start the timer ints, I use the "dumb" timer for system ints, and ;leaving the "smart" timer for servo control ; ;Databook 5-29 ldi TEMP,$02 ;Enable timer 0 ints out TIMSK,TEMP ; in TEMP,TIMSK ; ori TEMP,$80 ;Turn on timer 1 overflow int out TIMSK,TEMP ;for servo control ;Databook 5-23 in TEMP,SREG ; ori TEMP,$80 ;Enable global ints (for real) out SREG,TEMP ; ; ;******************************************************************* ; ;This section is not chip inits, just seeding the software PN generator ; ldi TEMP,$AA ;Init the random number generator mov RAND1,TEMP ;since a 00,00,00 state will not mov RAND2,TEMP ;progress. mov RAND3,TEMP ; ; ;******************************************************************* ; ;Initial states for RC servo control using timer 2 ; rcall Servo_Set ;Set initial widths for the servos (SERVO.ASM) ;When there's a real application running, this ;might be redundant. ldi TEMP,$01 ; sts Servo_Control,TEMP ;Set servo 0(1) active ldi TEMP,FRAME_RATE ; sts FRAME_DELAY,TEMP ;Set the frame rate delay ldi TEMP,$00 ; out PORTC,TEMP ;Set servo outputs inactive ; ; ;******************************************************************* ; ;Turn off the LEDs ; ldi TEMP,$FF ;Turn off the lights out PORTB,TEMP ; ; ; ;******************************************************************* ; ;Initial states for watchdog timer ; ldi TEMP,Dog_Chow ;Start a countdown for resetting the watchdog sts Dog_Food,TEMP ; ; ;******************************************************************* ; ;Initial states for stepper motor control ; ldi TEMP,$00 ; out PORTA,TEMP ;Turn off the stepper outputs. ldi TEMP,$00 ; sts Step_State,TEMP ;Initial state for the stepper motor ; ;Use only one direction at a time. NOTE: I am initializing to stopped, so you'll need to ;set a direction as shown below before anything is going to happen ; ldi TEMP,$01 ; sts Step_Dir,TEMP ;Set forward as default direction. ;ldi TEMP,$00 ; ;sts Step_Dir,TEMP ;Set reverse as default direction. ldi TEMP,$02 ; sts Step_Dir,TEMP ;Set stopped as default direction. ;ldi TEMP,$01 ;sts Step_Mode,TEMP ;Set half step as default mode. ;ldi TEMP,$00 ;sts Step_Mode,TEMP ;Set full step as default mode. ldi TEMP,Step_Default ;Default step rate ; sts Step_Rate,TEMP ;Establish a step rate sts Step_Time,TEMP ;and set it running ;Start the watchdog, if desired (5-43) ;Make sure that the timeout selected here is more than 1mS larger than ;the value selected for Dog_Food in EQUATES.INC ;Dog_Food = 255, timer= 256 seems to work.but beware. ;The timer as implemented could be as much as 1mS off, since events ;can begin just after a reload. ; ;ldi TEMP,$0F ;000XXXXX Reserved ;XXX0XXXX Watchdog turnoff enable ;XXXX1XXX Watchdog enable bit 1=enable ;XXXXX000 (8) Watchdog timeout, 16mS ;XXXXX001 (9) Watchdog timeout. 32mS ;XXXXX010 (A) Watchdog timeout. 64mS ;XXXXX011 (B) Watchdog timeout. 128mS ;XXXXX100 (C) Watchdog timeout, 256mS ;XXXXX101 (D) Watchdog timeout, 512mS ;XXXXX110 (E) Watchdog timeout,1024mS ;XXXXX111 (F) Watchdog timeout,2048mS ;out WDTCR,TEMP ; ; ;******************************************************************* ; ;DS1820 initialization ldi TEMP,$00 ;Just init it and show it's not currently in use. sts TEMP_FLAG,TEMP ; sts TEMP_STAT,TEMP ; rcall RESET_1820 ;Initialize the sensor rcall Get_Serno ;You really shouldn't need to do this more than once. ; ;******************************************************************* ; ;DS1602 initialization rcall Clear_Etime ;Clear the non-battery-backed counter ;rcall Clear_Rtime ;Optionally, clear the battery-backed counter as well ; ; ;******************************************************************* ; ;Serial comms initialization rcall Init_Buffers ;Make the buffers empty ;98.07.27 Added this to initialize the HS status before ;enabling int driven comms. Note that we do not SEND xon ;here, just establishing a known state. ;This MUST be done prior to enabling int driven comms ; ldi TEMP,$FF ;Set serial input state to XON sts HS_FLAG,TEMP ; ldi TEMP,$00 ;Set the inter-char timer to zero sts Char_Delay,TEMP ; rcall Set_Baud_9600 ;Or something else if you prefer (SERIAL.ASM) in TEMP,UCR ;Enable TX and RX ints ori TEMP,$C0 ; out UCR,TEMP ; ;Say howdy! ldi ZL,low (Signon_Message*2) ;Point at a signon message (in TABLES.ASM) ldi ZH,high (Signon_Message*2) ; rcall String_Serout ;Send it to the serial output buffer rjmp IDLE