static int dma_stm32_stop(struct device *dev, u32_t id) { struct dma_stm32_device *ddata = dev->driver_data; struct dma_stm32_stream *stream = &ddata->stream[id]; u32_t scr, sfcr, irqstatus; int ret; /* Disable all IRQs */ scr = dma_stm32_read(ddata, DMA_STM32_SCR(id)); scr &= ~DMA_STM32_SCR_IRQ_MASK; dma_stm32_write(ddata, DMA_STM32_SCR(id), scr); sfcr = dma_stm32_read(ddata, DMA_STM32_SFCR(id)); sfcr &= ~DMA_STM32_SFCR_FEIE; dma_stm32_write(ddata, DMA_STM32_SFCR(id), sfcr); /* Disable stream */ ret = dma_stm32_disable_stream(ddata, id); if (ret) return ret; /* Clear remanent IRQs from previous transfers */ irqstatus = dma_stm32_irq_status(ddata, id); if (irqstatus) { dma_stm32_irq_clear(ddata, id, irqstatus); } /* Finally, flag stream as free */ stream->busy = false; return 0; }
static void dma_stm32_irq_handler(void *arg, u32_t id) { struct device *dev = arg; struct dma_stm32_device *ddata = dev->driver_data; struct dma_stm32_stream *stream = &ddata->stream[id]; u32_t irqstatus, config, sfcr; irqstatus = dma_stm32_irq_status(ddata, id); config = dma_stm32_read(ddata, DMA_STM32_SCR(id)); sfcr = dma_stm32_read(ddata, DMA_STM32_SFCR(id)); /* Silently ignore spurious transfer half complete IRQ */ if (irqstatus & DMA_STM32_HTI) { dma_stm32_irq_clear(ddata, id, DMA_STM32_HTI); return; } stream->busy = false; if ((irqstatus & DMA_STM32_TCI) && (config & DMA_STM32_SCR_TCIE)) { dma_stm32_irq_clear(ddata, id, DMA_STM32_TCI); stream->dma_callback(stream->dev, id, 0); } else { SYS_LOG_ERR("Internal error: IRQ status: 0x%x\n", irqstatus); dma_stm32_irq_clear(ddata, id, irqstatus); stream->dma_callback(stream->dev, id, -EIO); } }
static int dma_stm32_start(struct device *dev, u32_t id) { struct dma_stm32_device *ddata = dev->driver_data; struct dma_stm32_stream_reg *regs = &ddata->stream[id].regs; u32_t irqstatus; int ret; ret = dma_stm32_disable_stream(ddata, id); if (ret) { return ret; } dma_stm32_write(ddata, DMA_STM32_SCR(id), regs->scr); dma_stm32_write(ddata, DMA_STM32_SPAR(id), regs->spar); dma_stm32_write(ddata, DMA_STM32_SM0AR(id), regs->sm0ar); dma_stm32_write(ddata, DMA_STM32_SFCR(id), regs->sfcr); dma_stm32_write(ddata, DMA_STM32_SM1AR(id), regs->sm1ar); dma_stm32_write(ddata, DMA_STM32_SNDTR(id), regs->sndtr); /* Clear remanent IRQs from previous transfers */ irqstatus = dma_stm32_irq_status(ddata, id); if (irqstatus) { dma_stm32_irq_clear(ddata, id, irqstatus); } dma_stm32_dump_reg(ddata, id); /* Push the start button */ dma_stm32_write(ddata, DMA_STM32_SCR(id), regs->scr | DMA_STM32_SCR_EN); return 0; }