/Articles/Forth/HTML/CodeAsm/usart.html
0,0 → 1,379
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title> words/usart.asm </title>
<meta name="keywords" content="amforth programming language Forth ATmega ATMEL">
<meta name="description" content="amforth - laguage Forth for ATMEL ATmega">
<!-- AUTOINCLUDE START "Page/Head.en.ihtml" DO NOT REMOVE -->
<link rel="StyleSheet" href="../../../../Web/CSS/MLAB.css" type="text/css" title="MLAB Basic Style">
<link rel="StyleSheet" href="../../../../Web/CSS/MLAB_Print.css" type="text/css" media="print">
<link rel="shortcut icon" type="image/x-icon" href="../../../../Web/PIC/MLAB.ico">
<script type="text/javascript" src="../../../../Web/JS/MLAB_Menu.js"></script>
<!-- AUTOINCLUDE END -->
</head>
 
<body lang="en">
 
<!-- AUTOINCLUDE START "Page/Header.en.ihtml" DO NOT REMOVE -->
<!-- ============== HEADER ============== -->
<div class="Header">
<script type="text/javascript">
<!--
SetRelativePath("../../../../");
DrawHeader();
// -->
</script>
<noscript>
<p><b> JavaScript is required for including of the header </b></p>
</noscript>
</div>
<!-- AUTOINCLUDE END -->
 
<!-- AUTOINCLUDE START "Page/Menu.en.ihtml" DO NOT REMOVE -->
<!-- ============== MENU ============== -->
<div class="Menu">
<script type="text/javascript">
<!--
SetRelativePath("../../../../");
DrawMenu();
// -->
</script>
<noscript>
<p><b> JavaScript is required for including of the menu </b><p>
</noscript>
</div>
<!-- AUTOINCLUDE END -->
 
<!-- ============== TEXT ============== -->
<div class="Text">
 
<h1> words/usart.asm </h1>
 
<p>
<input type=button onClick="history.back()" value="Back">
<input type=button onClick="history.forward()" value="Forward">
<a href="../WordList.en.html">Jump to Vocabulary</a>
</p>
 
<pre>
;;; usart driver
 
;; bit definitions
 
 
.set pc_ = pc
 
.org URXCaddr
rjmp usart0_rx_isr
.org UDREaddr
rjmp usart0_udre_isr
.org pc_
 
; sizes have to be powers of 2!
.equ usart0_tx_size = $10
.equ usart0_rx_size = $10
 
.equ usart0_tx_mask = usart0_tx_size - 1
.equ usart0_rx_mask = usart0_rx_size - 1
 
.set usart0_tx_in = heap
.set heap = heap + 1
 
.set usart0_tx_out = heap
.set heap = heap + 1
 
.set usart0_tx_data = heap
.set heap = heap + usart0_tx_size
 
.set usart0_rx_in = heap
.set heap = heap + 1
 
.set usart0_rx_out = heap
.set heap = heap + 1
 
.set usart0_rx_data = heap
.set heap = heap + usart0_rx_size
 
; ( -- v) System Value
; R( -- )
; returns usart0 baudrate
VE_BAUD0:
.db 05,&quot;baud0&quot;
.dw VE_HEAD
.set VE_HEAD = VE_BAUD0
XT_BAUD0:
.dw PFA_DOVALUE
PFA_BAUD00: ; ( -- )
.dw 10
 
; ( -- ) Hardware Access
; R( --)
; initialize usart0
VE_USART0:
.db $06, &quot;usart0&quot;,0
.dw VE_HEAD
.set VE_HEAD = VE_USART0
XT_USART0:
.dw DO_COLON
PFA_USART0: ; ( -- )
.dw XT_ZERO
.dw XT_DOLITERAL
.dw usart0_tx_in
.dw XT_CSTORE
 
.dw XT_ZERO
.dw XT_DOLITERAL
.dw usart0_tx_out
.dw XT_CSTORE
 
.dw XT_ZERO
.dw XT_DOLITERAL
.dw usart0_rx_in
.dw XT_CSTORE
 
.dw XT_ZERO
.dw XT_DOLITERAL
.dw usart0_rx_out
.dw XT_CSTORE
 
.dw XT_F_CPU
.dw XT_D2SLASH
.dw XT_D2SLASH
.dw XT_D2SLASH
.dw XT_D2SLASH
.dw XT_ROT
.dw XT_UMSLASHMOD
.dw XT_SWAP
.dw XT_DROP
.dw XT_1MINUS
 
.dw XT_DUP
.dw XT_DOLITERAL
.dw BAUDRATE0_LOW
.dw XT_CSTORE
.dw XT_BYTESWAP
.dw XT_DOLITERAL
.dw BAUDRATE0_HIGH
.dw XT_CSTORE
.dw XT_DOLITERAL
.dw (1&lt;&lt;UMSEL01)|(3&lt;&lt;UCSZ00)
.dw XT_DOLITERAL
.dw USART0_C
.dw XT_CSTORE
.dw XT_DOLITERAL
.dw (1&lt;&lt;TXEN0) | (1&lt;&lt;RXEN0) | (1&lt;&lt;RXCIE0)
.dw XT_DOLITERAL
.dw USART0_B
.dw XT_CSTORE
.dw XT_EXIT
 
usart0_udre_isr:
push xl
in xl,SREG
push xl
push xh
push zl
push zh
 
