#include "EWDriver.h" #include "base/delay.h" #include "base/utility.h" #include "hardware/gpio_cfg.h" #include "hardware/adc_cfg.h" #include "hardware/power.h" #include "ewdriver.h" #include "hardware/timer_cfg.h" #include "debug.h" static volatile EWBus_Mod_en bus_mod = OFF_MOD; static volatile CurrentSample_Range_eu buscurrent_range = Current_Max; #define FB_Read_AD_Sample_C 30 #if FIREBUS_ADC_BUF_LEN < FB_Read_AD_Sample_C #error "EWDriver ADC define error" #endif #define SMod_Read_Idle_Filter 90 #define DMod_Read_Idle_Filter 100 volatile uint16_t* EW_Read_AD_V = FireBus_ADC_Buf; static volatile uint16_t SMod_Read_Idle_C; static uint16_t firebus_idle_diff = SMod_Read_Idle_Filter; const static uint16_t data2bit_signal[]={200,234,275,323,380,446}; static uint16_t datapulus[6][2]; //发送起始信号 #define SMod_Begin_Plus() SMod_2Bit_Plus(4) //发送结束信号 #define SMod_End_Plus() SMod_2Bit_Plus(5) uint8_t EW_CommBuf[EW_DMODE_FRAME_SIZE]; uint16_t EW_DMOD_Peroid = 300; uint16_t EW_DMOD_READ_Timeout = 6000; uint16_t EW_FreeBack_MaxCur,EW_FreeBack_MinCur; uint16_t EW_FreeBack_MaxTime,EW_FreeBack_MinTime; //通信监控变量初始化 void EW_FreeBack_Prapare(void) { EW_FreeBack_MaxCur = 0; EW_FreeBack_MinCur = 0xFFFE; EW_FreeBack_MaxTime = 0; EW_FreeBack_MinTime = 0xFFFE; } //发送唤醒信号 static void SMod_Wake_Plus(void) { EW_SINGLE_MOD_M; delay_us(200); EW_SINGLE_MOD_H; delay_us(600); } //发送2Bit数据信号 static void SMod_2Bit_Plus(uint8_t data) { if(data > 5) return; EW_SINGLE_MOD_M; delay_us(datapulus[data][0]); EW_SINGLE_MOD_H; delay_us(datapulus[data][1]); } //读取1bit数据 static uint8_t SMod_ReadBit(uint16_t wait_us) { uint32_t ul_temp = 0; ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_MIDLE); EW_SINGLE_MOD_M; delay_us(wait_us); while(ul_temp < FB_Read_AD_Sample_C) { EW_Read_AD_V[ul_temp++] = ADC_GetCurADCFast(); } EW_SINGLE_MOD_H; Bubble_Sort_u16((uint16_t*)EW_Read_AD_V,FB_Read_AD_Sample_C); ul_temp = EW_Read_AD_V[FB_Read_AD_Sample_C - 6]; ul_temp += EW_Read_AD_V[FB_Read_AD_Sample_C - 7]; ul_temp += EW_Read_AD_V[FB_Read_AD_Sample_C - 8]; ul_temp += EW_Read_AD_V[FB_Read_AD_Sample_C - 9]; ul_temp >>= 2; if(ul_temp > SMod_Read_Idle_C) { LED1_Out_On; return 1; } LED1_Out_Off; return 0; } static uint8_t DMod_ReadBit(uint16_t wait_us) { uint32_t ul_temp = 0; ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_MIDLE); EW_DIFF_MOD_M; delay_us(wait_us); while(ul_temp < FB_Read_AD_Sample_C) { EW_Read_AD_V[ul_temp++] = ADC_GetCurADCFast(); } EW_DIFF_MOD_L; Bubble_Sort_u16((uint16_t*)EW_Read_AD_V,FB_Read_AD_Sample_C); ul_temp = EW_Read_AD_V[FB_Read_AD_Sample_C - 6]; ul_temp += EW_Read_AD_V[FB_Read_AD_Sample_C - 7]; ul_temp += EW_Read_AD_V[FB_Read_AD_Sample_C - 8]; ul_temp += EW_Read_AD_V[FB_Read_AD_Sample_C - 9]; ul_temp >>= 2; if(ul_temp > SMod_Read_Idle_C) { LED1_Out_On ; return 1; } LED1_Out_Off; return 0; } //从AD采样缓存总,计算空闲电流 static uint16_t FireBus_UpdataIdeV(void) { SMod_Read_Idle_C = 0; SMod_Read_Idle_C = (uint32_t)(EW_Read_AD_V[FB_Read_AD_Sample_C - 6]); SMod_Read_Idle_C += (uint32_t)(EW_Read_AD_V[FB_Read_AD_Sample_C - 7]*3); SMod_Read_Idle_C += (uint32_t)(EW_Read_AD_V[FB_Read_AD_Sample_C - 8]*4); SMod_Read_Idle_C += (uint32_t)(EW_Read_AD_V[FB_Read_AD_Sample_C - 9]*2); SMod_Read_Idle_C /= 10; SMod_Read_Idle_C += firebus_idle_diff; return SMod_Read_Idle_C; } //采集空闲电流 static uint16_t SMod_GetIdleV(void) { firebus_idle_diff = SMod_Read_Idle_Filter; SMod_ReadBit(80);//获取采样电流 return FireBus_UpdataIdeV(); } //static uint16_t DMod_GetIdleV(void) //{ // firebus_idle_diff = DMod_Read_Idle_Filter; // DMod_ReadBit(300);//获取采样电流 // return FireBus_UpdataIdeV(); //} static uint16_t SMod_GetIdle2V(void) { uint32_t ul_temp = 0; firebus_idle_diff = SMod_Read_Idle_Filter; while(ul_temp < FB_Read_AD_Sample_C) { EW_Read_AD_V[ul_temp++] = ADC_GetCurADCFast(); } return FireBus_UpdataIdeV(); } static uint16_t DMod_GetIdle2V(void) { uint32_t ul_temp = 0; firebus_idle_diff = DMod_Read_Idle_Filter; while(ul_temp < FB_Read_AD_Sample_C) { EW_Read_AD_V[ul_temp++] = ADC_GetCurADCFast(); } return FireBus_UpdataIdeV(); } /* @brief 读取模块ACK @param 超时 0.1ms */ static uint8_t DMod_ReadAck(uint16_t time_out) { uint32_t ul_temp = 0; uint32_t ul_temp2 = 0; uint16_t us_count = 0; CurrentSample_Range_eu range = buscurrent_range;//档位保存 ul_temp = time_out*10; ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_MIDLE); EW_DIFF_MOD_M; Power_SetSampleCurrentRange(EWDriver_Sample_R); delay_ms(1); DMod_GetIdle2V(); Get10usCount(); while((ul_temp2 < ul_temp) && (us_count < 10)) { if(ADC_GetCurADCFast() > SMod_Read_Idle_C) { us_count++; }else{ us_count = 0; } ul_temp2 += Get10usCount(); } Power_SetSampleCurrentRange(range); if(us_count < 10) { EW_DIFF_MOD_H; return 0; } delay_ms(20); EW_DIFF_MOD_H return 1; } //采集到应答信号返0 否则返1 static uint8_t SMod_WaitAck(uint16_t time_out) { while(time_out > 0) { time_out--; if(SMod_ReadBit(80) > 0) { delay_us(350); return 0; } delay_us(350); } return 1; } void EW_BusDef_Init(void) { uint16_t us_temp = 80; uint8_t count = 0; for(count = 0; count < 6;count++) { datapulus[count][0] = us_temp; datapulus[count][1] = data2bit_signal[count] - us_temp-12;//-4为延时偏移,实测。 } } /* @brief 单端发送4Bytes 数据 @param *buf 4字节数据缓存指针 @param type 数据帧类型 @param bg_count 起始信号个数 @param end_count 结束信号个数 */ void SMod_FireBusSend4BytesFrame(uint8_t* buf,EW_SINGLE_FRAME_TYPE_en type ,uint8_t bg_count,uint8_t end_count) { uint8_t uc_plus_type[17]; uint8_t uc_data; uint32_t ul_count1 = 0; uint32_t ul_count2 = 0; uc_plus_type[ul_count1++] = (uint8_t)type; while(ul_count1 < 17) { ul_count2 = 0; uc_data = *buf; while(ul_count2 < 4) { uc_plus_type[ul_count1++] = (uc_data & 0xC0)>>6; uc_data <<= 2; ul_count2++; } buf++; } SMod_Wake_Plus(); /******************/ while(bg_count > 0) { bg_count --; SMod_Begin_Plus(); } for(ul_count1 = 0; ul_count1 < 17; ul_count1++) { SMod_2Bit_Plus(uc_plus_type[ul_count1]); } while(end_count > 0) { end_count --; SMod_End_Plus(); } } /* @brief 单端模式发送数据 @param *buf 数据缓存指针 @param bg_count 起始信号个数 @param end_count 结束信号个数 */ uint8_t SMod_SendData(uint8_t* buf, uint16_t len,uint8_t bg_count,uint8_t end_count) { uint16_t us_count = 0; uint8_t* databuf = (uint8_t*)rt_malloc(len+4); if(databuf == RT_NULL) { return 1; } len--; rt_memcpy(databuf,buf,len); while((len % 4) != 3) { databuf[len++] = 0; } databuf[len] = CheckXOR_8(databuf,len); len++; if(len == 4) { SMod_FireBusSend4BytesFrame(databuf,COMPLETE_FRAME,bg_count,end_count); goto SMod_Data_Send_End; } SMod_FireBusSend4BytesFrame(databuf,BEGIN_FRAME,bg_count,end_count); us_count += 4; while(us_count < (len-4)) { delay_ms(40); SMod_FireBusSend4BytesFrame(databuf+us_count,DATA_FRAME,bg_count,end_count); us_count += 4; } delay_ms(40); SMod_FireBusSend4BytesFrame(databuf+us_count,END_FRAME,bg_count,end_count); SMod_Data_Send_End: rt_free(databuf); return 0; } /* @brief 单端接收数据 @param *buf 数据缓存指针 @param len 读取数据长度 @param time_out 应答信号超时个数 */ uint8_t SMod_FireBusReadDatas(uint8_t* buf, uint8_t len, uint16_t time_out) { uint32_t ul_temp = 0; uint8_t uc_data; CurrentSample_Range_eu range = buscurrent_range;//档位保存 Power_SetSampleCurrentRange(EWDriver_Sample_R); ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_MIDLE); delay_ms(1); //采集空闲电流 SMod_GetIdleV(); delay_us(350); SMod_GetIdleV(); delay_us(350); if(SMod_WaitAck(time_out) > 0) { Power_SetSampleCurrentRange(range); return 1; } while(len > 0) { ul_temp = 0; uc_data = 0; len--; while(ul_temp < 8) { uc_data <<= 1; uc_data += SMod_ReadBit(80); delay_us(500); ul_temp++; } *buf = uc_data; buf++; } Power_SetSampleCurrentRange(range); return 0; } /* @brief 获取巡检数据 @param count 巡检脉冲数 @param buf 数据缓存区 @rtv 无 */ void FireBus_ReadInspect_Data(uint16_t count,uint8_t* buf) { uint16_t index; uint8_t data; CurrentSample_Range_eu range = buscurrent_range;//档位保存 Power_SetSampleCurrentRange(EWDriver_Sample_R); ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_MIDLE); //delay_us(500); //总线跳转到中电平 EW_SINGLE_MOD_M; //延时等待电流稳定 //COM_PH2_Out = 0; delay_us(240); //获取中电平电流 SMod_GetIdle2V(); EW_SINGLE_MOD_H delay_us(700); rt_memset(buf,0,((count+7 ) >> 3)); index = 0; while(index < count) { data = *(buf+(index >> 3)); if( SMod_ReadBit(80) > 0) { data |= (0x01 << (index & 0x07)); }; EW_SINGLE_MOD_H delay_us(800); *(buf+(index >> 3)) = data; index++; } Power_SetSampleCurrentRange(range); } /*************************************************************/ #define DMOD_READ_AD_FILTER_COUNT 4 static uint16_t TEST_IDLE_Line_Buf[1000]; static uint16_t TEST_IDLE_Line_Count = 0; static uint8_t SMod_FireBusReadPlus(uint16_t* plus_h, uint16_t* plus_t,uint16_t time_out,uint16_t ad_line,uint16_t* max_ad,uint16_t* min_ad) { uint32_t ul_ad_sample; uint32_t ul_index = 0; uint16_t us_adc_buf[DMOD_READ_AD_FILTER_COUNT+1]; uint32_t ul_count = 0; uint32_t uc_step = 0; uint32_t ul_maxad = 0,ul_minad = 0; uint32_t ul_h_count = 0,ul_l_count = 0; uint32_t ul_h_all_count = 0; uint32_t ul_l_all_count = 0; *max_ad = 0; *min_ad = 0xFFFF; if(TEST_IDLE_Line_Count > 999) { TEST_IDLE_Line_Count = 999; } TEST_IDLE_Line_Buf[TEST_IDLE_Line_Count++] = ad_line; for(ul_count =0; ul_count < DMOD_READ_AD_FILTER_COUNT; ul_count++) { us_adc_buf[ul_count++] = ADC_GetCurADCFast(); } //数据发送时,以高脉冲在先,然后是低电平, do{ time_out--; ul_ad_sample = ADC_GetCurADCFast(); // if(ul_ad_sample > *max_ad) // *max_ad = ul_ad_sample; // if(ul_ad_sample > ad_line) // { // PBout(I2IC_SCL_Pin_Nu) = 1 ; // }else{ // PBout(I2IC_SCL_Pin_Nu) = 0; // } us_adc_buf[ul_count++] = ul_ad_sample; ul_count %= DMOD_READ_AD_FILTER_COUNT; ul_h_count = 0; ul_l_count = 0; for(ul_index =0; ul_index < DMOD_READ_AD_FILTER_COUNT; ul_index++) { if(us_adc_buf[ul_index] > ad_line) { ul_h_count++; ul_h_all_count++; ul_maxad += us_adc_buf[ul_index]; }else{ ul_l_count++; ul_l_all_count++; ul_minad += us_adc_buf[ul_index]; } } if(uc_step == 0 && ul_h_count >(DMOD_READ_AD_FILTER_COUNT-1))//启动周期计数 { (*plus_h)++; (*plus_t)++; uc_step = 1; }else if(uc_step == 0){ continue;//未启动 } if(uc_step == 1) { if(ul_h_count > (DMOD_READ_AD_FILTER_COUNT-1)) { PBout(I2IC_SCL_Pin_Nu) = 1 ; (*plus_h)++; uc_step = 1; }else if(ul_l_count > (DMOD_READ_AD_FILTER_COUNT-1)) //由高变低 { PBout(I2IC_SCL_Pin_Nu) = 0; uc_step = 2; } } else if(uc_step == 2 && ul_h_count > (DMOD_READ_AD_FILTER_COUNT-1))//由低变高 { PBout(I2IC_SCL_Pin_Nu) = 1 ; break; } (*plus_t)++; }while(time_out > 0); *max_ad = ul_maxad / ul_h_all_count; *min_ad = ul_minad / ul_h_all_count; if(time_out < 1)//等待起始信号超时 { return 1; } return 0; } /* @brief 单端第二版,差分接收数据 @param *buf 数据缓存指针 @param len 读取数据长度 @param time_out 超时脉冲数(约1bit数据时间) @rtv 0 成功 否则失败 */ static uint16_t us_plus_H,us_plus_H2;//高电平采用次数 static uint16_t us_plus_T,us_plus_T2;//采样周期 uint16_t idle_line = 0; uint8_t DMod_FireBusReadDatasV2(uint8_t* buf, uint8_t len, uint32_t time_out) { uint32_t ul_ad_sample; uint32_t ul_check_falg; //奇校验 uint32_t us_time_out = time_out; uint32_t ul_data = 0; //uint32_t us_dataT_Or;//数据周期 uint32_t us_temp1,us_temp2; uint16_t ad_max = 0,ad_min = 0; uint8_t uc_rtv = 0; CurrentSample_Range_eu range = buscurrent_range;//档位保存 Power_SetSampleCurrentRange(EWDriver_Sample_R); ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_HFAST); memset(TEST_IDLE_Line_Buf,0,sizeof(TEST_IDLE_Line_Buf)); TEST_IDLE_Line_Count = 0; delay_us(2000); //总线跳转到中电平 EW_DIFF_MOD_M; //延时等待电流稳定 delay_us(800); //COM_PH2_Out = 0; PBout(I2IC_SCL_Pin_Nu) = 0; delay_us(200); //获取中电平电流 PBout(I2IC_SCL_Pin_Nu) = 1 ; DMod_GetIdle2V(); PBout(I2IC_SCL_Pin_Nu) = 0 ; //读取指定长度数据 //读取单字节数据 ul_data = 0; //等待起始信号唤醒信号 us_plus_H = 0; us_plus_T = 0; us_time_out = 2000 + time_out; do{ ul_ad_sample = ADC_GetCurADCFast(); if(ad_max < ul_ad_sample) ad_max = ul_ad_sample; if(ul_ad_sample > SMod_Read_Idle_C) { us_plus_H++; }else{ us_plus_H = 0; } delay_us(2); us_time_out--; } while((us_plus_H < 4) && (us_time_out > 0)); if(us_time_out < 1)//等待起始信号超时 { uc_rtv = 1; goto DMOD_Read_END; } while(len > 0) { //等待数据帧起始信号 us_time_out = 10; us_plus_T2 = 0xFFFF; us_plus_H2 = 0; while(us_time_out > 0) { us_plus_H = 0; us_plus_T = 0; idle_line = (uint16_t)(ad_max*0.005f+ad_min*0.095f) + SMod_Read_Idle_C; // idle_line = SMod_Read_Idle_C; // idle_line = ad_max - SMod_Read_Idle_C; // idle_line = (idle_line>>1)+ (idle_line>>4)+ SMod_Read_Idle_C; if(SMod_FireBusReadPlus(&us_plus_H,&us_plus_T,time_out,idle_line,&ad_max,&ad_min ) > 0) { uc_rtv = 2; goto DMOD_Read_END; } if(us_plus_H2 > (us_plus_T2- us_plus_H2)) { us_temp1 = us_plus_T << 1; //2倍 us_temp2 = us_plus_T + (us_plus_T >> 1);//1.5倍 if((us_plus_T2 > us_temp2) && (us_plus_T2 < us_temp1)) { break; } } us_plus_T2 = us_plus_T; us_plus_H2 = us_plus_H; us_time_out--; } //采集8bit数据+1位校验 ul_data = 0; ul_check_falg = 0; us_time_out = 0; us_plus_T2 = 0; //us_dataT_Or = us_plus_T;//保存数据周期 do{ ul_data <<= 1; if(us_plus_H > (us_plus_T- us_plus_H)) //高电平时间大于低电平 1 { ul_data |= 0x01; ul_check_falg ^= 0x01; }else{//检测是否是结束信号 0 us_temp1 = us_plus_T2 << 1; //2倍 us_temp2 = us_plus_T2 + (us_plus_T2 >> 1);//1.5倍 if((us_plus_T > us_temp2) && (us_plus_T < us_temp1)) { break; } } //约束数据周期范围 // if(((us_dataT_Or+4) < us_plus_T) // || ((us_dataT_Or - 4) > us_plus_T)) // { // SetSampleCurrentRange(range); // EW_SINGLE_MOD_H; // return 3; // } us_plus_T2 = us_plus_T; us_plus_H2 = us_plus_H; us_plus_H = 0; us_plus_T = 0; idle_line = (uint16_t)(ad_max*0.01f+ad_min*0.09f) + SMod_Read_Idle_C; if(idle_line > 200) { idle_line = 200; } //idle_line = (idle_line>>1)+ (idle_line>>4)+ SMod_Read_Idle_C; //idle_line = SMod_Read_Idle_C; if(SMod_FireBusReadPlus(&us_plus_H,&us_plus_T,time_out,idle_line,&ad_max,&ad_min ) > 0) { uc_rtv = 4; goto DMOD_Read_END; } if(EW_FreeBack_MaxTime < ad_max) { EW_FreeBack_MaxTime = ad_max; } if(EW_FreeBack_MinTime > ad_max) { EW_FreeBack_MinTime = ad_max; } if(EW_FreeBack_MaxTime < us_plus_T) { EW_FreeBack_MaxTime = us_plus_T; } if(EW_FreeBack_MinTime > us_plus_T) { EW_FreeBack_MinTime = us_plus_T; } us_time_out++; }while(us_time_out < 13); if(ul_check_falg == 0) { uc_rtv =5; goto DMOD_Read_END; } if(us_time_out != 9) { uc_rtv = 6; goto DMOD_Read_END; } ul_data >>= 2; *buf = (uint8_t)ul_data; buf++; len--; } DMOD_Read_END: delay_ms(1); EW_DIFF_MOD_H Power_SetSampleCurrentRange(range); return uc_rtv; } static uint16_t us_plus_H,us_plus_H2;//高电平采用次数 static uint16_t us_plus_T,us_plus_T2;//采样周期 typedef struct{ uint16_t cur_idle; uint16_t cur_idle_ad; uint16_t cur_high_value; uint16_t cur_idle_line; uint16_t cur_max; }firebus_def; uint8_t DMod_FireBusReadDatasV2_RC(uint8_t* buf, uint8_t len, uint32_t time_out) { uint32_t ul_ad_sample; uint32_t ul_check_falg; //奇校验 uint32_t us_time_out = time_out; uint32_t ul_data = 0; uint32_t us_dataT_Or;//数据周期 uint32_t us_temp1,us_temp2; uint16_t ad_max = 0,ad_min_temp=0,ad_max_temp = 0; firebus_def fire_dat={0}; uint8_t ret=0; CurrentSample_Range_eu range = buscurrent_range;//档位保存 Power_SetSampleCurrentRange(R10_2mA_30mA_MC); ADC_CurChnnelSet(AN_MAL_CH,ADC_SPEED_HFAST); delay_us(2000); //总线跳转到中电平 EW_DIFF_MOD_M; //延时等待电流稳定 delay_us(800); //COM_PH2_Out = 0; PBout(I2IC_SCL_Pin_Nu) = 0; delay_us(200); //获取中电平电流 PBout(I2IC_SCL_Pin_Nu) = 1 ; DMod_GetIdle2V(); fire_dat.cur_idle=SMod_Read_Idle_C; fire_dat.cur_idle_ad=ADC_GetCurADCFast(); PBout(I2IC_SCL_Pin_Nu) = 0 ; //读取指定长度数据 //读取单字节数据 ul_data = 0; //等待起始信号唤醒信号 us_plus_H = 0; us_plus_T = 0; us_time_out = 2000 + time_out; do{ ul_ad_sample = ADC_GetCurADCFast(); if(ad_max < ul_ad_sample) ad_max = ul_ad_sample; if(ul_ad_sample > SMod_Read_Idle_C) { if(ul_ad_sample-SMod_Read_Idle_C>50){ us_plus_H++; fire_dat.cur_high_value=fire_dat.cur_high_value/2+ul_ad_sample/2; }else{ SMod_Read_Idle_C=ul_ad_sample; } }else{ us_plus_H = 0; fire_dat.cur_high_value=0; } delay_us(2); us_time_out--; } while((us_plus_H < 4) && (us_time_out > 0)); fire_dat.cur_max=ad_max; if(us_time_out < 1)//等待起始信号超时 { ret=1; goto end; } // 空闲判线以最高电平为基准 SMod_Read_Idle_C=(SMod_Read_Idle_C+fire_dat.cur_high_value)/2; fire_dat.cur_idle_line=SMod_Read_Idle_C; while(len > 0) { //等待数据帧起始信号 us_time_out = 10; us_plus_T2 = 0xFFFF; us_plus_H2 = 0; while(us_time_out > 0) { us_plus_H = 0; us_plus_T = 0; idle_line = SMod_Read_Idle_C; // idle_line = ad_max - SMod_Read_Idle_C; // idle_line = (idle_line>>1)+ (idle_line>>4)+ SMod_Read_Idle_C; if(SMod_FireBusReadPlus(&us_plus_H,&us_plus_T,time_out,idle_line,&ad_max_temp,&ad_min_temp ) > 0) { ret=2; goto end; } if(us_plus_H2 > (us_plus_T2- us_plus_H2)) { us_temp1 = us_plus_T << 1; //2倍 us_temp2 = us_plus_T + (us_plus_T >> 1);//1.5倍 if((us_plus_T2 > us_temp2) && (us_plus_T2 < us_temp1)) { break; } } us_plus_T2 = us_plus_T; us_plus_H2 = us_plus_H; us_time_out--; } //采集8bit数据+1位校验 ul_data = 0; ul_check_falg = 0; us_time_out = 0; us_plus_T2 = 0; us_dataT_Or = us_plus_T;//保存数据周期 do{ ul_data <<= 1; if(us_plus_H > (us_plus_T- us_plus_H)) //高电平时间大于低电平 1 { ul_data |= 0x01; ul_check_falg ^= 0x01; }else{//检测是否是结束信号 0 us_temp1 = us_plus_T2 << 1; //2倍 us_temp2 = us_plus_T2 + (us_plus_T2 >> 1);//1.5倍 if((us_plus_T > us_temp2) && (us_plus_T < us_temp1)) { break; } } //约束数据周期范围 // if(((us_dataT_Or+4) < us_plus_T) // || ((us_dataT_Or - 4) > us_plus_T)) // { // SetSampleCurrentRange(range); // EW_SINGLE_MOD_H; // return 3; // } us_plus_T2 = us_plus_T; us_plus_H2 = us_plus_H; us_plus_H = 0; us_plus_T = 0; //idle_line = ad_max - SMod_Read_Idle_C; //idle_line = (idle_line>>1)+ (idle_line>>4)+ SMod_Read_Idle_C; idle_line = SMod_Read_Idle_C; if(SMod_FireBusReadPlus(&us_plus_H,&us_plus_T,time_out,idle_line,&ad_max_temp,&ad_min_temp ) > 0) { ret=4; goto end; } ad_max = (uint16_t)(ad_max * 0.7f + ad_max_temp*0.3f); us_time_out++; }while(us_time_out < 13); if(ul_check_falg == 0) { ret=5; goto end; } if(us_time_out != 9) { ret=6; goto end; } ul_data >>= 2; *buf = (uint8_t)ul_data; buf++; len--; } //delay_us(time_out >> 1); end: EW_DIFF_MOD_H; Power_SetSampleCurrentRange(range); if(ret){ DBG_LOG("cur_idle=%d,high_value=%d,idle_line=%d.",fire_dat.cur_idle, fire_dat.cur_high_value,fire_dat.cur_idle_line); DBG_LOG("cur_max=%d,cur_idle_ad=%d",fire_dat.cur_max,fire_dat.cur_idle_ad); } return ret; } /* @brief 差分模式数据发送 @param buf 发送数据缓存 @param len 发送长度 @param pre 数据脉冲周期 */ static void DMod_SendBytesSelf(uint8_t* buf, uint8_t len, uint16_t pre,uint8_t rw_flag, uint8_t (*crc_fun)(uint8_t *,uint16_t)) { uint16_t us_count = 0; uint8_t uc_checkc_flag = 0; uint8_t uc_datatemp = 0; uint16_t beg_send_pre,beg_H_plus,end_H_plus,data1_H_plus,data0_H_plus; beg_send_pre = pre+(pre >> 1)+(pre >> 2);//1.75倍数据周期 beg_H_plus = (uint16_t)(beg_send_pre * 0.65f)+1; end_H_plus = (uint16_t)(beg_send_pre * 0.35f)+1; data1_H_plus = (uint16_t)(pre * 0.65f); data0_H_plus = (uint16_t)(pre * 0.35f); //buf[len] = CheckCRC_8(buf,len); buf[len] = crc_fun(buf,len); len++; /* 1.发送3个结束信号用作芯片唤醒 2.循环发送缓存数据中的数据 2-1 发送1个起始信号 2-2 发送8bit数据信号 2-3 发送1bit校验信号 2-4 发送1个结束信号 2-5 调整循环变量,满足循环从2-1再次执行,否则退出 3 补发送一个结束信号 */ //发送唤醒脉冲 __disable_irq(); while(us_count < 3) { EW_DIFF_MOD_L; delay_us( beg_send_pre - end_H_plus); EW_DIFF_MOD_H; delay_us(end_H_plus); us_count++; } while(len > 0) { us_count = 0; uc_checkc_flag = 0; len--; //发送起始信号 EW_DIFF_MOD_L; delay_us(beg_H_plus); EW_DIFF_MOD_H; delay_us( beg_send_pre - beg_H_plus); uc_datatemp = *buf; //8bit数据信号+1bit校验 while(us_count < 9) { if((uc_datatemp & 0x80) > 0) { EW_DIFF_MOD_L; delay_us(data1_H_plus); EW_DIFF_MOD_H; delay_us( pre - data1_H_plus); uc_checkc_flag ^= 0x01; }else{ EW_DIFF_MOD_L; delay_us(data0_H_plus); EW_DIFF_MOD_H; delay_us( pre - data0_H_plus); } uc_datatemp <<= 1; us_count++; if(us_count == 8) { uc_checkc_flag ^= 0x01; uc_datatemp &= 0x7F; uc_datatemp |= (uc_checkc_flag << 7); } } buf++; //发结束始信号 EW_DIFF_MOD_L; delay_us(end_H_plus); EW_DIFF_MOD_H; delay_us( beg_send_pre - end_H_plus); } //补发结束信号 EW_DIFF_MOD_L; delay_us(end_H_plus); EW_DIFF_MOD_H; delay_us( beg_send_pre - end_H_plus); if(rw_flag > 0) { EW_DIFF_MOD_L; } __enable_irq(); delay_ms(5);//保障芯片3ms总线空闲监听退出 } void DMod_SendBytes(uint8_t* buf, uint8_t len, uint16_t pre,uint8_t rw_flag) { delay_os_ms(50); DMod_SendBytesSelf(buf,len,pre,rw_flag,CheckCRC_8); } /* * 函数会在 buf[len] 的位置添加一个校验数据 * 所以传入的buf的实际长度要求至少比len长1 */ void DMod_SendBytesXor(uint8_t* buf, uint8_t len, uint8_t rw_flag) { DMod_SendBytesSelf(buf,len,EW_DMOD_Peroid,rw_flag,CheckXOR_8); } uint8_t DMod_ReadBytesXor(uint8_t* buf, uint8_t len,uint16_t retry_times) { uint8_t ret; // for(int i=0;i> 3)); index = 0; while(index < count) { data = *(buf+(index >> 3)); if( DMod_ReadBit(400) > 0) { data |= (0x01 << (index & 0x07)); } delay_us(1200); *(buf+(index >> 3)) = data; index++; } Power_SetSampleCurrentRange(range); delay_ms(1); EW_DIFF_MOD_H; } /***********************************************************/ volatile uint8_t EW_Trim_Flag = 0; static void EW_TrimPlusCallback(uint8_t flag) { if(flag == 1) { EW_DIFF_MOD_L; }else if(flag > 1){ EW_DIFF_MOD_H; } EW_Trim_Flag = flag; } /* @brief 发送校准脉冲 @param cycle 周期 @param duty 总线高电平时间 @param count 脉冲个数 */ void EW_SendTrimSquare(uint16_t cycle,uint16_t duty, uint32_t count) { FireBus_ClkAmend(cycle,duty,count,EW_TrimPlusCallback); EW_Trim_Flag = 0; while(EW_Trim_Flag != 3) { delay_ms(20); } delay_ms(1); EW_DIFF_MOD_H } /* @breif 通信测试 */ uint8_t EW_CommTest(uint8_t* buf,uint16_t len,uint16_t cycle) { uint8_t auc_buf[16]; uint16_t us_head = 1; us_head = (us_head << 6)& 0xFFC0; us_head += EW_COMM_TEST; auc_buf[0] = us_head & 0xFF; auc_buf[1] = (us_head >> 8) & 0xFF; if(len > 13) { len = 13; } memcpy(auc_buf+2,buf,len); len += 2; DMod_SendBytes(auc_buf,len,cycle,1); memset(buf,0,len); delay_ms(2); return DMod_FireBusReadDatasV2(buf,len+1,500); } /* @brief 使能MTP写 @param addr 通信地址 @param 使能开关 @rtv 执行结果 */ uint8_t EW_EnWriteMTP(uint16_t addr ,uint8_t en_flag) { uint8_t uc_ack = 0; uint8_t uc_readflag = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 40; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; EW_CommBuf[2] = en_flag; DMod_SendBytes((uint8_t*)EW_CommBuf,3,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf+2,1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2]) { return 1; } return uc_ack; } /* @brief 读MTP @param addr 通信地址 @param mtpaddr MTP地址/4 @param buf 写入数据的缓存 @param len 数据长度 */ uint8_t EW_WriteMTP(uint16_t addr,uint8_t mtpaddr,uint8_t* buf,uint8_t len) { uint8_t uc_ack = 0; uint8_t uc_readflag = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 63; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; while(len > 10) { EW_CommBuf[2] = mtpaddr; EW_CommBuf[3] = 8; memcpy((EW_CommBuf+4),buf,8); DMod_SendBytes((uint8_t*)EW_CommBuf,len+4,EW_DMOD_Peroid,uc_readflag); len -= 8; mtpaddr += 8; buf += 8; delay_os_ms(20); if(uc_readflag == 0) { continue; } uc_ack = DMod_FireBusReadDatasV2((uint8_t*)(EW_CommBuf+2),1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2]) { return 1; } } EW_CommBuf[2] = mtpaddr; EW_CommBuf[3] = len; memcpy((EW_CommBuf+4),buf,len); DMod_SendBytes((uint8_t*)EW_CommBuf,len+4,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } len = (len>>2)*8+6; delay_ms(len); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)(EW_CommBuf+2),1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2]) { return 1; } return uc_ack; } /* @brief 读MTP @param addr 通信地址 @param mtpaddr MTP地址/4 @param buf 读出数据的缓存 @param len 数据长度 */ uint8_t EW_ReadMTP(uint16_t addr,uint8_t mtpaddr,uint8_t* buf,uint8_t len) { uint8_t uc_ack = 0; uint8_t uc_readflag = 1; if(addr == 0) { return 1; } addr<<=6; addr = (addr & 0xFFC0) | 62; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; while(len > 10) { EW_CommBuf[2] = mtpaddr; EW_CommBuf[3] = 8; DMod_SendBytes((uint8_t*)EW_CommBuf,4,EW_DMOD_Peroid,uc_readflag); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)buf,9,EW_DMOD_READ_Timeout); if((buf[8] != CheckCRC_8(buf,8)) || (uc_ack != 0)) { return 1; } mtpaddr += 8; buf += 8; len -= 8; delay_os_ms(20); } EW_CommBuf[2] = mtpaddr; EW_CommBuf[3] = len; DMod_SendBytes((uint8_t*)EW_CommBuf,4,EW_DMOD_Peroid,uc_readflag); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)buf,len+1,EW_DMOD_READ_Timeout); if(buf[len] != CheckCRC_8(buf,len)) { return 1; } return uc_ack; } /* @brief 运行BootLoader程序 @param addr 通信地址 @param reboot 仅重启标准 1 有效 @rtv 返回执行结果 0 成功 */ uint8_t EW_RunBootLoader(uint16_t addr,uint8_t reboot) { uint32_t ul_bootflag = 0x55AA6699; addr<<=6; addr = (addr & 0xFFC0) | 61; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; if(reboot == 1) { ul_bootflag = 0x9966AA55; } memcpy((EW_CommBuf+2),&ul_bootflag,4); DMod_SendBytes((uint8_t*)EW_CommBuf,6,EW_DMOD_Peroid,0); return 0; } /* @brief 写运行配置,写入MTP中 @param addr 通信地址 @param runcfg 配置结构体 @rtv 返回执行结果 */ uint8_t EW_WriteRunCfg(uint16_t addr,RunCfg_un* runcfg) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 20; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((EW_CommBuf+2),runcfg,3); DMod_SendBytes((uint8_t*)EW_CommBuf,6,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } delay_ms(4); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf+2,1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2] ) { return 1; } return uc_ack; } /* @brief 快速分配通信地址 @param 通信地址 @param UID @param uid_len UID长度 @param ack_data 应答数据 包括2bytes延时和2bytes状态 @rtv 执行结果 */ uint8_t EW_SetAddrByUID(uint16_t addr,uint8_t* uid,uint8_t uid_len) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 21; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((EW_CommBuf+2),uid,uid_len); DMod_SendBytes((uint8_t*)EW_CommBuf,uid_len+2,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf+2,1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2] ) { return 1; } return uc_ack; } /* @brief 快速分配通信地址 @param 通信地址 @param 设置延时 @param UID @param UID长度 @param 应答数据 包括2bytes延时和2bytes状态 @rtv 执行结果 */ uint8_t EW_FastSetByUID(uint16_t addr,uint16_t delay,uint8_t* uid,uint8_t uid_len,uint8_t* ack_data) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 22; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((EW_CommBuf+2),&delay,2); memcpy((EW_CommBuf+4),uid,uid_len); uid_len +=4; DMod_SendBytes(((uint8_t*)(EW_CommBuf)),uid_len,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } delay_ms(2); uc_ack = DMod_FireBusReadDatasV2(ack_data,2,EW_DMOD_READ_Timeout); if(ack_data[0] != EW_CommBuf[2] || ack_data[1] != EW_CommBuf[3]) { return 1; } return uc_ack; } /* @brief 设置延时 @param addr 通信地址 @param 延期时间 @rtv 返回执行结果 */ uint8_t EW_SetDelay(uint16_t addr,uint16_t delay) { uint8_t uc_readflag = 0; uint8_t uc_ack; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 23; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((EW_CommBuf+2),&delay,2); DMod_SendBytes((uint8_t*)EW_CommBuf,4,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf+2,1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2]) { return 1; } return uc_ack; } /* @brief 密码验证 @param addr 通信地址 @param 密码数据 @param 密码长度 @rtv 返回执行结果 */ uint8_t EW_VerfyPWD(uint16_t addr,uint8_t* pwd,uint8_t pwd_len) { uint8_t uc_readflag = 0; uint8_t uc_ack; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 24; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((EW_CommBuf+2),pwd,pwd_len); pwd_len += 2; DMod_SendBytes((uint8_t*)EW_CommBuf,pwd_len,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf+2,1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2]) { return 1; } return uc_ack; } /* @brief 执行起爆 @param addr 通信地址 @param 延迟起爆时间*50ms @rtv 返回执行结果 */ uint8_t EW_Boom(uint16_t addr,uint8_t delay_count) { addr<<=6; addr = (addr & 0xFFC0) | 25; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; EW_CommBuf[2] = delay_count; DMod_SendBytes((uint8_t*)EW_CommBuf,3,EW_DMOD_Peroid,0); return 0; } /* @brief 分组充电 @param addr 通信地址 @param 充电挡位 0:直通 1 :16V 2:20V 3:2.5V @param 分组挡位 addr = group*4 大于addr的可以充电 @rtv 返回执行结果 */ uint8_t EW_Charge(uint16_t addr,uint8_t chg_class,uint8_t group) { addr<<=6; addr = (addr & 0xFFC0) | 26; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; EW_CommBuf[2] = chg_class; EW_CommBuf[3] = group; DMod_SendBytes((uint8_t*)EW_CommBuf,4,EW_DMOD_Peroid,0); return 0; } /* @brief 放电 @param addr 通信地址 */ uint8_t EW_DisCharge(uint16_t addr) { addr<<=6; addr = (addr & 0xFFC0) | 27; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,0); return 0; } /* @brief 读状态信息 @param addr 通信地址 @param *state 返回状态码 @param len 数据长度 */ uint8_t EW_ReadState(uint16_t addr,uint8_t* state) { uint8_t uc_ack = 0; uint8_t uc_readflag = 0; if(addr == 0) { return 1; } uc_readflag = 1; addr<<=6; addr = (addr & 0xFFC0) | 28; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 1; } delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,5,EW_DMOD_READ_Timeout); if(EW_CommBuf[4] != CheckCRC_8((uint8_t*)EW_CommBuf,4)) { return 1; }else{ memcpy(state,((uint8_t*)EW_CommBuf),4); } return uc_ack; } /* @brief 校准地址 @param addr 通信地址 @param cycle 校准周期 us @param plus_count 脉冲个数 */ uint8_t EW_ClkAmend(uint16_t addr ,uint16_t cycle,uint16_t plus_count) { addr<<=6; addr = (addr & 0xFFC0) | 29; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,0); delay_ms(5); EW_SendTrimSquare(cycle,cycle>>1,plus_count); return 0; } /* @brief 巡检 @param addr 通信地址 @param cycle 校准周期 us @param plus_count 脉冲个数 */ uint8_t EW_Inspect(uint16_t bgaddr ,uint16_t endaddr,uint16_t state,uint8_t* buf) { uint16_t addr = 0; addr<<=6; addr = (addr & 0xFFC0) | 30; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((uint8_t*)&EW_CommBuf[2],&bgaddr,2); memcpy((uint8_t*)&EW_CommBuf[4],&endaddr,2); memcpy((uint8_t*)&EW_CommBuf[6],&state,2); DMod_SendBytes((uint8_t*)EW_CommBuf,8,EW_DMOD_Peroid,1); delay_ms(5); DMod_ReadInspect_Data(endaddr-bgaddr,buf); return 0; } /* @brief 配置验证 @param addr 通信地址 @param cfg_mask 源掩码信息 @param 比较信息 (EW_Cfg & cfg_mask) == cfg_state @param 反码状态 0 比较通过不反码 1 比较通过反码 @param */ uint8_t EW_CheckRunCfg(uint16_t addr,uint32_t cfg_mask ,uint32_t cfg_state,uint8_t* rtv) { addr<<=6; addr = (addr & 0xFFC0) | 31; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((uint8_t*)&EW_CommBuf[2],&cfg_mask,3); memcpy((uint8_t*)&EW_CommBuf[5],&cfg_state,3); EW_CommBuf[8] = *rtv; DMod_SendBytes((uint8_t*)EW_CommBuf,9,EW_DMOD_Peroid,1); delay_ms(5); *rtv = DMod_ReadAck(50); return 0; } /* @brief 配置验证 @param addr 通信地址 @param check_class 检测模式 0 基本自检 1 起爆开关检测 2 电容检测 8 读电容检测时间 @param *buf 读出测试结果 */ uint8_t EW_ChecSelf(uint16_t addr,uint8_t check_class,uint8_t* buf) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(check_class == 8) { uc_readflag = 1; } if(buf == NULL && check_class ==8) { return 1; } addr<<=6; addr = (addr & 0xFFC0) | 32; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; EW_CommBuf[2] = check_class; DMod_SendBytes((uint8_t*)EW_CommBuf,9,EW_DMOD_Peroid,uc_readflag); if( uc_readflag == 0) { return 0; } delay_ms(5); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,5,EW_DMOD_READ_Timeout); if(EW_CommBuf[4] == CheckCRC_8((uint8_t*)EW_CommBuf,4)) { memcpy(buf,(uint8_t*)EW_CommBuf,4); }else{ uc_ack = 1; } return uc_ack; } /* @brief 保持起爆配置信息和使能起爆 */ uint8_t EW_SaveFireInfo(uint16_t addr) { addr<<=6; addr = (addr & 0xFFC0) | 33; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,0); return 0; } /* @brief 读延时 @param addr 通信地址 @param delay 返回延时 */ uint8_t EW_ReadDelay(uint16_t addr,uint16_t* delay) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 34; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,uc_readflag); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,3,EW_DMOD_READ_Timeout); if(EW_CommBuf[2] == CheckCRC_8((uint8_t*)EW_CommBuf,2)) { memcpy(delay,(uint8_t*)EW_CommBuf,2); }else{ uc_ack = 1; } return uc_ack; } /* @brief 通信反码配置 @param addr 通信地址 @param speed 通信挡位 0:10K 1:7K 2:5K 3:4.5K 4: 4K 4+n:4-0.5*n @param cur 电流挡位 0:1mA 1:2mA 2:4mA 3:8mA */ uint8_t EW_SetReportCfg(uint8_t speed,uint8_t cur) { uint16_t addr = 0; addr<<=6; addr = (addr & 0xFFC0) | 35; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; EW_CommBuf[2] = speed; EW_CommBuf[3] = cur; DMod_SendBytes((uint8_t*)EW_CommBuf,4,EW_DMOD_Peroid,0); return 0; } /* @brief 更新网络地址 @param addr 通信地址 @param new_addr 新地址 */ uint8_t EW_UpdateCommAddr(uint8_t addr,uint16_t new_addr) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 36; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((EW_CommBuf+2),&new_addr,2); DMod_SendBytes((uint8_t*)EW_CommBuf,4,EW_DMOD_Peroid,uc_readflag); if(uc_readflag == 0) { return 0; } delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf+2,1,EW_DMOD_READ_Timeout); if(EW_CommBuf[0] != EW_CommBuf[2]) { return 1; } return uc_ack; } /* @brief 读校准值 @param addr 通信地址 @param clk_amend 校准信息 */ uint8_t EW_ReadClkAmend(uint16_t addr,uint32_t* clk_amend) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 37; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,uc_readflag); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,5,EW_DMOD_READ_Timeout); if(EW_CommBuf[4] == CheckCRC_8((uint8_t*)EW_CommBuf,4)) { memcpy(clk_amend,(uint8_t*)EW_CommBuf,4); }else{ uc_ack = 1; } return uc_ack; } /* @brief 读配置信息和版本号 @param addr 通信地址 @param clk_amend 校准信息 */ uint8_t EW_ReadRunCfgVersion(uint16_t addr,uint8_t* run_cfg,uint16_t* version) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 38; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,uc_readflag); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,6,EW_DMOD_READ_Timeout); if(EW_CommBuf[5] == CheckCRC_8((uint8_t*)EW_CommBuf,5)) { memcpy(run_cfg,(uint8_t*)EW_CommBuf,3); memcpy(version,(uint8_t*)EW_CommBuf+3,2); }else{ uc_ack = 1; } return uc_ack; } /* @brief 自动分配地址 @param max_addr 分配的最大地址 @param fac_addr 分配因子 */ uint8_t EW_AutoSetAddr(uint16_t max_addr,uint16_t fac_addr) { uint16_t addr = 0; addr<<=6; addr = (addr & 0xFFC0) | 39; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; memcpy((uint8_t*)EW_CommBuf+2,&max_addr,2); memcpy((uint8_t*)EW_CommBuf+4,&max_addr,2); DMod_SendBytes((uint8_t*)EW_CommBuf,6,EW_DMOD_Peroid,0); return 0; } /* @brief 读校准值 @param addr 通信地址 @param UID数据 */ uint8_t EW_ReadUID(uint16_t addr,uint8_t* uid,uint8_t uid_len) { uint8_t uc_readflag = 0; uint8_t uc_ack = 0; if(addr > 0) { uc_readflag = 1; } addr<<=6; addr = (addr & 0xFFC0) | 41; EW_CommBuf[0] = addr&0xFF; EW_CommBuf[1] = (addr >> 8)&0xFF; DMod_SendBytes((uint8_t*)EW_CommBuf,2,EW_DMOD_Peroid,uc_readflag); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,uid_len+1,EW_DMOD_READ_Timeout); if(EW_CommBuf[uid_len] == CheckCRC_8((uint8_t*)EW_CommBuf,uid_len)) { memcpy(uid,(uint8_t*)EW_CommBuf,uid_len); }else{ uc_ack = 1; } return uc_ack; } /**************************EW BootLoader命令*******************************************/ /* @brief 擦除代码空间 @rtv 返回值 0 成功 1 失败 */ uint8_t EWB_EraseCode(void) { uint8_t uc_ack = 0; EW_CommBuf[0] = 0xFE; EW_CommBuf[1] = 0; DMod_SendBytesXor(EW_CommBuf,2,1); delay_ms(50); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,4,EW_DMOD_READ_Timeout<<1); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4) && uc_ack == 0) { uc_ack = 0; }else{ uc_ack = 1; } return uc_ack; } /* @brief 擦除指定空间 @param 起始地址 @param 结束地址 @rtv 返回值 0 成功 1 失败 */ uint8_t EWB_EraseMTP(uint16_t bgaddr,uint16_t endaddr) { uint8_t uc_ack = 0; EW_CommBuf[0] = 0xFD; EW_CommBuf[1] = 4; EW_CommBuf[2] = bgaddr & 0xFF; EW_CommBuf[3] = (bgaddr >> 8) & 0xFF; EW_CommBuf[4] = endaddr & 0xFF; EW_CommBuf[5] = (endaddr >> 8) & 0xFF; DMod_SendBytesXor(EW_CommBuf,6,1); delay_ms(10); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,4,EW_DMOD_READ_Timeout<<1); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4) && uc_ack == 0) { uc_ack = 0; }else{ uc_ack = 1; } return uc_ack; } /* @brief 写数据到MTP,最多128字节 @param 起始地址 @param 写入数据缓存 @param 写入数据长度 @rtv 返回值 0 成功 1 失败 */ uint8_t EWB_WriteMTP(uint16_t bgaddr,const uint8_t* w_buf,uint8_t len) { uint8_t uc_ack = 0; uint8_t* cmd_buf = rt_malloc(len+8); uint32_t w_len = len; if(len > 128) { return 1; } EW_CommBuf[0] = 0xFC; EW_CommBuf[1] = 2+len; EW_CommBuf[2] = bgaddr & 0xFF; EW_CommBuf[3] = (bgaddr >> 8) & 0xFF; memcpy((EW_CommBuf+4),w_buf,len); DMod_SendBytesXor(EW_CommBuf,len+4,1); w_len = len+4; w_len *= 60; w_len /= 1000; delay_ms(5+w_len); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,4,EW_DMOD_READ_Timeout); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4) && uc_ack == 0) { uc_ack = 0; }else{ uc_ack = 1; } return uc_ack; } /* @breif 获取Crc32 @param 起始地址 @param 结束地址 @param *rt_crc32存储区域 @rtv 返回值 0 成功 1 失败 */ uint8_t EWB_CacluCrc32(uint16_t bgaddr,uint16_t endaddr, uint32_t* rt_crc32) { uint8_t uc_ack = 0; EW_CommBuf[0] = 0xFB; EW_CommBuf[1] = 4; EW_CommBuf[2] = bgaddr & 0xFF; EW_CommBuf[3] = (bgaddr >> 8) & 0xFF; EW_CommBuf[4] = endaddr & 0xFF; EW_CommBuf[5] = (endaddr >> 8) & 0xFF; DMod_SendBytesXor(EW_CommBuf,6,1); delay_ms(10); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,8,EW_DMOD_READ_Timeout); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4) && uc_ack == 0) { uc_ack = 0; memcpy(rt_crc32,(uint8_t*)(EW_CommBuf+3),4); }else{ uc_ack = 1; } return uc_ack; } /* @brief 读取MTP数据 @param 起始地址 @param 读取长度 @param *read_buf 读取数据缓存 @rtv 返回值 0 成功 1 失败 */ uint8_t EWB_ReadMTP(uint16_t bgaddr,uint8_t read_len, uint8_t* read_buf) { uint8_t uc_ack = 0; EW_CommBuf[0] = 0xFA; EW_CommBuf[1] = 4; EW_CommBuf[2] = bgaddr & 0xFF; EW_CommBuf[3] = (bgaddr >> 8) & 0xFF; EW_CommBuf[4] = read_len; DMod_SendBytesXor(EW_CommBuf,5,1); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,4+read_len,EW_DMOD_READ_Timeout); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4+read_len) && uc_ack == 0) { uc_ack = 0; memcpy(read_buf,(uint8_t*)(EW_CommBuf+3),read_len); }else{ uc_ack = 1; } return uc_ack; } /* brief 强制跳转用户区 @rtv 返回值 0 成功 1 失败 */ uint8_t EWB_RunApp(void) { uint8_t uc_ack = 0; EW_CommBuf[0] = 0xF9; EW_CommBuf[1] = 0; DMod_SendBytesXor(EW_CommBuf,2,1); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,4,EW_DMOD_READ_Timeout); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4) && uc_ack == 0) { uc_ack = 0; }else{ uc_ack = 1; } return uc_ack; } /* @brief 充放电控制 @param chg_flag 充电控制开关 1 充电 0 放电 @rtv 0 执行成功 1失败 */ uint8_t EWB_ChgCtrl(uint8_t chg_flag) { uint8_t uc_ack = 0; EW_CommBuf[0] = 0xF8; EW_CommBuf[1] = 1; EW_CommBuf[2] = chg_flag; DMod_SendBytesXor(EW_CommBuf,3,1); delay_ms(2); uc_ack = DMod_FireBusReadDatasV2((uint8_t*)EW_CommBuf,4,EW_DMOD_READ_Timeout); if(0 == CheckXOR_8((uint8_t*)EW_CommBuf,4) && uc_ack == 0) { uc_ack = 0; }else{ uc_ack = 1; } return uc_ack; }