F439_CPP_SPI_RA8875_TFT_LCD_04 1.0
STM32F439 SPI RA8875 7-inch TFT display with FRAM-backed touch calibration, built on the STM32_GFX, STM32_RA8875 and STM32_MB85RS64V libraries
Loading...
Searching...
No Matches
entryPointCPP.hpp File Reference

C-callable entry points into the C++ RA8875 display code. More...

#include "main.h"
#include <stdbool.h>

Go to the source code of this file.

Functions

void initTest (SPI_HandleTypeDef *halSPI)
 Creates the display object and starts the RA8875 controller.
 
void testLCD (bool buildTest)
 Runs one of the two display demonstrations.
 
void initFRAM (SPI_HandleTypeDef *halSPI)
 Creates the FRAM driver object and checks that the chip answers.
 
void testFRAM (void)
 Shows that the FRAM keeps its data, then does a write and read-back test.
 
bool initTouchCalibration (void)
 Reads the touch calibration stored in the FRAM and reports it on the redirected USART.
 
void testTouch (UART_HandleTypeDef *huart)
 Enables touch, runs the three-point calibration and shows the result.
 

Detailed Description

C-callable entry points into the C++ RA8875 display code.

Project: F439_CPP_SPI_RA8875_TFT_LCD_04

The CubeMX-generated main.c is plain C, so it cannot create or call the C++ Adafruit_RA8875 object directly. This header declares the small set of extern "C" functions that main.c calls instead; their bodies are in entryPointCPP.cpp, which owns the display object.

Created on: Jan 26, 2025 Author: johng

Definition in file entryPointCPP.hpp.

Function Documentation

◆ initFRAM()

void initFRAM ( SPI_HandleTypeDef * halSPI)

Creates the FRAM driver object and checks that the chip answers.

Parameters
halSPIHandle of the SPI peripheral shared with the display (SPI1).

Constructs an MB85RS64V with the SPI handle and the chip-select pin MB85RS64_CS (PB10), then calls MB85RS64V::begin(), which reads the device ID and checks it. The ID is then read once more to be printed, and that read is checked against 04h 7Fh 03h 02h too: a transfer can complete without error and still return wrong bytes (an all-zero reply was seen once), so a wrong or failed read is retried, up to 3 attempts, before it counts as a failure. Prints the result on the redirected USART. If the object cannot be allocated, the chip does not answer, or the ID is still wrong after 3 attempts, it prints the reason (for "not found" also the SPI settings and the status register) and calls Error_Handler(), which does not return. The FRAM shares SPI1 with the RA8875 display, so call it after initTest() has finished: the display library has then left the bus in the settings the FRAM also accepts.

Note
Call it once from main.c, after initTest(), inside a USER CODE section.
Warning
Not thread-safe and not ISR-safe: it stores the new object in a shared global pointer without any lock, and begin() is a sequence of separate SPI transactions on a bus another driver also uses. Call it once, from the main thread, while nothing else is using SPI1.

Definition at line 300 of file entryPointCPP.cpp.

References MB85RS64V::begin(), MB85RS64V::ID_LENGTH, initFRAM(), MB85RS64V::lastStatus(), MB85RS64V::readId(), and MB85RS64V::readStatus().

Referenced by initFRAM(), and main().

◆ initTest()

void initTest ( SPI_HandleTypeDef * halSPI)

Creates the display object and starts the RA8875 controller.

Parameters
halSPIHandle of the SPI peripheral wired to the display (SPI1 here, set up by CubeMX as master, full duplex, 8-bit, mode 0, MSB first, software NSS).

Constructs an Adafruit_RA8875 with the SPI handle and the CS (RA8875_CS_*) and RESET (LCD_RESET_*) pins from main.h, then calls Adafruit_RA8875::begin() for an 800x480 panel. begin() sets CS high, pulses RESET, reads the chip ID (it must be 0x75), initialises the controller and raises the SPI clock, so nothing else needs to be done here. Prints "RA8875 Found" on the redirected USART. The object is created with new (std::nothrow), so a failed allocation returns a null pointer instead of throwing; that is checked before the object is used, and the reason is printed. If the object cannot be allocated, or the chip does not answer, it prints the reason and calls Error_Handler(), which does not return. The WAIT and INT pins are not used.

