/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2026 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "cmsis_os.h" #include "ui.h" #include "usb_host.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "display.h" #include "graphics.h" #include "font.h" #include "menu.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ CRC_HandleTypeDef hcrc; DMA2D_HandleTypeDef hdma2d; I2C_HandleTypeDef hi2c3; LTDC_HandleTypeDef hltdc; SPI_HandleTypeDef hspi5; TIM_HandleTypeDef htim1; UART_HandleTypeDef huart1; SDRAM_HandleTypeDef hsdram1; osThreadId defaultTaskHandle; /* USER CODE BEGIN PV */ volatile bool led1_state = false; volatile bool led2_state = false; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_CRC_Init(void); static void MX_DMA2D_Init(void); static void MX_FMC_Init(void); static void MX_I2C3_Init(void); static void MX_LTDC_Init(void); static void MX_SPI5_Init(void); static void MX_TIM1_Init(void); static void MX_USART1_UART_Init(void); void StartDefaultTask(void const * argument); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /** * @brief Convert a single digit (0-9) to its ASCII character * @param digit: The digit to convert (0-9) * @retval ASCII character '0' through '9' */ static char digit_to_ascii(uint8_t digit) { return (char)('0' + digit); } /** * @brief Convert an unsigned 32-bit integer to a null-terminated string * @param value: The number to convert * @param buffer: Pointer to the output buffer * @param buffer_size: Size of the buffer * @retval None */ static void uint32_to_string(uint32_t value, uint8_t *buffer, uint8_t buffer_size) { uint8_t i = 0; uint8_t digits[10]; // Maximum 10 digits for uint32_t uint8_t digit_count = 0; // Handle zero case if (value == 0) { if (buffer_size > 0) { buffer[0] = '0'; buffer[1] = '\0'; } return; } // Extract digits from right to left while (value > 0 && digit_count < 10) { digits[digit_count] = (uint8_t)(value % 10); value /= 10; digit_count++; } // Convert digits to ASCII and store in buffer (reversed) for (i = 0; i < digit_count && i < (buffer_size - 1); i++) { buffer[i] = digit_to_ascii(digits[digit_count - 1 - i]); } // Null terminate if (i < buffer_size) { buffer[i] = '\0'; } else if (buffer_size > 0) { buffer[buffer_size - 1] = '\0'; } } void LCD_Write_Cmd(uint8_t cmd) { LCD_CS_LOW(); LCD_DC_LOW(); HAL_SPI_Transmit(&hspi5, &cmd, 1, 1000); LCD_CS_HIGH(); } void LCD_Write_Data (uint8_t data) { LCD_CS_LOW(); LCD_DC_HIGH(); HAL_SPI_Transmit(&hspi5, &data, 1, 1000); LCD_CS_HIGH(); } //initialize the tft void ILI9341_Init(void) { LCD_RES_LOW(); osDelay(50); LCD_RES_HIGH(); osDelay(20); LCD_Write_Cmd(ILI9341_SWRESET); osDelay(10); LCD_Write_Cmd(ILI9341_POWERB); osDelay(10); LCD_Write_Data(0x00);; LCD_Write_Data(0xD9); LCD_Write_Data(0x30); LCD_Write_Cmd(ILI9341_POWER_SEQ); LCD_Write_Data(0x64); LCD_Write_Data(0x03); LCD_Write_Data(0X12); LCD_Write_Data(0X81); LCD_Write_Cmd(ILI9341_DTCA); LCD_Write_Data(0x85); LCD_Write_Data(0x10); LCD_Write_Data(0x7A); LCD_Write_Cmd(ILI9341_POWERA); LCD_Write_Data(0x39); LCD_Write_Data(0x2C); LCD_Write_Data(0x00); LCD_Write_Data(0x34); LCD_Write_Data(0x02); LCD_Write_Cmd(ILI9341_PRC); LCD_Write_Data(0x20); LCD_Write_Cmd(ILI9341_DTCB); LCD_Write_Data(0x00); LCD_Write_Data(0x00); LCD_Write_Cmd(ILI9341_POWER1); LCD_Write_Data(0x1B); LCD_Write_Cmd(ILI9341_POWER2); LCD_Write_Data(0x12); LCD_Write_Cmd(ILI9341_VCOM1); LCD_Write_Data(0x08); LCD_Write_Data(0x26); LCD_Write_Cmd(ILI9341_VCOM2); LCD_Write_Data(0XB7); LCD_Write_Cmd(ILI9341_PIXEL_FORMAT); LCD_Write_Data(0x55); //select RGB565 LCD_Write_Cmd(ILI9341_FRMCTR1); LCD_Write_Data(0x00); LCD_Write_Data(0x1B);//frame rate = 70 LCD_Write_Cmd(ILI9341_DFC); // Display Function Control LCD_Write_Data(0x0A); LCD_Write_Data(0xA2); LCD_Write_Cmd(ILI9341_3GAMMA_EN); // 3Gamma Function Disable LCD_Write_Data(0x02); LCD_Write_Cmd(ILI9341_GAMMA); LCD_Write_Data(0x01); LCD_Write_Cmd(ILI9341_PGAMMA); //Set Gamma LCD_Write_Data(0x0F); LCD_Write_Data(0x1D); LCD_Write_Data(0x1A); LCD_Write_Data(0x0A); LCD_Write_Data(0x0D); LCD_Write_Data(0x07); LCD_Write_Data(0x49); LCD_Write_Data(0X66); LCD_Write_Data(0x3B); LCD_Write_Data(0x07); LCD_Write_Data(0x11); LCD_Write_Data(0x01); LCD_Write_Data(0x09); LCD_Write_Data(0x05); LCD_Write_Data(0x04); LCD_Write_Cmd(ILI9341_NGAMMA); LCD_Write_Data(0x00); LCD_Write_Data(0x18); LCD_Write_Data(0x1D); LCD_Write_Data(0x02); LCD_Write_Data(0x0F); LCD_Write_Data(0x04); LCD_Write_Data(0x36); LCD_Write_Data(0x13); LCD_Write_Data(0x4C); LCD_Write_Data(0x07); LCD_Write_Data(0x13); LCD_Write_Data(0x0F); LCD_Write_Data(0x2E); LCD_Write_Data(0x2F); LCD_Write_Data(0x05); LCD_Write_Cmd(ILI9341_RGB_INTERFACE); LCD_Write_Data(0xC2); //Data is fetched during falling edge of DOTCLK LCD_Write_Cmd(ILI9341_INTERFACE); LCD_Write_Data(0x01); LCD_Write_Data(0x00); LCD_Write_Data(0x06); LCD_Write_Cmd(ILI9341_MAC); // Memory Access Control command LCD_Write_Data(MADCTL_BGR); LCD_Write_Cmd(ILI9341_SLEEP_OUT); //Exit Sleep osDelay(100); LCD_Write_Cmd(ILI9341_DISPLAY_ON); //display on osDelay(100); } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_CRC_Init(); MX_DMA2D_Init(); MX_FMC_Init(); MX_I2C3_Init(); MX_LTDC_Init(); MX_SPI5_Init(); MX_TIM1_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* USER CODE BEGIN RTOS_MUTEX */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */ /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_TIMERS */ /* start timers, add new ones, ... */ /* USER CODE END RTOS_TIMERS */ /* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ /* USER CODE END RTOS_QUEUES */ /* Create the thread(s) */ /* definition and creation of defaultTask */ osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 4096); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* USER CODE END RTOS_THREADS */ /* Start scheduler */ osKernelStart(); /* We should never get here as control is now taken by the scheduler */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 16; RCC_OscInitStruct.PLL.PLLN = 72; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 3; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /** * @brief CRC Initialization Function * @param None * @retval None */ static void MX_CRC_Init(void) { /* USER CODE BEGIN CRC_Init 0 */ /* USER CODE END CRC_Init 0 */ /* USER CODE BEGIN CRC_Init 1 */ /* USER CODE END CRC_Init 1 */ hcrc.Instance = CRC; if (HAL_CRC_Init(&hcrc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN CRC_Init 2 */ /* USER CODE END CRC_Init 2 */ } /** * @brief DMA2D Initialization Function * @param None * @retval None */ static void MX_DMA2D_Init(void) { /* USER CODE BEGIN DMA2D_Init 0 */ /* USER CODE END DMA2D_Init 0 */ // Configure DMA2D for RGB565 memory-to-memory copy hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; HAL_DMA2D_Init(&hdma2d); HAL_DMA2D_ConfigLayer(&hdma2d, 1); /* USER CODE BEGIN DMA2D_Init 1 */ /* USER CODE END DMA2D_Init 1 */ hdma2d.Instance = DMA2D; hdma2d.Init.Mode = DMA2D_M2M; hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; hdma2d.Init.OutputOffset = 0; hdma2d.LayerCfg[1].InputOffset = 0; hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565; hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; hdma2d.LayerCfg[1].InputAlpha = 0; if (HAL_DMA2D_Init(&hdma2d) != HAL_OK) { Error_Handler(); } if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN DMA2D_Init 2 */ /* USER CODE END DMA2D_Init 2 */ } /** * @brief I2C3 Initialization Function * @param None * @retval None */ static void MX_I2C3_Init(void) { /* USER CODE BEGIN I2C3_Init 0 */ /* USER CODE END I2C3_Init 0 */ /* USER CODE BEGIN I2C3_Init 1 */ /* USER CODE END I2C3_Init 1 */ hi2c3.Instance = I2C3; hi2c3.Init.ClockSpeed = 100000; hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c3.Init.OwnAddress1 = 0; hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c3.Init.OwnAddress2 = 0; hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c3) != HAL_OK) { Error_Handler(); } /** Configure Analogue filter */ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { Error_Handler(); } /** Configure Digital filter */ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C3_Init 2 */ /* USER CODE END I2C3_Init 2 */ } /** * @brief LTDC Initialization Function * @param None * @retval None */ static void MX_LTDC_Init(void) { /* USER CODE BEGIN LTDC_Init 0 */ /* USER CODE END LTDC_Init 0 */ LTDC_LayerCfgTypeDef pLayerCfg = {0}; /* USER CODE BEGIN LTDC_Init 1 */ /* USER CODE END LTDC_Init 1 */ hltdc.Instance = LTDC; hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL; hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL; hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL; hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC; hltdc.Init.HorizontalSync = 9; hltdc.Init.VerticalSync = 1; hltdc.Init.AccumulatedHBP = 29; hltdc.Init.AccumulatedVBP = 3; hltdc.Init.AccumulatedActiveW = 269; hltdc.Init.AccumulatedActiveH = 323; hltdc.Init.TotalWidth = 279; hltdc.Init.TotalHeigh = 327; hltdc.Init.Backcolor.Blue = 0; hltdc.Init.Backcolor.Green = 0; hltdc.Init.Backcolor.Red = 0; if (HAL_LTDC_Init(&hltdc) != HAL_OK) { Error_Handler(); } pLayerCfg.WindowX0 = 0; pLayerCfg.WindowX1 = 240; pLayerCfg.WindowY0 = 0; pLayerCfg.WindowY1 = 320; pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; pLayerCfg.Alpha = 255; pLayerCfg.Alpha0 = 0; pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; pLayerCfg.FBStartAdress = (uint32_t)(¤t_framebuffer); pLayerCfg.ImageWidth = 240; pLayerCfg.ImageHeight = 320; pLayerCfg.Backcolor.Blue = 0; pLayerCfg.Backcolor.Green = 0; pLayerCfg.Backcolor.Red = 0; if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN LTDC_Init 2 */ /* Enable Layer 1 */ __HAL_LTDC_LAYER_ENABLE(&hltdc, 0); /* Reload configuration immediately */ __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc); /* USER CODE END LTDC_Init 2 */ } /** * @brief SPI5 Initialization Function * @param None * @retval None */ static void MX_SPI5_Init(void) { /* USER CODE BEGIN SPI5_Init 0 */ /* USER CODE END SPI5_Init 0 */ /* USER CODE BEGIN SPI5_Init 1 */ /* USER CODE END SPI5_Init 1 */ /* SPI5 parameter configuration*/ hspi5.Instance = SPI5; hspi5.Init.Mode = SPI_MODE_MASTER; hspi5.Init.Direction = SPI_DIRECTION_2LINES; hspi5.Init.DataSize = SPI_DATASIZE_8BIT; hspi5.Init.CLKPolarity = SPI_POLARITY_LOW; hspi5.Init.CLKPhase = SPI_PHASE_1EDGE; hspi5.Init.NSS = SPI_NSS_SOFT; hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi5.Init.TIMode = SPI_TIMODE_DISABLE; hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi5.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi5) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN SPI5_Init 2 */ /* USER CODE END SPI5_Init 2 */ } /** * @brief TIM1 Initialization Function * @param None * @retval None */ static void MX_TIM1_Init(void) { /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 65535; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM1_Init 2 */ /* USER CODE END TIM1_Init 2 */ } /** * @brief USART1 Initialization Function * @param None * @retval None */ static void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ } /* FMC initialization function */ static void MX_FMC_Init(void) { /* USER CODE BEGIN FMC_Init 0 */ /* USER CODE END FMC_Init 0 */ FMC_SDRAM_TimingTypeDef SdramTiming = {0}; /* USER CODE BEGIN FMC_Init 1 */ /* USER CODE END FMC_Init 1 */ /** Perform the SDRAM1 memory initialization sequence */ hsdram1.Instance = FMC_SDRAM_DEVICE; /* hsdram1.Init */ hsdram1.Init.SDBank = FMC_SDRAM_BANK2; hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3; hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE; hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1; /* SdramTiming */ SdramTiming.LoadToActiveDelay = 2; SdramTiming.ExitSelfRefreshDelay = 7; SdramTiming.SelfRefreshTime = 4; SdramTiming.RowCycleDelay = 7; SdramTiming.WriteRecoveryTime = 3; SdramTiming.RPDelay = 2; SdramTiming.RCDDelay = 2; if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK) { Error_Handler( ); } /* USER CODE BEGIN FMC_Init 2 */ #define TMRD(x) (x << 0) /* Load Mode Register to Active */ #define TXSR(x) (x << 4) /* Exit Self-refresh delay */ #define TRAS(x) (x << 8) /* Self refresh time */ #define TRC(x) (x << 12) /* Row cycle delay */ #define TWR(x) (x << 16) /* Recovery delay */ #define TRP(x) (x << 20) /* Row precharge delay */ #define TRCD(x) (x << 24) /* Row to column delay */ uint32_t tmp; // Enable clock for FMC RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; // Initialization step 1 FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE_1; FMC_Bank5_6->SDCR[1] = FMC_SDCR1_NR_0 | FMC_SDCR1_MWID_0 | FMC_SDCR1_NB | FMC_SDCR1_CAS; // Initialization step 2 FMC_Bank5_6->SDTR[0] = TRC(7) | TRP(2); FMC_Bank5_6->SDTR[1] = TMRD(2) | TXSR(7) | TRAS(4) | TWR(2) | TRCD(2); // Initialization step 3 while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); FMC_Bank5_6->SDCMR = 1 | FMC_SDCMR_CTB2 | (1 << 5); // Initialization step 4 for(tmp = 0; tmp < 1000000; tmp++); // Initialization step 5 while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); FMC_Bank5_6->SDCMR = 2 | FMC_SDCMR_CTB2 | (1 << 5); // Initialization step 6 while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); FMC_Bank5_6->SDCMR = 3 | FMC_SDCMR_CTB2 | (4 << 5); // Initialization step 7 while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); FMC_Bank5_6->SDCMR = 4 | FMC_SDCMR_CTB2 | (1 << 5) | (0x231 << 9); // Initialization step 8 while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); FMC_Bank5_6->SDRTR |= (683 << 1); while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY); /* USER CODE END FMC_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, NCS_MEMS_SPI_Pin|CSX_Pin|OTG_FS_PSO_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(ACP_RST_GPIO_Port, ACP_RST_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOD, RDX_Pin|WRX_DCX_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOG, LD3_Pin|LD4_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : NCS_MEMS_SPI_Pin CSX_Pin OTG_FS_PSO_Pin */ GPIO_InitStruct.Pin = NCS_MEMS_SPI_Pin|CSX_Pin|OTG_FS_PSO_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pins : B1_Pin MEMS_INT1_Pin MEMS_INT2_Pin TP_INT1_Pin */ GPIO_InitStruct.Pin = B1_Pin|MEMS_INT1_Pin|MEMS_INT2_Pin|TP_INT1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : ACP_RST_Pin */ GPIO_InitStruct.Pin = ACP_RST_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(ACP_RST_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : OTG_FS_OC_Pin */ GPIO_InitStruct.Pin = OTG_FS_OC_Pin; GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(OTG_FS_OC_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : BOOT1_Pin */ GPIO_InitStruct.Pin = BOOT1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(BOOT1_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pin : TE_Pin */ GPIO_InitStruct.Pin = TE_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(TE_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : RDX_Pin WRX_DCX_Pin */ GPIO_InitStruct.Pin = RDX_Pin|WRX_DCX_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /*Configure GPIO pins : BUTTON1_Pin BUTTON2_Pin BUTTON3_Pin BUTTON4_Pin */ GPIO_InitStruct.Pin = BUTTON1_Pin|BUTTON2_Pin|BUTTON3_Pin|BUTTON4_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /*Configure GPIO pin : BUTTON5_Pin */ GPIO_InitStruct.Pin = BUTTON5_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(BUTTON5_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : LD3_Pin LD4_Pin */ GPIO_InitStruct.Pin = LD3_Pin|LD4_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /* USER CODE BEGIN Header_StartDefaultTask */ /** * @brief Function implementing the defaultTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void const * argument) { /* init code for USB_HOST */ /* USER CODE BEGIN 5 */ ILI9341_Init(); /* Infinite loop */ for(;;) { if (UP_BUTTON_PRESSED()) { ui_up_button_pressed(); } if (DOWN_BUTTON_PRESSED()) { ui_down_button_pressed(); } if (LEFT_BUTTON_PRESSED()) { ui_left_button_pressed(); } if (OK_BUTTON_PRESSED()) { ui_ok_button_pressed(); } ui_task(); HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, led1_state ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, led2_state ? GPIO_PIN_SET : GPIO_PIN_RESET); osDelay(100); } /* USER CODE END 5 */ } /** * @brief Period elapsed callback in non blocking mode * @note This function is called when TIM6 interrupt took place, inside * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment * a global variable "uwTick" used as application time base. * @param htim : TIM handle * @retval None */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { /* USER CODE BEGIN Callback 0 */ /* USER CODE END Callback 0 */ if (htim->Instance == TIM6) { HAL_IncTick(); } /* USER CODE BEGIN Callback 1 */ /* USER CODE END Callback 1 */ } /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */