#include "sc6.h"
#include "elog.h"
#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "usart.h"

/******           Port             ***************/
#if 1
My_SC6_TypeDef mysc6 =
    {
        SC6_Init,
        SC6_Port,
        SC6_Set_State,
        // SEL_232_485_GPIO_Port,
        // HDPLX_GPIO_Port,
        // DE485_GPIO_Port,
        // SEL_232_485_Pin,
        // HDPLX_Pin,
        // DE485_Pin,
        NULL,
        NULL,
        NULL,
        0,
        0,
        0,
        Uart_Interface_Default, /* 接口类型 0: common, 1: 485 ,2:3160*/
        Uart_RSMODE_232,        /* mode_232_485 0 commome  1:485*/
        Uart_Trans_DMA,         /* trans_type0 :polling, 1: IT  2: DMA*/
        Uart_Trans_DMA,         /* rcv_type 0 :polling, 1: IT  2: DMA*/
        Uart_IDLE_IT_ENABLE,    /* idle_enable_disable 0 :不启用空闲 , 1: 启用空闲*/
       NULL, /* pointer huart*/
};

UART_HandleTypeDef *psc6Uart = &huart2;
#define SC6_Uart_IRQHandler USART2_IRQHandler

extern volatile uint8_t measure_flag;
SC6_TypeDef *sc6;

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

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

//  uint8_t SC6_Data_Buf[SC6_Rcv_Buf_Size*2]    = {0};

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};

// uint8_t SC6_sn_buf[15] = {0};
// uint8_t SC6_rcvbuf[2][SC6_Rcv_Buf_Size] = {0};

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

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

void SC6_Uart_IRQHandler(void)
{
    uint16_t count = 0;
    uint16_t data_length = 0;
    if (__HAL_UART_GET_FLAG(psc6Uart, UART_FLAG_TC) != RESET)
    {
        log_i("SC6_.... TC IT ...");
        // sc6->uarthelper ->status = Uart_Status_Send_Cplt ;
        // SC6_Set_UartHelper_Status( sc6, Uart_Status_Send_Cplt);
        SC6_Set_GPIO_For_TC_Cplt(sc6);

        sc6->uarthelper->huart->gState = HAL_UART_STATE_READY;
        // psc6Uart->gState = HAL_UART_STATE_READY;
        // UartHelper_Trans_Cplt_Callback(  sc6->uarthelper  );
        //  log_i("Send SC6_Uart_IRQHandler->  interface_type %d,  232-485  %d ,  sel: %d ,de485  %d  , duplx %d "
        //     ,sc6->uarthelper->interface->interface_type
        //     ,sc6->uarthelper->interface->mode_232_485
        //     ,HAL_GPIO_ReadPin(sc6->uarthelper->interface->sel_gpio,sc6->uarthelper->interface->sel_pin)
        //     ,HAL_GPIO_ReadPin(sc6->uarthelper->interface->de485_gpio,sc6->uarthelper->interface->de485_pin)
        //     ,HAL_GPIO_ReadPin(sc6->uarthelper->interface->dplx_gpio,sc6->uarthelper->interface->dplx_pin)
        //     );
        // sc6->status = Uart_Status_Send_Cplt;
        // huart3.gState = HAL_UART_STATE_READY;
        __HAL_UART_CLEAR_FLAG(sc6->uarthelper->huart, UART_FLAG_TC);
    }

    if (__HAL_UART_GET_FLAG(psc6Uart, UART_FLAG_IDLE) != RESET )
    {
        log_i("SC6_....  IDLE  IT ....  ");
        // TODO ...处理空闲 ，最后一位  datalength-1

        count = __HAL_DMA_GET_COUNTER(sc6->uarthelper->huart->hdmarx);
        data_length = 2* SC6_Result_Buf_Size - count;
        if (data_length > 0)
        {
            log_i("SC6_. IDLE..data_length  %d",   data_length);
            SC6_copy(sc6, data_length);
            // log_i("SC6_. IDLE..res  %02X %d %02X",  sc6->uarthelper ->receive_buf[0],  sc6->uarthelper ->receive_buf[2],  sc6->uarthelper ->receive_buf[data_length-1]);
        }
 
        __HAL_UART_CLEAR_IDLEFLAG(psc6Uart);
    }

    if (__HAL_UART_GET_FLAG(psc6Uart, UART_FLAG_ORE) != RESET)
    {
        log_i("SC6_....ORE");

        __HAL_UART_CLEAR_FLAG(psc6Uart, UART_FLAG_ORE);
    }
    if (__HAL_UART_GET_FLAG(psc6Uart, UART_FLAG_FE) != RESET)
    {
        log_i("SC6_....FE");

        __HAL_UART_CLEAR_FLAG(psc6Uart, UART_FLAG_FE);
    }
    if (__HAL_UART_GET_FLAG(psc6Uart, UART_FLAG_PE) != RESET)
    {
        log_i("SC6_....PE");

        __HAL_UART_CLEAR_FLAG(psc6Uart, UART_FLAG_PE);
    }
    HAL_UART_IRQHandler(psc6Uart);
}