lds xl,usart0_tx_in
lds xh,usart0_tx_out
 
cp xh,xl
brne usart0_udre_next
 
usart0_udre_last:
lds xl, USART0_B
cbr xl,(1&lt;&lt;UDRIE0)
sts USART0_B,xl
 
rjmp usart0_udre_done
 
usart0_udre_next:
inc xh
andi xh,usart0_tx_mask
sts usart0_tx_out,xh
 
ldi zl,low(usart0_tx_data)
ldi zh,high(usart0_tx_data)
add zl,xh
adc zh,zeroh
 
ld xl,z
out_ UDR0,xl
 
usart0_udre_done:
pop zh
pop zl
pop xh
pop xl
out SREG,xl
pop xl
reti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
usart0_rx_isr:
push xl
in xl, SREG
push xl
push xh
push zl
push zh
 
lds xl,usart0_rx_in
inc xl
andi xl,usart0_rx_mask
 
ldi zl, low(usart0_rx_data)
ldi zh, high(usart0_rx_data)
add zl, xl
adc zh, zeroh
in_ xh, UDR0
st Z, xh
sts usart0_rx_in, xl
 
pop zh
pop zl
pop xh
pop xl
out SREG, xl
pop xl
reti
 
; (c -- ) Hardware Access
; R( --)
; put 1 character into output queue, wait if needed, enable UDRIE0 interrupt
VE_TX0:
.db $03, &quot;tx0&quot;
.dw VE_HEAD
.set VE_HEAD = VE_TX0
XT_TX0:
.dw DO_COLON
PFA_TX0:
; wait for queue
.dw XT_TX0Q
.dw XT_DOCONDBRANCH
.dw PFA_TX0
; append to queue
.dw XT_DOLITERAL
.dw usart0_tx_in
.dw XT_CFETCH ; ( -- c tx_in)
.dw XT_1PLUS
.dw XT_DOLITERAL
.dw usart0_tx_mask
.dw XT_AND ; ( -- c tx_in_new)
.dw XT_DUP
.dw XT_DOLITERAL
.dw usart0_tx_in
.dw XT_CSTORE
.dw XT_DOLITERAL
.dw usart0_tx_data ; ( -- c tx_in_new data)
.dw XT_PLUS
.dw XT_CSTORE
; enable interrupt
.dw XT_DOLITERAL
.dw USART0_B
.dw XT_DUP ;
.dw XT_CFETCH
.dw XT_DOLITERAL
.dw 1&lt;&lt;UDRIE0
.dw XT_OR
.dw XT_SWAP
.dw XT_CSTORE
.dw XT_EXIT
 
; ( -- f) Hardware Access
; R( --)
; check if a character can be appended to output queue.
VE_TX0Q:
.db $04, &quot;tx0?&quot;,0
.dw VE_HEAD
.set VE_HEAD = VE_TX0Q
XT_TX0Q:
.dw DO_COLON
PFA_TX0Q:
.dw XT_PAUSE
.dw XT_DOLITERAL
.dw usart0_tx_out
.dw XT_CFETCH
.dw XT_DOLITERAL
.dw usart0_tx_in
.dw XT_CFETCH
.dw XT_EQUAL
.dw XT_EXIT
 
; ( -- c) Hardware Access
; R( --)
; get 1 character from input queue, wait if needed
VE_RX0:
.db $03, &quot;rx0&quot;
.dw VE_HEAD
.set VE_HEAD = VE_RX0
XT_RX0:
.dw DO_COLON
PFA_RX0:
.dw XT_RX0Q
.dw XT_DOCONDBRANCH
.dw PFA_RX0
.dw XT_DOLITERAL
.dw usart0_rx_out
.dw XT_CFETCH
.dw XT_1PLUS
.dw XT_DOLITERAL
.dw usart0_rx_mask
.dw XT_AND
.dw XT_DUP
.dw XT_DOLITERAL
.dw usart0_rx_out
.dw XT_CSTORE
.dw XT_DOLITERAL
.dw usart0_rx_data
.dw XT_PLUS
.dw XT_CFETCH
.dw XT_EXIT
 
; ( -- f) Hardware Access
; R( --)
; check if unread characters are in the input queue.
VE_RX0Q:
.db $04, &quot;rx0?&quot;,0
.dw VE_HEAD
.set VE_HEAD = VE_RX0Q
XT_RX0Q:
.dw DO_COLON
PFA_RX0Q:
.dw XT_PAUSE
.dw XT_DOLITERAL
.dw usart0_rx_out
.dw XT_CFETCH
.dw XT_DOLITERAL
.dw usart0_rx_in
.dw XT_CFETCH
.dw XT_NOTEQUAL
.dw XT_EXIT
</pre>
 
<p>
<input type=button onClick="history.back()" value="Back">
<input type=button onClick="history.forward()" value="Forward">
<a href="../WordList.en.html">Jump to Vocabulary</a>
</p>
 
</div>
 
<!-- AUTOINCLUDE START "Page/Footer.en.ihtml" DO NOT REMOVE -->
<!-- ============== FOOTER ============== -->
<div class="Footer">
<script type="text/javascript">
<!--
SetRelativePath("../../../../");
DrawFooter();
// -->
</script>
<noscript>
<p><b> JavaScript is required for including of the footer </b></p>
</noscript>
</div>
<!-- AUTOINCLUDE END -->
 
</body>
</html>