sonde/uart.S
2016-04-29 11:30:56 +02:00

76 lines
2.1 KiB
ArmAsm

//UART Functions per AVR Application Note #305
#include <avr/io.h>
//#include "uLogTimer.h"
//
//half bit delay
//
//#define b 31 //38400 bps@8MHz with 0.3% error
#define b 66 //19200 bps@8MHz with 0.6% error
UARTDelay:
ldi r17, b
UARTDelay1:
dec r17
brne UARTDelay1
ret
//
//asynchronous 8n1 serial transmit byte
//
#define TX_PIN 6 //TX pin is PA6
.global SerialPutChar
SerialPutChar:
push r16
push r17
ldi r16, 10 ;1 start + 8 data + 1 stop bits (bit count)
com r24 ;Invert it (r24 = xmit byte)
sec ;Start bit
putchar0:
brcc putchar1 ;If carry set
cbi _SFR_IO_ADDR(PORTB), PB0 ;send a '0'
rjmp putchar2 ;else
putchar1:
sbi _SFR_IO_ADDR(PORTB), PB0 ;send a '1'
nop
putchar2:
rcall UARTDelay ;1/2 bit delay +
rcall UARTDelay ;1/2 bit delay = 1bit delay
lsr r24 ;Get next bit
dec r16 ;If not all bits sent
brne putchar0 ;send next
;else
pop r17
pop r16
ret ;return
//
//asynchronous 8n1 serial receive byte
//
#define RX_PIN 5 //RX pin is PA5
.global SerialGetChar
SerialGetChar:
push r16
push r17
ldi r16, 9 ;8 data bits + 1 stop bit
getchar1:
sbic _SFR_IO_ADDR(PINB), PB1 ;Wait for start bit
rjmp getchar1
rcall UARTDelay ;1.5bit delay after start bit edge
getchar2:
rcall UARTDelay ;1 bit delay from here
rcall UARTDelay
clc ;clear carry
sbic _SFR_IO_ADDR(PINB), PB1 ;if RX pin high
sec ;
dec r16 ;If bit is stop bit
breq getchar3 ; return
;else
ror r24 ; shift bit into r24 (rec'd byte)
rjmp getchar2 ; go get next
getchar3:
ldi r25, 0x00 ;zero extend r24:r25 for return
pop r17
pop r16
ret