Example #1
0
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;
}
Example #2
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);
	}
}
Example #3
0
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;
}