;;; usart driver, receiving .if WANT_MPC == 1 ; ( -- addr ) variable mpc_ID, RS485 ; module address VE_MPCID: .dw $ff06 .db "mpc_ID" .dw VE_HEAD .set VE_HEAD = VE_MPCID XT_MPCID: .dw PFA_DOVARIABLE PFA_MPCID: .dw here .set var_mpcid = here .set here = here + CELLSIZE .endif .set pc_ = pc .org URXCaddr jmp_ usart_rx_isr .org pc_ ; sizes have to be powers of 2! .equ usart_rx_size = $10 .equ usart_rx_mask = usart_rx_size - 1 .set usart_rx_in = here .set here = here + 1 .set usart_rx_out = here .set here = here + 1 .set usart_rx_data = here .set here = here + usart_rx_size .if WANT_MPC == 0 ; --- original version --- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; todo: wenn XON/XOFF erkannt werden, nicht in den Input Buffer schreiben! usart_rx_isr: push xl in xl, SREG push xl push xh push zl push zh lds xh, USART_DATA lds xl,usart_rx_in ldi zl, low(usart_rx_data) ldi zh, high(usart_rx_data) add zl, xl adc zh, zeroh st Z, xh inc xl andi xl,usart_rx_mask sts usart_rx_in, xl usart_rx_isr_finish: pop zh pop zl pop xh pop xl out SREG, xl pop xl reti .else ; --- MPC version --- usart_rx_isr: push xl ; save registers in xl, SREG push xl push xh push zl push zh push temp0 in_ xh, UCSRA ; xh = UCSRnA mov temp0, xh ; temp0 = xh; save value andi xh, (1< _finish on error (zero flag=0) lds xl,usart_rx_in ; xl = i_in ldi zl, low(usart_rx_data) ; Z = &buf[0] ldi zh, high(usart_rx_data) ; add zl, xl ; Z += i_in adc zh, zeroh ; . sbrc temp0, MPCM ; if (UCSRnA[MPCM] == 0) rjmp usart_rx_isr_mpcmode ; { st Z, xh ; . buf[i_in] = xh (== UDRn); normal mode inc xl ; . xl += 1 andi xl,usart_rx_mask ; . xl %= siz (Ringbuffer) sts usart_rx_in, xl ; . i_in = xl rjmp usart_rx_isr_finish ; } else { usart_rx_isr_mpcmode: ; multi-processor-communication mode ldi zl, low(var_mpcid) ; . Z = &var_mpcid ldi zh, high(var_mpcid) ; . . ld xl, Z ; . xl = var_mpcid cp xl, xh ; . xl == xh? brne usart_rx_isr_finish ; . if ( var_mpcid == UDRn ) andi temp0, (~(1<