/*
 * boot_api.c
 *
 *  Created on: 2019年10月26日
 *      Author: wjandcf
 */

#include <type_define.h>
#include <lpuart1.h>
#include "common.h"

#if defined (INST_LPUART1)
lpuart_buff_t UART1_Callback_Data;
uint8_t UART1_Rx_Buf;
uint8_t UART1_User_Rx_Buf[UART1_User_Rx_Buf_Size];  /* UART1 User receive  buffer */
uint16_t UART1_User_Rx_In   = 0;
uint16_t UART1_User_Rx_Out  = 0;

#endif


/*!
 * boot 功能函数 地址列表
 *
 */
const uint32_t boot_api[3]= {
  0x00000424, /* sum_add */
  0x00000428, /* ymodem_crc16 */
  0x0000042C, /* get_lpuart_data */
};

/*!
 *
 * sum_add
 * @ a
 * @ b
 * @ return  a + b
 *
 **/
uint32_t sum_add(uint32_t a, uint32_t b)
{
  uint32_t (*func_ptr)(uint32_t, uint32_t);
  func_ptr = (uint32_t (*)(uint32_t, uint32_t))(*(uint32_t *)boot_api[0]);
  return func_ptr(a, b);
}

/*!
 * ymodem_crc16
 * @ func_ptr : function pointer type
 * @ buffer   : buffer address pointer
 * @ size     : crc16 calculate size
 **/
uint16_t ymodem_crc16(uint8_t *buffer, uint16_t size)
{
  uint16_t (*func_ptr)(uint8_t*, uint16_t);
  func_ptr = (uint16_t (*)(uint8_t*, uint16_t))(*(uint32_t *)boot_api[1]);
  return func_ptr(buffer, size);
}


/*!
 * @brief callback for all peripherals which support UART features
 * Implements : uart_callback_t_class
 *
 */
void LPUART1_Rx_Callback_IRQHandler(void *driverState, uart_event_t event, void *userData)
{
#if defined (INST_LPUART1)
  lpuart_state_t * s_lpuartStatePtr = ( lpuart_state_t * ) driverState;
  if (s_lpuartStatePtr->transferType == LPUART_USING_INTERRUPTS) {
    lpuart_buff_t * s_lpuart_buff_Ptr = ( lpuart_buff_t * ) userData;
    uint8_t * (*func_ptr)(lpuart_buff_t *, uint32_t __IO *);
    func_ptr = (uint8_t *(*)(lpuart_buff_t *, uint32_t __IO *))(*(uint32_t *)boot_api[2]);
    s_lpuartStatePtr->rxBuff = func_ptr(s_lpuart_buff_Ptr, &s_lpuartStatePtr->rxSize);
  }
#endif
}

/*!
 * @brief LPUART_DRV_Callback_Init
 * Implements : uart_callback_t_class
 *
 */
void LPUART_DRV_Callback_Init(uint32_t instance, lpuart_buff_t *userData)
{
#if defined (INST_LPUART1)
  if (instance == 1) {
    userData->rx_buf = &UART1_Rx_Buf;
    userData->user_buf = UART1_User_Rx_Buf;
    userData->in = &UART1_User_Rx_In;
    userData->size = UART1_User_Rx_Buf_Size;
    LPUART_DRV_InstallRxCallback(instance, LPUART1_Rx_Callback_IRQHandler, userData);
    LPUART_DRV_ReceiveData(instance, &UART1_Rx_Buf, 1);
  }
#endif
}


