/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    app_threadx.c
  * @author  MCD Application Team
  * @brief   ThreadX applicative file
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2020-2021 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 "app_threadx.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include <stdint.h>
#include <stdio.h>

#include "tx_queue.h"

#include "keys_thread.h"
#include "gsm_thread.h"
#include "gsm_rx_thread.h"
#include "fan_thread.h"
#include "eth_thread.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#define KEYS_THREAD_STACK_SIZE_BYTES		(1024U)
#define GSM_THREAD_STACK_SIZE_BYTES			(1024U)
#define GSM_RX_THREAD_STACK_SIZE_BYTES		(1024U)
#define FAN_THREAD_STACK_SIZE_BYTES			(512U)
#define ETH_THREAD_STACK_SIZE_BYTES			(2048U)

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

TX_THREAD scan_keys_thread;
TX_THREAD gsm_thread;
TX_THREAD gsm_rx_thread;
TX_THREAD fan_thread;
TX_THREAD eth_thread;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/**
  * @brief  Application ThreadX Initialization.
  * @param memory_ptr: memory pointer
  * @retval int
  */
UINT App_ThreadX_Init(VOID *memory_ptr)
{
  UINT ret = TX_SUCCESS;
  /* USER CODE BEGIN App_ThreadX_MEM_POOL */

  TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;
  VOID *keys_thread_pointer;
  VOID *gsm_thread_pointer;
  VOID *gsm_rx_thread_pointer;
  VOID *fan_thread_pointer;
  VOID *eth_thread_pointer;

  /* USER CODE END App_ThreadX_MEM_POOL */

  /* USER CODE BEGIN App_ThreadX_Init */

  // Allocate the stack for key thread
  ret = tx_byte_allocate(byte_pool, &keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }

  char* scan_keys_thread_name = "Scan Keys Thread";
  ret = tx_thread_create(&scan_keys_thread, scan_keys_thread_name, scanKeysThread, 0x0001, keys_thread_pointer, KEYS_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", scan_keys_thread_name); return ret; }


  // Allocate the stack for gsm send thread
  ret = tx_byte_allocate(byte_pool, &gsm_thread_pointer, GSM_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }

  char* gsm_thread_name = "GSM Thread";
  ret = tx_thread_create(&gsm_thread, gsm_thread_name, gsmThread, 0x0001,	gsm_thread_pointer, GSM_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", gsm_thread_name); return ret; }

  // Allocate the stack for gsm rx thread
  ret = tx_byte_allocate(byte_pool, &gsm_rx_thread_pointer, GSM_RX_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }

  char* gsm_rx_thread_name = "GSM RX Thread";
  ret = tx_thread_create(&gsm_rx_thread, gsm_rx_thread_name, gsmRxThread, 0x0001, gsm_rx_thread_pointer, GSM_RX_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", gsm_rx_thread_name); return ret; }

  // Allocate the stack for fan control thread
  ret = tx_byte_allocate(byte_pool, &fan_thread_pointer, FAN_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }

  char* fan_thread_name = "FAN Thread";
  ret = tx_thread_create(&fan_thread, fan_thread_name, fanThread, 0x0001, fan_thread_pointer, FAN_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", fan_thread_name); return ret; }

  // Allocate the stack for ethernet thread
  ret = tx_byte_allocate(byte_pool, &eth_thread_pointer, ETH_THREAD_STACK_SIZE_BYTES, TX_NO_WAIT);
  if (ret != TX_SUCCESS) { printf("Cannot allocate bytes of memory!\n"); return ret; }

  char* eth_thread_name = "ETH Thread";
  ret = tx_thread_create(&eth_thread, eth_thread_name, ethThread, 0x0001, eth_thread_pointer, ETH_THREAD_STACK_SIZE_BYTES, TX_MAX_PRIORITIES-1, TX_MAX_PRIORITIES-1, TX_NO_TIME_SLICE, TX_AUTO_START);
  if (ret != TX_SUCCESS) { printf("Cannot create %s!\n", fan_thread_name); return ret; }


  /* USER CODE END App_ThreadX_Init */

  return ret;
}

  /**
  * @brief  Function that implements the kernel's initialization.
  * @param  None
  * @retval None
  */
void MX_ThreadX_Init(void)
{
  /* USER CODE BEGIN  Before_Kernel_Start */

  /* USER CODE END  Before_Kernel_Start */

  tx_kernel_enter();

  /* USER CODE BEGIN  Kernel_Start_Error */

  /* USER CODE END  Kernel_Start_Error */
}

/**
  * @brief  App_ThreadX_LowPower_Timer_Setup
  * @param  count : TX timer count
  * @retval None
  */
void App_ThreadX_LowPower_Timer_Setup(ULONG count)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Timer_Setup */

  /* USER CODE END  App_ThreadX_LowPower_Timer_Setup */
}

/**
  * @brief  App_ThreadX_LowPower_Enter
  * @param  None
  * @retval None
  */
void App_ThreadX_LowPower_Enter(void)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Enter */

  /* USER CODE END  App_ThreadX_LowPower_Enter */
}

/**
  * @brief  App_ThreadX_LowPower_Exit
  * @param  None
  * @retval None
  */
void App_ThreadX_LowPower_Exit(void)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Exit */

  /* USER CODE END  App_ThreadX_LowPower_Exit */
}

/**
  * @brief  App_ThreadX_LowPower_Timer_Adjust
  * @param  None
  * @retval Amount of time (in ticks)
  */
ULONG App_ThreadX_LowPower_Timer_Adjust(void)
{
  /* USER CODE BEGIN  App_ThreadX_LowPower_Timer_Adjust */
  return 0;
  /* USER CODE END  App_ThreadX_LowPower_Timer_Adjust */
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */
