#include "sc6.h"

osThreadId_t SC6_Handle;
const osThreadAttr_t SC6_attributes = {
    .name       = "SC6",
    .stack_size = 1024,
    .priority   = (osPriority_t) osPriorityBelowNormal,
};

// 事件
osEventFlagsId_t SC6_EventHandle;
const osEventFlagsAttr_t SC6_Event_attributes = {
  .name = "SC6_Event"
};

extern UART_HandleTypeDef huart1;
UART_HandleTypeDef *pSC6Uart = &huart1;

static uint8_t SC6_TRANS_BUF[8]  = { 0x52, 0x45, 0x53, 0x55, 0x4D, 0x45, 0x0D, 0x0A };
static uint8_t SC6_start_buf[8]  = { 0x52, 0x45, 0x53, 0x55, 0x4D, 0x45, 0x0D, 0x0A };  /* RESUME\r\n*/
static uint8_t SC6_stop_buf[7]   = { 0x50, 0x41, 0x55, 0x53, 0x45, 0x0D, 0x0A };  /* PAUSE\r\n*/

static uint8_t SC6_start_rcv_buf[12]  = { 0x52, 0x45, 0x53, 0x55, 0x4D, 0x45, 0x44, 0x2E, 0x2E, 0x2E, 0x0D, 0x0A };  /* RESUMED...\r\n*/
static uint8_t SC6_stop_rcv_buf[11]   = { 0x50, 0x41, 0x55, 0x53, 0x45, 0x44, 0x2E, 0x2E, 0x2E, 0x0D, 0x0A  };  /* PAUSED...\r\n*/


static uint8_t data_start_tag[7] =  {0x53, 0x43, 0x36 ,0x2d , 0x4c , 0x50 , 0x54};  //, "SC6-LPT" 
static uint8_t data_end_tag[2] = {0x0D, 0x0A};

static uint8_t SC6_RCV_BUF[ 2* SC6_Result_Buf_Size ] = {0};

UART_HELPER_TypeDef *SC6_uart_helper;

SC6_TypeDef  sc6 ={
    SC6_Init,
    SC6_Port,
    SC6_Test,
    SC6_Start,
    SC6_Stop,
    NULL,
    0,      // state
    0,      // data_ok
    {0},    // buf
    0,      // size_received
    0,      // time base
    1000,      // timeout ticks,  1000ms = 1S
    0,          // event_flag
	{0},
	{0},
	{0},
	0xFFFF,
};

int SC6_Init( )
{
    SC6_uart_helper = UART_HELPER_Init( );

    if (SC6_uart_helper ==NULL)  return -1;

    // TODO 接口
    UART_HELPER_Set_Huart( SC6_uart_helper, pSC6Uart );
    UART_HELPER_Set_Interface_Type(SC6_uart_helper, Uart_Interface_Max3160_485);

    //  传输
    UART_HELPER_Setup_Trans_mode(  SC6_uart_helper, Uart_Trans_DMA);
    // UART_HELPER_Setup_Rcv_mode( SC6_uart_helper, Uart_Trans_IT );
    UART_HELPER_Set_enable_idle(  SC6_uart_helper, Uart_IDLE_IT_ENABLE);

    //  回调GPIO 操作 数据操作
    UART_HELPER_Set_trans_GPIO(  SC6_uart_helper, SC6_Trans_GPIO );  // enbale rcv
    UART_HELPER_Set_trans_cplt_GPIO( SC6_uart_helper, SC6_Trans_Cplt_GPIO );

    UART_HELPER_Set_Callback( SC6_uart_helper,&sc6, SC6_CallBack );

    // 设置 Buf
    UART_HELPER_Set_Rcv_Buf(SC6_uart_helper, SC6_RCV_BUF, sizeof(SC6_RCV_BUF));
    UART_HELPER_Set_Trans_Buf( SC6_uart_helper, SC6_TRANS_BUF, sizeof(SC6_TRANS_BUF) );

    //  GPIO 操作
    switch (SC6_uart_helper->interface_type)
    {
        case Uart_Interface_Default:
            break;
        case Uart_Interface_485:
            usart6_send_enable();   
            break;
        case Uart_Interface_Max3160_232:
            SC6_MAX3160_232();
            break;
        case Uart_Interface_Max3160_485:
            max3160_485_receive_mode();
            break;    
        default:
            break;
    }
    sc6.state = SC6_State_Waiting;
    sc6.timebase_ticks = osKernelGetTickCount( );
}

