;***************************************************************************************** ; Communication Buffers ;***************************************************************************************** .DSEG .EQU UART_ISIZE = 64 .EQU UART_OSIZE = 32 .EQU UART_CSIZE = 40 uart_ibuf: .BYTE UART_ISIZE uart_iput: .byte 1 uart_iget: .byte 1 uart_obuf: .byte UART_OSIZE uart_oput: .byte 1 uart_oget: .byte 1 uart_cmd: .byte UART_CSIZE cmd_ptr: .byte 2 uart_handbox_btn: .byte 1 ;***************************************************************************************** ; Write String to terminal ; Z points to String in data memory ;***************************************************************************************** .CSEG puts_ram_func: push r16 puts_ram_loop: ld r16 ,Z tst r16 breq puts_ram_exit rcall putc_func adiw zh:zl ,1 rjmp puts_ram_loop puts_ram_exit: pop r16 ret .MACRO puts_ram ldi zl ,low(@0) ldi zh ,high(@0) call puts_ram_func .ENDMACRO ;***************************************************************************************** ; Write String to terminal ; Z points to String in program memory ;***************************************************************************************** puts_rom_func: push r0 push r16 puts_rom_loop: lpm tst r0 breq puts_rom_exit mov r16 ,r0 rcall putc_func adiw zh:zl ,1 rjmp puts_rom_loop puts_rom_exit: pop r16 pop r0 ret .MACRO puts_rom ldi zl ,low(@0<<1) ldi zh ,high(@0<<1) call puts_rom_func .ENDMACRO ;***************************************************************************************** ; UART Character Out ; ; R16 : Byte for output ;***************************************************************************************** putc_func: #ifndef SIMULATE sbis UCSR0A ,UDRE1 rjmp putc_func out UDR0 ,r16 #endif ret .MACRO PUTC ldi r16 ,@0 call putc_func .ENDMACRO ;***************************************************************************************** putc1_func: lds r0 ,UCSR1A sbrs r0 ,UDRE1 #ifndef SIMULATE rjmp putc1_func #endif sts UDR1 ,r16 ret .MACRO putc1 ldi r16 ,@0 call putc1_func .ENDMACRO ;***************************************************************************************** ; UART Getline ; 2005-05-10 no echo ; ;***************************************************************************************** gets: push r16 push r17 push r18 push xl push xh lds r17 ,monitor_inptr ;next char position clr r0 ;high byte for add ldi xl ,low(uart_cmd) ldi xh ,high(uart_cmd) add xl ,r17 adc xh ,r0 ;X = next char position gets_loop: rcall getc ;get one character brtc gets_exit ;no char, return with T flag not set cpi r16 ,'#' ;end of LX200 commands brne gets_no_lx200_end tst r17 brne gets_lx200_end gets_no_lx200_end: cpi r16 ,13 ;return brne gets_no_return ;T flag not set gets_lx200_end: clr r16 ;put zero byte at line end st X ,r16 inc r17 ;string length ++ rjmp gets_exit ;return with T flag set gets_no_return: cpi r16 ,8 ;backspace ? brne gets_no_backspace tst r17 ;no backspace at beginning of line breq gets_no_backspace dec r17 sbiw xh:xl ,1 rjmp gets_loop gets_no_backspace: cpi r17 ,UART_CSIZE-1 ;line buffer full ? breq gets_loop ;ignore character cpi r16 ,32 ;check if printable character brlo gets_loop ;< 32 not allowed tst r16 brmi gets_loop ;> 127 not allowed cpi r16 ,'a' ;make uppercase brlo gets_no_lowercase cpi r16 ,'z'+1 brge gets_no_lowercase subi r16 ,'a'-'A' gets_no_lowercase: st X ,r16 adiw xh:xl ,1 inc r17 rjmp gets_loop gets_exit: sts monitor_inptr ,r17 pop xh pop xl pop r18 pop r17 pop r16 ret ;***************************************************************************************** ; Check if UART Character in buffer ; ; R16 : character ; T-Flag : 0=no char ;***************************************************************************************** getc_check: push r16 push r17 push r18 clt ;default: return false in r18 ,SREG ;save status register cli ;no concurrent access to buffer lds r16 ,uart_iput ;check if buffer empty subi r16 ,1 ;if uart_iget is one step behind uart_iput andi r16 ,UART_ISIZE-1 lds r17 ,uart_iget cpse r16 ,r17 set ;if character in buffer: return true sbrc r18 ,7 ;restore interrupt enable flag sei pop r18 pop r17 pop r16 ret ;***************************************************************************************** ; UART Character In ; ; R16 : character ; T-Flag : 0=no char ;***************************************************************************************** getc: push r17 push r18 push xl push xh in r18 ,SREG ;save status register cli ;no concurrent access to buffer clt lds r16 ,uart_iput ;check if buffer empty subi r16 ,1 ;if uart_iget is one step behind uart_iput andi r16 ,UART_ISIZE-1 lds r17 ,uart_iget cp r16 ,r17 breq getc_buffer_empty inc r17 ;uart_iget ++ (pre increment) andi r17 ,UART_ISIZE-1 sts uart_iget ,r17 ldi xl ,low(uart_ibuf) ;get character uart_ibuf[uart_iget] ldi xh ,high(uart_ibuf) add xl ,r17 ldi r17 ,0 adc xh ,r17 ld r16 ,X ;return character in r16 set getc_buffer_empty: sbrc r18 ,7 ;restore interrupt enable flag bset 7 pop xh pop xl pop r18 pop r17 ret ;***************************************************************************************** ; UART Init ;***************************************************************************************** uart0_init: cbi DDRE ,0 ;RXD0 (Port E0) is input sbi DDRE ,1 ;TXD0 (Port E1) is output ldi r16 ,high(USART0_BAUDRATE) ldi r17 ,low(USART0_BAUDRATE) sts UBRR0H ,r16 out UBRR0L ,r17 ldi r16 ,0b00000000 ;no double speed, no multiprocessor mode out UCSR0A ,r16 ldi r16 ,0b10011000 ;receiver IRQ, transmitter, receiver enabled out UCSR0B ,r16 ldi r16 ,0b00000110 ;8 N 1 sts UCSR0C ,r16 ldi r16 ,1 ;input buffer pointer on first character sts uart_iput ,r16 sts uart_oput ,r16 ldi r16 ,0 sts uart_iget ,r16 sts uart_oget ,r16 ret uart1_init: cbi DDRD ,2 ;RXD1 (Port D2) is input sbi DDRD ,3 ;TXD1 (Port D3) is output ldi r16 ,high(USART1_BAUDRATE) ldi r17 ,low(USART1_BAUDRATE) sts UBRR1H ,r16 sts UBRR1L ,r17 ldi r16 ,0b00000000 ;no double speed, no multiprocessor mode sts UCSR1A ,r16 ldi r16 ,0b10011000 ;receiver IRQ, transmitter, receiver enabled sts UCSR1B ,r16 ldi r16 ,0b00000110 ;8 N 1 sts UCSR1C ,r16 ret ;***************************************************************************************** ; UART RX Complete Interrupt ;***************************************************************************************** usart0_rx: push r16 in r16 ,SREG push r16 push r17 push xl push xh lds r16 ,uart_iput ;check if buffer full lds r17 ,uart_iget ;when uart_iput == uart_iget cp r16 ,r17 breq uart_rx_buffer_full ldi xl ,low(uart_ibuf) ;store character as uart_ibuf [uart_iput] ldi xh ,high(uart_ibuf) add xl ,r16 ldi r17 ,0 adc xh ,r17 in r17 ,UDR0 st X ,r17 inc r16 ;uart_iput ++ (post increment) andi r16 ,UART_ISIZE-1 sts uart_iput ,r16 uart_rx_buffer_full: pop xh pop xl pop r17 pop r16 out SREG ,r16 pop r16 reti usart1_rx: push r16 in r16 ,SREG push r16 lds r16 ,UDR1 pop r16 out SREG ,r16 pop r16 reti ;*****************************************************************************************