-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmcuicom.c
158 lines (126 loc) · 3.54 KB
/
mcuicom.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
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifndef MCUICOM_C
#define MCUICOM_C
#endif
#include "mcuicom.h"
#include "hostcmdset.h"
#include "macros.h"
static buffer_t mcuicom_rcv_buf;
static int first_cmdend = -1;
#include "debug.h"
inline void mcuicom_setup(void)
{
// Set up the receive buffer
buffer_init(&mcuicom_rcv_buf);
// Clear UART1 registers
U1MODE = 0x0000;
U1STA = 0x0000;
// Enable UART1 module
U1MODEbits.UARTEN = 1;
// Set up UART1 baud rate
U1BRG = BRGVAL;
// Clear UART1 receiver interrupt flag
IFS0bits.U1RXIF = 0;
// Clear UART1 transmitter interrupt flag
IFS0bits.U1TXIF = 0;
// Enable UART1 receiver ISR
IEC0bits.U1RXIE = 1;
// Disable UART1 transmitter ISR
IEC0bits.U1TXIE = 0;
// Set up UART1 receiver to interrupt when one character is received
U1STAbits.URXISEL = 0;
// Enable UART1 transmitter
U1STAbits.UTXEN = 1;
}
int mcuicom_send(const char * const data)
{
int sent;
for (sent = 0; data[sent] != '\0'; ++sent)
{
while (U1STAbits.UTXBF); // Wait while the transmit buffer is full
U1TXREG = data[sent];
}
return sent;
}
/**
* UART1 receive ISR.
*/
void __attribute__((interrupt, auto_psv)) _U1RXInterrupt(void)
{
// Disable UART1 receiver interrupts, to prevent CPU from interrupting
// and modifying the receive buffer.
IEC0bits.U1RXIE = 0;
#ifdef __dsPIC30F4011__
if (U1STAbits.URXDA)
dbgmsg_uart1("data received\n");
if (mcuicom_rcv_buf.used < mcuicom_rcv_buf.size)
dbgmsg_uart1("used < size\n");
#endif
// While UART1 receive buffer has data and the 'mcuicom_rcv_buf' has free
// space...
while (U1STAbits.URXDA && mcuicom_rcv_buf.used < mcuicom_rcv_buf.size)
{
// Read the received byte from the UART1 receive register
mcuicom_rcv_buf.data[mcuicom_rcv_buf.used] = U1RXREG;
#ifdef __dsPIC30F4011__
if (mcuicom_rcv_buf.data[mcuicom_rcv_buf.used] == '\r')
dbgmsg_uart1("carriage return received\n");
#endif
// If this byte is a command separator and no command separator has been
// found previously, remember its position in the buffer
if (first_cmdend < 0 &&
mcuicom_rcv_buf.data[mcuicom_rcv_buf.used] == *CMDEND)
{
#ifdef __dsPIC30F4011__
dbgmsg_uart1("first_cmdend set\n");
#endif
first_cmdend = mcuicom_rcv_buf.used;
}
// Increment the count of elements stored in the buffer
++mcuicom_rcv_buf.used;
}
#ifdef __dsPIC30F4011__
dbgmsg_uart1("_U1RXInterrupt\n");
#endif
// Re-enable UART1 receiver interrupts
IEC0bits.U1RXIE = 1;
// Clear the UART1 receiver interrupt flag
IFS0bits.U1RXIF = 0;
}
int mcuicom_read_cmd(char buf[], int size, bool_t *full)
{
int copied;
int i, j;
// Copy received data to the user's buffer
for (copied = 0; copied <= first_cmdend && copied < size; ++copied)
buf[copied] = mcuicom_rcv_buf.data[copied];
// Set the full flag accordingly
if (copied > first_cmdend)
*full = true;
else
*full = false;
// Shift the data in the buffer to remove already copied data and search
// for the next command end marker
if (copied)
{
// Disable UART1 receive interrupt to prevent the ISR from messing
// around with 'mcuicom_rcv_buf.used'
IEC0bits.U1RXIE = 0;
for (i = 0, j = copied; j < mcuicom_rcv_buf.used; ++i, ++j)
mcuicom_rcv_buf.data[i] = mcuicom_rcv_buf.data[j];
mcuicom_rcv_buf.used -= copied;
for (i = 0;
i < mcuicom_rcv_buf.used && mcuicom_rcv_buf.data[i] != *CMDEND;
++i);
if (i < mcuicom_rcv_buf.used)
first_cmdend = i;
else
first_cmdend = -1;
// Enable UART1 receive interrupt again
IEC0bits.U1RXIE = 1;
}
return copied;
}
bool_t mcuicom_cmd_available(void)
{
return first_cmdend > -1;
}