void SC6_Port( )
{
    SC6_Handle = osThreadNew( SC6_Task, NULL, &SC6_attributes );
    // SC6_EventHandle = osEventFlagsNew(&SC6_Event_attributes);
}

int SC6_Test( )
{
    sc6.state = SC6_State_Test;  // 操作状态
    return 0;
}

void SC6_Start( )
{
    sc6.state = SC6_State_Start;  // 操作状态
 
}

void SC6_Stop( )
{
    sc6.state = SC6_State_Stop;
    // TODO stop  task？
}

void SC6_Task( )
{
   // memset(  SC6_RCV_Buf, 0, 2*SC6_Rcv_Buf_Size );  /* ph*3 ph *2 否则内存泄漏 */
    sc6.event_flag = 0;
    static uint64_t  ticks;
    static int err_con = 0;
    static int st;
    for ( ; ; )
    {  
        switch (sc6.state)
        {
        case SC6_State_Waiting:
            log_i( " SC6_ task..... : %d    %d " , sc6.state , sc6.state );
            osDelay(20);
            break;

        case SC6_State_Test:
			log_d( " SC6_  test     ...   "  );
			ticks = osKernelGetTickCount();
			sc6.size_received = 0;
			sc6.index_SC6_LPT = 0xFFFF;
            sc6.state = SC6_State_Test_Data_Getting;
			ticks = osKernelGetTickCount();
	        UART_HELPER_Set_Trans_Buf( SC6_uart_helper, SC6_TRANS_BUF, sizeof(SC6_TRANS_BUF) );
            SC6_Receive();
            SC6_Transmit();
 
            sc6.state = SC6_State_Test_Data_Getting;
            continue;
        case SC6_State_Test_Data_Getting:
             if ( osKernelGetTickCount() - ticks > 2000 )
            {
                err_con++;
                if( err_con >3)
                {
                    log_w( " SC6_ Test data gettting ... error "  );
                    sc6.state = SC6_State_Error;
                }
                sc6.state = SC6_State_Test;                
            }
            osDelay(1);
            continue;

        case SC6_State_Test_OK:
			HAL_UART_DMAStop(SC6_uart_helper->huart );
			sc6.state = SC6_State_Error;
			sc6.size_received = 0;
			sc6.index_SC6_LPT =0xFFFF;
			err_con = 0;   		
            sc6.state = SC6_State_Ready;                
            continue;

        case SC6_State_Ready:
            osDelay(1);
            continue;

        case SC6_State_Start:
			ticks = osKernelGetTickCount();
			sc6.size_received = 0;
			sc6.index_SC6_LPT = 0xFFFF;
            sc6.state = SC6_State_Start_Trans;
            continue;
        case SC6_State_Start_Trans:
            UART_HELPER_Set_Trans_Buf( SC6_uart_helper, SC6_TRANS_BUF, sizeof(SC6_TRANS_BUF) );
            // HAL_UARTEx_ReceiveToIdle_DMA(&huart1, SC6_RCV_BUF,13);
            // __HAL_UART_ENABLE_IT( &huart1, UART_IT_IDLE );
            // HAL_UART_Receive_DMA( &huart1, SC6_RCV_BUF, 13 );
            SC6_Receive();
            SC6_Transmit();
            ticks =  osKernelGetTickCount();
            err_con = 0;
            sc6.state = SC6_State_Check_Data;
            continue;
        // case SC6_State_Data_Getting:
        //     if ( osKernelGetTickCount() - ticks > 2000 )
        //     {
        //         err_con++;
        //         if( err_con >3)
        //         {
        //             log_w( " SC6_ gettting ... error "  );
        //             sc6.state = SC6_State_Error;
        //         }
        //         sc6.state = SC6_State_Start_Trans;                
        //     }
        //     osDelay(1);
        //     continue;
        case SC6_State_Check_Data:
			// log_d( " SC6_ _Check_Data   %d   size_received  %d  sc6.index_SC6_LPT site -> %d" , 
			// 		sc6.state ,sc6.size_received, sc6.index_SC6_LPT );
			// log_d( " SC6_Task    %s   " , sc6.SC6_Data_Buf );

			// find begin tag   "SC6_LPT" ,index_SC6_LPT 为出现 "SC6_LPT" 的位置编号
            if ( sc6.index_SC6_LPT==0xFFFF && sc6.size_received > 2*SC6_Rcv_Buf_Size +SC6_RESUMED_Buf_Size) 
            {
				log_d( " SC6_Task  check ....bytes overflow   "  );
                err_con++;
                if( err_con > 2)
                {
                    HAL_UART_DMAStop(SC6_uart_helper->huart );
                    sc6.state = SC6_State_Error;
                    sc6.size_received = 0;
                    sc6.index_SC6_LPT =0xFFFF;
                    err_con = 0;   
                    break;                     
                }
                // 重新测量
                log_w( " SC6_ Get Data  Error %d,  Retrying...", err_con   );
                HAL_UART_DMAStop(SC6_uart_helper->huart );
            }
            sc6.index_SC6_LPT = 0xFFFF;
            // if ( sc6.index_SC6_LPT==0xFFFF && sc6.size_received <= 2*SC6_Rcv_Buf_Size +SC6_RESUMED_Buf_Size && sc6.size_received!=0) 
            if ( sc6.index_SC6_LPT==0xFFFF   && sc6.size_received!=0 ) 
            {
				// log_d( " SC6_Task  check ....  "  );
                for (size_t i = 0; i < sc6.size_received; i++)
                {
                    if (sc6.result_buf[i]  == data_start_tag[0] ) 
                    {
                        // log_d( " ....i   %d   %02X   %02X", i ,data_start_tag[0], sc6.result_buf[i] );
                        if ( sc6.result_buf[i+1]  == data_start_tag[1] && sc6.result_buf[i+2]  == data_start_tag[2]
                            &&  sc6.result_buf[i+3]  == data_start_tag[3] &&  sc6.result_buf[i+4]  == data_start_tag[4]
                            &&  sc6.result_buf[i+5]  == data_start_tag[5] &&  sc6.result_buf[i+6]  == data_start_tag[6])
                        {
                            sc6.index_SC6_LPT = i;
                            break;
                        }

                    }
                }
            }

            if ( sc6.index_SC6_LPT!=0xFFFF ) 
            {
                // log_d( "  SC6_LPT was found  %d  %d  %d  " ,sc6.size_received,sc6.index_SC6_LPT,SC6_Rcv_Buf_Size );
                // log_d( "  sc6.result_buf[sc6.index_SC6_LPT+SC6_Result_Buf_Size-1]  %02X  " ,sc6.result_buf[sc6.index_SC6_LPT+SC6_Result_Buf_Size-1] );
 
                if (  (sc6.size_received - sc6.index_SC6_LPT >= SC6_Result_Buf_Size) 
                        && sc6.result_buf[sc6.index_SC6_LPT+SC6_Result_Buf_Size-1] == data_end_tag[1] )
                {
                    log_i("SC6_ Get Data OK..." );
                    HAL_UART_DMAStop(SC6_uart_helper ->huart );
                    memset(SC6_RCV_BUF, 0, sizeof(SC6_RCV_BUF));
                    //  result  sn 
                    memcpy( sc6.SC6_Result_Buf, sc6.result_buf[sc6.index_SC6_LPT], SC6_Result_Buf_Size);
                    memcpy( sc6.SC6_sn_buf, sc6.result_buf[sc6.index_SC6_LPT+4], 4);
                    sc6.size_received = 0;
                    sc6.index_SC6_LPT =0xFFFF;
                    err_con = 0;
                    UART_HELPER_Set_Trans_Buf( SC6_uart_helper , SC6_stop_buf, sizeof(SC6_stop_buf) );
					SC6_Receive();
					SC6_Transmit();
                    sc6.state = SC6_State_Stop; 
					break;
                }
            }
 			if( (osKernelGetTickCount()- ticks) >=4000){
                log_w("SC6_ Get Data Timeout Failed %d,Retrying...",err_con);
                sc6.state=SC6_State_Error;
                break;
            }  
            // sc6.state = SC6_State_Stop;
            osDelay(1); 
            break;

 
        case SC6_State_Stop:
            // log_d("  SC6_ stop, aftetr deal, wait to change status....");
            osDelay(10); 
            continue;
 
        case SC6_State_Timeout:
            log_e( " SC6_ timeout ..... "  );
            sc6.state = SC6_State_Waiting ;
            // TODO 停止DMA
            if (SC6_uart_helper->rcv_mode == Uart_Trans_DMA)
            {
            HAL_UART_DMAStop( SC6_uart_helper->huart );
            }
            osDelay(5); 
            break;
        case SC6_State_Error:
            log_e( " SC6_ error ..... "  );
            sc6.state = SC6_State_Waiting ;
            // TODO 停止DMA
            if (SC6_uart_helper->rcv_mode == Uart_Trans_DMA)
            {
            HAL_UART_DMAStop( SC6_uart_helper->huart );
            }
            osDelay(5); 
            break;  
        }
        osDelay(20); 
    }
}


