linux stm32mp157 DAC对DMA的使用例程
时间: 2024-03-11 18:47:43 浏览: 76
以下是一个 Linux STM32MP157 DAC 对 DMA 的使用示例:
1. 首先,需要在设备树中定义 DAC 控制器和 DMA 控制器。例如:
```
&dac {
compatible = "st,stm32-dac";
reg = <0x40007400 0x400>;
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
#dma-cells = <1>;
};
&dma1 {
compatible = "st,stm32-dma";
reg = <0x40020000 0x4000>;
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
};
```
2. 在 Linux 驱动程序中,需要获取 DAC 控制器和 DMA 控制器的物理地址,并映射到虚拟地址空间中。例如:
```
static void __iomem *dac_base;
static void __iomem *dma_base;
static int mydriver_probe(struct platform_device *pdev)
{
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dac_base = devm_ioremap_resource(&pdev->dev, res);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
dma_base = devm_ioremap_resource(&pdev->dev, res);
...
}
```
3. 在需要使用 DMA 的地方,需要分配 DMA 缓冲区,并将其映射到虚拟地址空间中。例如:
```
#define BUF_SIZE 1024
static struct dma_chan *chan;
static dma_addr_t dma_addr;
static void *buf;
buf = dma_alloc_coherent(&pdev->dev, BUF_SIZE, &dma_addr, GFP_KERNEL);
if (!buf) {
return -ENOMEM;
}
chan = dma_request_chan(&pdev->dev, "dma1");
if (!chan) {
dma_free_coherent(&pdev->dev, BUF_SIZE, buf, dma_addr);
return -ENODEV;
}
```
4. 配置 DAC 控制器和 DMA 控制器。例如:
```
#define SAMPLE_RATE 48000
#define DMA_PERIODS 2
#define DMA_PERIOD_SIZE (BUF_SIZE / DMA_PERIODS)
static void dac_dma_config(void)
{
u32 cr;
u32 ndtr = DMA_PERIOD_SIZE / 2; // 2 bytes per sample
// Enable DAC channel 1
cr = readl(dac_base + DAC_CR);
writel(cr | DAC_CR_EN1, dac_base + DAC_CR);
// Enable DMA for DAC channel 1
cr = readl(dac_base + DAC_CR);
writel(cr | DAC_CR_DMAEN1, dac_base + DAC_CR);
// Configure DMA
dmaengine_slave_config(chan, dma_addr, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
dmaengine_set_dma_callback(chan, dac_dma_complete, NULL);
dmaengine_set_periodic_mode(chan, ndtr, ndtr);
dmaengine_set_src_addr(chan, buf);
dmaengine_set_dst_addr(chan, dac_base + DAC_DHR12R1);
dmaengine_set_transfer_size(chan, DMA_PERIOD_SIZE);
}
```
5. 开始 DMA 传输。例如:
```
static void dac_dma_start(void)
{
dma_async_issue_pending(chan);
writel(DAC_SWTRIGR_SWTRIG1, dac_base + DAC_SWTRIGR);
}
```
以上是一个简单的 Linux STM32MP157 DAC 对 DMA 的使用示例,具体实现可能因硬件平台和应用场景而有所不同。需要根据实际情况进行调整和修改。
阅读全文