跳转到主要内容

SPI

下列场景显示了在一般情况下,在TouchGFX Generator中选择“Custom”显示接口并使用SPI时,创建TouchGFX驱动程序所包含的步骤。 包含的步骤与MCU无嵌入式显示控制器时使用的其他显示接口相同。

在STM32CubeMX中配置SPI外设后,可以使用TouchGFX Generator生成HAL,生成时使用“自定义”显示接口,以便开发者使用自己编写的专属驱动将帧缓冲的更新部分传输到连接的显示屏。 图X显示了TouchGFX Generator的配置,在其中选择Custom显示接口,这样生成的代码可支持将更新后的帧缓冲部分传输到显示屏。

项目活动

通常,对于自带GRAM的显示屏(如8080或SPI接口显示屏),驱动程序的构成方式如下:

  1. 根据要重绘的帧缓存区域,将“显示光标”移动到GRAM中与此对应的位置。
  2. 准备将传入的像素数据写入GRAM。
  3. 发送像素数据。

传输帧缓存内容

在帧缓存内容被更新后,TouchGFX Engine会调用HAL::flushFrameBuffer

响应来自TouchGFX Engine的信号 (S?)。

void  TouchGFXHAL::flushFrameBuffer(const Rect& rect)
{
/* Set Cursor */
__ST7789H2_SetDisplayWindow(rect.x, rect.y, rect.width, rect.height);

/* Prepare to write to LCD RAM */
ST7789H2_WriteReg(ST7789H2_WRITE_RAM, (uint8_t*)NULL, 0);

/* Send Pixels */
this->copyFrameBufferBlockToLCD(rect);
}

以下__ST7789H2_SetDisplayWindow函数通过写入特定寄存器来设置GRAM中虚拟“光标”的xy坐标,对于使用GRAM的显示屏,这很常见的用法。

extern "C"
void __ST7789H2_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
{
uint8_t parameter[4];

/* CASET: Column Address Set */
parameter[0] = 0x00;
parameter[1] = Xpos;
parameter[2] = 0x00;
parameter[3] = Xpos + Width - 1;
ST7789H2_WriteReg(ST7789H2_CASET, parameter, 4);

/* RASET: Row Address Set */
parameter[0] = 0x00;
parameter[1] = Ypos;
parameter[2] = 0x00;
parameter[3] = Ypos + Height - 1;
ST7789H2_WriteReg(ST7789H2_RASET, parameter, 4);
}

以下TouchGFXHAL::copyFrameBufferBlockToLCD函数是一个私有函数,该函数一次发送一行更新过的帧缓存区域(Rect) ,并相应地更新帧缓冲指针。

void TouchGFXHAL::copyFrameBufferBlockToLCD(const Rect rect)
{
__IO uint16_t* ptr;
uint32_t height;

// Use default implementation (CPU copy!).
// This can be accelerated using regular DMA hardware
for (height = 0; height < rect.height ; height++)
{
ptr = getClientFrameBuffer() + rect.x + (height + rect.y) * BSP_LCD_GetXSize();
LCD_IO_WriteMultipleData((uint16_t*)ptr, rect.width);
}
}

flushFrameBuffer返回

在函数返回后,TouchGFX Engine返回。 如果开发者想要使用DMA执行这些传输,则HAL::flushFrameBuffer(Rect& rect)函数必须等到DMA完成中断发送的信号后才返回