20const uint32_t HEADER_BYTES = 12;
23const uint32_t HEADER_MAGIC = 0x314C4143;
26const uint16_t HEADER_VERSION = 1;
34uint32_t crc32(
const uint8_t *data, uint32_t length) {
35 uint32_t crc = 0xFFFFFFFFu;
36 for (uint32_t i = 0; i < length; i++) {
38 for (
int bit = 0; bit < 8; bit++) {
39 crc = (crc & 1u) ? ((crc >> 1) ^ 0xEDB88320u) : (crc >> 1);
53bool storageRead(
void *ctx, uint32_t address, uint8_t *data, uint32_t length) {
58 return fram->
read(
static_cast<uint16_t
>(address), data, length);
71bool storageWrite(
void *ctx, uint32_t address,
const uint8_t *data, uint32_t length) {
74 !fram->
write(
static_cast<uint16_t
>(address), data, length)) {
75 printf(
"Calibration storage write failed (address 0x%04lX, %lu bytes)\r\n", (
unsigned long) address,
76 (
unsigned long) length);
95 if (display ==
nullptr || fram ==
nullptr) {
96 printf(
"touchCalibrationAttachStorage: display or FRAM object is missing\r\n");
115 if (display ==
nullptr || fram ==
nullptr || matrix ==
nullptr) {
116 printf(
"touchCalibrationLoad: missing argument\r\n");
121 uint8_t header[HEADER_BYTES];
123 printf(
"Stored calibration: header could not be read\r\n");
128 const uint32_t magic = (uint32_t) header[0] | ((uint32_t) header[1] << 8) | ((uint32_t) header[2] << 16) |
129 ((uint32_t) header[3] << 24);
130 const uint16_t version = (uint16_t) (header[4] | (header[5] << 8));
131 const uint16_t length = (uint16_t) (header[6] | (header[7] << 8));
132 const uint32_t storedCrc = (uint32_t) header[8] | ((uint32_t) header[9] << 8) | ((uint32_t) header[10] << 16) |
133 ((uint32_t) header[11] << 24);
135 if (magic != HEADER_MAGIC) {
136 printf(
"Stored calibration: none (no marker in the FRAM)\r\n");
139 if (version != HEADER_VERSION || length != BLOCK_BYTES) {
140 printf(
"Stored calibration: unknown format (version %u, length %u)\r\n", (
unsigned) version,
145 uint8_t block[BLOCK_BYTES];
147 printf(
"Stored calibration: matrix block could not be read\r\n");
151 if (crc32(block, BLOCK_BYTES) != storedCrc) {
152 printf(
"Stored calibration: checksum does not match, data is damaged\r\n");
157 printf(
"Stored calibration: the library does not report it as calibrated\r\n");
161 printf(
"Stored calibration: matrix divider is zero, not usable\r\n");
176 if (display ==
nullptr || fram ==
nullptr || matrix ==
nullptr) {
177 printf(
"touchCalibrationSave: missing argument\r\n");
185 uint8_t block[BLOCK_BYTES];
187 printf(
"Calibration save: matrix block could not be read back\r\n");
191 const uint32_t crc = crc32(block, BLOCK_BYTES);
194 uint8_t header[HEADER_BYTES];
195 header[0] = (uint8_t) (HEADER_MAGIC & 0xFF);
196 header[1] = (uint8_t) ((HEADER_MAGIC >> 8) & 0xFF);
197 header[2] = (uint8_t) ((HEADER_MAGIC >> 16) & 0xFF);
198 header[3] = (uint8_t) ((HEADER_MAGIC >> 24) & 0xFF);
199 header[4] = (uint8_t) (HEADER_VERSION & 0xFF);
200 header[5] = (uint8_t) (HEADER_VERSION >> 8);
201 header[6] = (uint8_t) (BLOCK_BYTES & 0xFF);
202 header[7] = (uint8_t) (BLOCK_BYTES >> 8);
203 header[8] = (uint8_t) (crc & 0xFF);
204 header[9] = (uint8_t) ((crc >> 8) & 0xFF);
205 header[10] = (uint8_t) ((crc >> 16) & 0xFF);
206 header[11] = (uint8_t) ((crc >> 24) & 0xFF);
208 printf(
"Calibration save: header could not be written\r\n");
218 return memcmp(&check, matrix,
sizeof(
tsMatrix_t)) == 0;
#define CFG_EEPROM_TOUCHSCREEN_CALIBRATED
EEPROM Storage Location.
Class that stores state and functions for interacting with the RA8875 display controller.
bool readCalibration(int location, tsMatrix_t *matrixPtr)
void writeCalibration(int location, tsMatrix_t *matrixPtr)
void setCalibrationStorage(StorageReadFn read, StorageWriteFn write, void *ctx, uint32_t sizeBytes)
Driver for one MB85RS64V SPI FRAM (8192 bytes) on an STM32 HAL SPI bus.
bool read(uint16_t address, uint8_t *buffer, size_t length)
Reads bytes from the FRAM array (READ, 03h).
static constexpr uint16_t SIZE_BYTES
Capacity in bytes (8192; addresses 0x0000 to 0x1FFF).
bool write(uint16_t address, const uint8_t *data, size_t length)
Writes bytes to the FRAM array (WREN, then WRITE, 02h); a retry repeats both steps.
: Header for main.c file. This file contains the common defines of the application.
bool touchCalibrationSave(Adafruit_RA8875 *display, MB85RS64V *fram, tsMatrix_t *matrix)
Saves the calibration matrix to the FRAM and checks it by reading it back.
bool touchCalibrationLoad(Adafruit_RA8875 *display, MB85RS64V *fram, tsMatrix_t *matrix)
Loads the calibration matrix from the FRAM if a valid one is stored.
void touchCalibrationAttachStorage(Adafruit_RA8875 *display, MB85RS64V *fram)
Registers the FRAM read and write callbacks with the display library.
Stores the touch calibration matrix in the MB85RS64V FRAM and checks it when loading.
constexpr uint16_t TOUCH_CAL_ADDRESS
FRAM address of the calibration matrix block written by the RA8875 library.
constexpr uint16_t TOUCH_CAL_HEADER_ADDRESS
FRAM address of the 12-byte validity header.