int SC6_copy(SC6_TypeDef *sc6 ,uint16_t size)
{
    log_i( "*** SC6_  copy  state %d   size :%d    size_rcv  %d ", sc6->state,size,sc6->size_received );
    // log_i( "SC6_ idle copy  %02x %02x %02x %02x ", SC6_Rcv_Buf[0], SC6_Rcv_Buf[1], SC6_Rcv_Buf[11], SC6_Rcv_Buf[size-1]);
    if ( sc6->state == MODULE_SC6_STATE_CHECK_DATA  )
    {
    __disable_irq();
        memcpy(sc6->SC6_Data_Buf , sc6->uarthelper->receive_buf, size);
    __enable_irq();
        sc6->size_received = sc6->size_received + size;
            log_w("SC6_. copy after  %02X %02X  %02X  %02X %d    %d"
            ,  sc6->SC6_Data_Buf[0],  sc6->SC6_Data_Buf[12], sc6->SC6_Data_Buf[13],  sc6->SC6_Data_Buf[sc6->size_received-1]
            , size,sc6->size_received);
        return 0;
    }
    return 0;
}

void SC6_Set_State( MODULE_SC6_WORK_STATE state  )
{
    // log_i( "Set_State...sc6->state .%d ", sc6->state);
      sc6->state = state;
}

uint8_t SC6_Init()
{

    sc6 = (SC6_TypeDef *)malloc(sizeof(SC6_TypeDef));

    UartInterface_TypeDef *interface    = UartInterface_Init( );
    UartHelper_TypeDef *uarthelper      = UartHelper_Init();

    SC6_Set_Uarthelper( sc6,  uarthelper );
    SC6_Set_Interface( sc6,  interface );
    SC6_Set_Huart( sc6, psc6Uart );
 
    /* set_GPIO  UartInterface */
    UartInterface_Set_Sel_GPIO_Pin( sc6->uarthelper->interface, mysc6.sel_gpio, mysc6.sel_pin );
    UartInterface_Set_Dplx_GPIO_Pin( sc6->uarthelper->interface, mysc6.dplx_gpio, mysc6.dplx_pin );
    UartInterface_Set_DE485_GPIO_Pin( sc6->uarthelper->interface, mysc6.de_gpio, mysc6.de_pin );

    /* interface type */
    SC6_Set_Interface_Type( sc6, mysc6.interface_type );
    SC6_Set_RsMode_232_485 ( sc6, mysc6.mode_232_485 ); //  max3160 的232  485选择
    SC6_Set_Trans_Type( sc6, mysc6.trans_type ) ;
    SC6_Set_Rcv_Type ( sc6, mysc6.rcv_type ) ;
    SC6_Set_Idle_Enable (sc6, mysc6.idle_enable_disable ) ;
    // UartHelper_Setup_Interface_type( sc6 ,mysc6.interface_type); 
 
    //  check  
    if ( sc6->uarthelper->huart == psc6Uart ){
        log_i ( "sc6 set huart ok. trans_type -> %d  rcv_type -> %d  ( 0 :polling, 1: IT  2: DMA) ",sc6->trans_type ,sc6->rcv_type ) ;
        log_i( " interface->   %d  %d (0:default, 1:485, 2:3160) " ,sc6->uarthelper->interface_type  ,sc6->uarthelper->interface->interface_type );  
        log_i( "sc6 232_485 ->   %d  %d (0:232 ,1: 485)   " ,sc6->uarthelper->mode_232_485, sc6->uarthelper->interface->mode_232_485  );  
    }else{
        log_e ( "sc6 set huart failure "  ) ;
    }
        
    // sc6 send rcv buf 是动态的
    SC6_Set_Timeout( sc6, 1000 );
    // SC6_Set_Sendbuf( sc6,  SC6_SND_Buf, 8 );
    // SC6_Set_Rcvbuf(  sc6,  SC6_RCV_Buf, sizeof(SC6_RCV_Buf) );

    // set paras;
    sc6->timebase        = 0;
    // sc6->timeout_ms    = 1000;
    sc6->send_status     = Uart_Status_Ready;
    sc6->send_flag       = 0;
    sc6->command_seq     = 4;
    // sc6->mode            = 2;
    // sc6->data_begin_flag = 0;
    sc6->state           = MODULE_SC6_STATE_WAIT;
    return 0;
}

