MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 1 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00001 ;;; 00002 ;;; 2000 Bike-trip microcontroller code 00003 ;;; 00004 ;;; -- Jorj Bauer 00005 ;;; 00006 ;;; This code is in the public domain. Feel free to use it for anything you like. I make no 00007 ;;; warantees or guarantees as to its fitness for any specific purpose, yadda yadda yadda, 00008 ;;; will not be held responsible for any consequences, whatever. 00009 ;;; 00010 ;;; Version 0.1 (2/4/00): takes the picture, but doesn't end properly. Some quick notes: 00011 ;;; - the parallel port inverts several lines in hardware (C0, C1, C3, and S7). I'm inverting 00012 ;;; these in software, and the notes about "inverting C013" refer to this. 00013 ;;; - we probably don't need to set all of the control lines everywhere. C1, for example, isn't 00014 ;;; really used and could be tied (low, I think). 00015 ;;; - the picture is a little streaky in this version. I'm assuming that's a hardware problem, 00016 ;;; not a software problem. 00017 ;;; 00018 ;;; Version 0.2 (2/11/00): should now guess the brightness before taking the picture (by 00019 ;;; taking several small pictures first). 00020 ;;; - The problem with the picture streakiness isn't the wiring (running through the 00021 ;;; parallel port to a real PC doesn't suffer from any quality problems). This means 00022 ;;; it's either software in the PIC, software in the picture re-correction, or the 00023 ;;; breadboard. The last option is unlikely, since I've moved to another breadboard 00024 ;;; (purely for portability) and the picture problems are exactly the same (the exact same 00025 ;;; streaks show up in the same places). 00026 ;;; - Multiple sizes and bit depths are now supported. The picture-taking code ends 00027 ;;; correctly for all picture sizes. 00028 ;;; - I've started putting in color quickcam support. Color quickcams have a couple of 00029 ;;; differences from their B&W cousins. They scan in 24bpp mode, for starters, which means 00030 ;;; the loop counters will have to be much larger. (I haven't touched them yet.) While 00031 ;;; waiting for a scan to begin, the camera sends 0x7E data bytes which should be ignored. 00032 ;;; (This is done.) The camera sends three extra bytes at the end of a scan: 0xE, 0x0, and 00033 ;;; 0xF (to signify the end of the scan). I'm now reading these bytes, but ignoring the 00034 ;;; values. (This may also work for B&W qcams; I'm not sure yet.) The mode numbers for 00035 ;;; size and bit depth are probably different; I haven't looked at them yet (which is why I 00036 ;;; haven't started changing the counters). 00037 ;;; 00038 ;;; Version 0.4 (04/08/00): should now talk to the GPS, and spit data out the serial port. 00039 ;;; - Canned the relay idea. I realized that last year, I also sent tracking data from the 00040 ;;; GPS to the web site; this would be impossible to buffer (as it tends to be gigantic). 00041 ;;; Instead, I'm using a bit-banging serial interface on port C (which is also the parallel 00042 ;;; control port). As a result, we can't specifically set port C to any value; the 00043 ;;; individual bits need to be toggled. 00044 ;;; - Hardware handshaking is new to this version. The GPS and modem will need to talk to 00045 ;;; eachother, and we need to prevent data overrun to the modem. Port E is used for 00046 ;;; the hardware flow control lines to the phone. (The GPS has no flow control capability.) 00047 00048 00049 LIST p=17C43 00050 00051 #include "const.i" 00001 ;;; 00002 ;;; const.i: constant definitions. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 2 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00003 ;;; 00004 00005 ;;; Clock (oscillator) frequency. Used to derrive communications timings. 00006 ;#define ClkFreq D'14745600' ;14.7456MHz 00007 #define ClkFreq D'32514000' ; 32.514MHz 00008 ;;; The baud() macro is used to define the UART clock regulator constant. 00009 #define baud(X) (((((D'10'*ClkFreq)/(D'64'*X))+D'5')/D'10')-D'1') 00010 ;;; TOO_DARK: used in Quickcam auto-brightnessing. 00011 #define TOO_DARK 0x3 00012 00013 00014 00015 #define clc bcf ALUSTA, C ; A quick definition: CLC is "Clear Carry". 00016 #define sec bsf ALUSTA, C ; SEC is "Set Carry". 00017 #define skpz btfss ALUSTA, Z 00018 #define skpnz btfsc ALUSTA, Z 00019 00020 ;;; 00021 ;;; GPS constants 00022 ;;; 00023 #define DLE 0x10 00024 #define ETX 0x03 00025 00026 #define Pid_Ack_Byte D'6' 00027 #define Pid_Command_Data D'10' 00028 #define Pid_Xfer_Cmplt D'12' 00029 #define Pid_Date_Time_Data D'14' 00030 #define Pid_Position_Data D'17' 00031 #define Pid_Nak_Byte D'21' 00032 #define Pid_Records D'27' 00033 #define Pid_Trk_Data D'34' 00034 00035 #define Cmnd_Transfer_Posn D'2' 00036 #define Cmnd_Transfer_Time D'5' 00037 #define Cmnd_Transfer_Trk D'6' 00038 00039 00052 #include "ports.i" 00001 ;;; 00002 ;;; Port definitions. The LP_STATUS port is port A, control is port C, 00003 ;;; and data is port D. 00004 ;;; Serial in/out for the GPS is done via port C also. 00005 ;;; 00006 #define SETUP_PORT PORTA ; setup switches are on port a. 00007 #define DR_SETUP DDRA ; silly, since A is always inputs... 00008 ;#define USERINT 0 ; user interrupt button - skips the 20 minute wait 00009 #define IS6BIT 1 ; user wants 6-bit scan? (default is 4 bit.) 00010 ;; 2 is unused at the moment. 00011 ;#define DSR 3 ; I hate to put DSR here, but there ya go. 00012 ;; 4 and 5 are the hardware UART; 6 and 7 aren't physical port bits 00013 00014 ;; I hate to put the quickcam power on/off in port B, because I want to use B<0> 00015 ;; for DSR from the phone to match with the DTR and DCD. However, I need an output, MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 3 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00016 ;; and the only other pins that are left are on PORTA, which are always inputs. DSR 00017 ;; is an input, and can go to port A. DTR is an output, and can't go on port A, so 00018 ;; DTR and DSR/DCD will have to be on separate ports. 00019 00020 #define POWER_PORT PORTB 00021 #define DR_POWER DDRB 00022 #define POWER_QCAM 0 ; turn on quickcam when this is 1 ('power the relay'). 00023 00024 #define HWHS_PORT PORTB ; hardware handshaking (modem flow control). 00025 #define DR_HWHS DDRB 00026 ;#define DTR 1 ; set to 1 when we want to use the phone; drop to 0 to hang up. 00027 #define DCD 2 ; should be high when the phone is connected. 00028 ;;; DTR on our end is always high (telling the phone we're always clear to receive). 00029 #define LP_STATUS PORTB 00030 #define DR_STATUS DDRB 00031 ;;; 0, 1, 2 unused for status. 3 is S3, 4-7 are data. 00032 #define S3 3 ; RB3 = parallel port S3 00033 #define LP_CONTROL PORTC 00034 #define DR_CONTROL DDRC 00035 #define C0 0 00036 #define C1 1 ; C1 is always 0. We can tie this low if we run out of pins. 00037 #define C2 2 00038 #define C3 3 00039 #define GPS_PORT PORTC ; the GPS bit-banging serial is also on port C. 00040 #define DR_GPS DDRC 00041 #define GPS_SEND 4 00042 #define GPS_RCV 5 00043 #define PHONE_PORT PORTC 00044 #define DR_PHONE DDRC 00045 #define PHONE_SEND 6 00046 #define PHONE_RCV 7 00047 #define LP_DATA PORTD 00048 #define DR_DATA DDRD 00049 00053 #include "vars.asm" 00001 ;;; 00002 ;;; Variable space 00003 ;;; 00004 ;;; temporary space for storing/restoring registers for intt0.asm. 00005 ;;; 0000001C 00006 TEMP_WREG_INTERRUPT EQU 0x1C ; NOTE: these are all banked! 0000001D 00007 TEMP_ALUSTA_INTERRUPT EQU 0x1D 0000001E 00008 TEMP_BSR_INTERRUPT EQU 0x1E 0000001F 00009 TEMP_WREG EQU 0x1F 00000020 00010 TEMP_FSR1_INTERRUPT EQU 0x20 00011 00000021 00012 TxBitbangBlocking_data EQU 0x21 00000022 00013 TEMP_FSR1 EQU 0x22 00000023 00014 T0IntState EQU 0x23 00000024 00015 ZERO EQU 0x24 ; used for comparisons 00000025 00016 PhoneDSRTimer EQU 0x25 00017 ;qc_Handshake_Timer EQU 0x26 00000027 00018 Phone_Mode EQU 0x27 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 4 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00019 00020 ;;; 00021 ;;; Quickcam variables. 00022 ;;; 00023 00000028 00024 qc_brightness EQU 0x28 00000029 00025 qc_contrast EQU 0x29 0000002A 00026 COUNT1 EQU 0x2A 0000002B 00027 COUNT2 EQU 0x2B 0000002C 00028 qc_hsval EQU 0x2C ; must be in page 0 (same as status port). 0000002D 00029 qc_save_retval EQU 0x2D 0000002E 00030 qc_returned EQU 0x2E 0000002F 00031 qc_BR0L EQU 0x2F 00000030 00032 qc_BR0H EQU 0x30 00000031 00033 QC_FLAGS EQU 0x31 00000032 00034 qc_tempbr EQU 0x32 00000033 00035 qc_mode EQU 0x33 00036 00037 #define RESEND 0 ; bit 0 of QC_FLAGS denotes an error. 00038 #define AVERAGING 1 ; bit 1 of QC_FLAGS denotes "averaging" mode. This send s no data. 00039 #define QC_COLOR 2 ; bit 2 of QC_FLAGS tells us it's a color quickcam (ins tead of B&W). 00040 #define SCAN_STARTED 3 ; bit 3 tells whether or not the scan has received any valid data yet. 00041 00042 ;;; 00043 ;;; gps.asm variables. 00044 ;;; 00045 00000040 00046 GetTrackingData_LowCounter EQU 0x40 00000041 00047 GetTrackingData_HighCounter EQU 0x41 00000042 00048 GPS_TimerLow EQU 0x42 00000043 00049 GPS_TimerHigh EQU 0x43 00000044 00050 Phone_TimerLow EQU 0x44 00000045 00051 Phone_TimerHigh EQU 0x45 00000046 00052 Phone_HaveData EQU 0x46 00000047 00053 ExpectPhone_counter EQU 0x47 00000048 00054 ExpectPhoneMsg_high EQU 0x48 00000049 00055 ExpectPhoneMsg_low EQU 0x49 0000004A 00056 Sleep1_TimerLow EQU 0x4A 0000004B 00057 Sleep1_TimerHigh EQU 0x4B 0000004C 00058 ExpectPhone_expectChar EQU 0x4C 0000004D 00059 ExpectPhone_Timeout EQU 0x4D 0000004E 00060 ExpectPhone_timeout EQU 0x4E 0000004F 00061 TxByteEscapeDLE_Temp EQU 0x4F 00000050 00062 Sleep1M_Timer EQU 0x50 00000051 00063 Sleep20M_Timer EQU 0x51 00000052 00064 qc_bluedata EQU 0x52 00065 00000053 00066 g_writepkt EQU 0x53 00067 ;; through 0x53 + D'10' 0000005D 00068 g_readpkt EQU 0x5D MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 5 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00069 ;; through 0x5D + D'20' 00000071 00070 ReadPacket_counter EQU 0x71 00000072 00071 ReadPacket_length EQU 0x72 00000073 00072 ReadPacket_checksum EQU 0x73 00000074 00073 ReceiveAck_counter EQU 0x74 00000075 00074 ExpectPacket_expecting EQU 0x75 00000076 00075 ExpectPacket_counter EQU 0x76 00000077 00076 CommandWrapper_counter EQU 0x77 00000078 00077 CommandWrapper_cmd EQU 0x78 00000079 00078 GPS_counter EQU 0x79 0000007A 00079 SendPacket_ptr EQU 0x7A 0000007B 00080 SendPacket_size EQU 0x7B 0000007C 00081 CommandWrapper_datatype EQU 0x7C 0000007D 00082 GetTrackingData_counter EQU 0x7D 0000007E 00083 DialPhone_ATZcounter EQU 0x7E 00084 ;; 0x7f unused. 00085 00086 ;;; 00087 ;;; Ring buffers. 00088 ;;; 00089 00000080 00090 GPSTxQueue EQU 0x80 ; extends to TxQueueEnd... 0000008F 00091 GPSTxQueueEnd EQU 0x8F 00000090 00092 GPSTxPtr EQU 0x90 00000091 00093 GPSTxLen EQU 0x91 00000092 00094 GPSTxTemp EQU 0x92 00000093 00095 GPSTxBitnum EQU 0x93 ; 0 through 0xA. 0=no data to send. 1=start bit, 2-9=data, A=sto p bit. 00000094 00096 GPSTxSkipping EQU 0x94 ; set when we're syncing the stream. 00097 000000A0 00098 GPSRxQueue EQU 0xA0 ; extends to RxQueueEnd... 000000AF 00099 GPSRxQueueEnd EQU 0xAF 000000B0 00100 GPSRxPtr EQU 0xB0 000000B1 00101 GPSRxLen EQU 0xB1 000000B2 00102 GPSRxByte EQU 0xB2 ; byte being received. 000000B3 00103 GPSRxBitnum EQU 0xB3 000000B4 00104 GPSRxState EQU 0xB4 000000B5 00105 GPSRxTemp EQU 0xB5 000000B6 00106 GPSRxBitsample EQU 0xB6 000000B7 00107 GPSRxBit EQU 0xB7 00108 000000C0 00109 PhoneTxQueue EQU 0xC0 ; extends to TxQueueEnd... 000000CF 00110 PhoneTxQueueEnd EQU 0xCF 000000D0 00111 PhoneTxPtr EQU 0xD0 000000D1 00112 PhoneTxLen EQU 0xD1 000000D2 00113 PhoneTxTemp EQU 0xD2 000000D3 00114 PhoneTxBitnum EQU 0xD3 ; 0 through 0xA. 0=no data to send. 1=start bit, 2-9=data, A=sto p bit. 000000D4 00115 PhoneTxSkipping EQU 0xD4 ; set when we're syncing the stream. 00116 000000E0 00117 PhoneRxQueue EQU 0xE0 ; extends to RxQueueEnd... 000000EF 00118 PhoneRxQueueEnd EQU 0xEF 000000F0 00119 PhoneRxPtr EQU 0xF0 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 6 LOC OBJECT CODE LINE SOURCE TEXT VALUE 000000F1 00120 PhoneRxLen EQU 0xF1 000000F2 00121 PhoneRxByte EQU 0xF2 ; byte being received. 000000F3 00122 PhoneRxBitnum EQU 0xF3 000000F4 00123 PhoneRxState EQU 0xF4 000000F5 00124 PhoneRxTemp EQU 0xF5 000000F6 00125 PhoneRxBitsample EQU 0xF6 000000F7 00126 PhoneRxBit EQU 0xF7 00127 00054 IFDEF __17C43 00055 #include "P17C43.inc" 00001 LIST 00002 ; P17C43.INC Standard Header File, Version 1.04 Microchip Technology, Inc. 00268 LIST 00056 ENDIF 00057 IFDEF __17C44 00058 #include "P17C44.inc" 00059 ENDIF 00060 00061 #include "macros.asm" 00001 ;;; SAVE_BSR and RESTORE_BSR assume WHERE is a page 0 address. They put 00002 ;;; the BSR into that saved location and restore it. 00003 SAVE_BSR MACRO WHERE 00004 movwf TEMP_WREG 00005 movfp BSR, WREG 00006 movlb 0 ; must be in page 0 to store to WHERE 00007 movwf WHERE 00008 movfp TEMP_WREG, WREG 00009 ENDM 00010 00011 RESTORE_BSR MACRO WHERE 00012 movlb 0 00013 movfp WHERE, BSR 00014 ENDM 00015 00016 SAVE_FSR1 MACRO 00017 movwf TEMP_WREG 00018 movfp FSR1, WREG 00019 movlb 0 00020 movwf TEMP_FSR1 00021 movfp TEMP_WREG, WREG 00022 ENDM 00023 00024 RESTORE_FSR1 MACRO 00025 movlb 0 00026 movfp TEMP_FSR1, BSR 00027 ENDM 00028 00029 ;;; WAIT will delay (3*A)+4 instruction cycles (or something like that). 00030 WAIT MACRO A 00031 movlw A 00032 call Waiter 00033 ENDM 00034 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 7 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00035 ;;; QCMD sends a command to the quickcam. It takes two bytes of data. 00036 ;;; If the camera doesn't respond with the correct return byte, it sets 00037 ;;; RESEND to 0x1 (in send_error, actually); all QCMD calls that we care 00038 ;;; about are wrapped with "resend this command" gotos. 00039 QCMD MACRO A, B 00040 movlw A 00041 call Command 00042 movlw B 00043 call Command 00044 ENDM 00045 00046 ;;; SLEEP sleeps the specified number of microseconds (at least - if it's 00047 ;;; interrupted, then it sleeps longer). Note that if the value passed in 00048 ;;; here is too large, we'll overflow and not realize it. The most we can 00049 ;;; delay is 0xFFFF times (12/clock speed) seconds(-ish). 00050 ;;; THIS IS NOT PRECISE, and is not intended to be. The loop counter is 00051 ;;; 1-based (which means that 0x601 is *less* than 0x600), for ease of 00052 ;;; implementation. 00053 00054 USLEEP MACRO USECS 00055 LOCAL loopomatic 00056 ;; each loop takes at least 3 cycles, so we loop 1/3 of 2063 loops. 00057 ; movlb 0 00058 movlw high((USECS/(D'120000000'/ClkFreq))/10) 00059 movwf COUNT2 00060 movlw low((USECS/(D'120000000'/ClkFreq))/10) 00061 movwf COUNT1 00062 loopomatic 00063 decfsz COUNT1, F ; 3 cycles to each lower count, 2 at the end 00064 goto loopomatic 00065 decfsz COUNT2, F ; 3 cycles to each high cont, 2 at the end 00066 goto loopomatic 00067 ENDM 00068 00069 ;;; BIGSLEEP is USLEEP with four loop counters. 00070 00071 BIGSLEEP MACRO SECS 00072 LOCAL loopomatic 00073 ;; each loop takes at least 3 cycles, so we loop 1/3 of 2063 loops. 00074 movlb 0 00075 00076 Figure out the math for this! 00077 00078 movlw high((SECS/(D'120000000'/ClkFreq))/10) 00079 movwf COUNT2 00080 movlw low((SECS/(D'120000000'/ClkFreq))/10) 00081 movwf COUNT1 00082 loopomatic 00083 decfsz COUNT1, F ; 3 cycles to each lower count, 2 at the end 00084 goto loopomatic 00085 decfsz COUNT2, F ; 3 cycles to each high cont, 2 at the end 00086 goto loopomatic 00087 ENDM MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 8 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00088 00089 ;;; TIMER_BLOCK waits until there are at least 'A' cycles before the next 00090 ;;; interrupt. (Actually, it only checks the low byte of the timer, because 00091 ;;; that's probably good enough for our purposes. If we wanted to be 100% 00092 ;;; correct, we'd want to check the high byte as well.) 00093 00094 TIMER_BLOCK MACRO A 00095 LOCAL loopomatic 00096 loopomatic 00097 movlw (D'3'+A) ; 2 cycles for the "cpfsgt", plus however many 00098 cpfsgt TMR0L ; we're requesting from the macro, plus one for 00099 goto loopomatic ; good measure. 00100 ENDM 00101 00102 SEND_PHONE MACRO A 00103 movlw A 00104 call TxPhoneBlocking 00105 ENDM 00106 00107 SEND_PHONE_W MACRO 00108 call TxPhoneBlocking 00109 ENDM 00110 00062 00063 ;;; ************* 00064 ;;; BEGIN PROGRAM 00065 ;;; ************* 0000 00066 org 0 0000 C598 00067 goto main 00068 0010 00069 org 0x10 0010 C064 00070 goto t0_int 00071 00072 ;;; skip reserved memory addresses 0021 00073 org 0x21 00074 00075 #include "printstr.asm" 00001 PHONEMSG MACRO A 00002 movlw HIGH(A) 00003 movpf WREG, TBLPTRH 00004 movlw LOW(A) 00005 movpf WREG, TBLPTRL 00006 call PrintMsgPhone 00007 ENDM 00008 00009 GPSMSG MACRO A 00010 movlw HIGH(A) 00011 movpf WREG, TBLPTRH 00012 movlw LOW(A) 00013 movpf WREG, TBLPTRL 00014 call PrintMsgGPS 00015 ENDM 00016 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 9 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0021 00017 PrintMsgPhone 0021 A80A 00018 tablrd 0, 0, WREG ; Move the current table ptr info into tablatch. 0022 A20A 00019 tlrd 1, WREG ; Read hi byte of tablatch. 0023 A90A 00020 tablrd 0, 1, WREG ; Read low byte of TABLATCH and reload with the next word. 0024 00021 PrintMsg_loop 0024 A20A 00022 tlrd 1, WREG ; Read hi byte of tablatch. 0025 3024 00023 cpfslt ZERO ; "if zero is less than WREG, skip" 0026 0002 00024 return 0027 E18E 00025 call TxPhoneBlocking 0028 A90A 00026 tablrd 0, 1, WREG ; Read low byte of TABLATCH and reload with the next word. 0029 3024 00027 cpfslt ZERO ; "if zero is less than WREG, skip" 002A 0002 00028 return 002B E18E 00029 call TxPhoneBlocking 002C C024 00030 goto PrintMsg_loop 00031 002D 00032 PrintMsgGPS 002D A80A 00033 tablrd 0, 0, WREG ; Move the current table ptr info into tablatch. 002E A20A 00034 tlrd 1, WREG ; Read hi byte of tablatch. 002F A90A 00035 tablrd 0, 1, WREG ; Read low byte of TABLATCH and reload with the next word. 0030 00036 PrintMsgGPS_loop 0030 A20A 00037 tlrd 1, WREG ; Read hi byte of tablatch. 0031 3024 00038 cpfslt ZERO ; "if zero is less than WREG, skip" 0032 0002 00039 return 0033 E16C 00040 call TxGPSBlocking 0034 A90A 00041 tablrd 0, 1, WREG ; Read low byte of TABLATCH and reload with the next word. 0035 3024 00042 cpfslt ZERO ; "if zero is less than WREG, skip" 0036 0002 00043 return 0037 E16C 00044 call TxGPSBlocking 0038 C030 00045 goto PrintMsgGPS_loop 00046 00047 00076 #include "intt0.asm" 00001 ;;; 00002 ;;; intt0.asm: routines related to bit-banging on timer 0. 00003 ;;; 00004 00005 #include "t0macros.i" 00001 BITBANG_TX_MACRO MACRO TxSkipping, TxLen, TxPtr, TxBitnum, port, bit, TxQueueEnd 00002 LOCAL t0_check_startbit 00003 LOCAL t0_tx_data 00004 LOCAL t0_send_1 00005 LOCAL t0_inc_ptr 00006 00007 btfsc TxSkipping, 0 00008 goto t0_inc_ptr ; if we're skipping to sync the bits, we have to finish. 00009 00010 clrf WREG, F 00011 cpfseq TxLen 00012 goto t0_check_startbit 00013 bsf TxSkipping, 0 ; set the syncing flag, because... 00014 goto t0_inc_ptr ; ... there is no data pending. We count anyway, so that the byt es start at the right time. 00015 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 10 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00016 t0_check_startbit 00017 movfp TxPtr, FSR1 00018 ; redundant... 00019 ; clrf WREG, F 00020 cpfseq TxBitnum ; if TxBitnum==0, it's a start bit. 00021 goto t0_tx_data 00022 movlb 1 00023 bcf port^0x100, bit ; send the start bit (=0). 00024 movlb 0 00025 goto t0_inc_ptr 00026 00027 t0_tx_data 00028 sec ; Send the next data bit. We shift 1's into the data as we 00029 rrcf INDF1, F ; send the bits so that we don't have to deal with checking 00030 btfsc ALUSTA, C ; to see if we need to send a stop bit; the 1's for the stop 00031 goto t0_send_1 ; bits are shifted into the data register, so they happen 00032 movlb 1 00033 bcf port^0x100, bit ; automatically when we get that far. We just have to change 00034 movlb 0 00035 goto t0_inc_ptr ; the number of bits to send (total) to change the number of 00036 ; stop bits. 00037 t0_send_1 00038 movlb 1 00039 bsf port^0x100, bit 00040 movlb 0 00041 00042 t0_inc_ptr 00043 ;; testing: not skipping whole bytes while sending. 00044 incf TxBitnum, F 00045 movlw 0xA ; 0xA is "just after" 1 start bit + 8 data bits + 1 stop bit. 00046 cpfsgt TxBitnum ; (0xB would be 2 stop bits.) 00047 return 00048 00049 clrf TxBitnum, F ; if we've sent all of the bits, then start on the next byte. 00050 clrf WREG, F 00051 clc 00052 rrcf TxSkipping, F ; Now the old skipping bit is in the carry, 00053 ; and TxSkipping has been cleared. 00054 btfsc ALUSTA, C ; If we were skipping, then don't change the TxPtr or TxLen, 00055 return ; because it has no bearing on the data in the queue. If a byte 00056 ; was queued while we were skipping, we don't want to flush it h ere! 00057 00058 ; If we weren't skipping, then there must have been data in the 00059 incf TxPtr, F ; queue. Increment the pointer and 00060 movlw TxQueueEnd ; decrement the amount of data in the queue. This lets us keep 00061 andwf TxPtr, F ; running the timer to make sure that all of the bytes line up 00062 decf TxLen, F ; properly (the first bit is always at the right time). 00063 ;; added 4/7/00: if the TxLen falls below zero, undo that. We must have cleared 00064 ;; the buffer outside of the interrupt while transmitting. 00065 btfsc ALUSTA, OV ; check overflow 00066 clrf TxLen, F ; if we overflowed, go back to zero. 00067 ;; end 4/7/00 addition. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 11 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00068 return 00069 ENDM 00070 00071 00072 BITBANG_RX_MACRO MACRO RxBitnum, port, bit, RxByte, RxLen, RxPtr, RxQueue, RxQueueEnd, RxTemp, RxBitSample, RxBit 00073 LOCAL NotWaitingForStartBit 00074 LOCAL ReceiveDataBit 00075 LOCAL QueueByteRx 00076 LOCAL FramingError 00077 LOCAL SaveBit 00078 LOCAL three_or_greater 00079 LOCAL three_or_4 00080 LOCAL its_a_4 00081 LOCAL SampleNotWaitingForStartBit 00082 00083 ;; Sample the line. If this is our third sample, figure out the state of the line and continue. 00084 ;; roll the line's state bit onto RxBit. 00085 movlb 1 00086 clc 00087 btfsc port^0x100, bit 00088 sec 00089 movlb 0 00090 rlcf RxBit, F ; roll the current state bit on to RxBit. 00091 00092 ;; if we're waiting for a start bit and our previous sample 00093 ;; was not a 1, reset the counter (to synchronize our data 00094 ;; with the line). 00095 clrf WREG, F 00096 cpfseq RxBitnum ; if RxBitnum == 0 ... 00097 goto SampleNotWaitingForStartBit 00098 cpfsgt RxBitSample ; ... and RxBitSample > 0 ... 00099 goto SampleNotWaitingForStartBit 00100 btfsc RxBit, 0 ; ... and the line is currently low ... 00101 goto SampleNotWaitingForStartBit 00102 btfss RxBit, 1 ; ... and the previous sample was 1 ... 00103 goto SampleNotWaitingForStartBit 00104 00105 clrf RxBitSample, F ; then RxBitSample = 0 and RxBit = 1. 00106 clrf RxBit, F ; This slides our sampling window forward 00107 ; 1/3 bit-cycle to align it. 00108 00109 00110 SampleNotWaitingForStartBit 00111 incf RxBitSample, F 00112 movlw 0x2 00113 cpfsgt RxBitSample 00114 return 00115 00116 ;; we've taken three samples, which means it's time to use whatever data we got and 00117 ;; process it. If the value is: 00118 ;; 00119 ;;dec binary value is MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 12 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00120 ;;0 0 0 0 =0 00121 ;;1 0 0 1 =0 00122 ;;2 0 1 0 =0 00123 ;;3 0 1 1 =1 00124 ;;4 1 0 0 =0 00125 ;;5 1 0 1 =1 00126 ;;6 1 1 0 =1 00127 ;;7 1 1 1 =1 00128 00129 movlw 0x3 00130 cpfslt RxBit 00131 goto three_or_greater 00132 bcf RxTemp, bit ; it's a 0. 00133 goto SaveBit 00134 00135 three_or_greater 00136 movlw 0x4 00137 cpfsgt RxBit 00138 goto three_or_4 00139 bsf RxTemp, bit ; it's a 1. 00140 goto SaveBit 00141 00142 three_or_4 00143 btfss RxBit, 0 ; if it's set, it's a 3 00144 goto its_a_4 00145 bsf RxTemp, bit 00146 goto SaveBit 00147 00148 its_a_4 00149 bcf RxTemp, bit 00150 ;; fall through. 00151 00152 SaveBit 00153 clrf RxBitSample, F ; reset the bit sample state and bit sample data. 00154 clrf RxBit, F 00155 00156 ;; Now we have the line's state. Process the bit. 00157 00158 clrf WREG, F 00159 cpfseq RxBitnum 00160 goto NotWaitingForStartBit 00161 00162 movfp RxTemp, WREG 00163 00164 btfsc WREG, bit ; waiting for a start bit. If the line state is 1, 00165 return ; then it hasn't arrived; just bail out. 00166 00167 movlb 1 00168 btg PORTE^0x100, 2 ; for debugging: toggle E<2> when we get start bits. 00169 movlb 0 00170 clrf RxByte, F ; got a start bit. Initialize the data to 0. 00171 incf RxBitnum, F 00172 return MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 13 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00173 00174 NotWaitingForStartBit 00175 incf RxBitnum, F 00176 movlw 0x9 00177 cpfsgt RxBitnum 00178 goto ReceiveDataBit ; still receiving data bits... 00179 00180 movfp RxTemp, WREG 00181 00182 ; btfss WREG, bit ; stop bit should be high. 00183 ; call FramingError ; (Not really necessary; just for debugging.) 00184 btfsc WREG, bit ; stop bit should be high. If the line's not high, 00185 call QueueByteRx ; we've got a framing error (and drop the char). 00186 clrf RxBitnum, F ; Reset the bit state to 0 (waiting for start bit). 00187 return 00188 00189 ReceiveDataBit 00190 clc 00191 btfsc RxTemp, bit 00192 sec 00193 rrcf RxByte, F 00194 return 00195 ;;; 00196 ;;; QueueByteRx: puts RxByte into the queue. 00197 ;;; Drops bytes on overflow! Called from interrupt, so we don't 00198 ;;; have to "lock" by TIMER_BLOCKing. 00199 ;;; 00200 QueueByteRx 00201 movlw 0x10 00202 cpfslt RxLen 00203 return ; drop the byte if the queue is full. 00204 00205 movfp RxPtr, WREG 00206 addwf RxLen, W 00207 andlw RxQueueEnd 00208 movwf FSR1 00209 movfp RxByte, INDF1 00210 incf RxLen, F 00211 00212 ; This is the simple one-byte buffer. It works, but probably overflows a lot 00213 ; during GPS actions (where we may be sending a message out the serial port 00214 ; while we're waiting for this information). 00215 ; movfp RxByte, WREG 00216 ; movpf WREG, RxQueue 00217 ; bsf RxLen, 0 00218 00219 return 00220 ;; FramingError must preserve WREG! 00221 ;FramingError 00222 ; movlb 1 00223 ; btg PORTE^0x100, 1 ; For debugging: toggle PORTE<1> on framing error. 00224 ; movlb 0 00225 ; return MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 14 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00226 ENDM 00227 00228 00229 TX_ENQUEUE MACRO TxLen, TxPtr, TxQueueEnd 00230 LOCAL TxByteWait 00231 LOCAL TxByteQueue 00232 00233 SAVE_FSR1 00234 movwf TxBitbangBlocking_data 00235 TxByteWait 00236 movlw D'16' ; Is the transmit ring buffer full? 00237 cpfslt TxLen 00238 goto TxByteWait ; Yes. Block until we have a free byte in the buffer. 00239 00240 TIMER_BLOCK D'6' ; make sure we can add GPSTxPtr and GPSTxLen before they change. 00241 movfp TxPtr, WREG ; WREG = head of ring buffer. 00242 addwf TxLen, W ; WREG += length of data in ring buffer. Points to first free b yte. 00243 andlw TxQueueEnd ; WREG &= 0x8F (in other words, if we reach the end of the 00244 movwf FSR1 ; buffer, go back to the start.) 00245 TxByteQueue 00246 movfp TxBitbangBlocking_data, INDF1 ; Move the byte into the ring buffer, and 00247 incf TxLen, F ; increment the buffer length counter. 00248 RESTORE_FSR1 00249 return 00250 ENDM 00251 00252 ;;; 00253 ;;; RxBitbang: grabs a byte from the queue. Doesn't block. 00254 ;;; The returned value is 0 if there is no data in the queue! 00255 ;;; 00256 RX_DEQUEUE MACRO RxLen, RxPtr, RxQueue, RxQueueEnd 00257 clrf WREG, F 00258 cpfsgt RxLen 00259 retlw 0x0 ; if there's no data, return 0. 00260 00261 TIMER_BLOCK D'12' ; (twice as long as the needed delay?) 00262 movfp RxPtr, FSR1 ; store the first byte's address in FSR1. 00263 incf RxPtr, W ; W = Ptr+1 00264 andlw RxQueueEnd ; W &= Queue's bit signature 00265 movwf RxPtr ; Ptr = W 00266 decf RxLen, F ; QueueLen-- 00267 movpf INDF1, WREG 00268 00269 00270 ; This is the simple one-byte queue. It works (in conjunction with the one 00271 ; for queueing above), but we're probably overflowing the buffer while debugging 00272 ; the GPS routines (because we send chars out another serial port while the GPS 00273 ; is sending them in this one). 00274 ; btfss RxLen, 0 00275 ; retlw 0x0 00276 ; TIMER_BLOCK D'3' 00277 ; movfp RxQueue, WREG MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 15 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00278 ; bcf RxLen, 0 00279 00280 return 00281 ENDM 00282 00006 0039 00007 InitBitbang 0039 B080 00008 movlw GPSTxQueue ; initialize the ring buffers. 003A 0190 00009 movwf GPSTxPtr 003B B0A0 00010 movlw GPSRxQueue 003C 01B0 00011 movwf GPSRxPtr 00012 003D 2991 00013 clrf GPSTxLen, F 003E 29B1 00014 clrf GPSRxLen, F 003F 2993 00015 clrf GPSTxBitnum, F 0040 29B3 00016 clrf GPSRxBitnum, F 0041 2994 00017 clrf GPSTxSkipping, F 0042 29B4 00018 clrf GPSRxState, F 0043 29B5 00019 clrf GPSRxTemp, F 0044 29B6 00020 clrf GPSRxBitsample, F 0045 29B7 00021 clrf GPSRxBit, F 00022 0046 B0C0 00023 movlw PhoneTxQueue ; initialize the ring buffers. 0047 01D0 00024 movwf PhoneTxPtr 0048 B0E0 00025 movlw PhoneRxQueue 0049 01F0 00026 movwf PhoneRxPtr 00027 004A 29D1 00028 clrf PhoneTxLen, F 004B 29F1 00029 clrf PhoneRxLen, F 004C 29D3 00030 clrf PhoneTxBitnum, F 004D 29F3 00031 clrf PhoneRxBitnum, F 004E 29D4 00032 clrf PhoneTxSkipping, F 004F 29F4 00033 clrf PhoneRxState, F 0050 29F5 00034 clrf PhoneRxTemp, F 0051 29F6 00035 clrf PhoneRxBitsample, F 0052 29F7 00036 clrf PhoneRxBit, F 00037 0053 2923 00038 clrf T0IntState, F ; clear bit counter state. 0054 8505 00039 bsf T0STA, T0CS ; timer 0 from internal clock 0055 8905 00040 bcf T0STA, PS0 ; 1x prescalar. 0056 8A05 00041 bcf T0STA, PS1 ; 1x prescalar. 0057 8B05 00042 bcf T0STA, PS2 ; 1x prescalar. 0058 8C05 00043 bcf T0STA, PS3 ; 1x prescalar. 0059 8107 00044 bsf INTSTA, T0IE ; turn on the interrupt. 00045 005A B801 00046 movlb 1 005B 8510 00047 bsf DR_GPS^0x100, GPS_RCV ; the GPS receive line is an input. 005C 8C10 00048 bcf DR_GPS^0x100, GPS_SEND ; the GPS send line is an output. 005D 8411 00049 bsf GPS_PORT^0x100, GPS_SEND ; the quiescent state of RS232 is high. Set it. 00050 005E 8710 00051 bsf DR_PHONE^0x100, PHONE_RCV 005F 8E10 00052 bcf DR_PHONE^0x100, PHONE_SEND 0060 8611 00053 bsf PHONE_PORT^0x100, PHONE_SEND MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 16 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0061 B800 00054 movlb 0 00055 00056 ;; Initialize hardware handshaking on the phone port. 00057 ;; DTR is now part of the peripheral power setup. 00058 ; bcf HWHS_PORT, DTR 00059 ; bcf DR_HWHS, DTR ; DTR is an output, set to 0 when we're not connected 0062 8211 00060 bsf DR_HWHS, DCD ; DCD is an input 00061 00062 ; movlw 'G' 00063 ; call TxGPSBlocking 00064 ; movlw 'P' 00065 ; call TxGPSBlocking 00066 ; movlw 'S' 00067 ; call TxGPSBlocking 00068 00069 ; movlw 'P' 00070 ; call TxPhoneBlocking 00071 ; movlw 'h' 00072 ; call TxPhoneBlocking 00073 ; movlw 'o' 00074 ; call TxPhoneBlocking 00075 ; movlw 'n' 00076 ; call TxPhoneBlocking 00077 ; movlw 'e' 00078 ; call TxPhoneBlocking 00079 0063 0005 00080 retfie ; return and enable interrupts. 00081 00082 ;;; 00083 ;;; t0_int is called when the timer0 interrupt occurrs. 00084 ;;; 0064 00085 t0_int 0064 7C0A 00086 movfp WREG, TEMP_WREG_INTERRUPT 0065 7D04 00087 movfp ALUSTA, TEMP_ALUSTA_INTERRUPT 0066 7E0F 00088 movfp BSR, TEMP_BSR_INTERRUPT ; necessary. We may be in the middle of 0067 B800 00089 movlb 0 ; changing a page 1 variable outside. 0068 4920 00090 movpf FSR1, TEMP_FSR1_INTERRUPT 00091 0069 8D05 00092 bcf T0STA, T0CS ; turn off interrupt (actually, sets clock external - RA4 doesn' t change, so we're safe). 00093 ;; 00094 ;; change T0 to interrupt at the right time again. The correct time 00095 ;; is 104.167uS (for 9600 baud). Calculate the correct delay based 00096 ;; on the clock speed. WARNING: This may not round properly for clock 00097 ;; speeds other than 14.7456MHz! Do the math to be sure that it works 00098 ;; properly. Remeber that the compiler turns EACH STEP of this 00099 ;; calculation into integers as it does them! 00100 ;; 00101 00102 ; movlw 0xFF-high((D'104167'*((ClkFreq/D'4')/D'1000'))/D'4000000') 00103 ; movlw 0xFF-0x01 006A B0FF 00104 movlw 0xFF-0x00 00105 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 17 LOC OBJECT CODE LINE SOURCE TEXT VALUE 006B 010C 00106 movwf TMR0H 00107 ; ClkFreq is divided by 4 because we're doing two interrupt functions; 00108 ; we're transmitting on 1 of the cycles, and receiving the other 3. 00109 ; The "+0x1" is fudge factor because of the truncating (@14.7456MHz). 00110 ; The "0xF" is 8 cycles (from the time we entered the routine until the 00111 ; time that we re-enabled the timer), plus 4 cycles for the timer to 00112 ; start whirring again. 00113 ; movlw 0xFF-((low((D'104167'*((ClkFreq/D'4')/D'1000'))/D'4000000')+0x1) - 0xF) 00114 ; movlw 0xFF-(0xa5 - 0xF) 006C B040 00115 movlw 0xFF-(0xCE - 0xF) 006D 010B 00116 movwf TMR0L 006E 8505 00117 bsf T0STA, T0CS ; ... and turn back on the interrupt (set clock back internal). 00118 006F 1423 00119 incf T0IntState, W ; T0IntState = (T0IntState+1)%4 0070 B503 00120 andlw 0x3 0071 0123 00121 movwf T0IntState 00122 0072 290A 00123 clrf WREG, F 0073 3223 00124 cpfsgt T0IntState 0074 C078 00125 goto transmit_state 0075 E0AE 00126 call t0_rx ; It's a sampling state (1,2,3). 0076 E122 00127 call t1_rx 0077 C07F 00128 goto done_int 00129 0078 00130 transmit_state 0078 E084 00131 call t0_tx 0079 E0F8 00132 call t1_tx 00133 ;; fall through. 00134 00135 ; Straighten out the timer. We lose a little precision doing four processses, 00136 ; so we correct it here. 00137 ; movlw 0x2 ; timer takes 4 cycles to change after we modify it? 00138 ; addwf TMR0L ; we assume no carry; maybe we should? 007A 8D05 00139 bcf T0STA, T0CS ; turn off interrupt (actually, sets clock external - RA4 doesn' t change, so we're safe). 007B 0000 00140 nop 007C 0000 00141 nop 007D 0000 00142 nop 007E 8505 00143 bsf T0STA, T0CS 00144 007F 00145 done_int 007F 6920 00146 movfp TEMP_FSR1_INTERRUPT, FSR1 0080 5E0F 00147 movpf TEMP_BSR_INTERRUPT, BSR 0081 5D04 00148 movpf TEMP_ALUSTA_INTERRUPT, ALUSTA 0082 5C0A 00149 movpf TEMP_WREG_INTERRUPT, WREG 0083 0005 00150 retfie 00151 0084 00152 t0_tx 00153 BITBANG_TX_MACRO GPSTxSkipping, GPSTxLen, GPSTxPtr, GPSTxBitnum, GPS_PORT, GPS_SEND, GPSTxQueueE nd 0000 M LOCAL t0_check_startbit 0000 M LOCAL t0_tx_data 0000 M LOCAL t0_send_1 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 18 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0000 M LOCAL t0_inc_ptr M 0084 9894 M btfsc GPSTxSkipping, 0 0085 C09D M goto t0_inc_ptr ; if we're skipping to sync the bits, we have to finish. M 0086 290A M clrf WREG, F 0087 3191 M cpfseq GPSTxLen 0088 C08B M goto t0_check_startbit 0089 8094 M bsf GPSTxSkipping, 0 ; set the syncing flag, because... 008A C09D M goto t0_inc_ptr ; ... there is no data pending. We count anyway, so that the byt es start at the right time. M 008B M t0_check_startbit 008B 6990 M movfp GPSTxPtr, FSR1 M ; redundant... M ; clrf WREG, F 008C 3193 M cpfseq GPSTxBitnum ; if TxBitnum==0, it's a start bit. 008D C092 M goto t0_tx_data 008E B801 M movlb 1 008F 8C11 M bcf PORTC^0x100, 4 ; send the start bit (=0). 0090 B800 M movlb 0 0091 C09D M goto t0_inc_ptr M 0092 M t0_tx_data 0092 8004 M sec ; Send the next data bit. We shift 1's into the data as we 0093 1908 M rrcf INDF1, F ; send the bits so that we don't have to deal with checking 0094 9804 M btfsc ALUSTA, C ; to see if we need to send a stop bit; the 1's for the stop 0095 C09A M goto t0_send_1 ; bits are shifted into the data register, so they happen 0096 B801 M movlb 1 0097 8C11 M bcf PORTC^0x100, 4 ; automatically when we get that far. We just have to change 0098 B800 M movlb 0 0099 C09D M goto t0_inc_ptr ; the number of bits to send (total) to change the number of M ; stop bits. 009A M t0_send_1 009A B801 M movlb 1 009B 8411 M bsf PORTC^0x100, 4 009C B800 M movlb 0 M 009D M t0_inc_ptr M ;; testing: not skipping whole bytes while sending. 009D 1593 M incf GPSTxBitnum, F 009E B00A M movlw 0xA ; 0xA is "just after" 1 start bit + 8 data bits + 1 stop bit. 009F 3293 M cpfsgt GPSTxBitnum ; (0xB would be 2 stop bits.) 00A0 0002 M return M 00A1 2993 M clrf GPSTxBitnum, F ; if we've sent all of the bits, then start on the next byte. 00A2 290A M clrf WREG, F 00A3 8804 M clc 00A4 1994 M rrcf GPSTxSkipping, F ; Now the old skipping bit is in the carry, M ; and TxSkipping has been cleared. 00A5 9804 M btfsc ALUSTA, C ; If we were skipping, then don't change the TxPtr or TxLen, 00A6 0002 M return ; because it has no bearing on the data in the queue. If a byte M ; was queued while we were skipping, we don't want to flush it h MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 19 LOC OBJECT CODE LINE SOURCE TEXT VALUE ere! M M ; If we weren't skipping, then there must have been data in the 00A7 1590 M incf GPSTxPtr, F ; queue. Increment the pointer and 00A8 B08F M movlw GPSTxQueueEnd ; decrement the amount of data in the queue. This lets us keep 00A9 0B90 M andwf GPSTxPtr, F ; running the timer to make sure that all of the bytes line up 00AA 0791 M decf GPSTxLen, F ; properly (the first bit is always at the right time). M ;; added 4/7/00: if the TxLen falls below zero, undo that. We must have cleared M ;; the buffer outside of the interrupt while transmitting. 00AB 9B04 M btfsc ALUSTA, OV ; check overflow 00AC 2991 M clrf GPSTxLen, F ; if we overflowed, go back to zero. M ;; end 4/7/00 addition. 00AD 0002 M return 00AE 00154 t0_rx 00155 BITBANG_RX_MACRO GPSRxBitnum, GPS_PORT, GPS_RCV, GPSRxByte, GPSRxLen, GPSRxPtr, GPSRxQueue, GPSR xQueueEnd, GPSRxTemp, GPSRxBitsample, GPSRxBit 0000 M LOCAL NotWaitingForStartBit 0000 M LOCAL ReceiveDataBit 0000 M LOCAL QueueByteRx 0000 M LOCAL FramingError 0000 M LOCAL SaveBit 0000 M LOCAL three_or_greater 0000 M LOCAL three_or_4 0000 M LOCAL its_a_4 0000 M LOCAL SampleNotWaitingForStartBit M M ;; Sample the line. If this is our third sample, figure out the state of the line and continue. M ;; roll the line's state bit onto RxBit. 00AE B801 M movlb 1 00AF 8804 M clc 00B0 9D11 M btfsc PORTC^0x100, 5 00B1 8004 M sec 00B2 B800 M movlb 0 00B3 1BB7 M rlcf GPSRxBit, F ; roll the current state bit on to RxBit. M M ;; if we're waiting for a start bit and our previous sample M ;; was not a 1, reset the counter (to synchronize our data M ;; with the line). 00B4 290A M clrf WREG, F 00B5 31B3 M cpfseq GPSRxBitnum ; if RxBitnum == 0 ... 00B6 C0BF M goto SampleNotWaitingForStartBit 00B7 32B6 M cpfsgt GPSRxBitsample ; ... and RxBitSample > 0 ... 00B8 C0BF M goto SampleNotWaitingForStartBit 00B9 98B7 M btfsc GPSRxBit, 0 ; ... and the line is currently low ... 00BA C0BF M goto SampleNotWaitingForStartBit 00BB 91B7 M btfss GPSRxBit, 1 ; ... and the previous sample was 1 ... 00BC C0BF M goto SampleNotWaitingForStartBit M 00BD 29B6 M clrf GPSRxBitsample, F ; then RxBitSample = 0 and RxBit = 1. 00BE 29B7 M clrf GPSRxBit, F ; This slides our sampling window forward M ; 1/3 bit-cycle to align it. M M MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 20 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00BF M SampleNotWaitingForStartBit 00BF 15B6 M incf GPSRxBitsample, F 00C0 B002 M movlw 0x2 00C1 32B6 M cpfsgt GPSRxBitsample 00C2 0002 M return M M ;; we've taken three samples, which means it's time to use whatever data we got and M ;; process it. If the value is: M ;; M ;;dec binary value is M ;;0 0 0 0 =0 M ;;1 0 0 1 =0 M ;;2 0 1 0 =0 M ;;3 0 1 1 =1 M ;;4 1 0 0 =0 M ;;5 1 0 1 =1 M ;;6 1 1 0 =1 M ;;7 1 1 1 =1 M 00C3 B003 M movlw 0x3 00C4 30B7 M cpfslt GPSRxBit 00C5 C0C8 M goto three_or_greater 00C6 8DB5 M bcf GPSRxTemp, 5 ; it's a 0. 00C7 C0D2 M goto SaveBit M 00C8 M three_or_greater 00C8 B004 M movlw 0x4 00C9 32B7 M cpfsgt GPSRxBit 00CA C0CD M goto three_or_4 00CB 85B5 M bsf GPSRxTemp, 5 ; it's a 1. 00CC C0D2 M goto SaveBit M 00CD M three_or_4 00CD 90B7 M btfss GPSRxBit, 0 ; if it's set, it's a 3 00CE C0D1 M goto its_a_4 00CF 85B5 M bsf GPSRxTemp, 5 00D0 C0D2 M goto SaveBit M 00D1 M its_a_4 00D1 8DB5 M bcf GPSRxTemp, 5 M ;; fall through. M 00D2 M SaveBit 00D2 29B6 M clrf GPSRxBitsample, F ; reset the bit sample state and bit sample data. 00D3 29B7 M clrf GPSRxBit, F M M ;; Now we have the line's state. Process the bit. M 00D4 290A M clrf WREG, F 00D5 31B3 M cpfseq GPSRxBitnum 00D6 C0E0 M goto NotWaitingForStartBit M 00D7 6AB5 M movfp GPSRxTemp, WREG MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 21 LOC OBJECT CODE LINE SOURCE TEXT VALUE M 00D8 9D0A M btfsc WREG, 5 ; waiting for a start bit. If the line state is 1, 00D9 0002 M return ; then it hasn't arrived; just bail out. M 00DA B801 M movlb 1 00DB 3A15 M btg PORTE^0x100, 2 ; for debugging: toggle E<2> when we get start bits. 00DC B800 M movlb 0 00DD 29B2 M clrf GPSRxByte, F ; got a start bit. Initialize the data to 0. 00DE 15B3 M incf GPSRxBitnum, F 00DF 0002 M return M 00E0 M NotWaitingForStartBit 00E0 15B3 M incf GPSRxBitnum, F 00E1 B009 M movlw 0x9 00E2 32B3 M cpfsgt GPSRxBitnum 00E3 C0E9 M goto ReceiveDataBit ; still receiving data bits... M 00E4 6AB5 M movfp GPSRxTemp, WREG M M ; btfss WREG, bit ; stop bit should be high. M ; call FramingError ; (Not really necessary; just for debugging.) 00E5 9D0A M btfsc WREG, 5 ; stop bit should be high. If the line's not high, 00E6 E0EE M call QueueByteRx ; we've got a framing error (and drop the char). 00E7 29B3 M clrf GPSRxBitnum, F ; Reset the bit state to 0 (waiting for start bit). 00E8 0002 M return M 00E9 M ReceiveDataBit 00E9 8804 M clc 00EA 9DB5 M btfsc GPSRxTemp, 5 00EB 8004 M sec 00EC 19B2 M rrcf GPSRxByte, F 00ED 0002 M return M ;;; M ;;; QueueByteRx: puts RxByte into the queue. M ;;; Drops bytes on overflow! Called from interrupt, so we don't M ;;; have to "lock" by TIMER_BLOCKing. M ;;; 00EE M QueueByteRx 00EE B010 M movlw 0x10 00EF 30B1 M cpfslt GPSRxLen 00F0 0002 M return ; drop the byte if the queue is full. M 00F1 6AB0 M movfp GPSRxPtr, WREG 00F2 0EB1 M addwf GPSRxLen, W 00F3 B5AF M andlw GPSRxQueueEnd 00F4 0109 M movwf FSR1 00F5 68B2 M movfp GPSRxByte, INDF1 00F6 15B1 M incf GPSRxLen, F M M ; This is the simple one-byte buffer. It works, but probably overflows a lot M ; during GPS actions (where we may be sending a message out the serial port M ; while we're waiting for this information). M ; movfp RxByte, WREG MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 22 LOC OBJECT CODE LINE SOURCE TEXT VALUE M ; movpf WREG, RxQueue M ; bsf RxLen, 0 M 00F7 0002 M return M ;; FramingError must preserve WREG! M ;FramingError M ; movlb 1 M ; btg PORTE^0x100, 1 ; For debugging: toggle PORTE<1> on framing error. M ; movlb 0 M ; return 00156 00F8 00157 t1_tx 00158 BITBANG_TX_MACRO PhoneTxSkipping, PhoneTxLen, PhoneTxPtr, PhoneTxBitnum, PHONE_PORT, PHONE_SEND, PhoneTxQueueEnd 0000 M LOCAL t0_check_startbit 0000 M LOCAL t0_tx_data 0000 M LOCAL t0_send_1 0000 M LOCAL t0_inc_ptr M 00F8 98D4 M btfsc PhoneTxSkipping, 0 00F9 C111 M goto t0_inc_ptr ; if we're skipping to sync the bits, we have to finish. M 00FA 290A M clrf WREG, F 00FB 31D1 M cpfseq PhoneTxLen 00FC C0FF M goto t0_check_startbit 00FD 80D4 M bsf PhoneTxSkipping, 0 ; set the syncing flag, because... 00FE C111 M goto t0_inc_ptr ; ... there is no data pending. We count anyway, so that the byt es start at the right time. M 00FF M t0_check_startbit 00FF 69D0 M movfp PhoneTxPtr, FSR1 M ; redundant... M ; clrf WREG, F 0100 31D3 M cpfseq PhoneTxBitnum ; if TxBitnum==0, it's a start bit. 0101 C106 M goto t0_tx_data 0102 B801 M movlb 1 0103 8E11 M bcf PORTC^0x100, 6 ; send the start bit (=0). 0104 B800 M movlb 0 0105 C111 M goto t0_inc_ptr M 0106 M t0_tx_data 0106 8004 M sec ; Send the next data bit. We shift 1's into the data as we 0107 1908 M rrcf INDF1, F ; send the bits so that we don't have to deal with checking 0108 9804 M btfsc ALUSTA, C ; to see if we need to send a stop bit; the 1's for the stop 0109 C10E M goto t0_send_1 ; bits are shifted into the data register, so they happen 010A B801 M movlb 1 010B 8E11 M bcf PORTC^0x100, 6 ; automatically when we get that far. We just have to change 010C B800 M movlb 0 010D C111 M goto t0_inc_ptr ; the number of bits to send (total) to change the number of M ; stop bits. 010E M t0_send_1 010E B801 M movlb 1 010F 8611 M bsf PORTC^0x100, 6 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 23 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0110 B800 M movlb 0 M 0111 M t0_inc_ptr M ;; testing: not skipping whole bytes while sending. 0111 15D3 M incf PhoneTxBitnum, F 0112 B00A M movlw 0xA ; 0xA is "just after" 1 start bit + 8 data bits + 1 stop bit. 0113 32D3 M cpfsgt PhoneTxBitnum ; (0xB would be 2 stop bits.) 0114 0002 M return M 0115 29D3 M clrf PhoneTxBitnum, F ; if we've sent all of the bits, then start on the next byte. 0116 290A M clrf WREG, F 0117 8804 M clc 0118 19D4 M rrcf PhoneTxSkipping, F ; Now the old skipping bit is in the carry, M ; and TxSkipping has been cleared. 0119 9804 M btfsc ALUSTA, C ; If we were skipping, then don't change the TxPtr or TxLen, 011A 0002 M return ; because it has no bearing on the data in the queue. If a byte M ; was queued while we were skipping, we don't want to flush it h ere! M M ; If we weren't skipping, then there must have been data in the 011B 15D0 M incf PhoneTxPtr, F ; queue. Increment the pointer and 011C B0CF M movlw PhoneTxQueueEnd ; decrement the amount of data in the queue. This lets us keep 011D 0BD0 M andwf PhoneTxPtr, F ; running the timer to make sure that all of the bytes line up 011E 07D1 M decf PhoneTxLen, F ; properly (the first bit is always at the right time). M ;; added 4/7/00: if the TxLen falls below zero, undo that. We must have cleared M ;; the buffer outside of the interrupt while transmitting. 011F 9B04 M btfsc ALUSTA, OV ; check overflow 0120 29D1 M clrf PhoneTxLen, F ; if we overflowed, go back to zero. M ;; end 4/7/00 addition. 0121 0002 M return 0122 00159 t1_rx 00160 BITBANG_RX_MACRO PhoneRxBitnum, PHONE_PORT, PHONE_RCV, PhoneRxByte, PhoneRxLen, PhoneRxPtr, Phon eRxQueue, PhoneRxQueueEnd, PhoneRxTemp, PhoneRxBitsample, PhoneRxBit 0000 M LOCAL NotWaitingForStartBit 0000 M LOCAL ReceiveDataBit 0000 M LOCAL QueueByteRx 0000 M LOCAL FramingError 0000 M LOCAL SaveBit 0000 M LOCAL three_or_greater 0000 M LOCAL three_or_4 0000 M LOCAL its_a_4 0000 M LOCAL SampleNotWaitingForStartBit M M ;; Sample the line. If this is our third sample, figure out the state of the line and continue. M ;; roll the line's state bit onto RxBit. 0122 B801 M movlb 1 0123 8804 M clc 0124 9F11 M btfsc PORTC^0x100, 7 0125 8004 M sec 0126 B800 M movlb 0 0127 1BF7 M rlcf PhoneRxBit, F ; roll the current state bit on to RxBit. M M ;; if we're waiting for a start bit and our previous sample MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 24 LOC OBJECT CODE LINE SOURCE TEXT VALUE M ;; was not a 1, reset the counter (to synchronize our data M ;; with the line). 0128 290A M clrf WREG, F 0129 31F3 M cpfseq PhoneRxBitnum ; if RxBitnum == 0 ... 012A C133 M goto SampleNotWaitingForStartBit 012B 32F6 M cpfsgt PhoneRxBitsample ; ... and RxBitSample > 0 ... 012C C133 M goto SampleNotWaitingForStartBit 012D 98F7 M btfsc PhoneRxBit, 0 ; ... and the line is currently low ... 012E C133 M goto SampleNotWaitingForStartBit 012F 91F7 M btfss PhoneRxBit, 1 ; ... and the previous sample was 1 ... 0130 C133 M goto SampleNotWaitingForStartBit M 0131 29F6 M clrf PhoneRxBitsample, F ; then RxBitSample = 0 and RxBit = 1. 0132 29F7 M clrf PhoneRxBit, F ; This slides our sampling window forward M ; 1/3 bit-cycle to align it. M M 0133 M SampleNotWaitingForStartBit 0133 15F6 M incf PhoneRxBitsample, F 0134 B002 M movlw 0x2 0135 32F6 M cpfsgt PhoneRxBitsample 0136 0002 M return M M ;; we've taken three samples, which means it's time to use whatever data we got and M ;; process it. If the value is: M ;; M ;;dec binary value is M ;;0 0 0 0 =0 M ;;1 0 0 1 =0 M ;;2 0 1 0 =0 M ;;3 0 1 1 =1 M ;;4 1 0 0 =0 M ;;5 1 0 1 =1 M ;;6 1 1 0 =1 M ;;7 1 1 1 =1 M 0137 B003 M movlw 0x3 0138 30F7 M cpfslt PhoneRxBit 0139 C13C M goto three_or_greater 013A 8FF5 M bcf PhoneRxTemp, 7 ; it's a 0. 013B C146 M goto SaveBit M 013C M three_or_greater 013C B004 M movlw 0x4 013D 32F7 M cpfsgt PhoneRxBit 013E C141 M goto three_or_4 013F 87F5 M bsf PhoneRxTemp, 7 ; it's a 1. 0140 C146 M goto SaveBit M 0141 M three_or_4 0141 90F7 M btfss PhoneRxBit, 0 ; if it's set, it's a 3 0142 C145 M goto its_a_4 0143 87F5 M bsf PhoneRxTemp, 7 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 25 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0144 C146 M goto SaveBit M 0145 M its_a_4 0145 8FF5 M bcf PhoneRxTemp, 7 M ;; fall through. M 0146 M SaveBit 0146 29F6 M clrf PhoneRxBitsample, F ; reset the bit sample state and bit sample data. 0147 29F7 M clrf PhoneRxBit, F M M ;; Now we have the line's state. Process the bit. M 0148 290A M clrf WREG, F 0149 31F3 M cpfseq PhoneRxBitnum 014A C154 M goto NotWaitingForStartBit M 014B 6AF5 M movfp PhoneRxTemp, WREG M 014C 9F0A M btfsc WREG, 7 ; waiting for a start bit. If the line state is 1, 014D 0002 M return ; then it hasn't arrived; just bail out. M 014E B801 M movlb 1 014F 3A15 M btg PORTE^0x100, 2 ; for debugging: toggle E<2> when we get start bits. 0150 B800 M movlb 0 0151 29F2 M clrf PhoneRxByte, F ; got a start bit. Initialize the data to 0. 0152 15F3 M incf PhoneRxBitnum, F 0153 0002 M return M 0154 M NotWaitingForStartBit 0154 15F3 M incf PhoneRxBitnum, F 0155 B009 M movlw 0x9 0156 32F3 M cpfsgt PhoneRxBitnum 0157 C15D M goto ReceiveDataBit ; still receiving data bits... M 0158 6AF5 M movfp PhoneRxTemp, WREG M M ; btfss WREG, bit ; stop bit should be high. M ; call FramingError ; (Not really necessary; just for debugging.) 0159 9F0A M btfsc WREG, 7 ; stop bit should be high. If the line's not high, 015A E162 M call QueueByteRx ; we've got a framing error (and drop the char). 015B 29F3 M clrf PhoneRxBitnum, F ; Reset the bit state to 0 (waiting for start bit). 015C 0002 M return M 015D M ReceiveDataBit 015D 8804 M clc 015E 9FF5 M btfsc PhoneRxTemp, 7 015F 8004 M sec 0160 19F2 M rrcf PhoneRxByte, F 0161 0002 M return M ;;; M ;;; QueueByteRx: puts RxByte into the queue. M ;;; Drops bytes on overflow! Called from interrupt, so we don't M ;;; have to "lock" by TIMER_BLOCKing. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 26 LOC OBJECT CODE LINE SOURCE TEXT VALUE M ;;; 0162 M QueueByteRx 0162 B010 M movlw 0x10 0163 30F1 M cpfslt PhoneRxLen 0164 0002 M return ; drop the byte if the queue is full. M 0165 6AF0 M movfp PhoneRxPtr, WREG 0166 0EF1 M addwf PhoneRxLen, W 0167 B5EF M andlw PhoneRxQueueEnd 0168 0109 M movwf FSR1 0169 68F2 M movfp PhoneRxByte, INDF1 016A 15F1 M incf PhoneRxLen, F M M ; This is the simple one-byte buffer. It works, but probably overflows a lot M ; during GPS actions (where we may be sending a message out the serial port M ; while we're waiting for this information). M ; movfp RxByte, WREG M ; movpf WREG, RxQueue M ; bsf RxLen, 0 M 016B 0002 M return M ;; FramingError must preserve WREG! M ;FramingError M ; movlb 1 M ; btg PORTE^0x100, 1 ; For debugging: toggle PORTE<1> on framing error. M ; movlb 0 M ; return 00161 00162 016C 00163 TxGPSBlocking 00164 TX_ENQUEUE GPSTxLen, GPSTxPtr, GPSTxQueueEnd 0000 M LOCAL TxByteWait 0000 M LOCAL TxByteQueue M M SAVE_FSR1 016C 011F M movwf TEMP_WREG 016D 6A09 M movfp FSR1, WREG 016E B800 M movlb 0 016F 0122 M movwf TEMP_FSR1 0170 6A1F M movfp TEMP_WREG, WREG 0171 0121 M movwf TxBitbangBlocking_data 0172 M TxByteWait 0172 B010 M movlw D'16' ; Is the transmit ring buffer full? 0173 3091 M cpfslt GPSTxLen 0174 C172 M goto TxByteWait ; Yes. Block until we have a free byte in the buffer. M M TIMER_BLOCK D'6' ; make sure we can add GPSTxPtr and GPSTxLen before they change. 0000 M LOCAL loopomatic 0175 M loopomatic 0175 B009 M movlw (D'3'+D'6') ; 2 cycles for the "cpfsgt", plus however many 0176 320B M cpfsgt TMR0L ; we're requesting from the macro, plus one for 0177 C175 M goto loopomatic ; good measure. 0178 6A90 M movfp GPSTxPtr, WREG ; WREG = head of ring buffer. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 27 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0179 0E91 M addwf GPSTxLen, W ; WREG += length of data in ring buffer. Points to first free b yte. 017A B58F M andlw GPSTxQueueEnd ; WREG &= 0x8F (in other words, if we reach the end of the 017B 0109 M movwf FSR1 ; buffer, go back to the start.) 017C M TxByteQueue 017C 6821 M movfp TxBitbangBlocking_data, INDF1 ; Move the byte into the ring buffer, and 017D 1591 M incf GPSTxLen, F ; increment the buffer length counter. M RESTORE_FSR1 017E B800 M movlb 0 017F 6F22 M movfp TEMP_FSR1, BSR 0180 0002 M return 00165 0181 00166 RxGPS 00167 RX_DEQUEUE GPSRxLen, GPSRxPtr, GPSRxQueue, GPSRxQueueEnd 0181 290A M clrf WREG, F 0182 32B1 M cpfsgt GPSRxLen 0183 B600 M retlw 0x0 ; if there's no data, return 0. M M TIMER_BLOCK D'12' ; (twice as long as the needed delay?) 0000 M LOCAL loopomatic 0184 M loopomatic 0184 B00F M movlw (D'3'+D'12') ; 2 cycles for the "cpfsgt", plus however many 0185 320B M cpfsgt TMR0L ; we're requesting from the macro, plus one for 0186 C184 M goto loopomatic ; good measure. 0187 69B0 M movfp GPSRxPtr, FSR1 ; store the first byte's address in FSR1. 0188 14B0 M incf GPSRxPtr, W ; W = Ptr+1 0189 B5AF M andlw GPSRxQueueEnd ; W &= Queue's bit signature 018A 01B0 M movwf GPSRxPtr ; Ptr = W 018B 07B1 M decf GPSRxLen, F ; QueueLen-- 018C 480A M movpf INDF1, WREG M M M ; This is the simple one-byte queue. It works (in conjunction with the one M ; for queueing above), but we're probably overflowing the buffer while debugging M ; the GPS routines (because we send chars out another serial port while the GPS M ; is sending them in this one). M ; btfss RxLen, 0 M ; retlw 0x0 M ; TIMER_BLOCK D'3' M ; movfp RxQueue, WREG M ; bcf RxLen, 0 M 018D 0002 M return 00168 018E 00169 TxPhoneBlocking 00170 TX_ENQUEUE PhoneTxLen, PhoneTxPtr, PhoneTxQueueEnd 0000 M LOCAL TxByteWait 0000 M LOCAL TxByteQueue M M SAVE_FSR1 018E 011F M movwf TEMP_WREG 018F 6A09 M movfp FSR1, WREG 0190 B800 M movlb 0 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 28 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0191 0122 M movwf TEMP_FSR1 0192 6A1F M movfp TEMP_WREG, WREG 0193 0121 M movwf TxBitbangBlocking_data 0194 M TxByteWait 0194 B010 M movlw D'16' ; Is the transmit ring buffer full? 0195 30D1 M cpfslt PhoneTxLen 0196 C194 M goto TxByteWait ; Yes. Block until we have a free byte in the buffer. M M TIMER_BLOCK D'6' ; make sure we can add GPSTxPtr and GPSTxLen before they change. 0000 M LOCAL loopomatic 0197 M loopomatic 0197 B009 M movlw (D'3'+D'6') ; 2 cycles for the "cpfsgt", plus however many 0198 320B M cpfsgt TMR0L ; we're requesting from the macro, plus one for 0199 C197 M goto loopomatic ; good measure. 019A 6AD0 M movfp PhoneTxPtr, WREG ; WREG = head of ring buffer. 019B 0ED1 M addwf PhoneTxLen, W ; WREG += length of data in ring buffer. Points to first free b yte. 019C B5CF M andlw PhoneTxQueueEnd ; WREG &= 0x8F (in other words, if we reach the end of the 019D 0109 M movwf FSR1 ; buffer, go back to the start.) 019E M TxByteQueue 019E 6821 M movfp TxBitbangBlocking_data, INDF1 ; Move the byte into the ring buffer, and 019F 15D1 M incf PhoneTxLen, F ; increment the buffer length counter. M RESTORE_FSR1 01A0 B800 M movlb 0 01A1 6F22 M movfp TEMP_FSR1, BSR 01A2 0002 M return 00171 01A3 00172 RxPhone 00173 RX_DEQUEUE PhoneRxLen, PhoneRxPtr, PhoneRxQueue, PhoneRxQueueEnd 01A3 290A M clrf WREG, F 01A4 32F1 M cpfsgt PhoneRxLen 01A5 B600 M retlw 0x0 ; if there's no data, return 0. M M TIMER_BLOCK D'12' ; (twice as long as the needed delay?) 0000 M LOCAL loopomatic 01A6 M loopomatic 01A6 B00F M movlw (D'3'+D'12') ; 2 cycles for the "cpfsgt", plus however many 01A7 320B M cpfsgt TMR0L ; we're requesting from the macro, plus one for 01A8 C1A6 M goto loopomatic ; good measure. 01A9 69F0 M movfp PhoneRxPtr, FSR1 ; store the first byte's address in FSR1. 01AA 14F0 M incf PhoneRxPtr, W ; W = Ptr+1 01AB B5EF M andlw PhoneRxQueueEnd ; W &= Queue's bit signature 01AC 01F0 M movwf PhoneRxPtr ; Ptr = W 01AD 07F1 M decf PhoneRxLen, F ; QueueLen-- 01AE 480A M movpf INDF1, WREG M M M ; This is the simple one-byte queue. It works (in conjunction with the one M ; for queueing above), but we're probably overflowing the buffer while debugging M ; the GPS routines (because we send chars out another serial port while the GPS M ; is sending them in this one). M ; btfss RxLen, 0 M ; retlw 0x0 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 29 LOC OBJECT CODE LINE SOURCE TEXT VALUE M ; TIMER_BLOCK D'3' M ; movfp RxQueue, WREG M ; bcf RxLen, 0 M 01AF 0002 M return 00174 00077 #include "gps.asm" 00001 ;;; 00002 ;;; gps.asm - GPS-related routines. 00003 ;;; 00004 00005 ;;; 00006 ;;; InitGPS -- initialize variables necessary for the GPS. Currently, this 00007 ;;; does nothing. 00008 ;;; 01B0 00009 InitGPS 01B0 0002 00010 return 00011 00012 ;;; 00013 ;;; TxGPSBlockingEscapeDLE: sends any byte, and if it's a DLE, it sends it twice. 00014 ;;; 01B1 00015 TxGPSBlockingEscapeDLE 01B1 014F 00016 movwf TxByteEscapeDLE_Temp 01B2 E16C 00017 call TxGPSBlocking 01B3 6A4F 00018 movfp TxByteEscapeDLE_Temp, WREG 01B4 B210 00019 sublw DLE 01B5 9204 00020 skpz 01B6 0002 00021 return 01B7 B010 00022 movlw DLE ; if it's a DLE, send it again. 01B8 E16C 00023 call TxGPSBlocking 01B9 0002 00024 return 00025 00026 ;;; 00027 ;;; BLOCK_UNTIL_DATA will wait for data to be available on the 00028 ;;; GPS serial port. If it times out, it returns 0. Since it's a 00029 ;;; macro, that means it returns 0 for the function using it. 00030 ;;; 00031 BLOCK_UNTIL_DATA MACRO 00032 LOCAL TryAgain 00033 LOCAL HaveData 00034 clrf GPS_TimerLow, F 00035 clrf GPS_TimerHigh, F 00036 TryAgain 00037 clrf WREG, F 00038 cpfseq GPSRxLen 00039 goto HaveData 00040 WAIT 0x0 00041 incfsz GPS_TimerLow, F 00042 goto TryAgain 00043 incfsz GPS_TimerHigh, F 00044 goto TryAgain 00045 00046 ; PHONEMSG TimeoutString MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 30 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00047 retlw 0x0 00048 HaveData 00049 ENDM 00050 00051 ;;; 00052 ;;; Checksum expects a buffer beginning with the RecordType (in WREG). 00053 ;;; 01BA 00054 Checksum 01BA 0101 00055 movwf FSR0 01BB 290A 00056 clrf WREG, F 01BC 0E00 00057 addwf INDF0, W ; W = W + (*FSR0++) 00058 01BD 4079 00059 movpf INDF0, GPS_counter ; counter = (*FSR0++) 01BE 0E79 00060 addwf GPS_counter, W ; W = W + counter 00061 01BF 00062 Checksum_AddData 01BF 0E00 00063 addwf INDF0, W ; W = W + (*FSR0++) 01C0 1779 00064 decfsz GPS_counter, F ; if (--counter != 0) goto Checksum_AddData; 01C1 C1BF 00065 goto Checksum_AddData 00066 01C2 2D0A 00067 negw WREG, F ; return (~WREG)+1 01C3 0002 00068 return 00069 00070 ;;; 00071 ;;; SendPacket takes a buffer starting with the RecordType (in WREG). 00072 ;;; 01C4 00073 SendPacket 01C4 017A 00074 movwf SendPacket_ptr ; save the packet pointer for later. 01C5 0101 00075 movwf FSR0 01C6 1501 00076 incf FSR0, F 01C7 B002 00077 movlw 0x2 01C8 0E00 00078 addwf INDF0, W ; size = buf[1]+2 01C9 017B 00079 movwf SendPacket_size 00080 01CA B010 00081 movlw DLE 01CB E16C 00082 call TxGPSBlocking ; send packet header 00083 01CC 617A 00084 movfp SendPacket_ptr, FSR0 01CD 00085 SendPacket_SendData 01CD 6A00 00086 movfp INDF0, WREG ; while (size) { 01CE E1B1 00087 call TxGPSBlockingEscapeDLE ; write(fd, &buf[...], 1); 00088 01CF 177B 00089 decfsz SendPacket_size, F ; size--; 01D0 C1CD 00090 goto SendPacket_SendData ; } 00091 01D1 6A7A 00092 movfp SendPacket_ptr, WREG 01D2 E1BA 00093 call Checksum ; write(fd, Checksum(buf), 1) 01D3 E1B1 00094 call TxGPSBlockingEscapeDLE 00095 01D4 B010 00096 movlw DLE ; write (fd, &footer, 2) 01D5 E16C 00097 call TxGPSBlocking 01D6 B003 00098 movlw ETX 01D7 E16C 00099 call TxGPSBlocking MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 31 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00100 01D8 B601 00101 retlw 0x1 00102 00103 ;;; 00104 ;;; SendAck grabs the command number out of g_readpkt and ACKs that command. 00105 ;;; 01D9 00106 SendAck 01D9 B006 00107 movlw Pid_Ack_Byte 01DA 0153 00108 movwf g_writepkt 01DB B002 00109 movlw 0x2 01DC 0154 00110 movwf (g_writepkt+0x1) 01DD 6A5D 00111 movfp g_readpkt, WREG ; grab the command number to ack... 01DE 0155 00112 movwf (g_writepkt+0x2) 01DF 2956 00113 clrf (g_writepkt+0x3), F 01E0 B053 00114 movlw g_writepkt ; prepare for SendPacket call, but... 01E1 C1C4 00115 goto SendPacket ; ... let SendPacket return for us. 00116 00117 ;;; 00118 ;;; SendNak works just like SendAck (NAKing instead of ACKing). 00119 ;;; 01E2 00120 SendNak 01E2 B015 00121 movlw Pid_Nak_Byte 01E3 0153 00122 movwf g_writepkt 01E4 B002 00123 movlw 0x2 01E5 0154 00124 movwf (g_writepkt+0x1) 01E6 6A5D 00125 movfp g_readpkt, WREG ; grab the command number to nak... 01E7 0155 00126 movwf (g_writepkt+0x2) 01E8 2956 00127 clrf (g_writepkt+0x3), F 01E9 B053 00128 movlw g_writepkt ; prepare for SendPacket call, but... 01EA C1C4 00129 goto SendPacket ; ... let SendPacket return for us. 00130 00131 ;;; 00132 ;;; SendCommand wants a command number in WREG. 00133 ;;; 01EB 00134 SendCommand 01EB 0155 00135 movwf (g_writepkt+0x2) 01EC B00A 00136 movlw Pid_Command_Data 01ED 0153 00137 movwf g_writepkt 01EE B002 00138 movlw 0x2 01EF 0154 00139 movwf (g_writepkt+0x1) 01F0 2956 00140 clrf (g_writepkt+0x3), F 01F1 B053 00141 movlw g_writepkt 01F2 C1C4 00142 goto SendPacket ; let SendPacket return for us. 00143 00144 ;;; 00145 ;;; RxGPSEscapeDLE does just what you'd think. It expects a buffer pointer 00146 ;;; in FSR0 where you want the character. 00147 ;;; 01F3 00148 RxGPSEscapeDLE 00149 BLOCK_UNTIL_DATA ; returns 0 for us if we time out. 0000 M LOCAL TryAgain 0000 M LOCAL HaveData 01F3 2942 M clrf GPS_TimerLow, F MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 32 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01F4 2943 M clrf GPS_TimerHigh, F 01F5 M TryAgain 01F5 290A M clrf WREG, F 01F6 31B1 M cpfseq GPSRxLen 01F7 C1FF M goto HaveData M WAIT 0x0 01F8 B000 M movlw 0x0 01F9 E58A M call Waiter 01FA 1F42 M incfsz GPS_TimerLow, F 01FB C1F5 M goto TryAgain 01FC 1F43 M incfsz GPS_TimerHigh, F 01FD C1F5 M goto TryAgain M M ; PHONEMSG TimeoutString 01FE B600 M retlw 0x0 01FF M HaveData 01FF E181 00150 call RxGPS 0200 0100 00151 movwf INDF0 0201 B210 00152 sublw DLE 0202 9204 00153 skpz 0203 B601 00154 retlw 0x1 ; it's not a DLE, so we're done. 00155 00156 ;; it's a DLE. Re-read it. 0204 0701 00157 decf FSR0, F ; FSR0 is auto-incrementing. Undo that. 00158 BLOCK_UNTIL_DATA ; returns 0 for us if we time out. 0000 M LOCAL TryAgain 0000 M LOCAL HaveData 0205 2942 M clrf GPS_TimerLow, F 0206 2943 M clrf GPS_TimerHigh, F 0207 M TryAgain 0207 290A M clrf WREG, F 0208 31B1 M cpfseq GPSRxLen 0209 C211 M goto HaveData M WAIT 0x0 020A B000 M movlw 0x0 020B E58A M call Waiter 020C 1F42 M incfsz GPS_TimerLow, F 020D C207 M goto TryAgain 020E 1F43 M incfsz GPS_TimerHigh, F 020F C207 M goto TryAgain M M ; PHONEMSG TimeoutString 0210 B600 M retlw 0x0 0211 M HaveData 0211 E181 00159 call RxGPS ; if it was a DLE, re-read it. 0212 0100 00160 movwf INDF0 0213 B601 00161 retlw 0x1 ; return 1 on success. 00162 00163 ;;; 00164 ;;; ReadPacket reads a packet into g_readpkt. Returns 1 in WREG on success. 00165 ;;; 0214 00166 ReadPacket 0214 2971 00167 clrf ReadPacket_counter, F MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 33 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0215 00168 ReadPacket_TryAgain 0215 1571 00169 incf ReadPacket_counter, F 0216 9971 00170 btfsc ReadPacket_counter, 1 ; if counter reaches 2^1 (=2), bail. 0217 B600 00171 retlw 0x0 00172 0218 00173 ReadPacket_WaitForDLE 00174 ;; The first byte should be a DLE. We just read it into WREG. 00175 BLOCK_UNTIL_DATA ; returns 0 for us if we time out. 0000 M LOCAL TryAgain 0000 M LOCAL HaveData 0218 2942 M clrf GPS_TimerLow, F 0219 2943 M clrf GPS_TimerHigh, F 021A M TryAgain 021A 290A M clrf WREG, F 021B 31B1 M cpfseq GPSRxLen 021C C224 M goto HaveData M WAIT 0x0 021D B000 M movlw 0x0 021E E58A M call Waiter 021F 1F42 M incfsz GPS_TimerLow, F 0220 C21A M goto TryAgain 0221 1F43 M incfsz GPS_TimerHigh, F 0222 C21A M goto TryAgain M M ; PHONEMSG TimeoutString 0223 B600 M retlw 0x0 0224 M HaveData 0224 E181 00176 call RxGPS 0225 B210 00177 sublw DLE 0226 9204 00178 skpz 0227 C218 00179 goto ReadPacket_WaitForDLE; wait for a DLE. 00180 0228 00181 ReadPacket_ReadCommand 00182 ;; The second byte is the command. We read it into INDF0. 0228 B05D 00183 movlw g_readpkt 0229 0101 00184 movwf FSR0 ; FSR0 = g_readpkt 00185 022A E1F3 00186 call RxGPSEscapeDLE ; get command 022B 900A 00187 btfss WREG, 0 022C B600 00188 retlw 0x0 ; return error if command returned 0. 00189 00190 ; decf FSR0, F ; step back to the byte and send it out the 00191 ; movpf INDF0, WREG ; serial port for debugging. 00192 ; call TxPhoneBlocking 00193 00194 ;; Check to see if we're out of sync 00195 022D 0701 00196 decf FSR0, F ; writing it incremented FSR0. Move back. 022E 6A00 00197 movfp INDF0, WREG 022F B203 00198 sublw ETX ; if we get an ETX, we're out of sync; restart. 0230 9204 00199 skpz 0231 C233 00200 goto ReadPacket_ReadLength 0232 C215 00201 goto ReadPacket_TryAgain MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 34 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00202 0233 00203 ReadPacket_ReadLength 0233 E1F3 00204 call RxGPSEscapeDLE ; get size 0234 900A 00205 btfss WREG, 0 0235 B600 00206 retlw 0x0 ; return error if RxGPSEscapeDLE returned 0. 00207 00208 ; decf FSR0, F ; debugging. Print the char out the serial port. 00209 ; movpf INDF0, WREG 00210 ; call TxPhoneBlocking 00211 0236 0701 00212 decf FSR0, F ; writing it incremented FSR0. Move back. 0237 6A00 00213 movfp INDF0, WREG ; WREG = length byte (and FSR0++) 0238 0172 00214 movwf ReadPacket_length 00215 0239 00216 ReadPacket_ReadData 0239 E1F3 00217 call RxGPSEscapeDLE ; get data payload byte 023A 900A 00218 btfss WREG, 0 023B B600 00219 retlw 0x0 ; return error if RxGPSEscapeDLE returned 0. 00220 00221 ; decf FSR0, F ; debugging. Print the char out the serial port. 00222 ; movpf INDF0, WREG 00223 ; call TxPhoneBlocking 00224 023C 1772 00225 decfsz ReadPacket_length, F 023D C239 00226 goto ReadPacket_ReadData 00227 00228 ;; Read the checksum byte. 023E B073 00229 movlw ReadPacket_checksum 023F 0101 00230 movwf FSR0 0240 E1F3 00231 call RxGPSEscapeDLE ; get checksum into ReadPacket_checksum 0241 900A 00232 btfss WREG, 0 0242 B600 00233 retlw 0x0 ; return error if RxGPSEscapeDLE returned 0. 00234 00235 ; movfp ReadPacket_checksum, WREG 00236 ; call TxPhoneBlocking 00237 0243 B006 00238 movlw Pid_Ack_Byte ; if it's not ack and not nak, we checksum. 0244 045D 00239 subwf g_readpkt, W ; Check to see if it's an ACK packet... 0245 9A04 00240 skpnz 0246 C252 00241 goto ReadPacket_isGood ; it is, don't check the checksum. 00242 0247 B015 00243 movlw Pid_Nak_Byte ; Check to see if it's a NAK packet... 0248 045D 00244 subwf g_readpkt, W 0249 9A04 00245 skpnz 024A C252 00246 goto ReadPacket_isGood ; it is, don't check the checksum. 00247 00248 ;; need to check the checksum. 024B B05D 00249 movlw g_readpkt ; reset packet pointer (in WREG) for Checksum call. 024C E1BA 00250 call Checksum 024D 0473 00251 subwf ReadPacket_checksum, W 024E 9A04 00252 skpnz 024F C252 00253 goto ReadPacket_isGood ; checksum matches 00254 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 35 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0250 E1E2 00255 call SendNak 0251 B600 00256 retlw 0x0 00257 0252 00258 ReadPacket_isGood 00259 BLOCK_UNTIL_DATA ; returns 0 for us if we time out. 0000 M LOCAL TryAgain 0000 M LOCAL HaveData 0252 2942 M clrf GPS_TimerLow, F 0253 2943 M clrf GPS_TimerHigh, F 0254 M TryAgain 0254 290A M clrf WREG, F 0255 31B1 M cpfseq GPSRxLen 0256 C25E M goto HaveData M WAIT 0x0 0257 B000 M movlw 0x0 0258 E58A M call Waiter 0259 1F42 M incfsz GPS_TimerLow, F 025A C254 M goto TryAgain 025B 1F43 M incfsz GPS_TimerHigh, F 025C C254 M goto TryAgain M M ; PHONEMSG TimeoutString 025D B600 M retlw 0x0 025E M HaveData 025E E181 00260 call RxGPS 025F B210 00261 sublw DLE ; if we didn't get a DLE, return 0. 0260 9A04 00262 skpnz 0261 C263 00263 goto ReadPacket_isGood2 0262 B600 00264 retlw 0x0 00265 0263 00266 ReadPacket_isGood2 00267 BLOCK_UNTIL_DATA ; returns 0 for us if we time out. 0000 M LOCAL TryAgain 0000 M LOCAL HaveData 0263 2942 M clrf GPS_TimerLow, F 0264 2943 M clrf GPS_TimerHigh, F 0265 M TryAgain 0265 290A M clrf WREG, F 0266 31B1 M cpfseq GPSRxLen 0267 C26F M goto HaveData M WAIT 0x0 0268 B000 M movlw 0x0 0269 E58A M call Waiter 026A 1F42 M incfsz GPS_TimerLow, F 026B C265 M goto TryAgain 026C 1F43 M incfsz GPS_TimerHigh, F 026D C265 M goto TryAgain M M ; PHONEMSG TimeoutString 026E B600 M retlw 0x0 026F M HaveData 026F E181 00268 call RxGPS 0270 B203 00269 sublw ETX ; if we didn't get an ETX, return 0. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 36 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0271 9204 00270 skpz 0272 B600 00271 retlw 0x0 00272 00273 ;; Okay! It's a legitemate packet. If it's not an ack or nak packet, 00274 ;; we should ack it. If it is an ack or nak packet, no action is 00275 ;; required. 00276 0273 B006 00277 movlw Pid_Ack_Byte ; if it's not ACK or NAK, then send an ack reply. 0274 045D 00278 subwf g_readpkt, W 0275 9204 00279 skpz 0276 C278 00280 goto ReadPacket_CheckNak 0277 B601 00281 retlw 0x1 ; It's an ACK. all done. 00282 0278 00283 ReadPacket_CheckNak 0278 B015 00284 movlw Pid_Nak_Byte ; see if it's a NAK... 0279 045D 00285 subwf g_readpkt, W 027A 9204 00286 skpz 027B C27D 00287 goto ReadPacket_SendAck 027C B601 00288 retlw 0x1 ; It's a NAK. all done. 00289 027D 00290 ReadPacket_SendAck 00291 ;; If we get here, the packet is good, and it wasn't an ACK or NAK. 00292 ;; Send an ACK packet in reply. 027D E1D9 00293 call SendAck ; ack the packet. 027E B601 00294 retlw 0x1 ; and we're done. 00295 00296 ;;; 00297 ;;; ReceiveAck -- waits for an ack packet. Returns 1 if it gets it. 00298 ;;; 027F 00299 ReceiveAck 027F 2974 00300 clrf ReceiveAck_counter, F 0280 00301 ReceiveAck_begin 0280 1574 00302 incf ReceiveAck_counter, F 0281 9974 00303 btfsc ReceiveAck_counter, 1 ; if counter reaches 2^1 (=2), bail. 0282 B600 00304 retlw 0x0 00305 0283 E214 00306 call ReadPacket 0284 900A 00307 btfss WREG, 0 0285 C280 00308 goto ReceiveAck_begin ; if we timeout reading, try again. 00309 0286 B006 00310 movlw Pid_Ack_Byte ; if it's not an ack, read again. 0287 045D 00311 subwf g_readpkt, W 0288 9204 00312 skpz 0289 C280 00313 goto ReceiveAck_begin 00314 028A B00A 00315 movlw Pid_Command_Data ; if it's not a command ack, read again. 028B 045F 00316 subwf (g_readpkt+0x2), W 028C 9204 00317 skpz 028D C280 00318 goto ReceiveAck_begin 00319 028E B601 00320 retlw 0x1 00321 00322 ;;; MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 37 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00323 ;;; ExpectPacket takes a packet type to expect. It returns 1 on success. 00324 ;;; 028F 00325 ExpectPacket 028F 0175 00326 movwf ExpectPacket_expecting 0290 2976 00327 clrf ExpectPacket_counter, F 0291 00328 ExpectPacket_begin 00329 0291 1576 00330 incf ExpectPacket_counter, F 0292 9976 00331 btfsc ExpectPacket_counter, 1 ; if counter reaches 2^1 (=2), bail. 0293 B600 00332 retlw 0x0 00333 0294 E214 00334 call ReadPacket ; WREG = ReadPacket() 0295 900A 00335 btfss WREG, 0 0296 C291 00336 goto ExpectPacket_begin; loop until it returns a 1 00337 0297 6A75 00338 movfp ExpectPacket_expecting, WREG 0298 045D 00339 subwf g_readpkt, W 0299 9204 00340 skpz 029A C291 00341 goto ExpectPacket_begin; loop if it's the wrong type 00342 029B B601 00343 retlw 0x1 00344 00345 ;;; 00346 ;;; CommandWrapper takes two arguments, which have to be pre-set into its 00347 ;;; global variables CommandWrapper_cmd and CommandWrapper_datatype. It 00348 ;;; sends the command and then expects an ack and a datatype. 00349 ;;; 029C 00350 CommandWrapper 029C 2977 00351 clrf CommandWrapper_counter, F 029D 00352 CommandWrapper_begin 029D 1577 00353 incf CommandWrapper_counter, F 029E 9A77 00354 btfsc CommandWrapper_counter, 2; if counter reaches 2^2 (=4), bail. 029F B600 00355 retlw 0x0 00356 02A0 6A78 00357 movfp CommandWrapper_cmd, WREG 02A1 E1EB 00358 call SendCommand 00359 02A2 E27F 00360 call ReceiveAck 02A3 900A 00361 btfss WREG, 0 02A4 C29D 00362 goto CommandWrapper_begin; loop until we get the right ack. 00363 02A5 6A7C 00364 movfp CommandWrapper_datatype, WREG 02A6 E28F 00365 call ExpectPacket 02A7 900A 00366 btfss WREG, 0 02A8 C29D 00367 goto CommandWrapper_begin 02A9 B601 00368 retlw 0x1 00369 00370 ;;; 00371 ;;; GetTime calls CommandWrapper, and then sends the time data out the serial 00372 ;;; port (the Phone serial port, that is). 00373 ;;; 02AA 00374 GetTime 02AA 2991 00375 clrf GPSTxLen, F ; flush the phone buffers... MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 38 LOC OBJECT CODE LINE SOURCE TEXT VALUE 02AB 29B1 00376 clrf GPSRxLen, F 00377 02AC B005 00378 movlw Cmnd_Transfer_Time 02AD 0178 00379 movwf CommandWrapper_cmd 02AE B00E 00380 movlw Pid_Date_Time_Data 02AF 017C 00381 movwf CommandWrapper_datatype 02B0 E29C 00382 call CommandWrapper 02B1 900A 00383 btfss WREG, 0 02B2 B600 00384 retlw 0x0 ; error. Bail. 00385 02B3 B0FF 00386 movlw 0xFF 00387 SEND_PHONE_W 02B4 E18E M call TxPhoneBlocking 02B5 B05F 00388 movlw g_readpkt+0x2 02B6 0101 00389 movwf FSR0 02B7 B008 00390 movlw 0x8 ; 8 bytes to send... 02B8 0179 00391 movwf GPS_counter 02B9 00392 GetTime_SendData 02B9 6A00 00393 movfp INDF0, WREG 00394 SEND_PHONE_W 02BA E18E M call TxPhoneBlocking 02BB 1779 00395 decfsz GPS_counter, F 02BC C2B9 00396 goto GetTime_SendData 02BD B601 00397 retlw 0x1 00398 00399 ;;; 00400 ;;; GetPosn is like GetTime. 00401 ;;; 02BE 00402 GetPosn 02BE 2991 00403 clrf GPSTxLen, F ; flush the phone buffers... 02BF 29B1 00404 clrf GPSRxLen, F 00405 02C0 B002 00406 movlw Cmnd_Transfer_Posn 02C1 0178 00407 movwf CommandWrapper_cmd 02C2 B011 00408 movlw Pid_Position_Data 02C3 017C 00409 movwf CommandWrapper_datatype 02C4 E29C 00410 call CommandWrapper 02C5 900A 00411 btfss WREG, 0 02C6 B600 00412 retlw 0x0 ; error. Bail. 00413 ; movlb 1 00414 ; btg PORTE^0x100, 0 00415 ; movlb 0 00416 02C7 B0FE 00417 movlw 0xFE 00418 SEND_PHONE_W 02C8 E18E M call TxPhoneBlocking 02C9 B05F 00419 movlw g_readpkt+0x2 02CA 0101 00420 movwf FSR0 02CB B010 00421 movlw 0x10 ; 16 bytes to send... 02CC 0179 00422 movwf GPS_counter 02CD 00423 GetPosn_SendData 02CD 6A00 00424 movfp INDF0, WREG 00425 SEND_PHONE_W MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 39 LOC OBJECT CODE LINE SOURCE TEXT VALUE 02CE E18E M call TxPhoneBlocking 02CF 1779 00426 decfsz GPS_counter, F 02D0 C2CD 00427 goto GetPosn_SendData 02D1 B601 00428 retlw 0x1 00429 00430 ;;; 00431 ;;; GetTrackingData is a little more complicated; it needs to receive a 00432 ;;; number of tracking records and then send them out the phone port. 00433 ;;; 02D2 00434 GetTrackingData 00435 ; clrf GPSTxLen, F ; flush the phone buffers... 00436 ; clrf GPSRxLen, F 00437 02D2 297D 00438 clrf GetTrackingData_counter, F 02D3 00439 GetTrackingData_begin 02D3 157D 00440 incf GetTrackingData_counter, F 02D4 997D 00441 btfsc GetTrackingData_counter, 1; if counter reaches 2^1 (=2), bail. 02D5 B600 00442 retlw 0x0 00443 02D6 B006 00444 movlw Cmnd_Transfer_Trk 02D7 E1EB 00445 call SendCommand 00446 02D8 E27F 00447 call ReceiveAck ; if we don't ack, try sending it again. 02D9 900A 00448 btfss WREG, 0 02DA C2D3 00449 goto GetTrackingData_begin ; ReceiveAck returned 0; try resending the request. 00450 02DB B01B 00451 movlw Pid_Records 02DC E28F 00452 call ExpectPacket 02DD 900A 00453 btfss WREG, 0 02DE B600 00454 retlw 0x0 ; if we don't get a Pid_Records, then bail. 00455 02DF B0FD 00456 movlw 0xFD 00457 SEND_PHONE_W 02E0 E18E M call TxPhoneBlocking 00458 ;; The number of records is a little-endian short at g_readpkt[2]. 02E1 6A5F 00459 movfp g_readpkt+0x2, WREG 02E2 0140 00460 movwf GetTrackingData_LowCounter 00461 SEND_PHONE_W 02E3 E18E M call TxPhoneBlocking 00462 02E4 6A60 00463 movfp g_readpkt+0x3, WREG 02E5 0141 00464 movwf GetTrackingData_HighCounter 00465 SEND_PHONE_W 02E6 E18E M call TxPhoneBlocking 00466 00467 ;; From this point on, we use GetTrackingData_counter as an error counter while reading 00468 ;; records from the GPS. When we get a valid packet, we reset it to zero. For any 00469 ;; timeout, we increment it. If it ever reaches four, we bail. 00470 02E7 297D 00471 clrf GetTrackingData_counter, F ; start with zero errors. 02E8 00472 GetTrackingData_GetNextRecord 02E8 E214 00473 call ReadPacket 02E9 980A 00474 btfsc WREG, 0 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 40 LOC OBJECT CODE LINE SOURCE TEXT VALUE 02EA C2EE 00475 goto GetTrackingData_GotData 02EB 157D 00476 incf GetTrackingData_counter, F 02EC 9A7D 00477 btfsc GetTrackingData_counter, 2 ; if we reach 2^2 (=2) errors, bail. 02ED B600 00478 retlw 0x0 00479 02EE 00480 GetTrackingData_GotData 02EE B022 00481 movlw Pid_Trk_Data 02EF 045D 00482 subwf g_readpkt, W 02F0 9A04 00483 skpnz 02F1 C2F7 00484 goto GetTrackingData_IsTrk 02F2 B00C 00485 movlw Pid_Xfer_Cmplt 02F3 045D 00486 subwf g_readpkt, W 02F4 9204 00487 skpz 02F5 C2E8 00488 goto GetTrackingData_GetNextRecord ; unexpected packet; try again. 02F6 B601 00489 retlw 0x1 ; got the "end of transfer" packet, so we're done. 00490 02F7 00491 GetTrackingData_IsTrk 00492 02F7 B05F 00493 movlw g_readpkt+0x2 02F8 0101 00494 movwf FSR0 02F9 B00D 00495 movlw D'13' ; Send the 13 data bytes to the phone. 02FA 017D 00496 movwf GetTrackingData_counter 02FB 00497 GetTrackingData_SendData 02FB 6A00 00498 movfp INDF0, WREG 00499 SEND_PHONE_W 02FC E18E M call TxPhoneBlocking 02FD 177D 00500 decfsz GetTrackingData_counter, F 02FE C2FB 00501 goto GetTrackingData_SendData 00502 00503 ;; Note that GetTrackingData_counter is zero when it gets this far (as it should be, 00504 ;; for the error count while waiting for a packet above). 00505 02FF 280A 00506 clrf WREG, W ; if we're out of records, we're done. 00507 ;; 4/7/00: we don't care how many we've got. We wait for timeout or reception of the Xfer_Cmplt packet. 0300 C2E8 00508 goto GetTrackingData_GetNextRecord ; not many more, but still more... get the next one. 00509 00510 0301 00511 TimeoutString 0301 0D0A 5469 6D65 00512 data "\r\nTimeout waiting for packet\r\n", 0 6F75 7420 7761 6974 696E 6720 666F 7220 7061 636B 6574 0D0A 0000 00513 00078 #include "serial.asm" 00001 ;;; The serial routines here are from one of the application notes on Microchip's web site. 0311 00002 InitUART 0311 B034 00003 movlw baud(D'9600') ; set UART baud rate. 00004 0312 0117 00005 movwf SPBRG 0313 B020 00006 movlw B'00100000' ; turn on serial port transmitter 0314 0115 00007 movwf TXSTA MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 41 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0315 B090 00008 movlw B'10010000' ; turn on serial port receiver and the serial port itself 0316 0113 00009 movwf RCSTA 00010 0317 B055 00011 movlw 'U' 0318 E326 00012 call TxUARTBlocking 0319 B041 00013 movlw 'A' 031A E326 00014 call TxUARTBlocking 031B B052 00015 movlw 'R' 031C E326 00016 call TxUARTBlocking 031D B054 00017 movlw 'T' 031E E326 00018 call TxUARTBlocking 031F 0002 00019 return 00020 0320 00021 RxUARTBlocking 0320 B801 00022 movlb 1 0321 9016 00023 PollRcv btfss PIR^0x100, RCIF ; check RCIF bit 0322 C321 00024 goto PollRcv ; block until a char is received 0323 B800 00025 movlb 0 0324 540A 00026 movpf RCREG, WREG 0325 0002 00027 return 00028 00029 ;;; TxUARTBlocking sends whatever's in WREG. 0326 00030 TxUARTBlocking 0326 B801 00031 movlb 1 0327 00032 PollTXIF 0327 9116 00033 btfss PIR^0x100, TXIF ; check TXIF bit (PIR is bank 1). 0328 C327 00034 goto PollTXIF 0329 B800 00035 movlb 0 032A 0116 00036 movwf TXREG 032B 0002 00037 return 00038 00039 ;SerialTest 00040 ; ;; If there's any data from the Phone, send it to the GPS. 00041 ; clrf WREG, F 00042 ; cpfsgt PhoneRxLen 00043 ; goto RxPhone_bail 00044 ; call RxPhone 00045 ; call TxGPSBlocking 00046 ; 00047 ;RxPhone_bail 00048 ; ;; if there's any data from the GPS, send it out the phone. 00049 ; clrf WREG, F 00050 ; cpfsgt GPSRxLen 00051 ; goto SerialTest 00052 ; 00053 ; movlb 1 00054 ; btg PORTE^0x100, 0 ; debugging. Toggle E<0> when we send data. 00055 ; movlb 0 00056 ; call RxGPS 00057 ; call TxPhoneBlocking 00058 ; goto SerialTest 00059 00079 #include "quickcam.asm" MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 42 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00001 ;;; 00002 ;;; color quickcam definitions. 00003 ;;; 00004 ;; (These are bit numbers to toggle in the MODE we request for a SCAN.) 00005 ; #define CQC_1_1 (nothing) ; 0 decimation - full size 00006 #define CQC_BIDIR ; 1 bidirectional communication 00007 #define CQC_2_1 1 ; 2 half size 00008 #define CQC_4_1 2 ; 4 quarter size 00009 #define CQC_16BPP 3 ; 8 "thousands" of colors (only with compression) 00010 #define CQC_32BPP 4 ; 16 "billions" of colors 00011 #define CQC_24BPP 5 ; 32 "millions" of colors 00012 #define CQC_TEST_PATTERN 6 ; 64 no clue, but documented. 00013 00014 ; for 160x120 color pictures: mode 27 00015 ; for 320x240 color pictures: mode 25 00016 ; for 640x480 color pictures, must be in 32-bit mode 17 00017 00018 ;; Color quickcam command numbers: 00019 #define QC_SEND_FRAME D'7' ; aka SCAN 00020 #define QC_BRIGHTNESS D'11' 00021 #define QC_TOP D'13' 00022 #define QC_LEFT D'15' 00023 #define QC_HEIGHT D'17' 00024 #define QC_WIDTH D'19' 00025 #define QC_VERSION D'23' 00026 #define QC_LOAD_RAM D'27' 00027 #define QC_BLACK D'29' 00028 #define QC_WHITE D'31' 00029 #define QC_HUE D'33' 00030 #define QC_SATURATION D'35' 00031 #define QC_CONTRAST D'37' 00032 #define QC_STATUS D'41' 00033 #define QC_SPEED D'45' 00034 032C 00035 InitQuickcamHardware 032C B801 00036 movlb 1 00037 ; initialize CONTROL to something useful (like its normal state). 00038 ; we can't set the entire port, since it's used for other things. Set the 00039 ; individual bits. 032D 8211 00040 bsf LP_CONTROL^0x100, C2 ; inverted C0,1,3. 032E 8811 00041 bcf LP_CONTROL^0x100, C0 032F 8911 00042 bcf LP_CONTROL^0x100, C1 0330 8B11 00043 bcf LP_CONTROL^0x100, C3 0331 2913 00044 clrf LP_DATA^0x100, F 0332 8810 00045 bcf DR_CONTROL^0x100, C0 ; C0, 1, 2, 3 are outputs. 0333 8910 00046 bcf DR_CONTROL^0x100, C1 ; C0, 1, 2, 3 are outputs. 0334 8A10 00047 bcf DR_CONTROL^0x100, C2 ; C0, 1, 2, 3 are outputs. 0335 8B10 00048 bcf DR_CONTROL^0x100, C3 ; C0, 1, 2, 3 are outputs. 0336 2912 00049 clrf DR_DATA^0x100, F ; outputs. 00050 0337 B800 00051 movlb 0 0338 8B12 00052 bcf LP_STATUS, 3 ; turn off S3 through S7 0339 8C12 00053 bcf LP_STATUS, 4 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 43 LOC OBJECT CODE LINE SOURCE TEXT VALUE 033A 8D12 00054 bcf LP_STATUS, 5 033B 8E12 00055 bcf LP_STATUS, 6 033C 8F12 00056 bcf LP_STATUS, 7 00057 033D 8311 00058 bsf DR_STATUS, 3 ; then set them as inputs 033E 8411 00059 bsf DR_STATUS, 4 033F 8511 00060 bsf DR_STATUS, 5 0340 8611 00061 bsf DR_STATUS, 6 0341 8711 00062 bsf DR_STATUS, 7 00063 0342 0002 00064 return 00065 0343 00066 qc_initparams 00067 ;; set the file registers associated with the quickcam to their initial values. 0343 B0B4 00068 movlw D'180' 0344 0129 00069 movwf qc_contrast 0345 B096 00070 movlw D'150' 0346 0128 00071 movwf qc_brightness 0347 0002 00072 return 00073 00074 ;;; 00075 ;;; qc_init initializes the firmware in the quickcam. 00076 ;;; 0348 00077 qc_init 0348 B801 00078 movlb 1 00079 ;; initialize the hardware. 0349 B075 00080 movlw 0x75 034A 0113 00081 movwf LP_DATA^0x100 00082 WAIT 0x1 034B B001 M movlw 0x1 034C E58A M call Waiter 00083 00084 ;; set the individual bits for the control port. Can't set the entire word 00085 ;; because the port also does other things. 034D 8811 00086 bcf LP_CONTROL^0x100, C0 ; inverted C0,1,3 on the parallel port (%1101) 034E 8911 00087 bcf LP_CONTROL^0x100, C1 034F 8A11 00088 bcf LP_CONTROL^0x100, C2 0350 8B11 00089 bcf LP_CONTROL^0x100, C3 0351 B800 00090 movlb 0 00091 00092 ;; sleep (at least) 250 usecs 00093 USLEEP 250 0000 M LOCAL loopomatic M ;; each loop takes at least 3 cycles, so we loop 1/3 of 2063 loops. M ; movlb 0 0352 B000 M movlw high((250/(D'120000000'/ClkFreq))/10) 0353 012B M movwf COUNT2 0354 B00C M movlw low((250/(D'120000000'/ClkFreq))/10) 0355 012A M movwf COUNT1 0356 M loopomatic 0356 172A M decfsz COUNT1, F ; 3 cycles to each lower count, 2 at the end 0357 C356 M goto loopomatic 0358 172B M decfsz COUNT2, F ; 3 cycles to each high cont, 2 at the end MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 44 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0359 C356 M goto loopomatic 00094 035A B801 00095 movlb 1 00096 ;; again, set the individual bits. 035B 8011 00097 bsf LP_CONTROL^0x100, C0 ; inverted C0,1,3 again. (%1110) 035C 8911 00098 bcf LP_CONTROL^0x100, C1 035D 8211 00099 bsf LP_CONTROL^0x100, C2 035E 8B11 00100 bcf LP_CONTROL^0x100, C3 035F B800 00101 movlb 0 00102 00103 ;;; pause a little before continuing. 00104 WAIT 0x1 0360 B001 M movlw 0x1 0361 E58A M call Waiter 0362 0002 00105 return 00106 00107 00108 ;;; Command takes a command in WREG. Returns the value that the camera sends us 00109 ;;; on S4-S7 (in two nibbles) in SAVE_RETVAL and W (just in case we want to use 00110 ;;; it one way or the other). 0363 00111 Command 0363 B801 00112 movlb 1 0364 0113 00113 movwf LP_DATA^0x100 0365 8311 00114 bsf LP_CONTROL^0x100, C3 ; set C3. 0366 B800 00115 movlb 0 00116 00117 WAIT 0x1 ; wait for the cam to have time... 0367 B001 M movlw 0x1 0368 E58A M call Waiter 00118 0369 802C 00119 bsf qc_hsval, 0 ; wait for a 1 from the qcam on S3 036A E37E 00120 call Handshake 036B 012D 00121 movwf qc_save_retval ; save the command it returns in S4-S7 036C B801 00122 movlb 1 036D 8B11 00123 bcf LP_CONTROL^0x100, C3 ; clear C3 to tell the cam we got it 036E B800 00124 movlb 0 00125 00126 WAIT 0x1 ; give the cam time to see it 036F B001 M movlw 0x1 0370 E58A M call Waiter 00127 0371 882C 00128 bcf qc_hsval, 0 ; wait for a 0 from the qcam on S3 0372 E37E 00129 call Handshake 0373 8804 00130 clc ; take this retval and roll right 4 0374 190A 00131 rrcf WREG, F ; bits (it's the low nibble of its 0375 8804 00132 clc ; response). Then OR that with the 0376 190A 00133 rrcf WREG, F ; high nibble (returned from the 0377 8804 00134 clc ; previous Handshake) and return 0378 190A 00135 rrcf WREG, F ; that value as the "result" of 0379 8804 00136 clc ; sending this command. (For actual 037A 190A 00137 rrcf WREG, F ; commands, this should be the same 037B 092D 00138 iorwf qc_save_retval, F ; as the command we sent; when taking 037C 6A2D 00139 movfp qc_save_retval, WREG ; a picture, this is a data value.) MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 45 LOC OBJECT CODE LINE SOURCE TEXT VALUE 037D 0002 00140 return 00141 00142 ;;; Handshake takes a 1 or 0 in qc_hsval, returns when S3==qc_hsval<0> 00143 ;;; Added qc_Handshake_Timer 4/7/00. 00144 ;;; Temoporarily removed it again on 4/10/00 while testing the color qcam. 037E 00145 Handshake 00146 ; clrf qc_Handshake_Timer, F 037E 00147 Handshake_Loop 00148 WAIT 0x1 037E B001 M movlw 0x1 037F E58A M call Waiter 00149 ; decf qc_Handshake_Timer, F 00150 ; skpnz 00151 ; retlw 0x0 ; Timer expired (took too long), so bail out. 00152 0380 6A12 00153 movfp LP_STATUS, WREG ; copy LP_STATUS into WREG so that we don't 0381 982C 00154 btfsc qc_hsval, 0 ; read it twice to get the returned value. 0382 C386 00155 goto Handshake_WaitForOne ; If waiting for a 1, goto HS2. 0383 930A 00156 btfss WREG, S3 ; waiting for a 0. 0384 C389 00157 goto Handshake_Done ; got a 0, so clean up and exit. 0385 C37E 00158 goto Handshake_Loop ; didn't get a zero, so do it again. 0386 00159 Handshake_WaitForOne 0386 9B0A 00160 btfsc WREG, S3 ; waiting for a 1. 0387 C389 00161 goto Handshake_Done ; got a 1, so clean up and exit. 0388 C37E 00162 goto Handshake_Loop ; didn't get a 1, so do it again. 0389 00163 Handshake_Done 0389 3F0A 00164 btg WREG, 7 ; bit 7 of status is inverted. Un-invert it. 038A 012E 00165 movwf qc_returned ; We only want the high 4 bits of the returned 038B B0F0 00166 movlw 0xf0 ; value. Strip off the low nibble, and return 038C 0A2E 00167 andwf qc_returned, W ; the high nibble in W. (qc_returned has the 00168 ; un-anded value in it.) 038D 0002 00169 return 00170 00171 ;;; Set up the quickcam properties (brightness, height, width...). 00172 ;;; The brightness and contrast values are in the page 1 file locations 00173 ;;; qc_brightness and qc_contrast. (Likewise the other params.) 00174 ;;; We're now ignoring errors and not reporting them in any way. We 00175 ;;; used to report them, but everything's working smoothly now; we 00176 ;;; just need to put a timeout on the picture taking itself. 00177 038E 00178 Quickcam_Set_Params 00179 QCMD D'45', D'2' ; for color quickcams, per Connectix documentation. Always 2. 038E B02D M movlw D'45' 038F E363 M call Command 0390 B002 M movlw D'2' 0391 E363 M call Command 00180 0392 B00B 00181 movlw QC_BRIGHTNESS 0393 E363 00182 call Command 0394 6A28 00183 movfp qc_brightness, WREG 0395 E363 00184 call Command 00185 0396 B011 00186 movlw QC_HEIGHT MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 46 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0397 E363 00187 call Command 0398 B0F0 00188 movlw 0xF0 ; 320x240 height 0399 E363 00189 call Command 00190 039A B013 00191 movlw QC_WIDTH 039B E363 00192 call Command 039C B0A0 00193 movlw 0xA0 ; "width" (really some bizarre hack, related to 039D E363 00194 call Command ; width) 00195 00196 QCMD QC_TOP, 0x1 039E B00D M movlw D'13' 039F E363 M call Command 03A0 B001 M movlw 0x1 03A1 E363 M call Command 00197 00198 QCMD QC_LEFT, 0x7 ; should this be 0xB for a color quickcam? 03A2 B00F M movlw D'15' 03A3 E363 M call Command 03A4 B007 M movlw 0x7 03A5 E363 M call Command 00199 03A6 B025 00200 movlw QC_CONTRAST ; contrast 03A7 E363 00201 call Command 03A8 6A29 00202 movfp qc_contrast, WREG 03A9 E363 00203 call Command 00204 00205 QCMD QC_WHITE, D'130' ; used D'70' for old b/w quickcam; default was 105? 03AA B01F M movlw D'31' 03AB E363 M call Command 03AC B082 M movlw D'130' 03AD E363 M call Command 03AE 0002 00206 return 00207 03AF 00208 Quickcam_ClearBrightnessTable 03AF 292F 00209 clrf qc_BR0L, F 03B0 2930 00210 clrf qc_BR0H, F 03B1 0002 00211 return 00212 00213 ;;; 00214 ;;; Quickcam_GuessBrightness repeatedly calls qc_scan in "averaging" mode (which doesn't send 00215 ;;; serial data) until it guesses a good brightness. Then it lets it go. 00216 ;;; 03B2 00217 Quickcam_GuessBrightness 03B2 8131 00218 bsf QC_FLAGS, AVERAGING ; averaging. Don't send. 03B3 B00A 00219 movlw D'10' ; start with a brightness of 10. 03B4 0128 00220 movwf qc_brightness 00221 03B5 00222 guessagain 03B5 B801 00223 movlb 1 03B6 3A15 00224 btg PORTE^0x100, 2 ; flash the LED on port E, pin 2 so we can tell. 03B7 B800 00225 movlb 0 00226 03B8 E3AF 00227 call Quickcam_ClearBrightnessTable MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 47 LOC OBJECT CODE LINE SOURCE TEXT VALUE 03B9 E3DF 00228 call qc_scan 00229 03BA B0FA 00230 movlw D'250' 03BB 3028 00231 cpfslt qc_brightness 03BC 0002 00232 return ; if the brightness is 250 or above, we've gone too far. Bail out. 00233 00234 ; if more than 50% of the pixels were counted as "near black", then it's too dark 00235 ; (160*120/2 = 0x2580 pixels). For simplicity, we use 0x2600 pixels (9728) instead (50.7%). 00236 ; 00237 ; 0x21 is a good value, but a little washed out in a dark mixed environment. 00238 03BD B025 00239 movlw 0x25 ; test high byte of counter. Return if <= 0x25. 03BE 3230 00240 cpfsgt qc_BR0H 03BF 0002 00241 return 00242 00243 ;; The picture is too dark. Increment the brightness and try again. 03C0 6A28 00244 movfp qc_brightness, WREG 03C1 B10A 00245 addlw D'10' ; add 10 to the brightness and try again. 03C2 0128 00246 movwf qc_brightness 03C3 E348 00247 call qc_init ; re-initialize the quickcam. 03C4 C3B5 00248 goto guessagain 00249 03C5 00250 increment_br_counter 03C5 8804 00251 clc 03C6 152F 00252 incf qc_BR0L, F ; increment BR0L. 03C7 9804 00253 btfsc ALUSTA, C ; If BR0L rolled over, increment BR0H. 03C8 1530 00254 incf qc_BR0H, F 03C9 0002 00255 return 00256 03CA 00257 Quickcam_Average_StoreW 03CA 011F 00258 movwf TEMP_WREG 00259 ;; store the high nibble (WREG >> 4) 03CB 8804 00260 clc 03CC 190A 00261 rrcf WREG, F 03CD 8804 00262 clc 03CE 190A 00263 rrcf WREG, F 03CF 8804 00264 clc 03D0 190A 00265 rrcf WREG, F 03D1 8804 00266 clc 03D2 190A 00267 rrcf WREG, F 00268 03D3 0132 00269 movwf qc_tempbr ; if the brightness is near black, increment BR0L / BR0H. 03D4 B003 00270 movlw TOO_DARK 03D5 3232 00271 cpfsgt qc_tempbr 03D6 E3C5 00272 call increment_br_counter 00273 03D7 00274 BR_STORELOW 00275 ;; store the low nibble (WREG & 0x0F) 03D7 B00F 00276 movlw 0x0f 03D8 0A1F 00277 andwf TEMP_WREG, W ; get back the data (into W) 00278 03D9 0132 00279 movwf qc_tempbr ; if the brightness is near black, increment br0l/br0h. 03DA B003 00280 movlw TOO_DARK MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 48 LOC OBJECT CODE LINE SOURCE TEXT VALUE 03DB 3232 00281 cpfsgt qc_tempbr 03DC E3C5 00282 call increment_br_counter 03DD 0002 00283 return 00284 00285 ;;; 00286 ;;; 00287 ;;; 03DE 00288 Quickcam_ScanAndSend 03DE 8931 00289 bcf QC_FLAGS, AVERAGING ; sending data, not averaging. 03DF 00290 qc_scan 03DF E38E 00291 call Quickcam_Set_Params ; reset the camera state. 00292 00293 ;FINISH MODIFYING FROM HERE 00294 ;quickcam notes: 00295 ; 00296 ; qc_savedata, qc_savecounter and qc_counter 00297 ; clear qc_savedata and qc_counter and qc_savecounter 00298 ; 00299 ; read two 24-bit words of data, one octet at a time 00300 ; set qc_counter to 6; roll data right two bits 00301 ; while qc_counter > 0: 00302 ; roll the bit from current read on to qc_savedata and increment qc_counter 00303 ; if (qc_savecounter == 8) { 00304 ; write the data 00305 ; clear qc_savecounter and qc_savedata 00306 ; } 00307 ; decrement qc_counter 00308 ; repeat for each byte 00309 ; 00310 ; 00311 ; 00312 ;ddddd 03E0 9931 00313 btfsc QC_FLAGS, AVERAGING ; if averaging, don't send mode... 03E1 C3E2 00314 goto doscan 00315 03E2 00316 doscan 03E2 B007 00317 movlw 0x7 ; send a scan command to the camera with the mode 03E3 E363 00318 call Command ; that's specified in the configuration. The mode 03E4 6A33 00319 movfp qc_mode, WREG ; tells it what size and bit-depth to use. 03E5 9231 00320 btfss QC_FLAGS, QC_COLOR 03E6 C3EC 00321 goto doscan_callCommand ; if it's a b/w qcam, move along. 00322 03E7 B018 00323 movlw D'24' ; 320x240 24-bit color picture 03E8 850A 00324 bsf WREG, CQC_24BPP 03E9 9131 00325 btfss QC_FLAGS, AVERAGING 03EA B01A 00326 movlw D'26' ; 160x120 24-bit color picture 03EB 150A 00327 incf WREG, F ; According to the docs, color quickcams should send MODE+1. 00328 03EC 00329 doscan_callCommand 03EC E363 00330 call Command 00331 03ED 00332 readbytes 00333 ;; Figure out how many bytes to read. Once we've got the right number, start MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 49 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00334 ;; scanning. 00335 00336 ;; read the correct values out of the table 'scannums'. 03ED B004 00337 movlw HIGH (scannums) 03EE 4A0E 00338 movpf WREG, TBLPTRH 03EF B029 00339 movlw LOW (scannums) 03F0 4A0D 00340 movpf WREG, TBLPTRL 00341 03F1 6A33 00342 movfp qc_mode, WREG 03F2 8804 00343 clc 03F3 190A 00344 rrcf WREG, F ; w /= 2 03F4 0F0D 00345 addwf TBLPTRL, F 03F5 9804 00346 btfsc ALUSTA, C ; if carry is set, we need to increment tablptrh (table 03F6 150E 00347 incf TBLPTRH, F ; spans two pages). 00348 03F7 A80A 00349 tablrd 0, 0, WREG ; dummy read; updates tablatch. 03F8 A22A 00350 tlrd 1, COUNT1 ; Read hi byte of tablatch. 03F9 A92B 00351 tablrd 0, 1, COUNT2 ; Read low byte of TABLATCH and increment it. 00352 03FA 8B31 00353 bcf QC_FLAGS, SCAN_STARTED ; for color quickcam start-of-picture detection. 00354 00355 ;;; Actually read the bytes here. This loops until it should be done. There should be a time-out 00356 ;;; on this action in case something happens in the middle of it! 03FB 00357 readbytes_loop 03FB B000 00358 movlw 0x0 ; clear W so that we don't send a command. 03FC E363 00359 call Command ; This doesn't actually send a command; it just 00360 ; handshakes and reads the result. 00361 00362 ;; if we're doing a color picture, then continue. 03FD 9231 00363 btfss QC_FLAGS, QC_COLOR 03FE C40F 00364 goto readbytes_notcolor 00365 00366 ;; color quickcams need to read 6x as much data (4 bit vs. 24 bit). 00367 ;; for this version, we're going to take the final blue data and reduce 00368 ;; it into a B&W picture based solely on the blue channel. Not the prettiest. 00369 00370 SEND_PHONE_W ; send WREG via serial if we're not averaging. 03FF E18E M call TxPhoneBlocking 0400 B000 00371 movlw 0x0 ; read green byte. 0401 E363 00372 call Command 00373 SEND_PHONE_W ; send WREG via serial if we're not averaging. 0402 E18E M call TxPhoneBlocking 0403 B000 00374 movlw 0x0 ; read blue byte. 0404 E363 00375 call Command 00376 SEND_PHONE_W ; send WREG via serial if we're not averaging. 0405 E18E M call TxPhoneBlocking 00377 ; andlw 0xF0 ; take the top 4 bits of the blue byte... 00378 ; movwf qc_bluedata ; ... and save them for later. 0406 B000 00379 movlw 0x0 ; read second red byte 0407 E363 00380 call Command 00381 SEND_PHONE_W ; send WREG via serial if we're not averaging. 0408 E18E M call TxPhoneBlocking 0409 B000 00382 movlw 0x0 ; read second green byte MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 50 LOC OBJECT CODE LINE SOURCE TEXT VALUE 040A E363 00383 call Command 00384 SEND_PHONE_W ; send WREG via serial if we're not averaging. 040B E18E M call TxPhoneBlocking 040C B000 00385 movlw 0x0 ; read second blue byte 040D E363 00386 call Command 00387 00388 ;; Generate the calculated greyscale info from those two 24-bit color 00389 ;; pieces of data. We're just saving 4 bits of data, which looks fairly 00390 ;; ugly, but it's the easiest modification. 00391 00392 ;; It would be better to average r/g/b for each byte, take at least 5 bits 00393 ;; of that, and send that data. That would be difficult, though, because the 00394 ;; bit/byte boundaries don't line up. 00395 00396 ; rrcf WREG, F ; take the top 4 bits of the blue byte, and 00397 ; rrcf WREG, F ; rotate into the low nibble of WREG... 00398 ; rrcf WREG, F 00399 ; rrcf WREG, F 00400 ; andlw 0x0F ; ... mask against just the low nibble (since we rolled in carry data). .. 00401 ; iorwf qc_bluedata, W ; ... and combine with the previous 4 bits. 00402 040E 00403 readbytes_reducecolordata 040E 6A52 00404 movfp qc_bluedata, WREG 00405 00406 040F 00407 readbytes_notcolor 040F 9931 00408 btfsc QC_FLAGS, AVERAGING 0410 C412 00409 goto readbytes_1 00410 SEND_PHONE_W ; send WREG via serial if we're not averaging. 0411 E18E M call TxPhoneBlocking 0412 00411 readbytes_1 0412 9931 00412 btfsc QC_FLAGS, AVERAGING 0413 E3CA 00413 call Quickcam_Average_StoreW ; store the data if we're averaging. 00414 0414 172B 00415 decfsz COUNT2, F ; COUNT2--; loop if it's not zero yet 0415 C3FB 00416 goto readbytes_loop 0416 172A 00417 decfsz COUNT1, F ; COUNT1--; loop if it's not zero yet 0417 C3FB 00418 goto readbytes_loop 00419 0418 00420 done_readbytes 0418 9931 00421 btfsc QC_FLAGS, AVERAGING 0419 0002 00422 return ; don't send the EOF if we're averaging. 00423 SEND_PHONE 'E' 041A B045 M movlw 'E' 041B E18E M call TxPhoneBlocking 00424 SEND_PHONE 'O' 041C B04F M movlw 'O' 041D E18E M call TxPhoneBlocking 00425 SEND_PHONE 'F' 041E B046 M movlw 'F' 041F E18E M call TxPhoneBlocking 0420 0002 00426 return MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 51 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00427 0421 00428 Quickcam_TakePicture 0421 B801 00429 movlb 1 0422 8115 00430 bsf PORTE^0x100, 1 ; turn on the LED 0423 B800 00431 movlb 0 00432 ;; temporarily don't guess brightness; just use the default. 00433 ; call Quickcam_GuessBrightness 00434 0424 E348 00435 call qc_init ; re-initialize the quickcam. 0425 E3DE 00436 call Quickcam_ScanAndSend 00437 0426 B801 00438 movlb 1 0427 8915 00439 bcf PORTE^0x100, 1 ; turn off LED 0428 0002 00440 return 00441 00442 ;;; 00443 ;;; Data tables. 00444 ;;; 00445 0429 00446 scannums 00447 ;; number of line scans for each scan mode: 0429 9600 E100 00448 dw 0x9600, 0xE100 ; 320x240, 4bpp or 6bpp 042B 2680 3940 00449 dw 0x2680, 0x3940 ; 160x120, 4bpp or 6bpp 042D 0A60 0F10 00450 dw 0x0A60, 0x0F10 ; 80x60, 4bpp or 6bpp 00451 042F 00452 scansizes 00453 ;; size (high byte=height, low byte=width) for each scan mode. 00454 ;; these are the numbers passed to the height and width commands 00455 ;; when configuring the quickcam. 042F F0A0 F050 00456 dw 0xF0A0, 0xF050 ; 320x240, 4bpp or 6bpp 0431 7850 7828 00457 dw 0x7850, 0x7828 ; 160x120, 4bpp or 6bpp 0433 3C28 3C14 00458 dw 0x3C28, 0x3C14 ; 80x60, 4bpp or 6bpp 00459 00460 0435 00461 BriString 0435 6272 693A 0000 00462 data "bri:", 0 0438 00463 ModeString 0438 4D6F 6465 3A00 00464 data "Mode:", 0 0000 043C 00465 ScanString 043C 5363 616E 3A00 00466 data "Scan:", 0 0000 00467 00080 #include "phone.asm" 00001 ;;; phone.asm 00002 0440 00003 InitPhone 0440 2927 00004 clrf Phone_Mode, F 0441 8811 00005 bcf DR_POWER, POWER_QCAM ; set as output... 0442 0002 00006 return 00007 00008 ;;; 00009 ;;; BLOCK_UNTIL_PHONE_DATA will wait for data to be available on the MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 52 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00010 ;;; Phone serial port. It sets Phone_HaveData to 0xFF, and then clears 00011 ;;; it if we time out. 00012 ;;; 00013 ;;; The delay when timing out is a human-tangible amount (256 loops in 00014 ;;; a wait timer, plus two external loops around that for 65536 more). 00015 ;;; At 33 MHz, it's probably about 8 seconds. We should be able to wrap 00016 ;;; this macro, therefore keeping some rough estimate of how long we've 00017 ;;; been waiting for the correct data. 00018 00019 BLOCK_UNTIL_PHONE_DATA MACRO 00020 LOCAL TryAgain 00021 LOCAL HaveData 00022 clrf Phone_TimerLow, F 00023 clrf Phone_TimerHigh, F 00024 setf Phone_HaveData, F ; assume that we will receive data. 00025 TryAgain 00026 clrf WREG, F 00027 cpfseq PhoneRxLen 00028 goto HaveData 00029 WAIT 0x0 00030 incfsz Phone_TimerLow, F 00031 goto TryAgain 00032 incfsz Phone_TimerHigh, F 00033 goto TryAgain 00034 00035 clrf Phone_HaveData, F ; no data; clear the "we have data" flag. 00036 HaveData 00037 ENDM 00038 00039 00040 ;;; block for about 1 second... 00041 SLEEP1 MACRO 00042 LOCAL SleepLoop 00043 movlw 0x0 00044 movwf Sleep1_TimerLow 00045 movlw 0x36 00046 movwf Sleep1_TimerHigh 00047 SleepLoop 00048 WAIT 0x80 00049 decfsz Sleep1_TimerLow, F 00050 goto SleepLoop 00051 decfsz Sleep1_TimerHigh, F 00052 goto SleepLoop 00053 ENDM 00054 00055 ;;; block for about 1 minute... 00056 SLEEP1M MACRO 00057 LOCAL SleepLoop 00058 movlw D'60' 00059 movwf Sleep1M_Timer 00060 SleepLoop 00061 SLEEP1 00062 decfsz Sleep1M_Timer, F MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 53 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00063 goto SleepLoop 00064 ENDM 00065 00066 SLEEP20M MACRO 00067 LOCAL SleepLoop 00068 movlw D'20' 00069 movwf Sleep20M_Timer 00070 SleepLoop 00071 SLEEP1M 00072 decfsz Sleep20M_Timer, F 00073 goto SleepLoop 00074 ENDM 00075 00076 ;;; 00077 ;;; set ExpectPhoneMsg_high, ExpectPhoneMsg_low, ExpectPhone_timeout 00078 ;;; 00079 0443 00080 ExpectPhoneMsg 0443 2947 00081 clrf ExpectPhone_counter, F 0444 00082 ExpectPhoneMsg_restart 0444 6E48 00083 movfp ExpectPhoneMsg_high, TBLPTRH 0445 6D49 00084 movfp ExpectPhoneMsg_low, TBLPTRL 0446 A90A 00085 tablrd 0, 1, WREG ; Read low byte of TABLATCH and reload with the next word. 0447 A94C 00086 tablrd 0, 1, ExpectPhone_expectChar 0448 334C 00087 tstfsz ExpectPhone_expectChar 0449 C44F 00088 goto ExpectPhoneMsg_read 044A B601 00089 retlw 0x1 ; if we reach a 0 char, we're done. Return success. 00090 044B 00091 ExpectPhoneMsg_readChar 044B 1547 00092 incf ExpectPhone_counter, F 044C 6A47 00093 movfp ExpectPhone_counter, WREG 044D 324E 00094 cpfsgt ExpectPhone_timeout 044E B600 00095 retlw 0x0 ; if ExpectPhone_counter >= ExpectPhone_timeout, return 0 044F 00096 ExpectPhoneMsg_read 00097 BLOCK_UNTIL_PHONE_DATA 0000 M LOCAL TryAgain 0000 M LOCAL HaveData 044F 2944 M clrf Phone_TimerLow, F 0450 2945 M clrf Phone_TimerHigh, F 0451 2B46 M setf Phone_HaveData, F ; assume that we will receive data. 0452 M TryAgain 0452 290A M clrf WREG, F 0453 31F1 M cpfseq PhoneRxLen 0454 C45C M goto HaveData M WAIT 0x0 0455 B000 M movlw 0x0 0456 E58A M call Waiter 0457 1F44 M incfsz Phone_TimerLow, F 0458 C452 M goto TryAgain 0459 1F45 M incfsz Phone_TimerHigh, F 045A C452 M goto TryAgain M 045B 2946 M clrf Phone_HaveData, F ; no data; clear the "we have data" flag. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 54 LOC OBJECT CODE LINE SOURCE TEXT VALUE 045C M HaveData 045C 9046 00098 btfss Phone_HaveData, 0 ; if Phone_HaveData, we're cool. 045D C44B 00099 goto ExpectPhoneMsg_readChar ; if not, try again. 045E E1A3 00100 call RxPhone 045F 044C 00101 subwf ExpectPhone_expectChar, W 0460 9204 00102 skpz 0461 C444 00103 goto ExpectPhoneMsg_restart ; got the wrong char; start over. 00104 0462 A94C 00105 tablrd 0, 1, ExpectPhone_expectChar 0463 334C 00106 tstfsz ExpectPhone_expectChar 0464 C44F 00107 goto ExpectPhoneMsg_read ; continue... 0465 B601 00108 retlw 0x1 ; if we reach a 0 char, we're done. Return success. 00109 00110 ;;; 00111 ;;; 00112 ;;; 00113 00114 EXPECT MACRO String, Timeout 00115 movlw LOW(String) 00116 movwf ExpectPhoneMsg_low 00117 movlw HIGH(String) 00118 movwf ExpectPhoneMsg_high 00119 movlw Timeout 00120 movwf ExpectPhone_timeout 00121 call ExpectPhoneMsg 00122 ENDM 00123 00124 ;;; 00125 ;;; BigSleep is its own function so that either the SLEEP1M or SLEEP20M macros 00126 ;;; can return 0x0 from within them to bail out of the big sleep. 00127 ;;; 00128 0466 00129 BigSleep 00130 ;; turn off LEDs before sleeping. 0466 B801 00131 movlb 0x1 0467 8815 00132 bcf PORTE^0x100, 0 0468 8915 00133 bcf PORTE^0x100, 1 0469 8A15 00134 bcf PORTE^0x100, 2 046A B800 00135 movlb 0x0 046B E502 00136 call powerdown_peripherals ; turn off power to the qcam, phone, what have you. 00137 SLEEP20M ; returns 0x0 in WREG for us if the user button is pressed 0000 M LOCAL SleepLoop 046C B014 M movlw D'20' 046D 0151 M movwf Sleep20M_Timer 046E M SleepLoop M SLEEP1M 0000 M LOCAL SleepLoop 046E B03C M movlw D'60' 046F 0150 M movwf Sleep1M_Timer 0470 M SleepLoop M SLEEP1 0000 M LOCAL SleepLoop 0470 B000 M movlw 0x0 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 55 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0471 014A M movwf Sleep1_TimerLow 0472 B036 M movlw 0x36 0473 014B M movwf Sleep1_TimerHigh 0474 M SleepLoop M WAIT 0x80 0474 B080 M movlw 0x80 0475 E58A M call Waiter 0476 174A M decfsz Sleep1_TimerLow, F 0477 C474 M goto SleepLoop 0478 174B M decfsz Sleep1_TimerHigh, F 0479 C474 M goto SleepLoop 047A 1750 M decfsz Sleep1M_Timer, F 047B C470 M goto SleepLoop 047C 1751 M decfsz Sleep20M_Timer, F 047D C46E M goto SleepLoop 047E B601 00138 retlw 0x1 00139 00140 ;;; 00141 ;;; 00142 ;;; 00143 047F 00144 DialPhone 047F 29D1 00145 clrf PhoneTxLen, F ; flush the phone buffers... 0480 29F1 00146 clrf PhoneRxLen, F 00147 00148 ; bsf HWHS_PORT, DTR ; turn on DTR so the phone will listen to us 00149 ; DTR is now always asserted while the peripherals are on. 00150 00151 PHONEMSG ATString 0481 B005 M movlw HIGH(ATString) 0482 4A0E M movpf WREG, TBLPTRH 0483 B02A M movlw LOW(ATString) 0484 4A0D M movpf WREG, TBLPTRL 0485 E021 M call PrintMsgPhone 00152 SLEEP1 0000 M LOCAL SleepLoop 0486 B000 M movlw 0x0 0487 014A M movwf Sleep1_TimerLow 0488 B036 M movlw 0x36 0489 014B M movwf Sleep1_TimerHigh 048A M SleepLoop M WAIT 0x80 048A B080 M movlw 0x80 048B E58A M call Waiter 048C 174A M decfsz Sleep1_TimerLow, F 048D C48A M goto SleepLoop 048E 174B M decfsz Sleep1_TimerHigh, F 048F C48A M goto SleepLoop 0490 297E 00153 clrf DialPhone_ATZcounter, F 0491 00154 DialPhone_ResendATZ 0491 157E 00155 incf DialPhone_ATZcounter, F 0492 9B7E 00156 btfsc DialPhone_ATZcounter, 3 ; bail if we resend the ATZ too many times. 0493 B600 00157 retlw 0x0 ; if we do send too many of them, just bail. MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 56 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00158 00159 PHONEMSG ATZString 0494 B005 M movlw HIGH(ATZString) 0495 4A0E M movpf WREG, TBLPTRH 0496 B02D M movlw LOW(ATZString) 0497 4A0D M movpf WREG, TBLPTRL 0498 E021 M call PrintMsgPhone 00160 EXPECT OKString, 2 ; expect "OK" within about 16 seconds 0499 B05D M movlw LOW(OKString) 049A 0149 M movwf ExpectPhoneMsg_low 049B B005 M movlw HIGH(OKString) 049C 0148 M movwf ExpectPhoneMsg_high 049D B002 M movlw 2 049E 014E M movwf ExpectPhone_timeout 049F E443 M call ExpectPhoneMsg 04A0 900A 00161 btfss WREG, 0 04A1 C491 00162 goto DialPhone_ResendATZ 00163 00164 SLEEP1 0000 M LOCAL SleepLoop 04A2 B000 M movlw 0x0 04A3 014A M movwf Sleep1_TimerLow 04A4 B036 M movlw 0x36 04A5 014B M movwf Sleep1_TimerHigh 04A6 M SleepLoop M WAIT 0x80 04A6 B080 M movlw 0x80 04A7 E58A M call Waiter 04A8 174A M decfsz Sleep1_TimerLow, F 04A9 C4A6 M goto SleepLoop 04AA 174B M decfsz Sleep1_TimerHigh, F 04AB C4A6 M goto SleepLoop 00165 PHONEMSG ATDTString 04AC B005 M movlw HIGH(ATDTString) 04AD 4A0E M movpf WREG, TBLPTRH 04AE B030 M movlw LOW(ATDTString) 04AF 4A0D M movpf WREG, TBLPTRL 04B0 E021 M call PrintMsgPhone 00166 EXPECT CONNECTString, 6 ; expect 'CONNECT' within about 48 seconds 04B1 B060 M movlw LOW(CONNECTString) 04B2 0149 M movwf ExpectPhoneMsg_low 04B3 B005 M movlw HIGH(CONNECTString) 04B4 0148 M movwf ExpectPhoneMsg_high 04B5 B006 M movlw 6 04B6 014E M movwf ExpectPhone_timeout 04B7 E443 M call ExpectPhoneMsg 04B8 900A 00167 btfss WREG, 0 04B9 B600 00168 retlw 0x0 00169 ;; This sleep1 may be too much to handle at this stage. Removing it. -- 4/7/00 00170 ;; SLEEP1 00171 00172 EXPECT LoginString, 3 ; expect 'login:' within about 24 seconds 04BA B068 M movlw LOW(LoginString) MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 57 LOC OBJECT CODE LINE SOURCE TEXT VALUE 04BB 0149 M movwf ExpectPhoneMsg_low 04BC B005 M movlw HIGH(LoginString) 04BD 0148 M movwf ExpectPhoneMsg_high 04BE B003 M movlw 3 04BF 014E M movwf ExpectPhone_timeout 04C0 E443 M call ExpectPhoneMsg 04C1 900A 00173 btfss WREG, 0 04C2 B600 00174 retlw 0x0 00175 SLEEP1 0000 M LOCAL SleepLoop 04C3 B000 M movlw 0x0 04C4 014A M movwf Sleep1_TimerLow 04C5 B036 M movlw 0x36 04C6 014B M movwf Sleep1_TimerHigh 04C7 M SleepLoop M WAIT 0x80 04C7 B080 M movlw 0x80 04C8 E58A M call Waiter 04C9 174A M decfsz Sleep1_TimerLow, F 04CA C4C7 M goto SleepLoop 04CB 174B M decfsz Sleep1_TimerHigh, F 04CC C4C7 M goto SleepLoop 04CD 00176 RunPhone_SendLogin 00177 PHONEMSG UsernameString 04CD B005 M movlw HIGH(UsernameString) 04CE 4A0E M movpf WREG, TBLPTRH 04CF B081 M movlw LOW(UsernameString) 04D0 4A0D M movpf WREG, TBLPTRL 04D1 E021 M call PrintMsgPhone 00178 EXPECT ExpectPasswordString, 3 ; expect 'Password:' within about 24 seconds 04D2 B06F M movlw LOW(ExpectPasswordString) 04D3 0149 M movwf ExpectPhoneMsg_low 04D4 B005 M movlw HIGH(ExpectPasswordString) 04D5 0148 M movwf ExpectPhoneMsg_high 04D6 B003 M movlw 3 04D7 014E M movwf ExpectPhone_timeout 04D8 E443 M call ExpectPhoneMsg 04D9 900A 00179 btfss WREG, 0 04DA B600 00180 retlw 0x0 00181 SLEEP1 0000 M LOCAL SleepLoop 04DB B000 M movlw 0x0 04DC 014A M movwf Sleep1_TimerLow 04DD B036 M movlw 0x36 04DE 014B M movwf Sleep1_TimerHigh 04DF M SleepLoop M WAIT 0x80 04DF B080 M movlw 0x80 04E0 E58A M call Waiter 04E1 174A M decfsz Sleep1_TimerLow, F 04E2 C4DF M goto SleepLoop 04E3 174B M decfsz Sleep1_TimerHigh, F 04E4 C4DF M goto SleepLoop MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 58 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00182 PHONEMSG SendPasswordString 04E5 B005 M movlw HIGH(SendPasswordString) 04E6 4A0E M movpf WREG, TBLPTRH 04E7 B084 M movlw LOW(SendPasswordString) 04E8 4A0D M movpf WREG, TBLPTRL 04E9 E021 M call PrintMsgPhone 00183 00184 EXPECT RunningString, 3 ; expect 'Running' within about 24 seconds 04EA B079 M movlw LOW(RunningString) 04EB 0149 M movwf ExpectPhoneMsg_low 04EC B005 M movlw HIGH(RunningString) 04ED 0148 M movwf ExpectPhoneMsg_high 04EE B003 M movlw 3 04EF 014E M movwf ExpectPhone_timeout 04F0 E443 M call ExpectPhoneMsg 04F1 900A 00185 btfss WREG, 0 04F2 C4CD 00186 goto RunPhone_SendLogin 00187 04F3 B601 00188 retlw 0x1 00189 04F4 00190 HangupPhone 00191 ; bcf HWHS_PORT, DTR ; turn off DTR to drop the connection 00192 ; now done automatically when peripherals are turned off. 04F4 0002 00193 return 00194 00195 ;;; 00196 ;;; 00197 ;;; 00198 04F5 00199 powerup_peripherals 04F5 8811 00200 bcf DR_POWER, POWER_QCAM ; set as output... 04F6 8012 00201 bsf POWER_PORT, POWER_QCAM ; turn on the power to the quickcam and phone HWHS. 00202 SLEEP1 ; (short wait for power to stabilize) 0000 M LOCAL SleepLoop 04F7 B000 M movlw 0x0 04F8 014A M movwf Sleep1_TimerLow 04F9 B036 M movlw 0x36 04FA 014B M movwf Sleep1_TimerHigh 04FB M SleepLoop M WAIT 0x80 04FB B080 M movlw 0x80 04FC E58A M call Waiter 04FD 174A M decfsz Sleep1_TimerLow, F 04FE C4FB M goto SleepLoop 04FF 174B M decfsz Sleep1_TimerHigh, F 0500 C4FB M goto SleepLoop 0501 0002 00203 return 00204 0502 00205 powerdown_peripherals 0502 8812 00206 bcf POWER_PORT, POWER_QCAM ; turn off the power... 0503 8011 00207 bsf DR_POWER, POWER_QCAM ; set as input to sink current... 0504 0002 00208 return 00209 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 59 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00210 ;;; 00211 ;;; 00212 ;;; 00213 00214 0505 00215 RunPhone 0505 B040 00216 movlw 0x40 ; clear the RAM from 0x40 to 0x80, 0506 0101 00217 movwf FSR0 ; resetting the state of all of the 0507 00218 RunPhone_clearRAM ; local variables. 0507 2900 00219 clrf INDF0, F 0508 410A 00220 movpf FSR0, WREG 0509 B280 00221 sublw 0x80 050A 9204 00222 skpz 050B C507 00223 goto RunPhone_clearRAM 00224 050C E4F5 00225 call powerup_peripherals 00226 00227 ;; Since we're turning off the quickcam between pictures, we need to 00228 ;; re-initialize its hardware for each run. 00229 050D E32C 00230 call InitQuickcamHardware ; init quickcam hardware 050E E348 00231 call qc_init ; init quickcam variables 050F E3B2 00232 call Quickcam_GuessBrightness ; guess brightness offline 0510 E348 00233 call qc_init ; reinit qcam variables 00234 00235 ;; The nitty gritty: dial, log in, and send the data. 00236 ;; temporarily removed 4/11/00: testing the camera locally 00237 IF 0 == 1 00238 call DialPhone 00239 btfss WREG, 0 00240 goto RunPhone_done 00241 ENDIF 00242 00243 ;; turn on E<0> while talking to the GPS 0511 B801 00244 movlb 0x1 0512 8015 00245 bsf PORTE^0X100, 0 0513 8915 00246 bcf PORTE^0X100, 1 0514 B800 00247 movlb 0x0 00248 00249 ;; eventually re-enable DCD drop detection? 00250 ;; PHONEMSG TimeString 00251 ;; btfsc HWHS_PORT, DCD 00252 ;; temporarily don't get the time. 00253 IF 0 == 1 00254 call GetTime 00255 btfss WREG, 0 00256 goto RunPhone_done 00257 ENDIF 00258 00259 ;; PHONEMSG PosnString 00260 ;; btfsc HWHS_PORT, DCD 00261 IF 0 == 1 00262 call GetPosn MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 60 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00263 btfss WREG, 0 00264 goto RunPhone_done 00265 ENDIF 00266 00267 ;; turn on E<1> while talking to the quickcam 0515 B801 00268 movlb 0x1 0516 8815 00269 bcf PORTE^0X100, 0 0517 8115 00270 bsf PORTE^0X100, 1 0518 B800 00271 movlb 0x0 00272 0519 E3DE 00273 call Quickcam_ScanAndSend ; already got a brightness above; take picture 00274 00275 00276 ; temporarily disabled: /always/ send the tracking data. 00277 ;; tstfsz Phone_Mode ; if Phone_Mode==0, send tracking data. 00278 ;; goto RunPhone_done 00279 00280 ;; turn on E<0> and E<1> while transferring tracking 051A B801 00281 movlb 0x1 051B 8015 00282 bsf PORTE^0X100, 0 051C 8115 00283 bsf PORTE^0X100, 1 051D B800 00284 movlb 0x0 00285 00286 ;; PHONEMSG TrackingString 00287 ;; btfsc HWHS_PORT, DCD 00288 00289 ;; temporarily disabled; testing the camera. 00290 IF 0 == 1 00291 call GetTrackingData 00292 ENDIF 00293 051E 00294 RunPhone_done 00295 PHONEMSG DoneString 051E B005 M movlw HIGH(DoneString) 051F 4A0E M movpf WREG, TBLPTRH 0520 B052 M movlw LOW(DoneString) 0521 4A0D M movpf WREG, TBLPTRL 0522 E021 M call PrintMsgPhone 0523 00296 RunPhone_wait 0523 33D1 00297 tstfsz PhoneTxLen 0524 C523 00298 goto RunPhone_wait ; wait for all of the data to be sent before disconnecting. 00299 00300 ;; HangupPhone is now useless, because we hang it up by turning off peripheral 00301 ;; power in the call to powerdown_peripherals. 00302 ; call HangupPhone 0525 E466 00303 call BigSleep ; wait for 20 minutes to elapse or the button to be pressed. 00304 0526 1527 00305 incf Phone_Mode, F 0527 9A27 00306 btfsc Phone_Mode, 2 ; reset when mode becomes 4. 0528 2927 00307 clrf Phone_Mode, F 0529 C505 00308 goto RunPhone 00309 052A 00310 ATString MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 61 LOC OBJECT CODE LINE SOURCE TEXT VALUE 052A 6174 0D00 0000 00311 data "at\r", 0 052D 00312 ATZString 052D 6174 7A0D 0000 00313 data "atz\r", 0 0530 00314 ATDTString 0530 6174 6474 3231 00315 data "atdt215XXXXXXX\r", 0 35XX XXXX XXXX XXXX 0D00 0000 0539 00316 TimeString 0539 0A54 696D 653A 00317 data "\nTime:\n", 0 0A00 0000 053E 00318 PosnString 053E 0A50 6F73 6974 00319 data "\nPosition:\n", 0 696F 6E3A 0A00 0000 0545 00320 TrackingString 0545 0A54 7261 636B 00321 data "\nTracking:\n", 0 696E 673A 0A00 0000 054C 00322 PictureString 054C 0A50 6963 7475 00323 data "\nPicture:\n", 0 7265 3A0A 0000 0552 00324 DoneString 0552 0A54 7261 6E73 00325 data "\nTransfer finished.\n", 0 6665 7220 6669 6E69 7368 6564 2E0A 0000 055D 00326 OKString 055D 004F 004B 0000 00327 dw 'O', 'K', 0 0560 00328 CONNECTString 0560 0043 004F 004E 00329 dw 'C', 'O', 'N', 'N', 'E', 'C', 'T', 0 004E 0045 0043 0054 0000 0568 00330 LoginString 0568 006C 006F 0067 00331 dw 'l', 'o', 'g', 'i', 'n', ':', 0 0069 006E 003A 0000 056F 00332 ExpectPasswordString 056F 0050 0061 0073 00333 dw 'P', 'a', 's', 's', 'w', 'o', 'r', 'd', ':', 0 0073 0077 006F 0072 0064 003A 0000 0579 00334 RunningString 0579 0052 0075 006E 00335 dw 'R', 'u', 'n', 'n', 'i', 'n', 'g', 0 006E 0069 006E 0067 0000 0581 00336 UsernameString 0581 XXXX XX0A 0000 00337 data "XXX\n", 0 0584 00338 SendPasswordString 0584 XXXX XXXX XXXX 00339 data "XXXXXXXX\n", 0 XXXX 0A00 0000 00340 00081 00082 ;;; Waiter is the routine that does the waiting (for the WAIT macro). The MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 62 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00083 ;;; number of loops (-1) that it will perform is in WREG. We leave as soon as 00084 ;;; WREG reaches 0 (therefore, passing in a 0 will do 0xFF loops). 058A 00085 Waiter 058A 170A 00086 decfsz WREG, F 058B C58A 00087 goto Waiter 058C 0002 00088 return 00089 058D 00090 InitHardware 058D 8710 00091 bsf PORTA, 7 ; turnoff pull-ups on port B (yes, the bit to do this is on PORTA) 00092 ; port A is always inputs. Pins 1-3 used to set camera mode. Pin 4 00093 ; is the "skip the 20 minute wait and just take a damn picture" button. 058E B801 00094 movlb 1 058F 2915 00095 clrf PORTE^0x100, F ; PORT E is current status... 0590 B000 00096 movlw B'000' ; E0, E1, E2 outputs. 0591 0114 00097 movwf DDRE^0x100 0592 B800 00098 movlb 0 00099 0593 E32C 00100 call InitQuickcamHardware 0594 E311 00101 call InitUART 0595 E1B0 00102 call InitGPS 0596 E440 00103 call InitPhone 0597 0002 00104 return 00105 00106 ;;; 00107 ;;; Main entry point. 00108 ;;; 0598 00109 main 0598 8D04 00110 bcf ALUSTA, FS1 ; set up FSR0 to auto-increment. 0599 8404 00111 bsf ALUSTA, FS0 059A 8704 00112 bsf ALUSTA, FS3 ; set up FSR1 not to auto-increment. 00113 059B 2924 00114 clrf ZERO, F ; set up the "ZERO" register (for comparison). 00115 059C E58D 00116 call InitHardware 00117 00118 WAIT 0x0 ; let the RS232 lines settle. 059D B000 M movlw 0x0 059E E58A M call Waiter 00119 059F E039 00120 call InitBitbang 05A0 E343 00121 call qc_initparams ; set the default values for the quickcam params. 05A1 E348 00122 call qc_init ; initialize the quickcam hardware. 00123 05A2 C505 00124 goto RunPhone 00125 00126 END MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 63 SYMBOL TABLE LABEL VALUE ALUSTA 00000004 ATDTString 00000530 ATString 0000052A ATZString 0000052D AVERAGING 1 BANK0 00000000 BANK1 00000001 BANK2 00000002 BANK3 00000003 BIGSLEEP BITBANG_RX_MACRO BITBANG_TX_MACRO BLOCK_UNTIL_DATA BLOCK_UNTIL_PHONE_DATA BR_STORELOW 000003D7 BSR 0000000F BigSleep 00000466 BriString 00000435 C 00000000 C0 0 C1 1 C2 2 C3 3 CA1 00000003 CA1ED0 00000004 CA1ED1 00000005 CA1H 00000217 CA1IE 00000002 CA1IF 00000002 CA1L 00000216 CA1OVF 00000006 CA1_PR3 00000003 CA2ED0 00000006 CA2ED1 00000007 CA2H 00000315 CA2IE 00000003 CA2IF 00000003 CA2L 00000314 CA2OVF 00000007 CONNECTString 00000560 COUNT1 0000002A COUNT2 0000002B CPUSTA 00000006 CQC_16BPP 3 CQC_24BPP 5 CQC_2_1 1 CQC_32BPP 4 CQC_4_1 2 CQC_BIDIR CQC_TEST_PATTERN 6 CREN 00000004 CSRC 00000007 Checksum 000001BA MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 64 SYMBOL TABLE LABEL VALUE Checksum_AddData 000001BF ClkFreq D'32514000' Cmnd_Transfer_Posn D'2' Cmnd_Transfer_Time D'5' Cmnd_Transfer_Trk D'6' Command 00000363 CommandWrapper 0000029C CommandWrapper_begin 0000029D CommandWrapper_cmd 00000078 CommandWrapper_counter 00000077 CommandWrapper_datatype 0000007C DC 00000001 DCD 2 DDRB 00000011 DDRC 00000110 DDRD 00000112 DDRE 00000114 DLE 0x10 DR_CONTROL DDRC DR_DATA DDRD DR_GPS DDRC DR_HWHS DDRB DR_PHONE DDRC DR_POWER DDRB DR_SETUP DDRA DR_STATUS DDRB DialPhone 0000047F DialPhone_ATZcounter 0000007E DialPhone_ResendATZ 00000491 DoneString 00000552 ETX 0x03 EXPECT ExpectPacket 0000028F ExpectPacket_begin 00000291 ExpectPacket_counter 00000076 ExpectPacket_expecting 00000075 ExpectPasswordString 0000056F ExpectPhoneMsg 00000443 ExpectPhoneMsg_high 00000048 ExpectPhoneMsg_low 00000049 ExpectPhoneMsg_read 0000044F ExpectPhoneMsg_readChar 0000044B ExpectPhoneMsg_restart 00000444 ExpectPhone_Timeout 0000004D ExpectPhone_counter 00000047 ExpectPhone_expectChar 0000004C ExpectPhone_timeout 0000004E F 00000001 FERR 00000002 FS0 00000004 FS1 00000005 FS2 00000006 FS3 00000007 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 65 SYMBOL TABLE LABEL VALUE FSR0 00000001 FSR1 00000009 GLINTD 00000004 GPSMSG GPSRxBit 000000B7 GPSRxBitnum 000000B3 GPSRxBitsample 000000B6 GPSRxByte 000000B2 GPSRxLen 000000B1 GPSRxPtr 000000B0 GPSRxQueue 000000A0 GPSRxQueueEnd 000000AF GPSRxState 000000B4 GPSRxTemp 000000B5 GPSTxBitnum 00000093 GPSTxLen 00000091 GPSTxPtr 00000090 GPSTxQueue 00000080 GPSTxQueueEnd 0000008F GPSTxSkipping 00000094 GPSTxTemp 00000092 GPS_PORT PORTC GPS_RCV 5 GPS_SEND 4 GPS_TimerHigh 00000043 GPS_TimerLow 00000042 GPS_counter 00000079 GetPosn 000002BE GetPosn_SendData 000002CD GetTime 000002AA GetTime_SendData 000002B9 GetTrackingData 000002D2 GetTrackingData_GetNextRecord 000002E8 GetTrackingData_GotData 000002EE GetTrackingData_HighCounter 00000041 GetTrackingData_IsTrk 000002F7 GetTrackingData_LowCounter 00000040 GetTrackingData_SendData 000002FB GetTrackingData_begin 000002D3 GetTrackingData_counter 0000007D HWHS_PORT PORTB Handshake 0000037E Handshake_Done 00000389 Handshake_Loop 0000037E Handshake_WaitForOne 00000386 HangupPhone 000004F4 INDF0 00000000 INDF1 00000008 INT 00000000 INTE 00000000 INTEDG 00000007 INTF 00000004 INTSTA 00000007 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 66 SYMBOL TABLE LABEL VALUE IS6BIT 1 InitBitbang 00000039 InitGPS 000001B0 InitHardware 0000058D InitPhone 00000440 InitQuickcamHardware 0000032C InitUART 00000311 LP_CONTROL PORTC LP_DATA PORTD LP_STATUS PORTB LoginString 00000568 ModeString 00000438 NOT_PD 00000002 NOT_PR3 00000003 NOT_RBPU 00000007 NOT_RC8 00000006 NOT_TO 00000003 NOT_TX8 00000006 OERR 00000001 OKString 0000055D OV 00000003 PCL 00000002 PCLATH 00000003 PEIE 00000003 PEIF 00000007 PHONEMSG PHONE_PORT PORTC PHONE_RCV 7 PHONE_SEND 6 PIE 00000117 PIR 00000116 PORTA 00000010 PORTB 00000012 PORTC 00000111 PORTD 00000113 PORTE 00000115 POWER_PORT PORTB POWER_QCAM 0 PR1 00000214 PR2 00000215 PR3H 00000217 PR3L 00000216 PRODH 00000019 PRODL 00000018 PS0 00000001 PS1 00000002 PS2 00000003 PS3 00000004 PW1DCH 00000312 PW1DCL 00000310 PW2DCH 00000313 PW2DCL 00000311 PWM1ON 00000004 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 67 SYMBOL TABLE LABEL VALUE PWM2ON 00000005 PhoneDSRTimer 00000025 PhoneRxBit 000000F7 PhoneRxBitnum 000000F3 PhoneRxBitsample 000000F6 PhoneRxByte 000000F2 PhoneRxLen 000000F1 PhoneRxPtr 000000F0 PhoneRxQueue 000000E0 PhoneRxQueueEnd 000000EF PhoneRxState 000000F4 PhoneRxTemp 000000F5 PhoneTxBitnum 000000D3 PhoneTxLen 000000D1 PhoneTxPtr 000000D0 PhoneTxQueue 000000C0 PhoneTxQueueEnd 000000CF PhoneTxSkipping 000000D4 PhoneTxTemp 000000D2 Phone_HaveData 00000046 Phone_Mode 00000027 Phone_TimerHigh 00000045 Phone_TimerLow 00000044 PictureString 0000054C Pid_Ack_Byte D'6' Pid_Command_Data D'10' Pid_Date_Time_Data D'14' Pid_Nak_Byte D'21' Pid_Position_Data D'17' Pid_Records D'27' Pid_Trk_Data D'34' Pid_Xfer_Cmplt D'12' PollRcv 00000321 PollTXIF 00000327 PosnString 0000053E PrintMsgGPS 0000002D PrintMsgGPS_loop 00000030 PrintMsgPhone 00000021 PrintMsg_loop 00000024 QCMD QC_BLACK D'29' QC_BRIGHTNESS D'11' QC_COLOR 2 QC_CONTRAST D'37' QC_FLAGS 00000031 QC_HEIGHT D'17' QC_HUE D'33' QC_LEFT D'15' QC_LOAD_RAM D'27' QC_SATURATION D'35' QC_SEND_FRAME D'7' QC_SPEED D'45' QC_STATUS D'41' MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 68 SYMBOL TABLE LABEL VALUE QC_TOP D'13' QC_VERSION D'23' QC_WHITE D'31' QC_WIDTH D'19' Quickcam_Average_StoreW 000003CA Quickcam_ClearBrightnessTable 000003AF Quickcam_GuessBrightness 000003B2 Quickcam_ScanAndSend 000003DE Quickcam_Set_Params 0000038E Quickcam_TakePicture 00000421 RBIE 00000007 RBIF 00000007 RC8_9 00000006 RC9 00000006 RCD8 00000000 RCIE 00000000 RCIF 00000000 RCREG 00000014 RCSTA 00000013 RESEND 0 RESTORE_BSR RESTORE_FSR1 RX9 00000006 RX9D 00000000 RX_DEQUEUE ReadPacket 00000214 ReadPacket_CheckNak 00000278 ReadPacket_ReadCommand 00000228 ReadPacket_ReadData 00000239 ReadPacket_ReadLength 00000233 ReadPacket_SendAck 0000027D ReadPacket_TryAgain 00000215 ReadPacket_WaitForDLE 00000218 ReadPacket_checksum 00000073 ReadPacket_counter 00000071 ReadPacket_isGood 00000252 ReadPacket_isGood2 00000263 ReadPacket_length 00000072 ReceiveAck 0000027F ReceiveAck_begin 00000280 ReceiveAck_counter 00000074 RunPhone 00000505 RunPhone_SendLogin 000004CD RunPhone_clearRAM 00000507 RunPhone_done 0000051E RunPhone_wait 00000523 RunningString 00000579 RxGPS 00000181 RxGPSEscapeDLE 000001F3 RxPhone 000001A3 RxUARTBlocking 00000320 S3 3 SAVE_BSR MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 69 SYMBOL TABLE LABEL VALUE SAVE_FSR1 SCAN_STARTED 3 SEND_PHONE SEND_PHONE_W SETUP_PORT PORTA SLEEP1 SLEEP1M SLEEP20M SPBRG 00000017 SPEN 00000007 SREN 00000005 STKAV 00000005 SYNC 00000004 ScanString 0000043C SendAck 000001D9 SendCommand 000001EB SendNak 000001E2 SendPacket 000001C4 SendPacket_SendData 000001CD SendPacket_ptr 0000007A SendPacket_size 0000007B SendPasswordString 00000584 Sleep1M_Timer 00000050 Sleep1_TimerHigh 0000004B Sleep1_TimerLow 0000004A Sleep20M_Timer 00000051 T0CKI 00000001 T0CKIE 00000002 T0CKIF 00000006 T0CS 00000005 T0IE 00000001 T0IF 00000005 T0IntState 00000023 T0PS0 00000001 T0PS1 00000002 T0PS2 00000003 T0PS3 00000004 T0SE 00000006 T0STA 00000005 T16 00000003 TBLPTRH 0000000E TBLPTRL 0000000D TCON1 00000316 TCON2 00000317 TEMP_ALUSTA_INTERRUPT 0000001D TEMP_BSR_INTERRUPT 0000001E TEMP_FSR1 00000022 TEMP_FSR1_INTERRUPT 00000020 TEMP_WREG 0000001F TEMP_WREG_INTERRUPT 0000001C TIMER_BLOCK TMR0H 0000000C TMR0L 0000000B MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 70 SYMBOL TABLE LABEL VALUE TMR1 00000210 TMR1CS 00000000 TMR1IE 00000004 TMR1IF 00000004 TMR1ON 00000000 TMR2 00000211 TMR2CS 00000001 TMR2IE 00000005 TMR2IF 00000005 TMR2ON 00000001 TMR3CS 00000002 TMR3H 00000213 TMR3IE 00000006 TMR3IF 00000006 TMR3L 00000212 TMR3ON 00000002 TOO_DARK 0x3 TRMT 00000001 TX8_9 00000006 TX9 00000006 TX9D 00000000 TXD8 00000000 TXEN 00000005 TXIE 00000001 TXIF 00000001 TXREG 00000016 TXSTA 00000015 TX_ENQUEUE TimeString 00000539 TimeoutString 00000301 TrackingString 00000545 TxBitbangBlocking_data 00000021 TxByteEscapeDLE_Temp 0000004F TxGPSBlocking 0000016C TxGPSBlockingEscapeDLE 000001B1 TxPhoneBlocking 0000018E TxUARTBlocking 00000326 USLEEP UsernameString 00000581 W 00000000 WAIT WREG 0000000A Waiter 0000058A Z 00000002 ZERO 00000024 _EC_OSC 0000FFFF _LF_OSC 0000FFFC _MC_MODE 0000FFEF _MP_MODE 0000FFFF _PMC_MODE 00007FAF _RC_OSC 0000FFFD _WDT_1 0000FFFF _WDT_256 0000FFFB MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 71 SYMBOL TABLE LABEL VALUE _WDT_64 0000FFF7 _WDT_NORM 0000FFF3 _WDT_OFF 0000FFF3 _XMC_MODE 0000FFBF _XT_OSC 0000FFFE __17C43 00000001 baud (((((D'10'*ClkFreq)/(D'64'*X))+D'5')/D'10')-D'1') clc bcf ALUSTA, C done_int 0000007F done_readbytes 00000418 doscan 000003E2 doscan_callCommand 000003EC g_readpkt 0000005D g_writepkt 00000053 guessagain 000003B5 increment_br_counter 000003C5 main 00000598 powerdown_peripherals 00000502 powerup_peripherals 000004F5 qc_BR0H 00000030 qc_BR0L 0000002F qc_bluedata 00000052 qc_brightness 00000028 qc_contrast 00000029 qc_hsval 0000002C qc_init 00000348 qc_initparams 00000343 qc_mode 00000033 qc_returned 0000002E qc_save_retval 0000002D qc_scan 000003DF qc_tempbr 00000032 readbytes 000003ED readbytes_1 00000412 readbytes_loop 000003FB readbytes_notcolor 0000040F readbytes_reducecolordata 0000040E scannums 00000429 scansizes 0000042F sec bsf ALUSTA, C skpnz btfsc ALUSTA, Z skpz btfss ALUSTA, Z t0_int 00000064 t0_rx 000000AE t0_tx 00000084 t1_rx 00000122 t1_tx 000000F8 transmit_state 00000078 MPASM 02.40 Released BIKEMICR.ASM 9-6-2000 20:19:04 PAGE 72 MEMORY USAGE MAP ('X' = Used, '-' = Unused) 0000 : X--------------- X--------------- -XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 00C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0100 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0140 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0180 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 01C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0200 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0240 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0280 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 02C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0300 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0340 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0380 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 03C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0400 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0440 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0480 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 04C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0500 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0540 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0580 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXX------------- ---------------- All other memory blocks unused. Program Memory Words Used: 1412 Errors : 0 Warnings : 0 reported, 0 suppressed Messages : 0 reported, 0 suppressed