Get rid of ack/nack code.
[uccvend-snackrom.git] / ROM2 / sci.c
index 39006bc..6ef3cd3 100644 (file)
 #include "vend.h"
 #include "sci.h"
 
+char sci_tx_buf[BUFFER_LEN];
+volatile char sci_rx_buf[BUFFER_LEN];
+volatile bool sci_have_packet;
+volatile u8 sci_rx_buf_ptr;
+volatile u8 sci_rx_buf_ptr_start;
+volatile bool sci_echo;
+bool sci_doing_xmodem;
+
 void sci_init() {
-       _io_ports[M6811_BAUD] = M6811_DEF_BAUD;
+       /* assumes clock of 4.91Mhz */
+       _io_ports[M6811_BAUD] = 0x03; /* 9600 baud */
+
        /* Setup character format 1 start, 8-bits, 1 stop.  */
        _io_ports[M6811_SCCR1] = 0;
 
-       /* Enable reciever and transmitter.  */
-       _io_ports[M6811_SCCR2] = 0xc;
+       /* Enable reciever and transmitter & rx interrupt.  */
+       _io_ports[M6811_SCCR2] = M6811_RIE | M6811_TE | M6811_RE;
+
+       sci_have_packet = 0;
+       sci_rx_buf_ptr = 0;
+       sci_rx_buf_ptr_start = 0;
+       sci_echo = 0;
+       sci_doing_xmodem = 0;
+}
+
+void send_buffer(bool crlf) {
+       char* c;
+       for (c = sci_tx_buf; *c; c++) {
+               /* wait for TX ready */
+               while (!(_io_ports[M6811_SCSR] & M6811_TDRE));
+
+               /* send byte */
+               _io_ports[M6811_SCDR] = *c;
+       }
+       if (!crlf) return;
+       /* send CRLF */
+       while (!(_io_ports[M6811_SCSR] & M6811_TDRE));
+       _io_ports[M6811_SCDR] = '\r';
+       while (!(_io_ports[M6811_SCSR] & M6811_TDRE));
+       _io_ports[M6811_SCDR] = '\n';
+}
+
+void send_string(char* c) {
+       for (; *c; c++) {
+               while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TX ready */
+               _io_ports[M6811_SCDR] = *c; /* send byte */
+       }
+}
+
+char toupper(char c) {
+       if (c >= 'a' && c <= 'z') c -= 'a'-'A';
+       return c;
 }
+
+void sci_rx_int() {
+       char buf = _io_ports[M6811_SCDR];
+       if (sci_doing_xmodem) {
+               if ((sci_rx_buf_ptr+1)%BUFFER_LEN == sci_rx_buf_ptr_start) {
+                       /* we drop following bytes :( */
+                       return;
+               }
+               sci_rx_buf[sci_rx_buf_ptr] = buf;
+               sci_rx_buf_ptr++;
+               sci_rx_buf_ptr %= BUFFER_LEN;
+               return;
+       }
+       if (sci_echo) {
+               while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TX ready */
+               _io_ports[M6811_SCDR] = buf; /* send byte */
+       }
+
+       /* XXX FIXME we should do something about errors. nack? */
+       if (sci_have_packet) {
+               /* overrun :( */
+               return;
+       }
+       /* we upper case because no commands care that things aren't */
+       sci_rx_buf[sci_rx_buf_ptr] = toupper(buf);
+
+       if (buf == '\n' || buf == '\r') {
+               sci_rx_buf[sci_rx_buf_ptr] = '\0';
+               sci_have_packet = 1;
+       }
+
+       if (sci_rx_buf_ptr+1 < BUFFER_LEN)
+               sci_rx_buf_ptr++;
+       else {
+               sci_rx_buf[BUFFER_LEN-1] = '\0'; /* this is as much as we could fit */
+       }
+}
+
+void sci_interrupt_serial() {
+       if (_io_ports[M6811_SCSR] & M6811_RDRF) sci_rx_int();
+
+       if (_io_ports[M6811_SCSR] & M6811_OR)
+               _io_ports[M6811_SCDR]; /* declare it a lost cause */
+}
+
+void msg_clr() {
+       sci_have_packet = 0;
+       sci_rx_buf_ptr = 0;
+}
+
+u16 sci_timer;
+void serial_rti() { /* called every 6.6 ms */
+       if (sci_timer) sci_timer--;
+}
+
+/* for gdb compatibility */
+int serial_readchar(u8 timeout) {
+       int ret;
+       sci_timer = timeout * 152;
+       while (sci_timer && sci_rx_buf_ptr_start == sci_rx_buf_ptr); /* spin */
+       if (sci_timer == 0) return SERIAL_TIMEOUT;
+       ret = sci_rx_buf[sci_rx_buf_ptr_start];
+       sci_rx_buf_ptr_start++;
+       sci_rx_buf_ptr_start %= BUFFER_LEN;
+       return ret;
+}
+
+void serial_write(const char *str, int len) {
+       char *c, *end;
+       end = (char*)(str + len);
+       for (c = (char*)str; c < end; c++) {
+               while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TX ready */
+               _io_ports[M6811_SCDR] = *c; /* send byte */
+       }
+}
+

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