void SC6_Port()
{
    sc6Handle = osThreadNew(SC6_Task, (void*)(&sc6->state), &SC6_attributes);
}

void SC6_Task(void* argument)
{
    MODULE_SC6_WORK_STATE *state = argument;
    // FLAG   发送后进入 busy,  接收sn后就rcved_flag
    for (;;)
    {
        // log_i( " SC6_ state   %d   " , *state );
        switch (*state)
        {
        case MODULE_SC6_STATE_WAIT:
            break;
        case MODULE_SC6_STATE_START:
            log_i( " SC6_Task start   %d   " , *state );
                sc6->timebase = osKernelGetTickCount();
                sc6->flag |= SC6_FLAG_MASK_BUSY;
                sc6->uarthelper->huart->gState = HAL_UART_STATE_READY;
                HAL_UART_DMAStop(sc6->uarthelper->huart );
                memset(SC6_Rcv_Buf, 0, sizeof(SC6_Rcv_Buf));
                UartHelper_Set_rcv_buf(sc6->uarthelper , SC6_Rcv_Buf, sizeof(SC6_Rcv_Buf));
                sc6->size_received = 0;
                sc6->index_SC6_LPT = 0;
                UartHelper_Set_Trans_Buf( sc6->uarthelper , start_buf, sizeof(start_buf) );
                // SC6_Begin_Rcv( sc6, sc6->uarthelper->receive_buf, 2 * sc6->uarthelper->receive_buf_half_len );
                SC6_Begin_Rcv( sc6, SC6_Rcv_Buf, sizeof(SC6_Rcv_Buf) );
                int st =SC6_Transmit(sc6, sc6->uarthelper->trans_buf, sc6->uarthelper ->trans_size);
                log_w(" st :%d   %d" ,st , sc6->uarthelper->huart->gState),
                *state=MODULE_SC6_STATE_CHECK_DATA; 
            break; 
 
        case MODULE_SC6_STATE_CHECK_DATA:
            log_i( " SC6_Task check   %d   rcvsize  %d sc6->index_SC6_LPT  %d" , *state ,sc6->size_received,sc6->index_SC6_LPT);
            log_i( " SC6_Task    %s   " , sc6->SC6_Data_Buf );
            // find  SC6_LPT 
            if ( sc6->index_SC6_LPT==0 && sc6->size_received > 2*SC6_Rcv_Buf_Size +SC6_RESUMED_Buf_Size) 
            {
                sc6->error++;
                if( sc6->error > 2)
                {
                    HAL_UART_DMAStop(sc6->uarthelper ->huart );
                    *state=MODULE_SC6_STATE_ERROR;;
                    sc6->size_received = 0;
                    sc6->index_SC6_LPT =0;
                    sc6->error = 0;   
                    break;                     
                }
                // 重新测量
                log_w( " SC6_ Get Data  Error %d,  Retrying...",sc6->error   );
                HAL_UART_DMAStop(sc6->uarthelper ->huart );
            }
            sc6->index_SC6_LPT = 0;
            // if ( sc6->index_SC6_LPT==0 && sc6->size_received <= 2*SC6_Rcv_Buf_Size +SC6_RESUMED_Buf_Size && sc6->size_received!=0) 
            if ( sc6->index_SC6_LPT==0   && sc6->size_received!=0) 
            {

                for (size_t i = 0; i < sc6->size_received; i++)
                {
                    if (sc6->SC6_Data_Buf[i]  == data_start_tag[0] ) 
                    {
                        log_i( " ....i   %d   %02X   %02X", i ,data_start_tag[0], sc6->SC6_Data_Buf[i] );
                        if ( sc6->SC6_Data_Buf[i+1]  == data_start_tag[1] &&  sc6->SC6_Data_Buf[i+2]  == data_start_tag[2]
                            &&  sc6->SC6_Data_Buf[i+3]  == data_start_tag[3] &&  sc6->SC6_Data_Buf[i+4]  == data_start_tag[4]
                            &&  sc6->SC6_Data_Buf[i+5]  == data_start_tag[5] &&  sc6->SC6_Data_Buf[i+6]  == data_start_tag[6])
                        {
                            sc6->index_SC6_LPT = i;
                            break;
                        }

                    }
                }
            }

            if ( sc6->index_SC6_LPT!=0 ) 
            {
                // log_w( "  SC6_LPT was found  %d  %d  %d  " ,sc6->size_received,sc6->index_SC6_LPT,SC6_Rcv_Buf_Size );
                // log_w( "  SC6_LPT  %02X  %02X %02X %02X" 
                //         ,sc6->SC6_Data_Buf[0] ,sc6->SC6_Data_Buf[12], sc6->SC6_Data_Buf[13],sc6->SC6_Data_Buf[309]);
                // log_w( "  SC6_LPT  %02X  %02X %02X %02X" 
                //         ,sc6->SC6_Data_Buf[306] ,sc6->SC6_Data_Buf[307], sc6->SC6_Data_Buf[308],sc6->SC6_Data_Buf[309]);
                // TODO  拷贝后数据 。。。
                if (  (sc6->size_received - sc6->index_SC6_LPT >= SC6_Result_Buf_Size) 
                        && sc6->SC6_Data_Buf[sc6->index_SC6_LPT+SC6_Result_Buf_Size-1] == data_end_tag[1] )
                {
                    log_w("SC6_ Get Data OK..." );
                    HAL_UART_DMAStop(sc6->uarthelper ->huart );
                    memset(SC6_Rcv_Buf, 0, sizeof(SC6_Rcv_Buf));
                    //  result  sn 
                    memcpy( sc6->SC6_Result_Buf, sc6->SC6_Data_Buf[sc6->index_SC6_LPT], SC6_Result_Buf_Size);
                    memcpy( sc6->sn_buf, sc6->SC6_Data_Buf[sc6->index_SC6_LPT+4], 4);
                    sc6->size_received = 0;
                    sc6->index_SC6_LPT =0;
                    sc6->error = 0;
                    UartHelper_Set_Trans_Buf( sc6->uarthelper , stop_buf, sizeof(stop_buf) );
                    SC6_Transmit(sc6, sc6->uarthelper->trans_buf, sc6->uarthelper ->trans_size);
                    *state = MODULE_SC6_STATE_OK; 
                }
            }
 
 
            if( (osKernelGetTickCount()- sc6->timebase) >=4000){
                log_w("SC6_ Get Data Timeout Failed %d,Retrying...",sc6->error);
                *state=MODULE_SC6_STATE_ERROR;
                break;
            }            
            break;
        case MODULE_SC6_STATE_OK:
        //     log_i( " SC6_Task ok   %d   " , *state );
                HAL_UART_DMAStop(sc6->uarthelper ->huart );
                memset(SC6_Rcv_Buf, 0, sizeof(SC6_Rcv_Buf));
                sc6->size_received = 0;
                UartHelper_Set_Trans_Buf(sc6->uarthelper , stop_buf, sizeof(stop_buf));
            break;
        case MODULE_SC6_STATE_ERROR:
            log_e( " SC6_Task   error    "  );
                SC6_clean_flag( sc6 ,SC6_FLAG_MASK_BUSY);
                HAL_UART_DMAStop(sc6->uarthelper ->huart );
                memset(SC6_Rcv_Buf, 0, sizeof(SC6_Rcv_Buf));
                sc6->size_received = 0;
            *state=MODULE_SC6_STATE_WAIT;
            break;   
        case MODULE_SC6_STATE_STOP:
            break;
        default:
            SC6_clean_flag( sc6 ,SC6_FLAG_MASK_BUSY);
            *state=MODULE_SC6_STATE_WAIT;
            break;
        }

        osDelay(300);
    }
}

