Web Browser Chat Between 2 PCs Over RS232 Serial Port
by sergei_iliev in Circuits > Microcontrollers
164 Views, 1 Favorites, 0 Comments
Web Browser Chat Between 2 PCs Over RS232 Serial Port
Simple chat messaging between 2 PC's using OLIMEX PX128A1 board running XMEGA acorn micro kernel. Two UART chennels are used to connect 2 PCs that run Chrome browser Chat UI as clients written in vuejs. In contrast to RS232Chat that is using Windows exe as UI client, here the client is rendered in Chrome Browser and Serial API is used to set up RS232 channel in both directions.
OLIMEX PX128A1 Board
OLIMEX PX128A1 board runs 4 tasks concurrently within Acorn micro kernel, observing the Producer - Consumer design pattern to facilitate asynchronous communication within the 2 UART channels and LCD control screen.
Chrome Web Page Client
Browser based UI client running on both PC's. Web Serial API and vuejs were used to develop it thus making the UI completely agnostic to the host OS.
Task #1 Consumer - UART Channel D
Incoming bytes from Rx1 Interrupt handler channel D(first PC) are fed into a circular queue-like buffer dedicated to channel D.
Same task dispatches bytes to channel E
usart_task_D:
//***init buffer channel D0
ldi ZL,low(usartD0_16)
ldi ZH,high(usartD0_16)
rcall spc_queue16_init
/* USARTD0, 8 Data bits, No Parity, 1 Stop bit. */
rcall usart_init_d_int
_THRESHOLD_BARRIER_WAIT InitTasksBarrier,TASKS_NUMBER
_INTERRUPT_DISPATCHER_INIT temp,RX1_INT_ID
main_usart_d:
/*RECEIVE from channel #1*/
_INTERRUPT_WAIT RX1_INT_ID
ldi ZL,low(usartD0_16)
ldi ZH,high(usartD0_16)
ldi axl,low(USARTD0_QUEUE_MAX_SIZE)
ldi axh,high(USARTD0_QUEUE_MAX_SIZE)
rcall spc_queue16_pop
_INTERRUPT_END RX1_INT_ID
;queue output is in `dxh:dxl`
brts wait_rx_int_d ;is empty queue?
rjmp main_usart_d
wait_rx_int_d:
/*SEND to channel #2*/
rcall usart_send_bytes_e
rjmp main_usart_d
Channel D Producer - UART Rx Interrupt Handler Dispatcher
USARTD0_Rx:
_PRE_INTERRUPT
push ZH
push ZL
push cxh
push cxl
push dxh
push dxl
push axh
push axl
push argument
push bxl
push bxh
push r0
push r1
push r2
push r3
;read USART data in 16bit buffer
lds dxl,USARTD0_DATA
ldi ZL,low(usartD0_16)
ldi ZH,high(usartD0_16)
ldi axl,low(USARTD0_QUEUE_MAX_SIZE)
ldi axh,high(USARTD0_QUEUE_MAX_SIZE)
rcall spc_queue16_push_from_isr
pop r3
pop r2
pop r1
pop r0
pop bxh
pop bxl
pop argument
pop axl
pop axh
pop dxl
pop dxh
pop cxl
pop cxh
pop ZL
pop ZH
_keDISPATCH_DPC RX1_INT_ID
Acorn micro-kernel synchronizes access to shared queue structures for both channels
Task #2 Consumer - UART Channel E
Incoming bytes from Rx2 Interrupt handler channel E(second PC) are fed into a circular queue-like buffer dedicated to channel E.
Same task dispatches bytes to channel D
usart_task_E:
ldi ZL,low(usartE0_16)
ldi ZH,high(usartE0_16)
rcall spc_queue16_init
/* USARTE0, 8 Data bits, No Parity, 1 Stop bit. */
rcall usart_init_e_int
_THRESHOLD_BARRIER_WAIT InitTasksBarrier,TASKS_NUMBER
_INTERRUPT_DISPATCHER_INIT temp,RX2_INT_ID
main_usart_e:
;pop from other channel
_INTERRUPT_WAIT RX2_INT_ID
ldi ZL,low(usartE0_16)
ldi ZH,high(usartE0_16)
ldi axl,low(USARTE0_QUEUE_MAX_SIZE)
ldi axh,high(USARTE0_QUEUE_MAX_SIZE)
rcall spc_queue16_pop
_INTERRUPT_END RX2_INT_ID
;queue output is in `dxh:dxl`
brts wait_rx_int_e ;is empty queue?
rjmp main_usart_e
wait_rx_int_e:
rcall usart_send_byte_d ;cross channel
rjmp main_usart_e
Channel E Producer - UART Rx Interrupt Handler Dispatcher
USARTE0_Rx:
_PRE_INTERRUPT
push ZH
push ZL
push cxh
push cxl
push dxh
push dxl
push axh
push axl
push argument
push bxl
push bxh
push r0
push r1
push r2
push r3
;read USART data in 16bit buffer
lds dxl,USARTE0_DATA
ldi ZL,low(usartE0_16)
ldi ZH,high(usartE0_16)
ldi axl,low(USARTE0_QUEUE_MAX_SIZE)
ldi axh,high(USARTE0_QUEUE_MAX_SIZE)
rcall spc_queue16_push_from_isr
pop r3
pop r2
pop r1
pop r0
pop bxh
pop bxl
pop argument
pop axl
pop axh
pop dxl
pop dxh
pop cxl
pop cxh
pop ZL
pop ZH
_keDISPATCH_DPC RX2_INT_ID
Acorn micro-kernel synchronizes access to shared queue structures for both channels