mirror of
https://github.com/polpo/picogus.git
synced 2026-10-25 21:40:16 +00:00
PIO for DMA
This commit is contained in:
1 parent
f601c96384
commit
88164720ab
7 files changed
+93
-41
No files matched your search
Binary file not shown.
+1
-1
@@ -76,7 +76,7 @@ pico_enable_stdio_uart(sw-pico 1)
|
||||
pico_enable_stdio_usb(sw-pico 0)
|
||||
pico_enable_stdio_semihosting(sw-pico 0)
|
||||
|
||||
pico_generate_pio_header(sw-pico ${CMAKE_CURRENT_LIST_DIR}/io.pio)
|
||||
pico_generate_pio_header(sw-pico ${CMAKE_CURRENT_LIST_DIR}/isa_io.pio)
|
||||
|
||||
add_subdirectory(stdio_async_uart)
|
||||
|
||||
|
||||
+6
-6
@@ -2006,12 +2006,12 @@ __force_inline void write_gus(Bitu port,Bitu val,Bitu iolen) {
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // TODO implement DMA
|
||||
static Bitu GUS_Master_Clock = 617400; /* NOTE: This is 1000000Hz / 1.619695497. Seems to be a common base rate within the hardware. */
|
||||
static Bitu GUS_DMA_Event_transfer = 16; /* DMA words (8 or 16-bit) per interval */
|
||||
static Bitu GUS_DMA_Events_per_sec = 44100 / 4; /* cheat a little, to improve emulation performance */
|
||||
static double GUS_DMA_Event_interval = 1000.0 / GUS_DMA_Events_per_sec;
|
||||
static double GUS_DMA_Event_interval_init = 1000.0 / 44100;
|
||||
//#if 0 // TODO implement DMA
|
||||
static constexpr Bitu GUS_Master_Clock = 617400; /* NOTE: This is 1000000Hz / 1.619695497. Seems to be a common base rate within the hardware. */
|
||||
static constexpr Bitu GUS_DMA_Event_transfer = 16; /* DMA words (8 or 16-bit) per interval */
|
||||
static constexpr Bitu GUS_DMA_Events_per_sec = 44100 / 4; /* cheat a little, to improve emulation performance */
|
||||
static constexpr uint32_t GUS_DMA_Event_interval = 1000.0 / GUS_DMA_Events_per_sec;
|
||||
static constexpr uint32_t GUS_DMA_Event_interval_init = 1 / 44100;
|
||||
static bool GUS_DMA_Active = false;
|
||||
|
||||
void GUS_Update_DMA_Event_transfer() {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
.define public AD0_PIN 6
|
||||
.define public IRQ_PIN 19
|
||||
.define public IOW_PIN 4
|
||||
.define public IOR_PIN 5
|
||||
.define public IOCHRDY_PIN 26
|
||||
.define public ADS_PIN 27
|
||||
.define public BUSOE_PIN 28
|
||||
.define public DACK_PIN 20
|
||||
.define public DRQ_PIN 21
|
||||
.define public TC_PIN 22
|
||||
|
||||
.program dma_write
|
||||
.side_set 2 ; sideset bit 1 is ADS, bit 0 is IOCHRDY
|
||||
restart:
|
||||
out null, 32 side 0b01 ; wait to trigger DMA operation
|
||||
dmaloop:
|
||||
set pins, 1 side 0b11 ; assert DRQ
|
||||
wait 0 gpio DACK_PIN side 0b11 ; DACK faling edge
|
||||
set pins, 0 side 0b11 ; deassert DRQ
|
||||
wait 0 gpio IOW_PIN side 0b11 ; wait for IOW assert
|
||||
in pins, 8 side 0b10 ; input data, deassert IOCHRDY if we stall on full FIFO
|
||||
wait 1 gpio IOW_PIN side 0b11 ; wait for IOW deassert with IOCHRDY back high
|
||||
jmp pin restart side 0b01 ; if TC high, transfer is over. set ADS back to addr
|
||||
jmp dmaloop side 0b11 ; else wait for more data and get ADS back to data
|
||||
|
||||
% c-sdk {
|
||||
static inline void dma_write_program_init(PIO pio, uint sm, uint offset) {
|
||||
pio_sm_config c = dma_write_program_get_default_config(offset);
|
||||
|
||||
// Set up AD0 bus as input
|
||||
sm_config_set_in_pins(&c, AD0_PIN);
|
||||
// Autopush at 8 bits
|
||||
sm_config_set_in_shift(&c, false, true, 8);
|
||||
|
||||
// Autopull 32 bits (condition variables)
|
||||
sm_config_set_out_shift(&c, true, true /* autopull */, 32);
|
||||
|
||||
// Set the pin direction for IOW and AD0 bus as input at the PIO
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, IOW_PIN, 1, false);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, AD0_PIN, 8, false);
|
||||
|
||||
sm_config_set_jmp_pin(&c, TC_PIN);
|
||||
|
||||
// set up IOCHRDY and ADS
|
||||
sm_config_set_set_pins(&c, DRQ_PIN, 1);
|
||||
pio_gpio_init(pio, IOCHRDY_PIN);
|
||||
pio_gpio_init(pio, ADS_PIN);
|
||||
pio_gpio_init(pio, DRQ_PIN);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, IOCHRDY_PIN, 2, true);
|
||||
|
||||
// Load our configuration, and jump to the start of the program
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
// Set the state machine running
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
%}
|
||||
|
||||
+23
-30
@@ -1,44 +1,36 @@
|
||||
.define public AD0_PIN 6
|
||||
.define public IRQ_PIN 19
|
||||
.define public IOW_PIN 4 ; was 20
|
||||
.define public IOR_PIN 5 ; was 21
|
||||
.define public IOW_PIN 4
|
||||
.define public IOR_PIN 5
|
||||
.define public IOCHRDY_PIN 26
|
||||
.define public ADS_PIN 27
|
||||
.define public BUSOE_PIN 28
|
||||
.define public DACK_PIN 20
|
||||
|
||||
.program iow
|
||||
restart:
|
||||
.wrap_target
|
||||
; muxes to addr, IOCHRDY high
|
||||
set pins, 0b01
|
||||
; IOW rising edge (or already high when PIO starts)
|
||||
wait 1 gpio IOW_PIN
|
||||
; IOW falling edge:
|
||||
wait 0 gpio IOW_PIN
|
||||
; Read address
|
||||
in pins, 10
|
||||
; Set muxes to data. Wait 8 cycles for mux to switch
|
||||
set pins, 0b11 [8]
|
||||
; Read data
|
||||
in pins, 8
|
||||
; irq 0 rel
|
||||
; Set muxes back to address
|
||||
set pins, 0b01
|
||||
; get condition from handle_iow
|
||||
out X, 32
|
||||
; if we get a 0 condition from handle_iow, it's not an interesting address
|
||||
jmp !X restart
|
||||
; set IOCHRDY low
|
||||
set pins, 0b00
|
||||
; stall until handle_iow completes
|
||||
out null, 32
|
||||
wait 1 gpio IOW_PIN ; IOW rising edge (or already high when PIO starts)
|
||||
wait 0 gpio IOW_PIN ; IOW falling edge:
|
||||
jmp pin read_addr ; if this is not during DMA (~DACK deasserted), go ahead and read address
|
||||
jmp restart ; otherwise restart
|
||||
read_addr:
|
||||
in pins, 10 ; Read address
|
||||
set pins, 0b11 [8] ; Set muxes to data. Wait 8 cycles for mux to switch
|
||||
in pins, 8 ; Read data
|
||||
set pins, 0b01 ; Set muxes back to address
|
||||
out X, 32 ; get condition from handle_iow
|
||||
jmp !X restart ; if we get a 0 condition from handle_iow, it's not an interesting address
|
||||
set pins, 0b00 ; set IOCHRDY low
|
||||
out null, 32 ; stall until handle_iow completes
|
||||
set pins, 0b01 ; muxes to addr, IOCHRDY high
|
||||
.wrap
|
||||
|
||||
% c-sdk {
|
||||
static inline void iow_program_init(PIO pio, uint sm, uint offset) {
|
||||
pio_sm_config c = iow_program_get_default_config(offset);
|
||||
|
||||
// Set up AD0 buus as input
|
||||
// Set up AD0 pins as input
|
||||
sm_config_set_in_pins(&c, AD0_PIN);
|
||||
// Autopush at 18 bits (10 addr + 8 data)
|
||||
sm_config_set_in_shift(&c, false, true, 18);
|
||||
@@ -56,6 +48,9 @@ static inline void iow_program_init(PIO pio, uint sm, uint offset) {
|
||||
pio_gpio_init(pio, ADS_PIN);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, IOCHRDY_PIN, 2, true);
|
||||
|
||||
// JMP on ~DACK so we can ignore iow during DMA write
|
||||
sm_config_set_jmp_pin(&c, DACK_PIN);
|
||||
|
||||
// Load our configuration, and jump to the start of the program
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
// Set the state machine running
|
||||
@@ -65,10 +60,8 @@ static inline void iow_program_init(PIO pio, uint sm, uint offset) {
|
||||
|
||||
.program ior
|
||||
restart:
|
||||
; muxes to addr, IOCHRDY high
|
||||
set pins, 0b01
|
||||
; ensure IOR high when PIO starts
|
||||
wait 1 gpio IOR_PIN
|
||||
set pins, 0b01 ; muxes to addr, IOCHRDY high
|
||||
wait 1 gpio IOR_PIN ; ensure IOR high when PIO starts
|
||||
.wrap_target
|
||||
wait 0 gpio IOR_PIN ; IOR falling edge
|
||||
in pins, 10 ; - Read address
|
||||
+5
-3
@@ -33,9 +33,11 @@ typedef struct pio_spi_inst {
|
||||
} pio_spi_inst_t;
|
||||
|
||||
|
||||
static __force_inline void __time_critical_func(pio_spi_write_read_blocking)(pio_spi_inst_t* spi,
|
||||
const uint8_t* src, const size_t src_len,
|
||||
uint8_t* dst, const size_t dst_len) {
|
||||
static __force_inline void __time_critical_func(pio_spi_write_read_blocking)(
|
||||
pio_spi_inst_t* spi,
|
||||
const uint8_t* src, const size_t src_len,
|
||||
uint8_t* dst, const size_t dst_len
|
||||
) {
|
||||
size_t tx_remain = src_len, rx_remain = dst_len;
|
||||
|
||||
#ifdef USE_SPINLOCK
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
#include "psram_spi.h"
|
||||
pio_spi_inst_t psram_spi;
|
||||
#endif
|
||||
#include "io.pio.h"
|
||||
#include "isa_io.pio.h"
|
||||
|
||||
#ifdef SOUND_OPL
|
||||
#include "opl.h"
|
||||
|
||||
Reference in new issue
Block a user