X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fcortexelf-v1%2Fao_1802.c;h=9fb36595d3797376d32b06b042eb0e8f1f361936;hp=55e778df7d6dbfdf636248c6b73132a4ce834ae0;hb=ac8a9bc2ef301f1f18772af7d871c257a56ae70c;hpb=47004dfe8ee8c8b31085b066d3d0fd5142fd49da diff --git a/src/cortexelf-v1/ao_1802.c b/src/cortexelf-v1/ao_1802.c index 55e778df..9fb36595 100644 --- a/src/cortexelf-v1/ao_1802.c +++ b/src/cortexelf-v1/ao_1802.c @@ -17,9 +17,6 @@ #include #include -/* 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(); + if (MWR() == 0 || MRD() == 0) + DATA = BUS(); + 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) +{ } -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(); }