diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.c b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.c index 1f09fa6..b1f15d7 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.c @@ -77,23 +77,24 @@ extern struct cfdriver rdfpga_sdcard_cd; static int rdfpga_sdcard_wait_dma_ready(struct rdfpga_sdcard_softc *sc, const int count); static int rdfpga_sdcard_wait_device_ready(struct rdfpga_sdcard_softc *sc, const int count); static int rdfpga_sdcard_read_block(struct rdfpga_sdcard_softc *sc, const u_int32_t block, void *data); +static int rdfpga_sdcard_write_block(struct rdfpga_sdcard_softc *sc, const u_int32_t block, void *data); struct rdfpga_sdcard_rb_32to512 { - union { - u_int32_t block; - u_int8_t data[512]; - } x; + u_int32_t block; + u_int8_t data[512]; }; -#define RDFPGA_SDCARD_RS _IOR(0, 1, u_int32_t) -#define RDFPGA_SDCARD_RSO _IOR(0, 3, u_int32_t) +#define RDFPGA_SDCARD_RS _IOR(0, 1, u_int32_t) +#define RDFPGA_SDCARD_RSO _IOR(0, 3, u_int32_t) #define RDFPGA_SDCARD_RSO2 _IOR(0, 4, u_int32_t) #define RDFPGA_SDCARD_RSO3 _IOR(0, 5, u_int32_t) #define RDFPGA_SDCARD_RSTC _IOR(0, 6, u_int32_t) #define RDFPGA_SDCARD_RSTD _IOR(0, 7, u_int32_t) -#define RDFPGA_SDCARD_RSD _IOR(0, 8, u_int32_t) +#define RDFPGA_SDCARD_RSD _IOR(0, 8, u_int32_t) #define RDFPGA_SDCARD_RSD2 _IOR(0, 9, u_int32_t) -#define RDFPGA_SDCARD_RB _IOWR(0, 2, struct rdfpga_sdcard_rb_32to512) +#define RDFPGA_SDCARD_RB _IOWR(0, 2, struct rdfpga_sdcard_rb_32to512) +#define RDFPGA_SDCARD_WB _IOW(0, 10, struct rdfpga_sdcard_rb_32to512) +#define RDFPGA_SDCARD_RSTD2 _IOR(0, 11, u_int32_t) int rdfpga_sdcard_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) @@ -128,10 +129,20 @@ rdfpga_sdcard_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) *((u_int32_t*)data) = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMAW_CTRL); bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMAW_CTRL, 0); break; + case RDFPGA_SDCARD_RSTD2: + *((u_int32_t*)data) = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMA_CTRL); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMA_CTRL, 0); + break; case RDFPGA_SDCARD_RB: { struct rdfpga_sdcard_rb_32to512* u = data; - err = rdfpga_sdcard_read_block(sc, u->x.block, u->x.data); + err = rdfpga_sdcard_read_block(sc, u->block, u->data); + break; + } + case RDFPGA_SDCARD_WB: + { + struct rdfpga_sdcard_rb_32to512* u = data; + err = rdfpga_sdcard_write_block(sc, u->block, u->data); break; } default: @@ -228,7 +239,10 @@ rdfpga_sdcard_attach(device_t parent, device_t self, void *aux) } else { aprint_normal_dev(self, "dmamap: %lu %lu %d (%p)\n", sc->sc_dmamap->dm_maxsegsz, sc->sc_dmamap->dm_mapsize, sc->sc_dmamap->dm_nsegs, sc->sc_dmatag->_dmamap_load); } - + + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_CTRL, 0); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMAW_CTRL, 0); + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMA_CTRL, 0); } static int rdfpga_sdcard_wait_dma_ready(struct rdfpga_sdcard_softc *sc, const int count) { @@ -242,6 +256,16 @@ static int rdfpga_sdcard_wait_dma_ready(struct rdfpga_sdcard_softc *sc, const in ctr ++; } + if (ctrl) + return EBUSY; + + ctr = 0; + while (((ctrl = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMA_CTRL)) != 0) && + (ctr < count)) { + delay(1); + ctr ++; + } + if (ctrl) return EBUSY; @@ -262,9 +286,9 @@ static int rdfpga_sdcard_wait_device_ready(struct rdfpga_sdcard_softc *sc, const ctr ++; } - aprint_normal_dev(sc->sc_dev, "ctrl is 0x%08x (%d, old status 0x%08x, current 0x%08x)\n", ctrl, ctr, - bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_STATUS_OLD), - bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_STATUS)); + /* aprint_normal_dev(sc->sc_dev, "ctrl is 0x%08x (%d, old status 0x%08x, current 0x%08x)\n", ctrl, ctr, */ + /* bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_STATUS_OLD), */ + /* bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_STATUS)); */ if (ctrl) @@ -292,7 +316,7 @@ static int rdfpga_sdcard_read_block(struct rdfpga_sdcard_softc *sc, const u_int3 } /* for testing only, remove */ - memcpy(kvap, data, 512); + //memcpy(kvap, data, 512); if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, kvap, RDFPGA_SDCARD_VAL_DMA_MAX_SZ, /* kernel space */ NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_READ)) { @@ -328,3 +352,59 @@ static int rdfpga_sdcard_read_block(struct rdfpga_sdcard_softc *sc, const u_int3 return res; } + + +static int rdfpga_sdcard_write_block(struct rdfpga_sdcard_softc *sc, const u_int32_t block, void *data) { + int res = 0; + u_int32_t ctrl; + if ((res = rdfpga_sdcard_wait_device_ready(sc, 50000)) != 0) + return res; + + if (bus_dmamem_alloc(sc->sc_dmatag, RDFPGA_SDCARD_VAL_DMA_MAX_SZ, 64, 64, &sc->sc_segs, 1, &sc->sc_rsegs, BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) { + aprint_error_dev(sc->sc_dev, "cannot allocate DVMA memory"); + return ENXIO; + } + + void* kvap; + if (bus_dmamem_map(sc->sc_dmatag, &sc->sc_segs, 1, RDFPGA_SDCARD_VAL_DMA_MAX_SZ, &kvap, BUS_DMA_NOWAIT)) { + aprint_error_dev(sc->sc_dev, "cannot allocate DVMA address"); + bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1); + return ENXIO; + } + + memcpy(kvap, data, 512); + + if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, kvap, RDFPGA_SDCARD_VAL_DMA_MAX_SZ, /* kernel space */ NULL, + BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) { + aprint_error_dev(sc->sc_dev, "cannot load dma map"); + bus_dmamem_unmap(sc->sc_dmatag, kvap, RDFPGA_SDCARD_VAL_DMA_MAX_SZ); + bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1); + return ENXIO; + } + + bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 512, BUS_DMASYNC_PREWRITE); + + /* set DMA address */ + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_DMA_ADDR, (uint32_t)(sc->sc_dmamap->dm_segs[0].ds_addr)); + /* set block to read */ + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_ADDR, block); + ctrl = RDFPGA_SDCARD_CTRL_START; + /* initiate reading block from SDcard; once the read request is acknowledged, the HW will start the DMA engine */ + bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_SDCARD_REG_CTRL, ctrl); + + res = rdfpga_sdcard_wait_device_ready(sc, 100000); + + bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, 512, BUS_DMASYNC_POSTWRITE); + + bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); + /* aprint_normal_dev(sc->sc_dev, "dma: unloaded\n"); */ + + //memcpy(data, kvap, 512); + + bus_dmamem_unmap(sc->sc_dmatag, kvap, RDFPGA_SDCARD_VAL_DMA_MAX_SZ); + /* aprint_normal_dev(sc->sc_dev, "dma: unmapped\n"); */ + + bus_dmamem_free(sc->sc_dmatag, &sc->sc_segs, 1); + + return res; +} diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.h b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.h index 0d28124..2efee51 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.h +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga_sdcard.h @@ -57,7 +57,8 @@ struct rdfpga_sdcard_softc { #define RDFPGA_SDCARD_REG_STATUS_OLD3 (RDFPGA_SDCARD_REG_BASE + 0x1c) #define RDFPGA_SDCARD_REG_STATUS_DAT (RDFPGA_SDCARD_REG_BASE + 0x20) #define RDFPGA_SDCARD_REG_STATUS_DAT2 (RDFPGA_SDCARD_REG_BASE + 0x24) -/* nothing 0x18 - 0x3c ; DATA* not used directly */ +#define RDFPGA_SDCARD_REG_DMA_ADDR (RDFPGA_SDCARD_REG_BASE + 0x28) +#define RDFPGA_SDCARD_REG_DMA_CTRL (RDFPGA_SDCARD_REG_BASE + 0x2c) #define RDFPGA_SDCARD_CTRL_START 0x80000000 diff --git a/sbus-to-ztex-gateware/sbus_fsm.vhd b/sbus-to-ztex-gateware/sbus_fsm.vhd index 946c735..d8e7a57 100644 --- a/sbus-to-ztex-gateware/sbus_fsm.vhd +++ b/sbus-to-ztex-gateware/sbus_fsm.vhd @@ -166,6 +166,8 @@ ENTITY SBusFSM is CONSTANT REG_INDEX_SD_STATUS_OLD3: integer := 7; CONSTANT REG_INDEX_SD_STATUS_DAT : integer := 8; CONSTANT REG_INDEX_SD_STATUS_DAT2 : integer := 9; + CONSTANT REG_INDEX_SDDMA_ADDR : integer := 10; + CONSTANT REG_INDEX_SDDMA_CTRL : integer := 11; CONSTANT REG_INDEX_SDDMAW_DATA1 : integer := 16; CONSTANT REG_INDEX_SDDMAW_DATA2 : integer := 17; CONSTANT REG_INDEX_SDDMAW_DATA3 : integer := 18; @@ -351,9 +353,16 @@ ARCHITECTURE RTL OF SBusFSM IS signal fifo_fromsdcard_full : STD_LOGIC; signal fifo_fromsdcard_empty : STD_LOGIC; + signal fifo_tosdcard_din : STD_LOGIC_VECTOR ( 127 downto 0 ); + signal fifo_tosdcard_wr_en : STD_LOGIC; + signal fifo_tosdcard_rd_en : STD_LOGIC; + signal fifo_tosdcard_dout : STD_LOGIC_VECTOR ( 127 downto 0 ); + signal fifo_tosdcard_full : STD_LOGIC; + signal fifo_tosdcard_empty : STD_LOGIC; + signal out_sd_rd_addr_fast : std_logic_vector(32 downto 0); -- rd and address signal combined signal out_sd_rd_addr : std_logic_vector(32 downto 0); -- rd and address signal combined - signal out_sd_rd_addr_send : STD_LOGIC; + signal out_sd_rd_addr_send : STD_LOGIC := '0'; signal out_sd_rd_addr_rcv : STD_LOGIC; signal out_sd_rd_addr_req : STD_LOGIC; signal out_sd_rd_addr_ack : STD_LOGIC; @@ -645,6 +654,21 @@ ARCHITECTURE RTL OF SBusFSM IS rd_rst_busy : out STD_LOGIC ); end component; + component fifo_generator_to_sdcard is + Port ( + rst : in STD_LOGIC; + wr_clk : in STD_LOGIC; + rd_clk : in STD_LOGIC; + din : in STD_LOGIC_VECTOR(127 DOWNTO 0); + wr_en : in STD_LOGIC; + rd_en : in STD_LOGIC; + dout : out STD_LOGIC_VECTOR(127 DOWNTO 0); + full : out STD_LOGIC; + empty : out STD_LOGIC; + wr_rst_busy : out STD_LOGIC; + rd_rst_busy : out STD_LOGIC + ); + end component; component uart_tx is generic ( @@ -713,6 +737,9 @@ ARCHITECTURE RTL OF SBusFSM IS output_fifo_in : out std_logic_vector(160 downto 0); output_fifo_full : in std_logic; output_fifo_wr_en : out std_logic; + input_fifo_out : in std_logic_vector(127 downto 0); + input_fifo_empty : in std_logic; + input_fifo_rd_en : out std_logic; out_sd_rd : in std_logic; out_sd_addr : in std_logic_vector(31 downto 0); out_sd_rd_addr_req : in std_logic; @@ -813,6 +840,12 @@ BEGIN din => fifo_fromsdcard_din, wr_en => fifo_fromsdcard_wr_en, rd_en => fifo_fromsdcard_rd_en, dout => fifo_fromsdcard_dout, full => fifo_fromsdcard_full, empty => fifo_fromsdcard_empty, wr_rst_busy => open, rd_rst_busy => open); + label_fifo_tosdcard: fifo_generator_to_sdcard port map(rst => fifo_rst, + wr_clk => SBUS_3V3_CLK, + rd_clk => fast_100m_clk_out, + din => fifo_tosdcard_din, wr_en => fifo_tosdcard_wr_en, rd_en => fifo_tosdcard_rd_en, + dout => fifo_tosdcard_dout, full => fifo_tosdcard_full, empty => fifo_tosdcard_empty, + wr_rst_busy => open, rd_rst_busy => open); label_aes_wrapper: aes_wrapper port map( aes_wrapper_rst => fast_clk_rst_n, aes_wrapper_clk => fast_100m_clk_out, @@ -845,6 +878,9 @@ BEGIN output_fifo_in => fifo_fromsdcard_din, output_fifo_full => fifo_fromsdcard_full, output_fifo_wr_en => fifo_fromsdcard_wr_en, + input_fifo_out => fifo_tosdcard_dout, + input_fifo_empty => fifo_tosdcard_empty, + input_fifo_rd_en => fifo_tosdcard_rd_en, out_sd_rd => out_sd_rd_addr_fast(32), out_sd_addr => out_sd_rd_addr_fast(31 downto 0), out_sd_rd_addr_req => out_sd_rd_addr_req, @@ -923,6 +959,7 @@ BEGIN variable dma_addr_idx : integer range 0 to 191; variable dma_basereg_idx : integer range 0 to 191; variable reg_bank : integer range 0 to 2 := 0; + variable sdcard_deadbeef_counter : integer range 0 to 65535 := 0; BEGIN IF (SBUS_3V3_RSTs = '0') THEN State <= SBus_Start; @@ -935,6 +972,7 @@ BEGIN fifo_fromaes_rd_en <= '0'; fifo_fromstrng_rd_en <= '0'; fifo_fromsdcard_rd_en <= '0'; + fifo_tosdcard_wr_en <= '0'; -- LIFE_COUNTER25 <= LIFE_COUNTER25 - 1; CASE State IS @@ -1094,7 +1132,10 @@ BEGIN REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_AESDMAW_CTRL)(DMA_CTRL_ERR_IDX)='0') OR (REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL)(DMA_CTRL_START_IDX)='1' AND REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL)(DMA_CTRL_BUSY_IDX)='0' AND - REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL)(DMA_CTRL_ERR_IDX)='0') + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL)(DMA_CTRL_ERR_IDX)='0') OR + (REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL)(DMA_CTRL_START_IDX)='1' AND + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL)(DMA_CTRL_BUSY_IDX)='0' AND + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL)(DMA_CTRL_ERR_IDX)='0') )) then -- we have a DMA request pending and not been granted the bus IF ((REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_GCMDMA_CTRL)(DMA_CTRL_START_IDX) = '1') OR @@ -1106,8 +1147,9 @@ BEGIN (fifo_fromaes_empty = '0')) OR ((REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL)(DMA_CTRL_START_IDX) = '1') AND (fifo_fromsdcard_empty = '0') AND - (fifo_fromsdcard_dout(160) = '0') - ) + (fifo_fromsdcard_dout(160) = '0')) OR + ((REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL)(DMA_CTRL_START_IDX) = '1') AND + (fifo_tosdcard_full = '0')) ) THEN fifo_wr_en <= '1'; fifo_din <= x"61"; -- "a" -- GCM is always available (1 cycle) @@ -1156,6 +1198,15 @@ BEGIN REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_DATA4) <= fifo_fromsdcard_dout( 31 downto 0); fifo_fromsdcard_rd_en <= '1'; State <= SBus_Master_Translation; + ELSIF ((REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL)(DMA_CTRL_START_IDX) = '1') AND + (fifo_tosdcard_full = '0')) THEN + dma_write := false; + dma_ctrl_idx := reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL; + dma_addr_idx := reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_ADDR; + dma_basereg_idx := reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_DATA1; -- fixme + BUF_DATA_O <= REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_ADDR); -- virt address + BUF_PPRD_O <= '1'; -- reading from slave + State <= SBus_Master_Translation; ELSIF ((REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_AESDMA_CTRL)(DMA_CTRL_START_IDX) = '1') AND (fifo_fromaes_full = '0')) THEN dma_write := false; @@ -1426,9 +1477,9 @@ BEGIN when SBus_Master_Read_Ack => fifo_wr_en <= '1'; fifo_din <= x"65"; -- "e" + REGISTERS(dma_basereg_idx + (BURST_COUNTER mod 4)) <= BUF_DATA_I; + BURST_COUNTER := BURST_COUNTER + 1; IF (dma_ctrl_idx = REG_INDEX_GCMDMA_CTRL) THEN - REGISTERS(dma_basereg_idx + (BURST_COUNTER mod 4)) <= BUF_DATA_I; - BURST_COUNTER := BURST_COUNTER + 1; IF (finish_gcm) THEN finish_gcm := false; REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_GCM_C1) <= reverse_bit_in_byte(mas_c(31 downto 0)); @@ -1447,8 +1498,6 @@ BEGIN finish_gcm := true; END IF; ELSIF (dma_ctrl_idx = REG_INDEX_AESDMA_CTRL) THEN - REGISTERS(dma_basereg_idx + (BURST_COUNTER mod 4)) <= BUF_DATA_I; - BURST_COUNTER := BURST_COUNTER + 1; IF (BURST_COUNTER mod 4 = 0) THEN -- REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_AES128_CTRL) <= x"88000000"; -- request to start a CBC block -- enqueue the block in the AES FIFO @@ -1479,7 +1528,15 @@ BEGIN REGISTERS(dma_ctrl_idx)(DMA_CTRL_CBC_IDX) <= '0'; END IF; END IF; - END IF; -- GCM | AES + ELSIF (dma_ctrl_idx = (reg_bank_size*reg_bank_crypto_idx + REG_INDEX_SDDMA_CTRL)) THEN + IF (BURST_COUNTER mod 4 = 0) THEN + fifo_tosdcard_wr_en <= '1'; + fifo_tosdcard_din <= REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_DATA1) & -- fixme + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_DATA2) & + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_DATA3) & + BUF_DATA_I; + END IF; + END IF; -- GCM | AES | SD if (BURST_COUNTER = BURST_LIMIT) THEN State <= SBus_Master_Read_Finish; ELSIF (BUF_ACKs_I = ACK_WORD) THEN @@ -1583,7 +1640,15 @@ BEGIN REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_AESDMA_CTRL) <= (others => '0'); REGISTERS(reg_bank_size*reg_bank_crypto_idx + REG_INDEX_AESDMAW_CTRL) <= (others => '0'); REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_OLD) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_OLD2) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_OLD3) <= (others => '0'); + out_sd_rd_addr_send <= '0'; IF (RES_COUNTER = 0) THEN + fifo_rst <= '0'; -- fifo_wr_en <= '1'; fifo_din <= x"2A"; -- "*" State <= SBus_Idle; ELSE @@ -1687,6 +1752,10 @@ BEGIN -- fixme REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL) <= x"00000000"; END IF; + IF (fifo_fromsdcard_dout(159 downto 144) = x"1001") THEN + -- fixme + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL) <= x"00000000"; + END IF; elsif (fifo_fromsdcard_dout(160) = '0') THEN -- status indicating last stuff out of the FIFO was valid data -- indicative, does not remove word from FIFO @@ -1721,14 +1790,40 @@ BEGIN REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL)(SD_CTRL_SENT_IDX) <= '1'; out_sd_rd_addr <= '1' & REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_ADDR); out_sd_rd_addr_send <= '1'; + ELSE + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL)(SD_CTRL_START_IDX) <= '0'; + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL)(SD_CTRL_SENT_IDX) <= '1'; + out_sd_rd_addr <= '0' & REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_ADDR); + out_sd_rd_addr_send <= '1'; END IF; + sdcard_deadbeef_counter := 0; END IF; IF (REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL)(SD_CTRL_SENT_IDX) = '1') THEN IF (out_sd_rd_addr_rcv = '1') THEN out_sd_rd_addr_send <= '0'; - REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL) <= x"8000001F"; -- write 32 block (16 * 32 = 512 bytes) + IF (REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL)(SD_CTRL_READ_IDX) = '1') THEN + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL) <= x"8000001F"; -- write 32 block (16 * 32 = 512 bytes) to memory + ELSE + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL) <= x"8000001F"; -- read 32 block (16 * 32 = 512 bytes) to memory + END IF; REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL) <= (others => '0'); END IF; + IF (sdcard_deadbeef_counter = 255) THEN + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT) <= x"C0FFEE00"; + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT2) <= x"0000" & conv_std_logic_vector(sdcard_deadbeef_counter, 16); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_CTRL) <= (others => '0'); + END IF; + sdcard_deadbeef_counter := sdcard_deadbeef_counter + 1; + END IF; + if ((fifo_fromsdcard_full = '1') AND (fifo_fromsdcard_empty = '1')) THEN + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMAW_CTRL) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SDDMA_CTRL) <= (others => '0'); + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT) <= x"DEADBEEF"; + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT2) <= x"C000" & conv_std_logic_vector(sdcard_deadbeef_counter, 16); + sdcard_deadbeef_counter := sdcard_deadbeef_counter + 1; + ELSIF (REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT) = x"DEADBEEF") THEN + REGISTERS(reg_bank_size*reg_bank_sdcard_idx + REG_INDEX_SD_STATUS_DAT2) <= + fifo_fromsdcard_full & fifo_fromsdcard_empty & '0' & '0' & x"000" & conv_std_logic_vector(sdcard_deadbeef_counter, 16); END IF; END IF; diff --git a/sbus-to-ztex-gateware/xess_sdcard_wrapper.vhd b/sbus-to-ztex-gateware/xess_sdcard_wrapper.vhd index a2b1e6e..96c7d5e 100644 --- a/sbus-to-ztex-gateware/xess_sdcard_wrapper.vhd +++ b/sbus-to-ztex-gateware/xess_sdcard_wrapper.vhd @@ -14,6 +14,9 @@ entity xess_sdcard_wrapper is output_fifo_in : out std_logic_vector(160 downto 0); --1+ 32 +128 output_fifo_full : in std_logic; output_fifo_wr_en : out std_logic; + input_fifo_out : in std_logic_vector(127 downto 0); + input_fifo_empty : in std_logic; + input_fifo_rd_en : out std_logic; out_sd_rd : in std_logic; out_sd_addr : in std_logic_vector(31 downto 0); out_sd_rd_addr_req : in std_logic; @@ -81,7 +84,10 @@ architecture RTL of xess_sdcard_wrapper is XESS_SDCARD_READ_WAIT_BUSY, XESS_SDCARD_READ_WAIT_READ, XESS_SDCARD_READ_WAIT_READ2, - XESS_SDCARD_READ_WAIT_NOTBUSY); + XESS_SDCARD_WAIT_NOTBUSY, + XESS_SDCARD_WRITE_WAIT_BUSY, + XESS_SDCARD_WRITE_WAIT_WRITE, + XESS_SDCARD_WRITE_WAIT_WRITE2); SIGNAL XESS_SDCARD_State : XESS_SDCARD_States := XESS_SDCARD_INIT; begin @@ -113,7 +119,8 @@ begin xess_sdcard_wrapper: process (xess_sdcard_wrapper_rst, xess_sdcard_wrapper_clk) variable init_done : boolean := false; - variable timeout_counter : natural range 0 to 100000 := 0; + constant TIMEOUT_MAX : integer := 1000000; + variable timeout_counter : natural range 0 to TIMEOUT_MAX := 0; variable timedout : std_logic_vector(15 downto 0) := x"0000"; variable byte_counter : natural range 0 to BLOCK_SIZE_G := 0; -- fixme, wasteful variable databuf : std_logic_vector(127 downto 0); @@ -127,14 +134,16 @@ begin XESS_SDCARD_State <= XESS_SDCARD_INIT; timedout := x"0000"; byte_counter := 0; - timeout_counter := 100000; + timeout_counter := TIMEOUT_MAX; init_done := false; buf_counter := 0; -- end if; ELSIF RISING_EDGE(xess_sdcard_wrapper_clk) then sd_reset <= '0'; + leds <= x"EE"; output_fifo_wr_en <= '0'; + input_fifo_rd_en <= '0'; if (out_sd_rd_addr_req = '0') THEN out_sd_rd_addr_ack <= '0'; END IF; @@ -150,19 +159,23 @@ begin --output_fifo_in <= '1' & x"6000" & sd_error & x"00000000000000000000000000000000"; --output_fifo_wr_en <= '1'; sd_rd <= '1'; - sd_addr <= out_sd_addr; -last_addr := out_sd_addr; - byte_counter := 0; - buf_counter := 0; - timeout_counter := 100000; XESS_SDCARD_State <= XESS_SDCARD_READ_WAIT_BUSY; + ELSE + sd_wr <= '1'; + XESS_SDCARD_State <= XESS_SDCARD_WRITE_WAIT_BUSY; END IF; + + sd_addr <= out_sd_addr; +last_addr := out_sd_addr; + byte_counter := 0; + buf_counter := 0; + timeout_counter := TIMEOUT_MAX; END IF; -- if (timeout_counter = 0) then -- output_fifo_in <= (NOT timedout) & sd_error; -- output_fifo_wr_en <= '1'; -- timedout := conv_std_logic_vector(conv_integer(timedout)+1,16); --- timeout_counter := 100000; +-- timeout_counter := TIMEOUT_MAX; -- else -- timeout_counter := timeout_counter - 1; -- end if; @@ -188,7 +201,7 @@ output_fifo_wr_en <= '1'; output_fifo_in <= '1' & x"F" & timedout(11 downto 0) & sd_error & x"00000000000000000000000000000000"; output_fifo_wr_en <= '1'; timedout := conv_std_logic_vector(conv_integer(timedout)+1,16); - timeout_counter := 100000; + timeout_counter := TIMEOUT_MAX; else timeout_counter := timeout_counter - 1; end IF; @@ -198,14 +211,15 @@ output_fifo_wr_en <= '1'; IF (sd_busy = '1') THEN --output_fifo_in <= '1' & x"5000" & sd_error & x"00000000000000000000000000000000"; --output_fifo_wr_en <= '1'; - sd_rd <= '0'; - sd_addr <= (others => '0'); - XESS_SDCARD_State <= XESS_SDCARD_READ_WAIT_READ; - elsif (timeout_counter = 0) then + sd_rd <= '0'; + sd_addr <= (others => '0'); + XESS_SDCARD_State <= XESS_SDCARD_READ_WAIT_READ; + timeout_counter := TIMEOUT_MAX; + elsif (timeout_counter = 0) then output_fifo_in <= '1' & x"E" & timedout(11 downto 0) & sd_error & x"00000000000000000000000000000000"; output_fifo_wr_en <= '1'; timedout := conv_std_logic_vector(conv_integer(timedout)+1,16); - timeout_counter := 100000; + timeout_counter := TIMEOUT_MAX; else timeout_counter := timeout_counter - 1; END IF; @@ -220,6 +234,12 @@ output_fifo_wr_en <= '1'; sd_hndshk_i <= '1'; byte_counter := byte_counter + 1; XESS_SDCARD_State <= XESS_SDCARD_READ_WAIT_READ2; + ELSIF ((output_fifo_full = '0') AND (timeout_counter = 0)) THEN +output_fifo_in <= '1' & x"1100" & sd_error & x"00000000000000000000000000000000"; +output_fifo_wr_en <= '1'; + XESS_SDCARD_State <= XESS_SDCARD_IDLE; + ELSIF (output_fifo_full = '0') THEN + timeout_counter := timeout_counter - 1; ELSIF (sd_busy = '0') THEN output_fifo_in <= '1' & x"1000" & sd_error & x"00000000000000000000000000000000"; output_fifo_wr_en <= '1'; @@ -238,14 +258,14 @@ output_fifo_wr_en <= '1'; buf_counter := buf_counter + 1; END IF; IF (byte_counter = BLOCK_SIZE_G) THEN - timeout_counter := 100000; - XESS_SDCARD_State <= XESS_SDCARD_READ_WAIT_NOTBUSY; + timeout_counter := TIMEOUT_MAX; + XESS_SDCARD_State <= XESS_SDCARD_WAIT_NOTBUSY; ELSE XESS_SDCARD_State <= XESS_SDCARD_READ_WAIT_READ; END IF; END IF; - when XESS_SDCARD_READ_WAIT_NOTBUSY => + when XESS_SDCARD_WAIT_NOTBUSY => leds <= x"04"; IF (sd_busy = '0') THEN XESS_SDCARD_State <= XESS_SDCARD_IDLE; @@ -253,10 +273,70 @@ output_fifo_wr_en <= '1'; output_fifo_in <= '1' & x"D" & timedout(11 downto 0) & sd_error & x"00000000000000000000000000000000"; output_fifo_wr_en <= '1'; timedout := conv_std_logic_vector(conv_integer(timedout)+1,16); - timeout_counter := 100000; + timeout_counter := TIMEOUT_MAX; else timeout_counter := timeout_counter - 1; END IF; + + + when XESS_SDCARD_WRITE_WAIT_BUSY => + leds <= x"03"; + IF (sd_busy = '1') THEN +--output_fifo_in <= '1' & x"5000" & sd_error & x"00000000000000000000000000000000"; +--output_fifo_wr_en <= '1'; + sd_wr <= '0'; + sd_addr <= (others => '0'); + XESS_SDCARD_State <= XESS_SDCARD_WRITE_WAIT_WRITE; + timeout_counter := TIMEOUT_MAX; + elsif (timeout_counter = 0) then +output_fifo_in <= '1' & x"C" & timedout(11 downto 0) & sd_error & x"00000000000000000000000000000000"; +output_fifo_wr_en <= '1'; + timedout := conv_std_logic_vector(conv_integer(timedout)+1,16); + timeout_counter := TIMEOUT_MAX; + else + timeout_counter := timeout_counter - 1; + END IF; + + when XESS_SDCARD_WRITE_WAIT_WRITE => + leds <= x"1c"; + --only write byte if we have some space to output the buffer + IF ((sd_hndshk_o = '1') AND + ((input_fifo_empty = '0') OR ((byte_counter mod 16) /= 0))) THEN +--output_fifo_in <= '1' & x"40" & sd_data_o & conv_std_logic_vector(byte_counter,16) & x"00000000000000000000000000000000"; +--output_fifo_wr_en <= '1'; + IF ((byte_counter mod 16) = 0) THEN + databuf := input_fifo_out; + input_fifo_rd_en <= '1'; + END IF; + sd_data_i <= databuf(((15 - (byte_counter mod 16))*8 + 7) downto ((15 - (byte_counter mod 16))*8)); + sd_hndshk_i <= '1'; + byte_counter := byte_counter + 1; + XESS_SDCARD_State <= XESS_SDCARD_WRITE_WAIT_WRITE2; + ELSIF ((input_fifo_empty = '0') AND (timeout_counter = 0)) THEN +output_fifo_in <= '1' & x"1101" & sd_error & x"00000000000000000000000000000000"; +output_fifo_wr_en <= '1'; + XESS_SDCARD_State <= XESS_SDCARD_IDLE; + ELSIF (input_fifo_empty = '0') THEN + timeout_counter := timeout_counter - 1; + ELSIF (sd_busy = '0') THEN +output_fifo_in <= '1' & x"1001" & sd_error & x"00000000000000000000000000000000"; +output_fifo_wr_en <= '1'; + XESS_SDCARD_State <= XESS_SDCARD_IDLE; + END IF; + + when XESS_SDCARD_WRITE_WAIT_WRITE2 => + leds <= x"2c"; + IF (sd_hndshk_o = '0') THEN +--output_fifo_in <= '1' & x"3000" & sd_error & x"00000000000000000000000000000000"; +--output_fifo_wr_en <= '1'; + sd_hndshk_i <= '0'; + IF (byte_counter = BLOCK_SIZE_G) THEN + timeout_counter := TIMEOUT_MAX; + XESS_SDCARD_State <= XESS_SDCARD_WAIT_NOTBUSY; + ELSE + XESS_SDCARD_State <= XESS_SDCARD_WRITE_WAIT_WRITE; + END IF; + END IF; end case; end IF;