]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - stm32/z80-if.c
Merge branch 'master' into cmdline_edit
[z180-stamp.git] / stm32 / z80-if.c
index a9ce88450d8c551b22e23c3f9924e6f50461a22b..6c415d1a5500b08f51f2a554575756de7b71c4cf 100644 (file)
@@ -1,3 +1,68 @@
+/*
+ * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+/**
+ *
+ * Pin assignments
+ *
+ * | Z180-Sig  |  STM32-Port   |Buffer |  Dir  |   Special Function    |
+ * +------------+---------------+-------+-------+-----------------------+
+ * |   A0      | A     1       |   P   |  O    |                       |
+ * |   A1      | A     2       |   P   |  O    |                       |
+ * |   A2      | A     3       |   P   |  O    |                       |
+ * |   A3      | A     4       |   P   |  O    |                       |
+ * |   A4      | A     5       |   P   |  O    |                       |
+ * |   A5      | A     6       |   P   |  O    |                       |
+ * |   A6      | A     7       |   P   |  O    |                       |
+ * |   A7      | A     8       |       |  O    |                       |
+ * |   A8      | C     0       |   P   |  O    |                       |
+ * |   A9      | C     1       |   P   |  O    |                       |
+ * |   A10     | C     2       |   P   |  O    |                       |
+ * |   A11     | C     3       |   P   |  O    |                       |
+ * |   A12     | C     4       |   P   |  O    |                       |
+ * |   A13     | C     5       |   P   |  O    |                       |
+ * |   A14     | C     6       |       |  O    |                       |
+ * |   A15     | C     7       |       |  O    |                       |
+ * |   A16     | C     10      |       |  O    |                       |
+ * |   A17     | C     11      |       |  O    |                       |
+ * |   A18     | C     12      |       |  O    |                       |
+ * |   D0      | B     8       |       |  I/O  |                       |
+ * |   D1      | B     9       |       |  I/O  |                       |
+ * |   D2      | B     10      |       |  I/O  |                       |
+ * |   D3      | B     11      |       |  I/O  |                       |
+ * |   D4      | B     12      |       |  I/O  |                       |
+ * |   D5      | B     13      |       |  I/O  |                       |
+ * |   D6      | B     14      |       |  I/O  |                       |
+ * |   D7      | B     15      |       |  I/O  |                       |
+ * |   ME      | C     13      |   P   |  O    |                       |
+ * |   RD      | B     0       |   P   |  O    |                       |
+ * |   WR      | B     1       |   P   |  O    |                       |
+ * |   BUSREQ  | D     2       |       |  O    |                       |
+ * |   IOCS1   | A     11      |       |  I    |  TIM1_CH4             |
+ * |   BUSACK  | A     12      |       |  I    |                       |
+ * |   HALT    | A     12      |       |  I    |                       |
+ * |   NMI     | B     7       |       |  O    |                       |
+ * |   RST     | B     6       |       |  O    |  TIM16_CH1N           |
+ * |           |               |       |       |                       |
+ * |           | A     9       |       |       |  af1   USART1_TX      |
+ * |           | A     10      |       |       |  af1   USART1_RX      |
+ * |           | A     15      |       | JTDI  |  remap SPI1_NSS'      |
+ * |           | B     3       |       | JTDO  |  remap SPI1_SCK'      |
+ * |           | B     4       |       |NJTRST |  remap SPI1_MISO'     |
+ * |           | B     5       |       |       |  remap SPI1_MOSI'     |
+ * |           | C     14      |       |       |  af1   OSC32          |
+ * |           | C     15      |       |       |  af1   OSC32          |
+
+
+AFIO_MAPR2 =
+AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON  (frees
+AFIO_MAPR_SPI1_REMAP
+
+ */
+
 /**
  *
  * Pin assignments
 
 
 AFIO_MAPR2 =
-AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON  (frees 
-AFIO_MAPR_SPI1_REMAP 
+AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON  (frees
+AFIO_MAPR_SPI1_REMAP
 
  */
 
+#include <stdio.h>
+
 
 #include <libopencm3/stm32/gpio.h>
 #include <libopencm3/stm32/rcc.h>
 #include <libopencm3/stm32/timer.h>
 #include <libopencm3/stm32/dma.h>
