summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c')
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c b/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c
new file mode 100644
index 0000000000..77d7867a21
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c
@@ -0,0 +1,159 @@
+/*****************************************************************************/
+/*
+ $Id$
+
+ M68302 SCC Polled Driver
+
+ */
+/*****************************************************************************/
+
+
+#include <bsp.h>
+#include <m68302.h>
+#include <m68302scc.h>
+
+#define M68302_SCC_COUNT (3)
+
+static volatile m302_SCC_t *scc[M68302_SCC_COUNT] = { 0, 0, 0 };
+static volatile m302_SCC_Registers_t *scc_reg[M68302_SCC_COUNT] = { 0, 0, 0 };
+static int scc_translate[M68302_SCC_COUNT] = { 0, 0, 0 };
+
+static const rtems_unsigned16 baud_clocks[] =
+{
+ (SYSTEM_CLOCK / ( 4800 * 16)),
+ (SYSTEM_CLOCK / ( 9600 * 16)),
+ (SYSTEM_CLOCK / ( 19200 * 16)),
+ (SYSTEM_CLOCK / ( 38400 * 16)),
+ (SYSTEM_CLOCK / ( 57600 * 16)),
+ (SYSTEM_CLOCK / (115700 * 16))
+};
+
+void scc_initialise(int channel, int baud, int translate)
+{
+ rtems_unsigned16 scon;
+
+ if (channel < M68302_SCC_COUNT)
+ {
+ scc[channel] = &m302.scc1 + channel;
+ scc_reg[channel] = &m302.reg.scc[channel];
+ scc_translate[channel] = translate;
+
+ scon = (baud_clocks[baud] & 0xF800) == 0 ? 0 : 1;
+ scon |= (((baud_clocks[baud] / (1 + scon * 3)) - 1) << 1) & 0x0FFE;
+
+ scc_reg[channel]->scon = scon;
+ scc_reg[channel]->scm = 0x0171;
+
+ scc[channel]->bd.tx[0].status = 0x2000;
+ scc[channel]->bd.tx[0].length = 0;
+ scc[channel]->bd.tx[0].buffer =
+ (rtems_unsigned8*) &(scc[channel]->bd.tx[1].buffer);
+
+ scc[channel]->bd.rx[0].status = 0x2000;
+ scc[channel]->bd.rx[0].length = 0;
+ scc[channel]->bd.rx[0].buffer =
+ (rtems_unsigned8*) &(scc[channel]->bd.rx[1].buffer);
+
+ scc[channel]->parm.rfcr = 0x50;
+ scc[channel]->parm.tfcr = 0x50;
+
+ scc[channel]->parm.mrblr = 0x0001;
+ scc[channel]->prot.uart.max_idl = 0x0004;
+ scc[channel]->prot.uart.brkcr = 1;
+ scc[channel]->prot.uart.parec = 0;
+ scc[channel]->prot.uart.frmec = 0;
+ scc[channel]->prot.uart.nosec = 0;
+ scc[channel]->prot.uart.brkec = 0;
+ scc[channel]->prot.uart.uaddr1 = 0;
+ scc[channel]->prot.uart.uaddr2 = 0;
+ scc[channel]->prot.uart.character[0] = 0x0003;
+ scc[channel]->prot.uart.character[1] = 0x8000;
+
+ scc_reg[channel]->scce = 0xFF;
+ scc_reg[channel]->sccm = 0x15;
+
+ scc_reg[channel]->scm = 0x17d;
+ }
+}
+
+unsigned char scc_status(int channel, unsigned char status)
+{
+ rtems_unsigned16 rx_status;
+
+ m302.reg.wcn = 0;
+
+ if ((channel < M68302_SCC_COUNT) && scc[channel])
+ {
+ rx_status = scc[channel]->bd.rx[0].status;
+
+ if ((rx_status & 0x8000) == 0)
+ {
+ if (rx_status & 0x003B)
+ {
+ return 2;
+ }
+ if (status == 0)
+ {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+unsigned char scc_in(int channel)
+{
+ m302.reg.wcn = 0;
+
+ if ((channel < M68302_SCC_COUNT) && scc[channel])
+ {
+ if ((scc[channel]->bd.rx[0].status & 0x8000) == 0)
+ {
+ unsigned char c;
+
+ c = *(scc[channel]->bd.rx[0].buffer);
+
+ scc[channel]->bd.rx[0].status = 0xa000;
+
+ return c;
+ }
+ }
+
+ return 0;
+}
+
+void scc_out(int channel, unsigned char character)
+{
+ if ((channel < M68302_SCC_COUNT) && scc[channel])
+ {
+ do
+ {
+ m302.reg.wcn = 0;
+ }
+ while (scc[channel]->bd.tx[0].status & 0x8000);
+
+ *(scc[channel]->bd.tx[0].buffer) = character;
+
+ scc[channel]->bd.tx[0].length = 1;
+ scc[channel]->bd.tx[0].status = 0xa000;
+
+ if (scc_translate[channel])
+ {
+ if (character == '\n')
+ {
+ scc_out(channel, '\r');
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+