-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathAVR305.S
61 lines (56 loc) · 1.49 KB
/
AVR305.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
/* AVR305 half-duplex serial uart implementation in 28 instructions
* hard-coded for 81N, 115.2kbps @8Mhz = 69.4 cycles/bit
* @16Mhz = 139 cycles/bit
* @author: Ralph Doncaster
* @version: $Id$
*/
#define bitcnt r19
#define delayArg r24
; transmit byte contained in rSOURCE - 12 instructions
TxByte:
sbi UART_DDR, UART_Tx ; set Tx line to output
ldi bitcnt, 10 ; 1 start + 8 bit + 1 stop
com rSOURCE ; invert and set carry
TxLoop:
; 9 cycle loop
brcc tx1
cbi UART_Port, UART_Tx ; transmit a 0
tx1:
brcs TxDone
sbi UART_Port, UART_Tx ; transmit a 1
TxDone:
ldi delayArg, 18 ; 3 * 18 - 1 = 53 cycles
; ldi delayArg, 41 for 16Mhz
rcall Delay3Cycle
lsr rSOURCE
dec bitcnt
brne TxLoop
; fall into delay for stop bit = 1 = idle state
; delay (3 cycle * delayArg) -1 + 4 cycles (ret instruction)
; also clears carry (subi instead of dec) to save 1 instr in RxBit
Delay3Cycle:
subi delayArg, 1
brne delay3Cycle
ret
; receive byte into rDEST - 11 instructions
RxByte:
ldi rDEST, 0x80 ; bit shift counter
WaitStart:
sbic UART_Port-2, UART_Rx ; wait for start edge
rjmp WaitStart
ldi delayArg, 32 ; 1.5 bit delay
;ldi delayArg, 67 for 16Mhz
RxBit:
rcall Delay3Cycle ; delay and clear carry
; 6 cycle loop
; adiw delayArg, 19 clears carry
ldi delayArg, 19 ; 3 * 19 - 1 = 56 cycles
;ldi delayArg, 40 for 16Mhz
sbic UART_Port-2, UART_Rx
sec
ror rDEST
brcc RxBit
; fall into UartInit
UartInit:
sbi UART_Port, UART_Tx ; set Tx line to idle state (high)
ret