/******************         接口           *******************/
void SC6_Set_Uarthelper(SC6_TypeDef *sc6, UartHelper_TypeDef *uarthelper)
{
    sc6->uarthelper  = uarthelper;
}

void SC6_Set_Interface(SC6_TypeDef *sc6, UartInterface_TypeDef *interface)
{
    sc6->uarthelper->interface = interface;
}
void SC6_Set_Huart( SC6_TypeDef * sc6,  UART_HandleTypeDef * huart  )
{
    sc6->uarthelper->huart = huart;
}

void SC6_Set_Interface_Type( SC6_TypeDef *sc6,    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); 
}

void SC6_Set_RsMode_232_485(SC6_TypeDef *sc6, Uart_RS_Mode_TypeDef rs_232_485)
{
    //  TODO理清逻辑
    sc6->mode_232_485 = rs_232_485; 
    sc6->uarthelper->mode_232_485 = rs_232_485; 
       UartInterface_Setup_Mode_232_485( sc6->uarthelper->interface, rs_232_485 );
}
void SC6_Set_Trans_Type( SC6_TypeDef *sc6,  Uart_Transmode_TypeDef trans_type  )
{
    sc6->trans_type = trans_type; 
}
void SC6_Set_Rcv_Type( SC6_TypeDef *sc6,  Uart_Transmode_TypeDef rcv_type  )
{
    sc6->rcv_type = rcv_type; 
    
}
void SC6_Set_Idle_Enable( SC6_TypeDef *sc6,  Uart_IDLE_Enable_TypeDef idle_enable_disable  )
{
    sc6->idle_enable_disable = idle_enable_disable; 

}
void SC6_Set_TransMode( SC6_TypeDef *sc6,  Uart_Transmode_TypeDef trans_mode  )
{
    sc6->trans_type = trans_mode; 
    sc6->rcv_type = trans_mode; 

}
 
