/**
  ******************************************************************************
  * @file     USART1_user.c
  * @author   SINOMCU-AE
  * @brief    USART1 using
  *    
  *          This file provides functions to USART1 using:
  *      DMA1_ReceiveComplete_Callback();
  *      DMA1_TransferError_Callback();  
  *      Send_buff_Uart(uint8_t *uart_buff);   
  *      dma_uart_rx_init();
  *
  ******************************************************************************
  * @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_user.h"

extern uint8_t uart_buff[];
extern FlagStatus DMA_ReceptionComplete_Flag;
extern FlagStatus DMA_TransferError_Flag; 

/**
  * @brief  Function called by DMA1 IRQ Handler when Rx transfer is completed 
  * @param  None
  * @retval None
  */
void DMA1_ReceiveComplete_Callback(void) {
  DMA_ReceptionComplete_Flag = SET;
}

/**
  * @brief  Function called in case of error detected in DMA1 IRQ Handler
  * @param  None
  * @retval None
  */
void DMA1_TransferError_Callback(void) {
  DMA_TransferError_Flag = SET;
  MS32_DMA_DisableChannel(DMA1, MS32_DMA_CHANNEL_3);       // DMA transfer error,disable this channel
}

/**
  * @brief  send buff to uart
  * @param  pointer of send buff,send byte number
  * @retval None
  */
void Send_buff_Uart(uint8_t *uart_buff,uint8_t buff_len) {
  uint8_t send_count = 0;
  for(send_count = 0; send_count < buff_len;) {
    if(MS32_USART_IsActiveFlag_TXE(USART1)) {              // wait TXE set;TDR empty
      MS32_USART_TransmitData8(USART1,uart_buff[send_count++]);
    }
  }
}

/**
* @brief  DMA Initialization Function
          DMA channel3 receive USART1 data.
* @param  None
* @retval None
*/
void dma_uart_rx_init(void) {
  MS32_DMA_InitTypeDef  DmaInitStruct;
  
  // config DMA channel 3
  MS32_DMA_StructInit(&DmaInitStruct);
  DmaInitStruct.PeriphOrM2MSrcAddress = MS32_USART_DMA_GetRegAddr(USART1, MS32_USART_DMA_REG_DATA_RECEIVE);  // USART_RDR address
  DmaInitStruct.MemoryOrM2MDstAddress = (uint32_t)uart_buff;
  DmaInitStruct.Direction = MS32_DMA_DIRECTION_PERIPH_TO_MEMORY;
  DmaInitStruct.NbData = UART_BUFF_LEN;
  DmaInitStruct.PeriphOrM2MSrcIncMode = MS32_DMA_PERIPH_NOINCREMENT;
  DmaInitStruct.MemoryOrM2MDstIncMode = MS32_DMA_MEMORY_INCREMENT;
  DmaInitStruct.PeriphOrM2MSrcDataSize = MS32_DMA_PDATAALIGN_BYTE;
  DmaInitStruct.MemoryOrM2MDstDataSize = MS32_DMA_MDATAALIGN_BYTE;
  DmaInitStruct.Mode = MS32_DMA_MODE_CIRCULAR;
  DmaInitStruct.Priority = MS32_DMA_PRIORITY_HIGH;
  MS32_DMA_Init(DMA1,MS32_DMA_CHANNEL_3,&DmaInitStruct);   // this function had enable DMA clock
  
  // enable DMA channel 3
  MS32_DMA_EnableChannel(DMA1, MS32_DMA_CHANNEL_3);
  // enable DMA channel 3 TCIE,TEIE
  MS32_DMA_ITConfig(DMA1,MS32_DMA_CHANNEL_3,MS32_DMA_CCR_TCIE|MS32_DMA_CCR_TEIE,1);
  MS32_DMA_ClearFlag_TC3(DMA1);
}
/******************************** END OF FILE *********************************/
