示例#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;
}
示例#2
0
static void dma_stm32_irq_clear(struct dma_stm32_device *ddata,
				u32_t id, u32_t irqs)
{
	irqs = irqs << (((id & 2) << 3) | ((id & 1) * 6));

	if (id & 4) {
		dma_stm32_write(ddata, DMA_STM32_HIFCR, irqs);
	} else {
		dma_stm32_write(ddata, DMA_STM32_LIFCR, irqs);
	}
}
示例#3
0
static int dma_stm32_disable_stream(struct dma_stm32_device *ddata,
				  u32_t id)
{
	u32_t config;
	int count = 0;
	int ret = 0;

	for (;;) {
		config = dma_stm32_read(ddata, DMA_STM32_SCR(id));
		/* Stream already disabled */
		if (!(config & DMA_STM32_SCR_EN)) {
			return 0;
		}

		/* Try to disable stream */
		dma_stm32_write(ddata, DMA_STM32_SCR(id),
				config &= ~DMA_STM32_SCR_EN);

		/* After trying for 5 seconds, give up */
		k_sleep(K_SECONDS(5));
		if (count++ > (5 * 1000) / 50) {
			SYS_LOG_ERR("DMA error: Stream in use\n");
			return -EBUSY;
		}
	}

	return ret;
}
示例#4
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;
}