#include <avr/io.h>
#include "config.h"
#include "avr-asm-macros.S"
+#include "uart_defs.h"
#define XON_VALUE 0x11
#define XOFF_VALUE 0x13
+#if UART0_I
+
+#ifndef UART0_PARATY
+# warning "UART0: using default paraty: 'none'"
+# define UART0_PARATY UART_PARATY_NONE
+#endif
+
+#ifndef UART0_STOPBITS
+# warning "UART0: using default ammount of stop bits: '1'"
+# define UART0_STOPBITS UART_STOPBITS_1
+#endif
+
+#ifndef UART0_DATABITS
+# warning "UART0: using default ammount of data bits: '8'"
+# define UART0_DATABITS UART_DATABITS_8
+#endif
+
#ifdef UDR
# define OLD_UART
# ifdef UDR0
# define RXC0 RXC
# define TXB80 TXB8
# define RXB80 RXB8
+# define U2X0 U2X
+# define UDRIE0 UDRIE
+# define RXCIE0 RXCIE
+#endif
+
+#ifdef USART0_RX_vect
+# define RX_ISR USART0_RX_vect
+#endif
+
+#ifdef USART_RXC_vect
+# define RX_ISR USART_RXC_vect
+#endif
+
+#ifdef USART0_UDRE_vect
+# define TX_ISR USART0_UDRE_vect
+#endif
+
+#ifdef USART_UDRE_vect
+# define TX_ISR USART_UDRE_vect
#endif
#define CBB_SIZE 10
clr r25
ldi r22, lo8(uart0_ctx+UART0_CBB_RX_OFFSET)
ldi r23, hi8(uart0_ctx+UART0_CBB_RX_OFFSET)
- ldi r24, UART0_RXBUFFER_SIZE
ldi r20, lo8(uart0_rxbuffer)
ldi r21, hi8(uart0_rxbuffer)
rcall circularbytebuffer_init2
clr r25
ldi r22, lo8(uart0_ctx+UART0_CBB_TX_OFFSET)
ldi r23, hi8(uart0_ctx+UART0_CBB_TX_OFFSET)
- ldi r24, UART0_TXBUFFER_SIZE
ldi r20, lo8(uart0_txbuffer)
ldi r21, hi8(uart0_txbuffer)
rcall circularbytebuffer_init2
std Z+UART0_TXON_OFFSET, r24
std Z+UART0_RXON_OFFSET, r24
#endif
+#if UART0_HOOK
+ std Z+UART0_HOOK_OFFSET, r1
+ std Z+UART0_HOOK_OFFSET+1, r1
+ std Z+UART0_HOOKR_OFFSET, r1
+#endif
ldi r24, UBRRH_VALUE
STORE_IO UBRR0H, r24
ldi r24, UBRRL_VALUE
SET_BIT_IO UCSR0A, U2X0, r24
#else
CLEAR_BIT_IO UCSR0A, U2X0, r24
-/* UCSR0A */
#endif
ldi r24, (UART0_PARATY<<4)|(UART0_STOPBITS<<3)|((UART0_DATABITS&3)<<1)
STORE_IO UCSR0C, r24
* }
*/
-.global USART0_UDRE_vect
-USART0_UDRE_vect:
- push_range 21, 26
- push_range 30, 31
+.global TX_ISR
+TX_ISR:
+ push r1
+ push r21
+ push r22
in r21, _SFR_IO_ADDR(SREG)
+ CLEAR_BIT_IO UCSR0B, UDRIE0, r22
+ sei
+ push_range 23, 27
+ push_range 30, 31
+ clr r1
ldi r24, lo8(uart0_ctx+UART0_CBB_TX_OFFSET)
ldi r25, hi8(uart0_ctx+UART0_CBB_TX_OFFSET)
rcall circularbytebuffer_get_fifo
breq 30b
#endif
STORE_IO UDR0, r24
+ SET_BIT_IO UCSR0B, UDRIE0, r22
99:
+ ori r21, 0x80 /* set I bit */
out _SFR_IO_ADDR(SREG), r21
pop_range 30, 31
- pop_range 21, 26
- reti
+ pop_range 21, 27
+ pop r1
+ ret
/******************************************************************************/
/*
ldi r27, hi8(uart0_ctx+UART0_CBB_TX_OFFSET)
20:
movw r24, r26
+ cli
rcall circularbytebuffer_cnt
+ sei
cpi r24, UART0_TXBUFFER_SIZE
breq 20b
movw r22, r26
clr r25
cli
rcall circularbytebuffer_append
- sei
SET_BIT_IO UCSR0B, UDRIE0, r24
- ret
+ reti
/******************************************************************************/
/*
* }
*
*/
- .global USART0_RX_vect
- USART0_RX_vect:
+ .global RX_ISR
+ RX_ISR:
+ push_range 0, 1
push_range 16, 31
- in r21, _SFR_IO_ADDR(SREG)
+ in r16, _SFR_IO_ADDR(SREG)
+ clr r1
LOAD_IO r24, UDR0
#if UART0_SWFLOWCTRL
- ldi r26, lo8(uart0_ctx+UART0_TXON_OFFSET)
+ ldi r26, lo8(uart0_ctx+UART0_TXON_OFFSET)
ldi r27, hi8(uart0_ctx+UART0_TXON_OFFSET)
cpi r24, XON_VALUE
- brne 10f
- ldi r24, 1
- st X, r24
- rjmp 99f
-10:
+ breq 11f
cpi r24, XOFF_VALUE
- brne 20f
+ brne 12f
clr r24
- st X, r24
+11: st X, r24
rjmp 99f
+12:
+ push r24
+/* now the "sending" part*/
+ ldi r24, lo8(uart0_ctx+UART0_CBB_RX_OFFSET)
+ ldi r25, hi8(uart0_ctx+UART0_CBB_RX_OFFSET)
+ rcall circularbytebuffer_cnt
+ ldi r30, lo8(uart0_ctx+UART0_RXON_OFFSET)
+ ldi r31, hi8(uart0_ctx+UART0_RXON_OFFSET)
+ ld r18, Z
+ tst r18
+ breq 15f/* branch if rxon inactive -> we had send an XOFF earlier */
+ /* ok, we did not have send an XOFF, should we? */
+ cpi r24, UART0_THRESH_HIGH
+ brlo 90f /* ok, nothing critical, go on */
+ st Z, r1
+ ldi r24, XOFF_VALUE
+; sbi _SFR_IO_ADDR(PORTD), 5
+ rjmp 16f
+15:
+ cpi r24, UART0_THRESH_LOW
+ brsh 90f /* nothing has changed */
+ /* if we get here, we had send an XOFF and are now below threshold */
+ /* so we sen an XON */
+ ldi r24, XON_VALUE
+ cbi _SFR_IO_ADDR(PORTD), 5
+ st Z, r24
+16:
+ ldi r22, lo8(uart0_ctx+UART0_CBB_TX_OFFSET)
+ ldi r23, hi8(uart0_ctx+UART0_CBB_TX_OFFSET)
+ rcall circularbytebuffer_push
+ SET_BIT_IO UCSR0B, UDRIE0, r24
+90:
+ pop r24
#endif /* UART0_SWFLOWCTRL */
20:
#if UART0_HOOK
ldi r22, lo8(uart0_ctx+UART0_CBB_RX_OFFSET)
ldi r23, hi8(uart0_ctx+UART0_CBB_RX_OFFSET)
clr r25
+; sbi _SFR_IO_ADDR(PORTD), 6
rcall circularbytebuffer_append
-#if UART0_SWFLOWCTRL
- ldi r24, lo8(uart0_ctx+UART0_CBB_RX_OFFSET)
- ldi r25, hi8(uart0_ctx+UART0_CBB_RX_OFFSET)
- rcall circularbytebuffer_cnt
- ldi r22, lo8(uart0_ctx+UART0_CBB_TX_OFFSET)
- ldi r23, hi8(uart0_ctx+UART0_CBB_TX_OFFSET)
- ldi r30, lo8(uart0_ctx+UART0_RXON_OFFSET)
- ldi r31, hi8(uart0_ctx+UART0_RXON_OFFSET)
- ld r21, Z
- tst r21
- breq 60f
- cpi r24, UART0_THRESH_HIGH+1
- brlo 99f
- clr r25
- ldi r24, XOFF_VALUE
- rcall circularbytebuffer_push
- SET_BIT_IO UCSR0B, UDRIE0, r24
- rjmp 99f
-60:
- cpi r24, UART0_THRESH_LOW
- brge 99f
- clr r25
- ldi r24, XON_VALUE
- rcall circularbytebuffer_push
- SET_BIT_IO UCSR0B, UDRIE0, r24
-#endif /* UART0_SWFLOWCTRL */
99:
- out _SFR_IO_ADDR(SREG), r21
+ out _SFR_IO_ADDR(SREG), r16
pop_range 16, 31
+ pop_range 0, 1
reti
/******************************************************************************/
movw r24, r22
cli
rcall circularbytebuffer_get_fifo
+ clr r25
reti
/******************************************************************************/
st X+, r25
ret
#endif
+
+.global uart0_flush
+uart0_flush:
+10:
+ ldi r24, lo8(uart0_ctx+UART0_CBB_TX_OFFSET)
+ ldi r25, hi8(uart0_ctx+UART0_CBB_TX_OFFSET)
+ rcall circularbytebuffer_cnt
+ tst r24
+ brne 10b
+ ret
+
+#endif /* UART0_I */