list p=18F45K22,R=DEC #include ;******************************************************************* ; Bits definition Port A ;******************************************************************* KEYA2 equ 0 KEYA1 equ 1 KEYA0 equ 2 LCD_E equ 3 ;LCD enable DSD equ 4 ;DAC data DSCK equ 5 ;DAC clk SP_RST_B equ 6 ;******************************************************************* ; Bits definition Port C ;******************************************************************* DR_SP equ 0 ;Data ready to seakephone ANS0 equ 1 ANS1 equ 2 TX_PRI equ 6 ;Transmit to pristavka RX_PRI equ 7 ;Receive from pristavka ;******************************************************************* ; Bits definition Port E ;******************************************************************* LCD_RS equ 0 ;Command to LCD DCS equ 1 ;CS to DAC HANG equ 3 PRIEN equ 2 ;PRISTAVKA enable ;******************************************************************* ; Bits definition Port B ;******************************************************************* AMIEN EQU 0 SYNC_S equ 1 ;Sync signal 250uS or codec frame WR_LED1 equ 2 WR_LED0 equ 3 RD_KEY equ 4 ;Read key AMP_EN equ 5 ;0-Amplifier enable BEEP equ 7 ;Beep bit FRCV equ 6 ;Forse receive bit MON_MIC equ 7 ;MON_MIC bit ;******************************************************************* ; Sin table ;******************************************************************* SIN0 equ 0xd5 SIN1 equ 0xbd SIN2 equ 0xa3 SIN3 equ 0xa8 SIN4 equ 0xaa SIN5 equ 0xa8 SIN6 equ 0xa3 SIN7 equ 0xbd SIN8 equ 0x55 SIN9 equ 0x3d SIN10 equ 0x23 SIN11 equ 0x28 SIN12 equ 0x2a SIN13 equ 0x28 SIN14 equ 0x23 SIN15 equ 0x3d ;******************************************************************* ; Variables ;******************************************************************* CNTRL equ 0x00 CNTRH equ 0x01 TX_B0 equ 0x02 ;2 bytes of B - channel for transmitting to station TX_B1 equ 0x03 TX_B2 equ 0x04 ;2 lsb of second portion of b channel RC_B0 equ 0x05 ;2 bytes of B - channel received from station RC_B1 equ 0x06 R_BYTE0 equ 0x07 ;Four bytes of D - channel received from station R_BYTE1 equ 0x08 R_BYTE2 equ 0x09 R_BYTE3 equ 0x0a T_BYTE0 equ 0x0b ;3 bytes of D - channel for transmitting to station T_BYTE1 equ 0x0c T_BYTE2 equ 0x0d DCH_BUF equ 0x0e ;Buffer for SSP register T_CRC equ 0x0f ;CRC for transmit R_CRC equ 0x10 ;CRC for receive TX_CNTR equ 0x11 ;Counter of transmit quad bits TX_CTRL equ 0x12 ;Control register for transmitting TX_TMP_BUF equ 0x13 ;New byte to station TX_FIFO_H equ 0x14 ;Head of tx fifo TX_FIFO_T equ 0x15 ;Tail of tx fifo RCV_CNTR equ 0x16 ;Counter of received quad bits RCV_CTRL equ 0x17 ;Control register for receiving PHONE_STAT equ 0x18 ;Phone status register PHONE_STAT1 equ 0x19 ;Phone status 1 register KEY_ADDRESS equ 0x1a ;Address of keyboard and LED's KEY_BYTE equ 0x1b ;Byte of pressed key on current address KEY_SMP0 equ 0x1c KEY_SMP1 equ 0x1d T_TMP equ 0x1e ;Temporary byte for transmit of D-channel BIT_CNTR equ 0x1f ;Bit counter for key scanning R_CBYTE0 equ 0x20 ;Command code byte 0 R_CBYTE1 equ 0x21 ;Command code byte 1 R_CBYTE2 equ 0x22 ;Command code byte 2 MKS_CNTR equ 0x23 ;Counter of 250uS time intervals MS10_CNTR equ 0x24 ;Counter of 10 ms LED_CNTR equ 0x25 ;Counter on/off LED_LINE equ 0x26 ;Current state of register LED_TMP equ 0x27 ;State of current LED REG_TMP equ 0x28 ;Temporary register LED_NUM equ 0x29 ;Led number LCD_ADDRESS equ 0x2a ;LCD address LCD_BUF equ 0x2b ;Pointer to byte in LCD buffer LCD_BUF_A equ 0x2c ;Lcd buffer 4 bytes (4c..4f) CLR_LCD_ADR equ 0x2d ;Start cursor position for LCD clearing. CLR_LCD_CNTR equ 0x2e ;Number of characters for clearing FN_NUM equ 0x2f ;Number of function in command group BYTE1_SEQ equ 0x30 ;Second byte of command sequence BYTE2_SEQ equ 0x31 ;Second byte of command sequence BEEP_CNTR equ 0x32 ;Sound beep counter SYNC_CTRL equ 0x33 LCD_FIFO_STAT equ 0X34 LCD_FIFO_H equ 0x35 ;Head of lcd fifo LCD_FIFO_T equ 0x36 ;Tail of lcd fifo DAC_DATAL equ 0x37 DAC_DATAH equ 0x38 DAC_CNTR equ 0x39 TIME_ADDR equ 0x3a ;LCD address for time DATE_ADDR equ 0x3b ;LCD address for date BYTE_TO_WR equ 0x3c ;Byte converting to ascii TX_FIFO_STAT equ 0x3d KB_DELAY equ 0x3e TX_PRI_CNTR equ 0x3f TX_PRI_DATA equ 0x40 RX_PRI_CNTR equ 0x41 RX_PRI_DATA equ 0x42 CNTR64 equ 0x43 LCD_RST_W equ 0x44 DATA_SP0 equ 0x45 DATA_SP1 equ 0x46 LED_STATE equ 0x60 ;State of LED's (60..6b) 12 bytes ON_OFF_CNTR equ 0x70 ;switch on/off counter (70.7b) 12 bytes BLINK_CNTR equ 0x80 ;Array of pattern counter (80..8b) 12 bytes LCD_FIFO EQU 0x90 ;LCD Fifo 32 char LCD_FIFO_A EQU 0xb0 ;LCD Fifo attribute 32 char KEY_ARRAY equ 0xd0 ;Array for 48 keys (Bank 1) LED_ARRAY equ 0xd6 ;Array of 48 LED's (Bank 1) LED_ARRAY0 equ 0xd6 LED_ARRAY1 equ 0xd7 LED_ARRAY5 equ 0xdb TX_FIFO equ 0xe0 ;TX Fifo 16 char ;******************************************************************* DELAY_LINE equ 0x0 ;256 bytes in bank 2 ;******************************************************************* ; LCD_FIFO_STAT bits definition ;******************************************************************* FIFO_EMPTY equ 0 ;1-fifo empty FIFO_FULL equ 1 ;1 - fifo full ;******************************************************************* ; TX_FIFO_STAT bits definition ;******************************************************************* TX_FIFO_EMPTY equ 0 ;1-fifo empty TX_FIFO_FULL equ 1 ;1 - fifo full ;******************************************************************* ; LCD_BUF_A bits definition ;******************************************************************* DATA_COMMAND equ 0 ; 1- command, 0 - data ;******************************************************************* ; PHONE_STAT bits definition ;******************************************************************* HANG_STATE equ 0 ;1-Up, 0-Down TOGGLE_LED equ 1 ;1 - Toggle corresponding LED bit SET_RESET_LED equ 2 ;Set (1), Reset(0) corresponding LED bit RESET_DONE equ 3 ;1- reset done, 0 - wait reset command LCD_BUF_EMPTY equ 4 ;0 - LCD buffer empty CLEAR_LCD_EN equ 5 ;1 - Clear LCD in progress LCD_BUF_2B equ 6 ;1 - Second char in buffer COMMAND_SEQ equ 7 ;1 - command sequence in progress ;******************************************************************* ; PHONE_STAT1 bits definition ;******************************************************************* LED_GR_EN equ 0 ;Led group command in progress BEEP_EN equ 1 ;1 - Sound beep enable, 0 - disable PRINT_TIME_EN equ 2 ;1 - Enable print time PRINT_DATE_EN equ 3 ;1 - Enable print date TX_PRI_IP equ 4 ;1 - Transmit to pristavka in progress RX_PRI_IP equ 5 ;1 - Receive from pristavka in progress RX_PRI_SB equ 6 ;1 - Detect start bit RX_BRDY equ 7 ;1 - Byte from host ready ;******************************************************************* ; TX_CTRL bits definition ;******************************************************************* TX_3BRDY equ 0 ;1-New 3 bytes ready TX_3BIP equ 1 ;1-Transmit 3 bytes in progress TX_ZF equ 2 ;Transmit zero frame RELEASE_FLAG equ 3 ;Flag of released key MON_ST equ 4 ;MON key status MIC_ST equ 5 ;MIC key status SYNC_ST equ 6 ;State of sync 0 - sync OK KB_SCAN_EN equ 7 ;1 - scan kb enable ;******************************************************************* ; RCV_CTRL bits definition ;******************************************************************* COMMAND_RDY equ 0 ;1-command ready, 0-wait ;******************************************************************* MAX_ADR equ 4 ;Max address for keys ;******************************************************************* ; Speaker Phone control bits ;******************************************************************* MUTE equ 4 ;0 - mic on ATT_RANGE equ 5 ;0 - 52dB, 1 - 26dB SP_MODE0 equ 6 ;Mode of operation 00 - normal, SP_MODE1 equ 7 ;01 - receive, 10 - idle, 11 - transmit ;B3 - B0 Volume, 0000 - max, 1111 - min ;******************************************************************* org 0x00 ;Effective Reset Vector goto START ;******************************************************************* org 0x8 retfie ; goto INTR ;******************************************************************* org 0x18 retfie ; goto INTR1 ;******************************************************************* org 0x1a PAT_4 addwf PCL,F retlw 21 retlw 42 retlw 21 retlw 250 ;******************************************************************* PAT_6 addwf PCL,F retlw 21 retlw 21 retlw 21 retlw 21 retlw 21 retlw 233 ;******************************************************************* PAT_8 addwf PCL,F retlw 8 retlw 8 retlw 8 retlw 8 retlw 8 retlw 125 ;******************************************************************* PAT_11 addwf PCL,F retlw 42 retlw 42 retlw 42 retlw 42 retlw 42 retlw 255 ;******************************************************************* PAT_12 addwf PCL,F retlw 67 retlw 42 retlw 67 retlw 167 ;******************************************************************* PAT_13 addwf PCL,F retlw 8 retlw 13 retlw 50 retlw 13 ;******************************************************************* PAT_14 addwf PCL,F retlw 8 retlw 13 retlw 8 retlw 58 ;******************************************************************* BYTE_BMP addwf PCL,F retlw 1 retlw 2 retlw 4 retlw 8 retlw 0x10 retlw 0x20 retlw 0x40 retlw 0x80 ;******************************************************************* BLINK_F addwf PCL,F goto BF0 goto BF1 goto BF2 goto BF3 goto BF4 goto BF5 goto BF6 goto BF7 goto BF8 goto BF9 goto BF10 goto BF11 goto BF12 goto BF13 goto BF14 goto BF15 ;******************************************************************* CL_LCD_CPOS addwf PCL,F retlw 0x80 retlw 0xc0 retlw 0x94 retlw 0xd4 ;******************************************************************* CL_LCD_CNTR addwf PCL,F retlw 1 retlw 20 retlw 12 retlw 12 ;******************************************************************* org 0x100 COM_40 rlncf FN_NUM,F rlncf FN_NUM,w ; movf FN_NUM,W addwf PCL,F goto DISPL_TXT ;0x40 goto CLEAR_DISPL_SET_TIME ;0x41 goto CURSOR_CNTRL ;0x42 goto SET_CURSOR_POS ;0x43 goto TMP ;0x44 goto TMP ;0x45 goto TMP ;0x46 goto TMP ;0x47 goto TMP ;0x48 goto TMP ;0x49 goto TMP ;0x4a goto TMP ;0x4b goto TMP ;0x4c goto TMP ;0x4d goto LED_CTRL ;0x4e goto TMP ;CMD_SEQ ;0x4f ;******************************************************************* COM_50 rlncf FN_NUM,F rlncf FN_NUM,w addwf PCL,F goto SET_YEAR ;0x50 goto SET_DATE ;0x51 goto TMP ;0x52 goto SET_TIME ;0x53 goto SET_TIME_D ;0x54 goto TMP ;0x55 goto TMP ;0x56 goto TMP ;0x57 goto TMP ;0x58 goto TMP ;0x59 goto TMP ;0x5a goto TMP ;0x5b goto TMP ;0x5c goto TMP ;0x5d goto TMP ;0x5e goto TMP ;0x5f ;******************************************************************* COM_60 addwf PCL,F goto TMP ;MODE0 ;0x00 goto TMP ;MODE1 ;0x20 goto TMP ;0x40 goto TMP ;MODE3 ;0x60 goto TMP ;MODE4 ;0x80 goto TMP ;0xa0 goto TMP ;0xc0 goto TMP ;0xe0 ;******************************************************************* COM_TAB addwf PCL,F goto TMP ;LED4_CTRL ;0x00 goto TMP ;0x10 goto TMP ;LED4_CTRL ;0x20 goto TMP ;0x30 goto COM_40 ;0x40 goto COM_50 ;0x50 goto SOUND_DEV ;0x60 goto CTRL_COM ;0x70 goto TMP ;0x80 goto TMP ;0x90 goto TMP ;0xa0 goto TMP ;0xb0 goto TMP ;0xc0 goto TMP ;0xd0 goto TMP ;LED4_CTRL ;0xe0 goto TMP ;0xf0 ;******************************************************************* TMP goto CME ;******************************************************************* COM_MENU btfss RCV_CTRL,COMMAND_RDY ;Is new command received? return ;No. movlw 1 movwf PCLATH movlw 0x0f andwf R_CBYTE0,W ;Select number of function in group movwf FN_NUM ;Store it movlw 0xf0 andwf R_CBYTE0,F ;Select command group number rlncf R_CBYTE0,F rlncf R_CBYTE0,F swapf R_CBYTE0,W ;Store it in low nibble goto COM_TAB CME bcf RCV_CTRL,COMMAND_RDY ;Reset ready bit return ;******************************************************************* BF0 bcf PHONE_STAT,SET_RESET_LED goto BFSR BF1 bsf PHONE_STAT,SET_RESET_LED BFSR movlw 255 ;1 sec movwf INDF0 ;New value of counter bcf PHONE_STAT,TOGGLE_LED goto BFE6 BF2 movlw 167 ;1 sec movwf INDF0 ;New value of counter goto BFE BF3 movlw 83 ;.5 sec movwf INDF0 ;New value of counter goto BFE BF4 call GET_BLINK_CNTR_4 rlncf INDF0,W call PAT_4 ;4 pulse pattern goto BF16 BF5 movlw 21 ;.125 sec movwf INDF0 ;New value of counter goto BFE BF6 call GET_BLINK_CNTR_6 rlncf INDF0,W call PAT_6 ;4 pulse pattern goto BF16 BF7 movlw BLINK_CNTR addwf LED_CNTR,W movwf FSR0L incf INDF0,F movlw 8 btfsc INDF0,0 ;Odd or even? movlw 13 goto BF16 BF8 call GET_BLINK_CNTR_6 rlncf INDF0,W call PAT_8 ;4 pulse pattern goto BF16 BF9 movlw 0 ;256 ;2 sec movwf INDF0 ;New value of counter goto BFE BF10 movlw 42 ;.25 sec movwf INDF0 ;New value of counter goto BFE BF11 call GET_BLINK_CNTR_6 rlncf INDF0,W call PAT_11 ;4 pulse pattern goto BF16 BF12 call GET_BLINK_CNTR_4 rlncf INDF0,W call PAT_12 ;4 pulse pattern goto BF16 BF13 call GET_BLINK_CNTR_4 rlncf INDF0,W call PAT_13 ;4 pulse pattern goto BF16 BF14 call GET_BLINK_CNTR_4 rlncf INDF0,W call PAT_14 ;4 pulse pattern goto BF16 BF15 return BF16 movwf REG_TMP ;Store result movlw ON_OFF_CNTR addwf LED_CNTR,W movwf FSR0L movf REG_TMP,W movwf INDF0 ;New value of counter BFE bsf PHONE_STAT,TOGGLE_LED BFE6 movlw LED_ARRAY0 ;Get line address btfsc LED_CNTR,3 ;Is LED0..7? movlw LED_ARRAY1 ;Get line address movwf FSR0L ;Address in FSR0L rlncf LED_CNTR,W andlw 0x0e call BYTE_BMP ;Bit mask of LED in W btfss PHONE_STAT,TOGGLE_LED goto BFE4 xorwf INDF0,F return BFE4 btfss PHONE_STAT,SET_RESET_LED goto BFE5 iorwf INDF0,F return BFE5 xorlw 0xff ;Invert mask andwf INDF0,F return ;******************************************************************* SOUND_DEV ; bcf DATA_SP,MUTE ;Enable speakerphone mic ; btfsc R_CBYTE1,0 ; bsf DATA_SP,MUTE ;Disable speakerphone mic ; call WR_SP btfsc FN_NUM,3 ;Is it 60xxxx command? goto CME ;No btfsc R_CBYTE1,7 ;Is Speakerphone On? goto SND_D0 bcf PORTC,ANS1 nop bsf PORTC,ANS0 goto CME SND_D0 bsf PORTC,ANS1 nop bcf PORTC,ANS0 goto CME ;******************************************************************* LED_BLINK btfsc TX_CTRL,TX_ZF return btfss MKS_CNTR,0 ;Chek LED's once in 500uS return ; goto SOUND_BEEP L_B0 movf LED_CNTR,W addlw LED_STATE movwf FSR0L movf INDF0,W andlw 0x0f movwf LED_TMP ;Store state of current LED movlw ON_OFF_CNTR addwf LED_CNTR,W movwf FSR0L decfsz INDF0,F goto L_BE rlncf LED_TMP,F ;Pattern number rlncf LED_TMP,W clrf PCLATH call BLINK_F ;Next pulse L_BE incf LED_CNTR,1 btfss LED_CNTR,4 ;Is LED_CNTR=0x10? return ;No clrf LED_CNTR return ;******************************************************************* CLEAR_DISPL_SET_TIME btfss PHONE_STAT,RESET_DONE goto CME movf R_CBYTE1,F ;Is it clear display command? btfss STATUS,Z goto C_D_2 ;No. return movlw 0x3 ;Select bits 0,1 andwf R_CBYTE2,F ;Get field number btfsc STATUS,Z goto CME cpfseq R_CBYTE2 ;Is it field 3? goto C_D_0 ;No bcf PHONE_STAT1,PRINT_DATE_EN goto C_D_1 C_D_0 movlw 0x2 cpfseq R_CBYTE2 ;Is it field 2? goto C_D_1 ;No bcf PHONE_STAT1,PRINT_TIME_EN C_D_1 rlncf R_CBYTE2,W movwf BYTE1_SEQ call CDST0 goto CME C_D_2 movlw 0x04 ;Is it print time format HH:MM 'am' or 'pm'? cpfseq R_CBYTE1 goto C_D_3 ;No movlw 0x3 ;Select bits 0,1 andwf R_CBYTE2,F ;Get field number rlncf R_CBYTE2,W clrf PCLATH call CL_LCD_CPOS ;Get cursor position movwf TIME_ADDR bsf PHONE_STAT1,PRINT_TIME_EN goto CME C_D_3 movlw 0x0b ;Is it DD MMM YY format? cpfseq R_CBYTE1 goto CME ;No movlw 0x3 ;Select bits 0,1 andwf R_CBYTE2,F ;Get field number rlncf R_CBYTE2,W clrf PCLATH call CL_LCD_CPOS ;Get cursor position movwf DATE_ADDR bsf PHONE_STAT1,PRINT_DATE_EN goto CME ;******************************************************************* CDST0 ; bsf PHONE_STAT,CLEAR_LCD_EN ;Set LCD in progress flag clrf PCLATH call CL_LCD_CPOS ;Get cursor position movwf CLR_LCD_ADR ;Save it movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND call WRITE_TO_FIFO movf BYTE1_SEQ,W call CL_LCD_CNTR ;Get counter movwf CLR_LCD_CNTR ;Save it bcf LCD_BUF_A,DATA_COMMAND movlw 0x20 movwf LCD_BUF CDST1 call WRITE_TO_FIFO decfsz CLR_LCD_CNTR,F goto CDST1 movf CLR_LCD_ADR,W movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND call WRITE_TO_FIFO return ;******************************************************************* START movlb 0xf ;bank 15 clrf ANSELA,1 clrf ANSELB,1 clrf ANSELC,1 clrf ANSELD,1 clrf ANSELE,1 movlb 0x0 ;bank 0 movlw 0x0 ;Peripheral int enable movwf INTCON movlw 0x80 ;RA0, RA1,RA2,RA3,RA4,RA5,RA6 - outputs, RA7 - inputs movwf TRISA movlw 0x82 ;RB0,RB2,RB3,RB4,RB5,RB6-outputs, RB1,RB7 - inputs movwf TRISB movlw 0xd8 ;RC0,RC1,RC2,RC5-outputs, RC3,RC4,RC7,RC6 - inputs movwf TRISC movlw 0xff ;RD0,RD1,RD2,RD3,RD4,RD5,RD6,RD7 - inputs movwf TRISD movlw 0xf8 ;RE0,RE1,RE2-outputs, RE3,RE4,RE5,RE6,RE7 - inputs movwf TRISE movlw 0x70 movwf OSCCON movlw 0x40 ;PLL enable movwf OSCTUNE clrwdt ;Clear watch dog timer ; bsf OPTION_REG,PSA ;Prescaler is assigned to to WDT ; bcf OPTION_REG,PS0 ; bcf OPTION_REG,PS1 ; bcf OPTION_REG,PS2 ;Prescaler value 000 - 1:1. WDT period ~ 18 msec bcf INTCON2,NOT_RBPU ;Weak Pull-up enable movlw 0x0 movwf SSP1STAT ;SMP=0,CKE=0 movlw 0x5 ;SPI - disable,CKP=0,SPI slave,SS disable. movwf SSP1CON1 bsf SSP1CON3,BOEN bcf SSP2CON1,SSPEN ;SSP2 disable movlw 0x00 movwf BAUDCON1 ; movlw 0x4d ;48000/9600/64 - 1=77 movlw 0x67 ;64000/9600/64 - 1=104 movwf SPBRG1 clrf SPBRGH1 movlw 0x20 ;Async, TX enable, low speed, 8 bit movwf TXSTA1 movlw 0x90 ;Port enable, 8 bit, no address detect movwf RCSTA1 clrf PCLATU clrf FSR0H clrf FSR0L movlw 0x2 movwf FSR1H ;select bank 2 for indirect 1 clrf FSR1L bsf LATE,PRIEN ;Pristavka disable clrf 0xd0 clrf 0xd1 clrf 0xd2 clrf 0xd3 clrf 0xd4 clrf 0xd5 clrf 0xd6 clrf 0xd7 clrf 0xd8 clrf 0xd9 clrf 0xda clrf 0xdb clrf KEY_SMP0 clrf KEY_SMP1 movlw 0x3 movwf PORTC clrf PORTA bsf LATB,RD_KEY bcf RCV_CTRL,COMMAND_RDY clrf T_BYTE2 ;Yes. Fill with 0 D-chn buffer clrf T_BYTE1 clrf T_BYTE0 clrf T_CRC clrf KEY_ADDRESS clrf BIT_CNTR clrf MKS_CNTR clrf MS10_CNTR clrf LED_CNTR clrf PHONE_STAT clrf PHONE_STAT1 clrf CLR_LCD_CNTR clrf SYNC_CTRL call INIT_LED_TAB clrf KEY_BYTE bcf TX_CTRL,TX_3BIP ;Clear 3 bytes in progress bit bcf TX_CTRL,TX_3BRDY ;clear 3 byte ready bit ; bsf TX_CTRL,TX_ZF ;Send zero frame, untill reset bcf TX_CTRL,TX_ZF ;Send zero frame, untill reset bsf TX_CTRL,SYNC_ST ;No sync bsf TX_CTRL,MON_ST bsf TX_CTRL,MIC_ST, bsf PHONE_STAT,HANG_STATE btfsc PORTE,HANG ;Hang up? bcf PHONE_STAT,HANG_STATE bcf LATB,AMP_EN ;******************************************************************** bcf PIR1,SSP1IF ;Clear SPI interrupt flag call RESET_AMI ;Stop transmiting clrf T1CON ;Timer1 prescaler = 0 clrf REG_TMP bsf LATC,DR_SP call SP_RST call ST_DELAY ;Delay call WR_LED ; clrf FRCV_CNTR ;Clear counter for rcv wait call SET_AMI ;Start transmiting call ST_DELAY ;Delay bsf LCD_FIFO_STAT,FIFO_EMPTY bcf LCD_FIFO_STAT,FIFO_FULL bsf TX_FIFO_STAT,TX_FIFO_EMPTY bcf TX_FIFO_STAT,TX_FIFO_FULL clrf LCD_FIFO_H ;Fifo empty clrf LCD_FIFO_T call LCD_RESET clrf TX_FIFO_H ;Fifo empty clrf TX_FIFO_T call SP_CFG bcf PHONE_STAT,RESET_DONE call SYNC_AMI ;Wait ami synchronisation TMP_LOOP ; call TOGGLE_TMP ; call ST_DELAY clrwdt ;Clear watch dog timer ; goto TMP_LOOP ; call SET_AMI ;Start transmiting bsf SSP1CON1,SSPEN ;SPI - enable bcf PIR1,SSP1IF ;Clear SPI interrupt flag movf SSP1BUF,W clrf CNTRL clrf CNTRH ;******************************************************************** LOOP incfsz CNTRL,F goto LOOP1 incfsz CNTRH,F goto LOOP1 ; call SYNC_AMI ;Wait ami synchronisation ; goto START ;Yes. Reset LOOP1 clrwdt ;Clear watch dog timer ;****************************** ; Go to receive 36 bits ;****************************** call TOGGLE_TMP call RECEIVE_PRI RS0 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto RS0 ;No, wait movf SSP1BUF,W ;Get firs byte of B-channel movwf RC_B0 ;Save it bcf PIR1,SSP1IF ;Clear SPI interrupt flag RS1 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto RS1 ;No, wait movf SSP1BUF,W bcf PIR1,SSP1IF ;Clear SPI interrupt flag call LED_BLINK RS2 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto RS2 ;No, wait movf SSP1BUF,W movwf DCH_BUF andlw 0x3f ;take 6 bits of B-channel movwf RC_B1 ;Save them bcf PIR1,SSP1IF ;Clear SPI interrupt flag call RCV_DCHANNEL ;Get 2 bits of D-channel call TEST_COMMAND ; call LED_GR_SCAN RS3 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto RS3 ;No, wait movf SSP1BUF,W movwf DCH_BUF rlcf DCH_BUF,1 rlcf RC_B1,1 rlcf DCH_BUF,1 rlcf RC_B1,1 bcf PIR1,SSP1IF ;Clear SPI interrupt flag RS4 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto RS4 ;No, wait movf SSP1BUF,W movwf DCH_BUF bcf PIR1,SSP1IF ;Clear SPI interrupt flag rlcf DCH_BUF,F rlcf DCH_BUF,F movf RC_B0,W ;Prepare to transmit new byte to codec movwf SSP1BUF bcf SYNC_CTRL,0 bcf SYNC_CTRL,1 btfsc PORTB,SYNC_S ;Check sync bits bsf SYNC_CTRL,0 ;***************************** call RCV_DCHANNEL ;Get 2 bits of D-channel LP0 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto LP0 ;No, wait movf SSP1BUF,W ; call DELAY_TX movwf TX_B1 movf TX_B0,W movwf SSP1BUF bcf PIR1,SSP1IF btfsc PORTB,SYNC_S ;Check sync bit bsf SYNC_CTRL,1 call SCAN_LCD ;***************************** ; Go to transmit 36 bits ;***************************** call TOGGLE_TMP clrf TX_B2 TS0 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto TS0 ;No, wait movf SSP1BUF,W bcf PIR1,SSP1IF ;Clear SPI interrupt flag bcf STATUS,C ;Clear carry rrcf TX_B1,1 ;Shift 2 bits of b-channel rrcf TX_B2,1 ;to clear place for D-channel rrcf TX_B1,1 rrcf TX_B2,1 rrcf T_BYTE2,1 ;Shift D-channel 2 times rrcf T_BYTE1,1 rrcf T_BYTE0,1 btfss STATUS,C ;Bit7=0? goto TS_0_0 incf T_CRC,1 ;Yes. Increment CRC bsf STATUS,C ;Restore carry TS_0_0 rlcf T_TMP,1 rrcf T_BYTE2,1 rrcf T_BYTE1,1 rrcf T_BYTE0,1 btfss STATUS,C ;Bit7=0? goto TS_0_1 incf T_CRC,1 ;Yes. Increment CRC bsf STATUS,C ;Restore carry TS_0_1 rlcf T_TMP,1 rlcf T_TMP,1 rlcf T_TMP,1 swapf T_TMP,W andlw 0xc0 ;Mask for bit7,6 of D-channel iorwf TX_B1,1 ;Mix bits of B and D channels TS1 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto TS1 ;No, wait movf SSP1BUF,W movf TX_B1,W movwf SSP1BUF bcf PIR1,SSP1IF ;Clear SPI interrupt flag call SCAN_KBD ;Scan keyboard TS2 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto TS2 ;No, wait movf SSP1BUF,W movf TX_B2,W movwf SSP1BUF bcf PIR1,SSP1IF ;Clear SPI interrupt flag movlw 0x0 ;Clear W btfsc T_BYTE0,1 ;Is last bit =1 movlw 0xff ;No. Set tail=1 movwf TX_B2 bcf STATUS,C ;Clear carry rrcf T_BYTE2,1 rrcf T_BYTE1,1 rrcf T_BYTE0,1 btfss STATUS,C ;Bit7=0? goto TS_2_0 incf T_CRC,1 ;Yes. Increment CRC bsf STATUS,C ;Restore carry TS_2_0 rlcf TX_B2,1 rrcf T_BYTE2,1 rrcf T_BYTE1,1 rrcf T_BYTE0,1 btfss STATUS,C ;Bit7=0? goto TS_2_1 incf T_CRC,1 ;Yes. Increment CRC bsf STATUS,C ;Restore carry TS_2_1 rlcf TX_B2,1 swapf TX_B2,1 ; call CHECK_HANG ;Check hang state TS3 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto TS3 ;No, wait movf SSP1BUF,W movf TX_B2,W movwf SSP1BUF bcf PIR1,SSP1IF ;Clear SPI interrupt flag TS4 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto TS4 ;No, wait movf SSP1BUF,W bcf PIR1,SSP1IF ;Clear SPI interrupt flag movf RC_B1,W ;Prepare to transmit new byte to codec movwf SSP1BUF call SCAN_LCD bcf SYNC_CTRL,2 bcf SYNC_CTRL,3 btfsc PORTB,SYNC_S ;Check sync bitS bsf SYNC_CTRL,2 ;******************************** LP3 btfss PIR1,SSP1IF ;Is SPI receive 8 bits? goto LP3 ;No, wait btfsc PORTB,SYNC_S ;Check sync bit bsf SYNC_CTRL,3 movlw 0x9 ;Is sync pattern 1001? xorwf SYNC_CTRL,W btfss STATUS,Z call SYNC_AMI movf SSP1BUF,W ; call DELAY_TX movwf TX_B0 bcf PIR1,SSP1IF ;Clear SPI interrupt flag btfsc TX_CTRL,TX_3BIP ;Is 3 bytes transmitting is in progress? call TX_3B ;Yes. btfss RCV_CTRL,COMMAND_RDY call TEST_COMMAND call COM_MENU goto LOOP ;******************************************************************* DELAY_TX movwf INDF1 incf FSR1L movf INDF1,W return ;******************************************************************* SOUND_BEEP btfss PHONE_STAT1,BEEP_EN return movlw 0x80 xorwf LATB,F ;Toggle bit 7 movlw 0x0f andwf MKS_CNTR,W ;4 ms count btfss STATUS,Z return decfsz BEEP_CNTR,F ;Decrement counter return bcf PHONE_STAT1,BEEP_EN ;Beep disable ; bcf LATB,BEEP return ;******************************************************************* CMD_SEQ movf R_CBYTE1,W movwf BYTE1_SEQ xorlw 0xff ;Terminator? btfsc STATUS,Z ;Yes goto CME movf R_CBYTE2,W movwf BYTE2_SEQ xorlw 0xff ;Terminator? btfss STATUS,Z ;Yes bsf PHONE_STAT,COMMAND_SEQ call CMD_SEQ_MENU goto CME ;******************************************************************* CMD_SEQ_MENU movlw 0xd0 ;Clear field 3 xorwf BYTE1_SEQ,W btfss STATUS,Z goto CSM0 movlw 0x3 ;Go to clear display field 3 movwf BYTE1_SEQ call CDST0 return CSM0 movlw 0xcf ;Clear field 2 xorwf BYTE1_SEQ,W btfss STATUS,Z goto CSM1 movlw 0x2 ;Go to clear display field 3 movwf BYTE1_SEQ call CDST0 CSM1 movlw 0xce ;Clear field 3 xorwf BYTE1_SEQ,W btfss STATUS,Z goto CSM2 movlw 0x1 ;Go to clear display field 3 movwf BYTE1_SEQ call CDST0 CSM2 movlw 0xD1 ;Clear field 3 xorwf BYTE1_SEQ,W btfss STATUS,Z goto CSM3 movlw 0x3 ;Go to clear display field 3 movwf BYTE1_SEQ call CDST0 CSM3 return ;******************************************************************* WRITE_BYTE bcf LCD_BUF_A,DATA_COMMAND swapf BYTE_TO_WR,W ;Convert nibbles to ascii andlw 0x0f addlw 0x30 movwf LCD_BUF call WRITE_TO_FIFO movlw 0x0f andwf BYTE_TO_WR,W addlw 0x30 movwf LCD_BUF call WRITE_TO_FIFO return ;******************************************************************* SET_YEAR btfss PHONE_STAT1,PRINT_DATE_EN goto CME movf DATE_ADDR,W addlw 0x07 movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND call WRITE_TO_FIFO movf R_CBYTE2,W movwf BYTE_TO_WR call WRITE_BYTE goto CME ;******************************************************************* SET_DATE btfss PHONE_STAT1,PRINT_DATE_EN goto CME movf DATE_ADDR,W movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND call WRITE_TO_FIFO movf R_CBYTE2,W movwf BYTE_TO_WR call WRITE_BYTE movlw 0x20 movwf LCD_BUF call WRITE_TO_FIFO movf R_CBYTE1,F ;Is month value = 0? btfsc STATUS,Z goto CME ;Yes. Unproper value movlw 0xe0 ; andwf R_CBYTE1,W ;Check for proper month value btfss STATUS,Z ;Is high nibble >1? goto CME ;Yes. Unproper value movlw 0x0f ;Select low nibble andwf R_CBYTE1,W btfsc R_CBYTE1,4 ;Is month > 9? addlw 0x0a ;Yes, add 10 movwf BYTE_TO_WR ;Save it movlw 0xd ;Is pesult < 12? cpfslt BYTE_TO_WR goto CME ;No. Unproper value movlw 0x12 movwf PCLATH decf BYTE_TO_WR,F movf BYTE_TO_WR,W addwf BYTE_TO_WR,F addwf BYTE_TO_WR,F rlncf BYTE_TO_WR,W call MONTH_LUT movwf LCD_BUF call WRITE_TO_FIFO incf BYTE_TO_WR,F rlncf BYTE_TO_WR,W call MONTH_LUT movwf LCD_BUF call WRITE_TO_FIFO incf BYTE_TO_WR,F rlncf BYTE_TO_WR,W call MONTH_LUT movwf LCD_BUF call WRITE_TO_FIFO goto CME ;******************************************************************* SET_TIME btfss PHONE_STAT1,PRINT_TIME_EN goto CME movf TIME_ADDR,W movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND call WRITE_TO_FIFO movf R_CBYTE1,W movwf BYTE_TO_WR call WRITE_BYTE movlw 0x3a movwf LCD_BUF call WRITE_TO_FIFO movf R_CBYTE2,W movwf BYTE_TO_WR call WRITE_BYTE goto CME ;******************************************************************* SET_TIME_D btfss PHONE_STAT1,PRINT_TIME_EN goto CME movf TIME_ADDR,W addlw 5 movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND call WRITE_TO_FIFO bcf LCD_BUF_A,DATA_COMMAND movlw 0x20 movwf LCD_BUF call WRITE_TO_FIFO movf R_CBYTE1,W movwf LCD_BUF call WRITE_TO_FIFO movf R_CBYTE2,W movwf LCD_BUF call WRITE_TO_FIFO goto CME ;******************************************************************* DISPL_TXT btfss PHONE_STAT,RESET_DONE goto CME clrf LCD_BUF_A movf R_CBYTE1,W movwf LCD_BUF call WRITE_TO_FIFO movf R_CBYTE2,W ;Is second byte is empty symbol (00)? btfsc STATUS,Z goto CME ;Yes movwf LCD_BUF call WRITE_TO_FIFO goto CME ;******************************************************************* WRITE_TO_FIFO bcf LCD_FIFO_STAT,FIFO_EMPTY ;Fifo is not empty bcf TX_CTRL,KB_SCAN_EN clrf KB_DELAY btfsc LCD_FIFO_STAT,FIFO_FULL ;Is fifo full return ; yes movf LCD_FIFO_H,W addlw LCD_FIFO movwf FSR0L ;Store address for indirect addressing movf LCD_BUF,W ;Data or command movwf INDF0 ;Store new char in fifo movlw 0x20 ; addwf FSR0L,F ;Store address for indirect addressing movf LCD_BUF_A,W ;LCD address movwf INDF0 ;Store new char in fifo incf LCD_FIFO_H,F movlw 0x1f andwf LCD_FIFO_H,F movf LCD_FIFO_T,W xorwf LCD_FIFO_H,W ;Is tail = head? btfsc STATUS,Z bsf LCD_FIFO_STAT,FIFO_FULL ;fifo is full return ;******************************************************************* WRITE_CHAR clrf TRISD bsf LATE,LCD_RS ;Set data phase movf LCD_BUF,W movwf PORTD ; movlw 0x48 ; iorwf LATA,F bsf LATA,LCD_E nop nop nop nop nop ; xorwf LATA,F bcf LATA,LCD_E nop movlw 0xff movwf TRISD return ;******************************************************************* CTRL_COM movf R_CBYTE1,F ;Read status frame? btfsc STATUS,Z goto CC1 ;Yes btfss R_CBYTE1,4 ;Is it sound control command? goto CC0 ;No btfss R_CBYTE1,2 ;Is it one 0.8 sec beep? goto CME ;No. Return bsf PHONE_STAT1,BEEP_EN ;Beep enable movlw 200 ;0.8 sec movwf BEEP_CNTR goto CME CC0 btfss R_CBYTE1,0 ;Is it Reset command? goto CC2 ; call INIT_LED_TAB bcf LATE,PRIEN ;Pristavka enable movlw 0x8 ;Start link control movwf TX_TMP_BUF call WRITE_TO_TX_FIFO movlw 0x3 ;LKD-8DS movwf TX_TMP_BUF call WRITE_TO_TX_FIFO movlw 0x01 btfsc PORTE,HANG ;Hang up? movlw 0x02 movwf TX_TMP_BUF call WRITE_TO_TX_FIFO clrf MKS_CNTR bsf PHONE_STAT,RESET_DONE goto CME CC1 call STATUS_REQ goto CME CC2 goto CME ;******************************************************************* LED_CTRL btfss R_CBYTE1,4 ;Is it individual LED command? goto CME ;No LED_IND movlw 0x11 movwf PCLATH movlw 0x0f andwf R_CBYTE2,W ;Get LED state movwf LED_TMP ;Store it to TMP register movlw 0xf0 swapf R_CBYTE1,F ;Select high nibble of LED number andwf R_CBYTE1,F swapf R_CBYTE2,W ;Select low nibble of LED number andlw 0x0f iorwf R_CBYTE1,F ;Led number in W movlw 0x30 ;Max LED number 47 cpfslt R_CBYTE1 goto CME rlncf R_CBYTE1,W call LED_NUM_LUT movwf LED_NUM ;Store it btfss LED_NUM,7 ;Is it pristavka LED? goto L_C0 ;No movlw 0x0 cpfseq LED_TMP bsf LED_NUM,6 movf LED_NUM,W movwf TXREG1 goto CME L_C0 call SET_LED_STATE goto CME ;******************************************************************* SET_LED_STATE movlw 0x0f xorwf LED_TMP,W ;Is LED state changed? btfsc STATUS,Z return ; goto CME ;No. Return movf LED_NUM,W sublw 0xf btfsc STATUS,C ;Is it flex LED's (0..15)? goto LI4 return LI4 movf LED_NUM,W addlw LED_STATE movwf FSR0L movf LED_TMP,W movwf INDF0 call INIT_LED_CNTR return ;******************************************************************* LED4_CTRL bcf STATUS,C rlcf FN_NUM,F rlcf FN_NUM,W ;LED number=FN_MUM<<2+nibble num movwf LED_NUM bsf PHONE_STAT1,LED_GR_EN goto CME LED_GR_SCAN btfss PHONE_STAT1,LED_GR_EN return movlw 0xf andwf R_CBYTE2,W ;State of 1 LED in group movwf LED_TMP call SET_LED_STATE call SHIFT_LED_STATE incf LED_NUM,F movlw 0x3 andwf LED_NUM,W btfsc STATUS,Z bcf PHONE_STAT1,LED_GR_EN return ;******************************************************************* SHIFT_LED_STATE clrf REG_TMP SLS_0 incf REG_TMP,F rrcf R_CBYTE1,F rrcf R_CBYTE2,F btfss REG_TMP,2 goto SLS_0 return ;******************************************************************* GET_BLINK_CNTR_6 movlw BLINK_CNTR addwf LED_CNTR,W movwf FSR0L incf INDF0,F btfss INDF0,1 return btfss INDF0,2 return clrf INDF0 return ;******************************************************************* GET_BLINK_CNTR_4 movlw BLINK_CNTR addwf LED_CNTR,W movwf FSR0L incf INDF0,F btfss INDF0,2 return clrf INDF0 return ;******************************************************************* WR_LED clrf TRISD movf LED_ARRAY0,W movwf PORTD bsf LATB,WR_LED0 nop bcf LATB,WR_LED0 movf LED_ARRAY1,W movwf PORTD bsf LATB,WR_LED1 nop bcf LATB,WR_LED1 return ;******************************************************************* TOGGLE_TMP movlw 0x40 xorwf LATB,F return bsf LATB,FRCV nop nop bcf LATB,FRCV return ;******************************************************************* WRITE_TO_TX_FIFO bcf TX_FIFO_STAT,TX_FIFO_EMPTY ;Fifo is not empty btfsc TX_FIFO_STAT,TX_FIFO_FULL ;Is fifo full? return ; yes movf TX_FIFO_H,W addlw TX_FIFO movwf FSR0L ;Store address for indirect addressing movf TX_TMP_BUF,W ;Data movwf INDF0 ;Store new char in fifo incf TX_FIFO_H,F movlw 0xf andwf TX_FIFO_H,F movf TX_FIFO_T,W xorwf TX_FIFO_H,W ;Is tail = head? btfsc STATUS,Z bsf TX_FIFO_STAT,TX_FIFO_FULL ;fifo is full return ;******************************************************************* TEST_COMMAND movf R_BYTE0,W ;Test start bits (0101) andlw 0xf ;Select them sublw 0x5 btfss STATUS,Z ;Is it start? return ;No. Wait btfss R_BYTE3,6 ;Is bit0=1? return ;No btfss R_BYTE3,7 ;Is bit1=1? return ;No movlw 0x0f ;3 ms subwf CNTRL,W ;Compare clrf CNTRL clrf CNTRH btfss STATUS,C ;Is time more then 2.5ms return ;************ swapf R_BYTE0,W ;Select low nibble and move it to high andlw 0x0f movwf R_CBYTE0 ;Save it swapf R_BYTE1,W ;Select next nibble andlw 0xf0 iorwf R_CBYTE0,1 ;Save first byte ;************ swapf R_BYTE1,W ;Select next nibble andlw 0x0f movwf R_CBYTE1 ;Save it swapf R_BYTE2,W ;Select next nibble andlw 0xf0 iorwf R_CBYTE1,1 ;Save 2-nd byte ;************ swapf R_BYTE2,W ;Select next nibble andlw 0x0f movwf R_CBYTE2 ;Save it swapf R_BYTE3,W ;Select next nibble andlw 0xf0 iorwf R_CBYTE2,1 ;Save 3-d byte ;************ bsf RCV_CTRL,COMMAND_RDY ;Set command ready bit return ;******************************************************************* RD_TX_FIFO movf TX_FIFO_T,W addlw TX_FIFO movwf FSR0L ;Store address for indirect addressing movf INDF0,W ;Read new char from fifo movwf TX_TMP_BUF incf TX_FIFO_T,F movlw 0xf andwf TX_FIFO_T,F movf TX_FIFO_H,W xorwf TX_FIFO_T,W ;Is tail = head? btfss STATUS,Z return bsf TX_FIFO_STAT,TX_FIFO_EMPTY ;fifo is empty return ;******************************************************************* STATUS_REQ ; btfsc TX_CTRL,TX_ZF ;Is reset done? ; goto S_R0 ;No. Send zero frame movlw 0x1 movwf TXREG1 ;Send status request to pristavka bsf TX_CTRL,TX_3BIP ;Set 3 bytes in progress bit clrf TX_TMP_BUF btfss TX_FIFO_STAT,TX_FIFO_EMPTY ;Is Fifo empty? call RD_TX_FIFO ;No movlw 0x0 movwf T_CRC ;Init of CRC register movlw 6 ;6 quad bits for transmit movwf TX_CNTR ; movlw 0xb9 movlw 0x49 ; ; movlw 0x99 ; movwf T_BYTE0 swapf TX_TMP_BUF,W andlw 0xf0 ;Clear low nibble iorlw 0x8 ;Set bit of phone type movwf T_BYTE1 swapf TX_TMP_BUF,W andlw 0x0f ;Clear high nibble iorlw 0xc0 ;Set end bits movwf T_BYTE2 return S_R0 clrf T_BYTE2 ;Yes. Fill with 0 D-chn buffer clrf T_BYTE1 clrf T_BYTE0 clrf T_CRC return ;******************************************************************* TX_3B decfsz TX_CNTR,1 ;Decrement counter and check on last quad bit goto T_B0 ;No clrf T_BYTE2 ;Yes. Fill with 0 D-chn buffer clrf T_BYTE1 clrf T_BYTE0 bcf TX_CTRL,TX_3BIP ;Clear 3 bytes in progress bit return T_B0 decfsz TX_CNTR,W ;Last quad bit? return ;No T_B1 btfsc T_CRC,0 ;Is bit0 of CRC=0 bsf T_BYTE0,0 ;No. Set corresponding bit in transmit register btfsc T_CRC,1 ;Is bit1 of CRC=0 bsf T_BYTE0,1 ;No. Set corresponding bit in transmit register return ;******************************************************************* CHECK_HANG btfsc PORTE,HANG ;Hang up? goto H_U ;Yes H_U_0 btfss PHONE_STAT,HANG_STATE ;Is hang already Down? return ;Yes bcf PHONE_STAT,HANG_STATE ;No. Clear staus bit bsf LATC,ANS0 nop bcf LATC,ANS1 movlw 0x1 ;And send command to station movwf TX_TMP_BUF call WRITE_TO_TX_FIFO return H_U btfsc PHONE_STAT,HANG_STATE ;Is hang already Up? return ;Yes bsf PHONE_STAT,HANG_STATE ;No. Set staus bit movlw 0x2 ;And send command to station movwf TX_TMP_BUF call WRITE_TO_TX_FIFO return ;******************************************************************* SCAN_COM_SEQ btfss PHONE_STAT,COMMAND_SEQ return bcf PHONE_STAT,COMMAND_SEQ movf BYTE2_SEQ,W movwf BYTE1_SEQ call CMD_SEQ_MENU return ;******************************************************************* SCAN_LCD btfsc LCD_FIFO_STAT,FIFO_EMPTY ;Is Fifo empty? goto WAIT_KB_EN bcf LCD_FIFO_STAT,FIFO_FULL ;Yes movf LCD_FIFO_T,W addlw LCD_FIFO movwf FSR0L ;Store address for indirect addressing movf INDF0,W ;Store new char in fifo movwf LCD_BUF movlw 0x20 ;;Data or command addwf FSR0L ;Store address for indirect addressing btfsc INDF0,0 ;data or command? goto SCL_0 ;Command call WRITE_CHAR goto SCL_1 SCL_0 call WRITE_COMMAND SCL_1 incf LCD_FIFO_T,F movlw 0x1f andwf LCD_FIFO_T,F movf LCD_FIFO_H,W xorwf LCD_FIFO_T,W ;Is tail = head? btfsC STATUS,Z bsf LCD_FIFO_STAT,FIFO_EMPTY ;fifo is empty return WAIT_KB_EN btfsc TX_CTRL,KB_SCAN_EN return incf KB_DELAY,F movlw 0x10 cpfslt KB_DELAY bsf TX_CTRL,KB_SCAN_EN return ;******************************************************************* CURSOR_CNTRL btfss PHONE_STAT,RESET_DONE goto CME btfss R_CBYTE1,7 ;Cursor - on goto C_C0 movlw 0xe goto SCP2 C_C0 btfss R_CBYTE1,6 ;Cursor - on, blink goto C_C1 movlw 0xf goto SCP2 C_C1 movf R_CBYTE1,F ;Cursor - off btfss STATUS,Z goto CME movlw 0xc movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND goto SCP2 ;******************************************************************* SET_CURSOR_POS btfss PHONE_STAT,RESET_DONE goto CME movlw 0x14 ;20 characters in line subwf R_CBYTE2,W ;Is it first line? btfsc STATUS,C goto SCP0_0 movf R_CBYTE2,W goto SCP1 ;No. SCP0_0 movlw 0x28 ;20 characters in line subwf R_CBYTE2,W ;Is it second line? btfsc STATUS,C goto SCP0_1 movlw 0x14 ;Yes. Add 0xc0 to address subwf R_CBYTE2,W goto SCP0 SCP0_1 ; goto SCP0 movlw 0x3C ;20 characters in line subwf R_CBYTE2,W ;Is it third line? btfsc STATUS,C ;Yes. Add 0xc0 to address goto SCP0_2 movlw 0x14 ;Yes. Add 0xc0 to address subwf R_CBYTE2,W goto SCP1 SCP0_2 movlw 0x50 ;20 characters in line subwf R_CBYTE2,W ;Is it overflow? btfsc STATUS,C goto CME ;Yes. no shift movlw 0x28 ;Yes. Add 0xc0 to address subwf R_CBYTE2,W goto SCP0 SCP0 iorlw 0x40 SCP1 iorlw 0x80 movwf LCD_BUF bsf LCD_BUF_A,DATA_COMMAND SCP2 call WRITE_TO_FIFO goto CME ;******************************************************************* WRITE_COMMAND clrf TRISD bcf LATE,LCD_RS ;Set command phase movf LCD_BUF,W movwf PORTD nop nop ; movlw 0x48 bsf LATA,LCD_E nop nop nop nop nop bcf LATA,LCD_E nop movlw 0xff movwf TRISD return ;******************************************************************* RD_KBD movlw 0xff movwf TRISD bcf LATB,RD_KEY nop nop nop nop nop movf PORTD,W xorlw 0xff ;Invert data bsf LATB,RD_KEY return ;******************************************************************* SCAN_KBD btfss TX_CTRL,KB_SCAN_EN goto SC_KE0 movlw 0x0f ;4 ms count andwf MKS_CNTR,F btfss STATUS,Z goto SC_K00 call CHECK_HANG ;Check hang state bcf LATA,1 nop bcf LATA,2 btfsc KEY_ADDRESS,0 bsf LATA,2 btfsc KEY_ADDRESS,1 bsf LATA,1 movf KEY_ADDRESS,F ;Is address=0? btfss STATUS,Z goto SC_K000 ;No btfss PORTB,MON_MIC goto SC_MIC0 btfsc TX_CTRL,MIC_ST goto SC_KE bsf TX_CTRL,MIC_ST movlw 0xe7 movwf TX_TMP_BUF call WRITE_TO_TX_FIFO ; bcf DATA_SP,MUTE ;Enable speakerphone mic ; call WR_SP goto SC_KE SC_MIC0 btfss TX_CTRL,MIC_ST goto SC_KE bcf TX_CTRL,MIC_ST movlw 0x67 movwf TX_TMP_BUF call WRITE_TO_TX_FIFO ; bsf DATA_SP,MUTE ;Disable speakerphone mic ; call WR_SP goto SC_KE SC_K000 movlw 0x01 ;Is address=1? cpfseq KEY_ADDRESS goto SC_KE btfss PORTB,MON_MIC goto SC_MON0 btfsc TX_CTRL,MON_ST goto SC_KE bsf TX_CTRL,MON_ST movlw 0xeb movwf TX_TMP_BUF call WRITE_TO_TX_FIFO goto SC_KE SC_MON0 btfss TX_CTRL,MON_ST goto SC_KE bcf TX_CTRL,MON_ST movlw 0x6b movwf TX_TMP_BUF call WRITE_TO_TX_FIFO goto SC_KE SC_K00 movlw 0x01 ;Scan LCD xorwf MKS_CNTR,W btfss STATUS,Z goto SC_K01 ; call SCAN_LCD goto SC_KE SC_K01 movlw 0x02 ;Scan LED xorwf MKS_CNTR,W btfss STATUS,Z goto SC_K0 call WR_LED goto SC_KE SC_K0 movlw 0x04 ;1-st sample xorwf MKS_CNTR,W btfss STATUS,Z goto SC_K1 call RD_KBD movwf KEY_SMP0 goto SC_KE SC_K1 movlw 0x08 ;2-st sample xorwf MKS_CNTR,W btfss STATUS,Z goto SC_K2 call RD_KBD movwf KEY_SMP1 goto SC_KE SC_K2 movlw 0x0c ;3-st sample xorwf MKS_CNTR,W btfss STATUS,Z goto SC_KE call RD_KBD andwf KEY_SMP1,W movwf KEY_BYTE andwf KEY_SMP0,W iorwf KEY_BYTE,F movf KEY_SMP1,W andwf KEY_SMP0,W iorwf KEY_BYTE,F ; movlw 0x07 ; andwf KEY_BYTE,F bcf TX_CTRL,RELEASE_FLAG ;Clear release flag movlw KEY_ARRAY ;Get key array start address addwf KEY_ADDRESS,W ;Calculate line address movwf FSR0L ;Store address for indirect addressing movf INDF0,W ;Get last state of key line xorwf KEY_BYTE,W movwf KEY_BYTE btfsc STATUS,Z ;Is anything change? goto SC_K3 ;No xorwf INDF0,F ;Write changes to key array andwf INDF0,W ;Test new state of key. btfsc STATUS,Z ;Is key released? bsf TX_CTRL,RELEASE_FLAG ;Yes. Set release flag ; movlw 0x07 ; andwf INDF0,F ;Mask bits clrf BIT_CNTR SC_K2_0 rrcf KEY_BYTE,F btfsc STATUS,C goto DET_KEY_CODE incf BIT_CNTR,F ;Next key btfss BIT_CNTR,3 ;Is it last key? goto SC_K2_0 goto SC_K3 ;No key DET_KEY_CODE movlw 0x13 movwf PCLATH rlncf BIT_CNTR,F swapf KEY_ADDRESS,W ;Set line number andlw 0x30 ;Max 32 keys iorwf BIT_CNTR,W ; call KEY_CODE_SH ; addwf BIT_CNTR,W btfsc TX_CTRL,RELEASE_FLAG iorlw 0x80 movwf TX_TMP_BUF ; goto CHECK_HANG_KEY SC_K2_1 call WRITE_TO_TX_FIFO ; call TOGGLE_TMP SC_K3 incf KEY_ADDRESS,F movlw 0x03 andwf KEY_ADDRESS,F SC_KE incf MKS_CNTR,F return SC_KE0 clrf MKS_CNTR clrf KEY_ADDRESS return CHECK_HANG_KEY movlw 0x7e andwf TX_TMP_BUF,W ;Is it hang keys (0,1) btfss STATUS,Z goto SC_K2_1 ;No btfsc TX_CTRL,RELEASE_FLAG ;Is hang keys released? goto SC_K3 ;Yes, return movlw 0x00 cpfseq TX_TMP_BUF goto CHK0 call H_U goto SC_K3 CHK0 call H_U_0 goto SC_K3 ;******************************************************************* RCV_DCHANNEL rlcf DCH_BUF,1 ;Get firs bit of D-channel rrcf R_BYTE3,1 ;Save it rrcf R_BYTE2,1 rrcf R_BYTE1,1 rrcf R_BYTE0,1 rlcf DCH_BUF,1 ;Get second bit of D-channel rrcf R_BYTE3,1 ;Save it rrcf R_BYTE2,1 rrcf R_BYTE1,1 rrcf R_BYTE0,1 return ;******************************************************************* SET_AMI bsf LATB,AMIEN return ;******************************************************************* RESET_AMI bcf LATB,AMIEN return ;******************************************************************* SYNC_AMI ; btfss TX_CTRL,SYNC_ST ;Is sync Ok? ; return ;Yes. clrwdt bcf SSP1CON1,SSPEN ;SPI - disable SA0 btfsc PORTB,SYNC_S ;Check sync bit goto SA0 movlw 0xf0 ;250 uS - ffff-5dc=fa23 480=-fb7f - 4.608 movwf TMR1H ; 9c4=-f63b - 10 movlw 0x80 ; 5dc=-fa23 - 6 movwf TMR1L ; 7d0=-f82f - 8 ; bb8=-f447 - 12 ; fa0=-f060 - 16 bcf PIR1,TMR1IF ;Clear timer 1 overflow flag bsf T1CON,TMR1ON ;Enable timer1 SA1 btfss PORTB,SYNC_S ;Check sync bit goto SA1 SA2 btfsc PORTB,SYNC_S ;Check sync bit goto SA2 bcf T1CON,TMR1ON ;Stop timer1 btfss PIR1,TMR1IF ;Is time > 250 uS goto SYNC_AMI ;No wait SA3 btfss PORTB,SYNC_S ;Check sync bit goto SA3 bsf SSP1CON1,SSPEN ;SPI - enable bcf PIR1,SSP1IF ;Clear SPI interrupt flag bcf TX_CTRL,SYNC_ST ;Sync Ok, ; goto SYNC_AMI return ;******************************************************************* ST_DELAY clrf CNTRL clrf CNTRH DELAY decfsz CNTRL,1 goto DELAY clrwdt decfsz CNTRH,1 goto DELAY return ;******************************************************************* DELAY_TM clrwdt btfss PIR1,TMR1IF ;Is time > 250 uS goto DELAY_TM return ;******************************************************************* DELAY_250 movlw 0xf0 ;250 uS - ffff-bb8=f447 12mhZ movwf TMR1H ; ffff-fa0=f060 16mhZ movlw 0x60 ; movwf TMR1L bcf PIR1,TMR1IF ;Clear timer 1 overflow flag bsf T1CON,TMR1ON call DELAY_TM bcf T1CON,TMR1ON return ;******************************************************************* DELAY_2MS movlw 0x83 ;2 mS - ffff-7d00=8300 movwf TMR1H ; movlw 0x00 ; movwf TMR1L bcf PIR1,TMR1IF ;Clear timer 1 overflow flag bsf T1CON,TMR1ON call DELAY_TM bcf T1CON,TMR1ON return ;******************************************************************* LCD_RESET movlw 100 movwf LCD_RST_W LCD_W call ST_DELAY decfsz LCD_RST_W,1 goto LCD_W bcf LATE,LCD_RS ;Set command phase movlw 0x3c ;Set LCD to 8 bits,2 lines,5*8 dots movwf LCD_BUF call WRITE_COMMAND call DELAY_250 movlw 0x3c ;Set LCD to 8 bits,2 lines,5*8 dots movwf LCD_BUF call WRITE_COMMAND call DELAY_250 movlw 0x0e ;Display on, cursor on, no blink movwf LCD_BUF call WRITE_COMMAND call DELAY_250 movlw 0x2 ;Set address 0 movwf LCD_BUF call WRITE_COMMAND call DELAY_2MS call DELAY_2MS movlw 0x01 ;Clear display movwf LCD_BUF call WRITE_COMMAND call DELAY_2MS call DELAY_2MS ; call ST_DELAY ; movlw 0x07 ;Icrement, display shift ; movwf LCD_BUF ; call WRITE_COMMAND ; call ST_DELAY ; movlw 0x0e ;Display on, cursor on, no blink ; movwf LCD_BUF ; bsf LCD_BUF_A,DATA_COMMAND ; call WRITE_TO_FIFO ; bsf LATE,LCD_RS ;Set data phase clrf LCD_BUF_A movlw 0x20 ;Write '0' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x20 ;Write ' ' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x20 ;Write ' ' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x20 ;Write ' ' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x20 ;Write ' ' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x41 ;Write 'A' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x6c ;Write 'l' movwf LCD_BUF call WRITE_TO_FIFO clrwdt ;Clear watch dog timer movlw 0x62 ;Write 'b' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x61 ;Write 'a' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x5f ;Write '_' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x50 ;Write 'P' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x68 ;Write 'h' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x6f ;Write 'o' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x6e ;Write 'n' movwf LCD_BUF call WRITE_TO_FIFO movlw 0x65 ;Write 'e' movwf LCD_BUF call WRITE_TO_FIFO clrwdt ;Clear watch dog timer return ;******************************************************************* INIT_LED_TAB clrf 0x60 clrf 0x61 clrf 0x62 clrf 0x63 clrf 0x64 clrf 0x65 clrf 0x66 clrf 0x67 clrf 0x68 clrf 0x69 clrf 0x6a clrf 0x6b clrf 0x6c clrf 0x6d clrf 0x6e clrf 0x6f return ;******************************************************************* INIT_LED_CNTR movlw ON_OFF_CNTR addwf LED_NUM,W movwf FSR0L clrf INDF0 incf INDF0,F movlw BLINK_CNTR addwf LED_NUM,W movwf FSR0L clrf INDF0 decf INDF0,F return ;******************************************************************* WR_DAC movlw 0x10 movwf DAC_CNTR bcf LATE,DCS DW_0 bcf LATA,DSD btfsc DAC_DATAH,7 bsf LATA,DSD nop bsf LATA,DSCK nop bcf LATA,DSCK rlcf DAC_DATAL,F rlcf DAC_DATAH,F decfsz DAC_CNTR,F goto DW_0 bsf LATE,DCS return ;******************************************************************* SP_CFG movlw 0x00 movwf DATA_SP0 movlw 0xa4 movwf DATA_SP1 call WR_SP call DELAY_250 movlw 0x02 movwf DATA_SP0 movlw 0x2a movwf DATA_SP1 call WR_SP call DELAY_250 movlw 0x04 movwf DATA_SP0 movlw 0x00 movwf DATA_SP1 call WR_SP call DELAY_250 movlw 0x06 movwf DATA_SP0 movlw 0x00 movwf DATA_SP1 call WR_SP call DELAY_250 movlw 0x08 movwf DATA_SP0 movlw 0x00 movwf DATA_SP1 call WR_SP call DELAY_250 movlw 0x0a movwf DATA_SP0 movlw 0x00 movwf DATA_SP1 call WR_SP return ;******************************************************************* WR_SP bcf LATA,DSCK bcf LATC,DR_SP movlw 0x10 movwf DAC_CNTR SW_0 bcf LATA,DSD btfsc DATA_SP1,7 bsf LATA,DSD nop bsf LATA,DSCK nop nop bcf LATA,DSCK rlcf DATA_SP0,F rlcf DATA_SP1,F decfsz DAC_CNTR,F goto SW_0 bsf LATC,DR_SP movlw 0x4 movwf DAC_CNTR SW_1 bsf LATA,DSCK nop nop bcf LATA,DSCK decfsz DAC_CNTR,F goto SW_1 return ;******************************************************************* SP_RST bsf LATA,SP_RST_B movlw 0x10 movwf CNTRL SP_R_0 decfsz CNTRL,F goto SP_R_0 bcf LATA,SP_RST_B movlw 0x10 movwf CNTRL SP_R_1 decfsz CNTRL,F goto SP_R_1 bsf LATA,SP_RST_B return ;******************************************************************* DISPL_PRI_CHAR movf RX_PRI_DATA,W movwf LCD_BUF clrf LCD_BUF_A call WRITE_TO_FIFO return ;******************************************************************* RECEIVE_PRI btfss PIR1,RC1IF ;Is new byte from pristavka ready? return ;No bcf PIR1,RC1IF movf RCREG1,W ; movlw 0x2e movwf TX_TMP_BUF call WRITE_TO_TX_FIFO return ;******************************************************************* org 0x1300 KEY_CODE_SH addwf PCL,F retlw 0x10 ;1 retlw 0x11 ;2 retlw 0x12 ;3 retlw 0x6d ;page up retlw 0x20 ;flex1 retlw 0x24 ;flex5 retlw 0x28 ;flex9 retlw 0x2c ;flex13 retlw 0x13 ;4 retlw 0x14 ;5 retlw 0x15 ;6 retlw 0x1e ;page down retlw 0x20 ;flex1 0x21 flex2 retlw 0x23 ;flex4 0x25 flex6 retlw 0x21 ;flex2 0x29 flex10 retlw 0x24 ;flex5 0x2d flex14 retlw 0x16 ;7 retlw 0x17 ;8 retlw 0x18 ;9 retlw 0x01 ;V retlw 0x25 ;flex6 0x22 flex3 retlw 0x22 ;flex3 0x26 flex7 retlw 0x2a ;flex11 retlw 0x6b ;0x60 ;v- retlw 0x1a ;* retlw 0x19 ;0 retlw 0x1b ;# retlw 0x00 ;X retlw 0x23 ;flex4 retlw 0x27 ;flex8 retlw 0x2b ;flex12 retlw 0x61 ;v+ ;******************************************************************* org 0x1100 LED_NUM_LUT addwf PCL,F retlw 0x00 ;0 retlw 0x02 ;1 retlw 0x05 ;2 retlw 0x01 ;3 retlw 0x03 ;4 retlw 0x04 ;5 retlw 0x06 ;6 retlw 0x21 ;7 -> 21 retlw 0x08 ;8 retlw 0x09 ;9 retlw 0x0a ;10 retlw 0x0b ;11 retlw 0x0c ;12 retlw 0x03 ;13 retlw 0x0e ;14 retlw 0x0f ;15 retlw 0x10 ;16 retlw 0x11 ;17 retlw 0x12 ;18 retlw 0x13 ;19 retlw 0x14 ;20 retlw 0x15 ;21 retlw 0x16 ;22 retlw 0x17 ;23 retlw 0x18 ;24 retlw 0x19 ;25 retlw 0x1a ;26 retlw 0x1b ;27 retlw 0x0e ;28 -> 14 retlw 0x1d ;29 retlw 0x1e ;30 retlw 0x07 ;31 ->7 retlw 0x20 ;32 retlw 0x0f ;33 -> 15 retlw 0x22 ;34 retlw 0x23 ;35 retlw 0x24 ;36 retlw 0x25 ;37 retlw 0x26 ;38 retlw 0x27 ;39 retlw 0x28 ;40 retlw 0x29 ;41 retlw 0x2a ;42 retlw 0x2b ;43 retlw 0x2c ;44 retlw 0x2d ;45 retlw 0x2e ;46 retlw 0x2f ;47 ;******************************************************************* org 0x1200 MONTH_LUT addwf PCL,F retlw 'J' retlw 'A' retlw 'N' retlw 'F' retlw 'E' retlw 'B' retlw 'M' retlw 'A' retlw 'R' retlw 'A' retlw 'P' retlw 'R' retlw 'M' retlw 'A' retlw 'Y' retlw 'J' retlw 'U' retlw 'N' retlw 'J' retlw 'U' retlw 'L' retlw 'A' retlw 'U' retlw 'G' retlw 'S' retlw 'E' retlw 'P' retlw 'O' retlw 'C' retlw 'T' retlw 'N' retlw 'O' retlw 'V' retlw 'D' retlw 'E' retlw 'C' ;******************************************************************* end