#include "b6x.h" #include "drvs.h" #include "dbg.h" #include "rbuf.h" #include "app_uart.h" #include "app_speed_governor.h" #include "app_control_out.h" #include "app_ws2812.h" void app_uart_Init(uint8_t port, uint32_t baudrate, uint8_t io_tx, uint8_t io_rx) { uart_init(port, io_tx, io_rx); uart_conf(port, BRR_DIV(baudrate, 16M), LCR_BITS(8, 1, none)); // 使能FIFO 接收8字节时触发、使能超过20字节触发超时中断 uart_fctl(port, FCR_FIFOEN_BIT | FCR_RXTL_1BYTE, 0, UART_IR_RXRD_BIT); NVIC_EnableIRQ(port==UART1_PORT?UART1_IRQn:UART2_IRQn); } //CRC-8/MAXIM:x8+X5+X4+1 uint8_t crc8_checkout(uint8_t *buff, uint8_t length) { uint8_t i; uint8_t crc = 0; //initial value while (length--) { crc ^= *buff++; //crc ^= *buff; buff++; for(i = 0; i < 8; i++) { if(crc & 1) crc = (crc >> 1) ^ 0x8C; //0x8C = reverse 0x31 else crc >>= 1; } } return crc; } radar_daraframe_t radar_daraframe; uart_daraframe_t uart1_daraframe; volatile uint8_t uart1_state =0; volatile uint8_t uart1_data_cnt =0; extern GRB_Data_t WS2812_GRBs; bool uart2_Back_car=0; static void app_uart1_hande(void){ uint8_t ret_data[MAX_LEN]={0,0}; uint8_t length; switch(uart1_daraframe.cmd_id){ case 0x01://电门锁 if(1 ==uart1_daraframe.length){//电门锁状态设置/0:锁车状态/1:开锁状态 ret_data[0] =app_set_Door_lock_status(uart1_daraframe.data[0]); length = 1; app_uart_Sendcmd(UART1_PORT, uart1_daraframe.cmd_id, uart1_daraframe.reg_addr, ret_data, length); } break; case 0x02://油门控制 if(3 ==uart1_daraframe.length){ if(1==Get_Status(IN_GPS)){ Set_Status(OUT_Door_lock,0);//GPS超出范围,直接锁车 } if(app_get_Door_lock_status()){//开锁时 if(0 > *(int8_t *)(&uart1_daraframe.data[0])){//倒车 if(1 == uart2_Back_car){ // NVIC_EnableIRQ(UART2_IRQn); // app_uart_Init(UART2_PORT,9600,PA10,PA04);//倒车雷达 } uart2_Back_car =0; }else {//前进 if(0 == uart2_Back_car){ // NVIC_DisableIRQ(UART2_IRQn); // app_uart_Init(UART2_PORT,9600,PA10,PA09);//磁刹控制器 } uart2_Back_car =1; } app_set_speed(*(int8_t *)(&uart1_daraframe.data[0])); ret_data[0] = uart1_daraframe.data[0];//当前油门状态 倒车:-100~0 / 前进:0~100 ret_data[1] = app_set_brake_status(uart1_daraframe.data[1]);//当前刹车状态 if(1==Get_Status(IN_EXTI0_Custom0)){ ret_data[2] = app_set_gears_status(0);//进入管理员模式 }else { ret_data[2] = app_set_gears_status(uart1_daraframe.data[2]);//当前速度档位 } ret_data[3] = radar_daraframe.Left_data; ret_data[4] = radar_daraframe.Right_data; length = 5; app_uart_Sendcmd(UART1_PORT, uart1_daraframe.cmd_id, uart1_daraframe.reg_addr, ret_data, length); }else{ ret_data[0] = app_get_Door_lock_status(); length = 1; app_uart_Sendcmd(UART1_PORT, uart1_daraframe.cmd_id, uart1_daraframe.reg_addr, ret_data, length); } } break; case 0x03://推车模式 if(1 ==uart1_daraframe.length){//推车模式设置/0:退出推车状态/1:推车状态 ret_data[0] =app_set_Push_status(uart1_daraframe.data[0]); length = 1; app_uart_Sendcmd(UART1_PORT, uart1_daraframe.cmd_id, uart1_daraframe.reg_addr, ret_data, length); } break; case 0x04://GRB WS2812_GRBs.len =uart1_daraframe.length; for(length=0;length < WS2812_GRBs.len;length++){//G3,R3,B2 WS2812_GRBs.GRBs[length] = ((uint32_t)(uart1_daraframe.data[length] & 0xE0)<<16) | ((uint32_t)(uart1_daraframe.data[length] & 0x1C)<<11) | ((uint32_t)(uart1_daraframe.data[length] & 0x03)<<6); } // WS2812_GRBs.len =uart1_daraframe.length / 3; // for(length=0;length < WS2812_GRBs.len;length++){ // WS2812_GRBs.GRBs[length] = ((uint32_t)uart1_daraframe.data[3*length + 0]<<16) | ((uint32_t)uart1_daraframe.data[3*length +1]<<8) | ((uint32_t)uart1_daraframe.data[3*length +2]); // } // app_uart_Sendcmd(UART2_PORT, uart1_daraframe.cmd_id, uart1_daraframe.reg_addr, uart1_daraframe.data, length); // app_uart_Sendcmd(UART1_PORT, uart1_daraframe.cmd_id, uart1_daraframe.reg_addr, uart1_daraframe.data, length); break; default : break; /* 其他功能.... */ } uart1_state =0;//数据处理完要清零,准备接收下一帧数据 } static void uart1_Receive(uint8_t data) { uint8_t *frame = (uint8_t *)&uart1_daraframe; switch(uart1_state){ case 0://header if ((data == (uint8_t)(FRAME_HEADER >> 8)) && (uart1_daraframe.header == 0x0)) { uart1_daraframe.header = (FRAME_HEADER >> 8); } else if ((data == (uint8_t)(FRAME_HEADER & 0x00FF)) && (uart1_daraframe.header == (uint8_t)(FRAME_HEADER >> 8))) { uart1_daraframe.header = ((uint16_t)((FRAME_HEADER << 8)|(FRAME_HEADER >> 8)));//0xA100; uart1_daraframe.length = 0; uart1_state = 1;//to cmd id //debug("header"); } break; case 1://cmd_id //debug("rxcmd:%x", data); uart1_daraframe.cmd_id = data; uart1_state = 2;//to device addr break; case 2://reg addr //debug("reg_addr"); uart1_daraframe.reg_addr = data; uart1_state = 3;//to data length break; case 3://data length //debug("length"); uart1_daraframe.length = (data < MAX_LEN) ? data : MAX_LEN; if (uart1_daraframe.length == 0) { uart1_state = 5;//to crc } else { uart1_state = 4;//to data uart1_data_cnt = 0; } break; case 4://data //debug("data"); if (uart1_data_cnt < uart1_daraframe.length) { uart1_daraframe.data[uart1_data_cnt++] = data; } if (uart1_data_cnt == uart1_daraframe.length) { uart1_data_cnt = 0; uart1_state = 5;//to crc } break; case 5://CRC8 uart1_daraframe.crc = crc8_checkout(frame, 5 + uart1_daraframe.length); #if DISABLE_CRC8 uart1_daraframe.crc = data; #endif //计算并验证crc8 if (uart1_daraframe.crc == data) { uart1_state = 6;//to ack //debug("crc correct cmd:%x", uart1_daraframe.cmd_id); } else { uart1_state = 0;//to haeder uart1_daraframe.header = 0; //debug("crc error cmd:%x-%x", uart1_daraframe.cmd_id, uart1_daraframe.crc); } break; } // uart_putc(UART1_PORT,data);//debug // uart_putc(UART1_PORT,'0'+uart1_state); if(uart1_state == 6){ uart1_daraframe.header = 0; uart1_state = 7;//数据处理完,需要将状态位归零,才会接收下一帧数据,即:uart1_state =0时。 app_uart1_hande(); uart1_state =0; /* rx handler codes.... */ } } void UART1_IRQHandler(void) { uint32_t state = UART1->IFM.Word; // UART1->RIF.Word; if (state & 0x01) //(BIT_RXRD) { UART1->IDR.RXRD = 1; // Disable RXRD Interrupt uart1_Receive(UART1->RBR); UART1->ICR.RXRD = 1; // Clear RXRD Interrupt Flag UART1->IER.RXRD = 1; // Enable RXRD Interrupt } } /* ***************************************UART2***************************************************** */ uint8_t uart2_state =0; static void uart2_Receive(uint8_t data) { switch(uart2_state){ case 0://header if (data == 0x0C || data == 0x0D) { radar_daraframe.header = data; uart2_state = 1;//to data //debug("header"); } break; case 1://data //debug("data:%x", data); if(0x0c == radar_daraframe.header){ radar_daraframe.Left_data = data; }else if(0x0d == radar_daraframe.header){ radar_daraframe.Right_data = data; } uart2_state = 2; break; } // uart_putc(UART2_PORT,data); // uart_putc(UART2_PORT,'0'+uart2_state); if(uart2_state == 2){ radar_daraframe.header = 0; app_updata_radar(); uart2_state = 0; /* rx handler codes.... */ } } void UART2_IRQHandler(void) { uint32_t state = UART2->IFM.Word; // UART2->RIF.Word; if (state & 0x01) //(BIT_RXRD) { UART2->IDR.RXRD = 1; // Disable RXRD Interrupt uart2_Receive(UART2->RBR); UART2->ICR.RXRD = 1; // Clear RXRD Interrupt Flag UART2->IER.RXRD = 1; // Enable RXRD Interrupt } } //发送命令 void app_uart_Sendcmd(uint8_t port, volatile uint8_t cmd_id ,volatile uint8_t reg_addr ,volatile uint8_t *data, volatile uint8_t length) { uart_daraframe_t frame; uint8_t *cmd_data =(uint8_t *)&frame; uint8_t i; frame.header = ((uint16_t)((FRAME_HEADER << 8)|(FRAME_HEADER >> 8)));//0xA100 frame.cmd_id = cmd_id; frame.reg_addr = reg_addr; frame.length = length < MAX_LEN ? length:MAX_LEN; for(i = 0;i < frame.length ;i ++){ frame.data[i] = * data++; } length =5 + frame.length; frame.crc = crc8_checkout(cmd_data, length); while(length--) uart_putc(port, (uint32_t)(*cmd_data ++)); uart_putc(port, (uint32_t)(frame.crc)); }