D'oh. Wrong silence code.
[uccvend-snackrom.git] / ROM2 / sci.c
1 #include "vend.h"
2 #include "sci.h"
3
4 char sci_tx_buf[BUFFER_LEN];
5 volatile char sci_rx_buf[BUFFER_LEN];
6 volatile bool sci_have_packet;
7 volatile u8 sci_rx_buf_ptr;
8 volatile u8 sci_rx_buf_ptr_start;
9 volatile bool sci_echo;
10 bool sci_doing_xmodem;
11
12 void sci_init() {
13         /* assumes clock of 4.91Mhz */
14         _io_ports[M6811_BAUD] = 0x03; /* 9600 baud */
15
16         /* Setup character format 1 start, 8-bits, 1 stop.  */
17         _io_ports[M6811_SCCR1] = 0;
18
19         /* Enable reciever and transmitter & rx interrupt.  */
20         _io_ports[M6811_SCCR2] = M6811_RIE | M6811_TE | M6811_RE;
21
22         sci_have_packet = 0;
23         sci_rx_buf_ptr = 0;
24         sci_rx_buf_ptr_start = 0;
25         sci_echo = 0;
26         sci_doing_xmodem = 0;
27 }
28
29 void send_buffer(bool crlf) {
30         char* c;
31         for (c = sci_tx_buf; *c; c++) {
32                 /* wait for TX ready */
33                 while (!(_io_ports[M6811_SCSR] & M6811_TDRE));
34
35                 /* send byte */
36                 _io_ports[M6811_SCDR] = *c;
37         }
38         if (!crlf) return;
39         /* send CRLF */
40         while (!(_io_ports[M6811_SCSR] & M6811_TDRE));
41         _io_ports[M6811_SCDR] = '\r';
42         while (!(_io_ports[M6811_SCSR] & M6811_TDRE));
43         _io_ports[M6811_SCDR] = '\n';
44 }
45
46 void send_string(char* c) {
47         for (; *c; c++) {
48                 while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TX ready */
49                 _io_ports[M6811_SCDR] = *c; /* send byte */
50         }
51 }
52
53 char toupper(char c) {
54         if (c >= 'a' && c <= 'z') c -= 'a'-'A';
55         return c;
56 }
57
58 void sci_rx_int() {
59         char buf = _io_ports[M6811_SCDR];
60         if (sci_doing_xmodem) {
61                 if ((sci_rx_buf_ptr+1)%BUFFER_LEN == sci_rx_buf_ptr_start) {
62                         /* we drop following bytes :( */
63                         return;
64                 }
65                 sci_rx_buf[sci_rx_buf_ptr] = buf;
66                 sci_rx_buf_ptr++;
67                 sci_rx_buf_ptr %= BUFFER_LEN;
68                 return;
69         }
70         if (sci_echo) {
71                 while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TX ready */
72                 _io_ports[M6811_SCDR] = buf; /* send byte */
73         }
74
75         /* XXX FIXME we should do something about errors. nack? */
76         if (sci_have_packet) {
77                 /* overrun :( */
78                 return;
79         }
80         /* we upper case because no commands care that things aren't */
81         sci_rx_buf[sci_rx_buf_ptr] = toupper(buf);
82
83         if (buf == '\n' || buf == '\r') {
84                 sci_rx_buf[sci_rx_buf_ptr] = '\0';
85                 sci_have_packet = 1;
86         }
87
88         if (sci_rx_buf_ptr+1 < BUFFER_LEN)
89                 sci_rx_buf_ptr++;
90         else {
91                 sci_rx_buf[BUFFER_LEN-1] = '\0'; /* this is as much as we could fit */
92         }
93 }
94
95 void sci_interrupt_serial() {
96         if (_io_ports[M6811_SCSR] & M6811_RDRF) sci_rx_int();
97
98         if (_io_ports[M6811_SCSR] & M6811_OR)
99                 _io_ports[M6811_SCDR]; /* declare it a lost cause */
100 }
101
102 void msg_clr() {
103         sci_have_packet = 0;
104         sci_rx_buf_ptr = 0;
105 }
106
107 u16 sci_timer;
108 void serial_rti() { /* called every 6.6 ms */
109         if (sci_timer) sci_timer--;
110 }
111
112 /* for gdb compatibility */
113 int serial_readchar(u8 timeout) {
114         int ret;
115         sci_timer = timeout * 152;
116         while (sci_timer && sci_rx_buf_ptr_start == sci_rx_buf_ptr); /* spin */
117         if (sci_timer == 0) return SERIAL_TIMEOUT;
118         ret = sci_rx_buf[sci_rx_buf_ptr_start];
119         sci_rx_buf_ptr_start++;
120         sci_rx_buf_ptr_start %= BUFFER_LEN;
121         return ret;
122 }
123
124 void serial_write(const char *str, int len) {
125         char *c, *end;
126         end = (char*)(str + len);
127         for (c = (char*)str; c < end; c++) {
128                 while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TX ready */
129                 _io_ports[M6811_SCDR] = *c; /* send byte */
130         }
131 }
132

UCC git Repository :: git.ucc.asn.au