void SC6_Set_Timeout( SC6_TypeDef *sc6,    uint16_t timeout_ms )
{
    sc6->timeout_ms = timeout_ms; 
    sc6->timeout_enable = 1;

}
void SC6_Set_Sendbuf( SC6_TypeDef *sc6,  uint8_t * buf, uint16_t size )
{
 
    sc6->send_buf = buf;
    sc6->size_send = size;
}
void SC6_Set_Rcvbuf( SC6_TypeDef *sc6,  uint8_t * buf, uint16_t size )
{
    sc6->rcv_buf = buf;
    sc6->size_rcv = size;

}

int SC6_Get_Timeout(SC6_TypeDef *sc6)
{
    if ((osKernelGetTickCount() - sc6->timebase) > sc6->timeout_ms)
        return 1;
    return 0;
}

int SC6_Transmit(SC6_TypeDef *sc6, uint8_t *buf, uint16_t size)
{

    if (sc6->timeout_enable == 1)
    {
        sc6->timebase = osKernelGetTickCount();
    }
    return UartHelper_Transmit(sc6->uarthelper , buf, size);
}

int SC6_Begin_Rcv(SC6_TypeDef *sc6, uint8_t *buf, uint16_t size)
{
    return UartHelper_Begin_Rcv(sc6->uarthelper , buf, size);
}

Uart_Status_TypeDef SC6_Get_UartHelper_Status(SC6_TypeDef *sc6)
{
    return sc6->uarthelper ->status;
}
int SC6_Set_UartHelper_Status(SC6_TypeDef *sc6, Uart_Status_TypeDef status)
{
    sc6->uarthelper ->status = status;
    return 0;
}

int SC6_Init_Ok()
{
    // uint64_t timebase = osKernelGetTickCount( );
    // while (1)
    // {
    //     log_i(  " flag :  %d  %d ",sc6->flag , (sc6->flag & SC6_FLAG_MASK_RECVED_WL));
    //     if (count > 50)  break;
    //     if (  sc6->flag & SC6_FLAG_MASK_RECVED_WL != 0   ) return 0;
    //     osDelay ( 20 );
    //     count++;
    // }
    // return -1;
    
}

int SC6_Get_Data_OK(SC6_TypeDef *sc6)
{
    return sc6->data_ok;
}
void SC6_Set_Send_Flag(SC6_TypeDef *sc6)
{
    // vPortEnterCritical();
    sc6->send_flag = 1;
    sc6->command_seq = 0;
    sc6->data_ok = 0;
    // vPortExitCritical( );
}


void SC6_callback(SC6_TypeDef *sc6, uint8_t *buf, uint16_t size)
{
}

void SC6_Set_GPIO_For_TC_Cplt(SC6_TypeDef *sc6)
{
    // sc6->status = 2;
    UartHelper_Set_GPIO_For_Trans_Cplt(sc6->uarthelper );
}


void SC6_clean_flag(SC6_TypeDef *sc6,uint8_t mask)
{
    sc6->flag&=~mask;
}
 
uint8_t SC6_get_flag(SC6_TypeDef *sc6,uint8_t mask)
{
    return sc6->flag&mask;
}

uint16_t SC6_get_serial_number(SC6_TypeDef * sc6 )
{
    // if((sc6->flag&SC6_FLAG_MASK_RECVED_SN)==0){
    //     return 0xffff;
    // }
    // return sc6->sn;
}


void SC6_Error(SC6_TypeDef *sc6, char *str)
{
    log_e(str);
    while (1)
        ;
}


#endif
