硬汉嵌入式论坛

 找回密码
 立即注册
查看: 880|回复: 6
收起左侧

[SPI/QSPI] H750使用QSPI+MDMA发送全屏buffer没有现象是什么问题

[复制链接]

1

主题

7

回帖

10

积分

新手上路

积分
10
发表于 2024-6-4 15:11:37 | 显示全部楼层 |阅读模式
本帖最后由 arm120 于 2024-6-4 15:20 编辑

这是qspi和mdma配置
[C] 纯文本查看 复制代码
void QSPI_Init(void)
{
        
        QSPI_Handler.Instance=QUADSPI;
        QSPI_Handler.Init.ChipSelectHighTime=QSPI_CS_HIGH_TIME_1_CYCLE;  //片选为高延时
        QSPI_Handler.Init.ClockMode=QSPI_CLOCK_MODE_3;                                                       //配置时钟模式
        QSPI_Handler.Init.ClockPrescaler=10;                                                                                                                  //配置时钟分频比
        QSPI_Handler.Init.DualFlash=QSPI_DUALFLASH_DISABLE;                                                         //配置双闪存模式状态
        QSPI_Handler.Init.FifoThreshold=32;                                                                                                                          //配置FIFO中字节阈值(仅在间接模式使用)
        QSPI_Handler.Init.FlashID=QSPI_FLASH_ID_1;                                                                                           //配置使用的闪存
        QSPI_Handler.Init.FlashSize=412*412*3-1;                                                                                           //配置闪存大小
        QSPI_Handler.Init.SampleShifting=QSPI_SAMPLE_SHIFTING_HALFCYCLE; //配置采样移位
        HAL_QSPI_Init(&QSPI_Handler);
        
        __HAL_RCC_MDMA_CLK_ENABLE();
        
        hmdma.Instance = MDMA_Channel0;
        hmdma.Init.Request = MDMA_REQUEST_QUADSPI_FIFO_TH;
        hmdma.Init.TransferTriggerMode = MDMA_BUFFER_TRANSFER;
        hmdma.Init.Priority =  MDMA_PRIORITY_HIGH;
        hmdma.Init.Endianness =  MDMA_LITTLE_ENDIANNESS_PRESERVE;
        hmdma.Init.SourceInc = MDMA_SRC_INC_BYTE;
        hmdma.Init.DestinationInc =  MDMA_DEST_INC_DISABLE;
        hmdma.Init.SourceDataSize =  MDMA_SRC_DATASIZE_BYTE;
        hmdma.Init.DestDataSize = MDMA_DEST_DATASIZE_BYTE;
        hmdma.Init.DataAlignment = MDMA_DATAALIGN_PACKENABLE;
        hmdma.Init.BufferTransferLength = 128;
        hmdma.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
        hmdma.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
        hmdma.Init.SourceBlockAddressOffset = 0;
        hmdma.Init.DestBlockAddressOffset = 0;
        
        if (HAL_MDMA_Init(&hmdma) != HAL_OK)
  {
      Error_Handler();
  }
        
        __HAL_LINKDMA(&QSPI_Handler,hmdma,hmdma);

        HAL_NVIC_SetPriority(MDMA_IRQn,0,0);
        HAL_NVIC_EnableIRQ(MDMA_IRQn);
}


这是引脚配置


[C] 纯文本查看 复制代码
void QSPI_GPIOInit(void)
{
        GPIO_InitTypeDef GPIO_InitStructure; 
        RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
        
        PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_QSPI;
  PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK;
        
        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
      Error_Handler();
  }
        
  __HAL_RCC_GPIOE_CLK_ENABLE();
        __HAL_RCC_GPIOD_CLK_ENABLE(); 
        __HAL_RCC_GPIOB_CLK_ENABLE();
        __HAL_RCC_QSPI_CLK_ENABLE();
        
        GPIO_InitStructure.Pin=GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
        GPIO_InitStructure.Mode=GPIO_MODE_AF_PP;
        GPIO_InitStructure.Pull=GPIO_PULLUP;
        GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStructure.Alternate=GPIO_AF9_QUADSPI;
        HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
        
        GPIO_InitStructure.Pin = GPIO_PIN_2;
        GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStructure.Pull =GPIO_PULLUP;
        GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStructure.Alternate = GPIO_AF9_QUADSPI;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_InitStructure.Pin = GPIO_PIN_6;
        GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStructure.Pull = GPIO_PULLUP;
        GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStructure.Alternate = GPIO_AF10_QUADSPI;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);        
        
  GPIO_InitStructure.Pin = GPIO_PIN_2;
  GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStructure.Pull = GPIO_PULLUP;
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStructure.Alternate = GPIO_AF9_QUADSPI;
  HAL_GPIO_Init(GPIOE,&GPIO_InitStructure);

}



这是刷屏函数
[C] 纯文本查看 复制代码

#define BUFF_TOTAL 339488
uint8_t frame_cache[BUFF_TOTAL] __attribute__((section(".ARM.__at_0x24000000")));

