Project Objective
Following the successful implementation of PWM-based breathing light effects, the next phase involves expanding the user interface capabilities of the XR806 development board. To achieve richer information display, a TFT LCD module is integrated using the hardware SPI peripheral. This guide details the wiring, driver adaptation, and image rendering process.
Hardware Connection
The display module requires both 5V and 3.3V power rails. The XR806 board provides both, simplifying the power supply design. The SPI communication utilizes four primary signals along with control lines for chip seletcion and reset. The backlight is configured for constant illumination via the 3.3V rail.
| XR806 Pin | TFT LCD Pin | Function |
|---|---|---|
| 5V | VCC | Power Supply |
| GND | GND | Ground |
| A13 | CS | Chip Select (Active Low) |
| A12 | RESET | Hardware Reset |
| A11 | RS | Data/Command Select |
| B04 | MOSI | SPI Data Input |
| B07 | SCK | SPI Clock |
| 3V3 | LED | Backlight Power |
Implementation Strategy
The software development follows a layered approach:
- SPI Verification: Configure the hardware SPI peripheral and validate communication integrity using a loopback test (connecting MOSI to MISO).
- Driver Porting: Adapt existing LCD driver logic to utilize the XR806 Hardware Abstraction Layer (HAL) for SPI transactions.
- Asset Conversion: Convert bitmap images into C-style arrays using a tool like Image2Lcd for embedded storage.
Core Implementation
1. Pin Configuration
GPIO pins are defined for control signals. Macros are used to abstract the setting and clearing of these lines.
#define PIN_LCD_CS 13
#define PIN_LCD_RST 12
#define PIN_LCD_DC 11
#define PIN_LCD_BL 19
#define LCD_CS_ASSERT IoTGpioSetOutputVal(PIN_LCD_CS, 0)
#define LCD_CS_DEASSERT IoTGpioSetOutputVal(PIN_LCD_CS, 1)
#define LCD_DC_DATA IoTGpioSetOutputVal(PIN_LCD_DC, 1)
#define LCD_DC_CMD IoTGpioSetOutputVal(PIN_LCD_DC, 0)
#define LCD_RST_HIGH IoTGpioSetOutputVal(PIN_LCD_RST, 1)
#define LCD_RST_LOW IoTGpioSetOutputVal(PIN_LCD_RST, 0)
2. SPI Peripheral Initialization
The SPI controller is configured in master mode with polling operation. The clock speed is set to 24MHz.
void InitHardwareSPI(void) {
SPI_InitCfg spiSettings;
HAL_Status status;
spiSettings.csPolarity = DEMO_SPI_CS_LEVEL;
spiSettings.masterClock = DEMO_SPI_MCLK;
HAL_SPI_Init(DEMO_SPI_PORT, &spiSettings);
SPI_Config regConfig;
regConfig.firstBit = SPI_TCTRL_FBS_MSB;
regConfig.mode = SPI_CTRL_MODE_MASTER;
regConfig.opMode = SPI_OPERATION_MODE_POLL;
regConfig.sclk = 24000000;
regConfig.sclkMode = SPI_SCLK_Mode0;
printf("Initializing SPI interface...\n");
status = HAL_SPI_Open(DEMO_SPI_PORT, DEMO_SPI_CS, ®Config, 5000);
if (status != HAL_OK) {
printf("SPI initialization failed\n");
return;
}
HAL_SPI_Config(DEMO_SPI_PORT, SPI_ATTRIBUTION_IO_MODE, SPI_IO_MODE_NORMAL);
}
3. GPIO Setup
Control pins are initialized as outputs to manage the display state.
void SetupDisplayGPIO(void) {
IoTGpioInit(PIN_LCD_RST);
IoTGpioSetDir(PIN_LCD_RST, IOT_GPIO_DIR_OUT);
IoTGpioInit(PIN_LCD_CS);
IoTGpioSetDir(PIN_LCD_CS, IOT_GPIO_DIR_OUT);
IoTGpioInit(PIN_LCD_DC);
IoTGpioSetDir(PIN_LCD_DC, IOT_GPIO_DIR_OUT);
IoTGpioInit(PIN_LCD_BL);
IoTGpioSetDir(PIN_LCD_BL, IOT_GPIO_DIR_OUT);
}
4. Data Transmission Layer
The底层 SPI write function is wrapped to handle single-byte transactions compatible with the LCD driver.
uint8_t HAL_SPI_SendByte(uint8_t port, uint8_t data) {
uint8_t txBuffer = data;
uint8_t rxBuffer = 0;
HAL_Status status;
status = HAL_SPI_TransmitReceive(port, &txBuffer, &rxBuffer, 1);
if (status != HAL_OK) {
printf("SPI transmission error\n");
return 0;
}
return rxBuffer;
}
5. Display Execution
Once initialized, the image data array is rendered to the screen. The example below tiles the image across the display area.
LCD_Init1();
for (int row = 0; row < 6; row++) {
for (int col = 0; col < 5; col++) {
Gui_Drawbmp16(50 * col, 50 * row, gImage_jishu);
}
}
Compilation Constraints and Memory Issues
During the build process, a significant limitation was encountered regarding flash memory allocation. When the bitmap data array exceeds a certain size, the linker fails to allocate sections correctly.
The build system reports a overlap error between the application binary (app.bin) and the XIP binary (app_xip.bin). Specifically, the error log endicates:
[OHOS ERROR] err: bin 1 and bin 2 were overlaped!
[OHOS ERROR] Overlapped size: 1024 Byte(1kB)
[OHOS ERROR] bin 1 name:app.bin begin: 0x00008000 end: 0x00019000
[OHOS ERROR] bin 2 name:app_xip.bin begin: 0x00018C00
This suggests that the available code space is insufficient for large image arrays combined with the full SDK features. Features such as character rendering and complex graphics were omitted to accommodate the image data. Further optimization of the linker script or reduction of asset resolution is required to resolve the memory overlap.