| |
uart.h
// uart.h
//
// Beware! UART output and input "polarity" may not be what you want!!!
//
#ifndef __UART_H
#define __UART_H
#include "iodefs.h"
#include "progmem.h"
//
// Note: Only use #define TX_FALL_DELAY for baud rates faster than 38400
//
#ifndef TX_FALL_DELAY
#define TX_FALL_DELAY 0
#define TX_FALL_DELAY_CODE
#else
#undef TX_FALL_DELAY
#define TX_FALL_DELAY 3
#define TX_FALL_DELAY_CODE \
"nop" "\n\t" \
"nop" "\n\t" \
"nop" "\n\t"
#endif
//
// Number of 3-clock loops in one bit (i.e., one baud time)
//
#define UART_TX_COUNT \
((2*((CLOCK + (BAUD_RATE/2))/BAUD_RATE - 9 - TX_FALL_DELAY) + 3) / 6)
#define UART_RX_COUNT \
((2*((CLOCK + (BAUD_RATE/2))/BAUD_RATE-8) + 3) / 6)
#ifndef STOP_BITS
#define STOP_BITS 1
#endif
#ifndef BAUD_RATE
#define BAUD_RATE 9600
#endif
#define __uart_reset(port, bit) \
asm volatile ( \
"cbi %0, %1" "\n\t" \
"sbi %0-1, %1" \
: /* no outputs */ \
: "I" ((uint8_t)(port)), \
"I" ((uint8_t)(bit)) \
)
#define __uart_tx(port, bit, count) \
asm volatile ( \
"mov __tmp_reg__,%2" "\n" \
".L_%=:\t" \
"dec __tmp_reg__" "\n\t" \
"brne .L_%=" "\n\t" \
"cbi %0, %1" "\n\t" \
"sbi %0-1, %1" "\n\t" \
: /* no outputs */ \
: "I" ((uint8_t)(port)), \
"I" ((uint8_t)(bit)), \
"r" ((uint8_t)(count)) \
)
#define __uart_rx(port, bit) \
asm volatile ( \
"cbi %0-1, %1" "\n\t" \
"sbi %0, %1" "\n\t" \
: /* no outputs */ \
: "I" ((uint8_t)(port)), \
"I" ((uint8_t)(bit)) \
)
#define __putchar(port, bit, ch, stops, count)\
asm volatile ( \
"ldi r23, 9+%3" "\n\t" \
"mov r24, %2" "\n\t" \
"com r24" "\n\t" \
"sec" "\n" \
".L0_%=:\t" \
"brcc .L1_%=" "\n\t" \
TX_FALL_DELAY_CODE \
"sbi %0, %1" "\n\t" \
"rjmp .L2_%=" "\n" \
".L1_%=:\t" \
"cbi %0, %1" "\n\t" \
TX_FALL_DELAY_CODE \
"nop" "\n" \
".L2_%=:\t" \
"mov __tmp_reg__,%4" "\n" \
".L3_%=:\t" \
"dec __tmp_reg__" "\n\t" \
"brne .L3_%=" "\n\t" \
"lsr r24" "\n\t" \
"dec r23" "\n\t" \
"brne .L0_%=" \
: /* no outputs */ \
: "I" ((uint8_t)(port)), \
"I" ((uint8_t)(bit)), \
"r" ((uint8_t)(ch)), \
"I" ((uint8_t)(stops)), \
"r" ((uint8_t)(count)) \
: "r23", "r24" \
)
#define __getchar(port, bit, stops, count) ({ \
unsigned char ch; \
asm volatile ( \
"ldi r23,8+1" "\n" \
".L1_%=:\t" \
"sbis %1-2,%2" "\n\t" \
"rjmp .L1_%=" "\n\t" \
"mov __tmp_reg__,%4" "\n\t" \
"lsr __tmp_reg__" "\n" \
".L0_%=:\t" \
"dec __tmp_reg__" "\n\t" \
"brne .L0_%=" "\n" \
".L2_%=:\t" \
"mov __tmp_reg__,%4" "\n" \
".L3_%=:\t" \
"dec __tmp_reg__" "\n\t" \
"brne .L3_%=" "\n\t" \
"clc" "\n\t" \
"sbis %1-2,%2" "\n\t" \
"sec" "\n\t" \
"dec r23" "\n\t" \
"breq .L4_%=" "\n\t" \
"ror %0" "\n\t" \
"rjmp .L2_%=" "\n" \
".L4_%=:\t" \
: "=&r" (ch) \
: "I" ((uint8_t)(port)), \
"I" ((uint8_t)(bit)), \
"I" ((uint8_t)(stops)), \
"r" ((uint8_t)(count)) \
: "r23" \
); \
ch; \
})
#define _uart_reset() __uart_reset(TX_PORT, TX_BIT)
#define _uart_tx() __uart_tx(TX_PORT, TX_BIT, 2*(UART_TX_COUNT))
#define _uart_rx() __uart_rx(TX_PORT, TX_BIT)
#define _putchar(ch) __putchar(TX_PORT, TX_BIT, ch, STOP_BITS, UART_TX_COUNT)
#define _getchar() __getchar(TX_PORT, TX_BIT, STOP_BITS, UART_RX_COUNT);
void uart_tx(void);
void uart_rx(void);
#include "puthexb.h"
#include "getchar.h"
#include "putchar.h"
#include "crlf.h"
#include "pmputstr.h"
#endif /* __UART_H */
Back
|
|
|