因为之前的H750内部空间太小,无法放入UI资源,所以这次直接买了块NUCLEO-H743ZI2,驱动上做了指令1LANE和4LANE的兼容
驱动文件如下:
#include "board.h"
#include "sram.h"
#include "rtthread.h"
#include "rtdevice.h"
#include "lcdqspi.h"
#define DBG
#define DBG_TAG "lcdqspi"
#include "log.h"
#define FRAME_BLANKING_TIME (10U)
#define FRAME_MEM_SIZE (LCD_HBYTE * LCD_Y_SIZE)
#define FRAME_MEM_BASE SRAM_AXI_BASE
#define QSPI_CLK_MHZ (25)
#if (FRAME_MEM_SIZE > SRAM_AXI_SIZE)
#error "lcdqspi frame cache size is not enough!"
#endif
static uint8_t frame_cache[LCD_Y_SIZE][LCD_HBYTE] __attribute__ ((at(FRAME_MEM_BASE)));
void rt_hw_us_delay(rt_uint32_t us);
static QSPI_HandleTypeDef QSPI_Handler;
static QSPI_CommandTypeDef QSPI_Cmdhandler;
static struct rt_semaphore trans_sem = {
0};
static struct rt_completion frame_sync = {
0};
static struct rt_timer te_timer = {
0};
static __IO uint32_t te_offset = LCD_TE_OFT;
void QUADSPI_IRQHandler(void)
{
IRQ_ENTER();
HAL_QSPI_IRQHandler(&QSPI_Handler);
IRQ_LEAVE();
}
void MDMA_IRQHandler(void)
{
IRQ_ENTER();
HAL_MDMA_IRQHandler(QSPI_Handler.hmdma);
IRQ_LEAVE();
}
void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi)
{
rt_sem_release(&trans_sem);
}
void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi)
{
rt_sem_release(&trans_sem);
}
void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
{
static MDMA_HandleTypeDef hmdma;
__HAL_RCC_QSPI_CLK_ENABLE();
__HAL_RCC_QSPI_FORCE_RESET();
__HAL_RCC_QSPI_RELEASE_RESET();
__HAL_RCC_MDMA_CLK_ENABLE();
__HAL_RCC_MDMA_FORCE_RESET();
__HAL_RCC_MDMA_RELEASE_RESET();
HAL_NVIC_SetPriority(QUADSPI_IRQn, NVIC_PRIORITY_QSPI, 0);
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
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 = 16;
hmdma.Init.SourceBurst = MDMA_SOURCE_BURST_SINGLE;
hmdma.Init.DestBurst = MDMA_DEST_BURST_SINGLE;
hmdma.Init.SourceBlockAddressOffset = 0;
hmdma.Init.DestBlockAddressOffset = 0;
hmdma.Instance = MDMA_Channel1;
__HAL_LINKDMA(hqspi, hmdma, hmdma);
HAL_MDMA_DeInit(&hmdma);
HAL_MDMA_Init(&hmdma);
HAL_NVIC_SetPriority(MDMA_IRQn, 0x00, 0);
HAL_NVIC_EnableIRQ(MDMA_IRQn);
}
void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
{
__HAL_RCC_QSPI_FORCE_RESET();
__HAL_RCC_QSPI_RELEASE_RESET();
HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
__HAL_RCC_MDMA_FORCE_RESET();
__HAL_RCC_MDMA_RELEASE_RESET();
HAL_NVIC_DisableIRQ(MDMA_IRQn);
}
/* QSPI initialize */
static void ll_qspi_init(void)
{
static DMA_HandleTypeDef hdma;
__HAL_RCC_QSPI_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
QSPI_Handler.Instance = QUADSPI;
/* D1HCLK(200MHz) / (prescaler + 1) = 200/5 = 40MHZ */
QSPI_Handler.Init.ClockPrescaler = 200 / QSPI_CLK_MHZ - 1;
QSPI_Handler.Init.FifoThreshold = 16;
QSPI_Handler.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
QSPI_Handler.Init.FlashSize = POSITION_VAL(0X800000)-1;
QSPI_Handler.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_5_CYCLE;
/* clock keep high level in idle time cs inactive */
QSPI_Handler.Init.ClockMode = QSPI_CLOCK_MODE_3;
QSPI_Handler.Init.FlashID = QSPI_FLASH_ID_1;
QSPI_Handler.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
HAL_QSPI_Init(&QSPI_Handler);
/* 0xde is the first byte every transmit */
QSPI_Cmdhandler.Instruction = 0xde;
/* qspi 24bit address, lcd command is set in A15~A8 */
QSPI_Cmdhandler.Address = 0x000000;
QSPI_Cmdhandler.DummyCycles = 0;
QSPI_Cmdhandler.InstructionMode = QSPI_INSTRUCTION_1_LINE;
QSPI_Cmdhandler.AddressMode = QSPI_ADDRESS_1_LINE;
QSPI_Cmdhandler.AddressSize = QSPI_ADDRESS_24_BITS;
QSPI_Cmdhandler.DataMode = QSPI_DATA_NONE;
QSPI_Cmdhandler.NbData = 0;
QSPI_Cmdhandler.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
QSPI_Cmdhandler.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
QSPI_Cmdhandler.DdrMode = QSPI_DDR_MODE_DISABLE;
QSPI_Cmdhandler.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
}
/* lcd delay millisecond */
__INLINE static void lcd_dlyms(uint32_t ms)
{
rt_thread_delay(ms);
}
__INLINE static void lcd_dlyus(uint32_t us)
{
rt_hw_us_delay(us);
}
/* lcd transmit, write command, write display data */
static void lcd_transmit(uint32_t cmd, uint32_t len, uint8_t *dat)
{
if (len == 0)
{
/* write command, no parameter */
#if (CMD_LANE == CMD_LANE_1)
QSPI_Cmdhandler.Instruction = 0xd8;
QSPI_Cmdhandler.InstructionMode = QSPI_INSTRUCTION_1_LINE;
QSPI_Cmdhandler.AddressMode = QSPI_ADDRESS_1_LINE;
QSPI_Cmdhandler.DataMode = QSPI_DATA_NONE;

本文介绍了如何在NUCLEO-H743ZI2板上通过驱动指令优化处理1和4个LANE的兼容,并详细展示了QSPI初始化、LCD操作函数及帧缓存管理。着重于LCD驱动的配置和STM32平台上的内存优化,以解决UI资源放置问题。

8390

被折叠的 条评论
为什么被折叠?



