From: kosmirror <kos...@us...> - 2025-05-19 16:31:04
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 71a97d30c731858205ca9deaaee4bc36ec8db409 (commit) via 6717a0cf9ba2f87b655cb23cf2f5c9198d063d35 (commit) from 09b44b0d5e40e9302a71c9269e7df36c08377f1a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 71a97d30c731858205ca9deaaee4bc36ec8db409 Author: DC-SWAT <sw...@21...> Date: Mon May 19 09:50:07 2025 +0700 sci: Abort DMA on errors in SPI mode. Also minor log fixes. commit 6717a0cf9ba2f87b655cb23cf2f5c9198d063d35 Author: DC-SWAT <sw...@21...> Date: Mon May 19 09:46:36 2025 +0700 dmac: Added dma_is_running() and dma_transfer_abort() ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/dmac.c | 9 ++++++++- kernel/arch/dreamcast/hardware/sci.c | 13 +++++++------ kernel/arch/dreamcast/include/arch/dmac.h | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/dmac.c b/kernel/arch/dreamcast/hardware/dmac.c index d486ee76..aec59034 100644 --- a/kernel/arch/dreamcast/hardware/dmac.c +++ b/kernel/arch/dreamcast/hardware/dmac.c @@ -108,7 +108,7 @@ static void dma_irq_handler(irq_t code, irq_context_t *context, void *d) { } } -static bool dma_is_running(dma_channel_t channel) { +bool dma_is_running(dma_channel_t channel) { uint32_t chcr = dmac_read(channel, DMA_REG_CHCR); return (chcr & (REG_CHCR_TRANSFER_END | REG_CHCR_DMAC_EN)) == REG_CHCR_DMAC_EN; @@ -166,3 +166,10 @@ size_t dma_transfer_get_remaining(dma_channel_t channel) { return tcr * dma_unit_size[unit_size]; } + +void dma_transfer_abort(dma_channel_t channel) { + irq_disable_scoped(); + + dmac_write(channel, DMA_REG_CHCR, 0); + genwait_wake_all((void *)&channels_cfg[channel]); +} diff --git a/kernel/arch/dreamcast/hardware/sci.c b/kernel/arch/dreamcast/hardware/sci.c index 4ce22bbf..40f6898f 100644 --- a/kernel/arch/dreamcast/hardware/sci.c +++ b/kernel/arch/dreamcast/hardware/sci.c @@ -1021,7 +1021,7 @@ sci_result_t sci_spi_read_data(uint8_t *rx_data, size_t len) { if(status & ORER) { SCSSR1 &= ~ORER; sci_set_transfer_mode(0); - dbglog(DBG_ERROR, "SCI: Overrun error\n"); + dbglog(DBG_ERROR, "SCI: Overrun error in SPI read data\n"); return SCI_ERR_OVERRUN; } } while(!(status & RDRF)); @@ -1082,7 +1082,7 @@ sci_result_t sci_spi_dma_write_data(const uint8_t *data, size_t len, dma_callbac while(!(SCSSR1 & TEND)) { if(++timeout_cnt > SCI_MAX_WAIT_CYCLES) { sci_set_transfer_mode(0); - dbglog(DBG_ERROR, "SCI: Timeout waiting for TEND in SPI read data\n"); + dbglog(DBG_ERROR, "SCI: Timeout waiting for TEND in SPI DMA write\n"); return SCI_ERR_TIMEOUT; } } @@ -1109,7 +1109,6 @@ sci_result_t sci_spi_dma_read_data(uint8_t *data, size_t len, dma_callback_t cal /* Configure DMA */ dma_config_t config = sci_dma_rx_config; - config.callback = callback; /* Prepare DMA */ dma_addr_t src = hw_to_dma_addr(SCRDR1_ADDR); @@ -1131,7 +1130,8 @@ sci_result_t sci_spi_dma_read_data(uint8_t *data, size_t len, dma_callback_t cal while(!(SCSSR1 & TDRE)) { if(++timeout_cnt > SCI_MAX_WAIT_CYCLES) { sci_set_transfer_mode(0); - dbglog(DBG_ERROR, "SCI: Timeout waiting for TDRE in SPI read data\n"); + dma_transfer_abort(sci_dma_rx_config.channel); + dbglog(DBG_ERROR, "SCI: Timeout waiting for TDRE in SPI DMA read\n"); return SCI_ERR_TIMEOUT; } } @@ -1149,7 +1149,8 @@ sci_result_t sci_spi_dma_read_data(uint8_t *data, size_t len, dma_callback_t cal while(!(SCSSR1 & TEND)) { if(++timeout_cnt > SCI_MAX_WAIT_CYCLES) { sci_set_transfer_mode(0); - dbglog(DBG_ERROR, "SCI: Timeout waiting for TEND in SPI read data\n"); + dma_transfer_abort(sci_dma_rx_config.channel); + dbglog(DBG_ERROR, "SCI: Timeout waiting for TEND in SPI DMA read\n"); return SCI_ERR_TIMEOUT; } } @@ -1173,6 +1174,6 @@ sci_result_t sci_spi_dma_read_data(uint8_t *data, size_t len, dma_callback_t cal } sci_result_t sci_dma_wait_complete(void) { - dma_wait_complete(DMA_CHANNEL_1); + dma_wait_complete(sci_dma_rx_config.channel); return check_sci_errors(); } diff --git a/kernel/arch/dreamcast/include/arch/dmac.h b/kernel/arch/dreamcast/include/arch/dmac.h index 7882add4..21b1530d 100644 --- a/kernel/arch/dreamcast/include/arch/dmac.h +++ b/kernel/arch/dreamcast/include/arch/dmac.h @@ -21,6 +21,7 @@ __BEGIN_DECLS #include <stdint.h> +#include <stdbool.h> /** \defgroup dmac DMA Controller API \brief API to use the SH4's DMA Controller @@ -227,6 +228,17 @@ int dma_transfer(const dma_config_t *cfg, dma_addr_t dst, dma_addr_t src, */ void dma_wait_complete(dma_channel_t channel); +/** \brief Check if a DMA transfer is running + \ingroup dmac + + This function will return true if a DMA transfer is running for the given + DMA channel. + + \param channel The DMA channel to check. + \return True if a DMA transfer is running, false otherwise. +*/ +bool dma_is_running(dma_channel_t channel); + /** \brief Get the remaining size of a DMA transfer \ingroup dmac @@ -239,6 +251,15 @@ void dma_wait_complete(dma_channel_t channel); */ size_t dma_transfer_get_remaining(dma_channel_t channel); +/** \brief Abort a DMA transfer + \ingroup dmac + + This function will abort a DMA transfer for the given DMA channel. + + \param channel The DMA channel to abort. +*/ +void dma_transfer_abort(dma_channel_t channel); + /** @} */ __END_DECLS hooks/post-receive -- A pseudo Operating System for the Dreamcast. |