/* Includes ------------------------------------------------------------------*/
#include "mg32f10x.h"
#include <stdio.h>
#include <string.h>
#include "bsp_uart1.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
const uint8_t testdata[300] = 
{
  0x52,0x79,0x0C,0xAF,0xC0,0x99,0x44,0x71,0x9D,0x30,0xAD,0x68,0xF7,0x95,0xF8,0x38,
  0xF5,0x9C,0x19,0xDD,0xEC,0xBC,0x6C,0xF0,0x71,0xD8,0xE4,0x1D,0x6F,0x7F,0x08,0xD7,
  0x92,0x61,0x36,0x36,0xE3,0x08,0x7E,0xED,0x44,0x22,0x72,0x36,0x84,0x27,0xF5,0x98,
  0x95,0x7C,0xFE,0x4F,0x17,0x8A,0xD3,0x6C,0x43,0xB0,0xBC,0xEC,0x07,0x99,0x81,0x29,
  0x28,0x32,0xFD,0x3B,0x8D,0xCD,0x02,0x97,0xAE,0x80,0xE6,0xC9,0xE5,0x3B,0x9A,0x24,
  0x97,0x31,0xAF,0x57,0x00,0x5E,0xCC,0x1B,0xEB,0x5F,0x2C,0x07,0x68,0x21,0x72,0xFD,
  0x8B,0xDE,0x66,0x74,0xB4,0x09,0xD5,0x33,0xD7,0x5E,0x4A,0x42,0x46,0xD9,0x6F,0x5D,
  0x33,0xCF,0xAD,0xD6,0x62,0x5C,0xF8,0x62,0x92,0x4E,0xE0,0xF0,0x81,0x9A,0xCE,0x94,
  0x5A,0xCC,0x05,0x67,0xD0,0x3E,0xFE,0xB1,0x51,0xFF,0x57,0x8D,0xB1,0x8D,0xAC,0x32,
  0xB5,0xD5,0x7F,0xA8,0xB8,0x4A,0x0E,0xD3,0xEF,0x4A,0x15,0x0D,0x40,0x2D,0xA4,0xC6,
  0x97,0x8D,0x38,0xDA,0xDB,0x54,0xBF,0x6D,0x1C,0xFF,0x54,0xEF,0x82,0x5C,0x40,0xAC,
  0x68,0xA0,0x91,0xEC,0x1B,0x24,0x1D,0x86,0x77,0x5B,0xB6,0x85,0xAF,0xC1,0xAA,0xAD,
  0xC2,0xA6,0xA5,0x76,0x4C,0x66,0xA5,0xFF,0x0A,0x99,0xCA,0x1F,0xC3,0x71,0x86,0xA1,
  0x64,0x85,0xD6,0xA0,0xFB,0xE4,0x68,0x0D,0xDB,0x90,0xC6,0x4B,0x5B,0xB6,0x63,0xE3,
  0x4B,0x8A,0xAA,0x99,0xDD,0x31,0xD2,0xC1,0x4D,0x4A,0xEA,0xC2,0x42,0x36,0xC7,0x0A,
  0x28,0xC8,0xBD,0x46,0x52,0x70,0x94,0x23,0x44,0x39,0xD7,0x07,0xCC,0xCC,0x5C,0x81,
  0x4B,0x2F,0x8C,0xA1,0xDA,0xF4,0x86,0x74,0xB0,0x5A,0x49,0x10,0x1F,0xD4,0x8B,0x7B,
  0x9C,0x65,0x14,0x8E,0x81,0x28,0x6F,0x50,0xE2,0x4E,0x62,0x55,0xFD,0x27,0x7C,0x87,
  0x0E,0xAB,0xD0,0xE9,0x09,0xC7,0x9A,0x77,0xD7,0xBD,0x45,0xEE,
};
uint8_t rx_buffer[300] = {0};
UART_InitTypeDef UART_InitStructure;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

int main(void)
{
  uint32_t tx_index, rx_index;

  /* Init UART1 to 115200-8n1 for print message */
  uart1_init(72000000, 115200);

  /* Enable GPIOA clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_GPIOA, ENABLE);

  /* Enable UART2 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_BMX2 |RCC_APB2Periph_UART2, ENABLE);

  /*
    PA2 (UART2_TX)
    PA3 (UART2_RX)
  */
  GPIO_Init(GPIOA, GPIO_Pin_2 |GPIO_Pin_3, GPIO_MODE_AF |GPIO_OTYPE_PP |GPIO_PUPD_UP |GPIO_SPEED_HIGH |GPIO_AF7);

  /* UART2 configuration */
  UART_DeInit(UART2);
  UART_InitStructure.UART_BaudRate = 115200;
  UART_InitStructure.UART_WordLength = UART_WordLength_8b;
  UART_InitStructure.UART_StopBits = UART_StopBits_One;
  UART_InitStructure.UART_Parity = UART_Parity_None;
  UART_InitStructure.UART_AutoFlowControl = UART_AutoFlowControl_None;
  UART_Init(UART2, &UART_InitStructure);
  UART_FIFOCmd(UART2, ENABLE);

  /* Set the receive address */
  UART2->RAR = 0xD1;

  /* Enable 9-bit data transfer and address match mode */
  UART2->EXTLCR = UART_EXTLCR_WLS_E | UART_EXTLCR_ADDR_MATCH;

  /* Send Address */
  UART2->TAR = 0xD1;
  UART2->EXTLCR |= UART_EXTLCR_SEND_ADDR;

  /* Loop until receive one data */
  while(UART_GetFlagStatus(UART2, UART_FLAG_RFNE) == RESET);
  if(UART_ReadData(UART2) != 0x1D1)
  {
    printf("ERROR: the first received data is not the specified address!\r\n");
  }
  else
  {
    tx_index = 0;
    rx_index = 0;
    while(rx_index != 300)
    {
      /* Send data */
      if(UART_GetFlagStatus(UART2, UART_FLAG_TFNF) != RESET) {
        UART_WriteData(UART2, testdata[tx_index]);
        tx_index++;
      }

      /* Receive data */
      if(UART_GetFlagStatus(UART2, UART_FLAG_RFNE) != RESET) {
        rx_buffer[rx_index] = UART_ReadData(UART2);
        rx_index++;
      }
    }

    /* Check the correctness of received data */
    if(memcmp(rx_buffer, testdata, 300) == 0) {
      printf("Success!\r\n");
    }
    else {
      printf("ERROR: the received data is error!\r\n");
    }
  }

  /* Infinite loop */
  while (1)
  {
  }
}


#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 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) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif
