フレームバッファ設定
このセクションでは、以下のいずれかのフレームバッファ設定を使用するTouchGFX HALを生成するためのTouchGFX Generatorの設定方法について説明します。
- シングル
- ダブル
- 部分
フレームバッファの詳細については、こちらを参照してください。
シングル・フレームバッファ
バッファの設定として[Single Buffer] を選択すると、コンパイラが内蔵RAMにフレームバッファ用メモリを割り当てることができますが、このバッファ用に特定の場所を選択することも可能です。
By Allocation
[By Allocation]を選択すると、TouchGFX Generatorは、アプリケーションの寸法とビット深度に基づいた配列を割り当てます。
この配列をフレームバッファとして使用するようにHALを設定するコードが生成されます。
TouchGFXGeneratedHAL.cpp
namespace {
// Use the section "TouchGFX_Framebuffer" in the linker script
// to specify the placement of the buffer
LOCATION_PRAGMA("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 272 * 2 + 3) / 4] LOCATION_ATTRIBUTE("TouchGFX_Framebuffer");
}
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
setFrameBufferStartAddresses((void*)frameBuf, (void*)0, (void*)0);
}
By Address
フレームバッファの場所として[By Address] [By Address]</525>を選択すると、TouchGFX GeneratorはHAL初期化時に指定された開始アドレスを使用します。
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0, (void*)0);
}
ダブル・フレームバッファ
ダブル・フレームバッファ構成の場合、選択したフレームバッファ設定とディスプレイ・インタフェースに応じて、TouchGFX GeneratorによりフレームバッファをスワップするコードがHAL内に生成されます。 このフレームバッファ位置へのメモリ・インタフェースは、メイン・イベント・ループでTouchGFXエンジンによって使用されます。
By Address
[By Address] を選択すると、TouchGFX GeneratorはHAL初期化時に指定された2つの開始アドレスを使用します。
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC003FC00, (void*)0);
}
Tip
Tip
By Allocation
[By Allocation]を選択すると、TouchGFX Generatorは、シングル・フレームバッファの場合とまったく同様に、アプリケーションの寸法とビット深度に基づいた配列を、サイズを2倍にして割り当てます。
TouchGFXGeneratedHAL.cpp
namespace {
// Use the section "TouchGFX_Framebuffer" in the linker to specify the placement of the buffer
LOCATION_PRAGMA("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 272 * 2 + 3) / 4 * 2] LOCATION_ATTRIBUTE("TouchGFX_Framebuffer");
}
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf)/(sizeof(uint32_t)*2)), (void*)0);
}
パーシャル・フレームバッファ
パーシャル・フレームバッファ設定では、TouchGFXはディスプレイと同じサイズのフレームバッファを使用しません。 代わりに、フレームバッファとして使用する(所定のサイズの)ブロックの数をユーザが選択できます。 TouchGFXはフレームバッファ・アロケータ・オブジェクトを使用して、これらのブロックの使用方法を制御します。
この設定では、ユーザは(フレームバッファが配置される)外部メモリにポインタを指定することも、内部メモリにフレームバッファ配列を割り当てることもしません。
フレームバッファの概念の概要については、「フレームバッファ」の記事を参照してください。
Tip
パーシャル・フレームバッファ設定が採用されるのは、通常、TFTコントローラを搭載せず、内蔵RAM容量が小さい低コストのマイクロコントローラの場合に限られるため、フレームバッファの内容をディスプレイに転送する機能は開発者が実装するものと想定されています。 TFTコントローラを搭載していないマイクロコントローラでシリアル・ディスプレイなどにピクセルを転送する方法については、FMC / SPIシナリオを参照してください。
パーシャル・フレームバッファ設定を使用して、ディスプレイをTouchGFXとリンクさせるには、次の2つの関数を実装する必要があります。 以下に示すコードは、CubeMXによってTouchGFX/target/generated/TouchGFXGeneratedHAL.cpp
内に生成されたもので、TouchGFXエンジンとディスプレイ・ドライバ間のインタフェースを定義しています。
TouchGFXGeneratedHAL.cpp
/* ******************************************************
* Functions required by Partial Frame Buffer Strategy
* ******************************************************
*
* int touchgfxDisplayDriverTransmitActive() must return whether or not data is currently being transmitted, over e.g. SPI.
* void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h) will be called
* when the framework wants to send a block. The user must then transfer the data represented by the arguments.
*/
extern "C" int touchgfxDisplayDriverTransmitActive();
extern "C" int touchgfxDisplayDriverShouldTransferBlock(uint16_t bottom);
extern "C" void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
extern "C" void touchgfxSignalVSync(void);
TouchGFX Designerで使用できるSTM32G071のTouchGFXボード設定の場合、これらの関数はCore/Src/MB1642BDisplayDriver.c
に実装されます(ここでは1つだけ示します)。
Core/Src/MB1642BDisplayDriver.c
int touchgfxDisplayDriverTransmitActive(void)
{
return IsTransmittingBlock_;
}
この設定により、CubeMXも、TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp
の読み出し専用のTouchGFXGeneratedHAL
クラス内に、TouchGFXGeneratedHAL::flushFrameBuffer(Rect&)
を生成します。
Note
TouchGFXGeneratedHAL.cpp
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HAL::flushFrameBuffer(rect);
// Try transmitting a block
PartialFrameBufferManager::tryTransmitBlock();
}