From 33e86e5a51503b970088c7a36aed52cf243da56d Mon Sep 17 00:00:00 2001 From: Mahyar Koshkouei Date: Sat, 21 May 2022 12:42:25 +0100 Subject: [PATCH] Fix LCD corruption Fixed an issue whereby minigb_apu was being compiled even though sound support was disabled. This was somehow causing the LCD to become corrupted. Additionally added sleep routines during DMA transfer to LCD. Additionally made sound support an option within cmake. Signed-off-by: Mahyar Koshkouei --- CMakeLists.txt | 14 ++++++++++++-- inc/peanut_gb.h | 1 - src/main.c | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7dcd21..e3f3236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,18 @@ project(RP2040_GB C CXX) # Initialize the Raspberry Pi Pico SDK pico_sdk_init() -add_executable(RP2040_GB src/main.c src/rom.c src/mk_ili9225.c ext/minigb_apu/minigb_apu.c) -target_include_directories(RP2040_GB PRIVATE inc ext/minigb_apu) +add_executable(RP2040_GB src/main.c src/rom.c src/mk_ili9225.c) +target_include_directories(RP2040_GB PRIVATE inc) + +SET(ENABLE_SOUND FALSE CACHE BOOL "Enable Sound emulation") +if(ENABLE_SOUND) + ADD_COMPILE_DEFINITIONS(ENABLE_SOUND=1) + target_sources(RP2040_GB PRIVATE ext/minigb_apu/minigb_apu.c) + target_include_directories(RP2040_GB PRIVATE ext/minigb_apu) +else() + ADD_COMPILE_DEFINITIONS(ENABLE_SOUND=0) +endif() + target_link_libraries(RP2040_GB pico_stdlib pico_stdio pico_bootrom pico_multicore pico_stdio pico_multicore hardware_clocks hardware_pio hardware_vreg hardware_pio diff --git a/inc/peanut_gb.h b/inc/peanut_gb.h index 7dbd09d..bff8c3a 100644 --- a/inc/peanut_gb.h +++ b/inc/peanut_gb.h @@ -32,7 +32,6 @@ #pragma once #include "hedley.h" -#include "minigb_apu.h" #include /* Required for int types */ #include /* Required for memset */ diff --git a/src/main.c b/src/main.c index cb51023..7397d6b 100644 --- a/src/main.c +++ b/src/main.c @@ -14,11 +14,14 @@ */ #define ENABLE_LCD 1 -#define ENABLE_SOUND 0 + +#ifndef ENABLE_SOUND +# define ENABLE_SOUND 0 +#endif /* Use DMA for all drawing to LCD. Benefits aren't fully realised at the moment * due to busy loops waiting for DMA completion. */ -#define USE_DMA 0 +#define USE_DMA 1 /** * Reducing VSYNC calculation to lower multiple. @@ -48,6 +51,7 @@ #include #include #include +#include /* Project headers */ #include "hedley.h" @@ -174,6 +178,14 @@ void gb_error(struct gb_s *gb, const enum gb_error_e gb_err, const uint16_t val) #endif } +void core1_irq_dma_lcd_end_transfer(void) +{ + mk_ili9225_write_pixels_end(); + __atomic_store_n(&lcd_line_busy, 0, __ATOMIC_SEQ_CST); + //irq_clear(DMA_IRQ_0); + dma_channel_acknowledge_irq0(dma_lcd); +} + void core1_lcd_draw_line(const uint_fast8_t line) { const uint16_t palette[3][4] = { @@ -196,9 +208,10 @@ void core1_lcd_draw_line(const uint_fast8_t line) #if USE_DMA mk_ili9225_write_pixels_start(); dma_channel_transfer_from_buffer_now(dma_lcd, &fb[0], LCD_WIDTH); - dma_channel_wait_for_finish_blocking(dma_lcd); - mk_ili9225_write_pixels_end(); - __atomic_store_n(&lcd_line_busy, 0, __ATOMIC_SEQ_CST); + do { + __wfi(); + } while (dma_channel_is_busy(dma_lcd)); + __compiler_memory_barrier(); #else mk_ili9225_write_pixels(fb, LCD_WIDTH); __atomic_store_n(&lcd_line_busy, 0, __ATOMIC_SEQ_CST); @@ -225,13 +238,19 @@ void main_core1(void) channel_config_set_write_increment(&c2, false); channel_config_set_ring(&c2, false, 0); + /* Enable IRQ for wake on interrupt functionality. */ + irq_set_exclusive_handler(DMA_IRQ_0, core1_irq_dma_lcd_end_transfer); + dma_channel_set_irq0_enabled(dma_lcd, true); + irq_set_enabled(DMA_IRQ_0, true); + /* Clear LCD screen. */ mk_ili9225_write_pixels_start(); dma_channel_configure(dma_lcd, &c2, &spi_get_hw(spi0)->dr, &clear, SCREEN_SIZE_X*SCREEN_SIZE_Y+16, true); - /* TODO: Add sleeping wait. */ - dma_channel_wait_for_finish_blocking(dma_lcd); - mk_ili9225_write_pixels_end(); + do { + __wfi(); + } while (dma_channel_is_busy(dma_lcd)); + __compiler_memory_barrier(); /* Set DMA transfer to be the length of a DMG line. */ dma_channel_set_trans_count(dma_lcd, LCD_WIDTH, false); @@ -389,7 +408,7 @@ int main(void) { int input; #if ENABLE_SOUND - static float stream[AUDIO_NSAMPLES]; + static uint16_t stream[1098]; #endif gb.gb_frame = 0; @@ -401,7 +420,7 @@ int main(void) frames++; #if ENABLE_SOUND - audio_callback(NULL, stream, AUDIO_NSAMPLES); + audio_callback(NULL, stream, 1098); #endif /* Required since we do not know whether a button remains