メイン・コンテンツまでスキップ

SPI

このシナリオは、SPIを使用し、TouchGFX GeneratorでCustomディスプレイ・インタフェースを選択した場合の、一般的なTouchGFXドライバ作成手順を説明するものです。 これらの手順は、マイクロコントローラにディスプレイ・コントローラが組み込まれていない、他のディスプレイ・インタフェースに対する手順と同じです。

STM32CubeMXでSPIペリフェラルの設定が完了すれば、TouchGFX Generatorを使用し、Customディスプレイ・インタフェースを使用することで、HALを生成できます。これにより開発者は、開発者自身が作成した適切なドライバを使用して、フレームバッファの更新部分を接続されたディスプレイに転送できるようになります。 図Xに示すTouchGFX Generatorの設定では、Customディスプレイ・インタフェースを選択することで、生成されたコードが、フレームバッファの更新部分のディスプレイへの転送をサポートできるようになります。

プロジェクト作業

一般的に、8080やSPIディスプレイなどのGRAMを内蔵したディスプレイの場合、ドライバは次のように構成されます。

  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内の仮想「カーソル」のx およびy 座標を、特定のレジスタに書き込んで設定します。これは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)を一度に1ラインずつ送信し、それに応じてフレームバッファのポインタが進んでいることを確認するプライベート関数です。

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を使用する場合、開発者はDMA完了割込み信号によるセマフォを待機することで、HAL::flushFrameBuffer(Rect& rect)が戻らないようにする必要があります。