-
Notifications
You must be signed in to change notification settings - Fork 0
/
BasicSerial3INT.S
executable file
·91 lines (79 loc) · 2.35 KB
/
BasicSerial3INT.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* half-duplex 81N serial uart in hand-tuned assembler
* 1%/2% Tx/Rx timing error for 115.2kbps@8Mhz
* 2%/1% Tx/Rx timing error for 230.4kbps@8Mhz
* optimized for no jitter vs AVR305 with 1 cycle/bit jitter
* @author: Ralph Doncaster
* @version: $Id$
*/
#define delayCount r18
#include <avr/io.h>
; correct for avr/io.h 0x20 port offset for io instructions
#define UART_Port (PORTB-0x20)
#define UART_Tx 1
#define UART_Rx 1
; Supports using only one pin on the AVR for both Tx and Rx
; D1
; AVR ----+--|>|-----+----- Tx
; | 10K $ R1
; +--------(/^\)--- Rx
; NPN E C
.global TxTimedByte
; transmit byte in r24 with bit delay in r22 - 15 instructions
; calling code must set Tx line to idle state (high) or 1st byte may be lost
; i.e. PORTB |= (1<<UART_Tx)
TxTimedByte:
cli
sbi UART_Port-1, UART_Tx ; set Tx line to output
cbi UART_Port, UART_Tx ; start bit
in r0, UART_Port
ldi r25, 3 ; stop bit + idle state
TxLoop:
; 8 cycle loop + delay - total = 7 + 3*r22
mov delayCount, r22
TxDelay:
; delay (3 cycle * delayCount) -1
dec delayCount
brne TxDelay
bst r24, 0 ; store lsb in T
bld r0, UART_Tx
lsr r25
ror r24
out UART_Port, r0
brne TxLoop
; Rx(=Tx)ラインを入力に
cbi UART_Port-1, UART_Rx
; 割り込みフラグをリセット
; GIFR |= _BV(INTF0);
in r24, 0x3a ; GFIR
ori r24, 0x40 ; |= 0b01000000 INTF0
out 0x3a, r24
ret
// reti ; return and enable interrupts
.global RxTimedByte
; receive byte into r24 with bit delay in r22 & R24 - 16 instructions
RxTimedByte:
cbi UART_Port-1, UART_Rx ; set Rx line to input
#ifdef RX_PULLUP
sbi UART_Port, UART_Rx ; enable pullup
#endif
mov delayCount, r24 ; 1.5 bit delay
ldi r24, 0x80 ; bit shift counter
WaitStart:
sbic UART_Port-2, UART_Rx ; wait for start edge
rjmp WaitStart
cli
RxBit:
; 6 cycle loop + delay - total = 5 + 3*r22
; delay (3 cycle * delayCount) -1 and clear carry with subi
subi delayCount, 1
brne RxBit
mov delayCount, r22
sbic UART_Port-2, UART_Rx ; check UART PIN
sec
ror r24
brcc RxBit
StopBit:
dec delayCount
brne StopBit
ret
// reti ; return and enable interrupts