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
main.c
Go to the documentation of this file.
1/* USER CODE BEGIN Header */
18/* USER CODE END Header */
19/* Includes ------------------------------------------------------------------*/
20#include "main.h"
21
22/* Private includes ----------------------------------------------------------*/
23/* USER CODE BEGIN Includes */
24#include <stdio.h>
25#include "string.h"
26#include "stdbool.h"
27#include "entryPointCPP.hpp"
28
29/* USER CODE END Includes */
30
31/* Private typedef -----------------------------------------------------------*/
32/* USER CODE BEGIN PTD */
33
34/* USER CODE END PTD */
35
36/* Private define ------------------------------------------------------------*/
37/* USER CODE BEGIN PD */
38
39/* USER CODE END PD */
40
41/* Private macro -------------------------------------------------------------*/
42/* USER CODE BEGIN PM */
43
44/* USER CODE END PM */
45
46/* Private variables ---------------------------------------------------------*/
47SPI_HandleTypeDef hspi1;
48
49TIM_HandleTypeDef htim1;
50TIM_HandleTypeDef htim2;
51
52UART_HandleTypeDef huart1;
53
54/* USER CODE BEGIN PV */
55
56/* USER CODE END PV */
57
58/* Private function prototypes -----------------------------------------------*/
59void SystemClock_Config(void);
60static void MX_GPIO_Init(void);
61static void MX_SPI1_Init(void);
62static void MX_TIM1_Init(void);
63static void MX_TIM2_Init(void);
64static void MX_USART1_UART_Init(void);
65/* USER CODE BEGIN PFP */
66
67/* USER CODE END PFP */
68
69/* Private user code ---------------------------------------------------------*/
70/* USER CODE BEGIN 0 */
71
72#ifdef REDIRECT_PRINTF
73#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
74
75PUTCHAR_PROTOTYPE
76{
77 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
78
79 return ch;
80}
81#endif
82
83#ifdef TOUCH_CALIBRATION_ENABLE
84/* One-character interrupt receive used by the calibration's "space bar or Esc" wait.
85 * touchCalibration.cpp starts the receive with HAL_UART_Receive_IT(). */
87volatile uint8_t uartRxChar = 0;
89volatile uint8_t uartKeyPressed = 0;
90
99void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
100{
101 if (uartRxChar == ' ' || uartRxChar == 0x1B)
102 {
104 return;
105 }
106 if (HAL_UART_Receive_IT(huart, (uint8_t *)&uartRxChar, 1) != HAL_OK)
107 {
108 Error_Handler();
109 }
110}
111
119void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
120{
121 if (HAL_UART_Receive_IT(huart, (uint8_t *)&uartRxChar, 1) != HAL_OK)
122 {
123 Error_Handler();
124 }
125}
126#endif /* TOUCH_CALIBRATION_ENABLE */
127
128/* USER CODE END 0 */
129
134int main(void)
135{
136
137 /* USER CODE BEGIN 1 */
138
139 /* USER CODE END 1 */
140
141 /* MCU Configuration--------------------------------------------------------*/
142
143 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
144 HAL_Init();
145
146 /* USER CODE BEGIN Init */
147
148 /* USER CODE END Init */
149
150 /* Configure the system clock */
151 SystemClock_Config();
152
153 /* USER CODE BEGIN SysInit */
154
155 /* USER CODE END SysInit */
156
157 /* Initialize all configured peripherals */
158 MX_GPIO_Init();
159 MX_SPI1_Init();
160 MX_TIM1_Init();
161 MX_TIM2_Init();
162 MX_USART1_UART_Init();
163 /* USER CODE BEGIN 2 */
164
165 printf("\x1b[2J\x1b[H"); // Clear the dumb terminal screen
166 printf("Starting Initialization Process\r\n");
167
168 initTest(&hspi1);
169
170 // The FRAM shares SPI1 with the display, so it is started after the display is up
171 initFRAM(&hspi1);
172 testFRAM();
173
174 // Report the touch calibration the FRAM holds (calibration mode below overwrites it)
176
177#ifdef TOUCH_CALIBRATION_ENABLE
178 // Calibration mode: run the touch calibration, store it in the FRAM, then a short touch-to-draw demo
179 testTouch(&huart1);
180
181 // Calibration is the whole job of this project step, so stop here: the graphics demos are not run
182 printf("Calibration Complete\r\n");
183 while (1)
184 {
185 HAL_Delay(1000);
186 }
187#endif /* TOUCH_CALIBRATION_ENABLE */
188
189 HAL_Delay(500);
190
191 /* USER CODE END 2 */
192
193 /* Infinite loop */
194 /* USER CODE BEGIN WHILE */
195 while (1)
196 {
197 printf("Start Tests\r\n");
198 testLCD(true);
199 HAL_Delay(5000);
200 testLCD(false);
201 printf("Done\r\n");
202 HAL_Delay(5000);
203 /* USER CODE END WHILE */
204
205 /* USER CODE BEGIN 3 */
206 }
207 /* USER CODE END 3 */
208}
209
214void SystemClock_Config(void)
215{
216 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
217 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
218
221 __HAL_RCC_PWR_CLK_ENABLE();
222 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
223
227 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
228 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
229 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
230 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
231 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
232 RCC_OscInitStruct.PLL.PLLM = 8;
233 RCC_OscInitStruct.PLL.PLLN = 180;
234 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
235 RCC_OscInitStruct.PLL.PLLQ = 4;
236 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
237 {
238 Error_Handler();
239 }
240
243 if (HAL_PWREx_EnableOverDrive() != HAL_OK)
244 {
245 Error_Handler();
246 }
247
250 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
251 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
252 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
253 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
254 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
255 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
256
257 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
258 {
259 Error_Handler();
260 }
261}
262
268static void MX_SPI1_Init(void)
269{
270
271 /* USER CODE BEGIN SPI1_Init 0 */
272
273 /* USER CODE END SPI1_Init 0 */
274
275 /* USER CODE BEGIN SPI1_Init 1 */
276
277 /* USER CODE END SPI1_Init 1 */
278 /* SPI1 parameter configuration*/
279 hspi1.Instance = SPI1;
280 hspi1.Init.Mode = SPI_MODE_MASTER;
281 hspi1.Init.Direction = SPI_DIRECTION_2LINES;
282 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
283 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
284 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
285 hspi1.Init.NSS = SPI_NSS_SOFT;
286 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
287 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
288 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
289 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
290 hspi1.Init.CRCPolynomial = 10;
291 if (HAL_SPI_Init(&hspi1) != HAL_OK)
292 {
293 Error_Handler();
294 }
295 /* USER CODE BEGIN SPI1_Init 2 */
296
297 /* USER CODE END SPI1_Init 2 */
298
299}
300
306static void MX_TIM1_Init(void)
307{
308
309 /* USER CODE BEGIN TIM1_Init 0 */
310
311 /* USER CODE END TIM1_Init 0 */
312
313 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
314 TIM_MasterConfigTypeDef sMasterConfig = {0};
315
316 /* USER CODE BEGIN TIM1_Init 1 */
317
318 /* USER CODE END TIM1_Init 1 */
319 htim1.Instance = TIM1;
320 htim1.Init.Prescaler = 180-1;
321 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
322 htim1.Init.Period = 65535;
323 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
324 htim1.Init.RepetitionCounter = 0;
325 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
326 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
327 {
328 Error_Handler();
329 }
330 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
331 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
332 {
333 Error_Handler();
334 }
335 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
336 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
337 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
338 {
339 Error_Handler();
340 }
341 /* USER CODE BEGIN TIM1_Init 2 */
342
343 /* USER CODE END TIM1_Init 2 */
344
345}
346
352static void MX_TIM2_Init(void)
353{
354
355 /* USER CODE BEGIN TIM2_Init 0 */
356
357 /* USER CODE END TIM2_Init 0 */
358
359 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
360 TIM_MasterConfigTypeDef sMasterConfig = {0};
361
362 /* USER CODE BEGIN TIM2_Init 1 */
363
364 /* USER CODE END TIM2_Init 1 */
365 htim2.Instance = TIM2;
366 htim2.Init.Prescaler = 90-1;
367 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
368 htim2.Init.Period = 4294967295;
369 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
370 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
371 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
372 {
373 Error_Handler();
374 }
375 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
376 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
377 {
378 Error_Handler();
379 }
380 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
381 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
382 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
383 {
384 Error_Handler();
385 }
386 /* USER CODE BEGIN TIM2_Init 2 */
387
388 /* USER CODE END TIM2_Init 2 */
389
390}
391
397static void MX_USART1_UART_Init(void)
398{
399
400 /* USER CODE BEGIN USART1_Init 0 */
401
402 /* USER CODE END USART1_Init 0 */
403
404 /* USER CODE BEGIN USART1_Init 1 */
405
406 /* USER CODE END USART1_Init 1 */
407 huart1.Instance = USART1;
408 huart1.Init.BaudRate = 19200;
409 huart1.Init.WordLength = UART_WORDLENGTH_8B;
410 huart1.Init.StopBits = UART_STOPBITS_1;
411 huart1.Init.Parity = UART_PARITY_NONE;
412 huart1.Init.Mode = UART_MODE_TX_RX;
413 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
414 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
415 if (HAL_UART_Init(&huart1) != HAL_OK)
416 {
417 Error_Handler();
418 }
419 /* USER CODE BEGIN USART1_Init 2 */
420
421 /* USER CODE END USART1_Init 2 */
422
423}
424
430static void MX_GPIO_Init(void)
431{
432 GPIO_InitTypeDef GPIO_InitStruct = {0};
433 /* USER CODE BEGIN MX_GPIO_Init_1 */
434
435 /* USER CODE END MX_GPIO_Init_1 */
436
437 /* GPIO Ports Clock Enable */
438 __HAL_RCC_GPIOC_CLK_ENABLE();
439 __HAL_RCC_GPIOH_CLK_ENABLE();
440 __HAL_RCC_GPIOA_CLK_ENABLE();
441 __HAL_RCC_GPIOB_CLK_ENABLE();
442
443 /*Configure GPIO pin Output Level */
444 HAL_GPIO_WritePin(GPIOB, MB85RS64_CS_Pin|RA8875_CS_Pin, GPIO_PIN_SET);
445
446 /*Configure GPIO pin Output Level */
447 HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_RESET);
448
449 /*Configure GPIO pins : MB85RS64_CS_Pin RA8875_CS_Pin */
450 GPIO_InitStruct.Pin = MB85RS64_CS_Pin|RA8875_CS_Pin;
451 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
452 GPIO_InitStruct.Pull = GPIO_PULLUP;
453 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
454 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
455
456 /*Configure GPIO pin : LCD_RESET_Pin */
457 GPIO_InitStruct.Pin = LCD_RESET_Pin;
458 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
459 GPIO_InitStruct.Pull = GPIO_NOPULL;
460 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
461 HAL_GPIO_Init(LCD_RESET_GPIO_Port, &GPIO_InitStruct);
462
463 /* USER CODE BEGIN MX_GPIO_Init_2 */
464
465 /* USER CODE END MX_GPIO_Init_2 */
466}
467
468/* USER CODE BEGIN 4 */
469
470
477void _Error_Handler(const char *file, int line)
478{
479 __disable_irq();
480
481#ifdef REDIRECT_PRINTF
482 char buf[80];
483
484 snprintf(buf, sizeof(buf),
485 "Trapped in _Error_Handler(). Called from: %s, line: %d\r\n",
486 file, line);
487 printf("%s", buf);
488#endif
489
490 /* User can add an implementation to report the HAL error return state. */
491 while(1)
492 {
493 }
494}
495
496/* USER CODE END 4 */
497
498
499#ifdef USE_FULL_ASSERT
507void assert_failed(uint8_t *file, uint32_t line)
508{
509 /* USER CODE BEGIN 6 */
510 /* assert_param() can fire from inside any HAL call -- including before
511 * REDIRECT_PRINTF's UART is fully set up, or from an unusual calling
512 * context -- so this only attempts to report when REDIRECT_PRINTF is
513 * available, then halts either way. Continuing after a failed HAL
514 * parameter check is undefined behavior, not something safe to log
515 * and ignore. */
516 __disable_irq();
517
518#ifdef REDIRECT_PRINTF
519 {
520 char buf[96];
521
522 snprintf(buf, sizeof(buf),
523 "assert_param failed: file %s, line %lu\r\n",
524 (char *)file, (unsigned long)line);
525 printf("%s", buf);
526 }
527#endif
528
529 while (1)
530 {
531 }
532 /* USER CODE END 6 */
533}
534#endif /* USE_FULL_ASSERT */
C-callable entry points into the C++ RA8875 display code.
bool initTouchCalibration(void)
Reads the touch calibration stored in the FRAM and reports it on the redirected USART.
void testFRAM(void)
Shows that the FRAM keeps its data, then does a write and read-back test.
void testLCD(bool buildTest)
Runs one of the two display demonstrations.
void initTest(SPI_HandleTypeDef *halSPI)
Creates the display object and starts the RA8875 controller.
void initFRAM(SPI_HandleTypeDef *halSPI)
Creates the FRAM driver object and checks that the chip answers.
void testTouch(UART_HandleTypeDef *huart)
Enables touch, runs the three-point calibration and shows the result.
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
UART error callback (overrun, noise, framing or parity error).
Definition main.c:119
volatile uint8_t uartRxChar
The one character the interrupt receive is currently waiting for.
Definition main.c:87
volatile uint8_t uartKeyPressed
Set by HAL_UART_RxCpltCallback(): 0 = no key yet, otherwise ' ' (space) or 0x1B (Esc).
Definition main.c:89
int main(void)
The application entry point.
Definition main.c:134
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
UART receive-complete callback, called by the HAL from the USART interrupt.
Definition main.c:99
: Header for main.c file. This file contains the common defines of the application.