Note
Call it once from main.c, after the CubeMX MX_..._Init() calls, inside a USER CODE section. The object is created with new at this point, not as a global, so it is not constructed before the clocks and the SPI peripheral exist.
Warning
Not thread-safe and not ISR-safe: it stores the new object in a shared global pointer without any lock, and begin() is a sequence of separate SPI transactions. A task switch (or an interrupt) that called testLCD() or any other display call in between would use a half-initialised display or interleave its SPI transfers with begin()'s. Call it once, from the main thread, before anything else touches the display.

Definition at line 59 of file entryPointCPP.cpp.

References Adafruit_RA8875::begin(), initTest(), and RA8875_800x480.

Referenced by initTest(), and main().

◆ initTouchCalibration()

bool initTouchCalibration ( void )

Reads the touch calibration stored in the FRAM and reports it on the redirected USART.

Returns
true if a valid calibration was read; false if the FRAM holds none, or one that fails its checks (the reason is printed). A blank or damaged FRAM is not a fault of the program, so this does not call Error_Handler() for it: the caller decides what to do.

Prints "Reading the stored touch calibration from the FRAM", then either the matrix that was read or the reason it could not be used. The matrix is kept inside entryPointCPP.cpp for later use. If the display or FRAM object does not exist it prints the reason and calls Error_Handler(), which does not return.

Note
initTest() and initFRAM() must have run first. Call it once from main.c inside a USER CODE section.
Warning
Not thread-safe and not ISR-safe: it writes shared file-scope variables without a lock and does several separate SPI transactions on a bus shared with the display. Call it from one thread only, while the display code is idle.

Definition at line 442 of file entryPointCPP.cpp.

References tsMatrix_t::An, tsMatrix_t::Bn, tsMatrix_t::Cn, tsMatrix_t::Divider, tsMatrix_t::Dn, tsMatrix_t::En, tsMatrix_t::Fn, initTouchCalibration(), touchCalibrationAttachStorage(), and touchCalibrationLoad().

Referenced by initTouchCalibration(), and main().

◆ testFRAM()

void testFRAM ( void )

Shows that the FRAM keeps its data, then does a write and read-back test.

Reads and prints the first 16 bytes (what the previous run left there, so a power cycle demonstrates the non-volatility), writes a new pattern whose first byte is a boot counter, reads it back and compares. Prints each step on the redirected USART. Uses address 0x0000 only. On any failure (read, write or mismatch) it calls Error_Handler(), which does not return.

Note
initFRAM() must have run first; if it has not, this prints an error and calls Error_Handler().
Warning
Not thread-safe and not ISR-safe: each driver call is a separate SPI transaction on a bus shared with the display, so a task switch or interrupt that drew on the display between two of them could interleave its bytes. Call it from one thread only, while the display code is idle. It blocks for the duration of a few short SPI transfers.

Definition at line 377 of file entryPointCPP.cpp.

References MB85RS64V::lastStatus(), MB85RS64V::read(), testFRAM(), and MB85RS64V::write().

Referenced by main(), and testFRAM().

◆ testLCD()

void testLCD ( bool buildTest)

Runs one of the two display demonstrations.

Parameters
buildTesttrue runs the graphics demo, false runs the text demo.

The graphics demo turns the display on, enables the backlight output, fills the screen with seven colours in turn, then draws a circle, rectangles, a rounded rectangle, single pixels, a line, triangles, ellipses and curves using the RA8875's hardware drawing commands. The text demo clears the screen, switches to the controller's text mode and prints "Hello, World!" in several foreground and background colours and four enlargement sizes, with a blinking cursor. Progress is printed on the redirected USART. If PWM is defined at build time, the graphics demo also sweeps the PWM1 output down and up; it is compiled out by default because on Adafruit's board PWM1 does not reach the backlight (see the Adafruit_RA8875 documentation).

Note
initTest() must have run first. If it has not, testLCD() prints an error and calls Error_Handler() instead of using a NULL display.
Warning
Not thread-safe and not ISR-safe: every drawing call is several separate SPI transactions (set the cursor, then the colour, then the draw command), all on one shared display object. A task switch between two of them lets a second caller's commands interleave with the first caller's and corrupt both. Call it from one thread only, and never from an interrupt. The demos also block for several seconds in HAL_Delay().

