;*************************************************************************** ; ; File Name :'EQUATES.INC" ; Title : ; Date : ; Version : ; Support telephone :765 287 1987 David B. VanHorn ; Support fax :765 287 1989 ; Support Email :dvanhorn@cedar.net ; Target MCU :AT90S8515 ; ; DESCRIPTION ; ; DEFINITIONS ; ; ;***************************************************************************; ; 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.06.22 dvh Began life as a separate file ; 0.02 98.08.20 dvh Added servo support ; 0.03 98.08.21 dvh Added FRAME_RATE to initialize FRAME_DELAY for ; SERVO.ASM and INT.ASM ; Changed Frame_Delay to SRAM rather than register ; 0.04 98.08.30 dvh Added Watchdog timer support ; ;******************************************************************** ;HUGE WARNING! If the "device" line is left uncommented, the assembler ;will catch unimplemented opcodes, but it will NOT generate a hex file! ;Leave this on (uncommented) until things are assembling well, then turn ;it off for making a chip. If things stop working mysteriously, then turn ;the device directive back on, and you'll probably find that you CALLed a ;routine, rather than RCALLing it. ;******************************************************************** ;.DEVICE AT90S8515 ; .include "8515def.inc" ;Atmel supplied file that is a standard list of ; ;equates for on-chip peripherals and such ;******************************************************************** ;Universal Truths ; .dseg ;This tells the assembler that what follows is data, not code ; .equ TRUE =0FFh ;Yes .equ FALSE =00h ;No ; ;******************************************************************** ;Revision perversion ; ;It's lame, but you can't use "0" or "1", you have to specify in hex ;if you want to put it in a message like this: ;VERSION: .db "FIRMWARE VERSION ",MAJOR_REV,".","MINOR_REV","MINOR_REVB",CR,LF ; .equ MAJOR_REV =$30 ;Zero .equ MINOR_REV =$31 ;One .equ MINOR_REVB =$32 ;Two ; ;******************************************************************** ;Timer setup. ;No storage needed, this just calculates a value for the timer based on ;the desired sample rate and the clock frequency, with constants for the ;internal chip prescalers and dividers. ; .equ XTAL =8000000;in Hz .equ T0_DIV1 =$01 ; .equ T0_DIV8 =$02 ; .equ T0_DIV64 =$03 ; .equ T0_DIV256 =$04 ; .equ T0_DIV1024 =$05 ; .equ T0DIV =(255-127) ;Make for even MS! 1% error ; ;******************************************************************** ; ;ASCII Equivalents ; .equ NUL=$00 ;Null .equ SOH=$01 ;Start of Header .equ STX=$02 ;Start of Text .equ ETX=$03 ;End of Text .equ EOT=$04 ;End of Transmission .equ ENQ=$05 ;Enquiry .equ ACK=$06 ;Acknowlege .equ BEL=$07 ;Bell .equ BS=$08 ;Backspace .equ HT=$09 ;Horizontal Tab .equ LF=$0A ;Line Feed .equ VT=$0B ;Vertical Tab .equ FF=$0C ;Form Feed .equ CR=$0D ;Carriage Return .equ SO=$0E ; .equ SI=$0F ; .equ DLE=$10 ;Delete .equ XON=$11 ;AKA DC1 .equ XOFF=$12 ;AKA DC2 .equ DC3=$13 ; .equ DC4=$14 ; .equ NAK=$15 ;Negative Acknowlege .equ SYN=$16 ;Sync .equ ETB=$17 ; .equ CAN=$18 ;Cancel .equ EM=$19 ; .equ SUB=$1A ; .equ ESC=$1B ; .equ FS=$1C ;Field Separator .equ GS=$1D ;Group Separator .equ RS=$1E ;Record Separator .equ US=$1F ; ; ;******************************************************************** ; ;Register equates ; ;All registers below 16 are the "cheap seats". It takes a little ;more to move data around in them. Registers 16 and up are faster ;to work with, plus 26-31 have special uses. R0 does as well, but ;it's only used in pulling from tables, and we can push it. ; ;Even though it looks like most of the registers are "eaten up", ;there's really plenty left. If you get desperate, try moving things ;to SRAM locations (penalty of an LDS and maybe STS to use them) ;IMHO, the ISR's should be as fast as possible, so I dedicate registers ;to them. You could push and pop, or use SRAM with the additional time penalty. ; .def EPROM_DATA =R0 ;Reserve this for LPM accesses (not STRICTLY necessary) .def RAND1 =R1 ;Random number generator needs three .def RAND2 =R2 ;bytes. This could just as well be .def RAND3 =R3 ;SRAM, but it would be a little slower .def UD04 =R4 ; .def UD05 =R5 ; .def UD06 =R6 ; .def UD07 =R7 ; .def UD08 =R8 ;The cheap seats. Use these where possible, .def UD09 =R9 ;once the code is working with high regs, convert .def UD10 =R10 ;to low regs if workable. Costs 1 extra instr to set. .def UD11 =R11 ; .def UD12 =R12 ; .def LOOP =R13 ;Loop counter, local usage only. .def SPIBUFL =R14 ;SPI communication buffer for 16 bit conversation .def SPIBUFH =R15 ;to SPI peripherals .def TEMP =R16 ;The temps can't be in the cheap seats, because .def TEMP2 =R17 ;they are used in ISRs where 100s of nS count. .def TEMP3 =R18 ; .def TTEMP =R19 ;These two temps are used solely by ISRs so they don't .def TTEMP2 =R20 ;have to push and pop so much. .def TEMP4 =R21 ;These are still open and available .def TEMP5 =R22 ; .def TEMP6 =R23 ; .def TEMP7 =R24 ; .def UD25 =R25 ; ; .def XL =R26 ;These are used by the buffer managers, they're .def XH =R27 ;mostly listed here so I don't forget .def YL =R28 ; .def YH =R29 ; .def ZL =R30 ; .def ZH =R31 ; ; ;R26,27 R28,29 and R30,31 are pointers ;******************************************************************** ; ;Ram buffers ;Everything after this resides in specified locations in RAM. ; .org 0x60 ;The beginning of RAM (Since we are in a DSEG) ; ;******************************************************************** ;Dallas DS1602 RTC chip buffer (DS1602.ASM) ; .equ RTC_SIZE=8 ; RTC_BUF: .byte RTC_SIZE ; ;******************************************************************** ;Dallas DS1820 RTC chip buffer (DS1820.ASM) ; .equ TEMP_SIZE=9 .equ SERNO_SIZE=8 SERNO_BUF: .byte SERNO_SIZE ;Serial number returned by GET_SERNO TEMP_BUF: .byte TEMP_SIZE ;Temperature data TEMP_STAT: .byte 1 ;Sensor Status, 00-OK, FF-Bad TEMP_FLAG: .byte 1 ;Conversion progress flag FF=Started, 01=Done, 00=Not in use ;******************************************************************** ; ;Communication buffers, DTMF and Serial, and the tail pointers ;for each. The head pointer is the buffer address. ; ;Serial Buffer Constants ; .equ SER_SIZE=40 ;Size of serial I/O buffers .equ SERin_Size=SER_SIZE ;I made them equal, but you might not. .equ SERout_Size=SER_SIZE ; .equ SER_DLY=2 ;Inter-Charachter delay in Milliseconds ; SERIAL_IN_BUF: .byte Serin_Size ;Size defined above SERIAL_IN_TAIL: .byte 2 ;Tail pointer SERIAL_OUT_BUF: .byte Serout_SIZE ; SERIAL_OUT_TAIL:.byte 2 ;Tail pointer Watch_Char: .byte 1 ;Char to watch for Char_Time: .byte 1 ;How long to watch for it in mS, dec'd by TO ISR Char_Delay: .byte 1 ;Delay between chars, in mS dec'd by TO ISR HS_FLAG: .byte 1 ;00 or FF depending on Xon/Xoff state ; ;******************************************************************** ; ;Step motor control support. ; Step_Dir: .byte 1 ;Flag, Forward or reverse direction? Step_Time: .byte 1 ;Is it time to step? Step_State: .byte 1 ;Where are we now? Step_Mode: .byte 1 ;Flag, Full or half step? Step_Rate: .byte 1 ;mS per step .equ Step_Default = 50 ;mS per step (used only in INIT.ASM) ; ;******************************************************************** ;Morse variables SUBSEC: .byte 1 ;Decremented by the opsys counter. SUBSECA: .byte 1 ; MORSE: .byte 1 ;The char to send in ASCII DBT: .byte 1 ;Temp storage for some di-bits. DBH: .byte 1 ;Di-bit high DBL: .byte 1 ;di-bit low BEEPFLAG: .byte 1 ;Are we beeping? are we beeping? brother john brother john SPEED: .byte 1 ;speed, in WPM or something. ; ;******************************************************************** ; Dog_Food: .byte 1 ;A place to store dog food .equ Dog_Chow = 251 ;How many mS between feedings. ; ;**************************************************************; ;R/C Servo control bytes, load each byte with a value 0-255 corresponding to ;ccw - cw rotation position. ; SERVO_1: .byte 1 ;Servo width value SERVO_2: .byte 1 ;Servo width value SERVO_3: .byte 1 ;Servo width value SERVO_4: .byte 1 ;Servo width value SERVO_5: .byte 1 ;Servo width value SERVO_6: .byte 1 ;Servo width value SERVO_7: .byte 1 ;Servo width value SERVO_8: .byte 1 ;Servo width value Servo_Control: .byte 1 ;Servo active flags, always only one bit on, maybe none Frame_Delay: .byte 1 ;Servo frame delay counter, decremented by T1OVF interrupt ; ;Derive Servo_Base from Xtal and the structure of the servo control routines such that ;a SERVO_X value of 0 gives one end of rotation, and 255 gives the other. .equ T1Divisor = 1 ;Fixed in the servo routine ;So, we have a T1CR rate of 8MHz, and we'd like to have something that ;will result in an appropriate minimum pulse if SERVO_X = 0 ; ;This handles the different brands of servos, which require slightly different ;pulse widths to achieve the same travel range ;Just enter the time for minimum position, and max position, in uS, and we'll take ;care of the rest. .equ Futaba_Min = 1000 ;Microseconds for minimum position .equ Futaba_Max = 2000 ;Microseconds for maximum position .equ Futaba_Range = (Futaba_Max - Futaba_Min) .equ Cirrus_Min = 400 ;Microseconds for minimum position .equ Cirrus_Max = 2000 ;Microseconds for maximum position .equ Cirrus_Range = (Cirrus_Max - Cirrus_Min) ; .equ Fmin = (65535 - (Futaba_Min * 8)) .equ Cmin = (65535 - (Cirrus_Min * 8)) .equ Frange = (Futaba_Range * 8) .equ Crange = (Cirrus_Range * 8) ; ;Assign these as you populate your servos. ;This sets the min and max pulse widths, in uS for each servo. The servo position is ;then given for any servo by (Brand_Range / 256) * Position_Byte) ; .equ Servo_1_Min = Fmin .equ Servo_1_Range = Frange .equ Servo_2_Min = Cmin .equ Servo_2_Range = Crange .equ Servo_3_Min = Fmin .equ Servo_3_Range = Frange .equ Servo_4_Min = Fmin .equ Servo_4_Range = Frange .equ Servo_5_Min = Fmin .equ Servo_5_Range = Frange .equ Servo_6_Min = Fmin .equ Servo_6_Range = Frange .equ Servo_7_Min = Fmin .equ Servo_7_Range = Frange .equ Servo_8_Min = Fmin .equ Servo_8_Range = Frange ;Within reason then, you can change the XTAL, enter the new value at the top of ;this file, and the servo widths will be very close, or dead on. Staying with nice ;evenly divisible xtals will help. 1,2,4,8 mhz.. 7.312435 could be ugly. ; ; .equ FRAME_RATE = 10 ;Milliseconds between servo pulse bursts dec'd by TO ISR ; ;An interesting note on FRAME_RATE. With my servos, I found that 20mS gave rather ;sluggish performance, ; ;255mS is quite interesting, the servo seeks in a series of bursts, coming to a ;complete stop, but still driven to position on each pulse. It appears though, that ;it's force twoard position fades away with time, rather than abruptly stopping. ; ;50mS is "steppy" it feels and acts like a very coarse stepper motor, ;20mS is the "standard" frame rate, but it still acts rather sluggish. ;15mS was a lot like 20, ;12mS is very snappy! ;10mS was MUCH snappier, ;1mS made no noticable difference from 10. ; ; Apparently, if the FRAME_RATE is too slow, the servo comes to a stop between ;pulses and has to be re-accelerated? That would account for the slowdown. ;It also appears that the ideal FRAME_RATE for performance is a threshold thing. ;Start it off at 20 and decrease until you have problems, or you have a ;noticable pickup in performance. ; ;The width of the drive pulses from the servo electronics to the motor gets narrower ;as the servo approaches the programmed position.. Hmm.. :) ;