#include "pH.h" #include "elog.h" #include "FreeRTOS.h" #include "cmsis_os.h" #include "stm32f4xx.h" #include "usart.h" #include "main.h" /****** Port ***************/ #if 1 #define PH_Uart_IRQHandler USART3_IRQHandler // #define PH_Uart_IRQHandler USART4_IRQHandler UART_HandleTypeDef *pPHUart = &huart3; PH_TypeDef *ph ; My_PH_TypeDef my_pH = { PH_Init, PH_Port, PH_Test, PH_Start, PH_Stop, SEL_232_485_GPIO_Port, HDPLX_GPIO_Port, DE485_GPIO_Port, SEL_232_485_Pin, HDPLX_Pin, DE485_Pin, Uart_Interface_Max3160, /* 接口类型 0: common, 1: 485 ,2:3160*/ Uart_RSMODE_485, /* 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: 启用空闲*/ 0, //ph 0, // temprature NULL, /* pointer huart*/ }; extern volatile uint8_t measure_flag ; uint8_t PH_SND_Buf[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B }; uint8_t PH_RCV_Buf[PH_Rcv_Buf_Size*2] = { 0 }; osThreadId_t phHandle; const osThreadAttr_t PH_attributes = { .name = "ph", .stack_size = 1024, .priority = (osPriority_t) osPriorityBelowNormal, }; void PH_Uart_IRQHandler(void) { if (__HAL_UART_GET_FLAG( ph->uarthelper->huart, UART_FLAG_TC) != RESET) { // log_i("ph....huart3 TC callback ..."); PH_Send_Cplt_Callback( ph ); // ph->state = PH_Status_Send_Cplt; ph->uarthelper->huart->gState = HAL_UART_STATE_READY; __HAL_UART_CLEAR_FLAG( ph->uarthelper->huart, UART_FLAG_TC ); } if (__HAL_UART_GET_FLAG( ph->uarthelper->huart, UART_FLAG_IDLE ) != RESET) { uint16_t count = __HAL_DMA_GET_COUNTER( ph->uarthelper->huart->hdmarx ); log_i("....huart3 IDLE.... %d site3 == 4 %02X ", count, PH_RCV_Buf[2] ); uint16_t data_length = 2*PH_Rcv_Buf_Size - count; if (count == PH_Rcv_Buf_Size) { // HAL_UART_DMAStop( ph->uarthelper->huart ); ph->state = PH_Status_RCV_OK; } if (count < PH_Rcv_Buf_Size) { // HAL_UART_DMAStop( ph->uarthelper->huart ); ph->state = PH_Status_Error; } __HAL_UART_CLEAR_IDLEFLAG( ph->uarthelper->huart ); } HAL_UART_IRQHandler( ph->uarthelper->huart ); } int PH_Init( ) { ph = (PH_TypeDef *)malloc(sizeof(PH_TypeDef)); UartInterface_TypeDef *interface = UartInterface_Init( ); UartHelper_TypeDef *uarthelper = UartHelper_Init(); PH_Set_Uarthelper( ph, uarthelper ); PH_Set_Interface( ph, interface ); PH_Set_Huart( ph, pPHUart ); /* set_GPIO UartInterface */ UartInterface_Set_Sel_GPIO_Pin( ph->uarthelper->interface, my_pH.sel_gpio, my_pH.sel_pin ); UartInterface_Set_Dplx_GPIO_Pin( ph->uarthelper->interface, my_pH.dplx_gpio, my_pH.dplx_pin ); UartInterface_Set_DE485_GPIO_Pin( ph->uarthelper->interface, my_pH.de_gpio, my_pH.de_pin ); /* interface type */ PH_Set_Interface_Type( ph, my_pH.interface_type ); PH_Set_RsMode_232_485 ( ph, my_pH.mode_232_485 ); // max3160 的232 485选择 PH_Set_Trans_Type( ph, my_pH.trans_type ) ; PH_Set_Rcv_Type ( ph, my_pH.rcv_type ) ; PH_Set_Idle_Enable (ph, my_pH.idle_enable_disable ) ; // UartHelper_Setup_Interface_type( ph ,my_pH.interface_type); // check if ( ph->uarthelper->huart == pPHUart ){ log_i ( "ph set huart ok. trans_type -> %d rcv_type -> %d ( 0 :polling, 1: IT 2: DMA) ",ph->trans_type ,ph->rcv_type ) ; log_i( " interface-> %d %d (0:default, 1:485, 2:3160) " ,ph->uarthelper->interface_type ,ph->uarthelper->interface->interface_type ); log_i( "ph 232_485 -> %d %d (0:232 ,1: 485) " ,ph->uarthelper->mode_232_485, ph->uarthelper->interface->mode_232_485 ); }else{ log_e ( "ph set huart failure " ) ; } PH_Set_Timeout( ph, 500 ); PH_Set_Sendbuf( ph, PH_SND_Buf, 8 ); PH_Set_Rcvbuf( ph, PH_RCV_Buf, sizeof(PH_RCV_Buf) ); // set paras; ph->timebase = 0; // ph->timeout_ms = 1000; ph->send_status = Uart_Status_Ready; ph->send_flag = 0; ph->command_seq = 4; ph->mode = 2; ph->data_begin_flag = 0; ph->state = PH_Status_Waiting; return 0; } void PH_Port( ) { phHandle = osThreadNew( PH_Task, NULL, &PH_attributes ); } void PH_Task( ) { // log_i( " ph tran mode : %d ", ph->->trans_mode ); memset( PH_RCV_Buf, 0, 2*PH_Rcv_Buf_Size ); /* ph*3 ph *2 否则内存泄漏 */ uint64_t time_ticks; // log_i( " ph tran mode : %d %d " , ph->trans_mode , ph->mode ); for ( ; ; ) { switch (ph->state) { case PH_Status_Waiting: osDelay(20); break; case PH_Status_Ready: log_i(" pH send .................. "); my_pH.ph_val = 0; my_pH.temp_val = 0; memset( ph->rcv_buf, 0, 2*PH_Rcv_Buf_Size ); PH_Begin_Rcv( ph, ph->rcv_buf, ph->size_rcv ); // HAL_UARTEx_ReceiveToIdle_DMA( &huart3, PH_RCV_Buf, PH_Rcv_Buf_Size ); // HAL_UART_Receive_DMA ( &huart3, ph->rcv_buf, ph->size_rcv ); // __HAL_UART_ENABLE_IT( &huart3, UART_IT_IDLE ); ph->timebase = osKernelGetTickCount( ); // max3160_485_send_mode(); ph->state = PH_Status_Sending ; PH_Send( ph, ph->send_buf, ph->size_send ); break; case PH_Status_Sending: time_ticks = osKernelGetTickCount() ; // log_i( " time_ticks :%d %d" , time_ticks, ph->timebase); if ( ( time_ticks - ph->timebase ) > ph->timeout_ms) { ph->state = PH_Status_Timeout ; } osDelay(5); break; case PH_Status_Send_Cplt: time_ticks = osKernelGetTickCount() ; log_i( "PH_Status_Send_Cplt ..... " ); if ( (time_ticks - ph->timebase ) > ph->timeout_ms) { ph->state = PH_Status_Timeout ; } osDelay(5); break; case PH_Status_RCV_OK: if ( my_pH.ph_val == 0 & my_pH.temp_val==0 ) { my_pH.ph_val = ph->rcv_buf[3]*256 + ph->rcv_buf[4]; my_pH.temp_val = ph->rcv_buf[5]*256 + ph->rcv_buf[6]; log_i( "PH_Status_RCV_OK ..... ph %d temp %d " , my_pH.ph_val, my_pH.temp_val); ph->state = PH_Status_DATA_OK ; } // TODO 停止DMA HAL_UART_DMAStop( ph->uarthelper->huart ); osDelay(20); break; case PH_Status_DATA_OK: osDelay(20); break; case PH_Status_Timeout: log_e( " pH timeout ..... " ); ph->state = PH_Status_Waiting ; HAL_UART_DMAStop( ph->uarthelper->huart ); osDelay(5); break; case PH_Status_Error: log_e( " pH error ..... " ); ph->state = PH_Status_Waiting ; HAL_UART_DMAStop( ph->uarthelper->huart ); osDelay(5); break; default: break; } osDelay(20); } } int PH_Test( ) { HAL_UART_Transmit_IT( &huart3, ph->send_buf, ph->size_send ); osDelay(20); if ( HAL_UART_Receive ( &huart3, ph->rcv_buf, ph->size_rcv ,0xFF) != HAL_OK ){ return -1; } return 0; } void PH_Start( ) { // log_e( " pH PH_Start ..... " ); ph->state = PH_Status_Ready; } void PH_Stop( ) { ph->state = PH_Status_Waiting; } /****************** 接口 *******************/ void PH_Set_Uarthelper( PH_TypeDef *ph, UartHelper_TypeDef * uarthelper) { ph->uarthelper = uarthelper; } void PH_Set_Interface( PH_TypeDef *ph, UartInterface_TypeDef * interface ) { UartHelper_Set_Interface( ph->uarthelper, interface ); } void PH_Set_Huart( PH_TypeDef *ph, UART_HandleTypeDef * huart ) { ph->uarthelper->huart = huart; // UartHelper_Set_Huart( ph->uarthelper, huart ); } void PH_Set_Interface_Type( PH_TypeDef *ph, Uart_Interface_Type_Typedef interface_type ) { ph->interface_type = interface_type; ph->uarthelper->interface_type = interface_type; UartInterface_Setup_Interface_type( ph->uarthelper->interface ,ph->interface_type); } void PH_Set_RsMode_232_485( PH_TypeDef *ph, Uart_RS_Mode_TypeDef rs_232_485 ) { ph->mode_232_485 = rs_232_485; ph->uarthelper->mode_232_485 = rs_232_485; UartInterface_Setup_Mode_232_485( ph->uarthelper->interface, my_pH.mode_232_485 ); } void PH_Set_Trans_Type( PH_TypeDef *ph, Uart_Transmode_TypeDef trans_type ) { ph->trans_type = trans_type; } void PH_Set_Rcv_Type( PH_TypeDef *ph, Uart_Transmode_TypeDef rcv_type ) { ph->rcv_type = rcv_type; } void PH_Set_Idle_Enable( PH_TypeDef *ph, Uart_IDLE_Enable_TypeDef idle_enable_disable ) { ph->idle_enable_disable = idle_enable_disable; } void PH_Set_TransMode( PH_TypeDef *ph, Uart_Transmode_TypeDef trans_mode ) { ph->trans_type = trans_mode; ph->rcv_type = trans_mode; } void PH_Set_Timeout( PH_TypeDef *ph, uint16_t timeout_ms) { ph->timeout_ms = timeout_ms; } void PH_Set_Sendbuf( PH_TypeDef *ph, uint8_t * buf, uint16_t size) { ph->send_buf = buf; ph->size_send = size; // log_i( " size_send %d", sensor->size_send); } void PH_Set_Rcvbuf( PH_TypeDef *ph, uint8_t * buf, uint16_t size) { ph->rcv_buf = buf; ph->size_rcv = size; // log_i( " size_rcv %d", demo->size_rcv); } int PH_Send( PH_TypeDef *ph, uint8_t * buf, uint16_t size ) { // log_i( "SensorSend size_ %d", demo->size_send ); ph->timebase = HAL_GetTick(); UartInterface_Set_GPIO_For_Transmit( ph->uarthelper->interface ); // UartHelper_Send_TxPrepare_Callback( ph->uarthelper ); // ph->send_status = 1; if ( ph->trans_type == 0 ) return HAL_UART_Transmit( ph->uarthelper->huart, buf, size ,0XFF); if ( ph->trans_type == 1 ) return HAL_UART_Transmit_IT( ph->uarthelper->huart, buf, size ); if ( ph->trans_type == 2 ) return HAL_UART_Transmit_DMA( ph->uarthelper->huart, buf, size ); return -1; // ph->send_flag = 0; } void PH_Begin_Rcv( PH_TypeDef *ph, uint8_t * buf, uint16_t size) { /* 是否开启空闲中断*/ if ( ph->idle_enable_disable == 1 ) { // log_i(" ** idle enable..."); __HAL_UART_ENABLE_IT( ph->uarthelper->huart, UART_IT_IDLE ); } if ( ph->trans_type == 0 ) { // TODO 发生错误怎么处理 HAL_UART_Receive( ph->uarthelper->huart, buf, size ,0X0FFF); } if ( ph->trans_type == 1 ) { HAL_UART_Receive_IT( ph->uarthelper->huart, buf, size); } if ( ph->trans_type == 2 ) { HAL_UART_Receive_DMA( ph->uarthelper->huart, buf, size); } } void PH_Send_Cplt_Callback( PH_TypeDef *ph ) { // ph->timebase = HAL_GetTick(); ph->status = Uart_Status_Send_Cplt; if ( ph->interface_type != 0 ) { UartInterface_Set_GPIO_For_Trans_Cplt( ph->uarthelper->interface ); // UartHelper_Set_GPIO_For_Trans_Cplt( ph->uarthelper ); } } void PH_Rcv_Idle_Callback( PH_TypeDef *ph ) { /* 搬运 数据到 kfifo*/ ph->status = 0; ph->send_flag = 0; } void PH_Rcv_Cplt_Callback( PH_TypeDef *ph ) { /* 搬运 数据到 kfifo*/ log_i( " PH_Rcv_Cplt_Callback 1 .... " ); ph->rcv_ok = 1 ; // ph->status = 0; // ph->send_flag = 1; // if ( ph->mode < 2 ) // ph->command_seq++; } int PH_Get_Data_OK( PH_TypeDef *ph ) { return ph->rcv_ok; } void PH_Set_Send_Flag( PH_TypeDef *ph ) { // vPortEnterCritical(); ph->send_flag = 1; ph->command_seq = 0; ph->data_ok = 0; // vPortExitCritical( ); } #endif // UartHelper_Set_232 485 UartInterface // UartInterface_Setup_Mode_232_485( ph->uarthelper->interface, my_pH.mode_232_485 ); // if (ph->interface_type == 0) // UartInterface_Set_232( ph->uarthelper->interface); // if (ph->interface_type == 1) // UartInterface_Set_485( ph->uarthelper->interface); // if (ph->interface_type ==2 && my_pH.mode_232_485 ==Uart_RSMODE_232) // UartInterface_Set_232( ph->uarthelper->interface); // if (ph->interface_type ==2 && my_pH.mode_232_485 ==Uart_RSMODE_485) // UartInterface_Set_485( ph->uarthelper->interface); // log_i( " interface-> %d %d (0:default, 1:485, 2:3160) " ,ph->uarthelper->interface_type ,ph->uarthelper->interface->interface_type ); // log_i( "ph 232_485 -> %d %d (0:232 ,1: 485) " ,ph->uarthelper->mode_232_485, ph->uarthelper->interface->mode_232_485 );