+#include "debug.h"
 #include "z80-if.h"
 
+
 /* Number of array elements */
 #define NELEMS(x)  (sizeof x/sizeof *x)
 
@@ -157,7 +226,7 @@ AFIO_MAPR_SPI1_REMAP
 
 #define IOFIELD_GET(src, width, shift) \
                ((src>>shift) & MASK(width))
-               
+
 #define CNF_MODE_I_F       (GPIO_CNF_INPUT_FLOAT<<2 |GPIO_MODE_INPUT)
 #define CNF_MODE_O_PP  (GPIO_CNF_OUTPUT_PUSHPULL<<2 | GPIO_MODE_OUTPUT_10_MHZ)
 
@@ -186,16 +255,16 @@ static void tim16_setup(void)
 {
        RCC_APB2RSTR |= RCC_APB2RSTR_TIM16RST;
        RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM16RST;
-       
+
        TIM16_BDTR = TIM_BDTR_MOE;
-               
+
        TIM16_CCMR1 = 0
-               | TIM_CCMR1_OC1M_FORCE_LOW      
+               | TIM_CCMR1_OC1M_FORCE_LOW
                | TIM_CCMR1_CC1S_OUT;
-               
+
        TIM16_CCER = TIM_CCER_CC1NE
                | TIM_CCER_CC1NP;
-       
+
        TIM16_ARR = 48; /* default */
        TIM16_CCR1 = 1; /*  */
 }
@@ -205,7 +274,7 @@ static void tim16_setup(void)
 static void tim16_set(int mode)
 {
        uint16_t cc_mode;
-       
+
        cc_mode = TIM_CCMR1_CC1S_OUT;
 
        TIM16_CR1 = TIM_CR1_OPM;
@@ -218,9 +287,9 @@ static void tim16_set(int mode)
                TIM16_ARR = mode;
                cc_mode |= TIM_CCMR1_OC1M_PWM2;
        }
-                       
+
        TIM16_CCMR1 = cc_mode;
-               
+
        if (mode > 0)
                TIM16_CR1 |= TIM_CR1_CEN;
 }
@@ -229,44 +298,44 @@ static void tim16_set(int mode)
 
 
 
-/* 
+/*
  * A0..A6, A8..A13 are buffered. No need to disable.
  * A7, A14..A18: set to input.
  */
+
 static void z80_setup_adrbus_tristate(void)
 {
 #if 0
        gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_INPUT,
                GPIO_CNF_INPUT_FLOAT, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT);
-       gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, 
+       gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
                (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT));
 #else
-       GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0))) 
+       GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0)))
                        | (CNF_MODE_I_F << (4 * 0));
        GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7))))
                        | ((CNF_MODE_I_F << (4 * 6)) | (CNF_MODE_I_F << (4 * 7)));
        GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4))))
                        | ((CNF_MODE_I_F << (4*2)) | (CNF_MODE_I_F << (4*3)) | (CNF_MODE_I_F << (4*4)));
-#endif 
+#endif
 }
 
-       
+
 static void z80_setup_adrbus_active(void)
 {
 #if 0
        gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_OUTPUT_10_MHZ,
                GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT);
-       gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, 
+       gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
                (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT));
 #else
-       GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0))) 
+       GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0)))
                        | (CNF_MODE_O_PP << (4 * 0));
        GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7))))
                        | ((CNF_MODE_O_PP << (4 * 6)) | (CNF_MODE_O_PP << (4 * 7)));
        GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4))))
                        | ((CNF_MODE_O_PP << (4*2)) | (CNF_MODE_O_PP << (4*3)) | (CNF_MODE_O_PP << (4*4)));
-#endif 
+#endif
 }
 
 
@@ -339,9 +408,9 @@ void z80_release_bus(void)
 void z80_reset(level_t level)
 {
        int x = level ? -1 : 0;
-       
+
        tim16_set(x);
-       
+
 //     Z80_O_RST = level;
 }
 
