cortexelf-v1: More 1802 noodling
[fw/altos] / src / cortexelf-v1 / ao_1802.c
index 55e778df7d6dbfdf636248c6b73132a4ce834ae0..b7e11637ab9dbf9eeef4a80d5da106a86808c93f 100644 (file)
@@ -17,9 +17,6 @@
 #include <ao_1802.h>
 #include <ao_exti.h>
 
-/* Signals muxed between 1802 and STM */
-uint8_t                MRD, TPB, TPA, MWR;
-
 /* Decoded address driven by TPA/TPB signals */
 uint16_t       ADDRESS;
 
@@ -27,144 +24,305 @@ uint16_t  ADDRESS;
 uint8_t                DATA;
 
 /* Mux control */
-#define MUX_1802       0
-#define MUX_STM                1
+#define _MUX_1802              0
+#define _MUX_STM               1
 
 uint8_t                MUX_CONTROL;
 
-/* Signals driven by 1802 only */
-uint8_t                WAIT, CLEAR, Q, SC, N;
-uint8_t                DMA_IN, DMA_OUT, INTERRUPT;
-uint8_t                EF;
+/* Signals muxed between 1802 and STM */
+uint8_t
+MRD(void) {
+       return ao_gpio_get(MRD_PORT, MRD_BIT, MRD_PIN);
+}
 
-static uint8_t ma_stm;
+void
+MRD_set(uint8_t value) {
+       ao_gpio_set(MRD_PORT, MRD_BIT, MRD_PIN, value);
+}
 
 uint8_t