void LCD_Fill1(uint32_t color)
{
    uint8_t Color[2] = {color >> 8, color & 0xff};
    
    // 填充 frame_cache 数组
    for (uint32_t i = 0; i < BUFF_TOTAL; i += 2)
    {
        frame_cache[i] = Color[0];
        frame_cache[i + 1] = Color[1];
    }

    LCD_Address_Set(0, 0, 454 - 1, 454- 1);
    LCD_WR_REG(0x2C);
        LCD_4LineTransmit_DATA_DMA(0x3C, BUFF_TOTAL, frame_cache);
}


发送接口
[C] 纯文本查看 复制代码
void LCD_4LineTransmit_DATA_DMA(uint8_t reg,uint32_t len,uint8_t *dat)
{
        QSPI_CmdInitStructure.DummyCycles=0;
        QSPI_CmdInitStructure.Instruction=0x32;
        QSPI_CmdInitStructure.InstructionMode=QSPI_INSTRUCTION_1_LINE;
        
        QSPI_CmdInitStructure.Address=reg<<8;                
        QSPI_CmdInitStructure.AddressMode=QSPI_ADDRESS_1_LINE;
        QSPI_CmdInitStructure.AddressSize=QSPI_ADDRESS_24_BITS;
        
        QSPI_CmdInitStructure.DataMode=QSPI_DATA_4_LINES;
        QSPI_CmdInitStructure.NbData=len;
        QSPI_CmdInitStructure.SIOOMode=QSPI_SIOO_INST_EVERY_CMD;
        QSPI_CmdInitStructure.DdrMode=QSPI_DDR_MODE_DISABLE;
        QSPI_CmdInitStructure.DdrHoldHalfCycle=QSPI_DDR_HHC_ANALOG_DELAY;        
        QSPI_CmdInitStructure.AlternateBytesSize=QSPI_ALTERNATE_BYTES_NONE;        
        HAL_QSPI_Command(&QSPI_Handler,&QSPI_CmdInitStructure,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);
        //HAL_QSPI_Transmit(&QSPI_Handler,dat,HAL_QSPI_TIMEOUT_DEFAULT_VALUE);        
        HAL_QSPI_Transmit_DMA(&QSPI_Handler,dat) ;
//        uint32_t block_count = len / 128;
//  uint32_t remaining_data = len % 128;

//    if (block_count > 0) {
//        if (HAL_MDMA_Start_IT(&hmdma, (uint32_t)dat, (uint32_t)&QSPI_Handler.Instance->DR, 128, block_count) != HAL_OK) {
//            //Error_Handler();
//        }
//    }

//    if (remaining_data > 0) {
//        if (HAL_MDMA_Start_IT(&hmdma, (uint32_t)(dat + block_count * 128), (uint32_t)&QSPI_Handler.Instance->DR, remaining_data,1) != HAL_OK) {
//            //Error_Handler();
//        }
//    }

        
        //HAL_MDMA_Start_IT(&hmdma,(uint32_t)dat,(uint32_t)&QSPI_Handler.Instance->DR,len,1);
}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-6-4 15:35:57 | 显示全部楼层
注意Cache问题,楼主测试下先手动将buffer设置为0x00,MDMA后,调用函数SCB_CleanInvalidateDCache,在读取这个buffer看看对不对,如果不对,说明你的QSPI MDMA有点问题。
回复

使用道具 举报

1

主题

7

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2024-6-7 17:19:28 | 显示全部楼层
eric2013 发表于 2024-6-4 15:35
注意Cache问题,楼主测试下先手动将buffer设置为0x00,MDMA后,调用函数SCB_CleanInvalidateDCache,在读取 ...

有相关历程可以参考吗,我现在用HAL_QSPI_Transmit_DMA接口传数据屏幕只显示前面几行,后面数据都好像丢失了
回复

使用道具 举报

3

主题

422

回帖

431

积分

高级会员

积分
431
发表于 2024-6-7 19:08:29 | 显示全部楼层
啥显示模块支持QSPI?
回复

使用道具 举报

1

主题

7

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2024-6-10 14:35:05 | 显示全部楼层
glory 发表于 2024-6-7 19:08
啥显示模块支持QSPI?

SPD2010显示ic,支持qspi,分辨率412x412
回复

使用道具 举报

1

主题

15

回帖

18

积分

新手上路

积分
18
QQ
发表于 2024-8-20 19:17:59 | 显示全部楼层
arm120 发表于 2024-6-10 14:35
SPD2010显示ic,支持qspi,分辨率412x412

请问你的H750驱动SPD2010搞定了吗? 可以发给我参考下吗?
回复

使用道具 举报

1

主题

7

回帖

10

积分

新手上路

积分
10
 楼主| 发表于 2024-8-21 10:17:13 | 显示全部楼层
本帖最后由 arm120 于 2024-8-21 17:15 编辑
davidlau 发表于 2024-8-20 19:17
请问你的H750驱动SPD2010搞定了吗? 可以发给我参考下吗?

你可以参考一下 git clone https://github.com/Manahhl/H750_MDMA_QSPI.git
注意下,如果你要用这个硬件条件做测试,片选脚会有个小问题,要么用转接线接长一点,要么数据线都用短线
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-29 03:10 , Processed in 0.629007 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表