#include "vend.h"
+#include "chime.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;
+
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;
+}
+
+void send_packet() {
+ 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;
+ }
+}
+
+void sci_rx_int() {
+ /* XXX FIXME we should do something about errors. nack? */
+ if (sci_have_packet) {
+ /* overrun :( */
+ _io_ports[M6811_SCDR]; /* read it anyway */
+ return;
+ }
+ sci_rx_buf[sci_rx_buf_ptr] = _io_ports[M6811_SCDR];
+ if (sci_rx_buf[sci_rx_buf_ptr] == '\n' ||
+ sci_rx_buf[sci_rx_buf_ptr] == '\r') {
+ if (sci_rx_buf_ptr == 0) return; /* we've read a blank packet in */
+ sci_rx_buf[sci_rx_buf_ptr] = '\0';
+ sci_have_packet = 1;
+ sci_rx_buf_ptr = 0;
+ }
+ sci_rx_buf_ptr++;
+ if (sci_rx_buf_ptr >= BUFFER_LEN) {
+ sci_rx_buf[BUFFER_LEN] = '\0'; /* this is as much as we could fit */
+ sci_have_packet = 1;
+ sci_rx_buf_ptr = 0;
+ }
+}
+
+void sci_interrupt_serial() {
+ chime_start();
+
+ 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;
+}
+
+void send_ack() {
+ my_strncpy(sci_tx_buf, "!\n", BUFFER_LEN);
+ send_packet();
+}
+
+void send_nack() {
+ my_strncpy(sci_tx_buf, "?\n", BUFFER_LEN);
+ send_packet();
}