LIST P=16C55 ERRORLEVEL -302 ; LANC explorer ; allows user to test various LANC codes - both 1st and 2nd bytes can be ; set to any value, and command can be sent once, or sent repetitive ; ; This version is set to display the codes being sent on a 16 character LCD ; display. ; physical connections: ; A0, pin 6 LANC to camera ; C7..C0 data bus to LCD ; B7 E to LCD ; B6 R/W to LCD ; B5 RS to LCD ; B3 byte 2 decrease ; B2 byte 2 increase ; B1 byte 1 decrease ; B0 byte 1 increase ; A3 send repetitive ; A2 send once ;display format ; address 0 - sending indicator - toggle between 0x20 and 0x0 ; address 2,3 command byte 1 ; address 5,6 command byte 2 include ;defintions same equ 1 INPUT equ 0 ;bit to use for reading LANC - used 2x OUTPUT equ 0 ;bit to use for writing LANC - used 2x DEBUG equ 1 ;bit 1 output for debugging TRIS_READ_LANC equ 0fdh ;A0,2,3 in A1 out (debug bit) TRIS_WRITE_LANC equ 0fch ;A2,3 in - 0 out 1 out TRIS_READ_SWITCHES equ 00fh ;0,1,2,3 in 4,5,6,7 outputs BIT_TIME equ .31 ;for 4 MHz - used 2x ; on my SONY CCD-TR6, values from 33 to 28 worked - mid range ; is 30 or 31 B1UP EQU 0 B1UP_P EQU PORTB B1DN EQU 1 B1DN_P EQU PORTB B2UP EQU 2 B2UP_P EQU PORTB B2DN EQU 3 B2DN_P EQU PORTB DEBUG EQU 1 DEBUG_P EQU PORTA SEND1 EQU 2 SEND1_P EQU PORTA SENDX EQU 3 SENDX_P EQU PORTA ;port definitions LCD_DATA EQU PORTC LCD_CNTL EQU PORTB ; LCD Display Commands and Control Signal names. E EQU 7 ; LCD Enable control line RW EQU 6 ; LCD Read/Write control line RS EQU 5 ; LCD Register Select control line ;RAM defines can use 0x08 to 0x1f without resorting to banking counter EQU 0x08 counter2 EQU 0x09 bit_counter EQU 0x0a bits_to_send EQU 0x0b byte_to_write EQU 0x0c command_byte_1 EQU 0x0d command_byte_2 EQU 0x0e byte_number EQU 0x0f command_pass EQU 0x10 msd EQU 0x11 ;Holds Most Significant Digit in delay counter lsd EQU 0x12 ;Holds Least Significant Digit in delay counter temp EQU 0x13 char EQU 0x14 ;Holds value to send to LCD module. last_val_0 EQU 0x15 ;last value written to first char pos in LCD ; toggle between 0x20 and 0x00 after each ; send_5 b1up EQU 0x16 b1dn EQU 0x17 b2up EQU 0x18 b2dn EQU 0x19 send1 EQU 0x1A sendx EQU 0x1B org 0 ; RESET vector location RESET goto START ;vector table for far calls delay_771 goto delay_771_f send_cmd goto send_cmd_f send_char goto send_char_f wait_for_interframe goto wait_for_interframe_f send_command_5 goto send_command_5_f convert_to_hex goto convert_to_hex_f START ; POWER_ON Reset (Beginning of program) goto init_f ; ends with "goto main" main call wait_for_interframe ;do all switch reading in the ; 6 ms (4 left after this routine) ; between frames .... this is ; lots of time... each machine cycle is ; 1 us - so we have ~4000 to use... goto scan_switches_f ;ends with 'goto main' ; end of main section ;---------------------------------------------------------------- scan_switches_f ; switch var values: 0 = not pressed ; 1 = was open, now pressed BIT 0 ; 2 = was pressed, still pressed BIT 1 ; 4 = was pressed, now clear BIT 2 t0 btfsc B1UP_P, B1UP goto t0_0 ;key not pressed t0_1 ;is pressed now btfsc b1up, 1 ; was key previously pressed? goto t1 ;yes - no need for processing - goto next clrf b1up bsf b1up, 0 ; set b1up to 1 goto t1 t0_0 ;is not pressed now btfss b1up, 1 ;was pressed? goto t1 clrf b1up bsf b1up, 2 ;set b1up to 4 - was pressed, now clear ;================================== t1 btfsc B1DN_P, B1DN goto t1_0 ;key not pressed t1_1 ;is pressed now btfsc b1dn, 1 ; was key previously pressed? goto t2 ;yes - no need for processing - goto next clrf b1dn bsf b1dn, 0 ; set b1dn to 1 goto t2 t1_0 ;is not pressed now btfss b1dn, 1 ;was pressed? goto t2 clrf b1dn bsf b1dn, 2 ;set b1dn to 4 - was pressed, now clear ;================================== t2 btfsc B2UP_P, B2UP goto t2_0 ;key not pressed t2_1 ;is pressed now btfsc b2up, 1 ; was key previously pressed? goto t3 ;yes - no need for processing - goto next clrf b2up bsf b2up, 0 ; set b2up to 1 goto t3 t2_0 ;is not pressed now btfss b2up, 1 ;was pressed? goto t3 clrf b2up bsf b2up, 2 ;set b2up to 4 - was pressed, now clear ;================================== t3 btfsc B2DN_P, B2DN goto t3_0 ;key not pressed t3_1 ;is pressed now btfsc b2dn, 1 ; was key previously pressed? goto t4 ;yes - no need for processing - goto next clrf b2dn bsf b2dn, 0 ; set hat_ to 1 goto t4 t3_0 ;is not pressed now btfss b2dn, 1 ;was pressed? goto t4 clrf b2dn bsf b2dn, 2 ;set hat_right to 4 - was pressed, now clear ;================================== t4 btfsc SEND1_P, SEND1 goto t4_0 ;key not pressed t4_1 ;is pressed now btfsc send1, 1 ; was key previously pressed? goto t5 ;yes - no need for processing - goto next clrf send1 bsf send1, 0 ; set send1 to 1 goto t5 t4_0 ;is not pressed now btfss send1, 1 ;was pressed? goto t5 clrf send1 bsf send1, 2 ;set send1 to 4 - was pressed, now clear ;================================== t5 btfsc SENDX_P, SENDX goto t5_0 ;key not pressed ; get here if SENDX == 0 t5_1 ;is pressed now btfsc sendx, 1 ; was key previously pressed? goto t6 ;yes - no need for processing - goto next ; get here if sendx != 2 clrf sendx bsf sendx, 0 ; set sendx to 1 goto t6 t5_0 ;is not pressed now btfss sendx, 1 ;was pressed? goto t6 ;get here if sendx == 2 clrf sendx bsf sendx, 2 ;set sendx to 4 - was pressed, now clear ;================================== t6 ;time to digest what we have... ;+++++++++++++++++ p1 btfss b1up, 0 goto p2 ;b1up not newly pressed incf command_byte_1, 1 rlf b1up, same goto proc_out ;+++++++++++++++++ p2 btfss b1dn, 0 goto p3 ;b1dn not newly pressed decf command_byte_1, 1 rlf b1dn, same goto proc_out ;+++++++++++++++++ p3 btfss b2up, 0 goto p4 ;b2up not newly pressed incf command_byte_2, 1 rlf b2up, same goto proc_out ;+++++++++++++++++ p4 btfss b2dn, 0 goto p5 ;b2dn not newly pressed decf command_byte_2, 1 rlf b2dn, same goto proc_out ;+++++++++++++++++ p5 btfss send1, 0 goto p6 ;send1 not newly pressed call send_command_5 rlf send1, same goto proc_out ;+++++++++++++++++ p6 btfsc sendx, 1 ;sendx not still down? goto p6_yes ;get here is sendx != 2 btfsc sendx, 0 ;sendx not newly pressed? goto p6_yes ;get here if sendx != 1 goto p7 p6_yes ; get here if sendx == 1 || == 2 btfss sendx, 0 ;is first press? goto no_roll ;get here if sendx == 1 rlf sendx, same ;mark as not a new press... no_roll call send_command_5 goto proc_out ;+++++++++++++++++ p7 proc_out ; need to update display movlw 0x82 call send_cmd ;hi nibble first swapf command_byte_1, 0 andlw 0x0f call convert_to_hex call send_char ;then low movf command_byte_1, 0 andlw 0x0f call convert_to_hex call send_char movlw 0x85 call send_cmd ;hi nibble swapf command_byte_2, 0 andlw 0x0f call convert_to_hex call send_char ;low nibble movf command_byte_2, 0 andlw 0x0f call convert_to_hex call send_char goto main convert_to_hex_f addwf PCL, 1 retlw 0x30 ;'0' retlw 0x31 ;'1' retlw 0x32 ;'2' retlw 0x33 ;'3' retlw 0x34 ;'4' retlw 0x35 ;'5' retlw 0x36 ;'6' retlw 0x37 ;'7' retlw 0x38 ;'8' retlw 0x39 ;'9' retlw 0x61 ;'a' retlw 0x62 ;'b' retlw 0x63 ;'c' retlw 0x64 ;'d' retlw 0x65 ;'e' retlw 0x66 ;'f' ;---------------------------------------------------------------------- ;wait_for_interframe routine ; when called will eat time waiting for a roughly 2 ms idle time on ; LANC - reads INPUT bit of PORTA ; uses counter counter2 wait_for_interframe_f ; return sync_up movlw 3 movwf counter2 ; counter2 = 3 clrf counter ; counter = 0 sync_loop btfss PORTA, INPUT ;if lanc = 1, skip jump goto sync_up ; any lanc = 0 resets counters ; lanc == 1 to get here incfsz counter, 1 ; inc low byte of counter goto sync_loop ; skip jump if counter overflows to 0 decfsz counter2, 1 ; decrement counter2 goto sync_loop ; skip jump if --counter2 == 0 sync_ed retlw 0 ;return to caller ;-------------------------------------------------------------------- ; send_command_5 sends command in command_byte_1 and command_byte_2 ; the required 5 times. send_command_5_f movlw 5 movwf command_pass sc5_1 call wait_for_interframe ;------------------------------------------------------------------ ; send_command ; waits until bit INPUT of PORTA goes low, then delays ; 1 bit time minus a few cycles, then sends the byte in ; command_byte_1, then waits for INPUT to go low again, then ; sends byte in command_byte_2 ; uses: ; bit_counter, bits_to_send, byte_to_write, byte_number send_command movlw 2 movwf byte_number ;initialize outer loop counter movf command_byte_1, 0 movwf byte_to_write ;put command byte into byte_to_write sc_wait_for_LANC_start movlw TRIS_READ_LANC ; A0 = input tris PORTA sc_wfLs_1 btfsc PORTA, INPUT ;waiting for input port to drop - goto sc_wfLs_1 ;is start bit from camcorder movlw BIT_TIME - 1 ; @ 4 MHz movwf bit_counter sc_wfLs_2 ;each loop = 1.5 us @ 8MHz decfsz bit_counter, 1 goto sc_wfLs_2 sc_write_byte movlw 8 movwf bits_to_send movlw TRIS_WRITE_LANC ; A0 = output tris PORTA sc_write_bit movlw BIT_TIME ;34 loops @ 3 clocks @ 1us each @ 4mhz movwf bit_counter btfsc byte_to_write, 0 ;test bit 0 goto sc_wb_set_1 ;skipped if bit 0 = 0 bsf PORTA, OUTPUT ;clear output bit to 0 goto sc_wb_1 sc_wb_set_1 bcf PORTA, OUTPUT ;set output bit to 1 - sc_wb_1 decfsz bit_counter, 1 goto sc_wb_1 rrf byte_to_write, same decfsz bits_to_send, same goto sc_write_bit movlw TRIS_READ_LANC ; A0 = input tris PORTA decfsz byte_number, same goto sc_byte_2 goto sc_done sc_byte_2 movf command_byte_2, 0 movwf byte_to_write goto sc_wait_for_LANC_start sc_done decfsz command_pass, same goto sc5_1 toggle_disp incf last_val_0, same movlw 0x07 andwf last_val_0, same movlw 0x80 call send_cmd ; set ptr to 0 movf last_val_0, 0 ; get val into w call send_char ; write char retlw 0 ;;----------------------------------------------------------------------- ;call with outer loop count in w - each unit delays for 771 us delay_771_f ;return movwf msd ; Use msd and lsd Registers to Initilize LCD clrf lsd loop_771 decfsz lsd, F ; Delay time = msd * ((3 * 256) + 3) * Tcy goto loop_771 decfsz msd, F goto loop_771 return ;************************************************** ;* The LCD Module Subroutines * ;************************************************** ;***************************************************************** ;* send_char - Sends character contained in register W to LCD * ;* This routine sends the entire character to the PORT * ;* The data is transmitted on the PORT<7:0> pins * ;***************************************************************** send_char_f movwf char ; Character to be sent is in W send_char_busy ; Wait for LCD to be ready movlw 0xFF ; Set port_C for input tris PORTC bcf LCD_CNTL, RS ; Set LCD for command mode bsf LCD_CNTL, RW ; Setup to read busy flag bsf LCD_CNTL, E ; Set E high bcf LCD_CNTL, E ; Set E low movf LCD_DATA, w ; Read busy flag, DDram address movwf temp btfsc temp, 7 ; Check busy flag, high=busy goto send_char_busy bcf LCD_CNTL, RW movlw 0x00 tris PORTC ; Set port_C for output ;end of "busy check" movf char, w movwf LCD_DATA ; Send data to LCD bcf LCD_CNTL, RW ; Set LCD in read mode bsf LCD_CNTL, RS ; Set LCD in data mode bsf LCD_CNTL, E ; toggle E for LCD bcf LCD_CNTL, E return ;************************************************************** ;* SEND_CND - Sends command contained in register W to LCD * ;* This routine sends the entire character to the PORT * ;* The data is transmitted on the PORT<7:0> pins * ;************************************************************** send_cmd_f movwf char ; Command to be sent is in W send_cmd_busy ; Wait for LCD to be ready movlw 0xFF ; Set port_C for input tris PORTC bcf LCD_CNTL, RS ; Set LCD for command mode bsf LCD_CNTL, RW ; Setup to read busy flag bsf LCD_CNTL, E ; Set E high bcf LCD_CNTL, E ; Set E low movf LCD_DATA, w ; Read busy flag, DDram address movwf temp btfsc temp, 7 ; Check busy flag, high=busy goto send_cmd_busy bcf LCD_CNTL, RW movlw 0x00 tris PORTC ; Set port_C for output ; end of "busy check" movf char, w movwf LCD_DATA ; Send data to LCD bcf LCD_CNTL, RW ; Set LCD in read mode bcf LCD_CNTL, RS ; Set LCD in command mode bsf LCD_CNTL, E ; toggle E for LCD bcf LCD_CNTL, E return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; init_f clrf STATUS ; Do initialization (Bank 0) movlw TRIS_READ_LANC tris PORTA ; A0,2,3 inputs, 1 out movlw TRIS_READ_SWITCHES ; RB7 - 5 out, RB3 - 0 inputs tris PORTB movlw 0x00 tris PORTC ; RC Port are outputs clrf PORTA clrf PORTB clrf PORTC ; Initialize the LCD Display Module clrf LCD_CNTL ; ALL PORT output should output Low. movlw 0x038 ; Command for 8-bit interface, 2 lines movwf LCD_DATA bsf LCD_CNTL, E bcf LCD_CNTL, E movlw 0x75 ;117 * (3* 256 * 1 us) >> 15 ms... call delay_771 ; Command sequence for 2 lines of 5x7 characters movlw 0X038 movwf LCD_DATA bsf LCD_CNTL, E ; toggle E bcf LCD_CNTL, E movlw 0x10 ;16 * (3* 256 * 1 us) >> 4 ms... call delay_771 movlw 0X038 movwf LCD_DATA bsf LCD_CNTL, E ; toggle E bcf LCD_CNTL, E movlw 0x02 ;2 * (3* 256 * 1 us) >> 100us... call delay_771 movlw 0X038 movwf LCD_DATA bsf LCD_CNTL, E ; toggle E bcf LCD_CNTL, E ; Busy Flag should be valid after this point movlw 0x38 call send_cmd movlw 0x08 call send_cmd movlw 0x01 call send_cmd movlw 0x06 call send_cmd movlw 0x0C call send_cmd ;looks OK up to here...11/11/00 ;----------------------------------------------------------------------- ;init_f, lanc part clrwdt movlw 7 ;tmr0 prescale to 1:256 option clrf counter clrf counter2 clrf bit_counter clrf bits_to_send clrf byte_to_write movlw 0x28 movwf command_byte_1 clrf command_byte_2 clrf byte_number clrf command_pass clrf b1up clrf b1dn clrf b2up clrf b2dn clrf send1 clrf sendx clrf char clrf last_val_0 ;setup progress indicator characters 00-07 ;clear all CG RAM locations movlw 66 movwf counter movlw 0x40 ;char 0, line 0 call send_cmd ;01 000 000 clear_cg movlw 0x00 call send_char decfsz counter, 1 goto clear_cg ;set individual lines from bottome up... movlw 0x46 ;char 0, line 6 call send_cmd ;01 000 110 movlw 0xff ;0100 0110 call send_char movlw 0x4d ;char 1, line 5 call send_cmd ;01 001 101 movlw 0xff ;0100 1101 call send_char movlw 0x54 ;char 2, line 4 call send_cmd ;01 010 100 movlw 0xff ;0101 0100 call send_char movlw 0x5b ;char 3, line 3 call send_cmd ;01 011 011 movlw 0xff ;0101 1011 call send_char movlw 0x62 ;char 4, line 2 call send_cmd ;01 100 010 movlw 0xff ;0110 0010 call send_char movlw 0x69 ;char 5, line 1 call send_cmd ;01 101 001 movlw 0xff ;0110 1001 call send_char movlw 0x70 ;char 6, line 0 call send_cmd ;01 110 000 movlw 0xff ;0111 0000 call send_char movlw 0x78 ;char 7, line 0 call send_cmd ;01 111 000 movlw 0xff ;0111 1000 call send_char movlw 0x7e ;char 7, line 6 call send_cmd ;01 111 110 movlw 0xff ;0111 1110 call send_char movlw 0x80 call send_cmd movlw 0x00 call send_char ; show msg movlw 0xc0 ;2nd half of display call send_cmd movlw 'E' call send_char movlw 'x' call send_char movlw 'p' call send_char movlw 'l' call send_char movlw 'o' call send_char movlw 'r' call send_char movlw 'e' call send_char movlw 'r' call send_char goto proc_out org 0x1d0 de "Ed's LANC Explorerrev 1.00(c) 2000" end