text: /* USER CODE BEGIN Header */
  /**
    ******************************************************************************
    * @file           : main.c
    * @brief          : Main program body
    ******************************************************************************
    * @attention
    *
    * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
    * All rights reserved.</center></h2>
    *
    * This software component is licensed by ST under Ultimate Liberty license
    * SLA0044, the "License"; You may not use this file except in compliance with
    * the License. You may obtain a copy of the License at:
    *                             www.st.com/SLA0044
    *
    ******************************************************************************
    */
  /* USER CODE END Header */
  /* Includes ------------------------------------------------------------------*/
  #include "main.h"
  #include "cmsis_os.h"
  #include "lwip.h"
  
  /* Private includes ----------------------------------------------------------*/
  /* USER CODE BEGIN Includes */
  #include <stdio.h>
  #include <string.h>
  //#include <DHT.h>
  
  #include "dht11.h"
  #include "lcd.h"
  /* USER CODE END Includes */
  
  /* Private typedef -----------------------------------------------------------*/
  /* USER CODE BEGIN PTD */
  
  /* USER CODE END PTD */
  
  /* Private define ------------------------------------------------------------*/
  /* USER CODE BEGIN PD */
  #ifndef DHCP_STATE_BOUND
  #define DHCP_STATE_BOUND 10
  #endif
  /* USER CODE END PD */
  
  /* Private macro -------------------------------------------------------------*/
  /* USER CODE BEGIN PM */
  
  /* USER CODE END PM */
  
  /* Private variables ---------------------------------------------------------*/
  UART_HandleTypeDef huart3;
  
  osThreadId defaultTaskHandle;
  osThreadId tcpClientTaskHandle;
  osThreadId tcpServerTaskHandle;
  osThreadId udpServerTaskHandle;
  /* USER CODE BEGIN PV */
  //DHT_sensor dht11 = {DHT11_IO_GPIO_Port, DHT11_IO_Pin, DHT11, 0};
  /* USER CODE END PV */
  
  /* Private function prototypes -----------------------------------------------*/
  void SystemClock_Config(void);
  static void MX_GPIO_Init(void);
  static void MX_USART3_UART_Init(void);
  void StartDefaultTask(void const * argument);
  extern void StartTcpClientTask(void const * argument);
  extern void StartTcpServerTask(void const * argument);
  extern void StartUdpServerTask(void const * argument);
  
  /* USER CODE BEGIN PFP */
  
  /* USER CODE END PFP */
  
  /* Private user code ---------------------------------------------------------*/
  /* USER CODE BEGIN 0 */
  #if defined(NDEBUG) && defined(USE_SEMIHOST)
  #define printf(...)
  #endif
  
  #define TRANSMIT_TIMEOUT 5
  #define RECEIVE_TIMEOUT 1
  
  int __io_putchar(int ch)
  {
  	HAL_UART_Transmit(&huart3, (uint8_t *)&ch, sizeof(uint8_t), TRANSMIT_TIMEOUT);
  	return ch;
  }
  
  #ifdef USE_HTTP_SERVER_SOLUTION
  
  #define HTTP_TEMPERATURE_PAGE_TEMPLATE_STR "<html>"\
  "<body>"\
  "<h2>Temperature: %s &#8451</h2>"\
  "</body>"\
  "</html>"
  
  #define HTTP_HUMIDITY_PAGE_TEMPLATE_STR "<html>"\
  "<body>"\
  "<h2>Humidity: %s %%</h2>"\
  "</body>"\
  "</html>"
  
  http_status_t http_temperature_path_handler(http_buffer_t *out)
  {
  	printf("http_temperature_path_handler()\n");
  	if (out == NULL)
  	{
  		return HTTP_ERR_FAULT;
  	}
  	char * content = malloc(256);
  	if (content == NULL)
  	{
  		return HTTP_ERR_FAULT;
  	}
  
  #if 0
  	char ts[8];
  	DHT_data d = DHT_getData(&dht11);
  	snprintf(ts, 8, "%02u", (uint8_t)d.temp);
  	snprintf(content, 256, HTTP_TEMPERATURE_PAGE_TEMPLATE_STR, ts);
  #else
  	char temperature[6];
  	uint8_t buffer[4];
  	dht11_t dht11;
  	dht11_init (&dht11, DHT11_IO_GPIO_Port, DHT11_IO_Pin);
  	dht_status_t status = dht11_read (&dht11, buffer, sizeof(buffer));
  	if (status == DHT_OK)
  	{
  		dht11_to_str(buffer, sizeof(buffer), NULL, temperature);
  		printf("temperature = %s *C\n", temperature);
  	}
  	else
  	{
  		printf("dht11_read() error: %u\n", status);
  		strncpy(temperature, "--", sizeof(temperature));
  	}
  	snprintf(content, 256, HTTP_TEMPERATURE_PAGE_TEMPLATE_STR, temperature);
  #endif
  
  	int content_len = strlen(content);
  	snprintf(out->data, out->length, HTTP_RESPONSE_HEADER_TEMPLATE_STR, HTTP_OK_CODE, HTTP_OK_STR, content_len);
  	int header_len = strlen(out->data);
  	if(out->length < header_len + content_len)
  	{
  		free(content);
  		return HTTP_ERR_BUF_OVERFLOW;
  	}
  	strncat(out->data, content, content_len);
  	free(content);
  	return HTTP_OK;
  }
  
  http_status_t http_humidity_path_handler(http_buffer_t *out)
  {
  	printf("http_humidity_path_handler()\n");
  	if (out == NULL)
  	{
  		return HTTP_ERR_FAULT;
  	}
  	char * content = malloc(256);
  	if (content == NULL)
  	{
  		return HTTP_ERR_FAULT;
  	}
  #if 0
  	char hs[8];
  	DHT_data d = DHT_getData(&dht11);
  	snprintf(hs, 8, "%02u", (uint8_t)d.hum);
  	snprintf(content, 256, HTTP_HUMIDITY_PAGE_TEMPLATE_STR, hs);
  #else
  	char humidity[6];
  	uint8_t buffer[4];
  	dht11_t dht11;
  	dht11_init (&dht11, DHT11_IO_GPIO_Port, DHT11_IO_Pin);
  	dht_status_t status = dht11_read (&dht11, buffer, sizeof(buffer));
  	if (status == DHT_OK)
  	{
  		dht11_to_str(buffer, sizeof(buffer), humidity, NULL);
  		printf("humidity = %s %%\n", humidity);
  	}
  	else
  	{
  		printf("dht11_read() error: %u\n", status);
  		strncpy(humidity, "--", sizeof(humidity));
  	}
  	snprintf(content, 256, HTTP_HUMIDITY_PAGE_TEMPLATE_STR, humidity);
  #endif
  
  	int content_len = strlen(content);
  	snprintf(out->data, out->length, HTTP_RESPONSE_HEADER_TEMPLATE_STR, HTTP_OK_CODE, HTTP_OK_STR, content_len);
  	int header_len = strlen(out->data);
  	if(out->length < header_len + content_len)
  	{
  		free(content);
  		return HTTP_ERR_BUF_OVERFLOW;
  	}
  	strncat(out->data, content, content_len);
  	free(content);
  	return HTTP_OK;
  }
  
  void http_led_toggle_handler(bool LED[4])
  {
  	Led_TypeDef led[4] = {LED3, LED4, LED5, LED6};
  	for(size_t i = 0; i < 4; i++)
  	{
  		if (LED[i])
  		{
  			BSP_LED_Toggle(led[i]);
  		}
  	}
  }
  
  void http_led_on_handler(bool LED[4])
  {
  	Led_TypeDef led[4] = {LED3, LED4, LED5, LED6};
  	for(size_t i = 0; i < 4; i++)
  	{
  		if (LED[i])
  		{
  			BSP_LED_On(led[i]);
  		}
  	}
  }
  
  void http_led_off_handler(bool LED[4])
  {
  	Led_TypeDef led[4] = {LED3, LED4, LED5, LED6};
  	for(size_t i = 0; i < 4; i++)
  	{
  		if (LED[i])
  		{
  			BSP_LED_Off(led[i]);
  		}
  	}
  }
  #endif/* USE_SOLUTION */
  /* 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 */
    /* Configure LED3, LED4, LED5 and LED6 */
    BSP_LED_Init(LED3);
    BSP_LED_Init(LED4);
    BSP_LED_Init(LED5);
    BSP_LED_Init(LED6);
    /* Initialization of DWT module (cortex-m4)*/
    DWT_Init();
    /* USER CODE END Init */
  
    /* Configure the system clock */
    SystemClock_Config();
  
    /* USER CODE BEGIN SysInit */
  #if !defined(NDEBUG) && defined(USE_SEMIHOST)
    /* WARNING: to activate semihosting, please, make following changes:
     *
     * 1. Add '-specs=rdimon.specs -lc -lrdimon' to the menu item
     * 	'Properties->C/C++Build->Settings->MCU GCC Linker->Miscellaneous->Other flags'
     *
     * 2. Exclude from Build syscalls.c by selecting
     * 	'Resource Configurations->Exclude from Build' in the context menu of this file
     *
     * 3. Add macros USE_SEMIHOST to the menu item
     * 	'Properties->C/C++Build->Settings->MCU GCC Compiler->Preprocessor'
     * */
    initialise_monitor_handles();
    printf("Semihosting activated\n");
  #endif
    /* USER CODE END SysInit */
  
    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_USART3_UART_Init();
    /* USER CODE BEGIN 2 */
    /* WARNING: if you use minicom as a terminal utility,
     * please, add 'pu addcarreturn Yes' to the file ~/.minirc.dfl
     * to attach '\r' after '\n'
     * */
    printf("USART3 initialized\n");
    NVIC_SetPriorityGrouping(0);
  
    lcd_init();
    /* Use the LCD_CLR_SCR_CMD command
     * to clear the LCD screen */
    lcd_command_set(LCD_CLR_SCR_CMD);
    lcd_puts("GL Embedded");
    /* Do not forget to set the LCD_LFCR_CMD
     * command when printing more than 16
     * characters because LCD 16x2 is used */
    lcd_command_set(LCD_LFCR_CMD);
    lcd_puts("Starter Kit");
    /* 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, 256);
    defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
  
    /* definition and creation of tcpClientTask */
    osThreadDef(tcpClientTask, StartTcpClientTask, osPriorityNormal, 0, 2048);
    tcpClientTaskHandle = osThreadCreate(osThread(tcpClientTask), NULL);
  
    /* definition and creation of tcpServerTask */
    osThreadDef(tcpServerTask, StartTcpServerTask, osPriorityNormal, 0, 2048);
    tcpServerTaskHandle = osThreadCreate(osThread(tcpServerTask), NULL);
  
    /* definition and creation of udpServerTask */
    osThreadDef(udpServerTask, StartUdpServerTask, osPriorityNormal, 0, 2048);
    udpServerTaskHandle = osThreadCreate(osThread(udpServerTask), 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_SCALE1);
    /** 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 = 8;
    RCC_OscInitStruct.PLL.PLLN = 336;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 7;
    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_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    {
      Error_Handler();
    }
  }
  
  /**
    * @brief USART3 Initialization Function
    * @param None
    * @retval None
    */
  static void MX_USART3_UART_Init(void)
  {
  
    /* USER CODE BEGIN USART3_Init 0 */
  
    /* USER CODE END USART3_Init 0 */
  
    /* USER CODE BEGIN USART3_Init 1 */
  
    /* USER CODE END USART3_Init 1 */
    huart3.Instance = USART3;
    huart3.Init.BaudRate = 115200;
    huart3.Init.WordLength = UART_WORDLENGTH_8B;
    huart3.Init.StopBits = UART_STOPBITS_1;
    huart3.Init.Parity = UART_PARITY_NONE;
    huart3.Init.Mode = UART_MODE_TX_RX;
    huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart3.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart3) != HAL_OK)
    {
      Error_Handler();
    }
    /* USER CODE BEGIN USART3_Init 2 */
  
    /* USER CODE END USART3_Init 2 */
  
  }
  
  /**
    * @brief GPIO Initialization Function
    * @param None
    * @retval None
    */
  static void MX_GPIO_Init(void)
  {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
  
    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
  
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOE, CS_I2C_SPI_Pin|DISP_RS_Pin|DISP_RW_Pin|DISP_ENA_Pin
                            |DISP_DB4_Pin|DISP_DB5_Pin|DISP_DB6_Pin|DISP_DB7_Pin, GPIO_PIN_RESET);
  
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(OTG_FS_PowerSwitchOn_GPIO_Port, OTG_FS_PowerSwitchOn_Pin, GPIO_PIN_SET);
  
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOD, RMII_PHY_RST_Pin|DHT11_IO_Pin|LD4_Pin|LD3_Pin
                            |LD5_Pin|LD6_Pin|Audio_RST_Pin, GPIO_PIN_RESET);
  
    /*Configure GPIO pins : CS_I2C_SPI_Pin DISP_RS_Pin DISP_RW_Pin DISP_ENA_Pin
                             DISP_DB4_Pin DISP_DB5_Pin DISP_DB6_Pin DISP_DB7_Pin */
    GPIO_InitStruct.Pin = CS_I2C_SPI_Pin|DISP_RS_Pin|DISP_RW_Pin|DISP_ENA_Pin
                            |DISP_DB4_Pin|DISP_DB5_Pin|DISP_DB6_Pin|DISP_DB7_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  
    /*Configure GPIO pin : OTG_FS_PowerSwitchOn_Pin */
    GPIO_InitStruct.Pin = OTG_FS_PowerSwitchOn_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(OTG_FS_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pin : PDM_OUT_Pin */
    GPIO_InitStruct.Pin = PDM_OUT_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
    HAL_GPIO_Init(PDM_OUT_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pin : B1_Pin */
    GPIO_InitStruct.Pin = B1_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pin : I2S3_WS_Pin */
    GPIO_InitStruct.Pin = I2S3_WS_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
    HAL_GPIO_Init(I2S3_WS_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pins : SPI1_SCK_Pin SPI1_MISO_Pin */
    GPIO_InitStruct.Pin = SPI1_SCK_Pin|SPI1_MISO_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(GPIOA, &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 : RMII_PHY_INT_Pin */
    GPIO_InitStruct.Pin = RMII_PHY_INT_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(RMII_PHY_INT_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pin : CLK_IN_Pin */
    GPIO_InitStruct.Pin = CLK_IN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
    HAL_GPIO_Init(CLK_IN_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pins : RMII_PHY_RST_Pin DHT11_IO_Pin LD4_Pin LD3_Pin
                             LD5_Pin LD6_Pin Audio_RST_Pin */
    GPIO_InitStruct.Pin = RMII_PHY_RST_Pin|DHT11_IO_Pin|LD4_Pin|LD3_Pin
                            |LD5_Pin|LD6_Pin|Audio_RST_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 : I2S3_MCK_Pin I2S3_SCK_Pin I2S3_SD_Pin */
    GPIO_InitStruct.Pin = I2S3_MCK_Pin|I2S3_SCK_Pin|I2S3_SD_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  
    /*Configure GPIO pin : VBUS_FS_Pin */
    GPIO_InitStruct.Pin = VBUS_FS_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(VBUS_FS_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pins : OTG_FS_ID_Pin OTG_FS_DM_Pin OTG_FS_DP_Pin */
    GPIO_InitStruct.Pin = OTG_FS_ID_Pin|OTG_FS_DM_Pin|OTG_FS_DP_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  
    /*Configure GPIO pin : OTG_FS_OverCurrent_Pin */
    GPIO_InitStruct.Pin = OTG_FS_OverCurrent_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(OTG_FS_OverCurrent_GPIO_Port, &GPIO_InitStruct);
  
    /*Configure GPIO pins : Audio_SCL_Pin Audio_SDA_Pin */
    GPIO_InitStruct.Pin = Audio_SCL_Pin|Audio_SDA_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
    /*Configure GPIO pin : MEMS_INT2_Pin */
    GPIO_InitStruct.Pin = MEMS_INT2_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(MEMS_INT2_GPIO_Port, &GPIO_InitStruct);
  
    /* EXTI interrupt init*/
    HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  
    HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
  
  }
  
  /* USER CODE BEGIN 4 */
  void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  {
  	if (GPIO_Pin == B1_Pin)
  	{
  		if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_SET)
  		{
  			printf("The blue button is pushed\n");
  			BSP_LED_Toggle(GREEN);
  			osSignalSet (tcpClientTaskHandle, SIGNAL_PUSH_BUTTON);
  		}
  	}
  	else if (GPIO_Pin == RMII_PHY_INT_Pin)
  	{
          /* Get the IT status register value */
          ethernetif_phy_irq();
  	}
  }
  /* 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 LWIP */
    MX_LWIP_Init();
    /* USER CODE BEGIN 5 */
    struct dhcp *dhcp;
    char msg[16];
    bool dhcp_bound_flag = false;
    uint32_t offered_ip = 0;
    /* Infinite loop */
    for(;;)
    {
  	  dhcp = netif_dhcp_data(lwip_get_netif());
  
  	  if (dhcp->state == DHCP_STATE_BOUND && !dhcp_bound_flag)
  	  {
  		  dhcp_bound_flag = true;
  		  lcd_command_set(LCD_CLR_SCR_CMD);
  		  lcd_puts("DHCP IP address:");
  		  lcd_command_set(LCD_LFCR_CMD);
  		  offered_ip = ip4_addr_get_u32(&dhcp->offered_ip_addr);
  		  snprintf(msg, sizeof(msg), "%03lu.%03lu.%03lu.%03lu",
  				  (offered_ip)&0xFF,  (offered_ip >> 8)&0xFF, (offered_ip >> 16)&0xFF, (offered_ip >> 24)&0xFF);
  		  lcd_puts(msg);
  	  }
  
  	  BSP_LED_Toggle(BLUE);
  	  osDelay(1000);
    }
    /* USER CODE END 5 */
  }
  
   /**
    * @brief  Period elapsed callback in non blocking mode
    * @note   This function is called  when TIM1 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 == TIM1) {
      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) */
  	printf("Wrong parameters value: file %s on line %d\r\n", file, line)
    /* USER CODE END 6 */
  }
  #endif /* USE_FULL_ASSERT */
  
  /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  