85 lines
2.6 KiB
C
85 lines
2.6 KiB
C
#include <avr/io.h>
|
|
#include <stdio.h>
|
|
#include <util/setbaud.h>
|
|
#include "pins.h"
|
|
|
|
/** UART notes
|
|
* UCSR0A:
|
|
* 0: MP communication mode
|
|
* 1: U2X (double trans speed)
|
|
* 2: USART parity error
|
|
* 3: Data overrun (udr0 not read before next frame)
|
|
* 4: Frame error
|
|
* 5: Data register empty (new data can be transmitted)
|
|
* 6: USART transmit complete
|
|
* 7: USART recieve complete
|
|
* ____________________________________________________________
|
|
* UCSR0B:
|
|
* 0: transmit data bit 8
|
|
* 1: recieve data bit 8
|
|
* 2: USART char size 0 (used with UCSZ01 and UCSZ00 to set data frame size)
|
|
* 3: Transmitter enable
|
|
* 4: Reciever enable
|
|
* 5: USART data reg empty interrupt table
|
|
* 6: TX complete int enable
|
|
* 7: RX complete int enable
|
|
* ____________________________________________________________
|
|
* UCSR0C:
|
|
* 0: Clock polarity (1: falling edge trasmit, recieve rising edge)
|
|
* 1: USART char size 0
|
|
* 2: USART char size 1
|
|
* 3: USART stop bit select (1: 1 stop bit, 0: 2 stop bits)
|
|
* 4: USART parity mode (00: async, 01: sync)
|
|
* 5: USART Parity mode (02: master SPI)
|
|
* 6: USART mode select (00: async 01: sync)
|
|
* 7: USART mode select (02: master SPI)
|
|
* ____________________________________________________________
|
|
* UBRR0(H,L): baudrates
|
|
*
|
|
*
|
|
**/
|
|
|
|
//TODO replace with static void and just use high level functions?
|
|
void uart_sendbyte(uint8_t byte) {
|
|
UART_PORT &= ~(_BV(UART_RTS)); //us: ready to send
|
|
loop_until_bit_is_clear(UART_PORT, UART_CTS); //them: go ahead
|
|
//also wait for buffer to be empty, should never be a problem
|
|
loop_until_bit_is_set(UCSR0A, UDRE0); //done recieving
|
|
UDR0 = byte;
|
|
UART_PORT |= _BV(UART_RTS); //keep in mind cts is inverted; low is 1 and high is 0
|
|
}
|
|
|
|
//TODO replace with static void and just use high level functions?
|
|
uint8_t uart_recvbyte() {
|
|
loop_until_bit_is_clear(UART_PORT, UART_CTS); //wait for their request
|
|
UART_PORT &= ~(_BV(UART_RTS)); //hey, you can send now
|
|
loop_until_bit_is_set(UCSR0A, RXC0); //wait for them to actually send
|
|
UART_PORT |= _BV(UART_RTS); //okay, you can no longer send
|
|
return UDR0;
|
|
}
|
|
|
|
void uart_init() {
|
|
//set baud rate
|
|
UART_DDR |= _BV(UART_RTS);
|
|
UART_PORT |= _BV(UART_RTS); //keep in mind cts is inverted; low is 1 and high is 0
|
|
|
|
UBRR0H = UBRRH_VALUE;
|
|
UBRR0L = UBRRL_VALUE;
|
|
|
|
/**
|
|
TODO figure out why USE_2X is enable when it shoudn't be
|
|
//set baud rate
|
|
#ifdef USE_2X //is set by header
|
|
UCSR0A |= _BV(U2X0);
|
|
#else
|
|
UCSR0A &= ~(_BV(U2X0));
|
|
#endif
|
|
**/
|
|
|
|
UCSR0A &= ~(_BV(U2X0));
|
|
|
|
UCSR0C = ((_BV(UCSZ01)) | _BV(UCSZ00)); // set 8 bit char size, yes the '=' is intentional
|
|
UCSR0B = (_BV(RXEN0) | _BV(TXEN0));
|
|
|
|
}
|