//socket实现代码
#include "stm32l4xx_hal.h"
#include "nb_iot.h"

uint8_t uart3_char;
uint8_t UartTxDone;
extern UART_HandleTypeDef huart3;
TIM_HandleTypeDef htim3;
extern NB_CtrlTypeDef NB;
/**
* @brief  NB IO Initalization.
*         This function inits the UART interface to deal with the NB,
*         then starts asynchronous listening on the RX port.
* @param None
* @retval 0 on success, -1 otherwise.
*/
int8_t NB_IO_Init(void)
{
//  uint8_t data;
  /* Set the NB USART configuration parameters */
  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;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  
  /* Configure the USART IP */
  if(HAL_UART_Init(&huart3) != HAL_OK)
  {
    return -1;
  }
  
  HAL_UART_Receive_IT(&huart3, &uart3_char, 1);
  
  return 0;
}

/**
* @brief  NB IO Deinitialization.
*         This function Deinits the UART interface of the NB. When called
*         the NB commands can't be executed anymore.
* @param  None.
* @retval None.
*/
void NB_IO_DeInit(void)
{
  /* Reset USART configuration to default */
  HAL_UART_DeInit(&huart3);
}

/**
* @brief  Send Data to the NB module over the UART interface.
*         This function allows sending data to the  NB NB Module, the
*          data can be either an AT command or raw data to send over 
a pre-established NB connection.
* @param pData: data to send.
* @param Length: the data length.
* @retval 0 on success, -1 otherwise.
*/
int8_t NB_IO_Send(char* pData, uint32_t Length)
{
  uint32_t tickstart;
  
  UartTxDone = 0;
  if (HAL_UART_Transmit_IT(&huart3, (uint8_t *)pData, Length) != HAL_OK)
  {
    return -1;
  }
  tickstart = HAL_GetTick();
  while(UartTxDone!=1)
  {
    if((HAL_GetTick()-tickstart) > NB_WRITE_TIMEOUT)
    {
      return -1;
    }
  }
  
  return 0;
}

/**
* @brief  Rx Callback when new data is received on the UART.
* @param  UartHandle: Uart handle receiving the data.
* @retval None.
*/

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  kfifo_in(&NB.io_fifo, &uart3_char, 1);
  HAL_UART_Receive_IT(&huart3, &uart3_char, 1);
  NB.io_updata_time = HAL_GetTick();
  NB.io_updata_sign++;
  HAL_TIM_Base_Stop_IT(&htim3);
  HAL_TIM_Base_Start_IT(&htim3);
//  printf("%c", uart3_char);
//  printf("UART_RxC tick:%d\r\n", HAL_GetTick());
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  /* Set transmission flag: transfer complete */
  UartTxDone = 1;  
}
/**
* @brief  Function called when error happens on the UART.
* @param  UartHandle: Uart handle receiving the data.
* @retval None.
*/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
{
  /* Add user code here*/
}

void MX_TIM3_Init(void)
{
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 2399;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 1000;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.RepetitionCounter = 0;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
//  if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK)
//  {
//    Error_Handler();
//  }
//  printf("MX_TIM3_Init tick:%d\r\n", HAL_GetTick());
}

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
//  printf("TIM3_IRQHandler tick:%d\r\n", HAL_GetTick());
  HAL_TIM_IRQHandler(&htim3);
}

//回调函数，定时器中断服务函数调用的HAL库函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim==(&htim3))
  {
    nbiot_revc_data_process(0, 0);
//    HAL_TIM_Base_Stop_IT(&htim3);
  }
}

/**
* @brief  Receive Data from the NB module over the UART interface.
*         This function receives data from the  NB NB module, the
*         data is fetched from a ring buffer that is asynchonously and continuously
filled with the received data.
* @param  Buffer: a buffer inside which the data will be read.
* @param  Length: the Maximum size of the data to receive.
* @retval int32_t: the actual data size that has been received.
*/
int32_t NB_IO_Receive(uint8_t* Buffer, uint32_t Length)
{
  return kfifo_out(&NB.io_fifo, Buffer, Length);
}