Files
checker_slave/source/elec_det/driver/JQDriver.c
2024-01-23 18:13:09 +08:00

654 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "JQDriver.h"
#include "base/delay.h"
#include "hardware/adc_cfg.h"
#include "base/utility.h"
#include "hardware/power.h"
#include "hardware/timer_cfg.h"
#include "hardware/power.h"
volatile static uint16_t jq_idle_current;
#define JQ_IDLE_NOISE 100
#if JQ_Read_AD_Sample_C > FIREBUS_ADC_BUF_LEN
#error "JQDriver.c Firbus AD Sample BUFFER SIZE LIMIT"
#else
volatile uint16_t* JQ_Read_AD_V = FireBus_ADC_Buf;
#endif
volatile static uint16_t jq_ad_last_sample;
static volatile CurrentSample_Range_eu buscurrent_range = Current_Max;
volatile uint16_t JQ_FreeBack_MaxCur;
volatile uint16_t JQ_FreeBack_MaxTime;
volatile uint16_t JQ_FreeBack_MinCur;
volatile uint16_t JQ_FreeBack_MinTime;
volatile uint16_t JQ_CommEnd_MaxCur = 0;
volatile uint8_t JQ_CommEnd_CurEn = 0;
volatile uint16_t JQ_EnFreeBack_Test = 0;
static void JQ_CommBegin()
{
CurrentSampleR_Def;
//WaitDelayEnd(200);//20ms
//delay_ms(20);
delay_wait_untill_ms(20);
}
static void JQ_CommEnd()
{
uint16_t us_temp;
//StartDelayTime();
TimerCount_Off();
delay_wait_start();
if(JQ_CommEnd_CurEn > 0)
{
delay_os_ms(10);
us_temp = ADC_Comm1p6mA_EndCur();
if(us_temp > JQ_CommEnd_MaxCur)
{
JQ_CommEnd_MaxCur = us_temp;
}
}
CurrentSampleR_Def;
}
/*
@brief 采样总线反馈数据
@param sample_count 采样次数
*/
static void JQ_Sample(uint16_t sample_count)
{
uint16_t us_adv = 0;
uint16_t ul_count = 0;
jq_ad_last_sample = GetADC_Fast(ADC_CURR_DE);
for(ul_count = 0;ul_count < sample_count; ul_count++)
{
us_adv = GetADC_Fast(ADC_CURR_DE);
JQ_Read_AD_V[ul_count] = us_adv;
jq_ad_last_sample = us_adv;
}
}
/*
@brief 通信反码信息初始化
*/
void JQ_FreeBack_Prapare(uint8_t enable_flag)
{
JQ_FreeBack_MaxCur = 0;
JQ_FreeBack_MaxTime = 0;
JQ_FreeBack_MinCur = 0xFFFF;
JQ_FreeBack_MinTime = 0xFFFF;
JQ_EnFreeBack_Test = enable_flag;
}
//@brief 采样空闲电流
void JQ_SampleIdleCurrent()
{
uint16_t sample_count;
uint32_t ul_adc_v = 0;
JQBUS_W_1;
delay_ms(1);
JQ_Sample(JQ_Read_AD_Sample_C_IDLE);
Bubble_Sort_u16((uint16_t*)JQ_Read_AD_V,JQ_Read_AD_Sample_C_IDLE);
sample_count = 15;
while(sample_count < 25)
{
ul_adc_v +=JQ_Read_AD_V[sample_count++];
}
jq_idle_current = ul_adc_v/10 + JQ_IDLE_NOISE;
delay_us(200);
JQBUS_W_0
delay_us(2000);
}
/*
@brief 读取1bit数据
@rtv 返回读取结果
*/
uint16_t JQDriver_SAMPLE_Time;
uint8_t JQ_ReadBit(void)
{
uint16_t sample_count = 0;
uint32_t ul_adv_sum = 0;
uint8_t uc_bit = 0;
uint16_t uc_mincur_index = 0;
JQBUS_W_1;
delay_us(150);
Get1usCount();
JQ_Sample(JQ_Read_AD_Sample_C);
JQDriver_SAMPLE_Time = Get1usCount();
JQBUS_W_0;
while(sample_count < JQ_Read_AD_Sample_C)
{
if(JQ_Read_AD_V[sample_count] > jq_idle_current )
{
uc_bit++;
ul_adv_sum += JQ_Read_AD_V[sample_count] ;
}else if(uc_bit < 2)//连续两个大于2启动检测
{
uc_bit = 0;
ul_adv_sum = 0;
}
sample_count++;
}
if(uc_bit > 10)
{
/***************记录反码信息*************************/
ul_adv_sum = ul_adv_sum / uc_bit;
if( JQ_EnFreeBack_Test > 0 )
{
if(JQ_FreeBack_MaxCur == 0)
{
JQ_FreeBack_MaxCur = JQ_FreeBack_MinCur = ul_adv_sum;
}else if(ul_adv_sum > JQ_FreeBack_MaxCur){
JQ_FreeBack_MaxCur = ul_adv_sum;
}else if(ul_adv_sum < JQ_FreeBack_MinCur){
JQ_FreeBack_MinCur = ul_adv_sum;
}
if(JQ_FreeBack_MaxTime == 0)
{
JQ_FreeBack_MaxTime = JQ_FreeBack_MinTime = uc_bit;
}else if(uc_bit > JQ_FreeBack_MaxTime)
{
JQ_FreeBack_MaxTime = uc_bit;
}else if(uc_bit < JQ_FreeBack_MinCur){
JQ_FreeBack_MinTime = uc_bit;
}
}
delay_us(1100);
return 1;
}else{
delay_us(350);
return 0;
}
}
/*
@brief 发送不读反馈信号的命令
@param buf 命令字节缓存区
@param len 缓存区数据长度
*/
void JQ_SendBroadCast(uint8_t* buf,uint16_t len)
{
uint8_t uc_data;
uint8_t uc_bitcount;
JQ_CommBegin();
JQBUS_W_0;
delay_ms(2);
while(len > 0)
{
uc_bitcount = 0;
uc_data = *buf;
while(uc_bitcount < 8){
if((uc_data & 0x80) > 0)
{
JQBUS_W_1;
delay_us(JQBUS_H_PLUS);
JQBUS_W_0;
delay_us(JQBUS_L_PLUS);
}else{
JQBUS_W_1;
delay_us(JQBUS_L_PLUS);
JQBUS_W_0;
delay_us(JQBUS_H_PLUS);
}
uc_bitcount++;
uc_data <<= 1;
}
len--;
buf++;
}
JQBUS_IDLE;
JQ_CommEnd();
}
//@breif 发送读取命令
static void JQ_SendReadCmd(uint8_t* cmd_buf,uint16_t w_len)
{
uint8_t uc_data;
uint8_t uc_bitcount;
JQBUS_W_0;
delay_ms(2);
while(w_len > 0)
{
uc_bitcount = 0;
uc_data = *cmd_buf;
while(uc_bitcount < 8){
if((uc_data & 0x80) > 0)
{
JQBUS_W_1;
delay_us(JQBUS_H_PLUS);
JQBUS_W_0;
delay_us(JQBUS_L_PLUS);
}else{
JQBUS_W_1;
delay_us(JQBUS_L_PLUS);
JQBUS_W_0;
delay_us(JQBUS_H_PLUS);
}
uc_bitcount++;
uc_data <<= 1;
}
w_len--;
cmd_buf++;
}
JQBUS_RWIDLE;
}
/*
@brief 发送待反馈的命令
@param cmd_buf 命令数据缓存区
@param read_buf 数据反馈缓存区
@param w_len 发送缓冲区数据长度
@param r_len =0 读取1bit应答信号 > 0,读取数据长度
@rtv 应答ACK
*/
uint8_t JQ_SendRead(uint8_t* cmd_buf, uint8_t* read_buf,uint16_t w_len,uint16_t r_len)
{
uint8_t uc_data;
uint8_t ack = 0;
uint8_t uc_bitcount;
JQ_CommBegin();
if(w_len > 0)
{
JQ_SendReadCmd(cmd_buf,w_len);
}
Power_SetSampleRange_Seep(JQDriver_Sample_R,ADC_SPEED_HIGH);
JQ_SampleIdleCurrent();
while(r_len > 0)
{
uc_data = 0;
uc_bitcount = 0;
while(uc_bitcount < 8)
{
uc_data <<= 1;
uc_data |= (JQ_ReadBit() & 0x01);
uc_bitcount++;
}
*read_buf = uc_data;
r_len--;
read_buf++;
}
ack = JQ_ReadBit();
JQBUS_IDLE;
Power_SetSampleCurrentRange(Current_Max);
JQ_CommEnd();
return ack;
}
/*
@breif 起爆命令
@param cmd_count 起爆命令发送次数
@param read_buf 读取ACK数据1bit代表一个网络号
@param run_type 0 不读取应答信号 =1 读取应答信号 >1 读取应答信号,且强制反馈收到应答
*/
void JQ_BoomCmd(uint8_t cmd_count,uint8_t* read_buf,uint8_t run_type)
{
static uint8_t JQBoomcmd[2]={0xA9,0xB5};
static uint8_t JQBoomEnCmd[2] = {0x7A,0xB7};
uint16_t us_pluscount = 0;
uint8_t uc_data,uc_bitcount,send_count;
send_count = 0;
while(send_count < cmd_count)
{
JQ_SendBroadCast(JQBoomEnCmd,2);
delay_os_ms(20);
send_count++;
}
if(run_type == 0)
{
while(cmd_count > 0)
{
//JQ_SendBroadCast(JQBoomcmd,2);
delay_os_ms(20);
JQ_SendRead(JQBoomcmd,&uc_data,2,0);
cmd_count--;
}
us_pluscount = 0;
while(us_pluscount < 680)
{
JQBUS_W_1
delay_us(1000);
JQBUS_W_0
delay_us(400);
us_pluscount++;
}
}else{
while(cmd_count > 0)
{
delay_os_ms(20);
JQ_SendRead(JQBoomcmd,&uc_data,2,0);
cmd_count--;
}
Power_SetSampleRange_Seep(JQDriver_Sample_R,ADC_SPEED_HIGH);
JQ_SampleIdleCurrent();
while(us_pluscount < 680)
{
uc_data = 0;
uc_bitcount = 0;
while(uc_bitcount < 8)
{
uc_data <<= 1;
uc_data |= (JQ_ReadBit() & 0x01);
if((run_type > 1) && (uc_data& 0x01) < 1)
{
delay_us(750);
}
uc_bitcount++;
us_pluscount++;
}
*read_buf = uc_data;
read_buf++;
}
}
Power_SetSampleCurrentRange(Current_Max);
JQBUS_IDLE;
JQ_CommEnd();
}
/*
@breif 起爆使能
*/
void JQ_CheckerEnBoomCmd()
{
static uint8_t JQBoomEnCmd[2] = {0x7A,0xB7};
JQ_SendBroadCast(JQBoomEnCmd,2);
}
/*
@breif 起爆命令
@param plus_count 巡检脉冲个数
@rtv 巡检应答Ack 的脉冲个数
*/
uint16_t JQ_CheckerBoomCmd(uint16_t plus_count,uint16_t* us_shake)
{
static uint8_t JQBoomcmd[2]={0xA9,0xB5};
uint16_t us_pluscount = 0;
uint16_t us_ack_plus = 0;
uint16_t sample_count = 0;
uint16_t us_bitcount = 0;
uint16_t us_temp_shake;
uint16_t us_max,us_min;
JQ_CheckerEnBoomCmd();
delay_ms(20);
JQ_SendBroadCast(JQBoomcmd,2);
Power_SetSampleRange_Seep(JQDriver_Sample_R,ADC_SPEED_HIGH);
JQ_SampleIdleCurrent();
*us_shake = JQ_Read_AD_V[JQ_Read_AD_Sample_C_IDLE-2] - JQ_Read_AD_V[2];
while(us_pluscount < plus_count)
{
JQBUS_W_1;
delay_us(100);
//700us 延时
JQ_Sample(JQ_Read_AD_Sample_C);
GetMaxAndMinValue((uint16_t*)JQ_Read_AD_V,JQ_Read_AD_Sample_C,&us_max,&us_min);
us_min = us_max - us_min;
JQBUS_W_0;
sample_count = 0;
while(sample_count < JQ_Read_AD_Sample_C)
{
if(JQ_Read_AD_V[sample_count] > jq_idle_current )
{
us_bitcount++;
}else if(us_bitcount < 2)
{
us_bitcount = 0;
}
sample_count++;
}
if(us_bitcount > 6)
{
if(us_ack_plus == 0)
{
us_ack_plus = us_pluscount;
}
else{
us_ack_plus = ~0;
}
delay_us(50);
us_bitcount = 3;
}else{
if(us_min > *us_shake)
{
*us_shake = us_min;
}
delay_us(100);
us_bitcount = 3;
}
while(us_bitcount > 0)
{
JQ_Sample(JQ_Read_AD_Sample_C>>1);
GetMaxAndMinValue((uint16_t*)JQ_Read_AD_V,JQ_Read_AD_Sample_C>>1,&us_max,&us_min);
us_min = us_max - us_min;
if(us_min > *us_shake)
{
*us_shake = us_min;
}
us_bitcount--;
}
us_pluscount++;
}
JQBUS_IDLE;
JQ_CommEnd();
return us_ack_plus;
}
static uint16_t amend_endflag = 0;
//@brief 总线波形翻转
void JQ_TriggerPlus(uint8_t flag)
{
if(flag == 1)
{
JQBUS_W_0;
}else if(flag > 1){
JQBUS_W_1;
}
amend_endflag = flag;
}
//@brief 时钟校准
void JQ_TimeAmend(uint16_t cycle,uint16_t delayMs)
{
static uint8_t cmd_buf = 0x34;
JQ_SendBroadCast(&cmd_buf,1);
delay_os_ms(2);
FireBus_ClkAmend(cycle, cycle/2, delayMs+100,JQ_TriggerPlus);
while(amend_endflag != 3)
{
delay_ms(10);
}
JQBUS_IDLE;
delay_os_ms(20);
}
//@breif 巡检
void JQ_Inspect(uint16_t maxcount,uint8_t* buf,uint8_t state)
{
static uint8_t cmd_buf[]={0x97,0x00,0x00,0x00};
cmd_buf[3] = state;
JQ_SendRead(cmd_buf,buf,4,(maxcount+7)/8);
}
//@brief 启动UID扫描
void JQ_ScanUIDBegin()
{
static uint8_t start_readuid_cmd = 0x54;
JQ_SendBroadCast(&start_readuid_cmd,1);
}
//@brief 扫描模式读取UID
uint8_t JQ_ScanReadUID(uint16_t begnet,uint8_t* uidbuf)
{
static uint8_t scan_uid_cmd[]={0x59,0x00,0x00};
uint8_t time_out = 3;
uint8_t*p_buf = uidbuf;
uint8_t ack;
rt_memset(p_buf,0,8);
while(time_out > 0)
{
scan_uid_cmd[1] = (begnet >> 8);
scan_uid_cmd[2] = begnet,
ack = JQ_SendRead(scan_uid_cmd,p_buf,3,8);
if(ack > 0)
{
return ack;
}else{
delay_os_ms(20);
time_out--;
}
}
return 0;
}
//@brief 读延时
uint8_t JQ_ReadDelay(uint16_t netid,uint16_t* delaybuf)
{
static uint8_t cmd_buf[3]={0x63,0x00,0x00};
cmd_buf[1] = (netid >> 8);
cmd_buf[2] = netid;
return JQ_SendRead(cmd_buf,(uint8_t*)delaybuf,3,2);
}
//@brief 写延时
void JQ_WriteDelay(uint16_t netid,uint16_t delay)
{
static uint8_t cmd_buf[5]={0x68};
cmd_buf[1] = (netid >> 8);
cmd_buf[2] = netid;
cmd_buf[3] = (delay >> 8);
cmd_buf[4] = delay;
JQ_SendBroadCast(cmd_buf,5);
}
//@brief 验证密码
void JQ_VerifyPWD(uint8_t* pwd)
{
static uint8_t cmd_buf[5] = {0x76};
rt_memcpy(&cmd_buf[1],pwd,4);
JQ_SendBroadCast(cmd_buf,5);
}
//@brief 使能起爆
void JQ_BoomActive(void)
{
static uint8_t cmd_buf[] = {0x7A,0xB7};
JQ_SendBroadCast(cmd_buf,2);
}
//@brief 设置充电检测判线
void JQ_ChargJudge(uint8_t dac)
{
static uint8_t cmd_buf[] = {0x82,0x00};
cmd_buf[1] = dac;
JQ_SendBroadCast(cmd_buf,2);
}
//@brief 充电
void JQ_Chage(uint16_t bgnet)
{
static uint8_t cmd_buf[3] = {0x89};
cmd_buf[1] = bgnet>>8;
cmd_buf[2] = bgnet;
JQ_SendBroadCast(cmd_buf,3);
}
//@brief 放电
void JQ_DisChage(void)
{
static uint8_t cmd_buf[1] = {0x8A};
JQ_SendBroadCast(cmd_buf,1);
}
//@brief 快速放电
void JQ_FastDisChage(uint8_t sw)
{
static uint8_t cmd_buf[2] = {0x8B};
cmd_buf[1] = sw;
JQ_SendBroadCast(cmd_buf,2);
}
//@brief 检桥丝
void JQ_BridgeWire(void)
{
static uint8_t cmd_buf[1] = {0x8E};
JQ_SendBroadCast(cmd_buf,1);
}
//@brief 复位
void JQ_Reset(void)
{
static uint8_t cmd_buf[2] = {0x55,0xAA};
JQ_SendBroadCast(cmd_buf,2);
}
//@breif 读芯片ID
uint8_t JQ_ReadChipID(uint16_t netid,uint16_t* chipid)
{
static uint8_t cmd_buf[3] = {0x23};
cmd_buf[1] = netid>>8;
cmd_buf[2] = netid;
return JQ_SendRead(cmd_buf,(uint8_t*)chipid,3,2);
}
//@brief 读OTP
uint8_t JQ_ReadOTP(uint16_t netid,uint8_t otp_bgaddr,uint8_t read_count,uint8_t* readbuf)
{
static uint8_t cmd_buf[4] = {0x2A};
uint8_t otp_endaddr = otp_bgaddr+ read_count;
cmd_buf[1] = netid>>8;
cmd_buf[2] = netid;
cmd_buf[3] = otp_bgaddr;
while(otp_bgaddr < otp_endaddr)
{
cmd_buf[3] = otp_bgaddr;
if(JQ_SendRead(cmd_buf,readbuf,4,1) == 0)
{
break;
}
delay_os_ms(20);
readbuf++;
otp_bgaddr++;
}
return read_count - (otp_endaddr - otp_bgaddr);
}
//@brief 写OTP
uint8_t JQ_WriteOTP(uint8_t otp_bgaddr,uint8_t write_count,uint8_t* writebuf)
{
static uint8_t cmd_buf[3] = {0x1A};
uint8_t otp_endaddr = otp_bgaddr+ write_count;
while(otp_bgaddr < otp_endaddr)
{
cmd_buf[1] = otp_bgaddr;
cmd_buf[2] = *writebuf;
JQ_SendBroadCast(cmd_buf,3);
delay_os_ms(20);
writebuf++;
otp_bgaddr++;
}
return write_count - (otp_endaddr - otp_bgaddr);
}
//写OTP使能
void JQ_EnWOTP(void)
{
static uint8_t cmd_buf[2] = {0x1E,0xC9};
JQ_SendBroadCast(cmd_buf,2);
}
//@breif 读取单发状态
uint8_t JQ_ReadState(uint16_t netid,uint8_t* state)
{
static uint8_t cmd_buf[3] = {0x91};
cmd_buf[1] = netid>>8;
cmd_buf[2] = netid;
return JQ_SendRead(cmd_buf,state,3,1);
}
//@braief 设置通信电压模式
uint8_t JQ_SetPowerMode(uint16_t h_vol,uint16_t m_vol)
{
return 0;
}