void SC6_Trans_GPIO(void) 
{
    // HAL_GPIO_WritePin(R_W_GPIO_Port,R_W_Pin, SET);
    // HAL_GPIO_WritePin(NULL,0, SET);
    HAL_GPIO_WritePin(SEL_232_485_GPIO_Port,SEL_232_485_Pin, SET);
    HAL_GPIO_WritePin(HDPLX_GPIO_Port,HDPLX_Pin, RESET);
    HAL_GPIO_WritePin(DE485_GPIO_Port, DE485_Pin, SET);
}

void SC6_Trans_Cplt_GPIO(void) 
{
    // HAL_GPIO_WritePin(R_W_GPIO_Port,R_W_Pin, RESET);
    // HAL_GPIO_WritePin(NULL,0, RESET);
    HAL_GPIO_WritePin(SEL_232_485_GPIO_Port,SEL_232_485_Pin, SET);
    HAL_GPIO_WritePin(HDPLX_GPIO_Port,HDPLX_Pin, SET);
    HAL_GPIO_WritePin(DE485_GPIO_Port, DE485_Pin, RESET);
} 

int SC6_Transmit()
{
    //  TODO 结合队列
    sc6.size_received =0;
    if( SC6_uart_helper->transferring == 0)
    {
        return UART_HELPER_Trans(SC6_uart_helper, SC6_uart_helper->trans_record->buf, SC6_uart_helper->trans_record->size );
    }
    return 0;
}

