;ToDo's ; ; add timeouts to state engines ; fix slave timeout ; ; .nolist .include "c:\avrtools\appnotes\8515def.inc" .list ;------ PortB Defines ---------------------------------------- .equ db0 = 0 ;display data 0 .equ db1 = 1 ;display data 1 .equ db2 = 2 ;display data 2 .equ db3 = 3 ;display data 3 .equ rs = 4 ;display register select .equ display = 6 ;display enable ;------ PortD Defines ---------------------------------------- .equ RunButton = 2 ;run button .equ ModeButton = 3 ;mode button .equ RangeOut = 4 ;Output from rover scanner .equ RangeIn = 5 ;Input to rover scanner ;------ PortC Defines ---------------------------------------- .equ RangeOutf = 6 ;Output from fixed scanner .equ RangeInf = 7 ;Input to fixed scanner ;------ Macros for Port control ------------------------------ .macro EnableScanner cbi portd,RangeIn .endm .macro DisableScanner sbi portd,RangeIn .endm .macro EnableScannerf cbi portc,RangeInf .endm .macro DisableScannerf sbi portc,RangeInf .endm .macro ToggleDisplay sbi portb,display cbi portb,display .endm ;------ Command Constants ----------------------------------- .equ cmdForward = 0x01 ;Both drive motors go forward, (upper nibble is tick count) .equ cmdBackward = 0x22 ;Both drive motors go backward .equ cmdLeft = 0x33 ;Right motor forward, left motor stopped .equ cmdRight = 0x44 ;Left motor forward, right motor stopped .equ cmdJogLeft = 0x55 ;Slight turn to left, for course adjustment .equ cmdJogRight = 0x66 ;Slight turn to right, for course adjustment .equ cmdSpinLeft = 0x77 ;Right motor forward, left motor backwards .equ cmdSpinRight = 0x88 ;Left motor forward, right motor backwards .equ cmdVictory = 0x99 ;spin continously .equ cmdStop = 0xAA ;Both motors stop .equ cmdGetStatus = 0xBB ;Return 8535 sensor status .equ cmdGetEncoders = 0xCC ;Return encoder counts .equ cmdVictoryShake = 0xDD ;Do a little dance .equ cmdSleep = 0xEE ;put slave to sleep so we can talk to PC .equ cmdLogWall = 0xA5 ;used by logging routines .equ cmdDump = 0x8A ;slave dumps memory to PC .equ cmdGreenLed = 0x5A ;tell the slave to turn on the green led ;------ Position Constants for IR scanner ------------------- .equ pLeft = 0 .equ pCenter = 1 .equ pRight = 2 .equ ServoDefaultLeft = 0xbb ;these are the actual PWM values .equ ServoDefaultCenter = 0xd8 ;that would get loaded into the .equ ServoDefaultRight = 0xf5 ;timer to position the servo ;------ Mode Constants -------------------------------------- .equ mLeftNoFloor = 0b00000000 ;left wall with no floor sensors .equ mLeftSimpleNF = 0b00000001 ;Left wall with simple turns, no floor sensors .equ mLeft = 0b00000010 ;follow left wall .equ mLeftSimpleTurn = 0b00000011 ;Left wall with simple turn routines .equ mRightNoFloor = 0b00000100 ;Right wall with no floor sensors .equ mRightSimpleNF = 0b00000101 ;Right wall with simple turns, no floor sensors .equ mRight = 0b00000110 ;follow right wall .equ mRightSimpleTurn = 0b00000111 ;Right wall with simple turn routines ; |||----- 1 = use plain turns ; ||------ 1 = use floor sensor ; |------- 1 = right turn .equ mDiagnostic = 8 ;display diagnostic information .equ mServoCal = 9 ;calibrate the scanner servo .equ mScanner = 10 ;run the scanner and servo .equ mDump = 11 ;send data to PC .equ mSlaveDump = 12 ;slave send data to pc .equ mSpinTest = 13 ;do 4 90 degree spins .equ mTurnTest = 14 ;do a 90 degree turn .equ mLastMode = 15 ;last mode constant ;------ Mode Bits --------------------------------------- .equ mPlainTurns = 0 ;Use plain turns .equ mFloorSensor = 1 ;Use the floor sensors .equ mRightTurn = 2 ;Using right wall turns ;------ Flag Bits --------------------------------------- .equ Tick = 0 ;Timer Tick bit .equ StatusTick = 1 ;Timer Tick for GetStatus routines .equ ServoTick = 2 ;timer tick for moving servo .equ Running = 3 ;Running mode .equ Scanning = 4 ;IR scan in progress .equ Logging = 5 ;enable logging ;------ Valid Bits --------------------------------------- .equ ValidStatus = 0 ;Status block is valid .equ ValidFixed = 1 ;Fixed scan is valid .equ ValidRover = 2 ;Roving scan is valid .equ ValidWall = 3 ;Wall distance has been stored ;------ GetStatus States -------------------------------- .equ gsNone = 0 .equ gsWaiting = 1 .equ gsRequested = 2 .equ gsReceived = 3 ;------ Servo/Scanner States ---------------------------- .equ svNone = 0 .equ svScanningRover = 1 .equ svRoverReady = 2 .equ svScanningFixed = 3 .equ svFixedReady = 4 ;------ Register Defines -------------------------------- .def LPMReg = r0 ;used with LPM in DisplayRom .def ISRTimer0 = r1 ;used in timer0 ISR .def ISRDelay = r2 ;used in Delay routine .def ISRUart = r3 ;used in Uart ISR .def MyLoop = r4 ;loop counter .def UartTemp = r5 ;used in Uart ISR .def ScanValue = r6 ;IR scanner reading .def WallValue = r7 ;Stored distance to wall .def Test = r8 ;timer for steering adjustments .def Acc = r16 ;used as accumulator .def Mode = r17 ;running mode .def ScanPos = r18 ;scanner position .def Status = r19 ;current GetStatus state .def StatusTimer = r20 ;counts ticks for timing .def Servo = r21 ;current servo/sensor status .def ServoTimer = r22 ;counts ticks for timing .def Flags = r23 ;Flag bits .def Valid = r24 ;Valid status bits .def ScanAdjustDelay = r25 ;timer for steering adjustments ; r26 ;X register used for servo cal and scan storage .def Yptr = r28 ;Y register used to store status block ; r30 ;Z register used for IJMPs ;------ Ram Defines ------------------------------------- .equ StatusBlock = 0x60 ;begining of status block .equ sbBumper = 0x60 ;bumper status/busy flag .equ sbBattery = 0x61 ;battery voltage .equ sbFfloor = 0x62 ;front floor sensor .equ sbRfloor = 0x63 ;rear floor sensor .equ sbCheckSum = 0x64 ;checksum .equ RangeReadings = 0x65 ;IR scanner readings go here .equ RangeRover = 0x65 ;rover reading .equ RangeFixed = 0x66 ;fixed reading .equ ServoLeft = 0x67 ;value to position servo to left .equ ServoCenter = 0x68 ;value to position servo to center .equ ServoRight = 0x69 ;value to position servo to right .equ EncoderBlock = 0x6A ;encoder block storage .equ DataBuffer = 0x6E ;store data from here to 0x200 ;------ Display Constants ----------------------------------- .equ c_Clr = 0x01 ;clear display .equ c_CursorLeft = 0x10 ;move cursor left .equ c_CursorRight = 0x14 ;move cursor right .equ c_Goto = 0x80 ;data ram control .equ c_Cgen = 0x40 ;Character Generator ram .equ c_Line2 = 0x40 ;start address of line 2 .equ c_Line3 = 0x14 ;start address of line 3 .equ c_Line4 = 0x54 ;start address of line 4 .equ f_Set = 0x20 ;Function Commands .equ f_1line = 0x00 ;1 line mode .equ f_2line = 0x08 ;2 line mode .equ f_8font = 0x00 ;5x8 font .equ f_11font = 0x04 ;5x11 font .equ d_Set = 0x08 ;Display Control .equ d_DisplayOn = 0x04 ;Display on .equ d_DisplayOff = 0x00 ;Display off .equ d_CursorOn = 0x02 ;Cursor on .equ d_CursorOff = 0x00 ;Cursor off .equ d_BlinkOn = 0x01 ;Blink on .equ d_BlinkOff = 0x00 ;Blink off .equ e_Set = 0x04 ;Entry mode control .equ e_CursorRight = 0x02 ;cursor moves right .equ e_CursorLeft = 0x00 ;cursor moves left .equ e_NoShift = 0x00 ;cursor doesn't shift .equ e_Shift = 0x01 ;cursor shifts ;------ Interrupt Vector Table -------------------------- .cseg ;start code segment .org 0 rjmp Start ;reset vector reti ;irq0 reti ;irq1 reti ;timer1 capture reti ;timer1 compareA reti ;timer1 compareB reti ;timer1 overflow rjmp Timer0 ;timer0 overflow reti ;SPI transfer complete rjmp Uart0 ;uart rx complete reti ;udr empty reti ;uart tx complete reti ;analog compare ;**************************************************************** ; MainJumpTable - Jump table for the main routines * ;**************************************************************** MainJumpTable: rjmp ModeLeft ;left wall, no floor rjmp ModeLeft ;left wall, Simple turns, no floor rjmp ModeLeft ;use left wall routine rjmp ModeLeft ;left wall, Simple turns rjmp ModeRight ;Right wall, no floor rjmp ModeRight ;Right wall, Simple turns, no floor rjmp ModeRight ;use right wall routine rjmp ModeRight ;Right wall, Simple turns rjmp ModeDiagnostic ;use the diagnostic routine rjmp ModeServoCal ;calibrate the scanner servo rjmp ModeScanner ;run the scanner and servo rjmp ModeDump ;send data to PC rjmp ModeSlaveDump ;slave sends data to pc rjmp ModeSpinTest ;do spin testing rjmp ModeTurnTest ;do turn test ;**************************************************************** ; Timer0 - Timer Interrupt Service Routine * ; Entry occurs every 4ms * ;**************************************************************** Timer0: in ISRTimer0,sreg ;save status register sbr Flags,0b00000111 ;set tick flags inc ScanAdjustDelay ;controls adjustment delay out sreg,ISRTimer0 ;restore status register reti ;**************************************************************** ; Uart0 - Uart receiver Interrupt Service Routine * ;**************************************************************** Uart0: in ISRUart,sreg ;save status register in UartTemp,udr ;get the data cpi Status,gsRequested ;Are we expecting status info brne Uart10 ;if not then skip to end st y+,UartTemp ;save data to sram sbrc yl,2 ;test for end of status block ldi Status,gsReceived ;set the status to received Uart10: out sreg,ISRUart ;restore status register reti ;**************************************************************** ; Start - Start of code * ;**************************************************************** Start: ldi r16,0x00 ;porta 7-0 are inputs out ddra,r16 ldi r16,0x00 ;start 7-0 as inputs out ddrb,r16 ldi r16,0xbf ;portc 7,5-0 are outputs out ddrc,r16 ;portc 6 is input ldi r16,0xe0 ;portd 7-5 are outputs out ddrd,r16 ;portd 4-0 are inputs ldi r16,0xff out portc,r16 ldi r16,0xff out portd,r16 ;need RangeIn bits high sbis pind,ModeButton ;test the mode button and jump into rjmp BeSlave ;slave mode if pressed ;otherwise enable the display port ldi r16,0xff ;portb 7-0 are outputs out ddrb,r16 ldi r16,0xbf ;drive display lo out portb,r16 ldi r16,low(RAMEND) ;load the stack pointer out SPL,r16 ldi r16,high(RAMEND) out SPH,r16 ldi r16,0x03 ;timer0 uses ck/64 out tccr0,r16 ldi r16,0b00110011 ;disconnect OC1A, OC1B high, 10-bit PWM out tccr1a,r16 ldi r16,0x03 ;CK / 64 out tccr1b,r16 ldi r16,3 out ocr1bh,r16 ;start with servo centered (1.5ms) ldi r16,ServoDefaultCenter out ocr1bl,r16 ldi r16,12 out ubrr,r16 ;set baudrate to 19.2K ldi r16,0b10011000 out ucr,r16 ;enable uart ldi yl,low(StatusBlock) ;point Y register to status block ldi yh,high(StatusBlock) ldi r16,ServoDefaultLeft ;load the default PWM servo values sts ServoLeft,r16 ldi r16,ServoDefaultCenter sts ServoCenter,r16 ldi r16,ServoDefaultRight sts ServoRight,r16 clr Flags ;turn off all flags clr Valid ;clear all flags ldi Status,gsNone ;no GetStatus operation in process ldi Servo,svNone ;no servo operation in process ldi Mode,mLeftNoFloor ;start using the first mode ldi ScanPos,pCenter ;center scanner servo ldi r16,0b00000010 out timsk,r16 ;enable timer0 interrupt sei ;enable interrupts rcall InitDisplay ;start display MainStart: rcall ClearDisplay rcall DisplayRom .db "MasterMazer 1.8",0 rcall DisplayMode ;display the new mode MainLoop: rcall DoStatus ;talk to the slave card rcall TestBattery ;see what the battery looks like sbis pind,ModeButton ;test mode button rjmp ModeButtonPressed ;jump if pressed sbic pind,RunButton ;test run button rjmp MainLoop ;jump if button not pressed rcall WaitOnButtonRelease sbr Flags,1<