-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuart.c
executable file
·105 lines (96 loc) · 2.49 KB
/
uart.c
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
#include "uart.h"
static krn_mutex uart_mutex_tx;
static krn_mutex uart_mutex_rx;
krn_thread *uart_sleep_thread_tx;
krn_thread *uart_sleep_thread_rx;
volatile char* uart_tx_bfr;
int (*uart_rx_callback)(char c);
volatile int uart_tx_len;
volatile char* uart_rx_bfr;
volatile int uart_rx_len;
volatile int16_t uart_rx_wait_timeout;
void uart_init(int br)
{
P1SEL = BIT1 + BIT2;
P1SEL2 = BIT1 + BIT2;
UCA0CTL1 |= UCSSEL_2;
UCA0BR0 = br;
UCA0BR1 = 0;
UCA0MCTL = UCBRS0;
UCA0CTL1 &= ~UCSWRST;
uart_sleep_thread_tx = 0;
uart_sleep_thread_rx = 0;
uart_rx_callback = 0;
krn_mutex_init(&uart_mutex_tx);
krn_mutex_init(&uart_mutex_rx);
IE2 &= ~(UCA0TXIE | UCA0RXIE);
uart_rx_wait_timeout = 100 * 20;
}
void uart_write(char *bfr, int len)
{
CRITICAL_STORE;
if(!len) return;
krn_mutex_lock(&uart_mutex_tx);
CRITICAL_START();
uart_tx_bfr = bfr;
uart_tx_len = len;
IE2 |= UCA0TXIE;
uart_sleep_thread_tx = krn_thread_current;
krn_thread_lock(uart_sleep_thread_tx);
krn_dispatch();
CRITICAL_END();
krn_mutex_unlock(&uart_mutex_tx);
}
int uart_read(char *bfr, int len)
{
CRITICAL_STORE;
if(!len) return 0;
krn_mutex_lock(&uart_mutex_rx);
CRITICAL_START();
uart_rx_bfr = bfr;
uart_rx_len = len;
IE2 |= UCA0RXIE;
uart_sleep_thread_rx = krn_thread_current;
//krn_thread_lock(uart_sleep_thread_rx);
//krn_dispatch();
krn_sleep(uart_rx_wait_timeout);
uart_sleep_thread_rx = 0;
len = len - uart_rx_len;
CRITICAL_END();
krn_mutex_unlock(&uart_mutex_rx);
return len;
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) {
char c;
if(IFG2 & UCA0RXIFG) {
c = *uart_rx_bfr++ = UCA0RXBUF;
uart_rx_len--;
if(!(uart_rx_len && (uart_rx_callback ? uart_rx_callback(c) : 1))) {
IE2 &= ~UCA0RXIE;
if(uart_sleep_thread_rx) {
//krn_thread_unlock(uart_sleep_thread_rx);
krn_thread_wake(uart_sleep_thread_rx);
krn_thread_move(uart_sleep_thread_rx, krn_thread_current);
uart_sleep_thread_rx = 0;
//krn_dispatch(); //uncomment for extra hardness
}
}
}
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void) {
if(IFG2 & UCA0TXIFG) {
UCA0TXBUF = *uart_tx_bfr++;
uart_tx_len--;
if(!uart_tx_len) {
IE2 &= ~UCA0TXIE;
if(uart_sleep_thread_tx) {
krn_thread_unlock(uart_sleep_thread_tx);
krn_thread_move(uart_sleep_thread_tx, krn_thread_current);
uart_sleep_thread_tx = 0;
//krn_dispatch(); //uncomment for extra hardness
}
}
}
}