#include "bsp_uart.h"
#include "elog.h"

UART_HELPER_TypeDef * UART_HELPER_Init( )
{
    UART_HELPER_TypeDef *Handle = (UART_HELPER_TypeDef *)malloc(sizeof(UART_HELPER_TypeDef));
    if (Handle == NULL)
    {
        return NULL;
    }
	Handle->interface_type = Uart_Interface_Default;
	Handle->enable_idle_it = Uart_IDLE_IT_DISABLE;
	Handle->trans_mode = Uart_Trans_Polling;
	Handle->rcv_mode = Uart_Trans_Polling;

	Handle->trans_record = (Record_Trans_Rcv_TypeDef *)malloc(sizeof(Record_Trans_Rcv_TypeDef));
	// Handle->rcv_record = (Record_Trans_Rcv_TypeDef *)malloc(sizeof(Record_Trans_Rcv_TypeDef));

	Handle->send_flag = 0;
	Handle->send_tc_flag = 0;
	Handle->transferring = 0;

	Handle->enable_trans_gpio =NULL;
	Handle->enable_trans_cplt_gpio =NULL;

	Handle->obj =NULL;
	Handle->callback =NULL;
    return Handle;
}

void UART_HELPER_Set_Huart(UART_HELPER_TypeDef * uarthelper, UART_HandleTypeDef *huart)
{
    uarthelper->huart = huart;
}

int UART_HELPER_Set_Interface_Type(UART_HELPER_TypeDef * uarthelper, uint8_t interface_type)
{
	uarthelper->interface_type = interface_type;
	return 0;
}

int UART_HELPER_Setup_Trans_mode( UART_HELPER_TypeDef * uarthelper, uint8_t trans_mode )
{
    /* 0 :polling, 1: IT  2: DMA*/
	uarthelper->trans_mode = trans_mode;
	uarthelper->rcv_mode = trans_mode;
	return 0;
}

int UART_HELPER_Setup_Rcv_mode( UART_HELPER_TypeDef * uarthelper, uint8_t rcv_mode )
{
    /* 0 :polling, 1: IT  2: DMA*/
	uarthelper->rcv_mode = rcv_mode;
	return 0;    
}

int UART_HELPER_Set_trans_GPIO( UART_HELPER_TypeDef * uarthelper, enable_func_gpio trans_gpio_func )
{
	uarthelper->enable_trans_gpio = trans_gpio_func;
	return 0;
}

int UART_HELPER_Set_trans_cplt_GPIO( UART_HELPER_TypeDef * uarthelper, enable_func_gpio trans_cplt_gpio_func )
{
    // enable rcv
    uarthelper->enable_trans_cplt_gpio = trans_cplt_gpio_func;
	return 0;
}



int UART_HELPER_Set_enable_idle( UART_HELPER_TypeDef * uarthelper, uint8_t enable_idle)
{
	uarthelper->enable_idle_it = enable_idle;
	return 0;
}


int UART_HELPER_Set_Rcv_Buf( UART_HELPER_TypeDef * uarthelper, uint8_t * buf, uint16_t size)
{
	uarthelper->rcv_buf = buf;
	uarthelper->rcv_size = size;

	// uarthelper->rcv_record->buf = buf;
	// uarthelper->rcv_record->size = size;

	return 0;

}
int UART_HELPER_Set_Trans_Buf( UART_HELPER_TypeDef * uarthelper, uint8_t * buf, uint16_t size)
{
	// uarthelper->trans_buf = buf;
	// uarthelper->trans_size = size;

	uarthelper->trans_record->buf = buf;
	uarthelper->trans_record->size = size;

	return 0;

}

int UART_HELPER_Set_Callback( UART_HELPER_TypeDef * uarthelper, void *obj, callback_fun func)
{
	uarthelper->obj = obj;
	uarthelper->callback = func;
	return 0;
}

int UART_HELPER_Start_Rcv(UART_HELPER_TypeDef * uarthelper, uint8_t *buf, uint16_t size)
{
	int st;
    switch ( uarthelper->rcv_mode)
    {
        case 0:
            st = HAL_UART_Receive(uarthelper->huart,  buf,  size  , 0xFFFF);
            return st;
            break;
        case 1:
            st = HAL_UART_Receive_IT(uarthelper->huart,  buf,  size);
            return st;
            break;
        case 2:
            /* 会出现 st ==2  huart->gState != HAL_UART_STATE_READY */
			if (uarthelper->enable_idle_it == 1) 
			{
            // log_d("dma rcv idle en... ");
				__HAL_UART_ENABLE_IT(uarthelper->huart, UART_IT_IDLE);
			}
            st = HAL_UART_Receive_DMA(uarthelper->huart,  buf,  size);
            // log_i("dma rcv ... ");
            return st;
            break;    
        default:
            break;
    }
    return st;
}

int UART_HELPER_Trans(UART_HELPER_TypeDef * uarthelper, uint8_t *buf, uint16_t size )
{
	int st;
    uarthelper->transferring = 1;
	if (uarthelper->enable_trans_gpio != NULL)
	{
		uarthelper->enable_trans_gpio();
	}

    switch ( uarthelper->trans_mode)
    {
        case 0:
            st = HAL_UART_Transmit(uarthelper->huart,  buf,  size  , 0xFFFF);
            return st;
            break;
        case 1:
            st = HAL_UART_Transmit_IT(uarthelper->huart,  buf,  size);
            return st;
            break;
        case 2:
            /* 会出现 st ==2  huart->gState != HAL_UART_STATE_READY */
            st = HAL_UART_Transmit_DMA(uarthelper->huart,  buf,  size);
            return st;
            break;    
        default:
            break;
    }
    return st;
}


int UART_HELPER_Trans_TxCplt_Callback( UART_HELPER_TypeDef * uarthelper )
{
    // log_d( " uarthelper tc callback...........");
    uarthelper->transferring = 0;
	if (uarthelper->enable_trans_cplt_gpio != NULL)
	{
        // log_i( " uarthelper tc callback... not null........");
		uarthelper->enable_trans_cplt_gpio();
	}
    return 0;
}

int UART_HELPER_RCV_Cplt_Callback( UART_HELPER_TypeDef * uarthelper )
{
    log_i( " UART_HELPER_RCV_Cplt_Callback  ........");

    // TODO
    
    if (uarthelper->enable_idle_it == 0)
    {
        uarthelper->callback( uarthelper->obj, uarthelper->rcv_buf,uarthelper->rcv_size);
    }
    if (uarthelper->enable_idle_it == 1)
    {
        // idle 中断处理， do nothing
    }
    return 0;
}


int UART_HELPER_RCV_IDLE_Callback( UART_HELPER_TypeDef * uarthelper, uint16_t size )
{
    // TODO
    // if (uarthelper->rcv_mode == 0)
    // {
    //     HAL_UART_DMAStop( uarthelper->huart );
    // }

    // 包含停止DMA 开始新的接收
    HAL_UART_DMAStop( uarthelper->huart );
    uarthelper->callback( uarthelper->obj, uarthelper->rcv_buf, size);
    UART_HELPER_Start_Rcv(uarthelper, uarthelper->rcv_buf, uarthelper->rcv_size);
    return 0;
}