;********************************************************************** ; * ; Filename: dmx_Projector.asm * ; Date: 15-2-2004 * ; File Version: DMX -> Keyboard Interface * ; * ; Author: Paul Harris * ; Company: * ; * ;********************************************************************** list p=16f627A ; list directive to define processor #include <p16F627A.inc> ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _MCLRE_OFF & _LVP_OFF #DEFINE Keyboard_Clk_In PORTB,0 #DEFINE DMX_Data_In PORTB,1 #DEFINE Keyboard_Data_In PORTB,2 #DEFINE Keyboard_Data_Out PORTB,6 #DEFINE Keyboard_Clk_Out PORTB,7 #DEFINE Data_Rec_LED PORTA,3 #DEFINE Data_Error_LED PORTA,4 ;PORT A definitions ; 1= In, 0= Out PORTA_CONFIG equ B'11100111'; ;PORT B definitions 1 = Input 0= Output PORTB_CONFIG equ B'00111111' ; Programme Constants Start_Vector EQU D'0' Interrupt_Vector EQU D'4' Common_Ram_Base EQU H'70' Ram_Base EQU H'20' Osc_Freq EQU D'20000000' ; Pic Frequency Instruction_rate EQU Osc_Freq/D'4' ; Instruction Rate ; DMX Constants Baud_Rate EQU D'250000' Baud_Rate_Constant EQU (Osc_Freq/(D'16'*Baud_Rate))-D'1' Number_Of_Channels EQU D'8' startcode EQU D'0' Switch_Point EQU D'128' ; At What point dose 0 become 1 ?? DMX_Address EQU D'12' ; DMX Address to write to EEPROM ; Keyboard Constants Keybd_TX_Constant EQU D'200' ; - Instructions to process it ! Scroll_Key EQU h'7E' ; - Key to Enter setup mode is Scroll ! Plus_Key EQU h'79' Minus_Key EQU h'7B' Enter_Key EQU h'5A' Esc_Key EQU h'76' Space_Key EQU h'29' ; *********** Define Flags ************* ; IFlag Break_Detected equ 0 ; Break detected Start_Detected equ 1 ; Start Byte detected Valid_Channel equ 2 ; Reached valid channels No_DMX_Data equ 3 ; No recieved DMX Data ; Int_Flag Start equ 0 ; Start Bit Detected Parity equ 1 ; Parity Bit Deteected Stop equ 2 ; Stop Bit Detected Data_End equ 3 ; End Of Data Tranmission... ; Flag Keyboard_Data equ 0 ; New Data From Keyboard Keyboard_TX equ 1 ; DMX_Data equ 2 ; New DMX Data recieved dmx_error equ 3 ; Error detected in DMX tranmission ignore_next equ 4 ; Ignore next chacture (Setup Mode) ;***** VARIABLE DEFINITIONS CBLOCK Common_Ram_Base Int_W Int_Status Int_PCLath Int_FSR ee_address ee_data ENDC CBLOCK Ram_Base ; Interupt Variables Iflag Int_Flag Int_FlagB Int_TX_Data Int_Count Int_CountB Int_Data IH_Channel_Count_L IH_Channel_Count_H IH_Channels_Recieved IH_Temp Int_Parity flag ; Flags !! temp ; Temp Channel_Flags ; DMX Channels Activated Flags Old_Channel_Flags ; Old DMX Flags DMX_Start_Addr_L ; DMX Start Address DMX_Start_Addr_H DMX_Start_Code ; DMX Start Code52 Data_Recieved ; Keyboard Data recieved Channels ; Number of Channels to recieve Channel_Values : (Number_Of_Channels+2) Char_In ; Chacture temp register String_Count ; Chacture count for Tx Char_Count ; Count for setup of chactures Char_Channel ; Current Char channel on NumH ; Bin -> Dec NumL Hund Tens_Ones Char_Bank: 6 ; Characture temp save registers ENDC ;********************************************************************** ORG Start_Vector ; processor reset vector nop ; Included for ICD clrf PCLATH ; ensure page bits are cleared goto Initalise ; go to beginning of program ORG Interrupt_Vector ; interrupt vector location MOVWF Int_W ; Save PIC state SWAPF STATUS,W CLRF STATUS MOVWF Int_Status MOVF PCLATH,W MOVWF Int_PCLath CLRF PCLATH BCF STATUS,IRP MOVF FSR,W MOVWF Int_FSR IH_Interrupt_Poll btfsc INTCON,INTF ; Test for RB0 Interupt goto IH_RB0 btfsc PIR1,RCIF ; USART Interupt Pending ? goto IH_Check_USART ; Yes, Goto Usart handler btfsc PIR1,TMR1IF ; Timer 1 interupt ?? goto IH_Timer1 IH_Exit movf Int_FSR,W ; Restore PIC state movwf FSR movf Int_PCLath,W movwf PCLATH swapf Int_Status,W movwf STATUS swapf Int_W,F swapf Int_W,W retfie ; Return from interrupt ; ******************************************************** ; * Recieve From Keyboard IH_RB0 bsf STATUS,RP0 ; change to bank 1 btfsc OPTION_REG,INTEDG ; Look for Falling Edge goto IH_RB0_End ; 1 = rising edge IH_RB0_Start ; Falling Signal. bsf OPTION_REG,INTEDG ; set to look for Rising Edge bcf STATUS,RP0 ; move back to bank 0 btfsc Keyboard_Data_In ; Mirror Data On Output bsf Keyboard_Data_Out btfss Keyboard_Data_In bcf Keyboard_Data_Out bcf INTCON,INTF ; Clear interupt flag bcf Keyboard_Clk_Out ; Set Clock btfsc Int_Flag,Stop ; Stop Bit Detected yet ? goto IH_RB0_Stop ; Yes, btfsc Int_Flag,Start ; Start Bit Detected Yet ? goto IH_RB0_SBit ; Yes, btfsc Keyboard_Data_In ; Check if start bit present ? goto IH_Interrupt_Poll ; No, movlw d'8' ; Setup Bits to recieve movwf Int_Count ;bsf Data_Error_LED ; Led On clrf Int_Data ; Clear data register bsf Int_Flag,Start ; Set Flag goto IH_Interrupt_Poll IH_RB0_SBit rrf Int_Data,f bcf Int_Data,7 ; Clear Bit 7 btfsc Keyboard_Data_In ; Check Port bsf Int_Data,7 ; Set Bit If required decfsz Int_Count,f ; Exit Is More Data to Collect goto IH_Interrupt_Poll movlw D'2' ; Setup to recieve 2 Parity and stop bits movwf Int_Count bsf Int_Flag,Stop ; Set Stop bnit Flag goto IH_Interrupt_Poll IH_RB0_Stop decfsz Int_Count,f ; Two Bits Yet ? goto IH_Interrupt_Poll ; No, clrf Int_Flag ; Reset flags movf Int_Data,w movwf Data_Recieved bsf flag,Keyboard_Data ; Set Flag to show new keyboard Data ;bcf Data_Error_LED ; Led Off goto IH_Interrupt_Poll IH_RB0_End ; Rising Signal bcf INTCON,INTF ; Clear Interupt flag bcf OPTION_REG,INTEDG ; Set RB0 Interupt to falling edge bcf STATUS,RP0 ; change to bank 0 bsf Keyboard_Clk_Out ; Mirror Signal goto IH_Interrupt_Poll ; *********************************************************** ; * Recieve DMX Data IH_Check_USART bcf PIR1,RCIF ; Clear Interupt flag IH_Check_HW_Overrun btfsc RCSTA,OERR ; Has a HW overrun occurred ? goto IH_HW_Overrun ; Yes, do a HW reset IH_Check_9th_bit ; clrf IH_Timer_Count ; Clear Timer count btfss RCSTA,RX9D ; Dose 9th Bit of data = 1, eg Break goto IH_Wait_Break ; Yes, start receiving again IH_Check_SW_Overrun btfsc RCSTA,FERR ; Has a framing error occurred ? goto IH_SW_Overrun ; Yes, do a Usart reset IH_Test_Flags btfsc Iflag,Valid_Channel ; Test to see if receiving valid channels goto IH_Valid_Channel ; Yes, get next channel btfsc Iflag,Start_Detected ; Test to see it start byte has arrived goto IH_Wait_Channel ; Yes, Check Channel counts btfsc Iflag,Break_Detected ; Test to see if break has arrived goto IH_Wait_Start ; Yes, wait for start byte IH_Wait_Break clrf Iflag ; Clear all interupt flags movf RCREG,w ; Move recieved data in to w btfsc RCSTA,RX9D ; Test if break has arrived goto IH_Interrupt_Poll ; No, Break not detected btfsc STATUS,Z ; Yes, Dose detected break =0 ? bsf Iflag,Break_Detected ; Yes, set flag to indicate break arrived goto IH_Interrupt_Poll IH_Wait_Start clrf IH_Channels_Recieved ; Clear number of channels recieved clrf IH_Channel_Count_L ; Clear Low channel count clrf IH_Channel_Count_H ; Clear High channel count bsf Iflag,Start_Detected ; Set flag to indicate Start Byte arrived movf RCREG,w ; Check start code = 0 btfss STATUS,Z ; clrf Iflag ; if No then clear flags and wait for next break goto IH_Interrupt_Poll IH_Wait_Channel movf RCREG,w ; Store Recieved value in temp movwf IH_Temp incf IH_Channel_Count_L,f ; Increase channel count btfsc STATUS,Z ; for both Low and High bytes incf IH_Channel_Count_H,f ; movf IH_Channel_Count_H,w ; Compare the high byte of channel count to xorwf DMX_Start_Addr_H,w ; DMX start address btfss STATUS,Z ; If Not equal then exit goto IH_Interrupt_Poll movf IH_Channel_Count_L,w ; Compare the low byte of channel count to xorwf DMX_Start_Addr_L,w ; DMX Start address btfss STATUS,Z ; if not equal then exit goto IH_Interrupt_Poll bsf Iflag,Valid_Channel ; if address equal then set valid channels movf IH_Temp,w movwf Channel_Values ; Store value in first channel incf IH_Channels_Recieved,f ; and increase count goto IH_Interrupt_Poll IH_Valid_Channel movlw Channel_Values ; Load address of memory block addwf IH_Channels_Recieved,w ; add channel offset movwf FSR ; and move in to FSR movf RCREG,w ; Store result in the movwf INDF ; channel position in memory movf IH_Channels_Recieved,w ; incf IH_Channels_Recieved,f ; Increase count (Note No effect on w !) xorwf Channels,w ; Check if all channels recieved btfss STATUS,Z ; goto IH_Interrupt_Poll ; No, then return to interupt poll clrf Iflag ; Yes, Clear flags and wait for break bsf Data_Rec_LED ; Set DMX Data LED bsf flag,DMX_Data ; Set DMX Data recieve flag goto IH_Interrupt_Poll ; exit back to Handler IH_HW_Overrun bcf RCSTA,CREN ; Reset UART bsf RCSTA,CREN ; receive logic bsf flag,dmx_error ; Turn on hardware overrun LED bsf Data_Error_LED ; Turn on DMX Error led bcf Data_Rec_LED ; Off Data Led goto IH_Check_9th_bit IH_SW_Overrun bcf RCSTA,CREN ; reset UART bsf RCSTA,CREN ; receive logic bsf flag,dmx_error ; Turn on software Overrun Led bsf Data_Error_LED ; Turn on DMX Error led bcf Data_Rec_LED ; Off Data Led goto IH_Test_Flags ;********************************************************** ;* Transmitte to keyboard IH_Timer1 ; Keyboard Data Tx bcf PIR1,TMR1IF ; Clear interupt flag movlw h'ff'-High(Keybd_TX_Constant-d'30') ; movwf TMR1H ; Reload Timer movlw h'ff'-Low(Keybd_TX_Constant-d'30') ; - 30 (Number of steps lost) movwf TMR1L ; To too Clk Change btfsc Keyboard_Clk_Out ; High Or Low Out At Present goto IH_Data_TX ; High, bsf Keyboard_Clk_Out ; Low so set Clk then, goto IH_Interrupt_Poll ; exit back to Handler IH_Data_TX btfsc Int_FlagB,Data_End ; Finised TX ? goto IH_Data_End ; Yes. shut it all down then !! btfsc Int_FlagB,Stop ; Stop Bit Sent ? goto IH_Data_Stop ; Yes, btfsc Int_FlagB,Parity goto IH_Data_Parity btfsc Int_FlagB,Start ; Start Bit Sent ? goto IH_Data_Start ; Yes, IH_Data_Beginning movlw d'8' ; Setup Bits to tx movwf Int_CountB clrf Int_Parity bcf Keyboard_Data_Out ; Clear Data Output bcf Data_Rec_LED ; Led Off bsf Int_FlagB,Start ; Set Flag bcf Keyboard_Clk_Out ; Clear Clock output goto IH_Interrupt_Poll IH_Data_Start btfsc Int_TX_Data,0 ; Check Bit 0 bsf Keyboard_Data_Out btfss Int_TX_Data,0 bcf Keyboard_Data_Out btfsc Int_TX_Data,0 ; Create Parity Register incf Int_Parity,f rrf Int_TX_Data,f ; Rotate Data Around bcf Keyboard_Clk_Out ; Clear Clock output decfsz Int_CountB,f ; Exit Is More Data to Collect goto IH_Interrupt_Poll bsf Int_FlagB,Parity ; Set Parity bit Flag goto IH_Interrupt_Poll IH_Data_Parity btfsc Int_Parity,0 ; Check Parity Bit 0 bcf Keyboard_Data_Out ; And set output btfss Int_Parity,0 bsf Keyboard_Data_Out bsf Int_FlagB,Stop ; Set Stop bit Flag bcf Keyboard_Clk_Out ; Clear Clock output goto IH_Interrupt_Poll IH_Data_Stop bsf Keyboard_Data_Out ; Set Keyboard Data Out nop bsf Int_FlagB,Data_End ; Set Data End Flag bcf Keyboard_Clk_Out ; Clear Clock output goto IH_Interrupt_Poll IH_Data_End bcf T1CON,TMR1ON ; Disable Timer 1 clrf Int_FlagB ; Reset flags bcf flag,Keyboard_TX ; Clear Trasmit Flag bsf Data_Rec_LED ; Led On goto IH_Interrupt_Poll ; --------------------------------------------------------------------------- ; ***** Tables ; Number Lookup Table - Return Keyboard Codes for Numbers ; Num_Lookup clrf PCLATH addwf PCL,f retlw h'45' ;0 retlw h'16' ;1 retlw h'1E' ;2 retlw h'26' ;3 retlw h'25' ;4 retlw h'2E' ;5 retlw h'36' ;6 retlw h'3D' ;7 retlw h'3E' ;8 retlw h'46' ;9 ; Message Lookup msg1 movlw HIGH(msg1+3) movwf PCLATH movf String_Count,w addwf PCL,f retlw h'1B' ; s String =28 Chactures retlw h'24' ; e retlw h'4B' ; l retlw h'24' ; e retlw h'21' ; c retlw h'2C' ; t retlw h'29' ; retlw h'1C' ; a retlw h'23' ; d retlw h'23' ; d retlw h'2D' ; r retlw h'24' ; e retlw h'1B' ; s retlw h'1B' ; s retlw h'29' ; retlw h'3C' ; u retlw h'1B' ; s retlw h'43' ; i retlw h'31' ; n retlw h'34' ; g retlw h'29' ; retlw h'79' ; + retlw h'7B' ; - retlw h'29' ; retlw h'42' ; k retlw h'24' ; e retlw h'35' ; y retlw h'1B' ; s retlw h'29' ; retlw h'1C' ; a retlw h'23' ; d retlw h'23' ; d retlw h'2D' ; r retlw h'24' ; e retlw h'1B' ; s retlw h'1B' ; s retlw h'0' ; End OF String org h'100' ; Prevent table crossing PCLATH msg2 movlw HIGH(msg2+3) movwf PCLATH ; Setup PCLATH movf String_Count,w addwf PCL,f retlw h'1B' ; s String =24 Chactures retlw h'24' ; e retlw h'4B' ; l retlw h'24' ; e retlw h'21' ; c retlw h'2C' ; t retlw h'29' ; retlw h'42' ; k retlw h'24' ; e retlw h'35' ; y retlw h'1B' ; s retlw h'29' ; retlw h'2B' ; f retlw h'44' ; o retlw h'2D' ; r retlw h'29' ; retlw h'21' ; c retlw h'33' ; h retlw h'1C' ; a retlw h'31' ; n retlw h'31' ; n retlw h'24' ; e retlw h'4B' ; l retlw h'0' ; End Of String msg3 movlw HIGH(msg3+3) movwf PCLATH ; Setup PCLATH movf String_Count,w addwf PCL,f retlw h'1B' ; s String =14 Chactures retlw h'24' ; e retlw h'2C' ; t retlw h'2C' ; t retlw h'43' ; i retlw h'31' ; n retlw h'34' ; g retlw h'1B' ; s retlw h'29' ; retlw h'1B' ; s retlw h'1C' ; a retlw h'2A' ; v retlw h'24' ; e retlw h'23' ; d retlw h'0' ; End Of String msg4 movlw HIGH(msg4+3) movwf PCLATH ; Setup PCLATH movf String_Count,w addwf PCL,f retlw h'1B' ; S String =18 Chactures retlw h'24' ; e retlw h'2C' ; t retlw h'2C' ; t retlw h'43' ; i retlw h'31' ; n retlw h'34' ; g retlw h'1B' ; s retlw h'29' ; retlw h'31' ; N retlw h'44' ; o retlw h'2C' ; t retlw h'29' ; retlw h'1C' ; A retlw h'4B' ; l retlw h'4B' ; l retlw h'29' ; retlw h'1B' ; S retlw h'1C' ; a retlw h'2A' ; v retlw h'24' ; e retlw h'23' ; d retlw h'0' ; End Of String Initalise clrf PORTA ; \ clrf PORTB ; clrf flag ; Clear flag register clrf Iflag ; Clear Interupt flag clrf Int_Flag ; " clrf Int_FlagB ; " clrf DMX_Start_Addr_L; Clear DMX Address clrf DMX_Start_Addr_H; movlw b'00000111' ; Disable comparitors movwf CMCON movlw b'00000000' movwf T1CON ; Setup Timer 1 bsf STATUS,RP0 ; Set up port I/O directions movlw PORTA_CONFIG ; 1 = Input 0 = Output movwf TRISA ; Make PORTA movlw PORTB_CONFIG movwf TRISB ; Make PORTB movlw B'10000000' ; set up options - Timer0 from instruction cycle clock with movwf OPTION_REG ; no prescaler bcf STATUS,RP0 ; Bank 0 Get_DMX_Address movlw d'0' ; EEPROM Address for DMX Address Low movwf ee_address call ee_read movwf DMX_Start_Addr_L; Low Address incf ee_address,f call ee_read movwf DMX_Start_Addr_H; High Address movlw Number_Of_Channels movwf Channels ; Number of DMX Channels to recieve bsf Keyboard_Clk_Out ; Initialize UART bsf STATUS,RP0 ; Bank 1 movlw Baud_Rate_Constant movwf SPBRG bsf TXSTA,BRGH bcf TXSTA,SYNC bsf PIE1,TMR1IE ; Enable Timer1 Interupt bsf PIE1,RCIE ; Enable USART Interupt bcf STATUS,RP0 ; Bank 0 bsf RCSTA,RX9 bsf RCSTA,CREN bsf RCSTA,SPEN ; Interrupts clrf PIR1 ; Clear interupts clrf INTCON bsf INTCON,PEIE ; Enable Peripheral Interupts bsf INTCON,INTE ; Enable RB0 Interupt bsf INTCON,GIE ; Enable global interrupts ; ----------------------------------------------------------------- Main btfsc flag,DMX_Data ; New DMX Data ??? call Check_DMX_Data ; Yes btfsc flag,Keyboard_Data ; New Keyboard Data ? goto Check_Keyboard ; Yes goto Main ; Loop ; ***************************************************************************** ; * Check Incomming Data * ; * Input - DMX_Data, flags Output - flags * ; ***************************************************************************** Check_DMX_Data clrf Channel_Flags ; DMX Present output Flags bcf flag,DMX_Data ; Clear flag movf Channel_Values,w; Channel 1 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,0 ; Yes movf Channel_Values+d'1',w ; Channel 2 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,1 ; Yes movf Channel_Values+d'2',w ; Channel 3 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,2 ; Yes movf Channel_Values+d'3',w ; Channel 4 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,3 ; Yes movf Channel_Values+d'4',w ; Channel 5 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,4 ; Yes movf Channel_Values+d'5',w ; Channel 6 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,5 ; Yes movf Channel_Values+d'6',w ; Channel 7 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,6 ; Yes movf Channel_Values+d'7',w ; Channel 8 sublw Switch_Point ; btfss STATUS,C ; greater than switch Point ? bsf Channel_Flags,7 ; Yes Check_Channel_Flags movf Channel_Flags,w ; Look for chages between Current xorwf Old_Channel_Flags,w ; Activated DMX Channels and the old ones andwf Channel_Flags,w ; looking for value changing 0 -> 1 movwf Old_Channel_Flags ; Save Flags Left 4 Processing clrw btfsc Old_Channel_Flags,0 ; Key 1 EEPROM Address movlw d'2' btfsc Old_Channel_Flags,1 ; Key 2 EEPROM Address movlw d'8' btfsc Old_Channel_Flags,2 ; Key 3 EEPROM Address movlw d'14' btfsc Old_Channel_Flags,3 ; Key 4 EEPROM Address movlw d'20' btfsc Old_Channel_Flags,4 ; Key 5 EEPROM Address movlw d'26' btfsc Old_Channel_Flags,5 ; Key 6 EEPROM Address movlw d'32' btfsc Old_Channel_Flags,6 ; Key 7 EEPROM Address movlw d'38' btfsc Old_Channel_Flags,7 ; Key 8 EEPROM Address movlw d'44' andlw b'11111111' ; Used to get Status register to change btfsc STATUS,Z ; Any Data there ?? goto Check_End ; NO, movwf ee_address ; Look Value 1 call ee_read ; Get Value to Send To PC call To_Keyboard ; Send it ! call Delay ; And Wait incf ee_address,f ; Lookup Value 2 call ee_read ; Get Value to Send To PC call To_Keyboard ; Send it ! call Delay ; And Wait incf ee_address,f ; Lookup Value 3 call ee_read ; Get Value to Send To PC call To_Keyboard ; Send it ! call Delay ; And Wait incf ee_address,f ; Lookup Value 4 call ee_read ; Get Value to Send To PC call To_Keyboard ; Send it ! call Delay ; And Wait incf ee_address,f ; Lookup Value 5 call ee_read ; Get Value to Send To PC call To_Keyboard ; Send it ! call Delay ; And Wait incf ee_address,f ; Lookup Value 6 call ee_read ; Get Value to Send To PC call To_Keyboard ; Send it ! call Delay ; And Wait Check_End movf Channel_Flags,w ; Loadup Old Channel Flags movwf Old_Channel_Flags return ; ***************************************************************************** ; * Check Chacture From Keyboard * ; * Input - Flags, Data_Recieved Output - None * ; ***************************************************************************** Check_Keyboard bcf flag,Keyboard_Data ; Clear recieved flag movf Data_Recieved,w ; Check Data xorlw Scroll_Key ; to see if the same as setup key btfss STATUS,Z ; The Same ? goto Main ; No, clrf String_Count ; Clear Count bsf STATUS,RP0 ; Bank 1 bcf PIE1,RCIE ; disble USART Interupt Flag bcf STATUS,RP0 ; Bank 0 bsf Data_Rec_LED bsf Data_Error_LED ; Switch Off LED's msg1_loop movf String_Count,w ; get chacture call msg1 addlw d'0' ; Check Status reg looking for Z btfsc STATUS,Z goto Display_Address call Send_Char ; Send Chacture incf String_Count,f goto msg1_loop ; and arond Again Display_Address ; Disply current DMX Address movf DMX_Start_Addr_L,w movwf NumL movf DMX_Start_Addr_H,w movwf NumH goto bin2dec999fast Address_Recieve nop btfss flag,Keyboard_Data ; look for new keyboard Data goto Address_Recieve bcf flag,Keyboard_Data ; Clear recieved flag movf Data_Recieved,w ; Check Data xorlw h'F0' ; to see if F0 ? btfss STATUS,Z ; The Same ? goto Address_Recieve_2 ; No bsf flag,ignore_next ; Set Flag to ignore next chacture goto Address_Recieve ; Recieve next Char Address_Recieve_2 btfss flag,ignore_next ; Ignore next flag set ? goto Address_Recieve_3 ; No, bcf flag,ignore_next ; Yes - clear goto Address_Recieve ; Recieve next Char Address_Recieve_3 movf Data_Recieved,w ; Check Data xorlw Plus_Key ; to see if + ? btfsc STATUS,Z ; The Same ? goto Inc_DMX_Address ; Yes movf Data_Recieved,w ; Check Data xorlw Minus_Key ; to see if - ? btfsc STATUS,Z ; The Same ? goto Dec_DMX_Address ; Yes movf Data_Recieved,w ; Check Data xorlw Scroll_Key ; to see if save ? btfsc STATUS,Z ; The Same ? goto Save_Address ; Yes movf Data_Recieved,w ; Check Data xorlw Esc_Key ; to see if Escape ? btfsc STATUS,Z ; The Same ? goto Exit_Setup ; Yes goto Address_Recieve Save_Address ; Save DMX Addrsss in EEPROM movlw d'0' ; Address 1 movwf ee_address movf DMX_Start_Addr_L,w ; Write Low address movwf ee_data call ee_write incf ee_address,f ; Write next address movf DMX_Start_Addr_H,w ; Write High Address movwf ee_data call ee_write movlw d'8' ; Load Channel Count movwf Char_Channel incf ee_address,f Char_Setup clrf Char_Count clrf Char_Bank ; Clear Char Bank clrf Char_Bank+1 clrf Char_Bank+2 clrf Char_Bank+3 clrf Char_Bank+4 clrf Char_Bank+5 clrf Char_Bank+6 clrf String_Count msg2_loop movf String_Count,w ; get chacture call msg2 addlw d'0' ; Check Status reg looking for Z btfsc STATUS,Z goto Char_Setup_B call Send_Char ; Send Chacture incf String_Count,f goto msg2_loop ; and arond Again Char_Setup_B movf Char_Channel,w sublw d'9' ; Find Current Channel call Num_Lookup ; lookup number code call Send_Char ; And Send movlw Enter_Key call Send_Char ; + CR bcf flag,Keyboard_Data ; Clear New Data Flag movlw Char_Bank ; Setup indirect address movwf FSR movf Data_Recieved,w ; Check Data xorlw h'F0' ; to see if F0 ? btfss STATUS,Z ; The Same ? goto Char_Save ; No char_wait_loop nop btfss flag,Keyboard_Data ; Recieve next Char goto char_wait_loop bcf flag,Keyboard_Data ; Next Char is good !!! Char_Save nop btfss flag,Keyboard_Data ; look for new keyboard Data goto Char_Save bcf flag,Keyboard_Data ; Clear Flag movf Data_Recieved,w ; Check Data xorlw Scroll_Key ; to see if Enter ? btfsc STATUS,Z ; The Same ? goto Char_Write ; Yes, Write to EEPROM movf Data_Recieved,w ; Check Data xorlw Esc_Key ; to see if Enter ? btfsc STATUS,Z ; The Same ? goto Exit_Setup ; Yes movf Data_Recieved,w movwf INDF ; Save Key incf FSR,f ; Next pointer.... incf Char_Count,f ; Increase count movf Char_Count,w xorlw d'7' ; dose it = 7 ?? btfsc STATUS,Z decf Char_Count,f ; Yes, make = 6. goto Char_Save Char_Write movlw d'6' ; Setup Write to 6 locations in EEPROM movwf Char_Count movlw Char_Bank ; Setup indirect addressing movwf FSR Char_Write_Loop movf INDF,w movwf ee_data ; Get data call ee_write ; And write it incf ee_address,f ; next Address incf FSR,f ; Next Address decfsz Char_Count,f ; Check if finished ? goto Char_Write_Loop ; No, decfsz Char_Channel,f ; End Of write next channel or finish ! goto Char_Setup Char_Finish clrf String_Count msg3_loop movf String_Count,w ; get chacture call msg3 addlw d'0' ; Check Status reg looking for Z btfsc STATUS,Z goto Exit_All call Send_Char ; Send Chacture incf String_Count,f goto msg3_loop ; and arond Again Exit_Setup clrf String_Count msg4_loop movf String_Count,w ; get chacture call msg4 addlw d'0' ; Check Status reg looking for Z btfsc STATUS,Z goto Exit_All call Send_Char ; Send Chacture incf String_Count,f goto msg4_loop Exit_All bcf Data_Rec_LED bcf Data_Error_LED ; Switch Off LED's bsf STATUS,RP0 ; Bank 1 bsf PIE1,RCIE ; Enable USART Interupt Flag bcf STATUS,RP0 ; Bank 0 goto Main ; ***************************************************************************** ; * Increase Decrease DMX Address * ; * Input - DMX Address Output * ; ***************************************************************************** Inc_DMX_Address incfsz DMX_Start_Addr_L,f ; Increase DMX Address goto Display_Address ; No Overrun incf DMX_Start_Addr_H,f ; Yes increase High btfss DMX_Start_Addr_H,1 ; High =2 ??? goto Display_Address ; No decf DMX_Start_Addr_H,f ; Yes decf DMX_Start_Addr_L,f ; goto Address_Recieve ; Don't display new address Dec_DMX_Address decf DMX_Start_Addr_L,f btfss STATUS,Z ; Zero ??? goto Display_Address ; No, movf DMX_Start_Addr_H,w ; Yes, btfsc STATUS,Z ; High = 0 ??? goto Dec_DMX_Address_A ; No decf DMX_Start_Addr_H,f ; Yes, goto Display_Address Dec_DMX_Address_A incf DMX_Start_Addr_L,f ; Back to 1 goto Address_Recieve ; Don't display new address ; ***************************************************************************** ; * Send Chacture to keyboard * ; * Input - Chactuture in w Output - None ; ***************************************************************************** Send_Char movwf Char_In ; Save chacture call To_Keyboard ; send Chacture call Delay call Delay call Delay movlw h'F0' ; Send Break string call To_Keyboard call Delay call Delay call Delay movf Char_In,w call To_Keyboard call Delay call Delay call Delay return ; ***************************************************************************** ; * Write Byte to Keyboard * ; * Input - Byte to write in w Output - None * ; ***************************************************************************** To_Keyboard movwf Int_TX_Data ; Load Transmit register andlw b'11111111' ; load Status register btfsc STATUS,Z ; Check data Present. return ; No, bsf flag,Keyboard_TX; Set TX Flag - Wait till reset bsf T1CON,TMR1ON ; Enable Timer 1 - allow interupt Keyboard_Wait nop btfsc flag,Keyboard_TX; Wait till Transmitted. goto Keyboard_Wait return ; ****************************************************** ; * EEREAD * ; * * ; * ee_address = Address in EEPROM w = data read * ; ****************************************************** ee_read bsf STATUS,RP0 ; Move to bank 1 movf ee_address,w movwf EEADR ; Store eeaddress in correct location ;bcf EECON1,EEPGD ; Point to Data Memory bsf EECON1,RD ; Start EEprom read cycle movf EEDATA,w bcf STATUS,RP0 ; Bank to bank 0 return ; *************************************************************** ; * EEWRITE * ; * * ; * ee_aaddress = Address in EEPROM ee_data = data to write * ; *************************************************************** ee_write ;bcf PIR1,EEIF ; clear EE interupt flag bsf STATUS,RP0 ; Move to bank 1 movf ee_address,w movwf EEADR ; Save eeaddress movf ee_data,w movwf EEDATA ; save eedata bcf INTCON,GIE ; Disable interupts ;bcf EECON1,EEPGD ; Access Data Memory bsf EECON1,WREN ; put WREN movlw H'55' movwf EECON2 movlw H'AA' movwf EECON2 bsf EECON1,WR ; write cycle started bcf EECON1,WREN ; Disable Futher writes ;bcf STATUS,RP0 ; goto Bank 0 wr1 clrwdt ;btfss PIR1,EEIF ; wait for EE write interupt flag btfsc EECON1,WR ; Wait write to complete goto wr1 ; write cycle wait bcf STATUS,RP0 ; Bank 0 bsf INTCON,GIE ; Enable all interupts return ; *********************************************** ; * Fast binary to decimal conversion (0..999) * ; * * ; * Input: NumH:NumL * ; * Output Hund:Tens_Ones (packed BCD) * ; * * ; * Size: 59 instructions * ; * Execution time (with return): 60 * ; * * ; * 8-July-2000 by Nikolai Golovchenko * ; * Based on 8bit BIN2BCD of Scott Dattalo * ; *********************************************** bin2dec999fast swapf NumL,w ;Add the upper and lower nibbles addwf NumL,w ;to get the one's digit andlw 0x0F skpndc ;Go through a binary to bcd addlw 0x16 ;conversion for just the one's skpndc ;digit addlw 0x06 addlw 0x06 skpdc addlw -0x06 btfsc NumL,4 ;bit 4 is a special case addlw 0x16 - 1 + 0x6 skpdc addlw -0x06 ;now adjust the ten's digit btfsc NumL,5 ;2^5 = 32, so add 3 to the ten's addlw 0x30 ;digit if bit 5 is set btfsc NumL,6 ;2^6 = 64, so add 6 addlw 0x60 ;if bit 6 is set btfsc NumL,7 ;2^7 = 128, so add 2 (the ten's addlw 0x20 ;digit) if bit 7 is set addlw 0x60 ;convert the ten's digit to bcd clrf Hund rlf Hund,f ;if there's a carry, then the input btfss Hund,0 ;was greater than 99. addlw -0x60 movwf Tens_Ones movlw 0x66 ;2^8 = 256, so add 0x56 to Tens_Ones btfsc NumH,0 movlw 0x56 + 0x66 ;add 0x66 for decimal adjust addwf Tens_Ones,f skpnc incf Hund,f clrw skpc iorlw 0x60 skpdc iorlw 0x06 subwf Tens_Ones,f movlw 0x66 ;2^9 = 512, so add 0x12 to Tens_Ones btfsc NumH,1 movlw 0x12 + 0x66 addwf Tens_Ones,f skpnc incf Hund,f clrw skpc iorlw 0x60 skpdc iorlw 0x06 subwf Tens_Ones,f btfsc NumL,7 ;finish with hundreds incf Hund,f movlw 2 btfsc NumH,0 addwf Hund,f movlw 5 btfsc NumH,1 addwf Hund,f split movlw Space_Key call Send_Char ; Send Space movf Hund,w ; Send Hundreds call Num_Lookup call Send_Char swapf Tens_Ones,w andlw h'0F' call Num_Lookup ; Send Tens call Send_Char movf Tens_Ones,w andlw 0Fh call Num_Lookup ; Send Ones call Send_Char movlw Enter_Key ; Send CR call Send_Char goto Address_Recieve ; Return ; ******************************************************************** ; * Delay Loop * ; * Input - None Output - None * ; ******************************************************************** Delay clrf temp Delay_Loop nop nop nop nop incfsz temp,f goto Delay_Loop return ; ************** EEPROM Data *********************** ; Initalize EEDATA org H'2100' ; Initialize EEPROM Data de LOW(DMX_Address),HIGH(DMX_Address) ; Dmx Address Low:High de h'E0',h'74',h'E0',h'F0',h'74',h'00' ; Right Arrow de h'E0',h'6B',h'E0',h'F0',h'6B',h'00' ; Left Arrow de h'76',h'F0',h'76',h'00',h'00',h'00' ; Escape Key de h'03',h'F0',h'03',h'00',h'00',h'00' ; F5 Key de h'5A',h'F0',h'5A',h'00',h'00',h'00' ; Enter Key de h'36',h'F0',h'36',h'00',h'00',h'00' ; 6 de h'3D',h'F0',h'3D',h'00',h'00',h'00' ; 7 de h'3E',h'F0',h'3E',h'00',h'00',h'00' ; 8 de h'00',h'00',h'00',h'00',h'00',h'00' end