Definition at line 104 of file entryPointCPP.cpp.

References Adafruit_RA8875::cursorBlink(), Adafruit_RA8875::displayOn(), Adafruit_RA8875::drawCircle(), Adafruit_RA8875::drawCurve(), Adafruit_RA8875::drawEllipse(), Adafruit_RA8875::drawLine(), Adafruit_RA8875::drawPixel(), Adafruit_RA8875::drawRect(), Adafruit_RA8875::drawTriangle(), Adafruit_RA8875::fillCircle(), Adafruit_RA8875::fillCurve(), Adafruit_RA8875::fillEllipse(), Adafruit_RA8875::fillRect(), Adafruit_RA8875::fillRoundRect(), Adafruit_RA8875::fillScreen(), Adafruit_RA8875::fillTriangle(), Adafruit_RA8875::GPIOX(), Adafruit_RA8875::graphicsMode(), Adafruit_RA8875::PWM1config(), Adafruit_RA8875::PWM1out(), RA8875_BLACK, RA8875_BLUE, RA8875_CYAN, RA8875_GREEN, RA8875_MAGENTA, RA8875_PWM_CLK_DIV1024, RA8875_RED, RA8875_WHITE, RA8875_YELLOW, testLCD(), Adafruit_RA8875::textColor(), Adafruit_RA8875::textEnlarge(), Adafruit_RA8875::textMode(), Adafruit_RA8875::textSetCursor(), Adafruit_RA8875::textTransparent(), and Adafruit_RA8875::textWrite().

Referenced by main(), and testLCD().

◆ testTouch()

void testTouch ( UART_HandleTypeDef * huart)

Enables touch, runs the three-point calibration and shows the result.

Switches the display and its backlight on, enables the RA8875's touch panel, then runs the interactive calibration (three targets, touched one at a time) and prints the raw and display coordinates of each target on the redirected USART. Afterwards it clears the screen and, for about 15 seconds, draws a small red dot wherever the screen is touched, using the calibrated position, and prints the raw and calibrated coordinates of each touch.

This is calibration mode: it always runs the interactive calibration, ignores whatever calibration the FRAM already holds, and overwrites it with the new matrix (see touchCalibrationStorage.hpp), which is read back to check it. If the display or FRAM object does not exist, the calibration fails after repeated attempts, or the stored copy does not read back correctly, it prints the reason and calls Error_Handler(), which does not return.

Parameters
huartUART handle of the serial terminal (USART1); the calibration asks for the space bar on it between the targets, so the terminal must be open and able to send keys.
Note
initTest() and initFRAM() must have run first. Call it from main.c inside a USER CODE section.
Warning
Not thread-safe and not ISR-safe: it uses the one shared display object, and every drawing and touch call is several separate SPI transactions on a bus shared with the FRAM driver, so a task switch or interrupt that used the display or the FRAM in between could interleave its transfers and corrupt both. Call it from one thread only, while nothing else uses SPI1. It blocks until the user has touched all three targets.

Definition at line 468 of file entryPointCPP.cpp.

References tsMatrix_t::An, tsMatrix_t::Bn, tsMatrix_t::Cn, Adafruit_RA8875::displayOn(), tsMatrix_t::Divider, tsMatrix_t::Dn, tsMatrix_t::En, Adafruit_RA8875::fillCircle(), Adafruit_RA8875::fillScreen(), tsMatrix_t::Fn, Adafruit_RA8875::GPIOX(), Adafruit_RA8875::height(), Adafruit_RA8875::PWM1config(), Adafruit_RA8875::PWM1out(), RA8875_PWM_CLK_DIV1024, RA8875_RED, RA8875_WHITE, testTouch(), touchCalibrationApply(), touchCalibrationAttachStorage(), touchCalibrationRun(), touchCalibrationSave(), Adafruit_RA8875::touched(), Adafruit_RA8875::touchEnable(), Adafruit_RA8875::touchRead(), Adafruit_RA8875::width(), Point::x, and Point::y.

Referenced by main(), and testTouch().