标签: dma

STM32F4 I2C 与 DMA 不工作

我正在使用一台 STM32F4,我想与我的 LSM303 加速度计进行通信。为此,我使用 I2C,仅使用 I2C 工作正常,但当我尝试使用 DMA 时,它停止工作。当我使用 HAL_I2C_Master_Transmit_DMA 时,它可以工作,并且我得到了 IRQHandler 和 . 但是之后当我想使用 HAL_I2C_Master_Receive_DMA 时,它说 I2C 的状态尚未准备好...我读到 I2C 与 STM32FX 有点混乱,但我不明白为什么它在没有 DMA 的情况下工作正常。

此外,当它命中 Master_Transmit_DMA 的回调 I2C_DMAXferCplt 时,它表示 I2C_HandleTypeDef 的 CurrentState 仍然等于 HAL_I2C_STATE_BUSY_TX,因此它不会将状态恢复为 READY。这就是为什么当我调用 Master_Receive_DMA 时它没有收到任何东西。

这是我的 I2C 初始化:

    void MX_I2C2_Init(void)
      {
          I2C_ST_INS.Instance = I2C2;
          I2C_ST_INS.Init.ClockSpeed = 400000;
           I2C_ST_INS.Init.DutyCycle = I2C_DUTYCYCLE_2;
           I2C_ST_INS.Init.OwnAddress1 = 0;
          I2C_ST_INS.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
          I2C_ST_INS.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
          I2C_ST_INS.Init.OwnAddress2 = 0;
          I2C_ST_INS.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
          I2C_ST_INS.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;

          HAL_I2C_Init(&I2C_ST_INS);

        }

   void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
   {
          GPIO_InitTypeDef GPIO_InitStruct;
          if(i2cHandle->Instance==I2C1) …
Run Code Online (Sandbox Code Playgroud)

stm32 i2c dma

5
推荐指数
2
解决办法
5708
查看次数

如何调试 Linux I2S 音频输入问题

我正在尝试将 I2S 麦克风 (Invensense ICS43432) 连接到运行 Arch Linux 的 Raspberry Pi (B+),但失败了。我已经在相关的 Arch Linux ARM 论坛中寻求了具体的建议,但我的问题实际上比这更笼统:如何调试 Linux 音频输入问题?

我已经使用逻辑分析仪验证了 I2S 麦克风正在正确的通道(左)和 Raspberry Pi 的正确引脚中发送敏感数据。I2S 麦克风在 ALSA 下显示为“声卡”。 arecord我非常高兴从该设备进行录音,并且我已将该设备的增益提高了alsamixer30 dB。然而记录文件的所有数据字节都是零。

在Linux下如何检查音频数据流、DMA操作?

linux debugging alsa dma raspberry-pi

5
推荐指数
1
解决办法
1041
查看次数

在 Qemu 上编写用于 DMA 传输的 PCI 驱动程序

我正在 Qemu 上编写 PCI 设备,并在来宾操作系统中编写驱动程序(LKM)。虽然 Qemu 提供了一个示例 PCI 设备eduedu.txtedu.c)及其发行版,但我在编写内核模块来进行 DMA 传输时遇到了问题。这里介绍了一个基本的驱动程序,但它不支持 DMA。

我正在跟踪 link 和this的实现。我尝试将缓冲区从 IRQ 处理程序传输到 PCI 设备。设备可以读取数据(pci_dma_read),但我没有得到我应该接收的正确数据。这是进行 DMA 传输的代码段:

