Hello Helge, Helge Kruse <helge.kr...@gmx.net> writes:
> Am 04.09.2021 um 14:38 schrieb Erich Wälde: > >> Using the serial interface for a rs485 connection ... now, that >> I can understand :-) I have a collection of controllers "online", >> descriptions start here (German text): >> Vierte Dimension 2011/1 >> https://forth-ev.de/wiki/res/lib/exe/fetch.php/vd-archiv:4d2011-01.pdf >> Judging from your name German text should not be a problem for you. > Thanks for that hint. It's a very interesting article. I will experiment > with it. Yep, German is no problem for me. >> I'm very interested to hear, how you get along. Feel free to ask >> about technical details. > > I read about the MPC and find it very interesting. Unfortunately I won't > be able to use it, since the bus also uses broadcast addresses (126,127) > and the MPC is specific to one address (intentionally). Hmmm, you sure??? If I look at my code ... usart-isr-rx.asm ... see below. When "silent", the usart is set to 7N2. With mpc mode enabled incoming data isr will call into usart_rx_isr WHENEVER the highest bit of the address is set. The other 7 bits are passed in register UDRn --- oh, oh, my reading avr assembly brain isn't really awake ... --- and then the incoming Byte is compared to ram_station_id. If it matches switch usart to 8N1, if not, ignore. Noone stops you from comparing to several such IDs, I think. http://amforth.sourceforge.net/Projects/RS485/RS485Bus.html has this as Forth code. In section 6 (handling an incoming byte according to MPC-mode) you can better see the line, where the decision is made: | : mpc-rx-isr | rx-err? 0= if | UDR0 c@ \ -- udata | mpc? if | stationID = if \ <== add more stationID tests here ... | -mpc7 | then | else | rx-store | then | then | ; Unless I have misunderstood your text ... Cheers, Erich --- usart-isr-rx.asm ------------------------------------------- ;;; AmForth Version 4.5 ;;; usart driver, receiving .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 .dseg usart_rx_in: .byte 1 usart_rx_out: .byte 1 usart_rx_data: .byte usart_rx_size .cseg .if WANT_MPC == 0 ; --- original version --- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; usart_rx_isr: push xl in xl, SREG push xl push xh push zl push zh lds xh, USART_DATA ; optional: check for certain character(s) (e.g. CTRL-C) ; and trigger a soft interrupt instead of storing the ; charater into the input queue. 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<<FE) | (1<<DOR) | (1<<PE) ; set zero flag lds xh, USART_DATA ; xh = UDRn brne usart_rx_isr_finish ; test Z flag, --> _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(ram_station_id) ; . Z = &ram_station_id ldi zh, high(ram_station_id) ; . . ld xl, Z ; . xl = ram_station_id cp xl, xh ; . xl == xh? brne usart_rx_isr_finish ; . if ( ram_station_id == UDRn ) andi temp0, (~(1<<MPCM)) ; . { we are called! out_ UCSRA, temp0 ; . . UCSRA = temp0; clear MPCM ldi temp0, (USART_C_VALUE) ; . . temp0 = USARC_C_VALUE out_ UCSRC, temp0 ; . . UCSRC = temp0; 8N1 mode usart_rx_isr_finish: ; } _finish pop temp0 ; restore registers pop zh pop zl pop xh pop xl out SREG, xl pop xl reti .endif ; ( -- ) Hardware Access ; R( --) ; initialize usart ;VE_USART_INIT_RX: ; .dw $ff06 ; .db "+usart" ; .dw VE_HEAD ; .set VE_HEAD = VE_USART_INIT_RX XT_USART_INIT_RX_ISR: .dw DO_COLON PFA_USART_INIT_RX_ISR: ; ( -- ) .dw XT_ZERO .dw XT_DOLITERAL .dw usart_rx_in .dw XT_STORE .dw XT_EXIT ---------------------------------------------------------------- -- May the Forth be with you ... _______________________________________________ Amforth-devel mailing list for http://amforth.sf.net/ Amforth-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/amforth-devel