#include "driver/ewdriver.h" #include "base/define.h" #include "base/delay.h" //#include "console_usart.h" #include "base/utility.h" //#include "usartapp.h" //#include "arrayfifo.h" //#include "YeCommProtocol.h" #include "hardware/power.h" #include "elec_io.h" #pragma pack(1) typedef struct{ uint8_t head[2];//固定头,区分设备 uint16_t frame_len;//整帧长度,包括CRC uint8_t src_addr;//源地址 uint8_t dist_addr;//目的地址 uint8_t cmd;//命令 uint16_t sq;//流水号 }EwCmd_st; typedef struct{ EwCmd_st head; uint8_t oper_cmd; uint16_t h_v; uint16_t m_v; }EwBusCmd_st; typedef struct{ EwCmd_st head; uint8_t oper_cmd; uint16_t h_v; uint16_t m_v; uint16_t bus_v; uint32_t cur; uint8_t crc; }EwHartBeatCmd_st; typedef struct{ EwCmd_st head; uint16_t r_len; uint16_t w_len; uint16_t reate; uint8_t cmd_delay; uint8_t buf[64]; }EwBusRW_st; typedef struct{ EwCmd_st head; uint8_t ack; uint8_t buf[96]; }EwBusRWAck_st; typedef struct{ EwCmd_st head; uint16_t w_len; uint16_t cycle; uint16_t count; uint16_t reate; uint8_t cmd_delay; uint8_t buf[64]; }EwClkAmend_st; typedef struct{ EwCmd_st head; uint16_t reate; uint8_t w_len; uint8_t cmd_delay; uint16_t bitcount; uint8_t buf[64]; }EwInspect_st; typedef union{ EwCmd_st head; EwBusCmd_st busoper01; EwHartBeatCmd_st heartbeat02; EwBusRW_st busrw03; EwBusRWAck_st busrwack03; EwClkAmend_st clkamend04; EwInspect_st inspect05; uint8_t buf[128]; }EWCmd_un; #pragma pack() EWCmd_un ewcmd_nu; EwHartBeatCmd_st ew_beat_ack; volatile uint8_t ew_app_rec_flag = 0; volatile uint8_t heard_beat_flag = 0; struct rt_event ew_usart0_rx_event; //应答主机数据 static void EW_AckCmd(EWCmd_un* cmd_un) { uint8_t uc_temp = cmd_un->head.src_addr; uint8_t uc_last_dist = cmd_un->head.dist_addr; uint8_t uc_crc = 0; cmd_un->head.frame_len++;//长度包含CRC cmd_un->head.src_addr = Gpio_GetDeivceAddr();//cmd_un->head.src_addr; cmd_un->head.dist_addr = uc_temp; uc_crc = CheckCRC_8(cmd_un->buf,cmd_un->head.frame_len-1); cmd_un->buf[cmd_un->head.frame_len-1] = uc_crc; ConsoleUsart_send_bytes(cmd_un->buf,cmd_un->head.frame_len); //ConsoleUsart0DMA_send_bytes(cmd_un->yecmdbuf,cmd_un->head.frame_len,10); } static void EW_BusCmd01(EWCmd_un* cmd_un) { if(cmd_un->busoper01.oper_cmd == 1) { PowerCalibration_set(cmd_un->busoper01.h_v,cmd_un->busoper01.m_v); EW_DIFF_MOD_H; }else{ PowerCalibration_set(POWER_DEF_V,POWER_DEF_V-10); EW_BUS_OFF } cmd_un->head.frame_len = sizeof(EwCmd_st); cmd_un->buf[cmd_un->head.frame_len] = 0; cmd_un->head.frame_len++; EW_AckCmd(cmd_un); } static void EW_HeartBeatCmd02(EWCmd_un* cmd_un) { heard_beat_flag = cmd_un->heartbeat02.oper_cmd; memcpy(&ew_beat_ack,cmd_un,sizeof(EwCmd_st)); cmd_un->head.frame_len = sizeof(EwCmd_st); cmd_un->buf[cmd_un->head.frame_len] = 0; cmd_un->head.frame_len++; EW_AckCmd(cmd_un); } extern uint16_t EW_DMOD_READ_Timeout; static void EW_RWCmd03(EWCmd_un* cmd_un) { uint8_t auc_ew_head[2]; uint8_t uc_ack = 0; uint16_t ul_readlen = cmd_un->busrw03.r_len; auc_ew_head[0] = cmd_un->busrw03.buf[0]; auc_ew_head[1] = cmd_un->busrw03.buf[1]; if(cmd_un->busrw03.w_len > 0) { __disable_irq(); DMod_SendBytes(cmd_un->busrw03.buf,cmd_un->busrw03.w_len, cmd_un->busrw03.reate,ul_readlen); __enable_irq(); } delay_ms(cmd_un->busrw03.cmd_delay); if(ul_readlen > 0) { __disable_irq(); uc_ack = DMod_FireBusReadDatasV2(cmd_un->busrwack03.buf,ul_readlen,EW_DMOD_READ_Timeout); __enable_irq(); if(ul_readlen == 2 && uc_ack == 0) { if(auc_ew_head[0] != cmd_un->busrwack03.buf[0] || auc_ew_head[1] != cmd_un->busrwack03.buf[1]) { uc_ack = 10; } }else if(ul_readlen > 2 && uc_ack == 0) { if(cmd_un->busrwack03.buf[ul_readlen-1] != CheckCRC_8(cmd_un->busrwack03.buf,ul_readlen-1)) { uc_ack = 11; } } } cmd_un->busrwack03.ack = uc_ack; cmd_un->busrwack03.head.frame_len = sizeof(EwCmd_st) +1+ ul_readlen; EW_AckCmd(cmd_un); } static void EW_ClkAmendCmd04(EWCmd_un* cmd_un) { uint16_t us_cycle = cmd_un->clkamend04.cycle; __disable_irq(); DMod_SendBytes(cmd_un->clkamend04.buf,cmd_un->clkamend04.w_len, cmd_un->clkamend04.reate,0); __enable_irq(); delay_ms(cmd_un->clkamend04.cmd_delay); EW_SendTrimSquare(us_cycle,us_cycle>>1,cmd_un->clkamend04.count); cmd_un->busrwack03.ack = 0; cmd_un->busrwack03.head.frame_len = sizeof(EwCmd_st) +1; EW_AckCmd(cmd_un); } static void EW_InspectCmd05(EWCmd_un* cmd_un) { uint16_t us_cycle = cmd_un->clkamend04.cycle; uint16_t us_count = 0; us_count = cmd_un->inspect05.bitcount; __disable_irq(); DMod_SendBytes(cmd_un->inspect05.buf,cmd_un->inspect05.w_len, cmd_un->inspect05.reate,1); __enable_irq(); delay_ms(cmd_un->inspect05.cmd_delay); cmd_un->busrwack03.ack = 0; DMod_ReadInspect_Data(us_count,cmd_un->busrwack03.buf); cmd_un->busrwack03.head.frame_len = sizeof(EwCmd_st) +((us_count+7)>>3)+1; EW_AckCmd(cmd_un); } void EW_DoCmd(EWCmd_un* cmd_un) { switch(cmd_un->head.cmd) { case 0x01: EW_BusCmd01(cmd_un);break; case 0x02: EW_HeartBeatCmd02(cmd_un);break; case 0x03: EW_RWCmd03(cmd_un); break; case 0x04: EW_ClkAmendCmd04(cmd_un);break; case 0x05: EW_InspectCmd05(cmd_un);break; } } static void DoHeartBeat() { uint8_t uc_crc; ew_beat_ack.oper_cmd = 1; ew_beat_ack.h_v = Power_GetHPowerV(); ew_beat_ack.m_v = Power_GetMPowerV(); ew_beat_ack.bus_v = Power_GetBousV(); ew_beat_ack.cur = Power_GetCurrent(); ew_beat_ack.head.frame_len = sizeof(EwHartBeatCmd_st); uc_crc = CheckCRC_8((uint8_t*)&ew_beat_ack,ew_beat_ack.head.frame_len-1); ew_beat_ack.crc = uc_crc; ConsoleUsart_send_bytes((uint8_t*)&ew_beat_ack,ew_beat_ack.head.frame_len); } void EWUsartApp_Task(void* param) { rt_uint32_t event; uint32_t idle_count = 0; UNUSED(param); rt_event_init(&ew_usart0_rx_event, "ew_usart_rx_e", RT_IPC_FLAG_PRIO); ew_app_rec_flag = 0; while(1) { if(idle_count > 9) { idle_count = 0; if(heard_beat_flag > 0) { DoHeartBeat(); } } if(rt_event_recv(&ew_usart0_rx_event, UART_MC_FRAME_EVENT,RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,100, &event) != RT_EOK) { idle_count++; continue; } if((event & UART_MC_FRAME_EVENT) > 0) { ConsoleRxDisable(); if(ewcmd_nu.buf[0]=='E' && ewcmd_nu.buf[1] == 'w') { if(ewcmd_nu.buf[ewcmd_nu.head.frame_len-1] == CheckCRC_8(ewcmd_nu.buf,ewcmd_nu.head.frame_len-1)) { EW_DoCmd(&ewcmd_nu); } } ConsoleRxEnable(); ew_app_rec_flag = 0; } } } /* @brief 串口通信数据帧缓存 @param buf 源数据缓存空间 @paran len 存入数据的长度 @rtv 无 */ void EW_UsartApp_Push_Cmd(uint8_t* buf, uint16_t len) { if(ew_app_rec_flag > 0) { return; } if(len > sizeof(EWCmd_un)) { len = sizeof(EWCmd_un); } rt_memcpy((void*)&ewcmd_nu,buf,len); rt_event_send(&ew_usart0_rx_event,UART_MC_FRAME_EVENT);//发送串口数据接收事件 ew_app_rec_flag = 1; }