static int write_to_HyPerf(void *dev, void* addr, uint32_t size)
{
    /* ----------------------------------------------------------------------------
    * PCI address 'addr':
    * addr     -> DMA source address
    * 0x40000  -> DMA destination address
    * 100      -> DMA transfer count
    * 1        -> DMA command register
    * while (DMA command register & 1)
    *-------------------------------------------------------------------------------- …
Run Code Online (Sandbox Code Playgroud)

qemu linux-device-driver dma pci

5
推荐指数
1
解决办法
1884
查看次数

指定超时后有意接收完成 UART DMA 中断

我已将 UART 配置为以 DMA 模式接收,其中缓冲区的大小约为 64 字节。因此,基本上,HAL_UART_RxCpltCallback() DMA 接收完成中断仅在接收到 64 个字符时才会触发。

STM32中有没有一种方法可以为DMA Rx配置超时,当缓冲区仅部分填充(即接收到的字符少于64个)并且我们在指定的超时时间内不再接收到任何字符时,DMA将然后引发相同的基于 HAL_UART_RxCpltCallback() 的中断,让消费者使用 UART 当前接收到的任何部分数据?

stm32 dma stm32f4 stm32f7

5
推荐指数
1
解决办法
3446
查看次数

STM32:使用带有字符匹配ISR和DMA缓冲区的USART

我正在使用带有 FreeRTOS 和 STM32CubeMX 的STM32L432设备。

我尝试通过基于 ASCII 协议的 USART 实现 M2M 通信。协议序列的长度可以不同,但​​具有最大长度和定义的结束字符 (' \r ' / 0x0D )。

因此,我考虑使用 DMA(如FIFO)收集所有 RX-USART 数据,并使用基于USART_ICR_CMCF标志的地址匹配 isr 来确定结束字符。

初始化USART1并启用地址匹配ISR

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) {
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1) {
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);

    /* USER CODE BEGIN USART1_MspInit 1 …
Run Code Online (Sandbox Code Playgroud)

fifo stm32 dma usart stm32cubemx

5
推荐指数
1
解决办法
3020
查看次数

我正在寻找通过DMA而不是中断在MSP430上为USCI(UART)提供服务的示例代码

我有通过中断读取USCI(UART)的"正常"代码,但TI SimpliciTI堆栈是CPU占用的,并且在维护无线电时它会丢弃UART字节.

我假设DMA是可行的方法,但我找不到使用USCI作为输入的DMA的完整示例.

msp430 dma uart

4
推荐指数
1
解决办法
3976
查看次数

Linux下的DMA和I/O内存区域

我写这篇文章是因为我对DMA的行为有些怀疑.我正在阅读PCI布局以及设备驱动程序如何与卡交互,我读到了有关DMA的信息.由于我的理解,PCI卡没有DMA控制器,而不是他们要求成为总线的主控制器,然后他们能够获取DMA地址并在存储器和设备之间进行传输(通过总线).

这个DMA地址是RAM的一部分,实际上它是一个物理地址,在无所事事之前你需要将它转换成你的驱动程序可以使用的东西,比如内核虚拟内存.我用这段代码检查过:

    /* Virtual kernel address */
    kernel_buff = pci_alloc_consistent(dev, PAGE_SIZE, &dma_addr);

    pr_info("Kernel buffer - %12p , Dma_addr - %12p\n", kernel_buff, (void *)dma_addr );
    pr_info( "Kernelbuffer - dma_addr - %12p\n", kernel_buff - dma_addr);

    strcpy(kernel_buff, "Test dma\n");

    /* Test memory */

    ptest = (void *)dma_addr;
    ptest = phys_to_virt((unsigned long)ptest);

    pr_info("Ptest virtual memory(%p) containts - %s\n", ptest, (char *)ptest);
Run Code Online (Sandbox Code Playgroud)

输出是:

[425971.835669] Kernel buffer - ffff8800ca70a000 , Dma_addr -     ca70a000
[425971.835671] Kernelbuffer - dma_addr - ffff880000000000
[425971.835673] Ptest virtual memory(ffff8800ca70a000) containts - Test …
Run Code Online (Sandbox Code Playgroud)

linux memory kernel dma pci

4
推荐指数
1
解决办法
1620
查看次数

使用DMA访问高速串行端口

我在c#中使用serialport组件,效果很好!但问题是如何更快地处理高速(例如2 Mbps)数据传输.

正如我研究过的那样,我发现可以直接访问内存(使用像这个链接的 DMA ).谁能告诉我如何在我的应用程序中定义和使用它?

c# serial-port dma directmemory

4
推荐指数
1
解决办法
2059
查看次数

stm32 SPI + DMA

我尝试使用DMA通道使用SPI发送数据.当我在没有DMA的情况下发送一切都没问题,但是用DMA确实是错误的.当我调试我的程序时,SPI DR寄存器始终为0.我想使用dma循环模式一直发送我的数组.有我的代码GPIO INIT:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(GPIO_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

GPIO_PinAFConfig(GPIOB, AF_PIN_SOURCE, GPIO_AF);

GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);
Run Code Online (Sandbox Code Playgroud)

SPI INIT

SPI_I2S_DeInit(SPI1);

SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);

SPI_Cmd(SPI1, ENABLE);
Run Code Online (Sandbox Code Playgroud)

DMA INIT:

    DMA_InitTypeDef dma;
    DMA_DeInit(DMA1_Channel1);
    DMA_StructInit(&dma);

    dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
    dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    dma.DMA_PeripheralDataSize …
Run Code Online (Sandbox Code Playgroud)

c embedded spi stm32 dma

4
推荐指数
1
解决办法
2452
查看次数

DMA传输比CPU传输花费更多的时间

我们的任务旨在证明使用DMA复制大量数据与依靠处理器直接处理复制相比的好处。处理器是ST发现板上的STM32F407。

为了测量复制时间,必须在复制期间将GPIO引脚打开,并在复制后将其关闭。

该代码似乎是功能性,但它当前示出了CPU服用约2.15ms至完整和DMA约4.5ms,这是何意相反。我不确定是否没有足够的数据来提供更快的DMA速度来抵消设置数据的开销?

我尝试使用CPU和memcpy函数复制数组的元素,这似乎产生非常相似的时间。

功能代码如下所示:

DMASpeed(void)
{
    #define elementNum 32000
    int *ptr = NULL;
    ptr = (int*)malloc(elementNum * sizeof(int));
    int *ptr2 = NULL;
    ptr2 = (int*)malloc(elementNum * sizeof(int));
    for (int i = 0; i < elementNum; i++)
    {
        ptr[i] = 4;
    }
    LD5_GPIO_Port->BSRR = (uint32_t)LD5_Pin << 16U;
    LD6_GPIO_Port->BSRR = (uint32_t)LD6_Pin << 16U;
    // Initial value
    // printf("BEFORE: dst = '%s'\n", dst);

    // Transfer
    printf("Initiate DMA Transfer...\n");
    HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (int)ptr, (int)ptr2, (elementNum * sizeof(int)));
    LD5_GPIO_Port->BSRR = LD5_Pin;
    printf("DMA …
Run Code Online (Sandbox Code Playgroud)

c stm32 memcpy dma

4
推荐指数
2
解决办法
256
查看次数