-MA(void) {
-       if (MUX_CONTROL == MUX_1802)
-               return (ao_gpio_get_all(MA_PORT) >> MA_SHIFT) & 0xff;
-       else
-               return ma_stm;
+MWR(void) {
+       return ao_gpio_get(MWR_PORT, MWR_BIT, MWR_PIN);
+}
+
+void
+MWR_set(uint8_t value) {
+       ao_gpio_set(MWR_PORT, MWR_BIT, MWR_PIN, value);
 }
 
 static void
-MA_set(uint8_t ma) {
-       ao_gpio_set_mask(MA_PORT, ((uint16_t) ma) << MA_SHIFT, 0xff << MA_SHIFT);
-       ma_stm = ma;
+TPA_rising(void)
+{
+       ADDRESS = (ADDRESS & 0x00ff) | ((uint16_t) MA() << 8);
+       ao_wakeup(&ADDRESS);
 }
 
-static uint8_t data_stm;
+uint8_t
+TPA(void) {
+       return ao_gpio_get(TPA_PORT, TPA_BIT, TPA_PIN);
+}
 
-static uint8_t
-DATA_get(void) {
-       if (MUX_CONTROL == MUX_1802)
-               return ao_flip_bits[(ao_gpio_get_all(DATA_PORT) >> DATA_SHIFT) & 0xff];
-       else
-               return data_stm;
+void
+TPA_set(uint8_t tpa) {
+       ao_gpio_set(TPA_PORT, TPA_BIT, TPA_PIN, tpa);
+       if (tpa)
+               TPA_rising();
+}
+
+static void
+TPB_rising(void)
+{
+       ADDRESS = (ADDRESS & 0xff00) | MA();
+       ao_wakeup(&ADDRESS);
 }
 
 static void
-DATA_set(uint8_t data) {
-       ao_gpio_set_mask(DATA_PORT, ((uint16_t) ao_flip_bits[data]) << DATA_SHIFT, 0xff << DATA_SHIFT);
-       data_stm = data;
+TPB_falling(void)
+{
+       DATA = BUS();
+       ao_wakeup(&ADDRESS);
 }
 
-static uint8_t
-N_get(void) {
-       return (ao_gpio_get_all(N_PORT) >> N_SHIFT) & 0x7;
+uint8_t
+TPB(void) {
+       return ao_gpio_get(TPB_PORT, TPB_BIT, TPB_PIN);
 }
 
-static uint8_t
-EF_get(void) {
-       return (ao_gpio_get_all(EF_PORT) >> EF_SHIFT) & 0xf;
+void
+TPB_set(uint8_t tpb) {
+       ao_gpio_set(TPB_PORT, TPB_BIT, TPB_PIN, tpb);
+       if (tpb)
+               TPB_rising();
+       else
+               TPB_falling();
 }
 
-static uint8_t
-Q_get(void) {
+uint8_t
+MA(void) {
+       return (ao_gpio_get_all(MA_PORT) >> MA_SHIFT) & MA_MASK;
+}
+
+void
+MA_set(uint8_t ma) {
+       ao_gpio_set_mask(MA_PORT, ((uint16_t) ma) << MA_SHIFT, MA_MASK << MA_SHIFT);
+}
+
+/* Tri-state data bus */
+
+uint8_t
+BUS(void) {
+       return ao_flip_bits_8[(ao_gpio_get_all(BUS_PORT) >> BUS_SHIFT) & BUS_MASK];
+}
+
+void
+BUS_set(uint8_t bus) {
+       ao_gpio_set_mask(BUS_PORT, ao_flip_bits_8[bus] << BUS_SHIFT, BUS_MASK << BUS_SHIFT);
+}
+
+void
+BUS_stm(void)
+{
+       ao_set_output_mask(BUS_PORT, BUS_MASK << BUS_SHIFT);
+}
+
+void
+BUS_1802(void)
+{
+       ao_set_input_mask(BUS_PORT, BUS_MASK << BUS_SHIFT);
+}
+
+/* Pins controlled by 1802 */
+uint8_t
+SC(void) {
+       return ao_flip_bits_2[(ao_gpio_get_all(SC_PORT) >> SC_SHIFT) & SC_MASK];
+}
+
+uint8_t
+Q(void) {
        return ao_gpio_get(Q_PORT, Q_BIT, Q_PIN);
 }
 
-static uint8_t
-SC_get(void) {
-       static const uint8_t flip_sc[4] = { 0, 2, 1, 3 };
-       return flip_sc[(ao_gpio_get_all(SC_PORT) >> SC_SHIFT) & 3];
+uint8_t
+N(void) {
+       return (ao_gpio_get_all(N_PORT) >> N_SHIFT) & N_MASK;
+}
+
+/* Pins controlled by STM */
+uint8_t
+EF(void) {
+       return (ao_gpio_get_all(EF_PORT) >> EF_SHIFT) & EF_MASK;
 }
 
 void
-mrd(uint8_t value) { MRD = value; }
+EF_set(uint8_t ef) {
+       ao_gpio_set_mask(EF_PORT, ef << EF_SHIFT, EF_MASK << EF_SHIFT);
+}
+
+uint8_t
+DMA_IN(void) {
+       return ao_gpio_get(DMA_IN_PORT, DMA_IN_BIT, DMA_IN_PIN);
+}
 
 void
-mwr(uint8_t value) { MWR = value; }
+DMA_IN_set(uint8_t dma_in) {
+       ao_gpio_set(DMA_IN_PORT, DMA_IN_BIT, DMA_IN_PIN, dma_in);
+}
+
+uint8_t
+DMA_OUT(void) {
+       return ao_gpio_get(DMA_OUT_PORT, DMA_OUT_BIT, DMA_OUT_PIN);
+}
 
 void
-tpb(uint8_t value) {
-       TPB = value;
+DMA_OUT_set(uint8_t dma_out) {
+       ao_gpio_set(DMA_OUT_PORT, DMA_OUT_BIT, DMA_OUT_PIN, dma_out);
+}
 
-       /* Latch low address and data on rising edge of TPB */
-       if (TPB) {
-               ADDRESS = (ADDRESS & 0xff00) | MA();
-               DATA = DATA_get();
-               N = N_get();
-               ao_wakeup(&ADDRESS);
-       }
+uint8_t
+INT(void) {
+       return ao_gpio_get(INT_PORT, INT_BIT, INT_PIN);
 }
 
 void
-tpa(uint8_t value) {
-       TPA = value;
+INT_set(uint8_t dma_out) {
+       ao_gpio_set(INT_PORT, INT_BIT, INT_PIN, dma_out);
+}
+
+uint8_t
+CLEAR(void) {
+       return ao_gpio_get(CLEAR_PORT, CLEAR_BIT, CLEAR_PIN);
+}
+
+void
+CLEAR_set(uint8_t dma_out) {
+       ao_gpio_set(CLEAR_PORT, CLEAR_BIT, CLEAR_PIN, dma_out);
+}
 
+uint8_t
+WAIT(void) {
+       return ao_gpio_get(WAIT_PORT, WAIT_BIT, WAIT_PIN);
+}
+
+void
+WAIT_set(uint8_t dma_out) {
+       ao_gpio_set(WAIT_PORT, WAIT_BIT, WAIT_PIN, dma_out);
+}
+
+void
+tpb_isr(void) {
+       /* Latch low address and data on rising edge of TPB */
+       if (TPB())
+               TPB_rising();
+       else
+               TPB_falling();
+}
+
+void
+tpa_isr(void) {
        /* Latch high address on rising edge of TPA */
-       if (TPA) {
-               ADDRESS = (ADDRESS & 0x00ff) | ((uint16_t) MA() << 8);
-               SC = SC_get();
-               if (SC == SC_EXECUTE)
-                       EF = EF_get();
-               ao_wakeup(&ADDRESS);
-       }
+       if (TPA())
+               TPA_rising();
 }
 
-#define ao_1802_in(port, bit, callback) do {                           \
-               ao_enable_input(port, bit, 0);                          \
-               ao_exti_enable(port, bit);                              \
-               ao_exti_set_callback(port, bit, callback);              \
-               (*callback)();                                          \
+#define ao_1802_in(port, bit, mode) do {               \
+               ao_gpio_set_mode(port, bit, mode);      \
+               ao_set_input(port, bit);                \
+       } while (0)
+
+#define ao_1802_in_isr(port, bit, mode) do {           \
+               ao_gpio_set_mode(port, bit, mode);      \
+               ao_set_input(port, bit);                \
+               ao_exti_enable(port, bit);              \
        } while (0)
 
-static void mrd_isr(void) { mrd(ao_gpio_get(MRD_PORT, MRD_BIT, MRD_PIN)); }
-static void mwr_isr(void) { mwr(ao_gpio_get(MWR_PORT, MWR_BIT, MWR_PIN)); }
-static void tpb_isr(void) { tpb(ao_gpio_get(TPB_PORT, TPB_BIT, TPB_PIN)); }
-static void tpa_isr(void) { tpa(ao_gpio_get(TPA_PORT, TPA_BIT, TPA_PIN)); }
-static void q_isr(void) { Q = Q_get(); }
+#define ao_1802_out_isr(port, bit) do { \
+               ao_exti_disable(port, bit); \
+               ao_set_output(port, bit); \
+       } while (0)
 
-static void
-ao_set_1802(void)
+void
+MUX_1802(void)
 {
-       ao_gpio_set(MUX_PORT, MUX_BIT, MUX_PIN, 0);
-       ao_1802_in(MRD_PORT, MRD_BIT, mrd_isr);
-       ao_1802_in(MWR_PORT, MWR_BIT, mwr_isr);
-       ao_1802_in(TPB_PORT, TPB_BIT, tpb_isr);
-       ao_1802_in(TPA_PORT, TPA_BIT, tpa_isr);
-       MUX_CONTROL = MUX_1802;
+       if (MUX_CONTROL != _MUX_1802) {
+               /* Set pins to input, but pulled to idle value */
+               ao_1802_in(MRD_PORT, MRD_BIT, AO_EXTI_MODE_PULL_UP);
+               ao_1802_in(MWR_PORT, MWR_BIT, AO_EXTI_MODE_PULL_UP);
+               ao_1802_in_isr(TPB_PORT, TPB_BIT, AO_EXTI_MODE_PULL_DOWN);
+               ao_1802_in_isr(TPA_PORT, TPA_BIT, AO_EXTI_MODE_PULL_DOWN);
+               ao_set_input_mask(MA_PORT, MA_MASK << MA_SHIFT);
+
+               ao_gpio_set(MUX_PORT, MUX_BIT, MUX_PIN, 0);
+
+               /* Now change the pins to eliminate the pull up/down */
+               ao_gpio_set_mode(MRD_PORT, MRD_BIT, 0);
+               ao_gpio_set_mode(MWR_PORT, MWR_BIT, 0);
+               ao_gpio_set_mode(TPB_PORT, TPB_BIT, 0);
+               ao_gpio_set_mode(TPA_PORT, TPA_BIT, 0);
+
+               MUX_CONTROL = _MUX_1802;
+       }
 }
 
-static void
-ao_set_arm(void)
+void
+MUX_stm(void)
 {
-       ao_enable_output(MRD_PORT, MRD_BIT, MRD_PIN, 1);
-       ao_enable_output(MWR_PORT, MWR_BIT, MWR_PIN, 1);
-       ao_enable_output(TPB_PORT, TPB_BIT, TPB_PIN, 0);
-       ao_enable_output(TPA_PORT, TPA_BIT, TPA_PIN, 0);
-       ao_gpio_set(MUX_PORT, MUX_BIT, MUX_PIN, 1);
-       MUX_CONTROL = MUX_STM;
+       if (MUX_CONTROL != _MUX_STM) {
+               /* Set the pins back to pull to the idle value */
+               ao_gpio_set_mode(MRD_PORT, MRD_BIT, AO_EXTI_MODE_PULL_UP);
+               ao_gpio_set_mode(MWR_PORT, MWR_BIT, AO_EXTI_MODE_PULL_UP);
+               ao_gpio_set_mode(TPB_PORT, TPB_BIT, AO_EXTI_MODE_PULL_DOWN);
+               ao_gpio_set_mode(TPA_PORT, TPA_BIT, AO_EXTI_MODE_PULL_DOWN);
+
+               ao_gpio_set(MUX_PORT, MUX_BIT, MUX_PIN, 1);
+
+               /* Now set the pins as output, driven to the idle value */
+               ao_set_output(MRD_PORT, MRD_BIT, MRD_PIN, 1);
+               ao_set_output(MWR_PORT, MWR_BIT, MWR_PIN, 1);
+               ao_set_output(TPB_PORT, TPB_BIT, TPB_PIN, 0);
+               ao_set_output(TPA_PORT, TPA_BIT, TPA_PIN, 0);
+               ao_set_output_mask(MA_PORT, MA_MASK << MA_SHIFT);
+               MUX_CONTROL = _MUX_STM;
+       }
 }
 
 void
-ao_1802_control_init(void)
+ao_1802_init(void)
 {
-       ao_set_1802();
+       /* Multiplexed signals*/
+
+       /* active low signals */
+       ao_enable_input(MRD_PORT, MRD_BIT, AO_EXTI_MODE_PULL_UP);
+       ao_enable_input(MWR_PORT, MWR_BIT, AO_EXTI_MODE_PULL_UP);
+
+       /* active high signals with interrupts */
+       ao_exti_setup(TPA_PORT, TPA_BIT,
+                     AO_EXTI_MODE_PULL_DOWN | AO_EXTI_MODE_RISING | AO_EXTI_MODE_FALLING,
+                     tpa_isr);
+       ao_exti_setup(TPB_PORT, TPB_BIT,
+                     AO_EXTI_MODE_PULL_DOWN | AO_EXTI_MODE_RISING | AO_EXTI_MODE_FALLING,
+                     tpb_isr);
+
+       /* multiplexed address bus */
+       ao_enable_input_mask(MA_PORT, MA_MASK << MA_SHIFT, 0);
+
+       /* Data bus */
+
+       ao_enable_input_mask(BUS_PORT, BUS_MASK << BUS_SHIFT, 0);
+
+       /* Pins controlled by 1802 */
+       ao_enable_input_mask(SC_PORT, SC_MASK << SC_SHIFT, 0);
+       ao_enable_input(Q_PORT, Q_BIT, 0);
+       ao_enable_input_mask(N_PORT, N_MASK << N_SHIFT, 0);
+
+       /* Pins controlled by STM */
+       ao_enable_output_mask(EF_PORT, 0, EF_MASK << EF_SHIFT);
+       ao_enable_output(DMA_IN_PORT, DMA_IN_BIT, DMA_IN_PIN, 1);
+       ao_enable_output(DMA_OUT_PORT, DMA_OUT_BIT, DMA_OUT_PIN, 1);
+       ao_enable_output(INT_PORT, INT_BIT, INT_PIN, 1);
+       ao_enable_output(CLEAR_PORT, CLEAR_BIT, CLEAR_PIN, 1);
+       ao_enable_output(WAIT_PORT, WAIT_BIT, WAIT_PIN, 1);
 
-       ao_1802_in(Q_PORT, Q_BIT, q_isr);
-       (void) MA_set;
-       (void) DATA_set;
-       (void) ao_set_arm;
+       /* Force configuration to STM so that MUX_1802 will do something */
+       MUX_CONTROL = _MUX_STM;
+       MUX_1802();
 }