/* robomon.Asm Copyright ©1998, 1999 Larry Barello Author: Larry Barello lbarello@accessone.com You are allowed to use this file for personal use only. You may use, embed, modify or distribute the contents of this file in any way you see fit as long as you include this copyright notice in the resulting file. Any commercial or industrial use including publishing or distributing in any form requires the written authorization of the copyright holder(s). No guarantees are made about fitness, functionality, correctness or performance of this file. The file is supplied on a "AS IS" basis, with no responsibility assumed by the author(s) for bug fixes, support, or damages of any sort arising from the use of this file. Contact the author with problem reports or fixes, feature requests or additions and questions. They are welcomed and will be incorporated as time and energy permits. */ #include "Registers.inc" #include "AvrX.inc" #include "MotorControl.inc" NAME ROBOMON EXTERN LightSeekTcb LightSeekPid EXTERN AnalogConversion ADTaskTcb EXTERN Init_Encoder INT0_Interrupt INT1_Interrupt EXTERN MonitorPid MonitorTcb MonitorEntry MonitorStack EXTERN SmallContextSize SmallContext EXTERN MotorCtlTcb LeftMotor RightMotor EXTERN LCDTaskTcb EXTERN AvrXRunTask AvrXInitTask AvrXSetSemaphore EXTERN AvrXResume AvrXSuspend Clear_Ram Clear_Registers EXTERN _IntProlog _Epilog AvrXTimerHandler EEPromMutex EXTERN _GetChar PutChar RxC_Interrupt _PrintString PushChar EXTERN PutHexWord PutHexByte GetHexWord GetHexByte EXTERN PutCR PutSpace IsWhite InitSerialIO UDRE_Interrupt PUBLIC TICKRATE CPUCLK TCNT0_INIT AvrXStack RoboSpin ; ; This file contains the hardware definitions and the code to ; boot the MPU after a harware reset. ; ; Hardware Equates ; CPUCLK = 7372800 ;CPUCLK = 8000000 TICKRATE = 2400 ; Nice number for 60 hz TCCR0_INIT = CLK256 TCNT0_INIT = 256-(CPUCLK/256)/TICKRATE LeftFlag = 1 RightFlag = 2 RSEG AVRXDATA:DATA(0) ;+++++++++++++++++++++++++++++++++++++++++++++++ ; Process ID blocks ; ; ; RSEG DATA AvrXStack: = RAMEND ;------------------------------------------------ ; Interrupt Vector Table ; RSEG INTVECT ORG 0 rjmp CPU_Reset ORG INT0addr rjmp INT0_Interrupt ORG INT1addr rjmp INT1_Interrupt ORG ICP1addr ORG OC1Aaddr ORG OC1Baddr ORG OVF1addr rjmp OVF1_Interrupt ; A/D Capture value ORG OVF0addr rjmp OVF0_Interrupt ; System Clock ORG SPIaddr ORG URXCaddr rjmp RxC_Interrupt ORG UDREaddr rjmp UDRE_Interrupt ORG UTXCaddr ORG ACIaddr RSEG CODE ;---------------------------------------------- ; OVF0_Interrupt ; ; Reload counter then jmp to AvrX_TimerInterrupt ; every millisecond. ; OVF0_Interrupt: BeginInterrupt rcall _IntProlog ldi R30, TCNT0_INIT ; Reload timer out TCNT0, R30 rcall AvrXTimerHandler rjmp _Epilog ;---------------------------------------------- ; OVF1_Interrupt ; ; Pulse Width Modulation overflow interrupt. ; ; Interrupts every 512 cycles. Drive the Analog conversion ; ; OVF1_Interrupt: BeginInterrupt rcall _IntProlog ; Switch to kernel stack rcall AnalogConversion ; Run conversion rjmp _Epilog ;----------------------------------------------- ; CPU_Reset ; ; Does whatever ; ; CPU_Reset: ldi Zl, low(RAMEND) ; System stack at end of RAM (small) ldi Zh, high(RAMEND) out SPl, Zl out SPh, Zh rcall Clear_Ram rcall Clear_Registers ldi Zl, low(MotorCtlTcb) ; Initalize each of our task structures ldi Zh, high(MotorCtlTcb) rcall AvrXRunTask ; ldi Zl, low(MonitorTcb) ; ldi Zh, high(MonitorTcb) ldi Zl, low(RoboMonitorTcb) ldi Zh, high(RoboMonitorTcb) rcall AvrXRunTask ldi Zl, low(ADTaskTcb) ldi Zh, high(ADTaskTcb) rcall AvrXRunTask ldi Zl, low(LCDTaskTcb) ldi Zh, high(LCDTaskTcb) rcall AvrXRunTask ldi Zl, low(LightSeekTcb) ldi Zh, high(LightSeekTcb) rcall AvrXInitTask ; ; Set Sleep mode ; ldi Zl, 1<>1 DB MonitorPid, SmallContextSize DW SmallContext>>1 DB 0x00 ; Priority EVEN Robo_Mon_Entry: ldi Zl, low(robo_hello) ldi Zh, high(robo_hello) rcall _PrintString Robo_Monitor: rcall Robo_Prompt rcall _GetChar clr R0 cpi RxByte, 'm' breq rm_move cpi RxByte, 'l' breq rm_turnleft cpi RxByte, 'r' breq rm_turnright cpi RxByte, 's' breq rm_spin cpi RxByte, 'd' breq rm_debug cpi RxByte, 'i' breq rm_LightSeekoff cpi RxByte, 'o' breq rm_LightSeekon cpi RxByte, 'b' breq rm_reboot cpi RxByte, 'a' breq rm_SetAcceleration cpi RxByte, 'v' breq rm_SetVelocity cpi RxByte, 'p' breq rm_SetPosition cpi RxByte, '?' breq Robo_Mon_Entry rm_err: ldi TxByte, '?' rcall PutChar rjmp Robo_Monitor rm_reboot: BeginCritical rjmp CPU_Reset rm_move: rcall GetSignedHexWord rcall AddToRightMotor rcall AddToLeftMotor rjmp Robo_Monitor rm_turnright: rcall GetSignedHexWord rcall AddToLeftMotor rjmp Robo_Monitor rm_turnleft: rcall GetSignedHexWord rcall AddToRightMotor rjmp Robo_Monitor rm_spin: rcall GetSignedHexWord rcall RoboSpin rjmp Robo_Monitor rm_debug: rcall MonitorEntry rjmp Robo_Monitor rm_LightSeekon: ldi Zl, low(LightSeekPid) rcall AvrXResume rjmp Robo_Monitor rm_LightSeekoff: ldi Zl, low(LightSeekPid) rcall AvrXSuspend rjmp Robo_Monitor RoboSpin: rcall AddToLeftMotor com Yl com Yh adiw Yl, 1 rjmp AddToRightMotor rm_SetAcceleration: rcall GetLeftRightFlag rcall GetHexWord ldi Wl, AccelSetPoint rcall SaveIndirect rjmp Robo_Monitor rm_SetVelocity: rcall GetLeftRightFlag rcall GetHexWord ldi Wl, VelocitySetPoint rcall SaveIndirect rjmp Robo_Monitor rm_SetPosition: rcall GetLeftRightFlag rcall GetHexWord ldi Wl, PositionSetPoint+2 rcall SaveIndirect clr Yl sbrc Yh, 7 com Yl mov Yh, Yl ; Sign Extend and save upper word ldi Wl, PositionSetPoint rcall SaveIndirect rjmp Robo_Monitor GetLeftRightFlag: ldi Xl, 1<