int SC6_Receive()
{
    return UART_HELPER_Start_Rcv(SC6_uart_helper, SC6_uart_helper->rcv_buf, SC6_uart_helper->rcv_size);
    // return UART_HELPER_Start_Rcv(SC6_uart_helper, SC6_RCV_BUF, 13);
    // return 0;
}

void SC6_Set_Timeout_ms(    uint64_t ms_ticks )
{
    sc6.timeout_ticks = ms_ticks;
}

int SC6_Validate(   )
{
    return CRC16_Check(sc6.result_buf ,sc6.size_received);
}


int SC6_CallBack( SC6_TypeDef *pPH, uint8_t *buf, uint16_t size )
{
    log_d( " SC6_CallBack  -- state %d  size %d" , sc6.state, size);
    uint16_t size_tmp;
    size_tmp =size;
    switch (sc6.state)
    {
        case SC6_State_Test_Data_Getting:
            if (size>0) 
            {
                sc6.state++;
            }
            break;
        case SC6_State_Check_Data:
            if (size == 0)  return 0;
            if ((size + sc6.size_received) >= sizeof(sc6.result_buf) )
            {
                size_tmp = sizeof(sc6.result_buf) - sc6.size_received;
            }
            memcpy( (uint32_t)(sc6.result_buf+sc6.size_received), SC6_uart_helper->rcv_buf, size_tmp );
            sc6.size_received = sc6.size_received+size_tmp;
	

            // if ( SC6_uart_helper->enable_idle_it == 0 )
            // {
            //     // Modbus 长度校验，拷贝数据？
            //     if( sc6.size_received == ( sc6.result_buf[2]+ 5 ) )
            //     {
            //         sc6.state++;
            //     }
            //     return 0;
            // }
            // if ( SC6_uart_helper->enable_idle_it == 1 )
            // {
            //     // 长度校验，拷贝数据？
            //     if( sc6.size_received == ( sc6.result_buf[2]+ 5 ) )
            //     {
            //         sc6.state++;
            //     }
            //     return 0;
            // }   
            break;  
        default:
            break;
    }
    return 0;
}

// CRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t *)dataBuffer, BUFFER_SIZE);

// void SC6_Set_Interface( SC6_TypeDef *ph,  UartInterface_TypeDef * interface  )
// {
//     UartHelper_Set_Interface( sc6.uarthelper,   interface );
// }
// void SC6_Set_Huart( SC6_TypeDef *ph,  UART_HandleTypeDef * huart  )
// {
//     sc6.uarthelper->huart = huart;
//     // UartHelper_Set_Huart( sc6.uarthelper,    huart  );
// }
// void SC6_Set_Interface_Type( SC6_TypeDef *ph,    Uart_Interface_Type_Typedef interface_type  )
// {
//     sc6.interface_type = interface_type;  
//     sc6.uarthelper->interface_type = interface_type; 
//     UartInterface_Setup_Interface_type( sc6.uarthelper->interface ,sc6.interface_type); 
// }