@@ -406,7 +475,7 @@ void z80_memset(uint32_t addr, uint8_t data, int length)
 void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
 {
        uint8_t data;
-       
+
        z80_setup_dbus_out();
        Z80_O_ME = 0;
        while(length--) {
@@ -425,7 +494,7 @@ void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
   017B'                         rx.out_idx:    ds      1               ;
   017C'                         rx.buf:                ds      rx.buf_len      ;
   018B'                         rx.buf_end     equ     $-1             ; last byte (start+len-1)
-                                
+
   018C'                         tx.bs_mask:    ds      1               ; (buf_len - 1)
   018D'                         tx.in_idx:     ds      1               ;
   018E'                         tx.out_idx:    ds      1               ;
@@ -433,63 +502,81 @@ void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
   019E'                         tx.buf_end     equ     $-1             ; last byte
 */
 
-#define fifo_bufsize_mask      -3
-#define fifo_index_in          -2
-#define fifo_index_out         -1
 
-#if 1
+typedef struct __attribute__((packed)) {
+       uint8_t mask;
+       uint8_t in_idx;
+       uint8_t out_idx;
+       uint8_t buf[];
+} zfifo_t;
+
+
+
+#define FIFO_BUFSIZE_MASK      -3
+#define FIFO_INDEX_IN          -2
+#define FIFO_INDEX_OUT         -1
+
 
 static struct {
        uint32_t base;
        uint8_t idx_out,
                idx_in,
                mask;
-       } fifo_dsc[2];
-       
-void z80_memfifo_init(void)
+       } fifo_dsc[NUM_FIFOS];
+
+
+void z80_memfifo_init(const fifo_t f, uint32_t adr)
 {
+
+DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
+
+       fifo_dsc[f].base = adr;
+
        z80_request_bus();
-       fifo_dsc[fifo_in].base = tx_fifo;
-       fifo_dsc[fifo_in].idx_out = z80_read(tx_fifo+fifo_index_out);
-       fifo_dsc[fifo_in].idx_in = z80_read(tx_fifo+fifo_index_in);
-       fifo_dsc[fifo_in].mask = z80_read(tx_fifo+fifo_bufsize_mask);
-
-       fifo_dsc[fifo_out].base = rx_fifo;
-       fifo_dsc[fifo_out].idx_out = z80_read(rx_fifo+fifo_index_out);
-       fifo_dsc[fifo_out].idx_in = z80_read(rx_fifo+fifo_index_in);
-       fifo_dsc[fifo_out].mask = z80_read(rx_fifo+fifo_bufsize_mask);
+
+       fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
+       fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
+       fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
+
        z80_release_bus();
 }
-#endif
 
-int z80_memfifo_is_empty(fifo_t f)
+
+int z80_memfifo_is_empty(const fifo_t f)
 {
-       uint32_t adr = fifo_dsc[f].base+fifo_index_in;
-       uint8_t idx;
-       
-       z80_request_bus();
-       idx = z80_read(adr);
-       z80_release_bus();
+       int rc = 1;
 
-       return idx == fifo_dsc[f].idx_out;
+       if (fifo_dsc[f].base != 0) {
+
+               uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
+               uint8_t idx;
+
+               z80_request_bus();
+               idx = z80_read(adr);
+               z80_release_bus();
+               rc = idx == fifo_dsc[f].idx_out;
+       }
+
+       return rc;
 }
 
-int z80_memfifo_is_full(fifo_t f)
+int z80_memfifo_is_full(const fifo_t f)
 {
-       int rc;
-       
-       z80_request_bus();
-       rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
-               == z80_read(fifo_dsc[f].base+fifo_index_out);
-       z80_release_bus();
-       
+       int rc = 1;
+
+       if (fifo_dsc[f].base != 0) {
+               z80_request_bus();
+               rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
+                       == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
+               z80_release_bus();
+       }
        return rc;
 }
 
-uint8_t z80_memfifo_getc(fifo_t f)
+uint8_t z80_memfifo_getc(const fifo_t f)
 {
        uint8_t rc, idx;
-       
+
        while (z80_memfifo_is_empty(f))
                ;
 
@@ -497,9 +584,9 @@ uint8_t z80_memfifo_getc(fifo_t f)
        idx = fifo_dsc[f].idx_out;
        rc = z80_read(fifo_dsc[f].base+idx);
        fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
-       z80_write(fifo_dsc[f].base+fifo_index_out, fifo_dsc[f].idx_out);
+       z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
        z80_release_bus();
-       
+
        return rc;
 }
 
@@ -507,7 +594,7 @@ uint8_t z80_memfifo_getc(fifo_t f)
 void z80_memfifo_putc(fifo_t f, uint8_t val)
 {
        int idx;
-       
+
        while (z80_memfifo_is_full(f))
                ;
 
@@ -515,23 +602,23 @@ void z80_memfifo_putc(fifo_t f, uint8_t val)
        idx = fifo_dsc[f].idx_in;
        z80_write(fifo_dsc[f].base+idx, val);
        fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
-       z80_write(fifo_dsc[f].base+fifo_index_in, fifo_dsc[f].idx_in);
+       z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
        z80_release_bus();
 }
 
 /*--------------------------------------------------------------------------*/
 
-//volatile uint8_t io_infifo[256];
-
 static struct {
-       uint8_t  idx_out,
-                idx_in;
+       uint32_t base;
+       //uint8_t  idx_out, idx_in;
        uint16_t count;
        uint8_t  buf[256];
-       } io_infifo;
+       } msg_fifo;
 
 /*--------------------------------------------------------------------------*/
 
