/**
  ******************************************************************************
  * @file     UART_user.c
  * @author   SINOMCU-AE
  * @brief    USART1 config
  *    
  *          This file provides functions:
  *     USART_CharRead_Callback();
  *     USART_Error_Callback();
  *     Send_buff_Uart();
  *         
  ******************************************************************************
  * @attention 
  *                           DISCLAIMER
  * The present firmware which is for guidance only aims at providing customers
  * with coding information regarding their products in order for them to save
  * time. As a result, SinoMCU shall not be held liable for any direct,indirect
  * or consequential damages with respect to any claims arising from the content 
  * of such firmware and/or the use made by customers of the coding information 
  * contained herein in connection with their products.
  *
  * <h2><center>&copy; Copyright (c) 2021 sinomcu All rights reserved.</center></h2>
  *
  ******************************************************************************
  */

#include "USART1_CFG.h"
#include "UART_User.h"

extern UartRecvStatus recv_status;
extern UartRecvFinishFlag recv_finsh;

extern uint8_t uart_buff[UART_BUFF_LEN];

/**
  * @brief  Function called from USART IRQ Handler when RXNE set
  *         Reading character received on USART RX.
  * @param  None
  * @retval None
  */
void USART_CharRead_Callback(void) {
__IO uint32_t received_char;
  static uint8_t recv_count=0,recv_temp_count=0;

  // Read Received character. RXNE flag is cleared by reading of RDR register 
  received_char = MS32_USART_ReceiveData8(USART1);

  if(received_char == UART_START_CHAR) {                   // $, recv data to buff
    recv_status = RECV_ING;
    recv_finsh = NO_FINISH;
    recv_count =0;recv_temp_count=0;
    uart_buff[recv_count++] =received_char;
  }
  else if(recv_status == RECV_ING) {                       // had recv $,data to buff
    uart_buff[recv_count++] =received_char;
    if((received_char == UART_END_CHAR) || (recv_count >= UART_BUFF_LEN)) {         // recv 0x0A or had recv buff len,end recv
      uart_buff[recv_count] ='\0';
      recv_count =0;
      recv_status = RECV_FIN;
      recv_finsh = FINISH;
    }
  }
  else {                                                   // have't recv $,data discard
    recv_status =  WAIT_STAR;
    recv_temp_count++;
    if((received_char == UART_END_CHAR) || (recv_temp_count >= UART_BUFF_LEN)) {    // recv 0x0A or had recv buff len,end recv
      recv_finsh = RECV_ERROR;
      recv_temp_count=0;
    }
  }
}

/**
  * @brief  Function called in case of error detected in USART IT Handler
  * @param  None
  * @retval None
  */
void USART_Error_Callback(void) {
  __IO uint32_t isr_reg;

  isr_reg = MS32_USART_ReadReg(USART1, ISR);
  if (isr_reg & MS32_USART_ISR_ORE)  {
    recv_status = UART_ERROR_ORE;
    MS32_USART_ClearFlag_ORE(USART1);  
  } 
  else if(isr_reg & MS32_USART_ISR_NE)  {
    recv_status = UART_ERROR_NIOSE;
      NVIC_DisableIRQ(USART1_IRQn);
  } 
  else {
    recv_status = UART_ERROR_NO_DEF;
      NVIC_DisableIRQ(USART1_IRQn);
  }
}

/**
  * @brief  send buff to uart,end with chat '\0'
  * @param  pointer of send buff,uint8_t ptr
  * @retval None
  */
void Send_buff_Uart(uint8_t *uart_buff) {
  uint8_t send_count = 0;
  for(send_count = 0; uart_buff[send_count] !='\0';) {     // str end by '\0'
    if(MS32_USART_IsActiveFlag_TXE(USART1)) {
      MS32_USART_TransmitData8(USART1,uart_buff[send_count++]);
    }
    if(send_count > UART_BUFF_LEN) {                       // also end by max len
      break;
    }
  }
}


/******************************** END OF FILE *********************************/
