#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); // }