+#if 0
+
 static void tim1_setup(void)
 {
        RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
@@ -556,6 +643,8 @@ static void tim1_setup(void)
        TIM1_SMCR |= TIM_SMCR_SMS_TM;
 }
 
+#endif
+
 /*--------------------------------------------------------------------------*/
 
 static void tim1_ch4_setup(void)
@@ -588,7 +677,7 @@ static void dma1_ch4_setup(void)
                | DMA_CCR_MINC
                | DMA_CCR_CIRC;
 
-       DMA1_CMAR4 = (uint32_t) io_infifo.buf;
+       DMA1_CMAR4 = (uint32_t) msg_fifo.buf;
 
 #if (DB_SHIFT == 0) || (DB_SHIFT == 8)
        DMA1_CPAR4 = DB_PORT + IDR + DB_SHIFT/8;
@@ -596,14 +685,17 @@ static void dma1_ch4_setup(void)
        #error "Databus not byte aligned!"
 #endif
 
-       DMA1_CNDTR4 = io_infifo.count = NELEMS(io_infifo.buf);
+       DMA1_CNDTR4 = NELEMS(msg_fifo.buf);
+//     msg_fifo.count = NELEMS(msg_fifo.buf);
+       msg_fifo.count = 0;
+       msg_fifo.base = 0;
 
        DMA1_CCR4 |= DMA_CCR_EN;
 }
 
 /*--------------------------------------------------------------------------*/
 
-void z80_setup_io_infifo(void)
+void z80_setup_msg_fifo(void)
 {
        gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
                GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
@@ -613,16 +705,33 @@ void z80_setup_io_infifo(void)
 }
 
 
-int z80_io_infifo_getc(void)
+void z80_init_msg_fifo(uint32_t addr)
+{
+
+DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
+
+       z80_request_bus();
+       z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
+       z80_release_bus();
+       msg_fifo.base = addr;
+}
+
+
+int z80_msg_fifo_getc(void)
 {
        int c = -1;
-       
-       if (io_infifo.count != DMA1_CNDTR4) {
-               c = io_infifo.buf[NELEMS(io_infifo.buf) - io_infifo.count--];
-               if (io_infifo.count == 0)
-                       io_infifo.count = NELEMS(io_infifo.buf);
+
+       if (msg_fifo.count != (NELEMS(msg_fifo.buf) - DMA1_CNDTR4)) {
+               c = msg_fifo.buf[msg_fifo.count];
+               if (++msg_fifo.count == NELEMS(msg_fifo.buf))
+                       msg_fifo.count = 0;
+
+               if (msg_fifo.base != 0) {
+                       z80_request_bus();
+                       z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
+                       z80_release_bus();
+               }
        }
 
        return c;
 }
-