summaryrefslogtreecommitdiff
path: root/src/uart.c
blob: 4f3b88e56eafbe1a5bbed5b18693edfa29ac2efc (plain)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <avr/io.h>
#include <stdio.h>
#include <util/setbaud.h>
#include <util/delay.h>
#include "pins.h"
#include "debug.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
 *
 *
 **/

void uart_debug_sendbyte(uint8_t byte) { 
  loop_until_bit_is_set(UCSR0A, UDRE0); 
  UDR0 = byte; 
}

uint8_t uart_debug_recvbyte() {
  loop_until_bit_is_set(UCSR0A, RXC0);
  UART_PORT |= _BV(UART_RTS); 
  return UDR0;
}

void uart_debug_init() {

  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));

}

#ifdef FLASH_EEPROM
//this uart port recieves from the computer and writes the eeprom
void uart_flash_init() {
  //syncronization
  UART_DDR |= _BV(UART_RTS); 
  UART_DDR &= ~(_BV(UART_CTS)); //keep in mind cts/rts is inverted; low is 1 and high is 0
  UART_PORT |= _BV(UART_RTS); //keep in mind cts/rts is inverted; low is 1 and high is 0
  
  //for serial speed, we'll just use the same speed for now
  UBRR1H = UBRRH_VALUE;
  UBRR1L = UBRRL_VALUE;
  
  UCSR1A &= ~(_BV(U2X1));

  UCSR1C = ((_BV(UCSZ11)) | _BV(UCSZ10)); // set 8 bit char size, yes the '=' is intentional
  UCSR1B = (_BV(RXEN1) | _BV(TXEN1));

  //when the master initates serial via pyserial, for some reason it pulls our CTS low
  //for a brief moment. This hack avoids that
  printf("waiting for unwanted initation pulse...\r\n");
  loop_until_bit_is_clear(UART_PIN, UART_CTS);
  loop_until_bit_is_set(UART_PIN, UART_CTS);
  printf("complete\r\n");
}

void uart_flash_sendbyte(uint8_t byte) { 
  printf("send start\r\n");
  if(UART_PORT & _BV(UART_CTS)) {
    printf("send conflict!\r\n");
    debug_crash(); //make sure they're not trying to send
  }
  UART_PORT &= ~(_BV(UART_RTS)); //us: ready to send
  printf("waiting on master\r\n");
  loop_until_bit_is_clear(UART_PIN, UART_CTS); //them: go ahead
  printf("waiting for transmit buffer\r\n");
  loop_until_bit_is_set(UCSR1A, UDRE1);        //wait until buffer is empty
  UDR1 = byte;                                   
  UART_PORT |= _BV(UART_RTS);                  //okay, we be done sending
  printf("done splurting out the data, still need to mark end of packet\r\n"); 
  loop_until_bit_is_set(UART_PIN, UART_CTS); //wait for them to get the message so we don't double dip
  printf("we be done tho\r\n");
}

uint8_t uart_flash_recvbyte() {
  char byte_in;
  loop_until_bit_is_clear(UART_PIN, UART_CTS); //wait for their request
  UART_PORT &= ~(_BV(UART_RTS)); //hey, you can send now
  loop_until_bit_is_set(UCSR1A, RXC1); //wait for them to actually send
  byte_in = UDR1;
  UART_PORT |= _BV(UART_RTS); //okay, you can no longer send
  loop_until_bit_is_set(UART_PIN, UART_CTS); //wait for them to get the message so we don't double dip
  return byte_in;
}
#endif