| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474 |
- /******************************************************************************
- 版权所有:
- 文件名称: dido.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2013-02-28
- 功能说明: 开入开出
- 其它说明:
- // 启动继电器
- 1、启动继电器可以重复多次启动,每次启动都将重新计算超时时间。
- 2、启动继电器有2种关闭方式:
- 1) 超时自动关闭,超时时间为装置参数的遥控超时时间。
- 2) 通过函数调用关闭。
- 3、有保护启动标志时,选择继电器不允许关闭。
- 4、需提供启动继电器的超时设置函数.
- 5、只所以采用超时自动关闭,是因为以前的程序关闭方式存在问题,可能由于资源竞争的关系,
- 导致不该关闭时却关闭了,虽然概率很小,但理论上存在。
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "head.h"
- #ifdef GW_AREA_MAIN_2021
- /*------------------------------- 宏定义 --------------------------------------
- */
- /*------------------------------ 类型结构 -------------------------------------
- */
- /*------------------------------ 全局变量 -------------------------------------
- */
- struct di g_di[EQU_SLOT_NUM_MAX];
- struct _do g_do[EQU_SLOT_NUM_MAX];
- struct di_struct g_di_st[EQU_SLOT_NUM_MAX][DIDO_MAX_DI_PER_SLOT*2];
- int g_do_flag;
- struct rt_stat g_stat_di_delay;
- struct rt_stat g_stat_do_delay;
- static u32 di_error_count = 0;
- static u32 di_change_num = 0;
- static u32 error_count = 0;
- struct do_time g_do_time[EQU_SLOT_NUM_MAX];
- /*------------------------------ 函数声明 -------------------------------------
- */
- int dido_do_time(void);
- /*------------------------------ 外部函数 -------------------------------------
- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
- */
- int dido_init(void)
- {
- int i;
- memset(g_di,0,sizeof(g_di));
- memset(g_do,0,sizeof(g_do));
- memset(g_do_time,0,sizeof(g_do_time));
-
- // 检查装置配置
- if(equ_config_null())
- {
- return -1;
- }
- // 初始化取反标志
- for(i=0; i< g_equ_config->di_num; i++)
- {
- if(g_equ_config_di[i].is_Inverse == 0)
- {
- continue;
- }
- if(g_equ_config_di[i].slot < EQU_SLOT_NUM_MAX && g_equ_config_di[i].index < DIDO_MAX_DI_PER_SLOT)
- {
- if(g_equ_config_di[i].index < 32)
- {
- g_di[g_equ_config_di[i].slot].inv[0] |= 1<<g_equ_config_di[i].index;
- }
- else if(g_equ_config_di[i].index < 64)
- {
- g_di[g_equ_config_di[i].slot].inv[1] |= 1<<(g_equ_config_di[i].index - 32);
- }
- else
- {
- g_di[g_equ_config_di[i].slot].inv[2] |= 1<<(g_equ_config_di[i].index - 64);
- }
- }
- }
-
- dido_stat_reset();
-
- return 0;
- }
- int dido_di_is_on(u8 slot,u8 index)
- {
- // DTUv5 开入扩展板采集66个遥信
- if(slot >= EQU_SLOT_NUM_MAX || index >= 66)
- {
- return 0;
- }
- if(index < 32)
- {
- if(g_di[slot].value[0]&(1<<index))
- {
- return 1;
- }
- }
- else if(index < 64)
- {
- index -= 32;
- if(g_di[slot].value[1]&(1<<index))
- {
- return 1;
- }
- }
- else
- {
- index -= 64;
- if(g_di[slot].value[2]&(1<<index))
- {
- return 1;
- }
- }
- return 0;
- }
- // 查看某个时间点下的开入值
- int dido_di_is_on_ts(u8 slot,u8 index,u32 ts)
- {
- int i,r;
- struct ts_index ts_i;
- // DTUv5 开入扩展板采集66个遥信
- if(slot >= EQU_SLOT_NUM_MAX || index >= 66)
- {
- return 0;
- }
- #if 0
- {
- static int cnt = 0;
- if(cnt++ < 16)
- rt_printf("slot=%d,index=%d,ts=%d.\r\n",slot,index,ts);
- }
- #endif
- ts_i.n = g_di[slot].ts_i[index].n - 1; //ts_i下是无值的,所以应该减1
- for(i=0;i<DIDO_TS_NUM;i++)
- {
- r = (int)(ts - g_di[slot].ts_t[index][ts_i.n]);
- if(r >= 0)
- {
- return g_di[slot].ts_v[index][ts_i.n];
- }
- ts_i.n--;
- }
- if(index < 32)
- {
- if(g_di[slot].value[0]&(1<<index))
- {
- return 1;
- }
- }
- else if (index < 64)
- {
- index -= 32;
- if(g_di[slot].value[1]&(1<<index))
- {
- return 1;
- }
- }
- else
- {
- index -= 64;
- if(g_di[slot].value[2]&(1<<index))
- {
- return 1;
- }
- }
- return 0;
- }
- int dido_di_update(u8 * buf)
- {
- struct can_frame_head *cfh;
- struct timespec ts,ts_rec;
- u32 di,value_new,value_old;
- int i,j,is_on;
- unsigned long flags;
- u32 dt;
- // static bool bDI_Init[EQU_SLOT_NUM_MAX] = {false};
-
- // 检查帧内容
- cfh = (struct can_frame_head *)buf;
- if(cfh->src >= EQU_SLOT_NUM_MAX)
- {
- return -1;
- }
- if(cfh->len != 8)
- {
- return -2;
- }
- // 检查帧类型
- switch(buf[0])
- {
- case CAN_FRAME_TYPE_DI_INIT:
- case CAN_FRAME_TYPE_DI_ON:
- case CAN_FRAME_TYPE_DI_OFF:
- j = 0;
- break;
- case CAN_FRAME_TYPE_DI_INIT1:
- case CAN_FRAME_TYPE_DI_ON1:
- case CAN_FRAME_TYPE_DI_OFF1:
- j = 1;
- break;
- case CAN_FRAME_TYPE_DI_INIT2:
- case CAN_FRAME_TYPE_DI_ON2:
- case CAN_FRAME_TYPE_DI_OFF2:
- j = 2;
- break;
- default:
- return -3;
- }
- // 获取数据
- memcpy(&di,buf+4,4);
- switch(buf[0])
- {
- case CAN_FRAME_TYPE_DI_INIT:
- case CAN_FRAME_TYPE_DI_INIT1:
- case CAN_FRAME_TYPE_DI_INIT2:
- {
- //g_di[cfh->src].value[j] = di^g_di[cfh->src].inv[j];
- value_old = g_di[cfh->src].value[j];
- value_new = di^g_di[cfh->src].inv[j];
- di = value_old ^ value_new; // 得到有变化的位
- g_di[cfh->src].value[j] = value_new;
- // rt_printf("DI_INIT:src=%d,j=%d,di=%08x,oldv=%08x,newv=%08x.\r\n",cfh->src,j,di,value_old,value_new);
- if(g_di[cfh->src].bInited[j] == 0)
- {
- // 更新逻辑模型中的值
- for(i=0;i<DIDO_MAX_DI_PER_SLOT;i++)
- {
- is_on = (g_di[cfh->src].value[j]&(1<<i)) ? 1 : 0;
- sw_di_set( g_di_st[cfh->src][(j<<5)+i].owner,
- g_di_st[cfh->src][(j<<5)+i].type,
- is_on ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
- // 双点的值也需要重新初始化
- plc_db_init_value(cfh->src,(j<<5)+i,is_on);
- // 遥信时标
- g_di[cfh->src].ts_t[i][g_di[cfh->src].ts_i[i].n] = 0;
- g_di[cfh->src].ts_v[i][g_di[cfh->src].ts_i[i].n] = is_on;
- g_di[cfh->src].ts_i[i].n++;
- }
- g_di[cfh->src].bInited[j] = true;
- // bDI_Init[cfh->src] = true;
- return 0;
- }
- }
- break;
- case CAN_FRAME_TYPE_DI_ON:
- case CAN_FRAME_TYPE_DI_ON1:
- case CAN_FRAME_TYPE_DI_ON2:
- value_old = g_di[cfh->src].value[j] & (~di);
- value_new = (di^g_di[cfh->src].inv[j]) & di;
- g_di[cfh->src].value[j] = value_old | value_new;
- break;
- case CAN_FRAME_TYPE_DI_OFF:
- case CAN_FRAME_TYPE_DI_OFF1:
- case CAN_FRAME_TYPE_DI_OFF2:
- value_old = g_di[cfh->src].value[j] & (~di);
- value_new = ((~di)^g_di[cfh->src].inv[j]) & di;
- g_di[cfh->src].value[j] = value_old | value_new;
- break;
- default:
- return -3;
- }
- // 得到当前时刻,通过关中断保证时间的一致性
- rt_irq_save(flags);
- // gps_get_time(&ts); //modify by EWen can app 对时用的是clk_time_get,此处记录di时间取同一时间源
- clk_time_get(&ts);
- dt=g_adc_dots_count;
- rt_irq_restore(flags);
- // 计算变位的真正时刻
- // 记录秒的低8位和纳秒的高24位合成32位时间戳放在buf[8]~buf[11]的位置。
- // 因为开入滤波时间最长为65.536S,所以用秒的低8位(256S)
- // 作为时间戳有足够的余量保证时间戳的正确性,但需要考虑秒的进位。
-
- ts_rec.tv_sec = (ts.tv_sec & ~0xff) | buf[8];
- ts_rec.tv_nsec=(buf[9]<<24) | (buf[10]<<16) | (buf[11]<<8);
- if((u8)(ts.tv_sec & 0xff) < buf[8])
- {
- // 如果当前时刻秒的低8位小于记录时刻的低8位,说明当前秒的低8位
- // 已进位,记录秒需去掉此进位。
- ts_rec.tv_sec -= 0x100;
- }
- {
- u32 diff;
- diff = ts.tv_nsec + (ts.tv_sec - ts_rec.tv_sec)*NSEC_PER_SEC;
- diff -= ts_rec.tv_nsec;
- // 修正对应采样时间点
- dt -= (u32)rt_round(g_freq*CFG_ADC_DOTS_PER_PERIOD*diff/NSEC_PER_SEC);
-
- rt_stat_in(&g_stat_di_delay,diff);
- /*
- di_change_num ++;
- rt_printf("开入变位:src=%d,buf[0]=%02x,DI==0x%08x,new=0x%08x,T=%d,di_change_num=%d.\r\n",
- cfh->src,
- buf[0],
- g_di[cfh->src].value,
- di,
- diff,
- di_change_num);
- */
- #if 0
- if(diff > 1000000)
- {
- struct rtc_time_t tm;
- di_error_count ++;
-
- rt_printf("开入变位时间超出次数:%d\r\n\r\n",di_error_count);
- timespec_to_rtc(ts,&tm,0);
- rt_printf("当前时间: %04d-%02d-%02d %02d:%02d:%02d:%09d!\r\n",
- tm.year + 2000,
- tm.month,
- tm.day,
- tm.hour,
- tm.min,
- tm.ms/1000,
- ts.tv_nsec
- );
-
- timespec_to_rtc(ts_rec,&tm,0);
- rt_printf("变位时间: %04d-%02d-%02d %02d:%02d:%02d:%09d!\r\n",
- tm.year + 2000,
- tm.month,
- tm.day,
- tm.hour,
- tm.min,
- tm.ms/1000,
- ts_rec.tv_nsec
- );
- }
- #endif
- }
- // if (bDI_Init[cfh->src])
- // {
- // bDI_Init[cfh->src] = false;
- // }
- // else
- {
- // 记录遥信变位
- for(i=0; i<32; i++)
- {
- if(di&(0x01<<i))
- {
- // 记录SOE
- is_on = (g_di[cfh->src].value[j] & (1<<i)) ? 1:0;
- soe_record_yx((WORD)((j<<5) + i +(cfh->src<<8)),is_on,&ts_rec);
- // 更新逻辑模型中的值
- sw_di_set( g_di_st[cfh->src][(j<<5)+i].owner,
- g_di_st[cfh->src][(j<<5)+i].type,
- (is_on)? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
- // 更新记录
- g_di[cfh->src].ts_t[i][g_di[cfh->src].ts_i[i].n] = dt;
- g_di[cfh->src].ts_v[i][g_di[cfh->src].ts_i[i].n] = is_on;
- g_di[cfh->src].ts_i[i].n++;
- }
- }
- }
-
- return 0;
- }
- void dido_qd_set_keeptime(u32 us)
- {
- }
- int dido_do_have_select(u32 slot,u32 index)
- {
- // 只有开出板有选择继电器,其它板如辅助板没有
- if(g_board_info[slot].type == BOARD_TYPE_DO || g_board_info[slot].type == BOARD_TYPE_DO_2)
- {
- return 1;
- }
- return 0;
- }
- int dido_do(u32 slot,u32 v,int is_on)
- {
- unsigned long flags;
-
- //检查子板是否正常
- if(equ_slot_check(slot) != 0)
- {
- return -1;
- }
- // 检查DO资源
- if(equ_get_do_num(slot) == 0)
- {
- return -2;
- }
- // 保存输出值,在5ms中断中输出
- rt_irq_save(flags);
- g_do_flag = 1;
- if(is_on)
- {
- g_do[slot].on |= v;
- }
- else
- {
- g_do[slot].off |= v;
- }
- rt_irq_restore(flags);
- return 0;
- }
- int _dido_do(u32 slot,u32 v,int is_on)
- {
- int i,ret,err;
- u8 *buf;
- u32 do_time;
- struct timespec ts;
-
- // 帧头
- buf = can_request_tx_buf(CAN_FRAME_TYPE_DO_ON);
- if(is_on)
- {
- buf[0] = CAN_FRAME_TYPE_DO_ON;
- }
- else
- {
- buf[0] = CAN_FRAME_TYPE_DO_OFF;
- }
- buf[1] = slot;
- buf[2] = 0;
- buf[3] = 8;
- // 开出值
- buf[4] = (v>>24) & 0xff;
- buf[5] = (v>>16) & 0xff;
- buf[6] = (v>> 8) & 0xff;
- buf[7] = (v>> 0) & 0xff;
-
- // 开出时间
- clk_time_get(&ts);
- do_time = (u32)(((ts.tv_sec&0xff)<<24) | (ts.tv_nsec>>8));
- buf[8] = (unsigned char)(do_time>>24);
- buf[9] = (unsigned char)(do_time>>16);
- buf[10] = (unsigned char)(do_time>>8);
- buf[11] = (unsigned char)(do_time);
- // 开出帧发送,为了提高可靠性,连发2帧
- err = 0;
- for(i=0; i<2; i++)
- {
- ret = can_send(equ_slot_can_bus(slot),buf);
- if(ret < 0)
- {
- rt_printf("dido_do err:i=%d,ret=%d\r\n",i,ret);
- err++;
- }
- }
-
- return -err;
- }
- void dido_do_poll(void)
- {
- int i;
- // 检查开出标志
- if(g_do_flag == 0)
- {
- return;
- }
- g_do_flag = 0;
- // 真正开出
- for(i=0; i<EQU_SLOT_NUM_MAX; i++)
- {
- if(g_do[i].on)
- {
- _dido_do(i,g_do[i].on,1);
- g_do[i].on = 0;
- }
- if(g_do[i].off)
- {
- _dido_do(i,g_do[i].off,0);
- g_do[i].off = 0;
- }
- }
- return;
- }
- /*------------------------------ 内部函数 -------------------------------------
- 内部函数以下划线‘_’开头,不需要检查参数的合法性.
- */
- /*------------------------------ 测试函数 -------------------------------------
- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
- 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
- */
- int dido_printf(void)
- {
- int i,slot,index;
- struct ts_index ts_i;
-
- rt_printf("槽号\t值\r\n");
- for(i=0; i<EQU_SLOT_NUM_MAX; i++)
- {
- rt_printf("%02d:\tvalue=0x%08x_%08x,inv=0x%08x_%08x\r\n",i,g_di[i].value[1],g_di[i].value[0],g_di[i].inv[1],g_di[i].inv[0]);
- }
- rt_printf("\r\n");
- slot = 3;
- index = 2;
- ts_i.n = g_di[slot].ts_i[index].n;
- rt_printf("开入时间戳记录:slot=%d,index=%d,ts_i=%d.\r\n",slot,index,ts_i.n);
- rt_printf("序号\t值\t时间戳\r\n");
- ts_i.n = 0;
- for(i=0;i<DIDO_TS_NUM;i++)
- {
- rt_printf("%02d\t%d\t%08d\r\n",ts_i.n,g_di[slot].ts_v[index][ts_i.n],g_di[slot].ts_t[index][ts_i.n]);
- ts_i.n++;
- }
- rt_stat_printf(&g_stat_di_delay);
- rt_stat_printf(&g_stat_do_delay);
- #if 0
- {
- char tmpbuf[7];
- tmpbuf[0] = 1;
- tmpbuf[1] = 4;
- dido_auto_test(tmpbuf,1);
- }
- #endif
- return 0;
- }
- int dido_stat_reset(void)
- {
- rt_stat_init(&g_stat_di_delay,"di_delay");
- rt_stat_init(&g_stat_do_delay,"do_delay");
- return 0 ;
- }
- int dido_led_test(void)
- {
- #if 0
- int i;
- // 测试告警灯
- for(i=0; i<SWITCH_NUM_MAX; i++)
- {
- dido_led(1<<i);
- ustimer_delay(200*USTIMER_MS);
- dido_led(~(1<<i));
- }
-
- // 所有LED ON
- dido_led(0xffff);
- ustimer_delay(1*USTIMER_SEC);
- // 所有LED OFF
- dido_led(0xffff);
- #endif
- return 0;
- }
- int dido_single_test(u8 slot, u8 point)
- {
- int do_num;
-
- do_num = equ_get_do_num(slot);
- if(do_num == 0)
- {
- return 0;
- }
-
- switch (point/4)
- {
- case 0:
- dido_do(slot,(1<<do_num),1);
- break;
- case 1:
- dido_do(slot,(1<<(do_num+1)),1);
- break;
- case 2:
- dido_do(slot,(1<<(do_num+2)),1);
- break;
- case 3:
- dido_do(slot,(1<<(do_num+3)),1);
- break;
- case 4:
- dido_do(slot,(1<<(do_num+4)),1);
- break;
- case 5:
- dido_do(slot,(1<<(do_num+5)),1);
- break;
-
- default:
- break;
- }
- dido_do(slot,(1<<point),1);
- // ustimer_delay(100*USTIMER_MS);
- // dido_do(slot,(1<<point),0);
- return 0;
- }
- int dido_test(void)
- {
- static unsigned long us0 = 0;
- static char dido_test_pair[3][2] =
- {
- {1,3},
- {2,4},
- {5,5},
- };
- static char dido_test_di[32] =
- {
- 0,1,2,3,
- 0,1,2,3,
- 4,5,6,7,
- 4,5,6,7,
- 8,9,10,11,
- 8,9,10,11,
- 12,13,10,11,
- 12,13,12,13
- };
-
- int i,j,k,err_once,di_num;
- u32 slot_di,slot_do;
- if(g_test_on == 0)
- {
- return 0;
- }
- // 5秒处理一次
- if(ustimer_delay_origin2(&us0,10*USTIMER_SEC) != 1)
- {
- return 0;
- }
-
- rt_printf("dido_test begin...\r\n");
- #if 0
- // 所有开出ON
- rt_printf("dido_test all on.\r\n");
- dido_do(1,0xffff,1);
- dido_do(2,0xffff,1);
- dido_do(5,0xffff,1);
- dido_led(0xffff);
- // 检查所有开入
- ustimer_delay(1*USTIMER_SEC);
- // 所有开出OFF
- rt_printf("dido_test all off.\r\n");
- dido_do(1,0xffff,0);
- dido_do(2,0xffff,0);
- dido_do(5,0xffff,0);
- dido_led(0);
- #endif
- ustimer_delay(1*USTIMER_SEC);
- #if 1
- // 测试开出板、开入板
- // 开出板逐一开出
- rt_printf("dido_test single.\r\n");
- err_once = 0;
- for(i=0; i<3; i++)
- {
- slot_do = dido_test_pair[i][0];
- slot_di = dido_test_pair[i][1];
- if(equ_slot_check(slot_do)!= 0 || equ_slot_check(slot_di) != 0)
- {
- rt_printf("dido_test:board error:slot_do=%d,slot_in=%d\r\n",slot_do,slot_di);
- continue;
- }
- if(g_board_info[slot_do].status != BOARD_STATUS_NORMAL ||g_board_info[slot_di].status != BOARD_STATUS_NORMAL)
- {
- rt_printf("dido_test:board status error:slot_do=%d,slot_in=%d\r\n",slot_do,slot_di);
- continue;
- }
- for(j=0;j<equ_get_do_num(slot_do); j++)
- {
- dido_do(slot_do,(1<<j),1);
- // rt_printf("dido_test:开出:j=%d\r\n",j);
- ustimer_delay(250*USTIMER_MS);
-
- di_num = equ_get_di_num(slot_di);
- if(slot_di == equ_get_slot_by_type(BOARD_TYPE_AUX))
- {
- di_num -= 1;
- }
- for(k=0;k<di_num; k++)
- {
- // 是否对应的开出点
- if(dido_test_di[k] == j)
- {
- if((g_di[slot_di].value[0] & (1<<k)) == 0)
- {
- err_once++;
- error_count++;
- rt_printf("dido_test on err(err=%d):i=%d,j=%d,k=%d,di=0x%08x.\r\n",err_once,i,j,k,g_di[slot_di].value[0]);
- }
- }
- else
- {
- if((g_di[slot_di].value[0] & (1<<k)) != 0)
- {
- err_once++;
- error_count++;
- rt_printf("dido_test off err(err=%d):i=%d,j=%d,k=%d,di=0x%08x.\r\n",err_once,i,j,k,g_di[slot_di].value[0]);
- }
- }
- }
-
- dido_do(slot_do,(1<<j),0);
- ustimer_delay(20*USTIMER_MS);
- watchdog_feed_mainloop();
- }
- }
- #endif
- #if 0
- // 测试告警灯
- for(i=0; i<SWITCH_NUM_MAX; i++)
- {
- dido_led(1<<i);
- ustimer_delay(200*USTIMER_MS);
- }
-
- // 所有开出ON
- dido_do(1,0xffff,1);
- dido_do(2,0xffff,1);
- dido_do(5,0xffff,1);
- dido_led(0xffff);
- ustimer_delay(1*USTIMER_SEC);
- // 所有开出OFF
- dido_do(1,0xffff,0);
- dido_do(2,0xffff,0);
- dido_do(5,0xffff,0);
- dido_led(0);
- #endif
- rt_printf("\r\n开入变位时间超出次数:%d\r\n",di_error_count);
- rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\n");
- rt_stat_printf(&g_stat_di_delay);
- can_app_sb_monitor();
- rt_printf("\r\n");
- for(i=0;i<5;i++)
- {
- if(g_do_time[i].slot != 0)
- {
- rt_printf("do_time[%d]:diff_max=%d,diff_out_count=%d\r\n",g_do_time[i].slot,g_do_time[i].diff_max,g_do_time[i].diff_out_count);
- }
- }
- rt_printf("\r\n");
- rt_printf("dido_test end:err_once=%d,error_count=%d!\r\n\r\n\r\n",err_once,error_count);
- return 0;
- }
- int dido_auto_test(char *buf,int num)
- {
- static char test_do[16][4] =
- {
- {1,5,0,0,},
- {2,6,0,0,},
- {3,7,0,0,},
- {4,8,0,0,},
- {9,13,0,0,},
- {10,14,0,0,},
- {11,15,0,0,},
- {12,16,0,0,},
- {17,21,0,0,},
- {18,22,0,0,},
- {19,23,0,0,},
- {20,24,0,0,},
- {25,29,0,0,},
- {26,30,0,0,},
- {27,0,0,0,},
- {28,0,0,0,},
- };
-
- int i,j,k,err_once,flag,flag1,di_num, do_num;
- u32 slot_di,slot_do;
- u8 tmp[5],tmp_data[5];
- u8 bd_di60=0;
- u8 di_ok[4] = {0};
- u8 do_errflag = 0;
-
- char dido_test_pair[num][2];
- unsigned long us_begin = 0;
- dido_stat_reset();
-
- for(i=0;i<(num*2);)
- {
- for(j=0;j<2;j++)
- {
- dido_test_pair[i/2][j] = buf[i];
- i++;
- }
- }
-
- flag = 0;
- flag1 = 0;
- memset(tmp,0,sizeof(tmp));
- memset(tmp_data,0,sizeof(tmp_data));
- memset(dido_buf,0,sizeof(dido_buf));
-
- rt_printf("dido_test begin...\r\n");
- err_once = 0;
- for(i=0; i<num; i++)
- {
- slot_do = dido_test_pair[i][0];
- slot_di = dido_test_pair[i][1];
-
- if(equ_slot_check(slot_do)!= 0 || equ_slot_check(slot_di) != 0 || slot_di == equ_get_slot_by_type(BOARD_TYPE_AUX))
- {
- rt_printf("dido_test:board error:slot_do=%d,slot_in=%d\r\n",slot_do,slot_di);
- dido_buf[i+i*13] = 0;
- dido_buf[i+i*13+5] = 0;
- continue;
- }
- if(g_board_info[slot_do].status != BOARD_STATUS_NORMAL ||g_board_info[slot_di].status != BOARD_STATUS_NORMAL)
- {
- rt_printf("dido_test:board status error:slot_do=%d,slot_in=%d\r\n",slot_do,slot_di);
- dido_buf[i+i*13] = 0;
- dido_buf[i+i*13+5] = 0;
- continue;
- }
- dido_buf[i+i*13] = slot_do;
- dido_buf[i+i*13+5] = slot_di;
- if(slot_di == equ_get_slot_by_type(BOARD_TYPE_DI60))
- {
- bd_di60 = 1;
- }
- di_num = equ_get_di_num(slot_di);
- do_num = equ_get_do_num(slot_do);
- us_begin = ustimer_get_origin();
- //以循环保证不论开出所配置的脉宽是多少,都能保持2s输出
- while(1)
- {
- // 点亮所有遥信灯
- for(j=0; j<do_num; j++)
- {
- dido_do(slot_do,(1<<j),1);
- }
- // 延时2秒,让测试人员观察所有遥信灯是否正常点亮
- if(ustimer_get_duration(us_begin) > (2000*USTIMER_MS))
- // if(ustimer_get_duration(us_begin) > (10000*USTIMER_MS))
- {
- break;
- }
- }
- // 关闭所有遥信灯
- for(j=0; j<do_num; j++)
- {
- dido_do(slot_do,(1<<j),0);
- }
- // 等待子板的开出硬件接点真正释放,一般至少6ms
- ustimer_delay(20*USTIMER_MS);
- // 开始逐一测试开入开出对
- for(j=0; j<do_num; j++)
- {
- dido_do(slot_do,(1<<j),1);
- ustimer_delay(150*USTIMER_MS);
- memset(di_ok,0,sizeof(di_ok));
- do_errflag = 4;
- for (k=0; k<4; k++)
- {
- if (!test_do[j+bd_di60*i*do_num][k])
- {
- do_errflag--;
- }
- else if (test_do[j+bd_di60*i*do_num][k] < 33) //开入小于32个
- {
- if (!(g_di[slot_di].value[0] & (1<<(test_do[j+bd_di60*i*do_num][k]-1)))) //对应开入无值
- {
- do_errflag--;
- di_ok[k] = test_do[j+bd_di60*i*do_num][k];
- }
- }
- else if (test_do[j+bd_di60*i*do_num][k] >= 33) //开入小于32个 //开入大于32个
- {
- if (!(g_di[slot_di].value[1] & (1<<(test_do[j+bd_di60*i*do_num][k]-33)))) //对应开入无值
- {
- do_errflag--;
- di_ok[k] = test_do[j+bd_di60*i*do_num][k];
- }
- }
- }
- if (!do_errflag) //开出对应的所有开入都没有值,即代表该开出有问题
- {
- if (j<8)
- {
- dido_buf[i+i*13+1] |= (1<<j); //开出错误标志
- }
- else if (j<16)
- {
- dido_buf[i+i*13+2] |= (1<<(j-8)); //开出错误标志
- }
-
- rt_printf("dido_test do err:i=%d,j=%d,di=%d,di_l=0x%04x,di_h=0x%04x.\r\n",i,j,di_ok[0], g_di[slot_di].value[0],g_di[slot_di].value[1]);
- }
- else
- {
- for (k=0; k<4; k++)
- {
- if (!di_ok[k])
- continue;
- if ((di_ok[k]-1) < 8)
- {
- dido_buf[i+i*13+6] |= (1<<(di_ok[k]-1));
- }
- else if ((di_ok[k]-1) < 16)
- {
- dido_buf[i+i*13+7] |= (1<<(di_ok[k]-1-8));
- }
- else if ((di_ok[k]-1) < 24)
- {
- dido_buf[i+i*13+8] |= (1<<(di_ok[k]-1-16));
- }
- else if ((di_ok[k]-1) < 32)
- {
- dido_buf[i+i*13+9] |= (1<<(di_ok[k]-1-24));
- }
- else if ((di_ok[k]-1) < 40)
- {
- dido_buf[i+i*13+10] |= (1<<(di_ok[k]-1-32));
- }
- else if ((di_ok[k]-1) < 48)
- {
- dido_buf[i+i*13+11] |= (1<<(di_ok[k]-1-40));
- }
- else if ((di_ok[k]-1) < 56)
- {
- dido_buf[i+i*13+12] |= (1<<(di_ok[k]-1-48));
- }
- else if ((di_ok[k]-1) < 64)
- {
- dido_buf[i+i*13+13] |= (1<<(di_ok[k]-1-56));
- }
- rt_printf("dido_test di err:i=%d,j=%d,di=%d,di_l=0x%04x,di_h=0x%04x.\r\n",i,j,di_ok[k], g_di[slot_di].value[0],g_di[slot_di].value[1]);
- }
- }
- dido_do(slot_do,(1<<j),0);
- ustimer_delay(20*USTIMER_MS);
- watchdog_feed_mainloop();
- }
- }
- for(i=0;i<5;i++)
- {
- if(g_do_time[i].slot != 0)
- {
- rt_printf("do_time[%d]:diff_max=%d,diff_out_count=%d\r\n",g_do_time[i].slot,g_do_time[i].diff_max,g_do_time[i].diff_out_count);
- }
- }
-
- //rt_printf("\r\n");
- rt_printf("dido_test end:err_once=%d,error_count=%d!\r\n\r\n\r\n",err_once,error_count);
-
- return 0;
- }
- #else
- #include "gpio.h"
- #include "ad7616.h"
- /*------------------------------- 宏定义 --------------------------------------
- */
- #define DO_PWM_SW_HZ 0
- #define DO_PWM_SW_QD 1
- #define DO_PWM_SW_NULL 2
- #define DO_PWM_SW_FZ 3
- #ifdef __MINI_DTU__
- #define DO_QD_KC DO_OUT1
- #else
- #define DO_QD_KC DO_OUT4
- #endif
- /*------------------------------ 类型结构 -------------------------------------
- */
- /*------------------------------ 全局变量 -------------------------------------
- */
- struct di g_di[EQU_SLOT_NUM_MAX];
- struct _do g_do[EQU_SLOT_NUM_MAX];
- struct di_struct g_di_st[EQU_SLOT_NUM_MAX][DIDO_MAX_DI_PER_SLOT];
- struct do_struct g_do_st[DO_NUM];
- u16 g_do_status; // 开出状态,因为仅主板有开出
- u32 g_do_start_time;
- int g_do_flag;
- extern u32 g_brd_type_kz;
- struct rt_stat g_stat_di_delay;
- struct rt_stat g_stat_do_delay;
- static u32 di_error_count = 0;
- static u32 error_count = 0;
- struct do_time g_do_time[EQU_SLOT_NUM_MAX];
- /*------------------------------ 函数声明 -------------------------------------
- */
- static int _dido_do(u32 slot,u16 v,int is_on);
- static int _get_di(int slot,u16 di_num, u32 di, struct timespec ts);
- static inline void _io_do_status_update(int on, unsigned int i);
- unsigned int change_di_ch(unsigned int di);
- /*------------------------------ 外部函数 -------------------------------------
- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
- */
- /******************************************************************************
- 函数名称: dido_init
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 开入开出初始化
- 参数说明: 无
- 返回值: 无
- 修改记录:
- */
- void dido_init_di(void)
- {
- //return ret;
-
- u32 i,slot;
- u32 di0,di,di_num;
- di0 = gpio_get_di();
- // 主板
- slot = EQU_SLOT_KZ;
- di = (di0 & 0x7FFFF);
- g_di[slot].value[0] = di^g_di[slot].inv[0];
- di_num = equ_get_di_num(slot);
- for(i=0; i<di_num; i++)
- {
- if(di&(1<<i))
- {
- g_di_st[slot][i].b_on = 1;
- }
- else
- {
- g_di_st[slot][i].b_on = 0;
- }
- if(g_di[slot].value[0]&(1<<i))
- {
- sw_di_set(g_di_st[slot][i].owner,g_di_st[slot][i].type,SW_DI_TYPE_ON);
- g_di[slot].ts_v[i][g_di[slot].ts_i[i].n] = 1;
- }
- g_di[slot].ts_t[i][g_di[slot].ts_i[i].n] = 0;
- g_di[slot].ts_i[i].n++;
- }
- }
- int dido_init(void)
- {
- u32 i;
- // 检查装置配置
- if(equ_config_null())
- {
- return -1;
- }
- // 初始化取反标志
- for(i=0; i< g_equ_config->di_num; i++)
- {
- if(g_equ_config_di[i].is_Inverse == 0)
- {
- continue;
- }
- if(g_equ_config_di[i].slot < EQU_SLOT_NUM_MAX && g_equ_config_di[i].index < DIDO_MAX_DI_PER_SLOT)
- {
- if(g_equ_config_di[i].index < 32)
- {
- g_di[g_equ_config_di[i].slot].inv[0] |= 1<<g_equ_config_di[i].index;
- }
- else
- {
- g_di[g_equ_config_di[i].slot].inv[1] |= 1<<(g_equ_config_di[i].index - 32);
- }
- }
- }
- dido_init_di();
- dido_stat_reset();
- return 0;
- }
- // 只有分合闸有选择启动继电器
- int dido_do_have_select(u32 slot,u32 index)
- {
- int i = 0;
- i = equ_get_do_channel(index);
- if(i==DO_OUT0||i==DO_OUT1||i==DO_OUT5||i==DO_OUT6)
- {
- return 1;
- }
- return 0;
- }
- /******************************************************************************
- 函数名称: dido_do
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 板卡开出动作
- 参数说明: 无
- 返回值:
- 修改记录:
- */
- int dido_do(u32 slot,u16 v,int is_on)
- {
- //unsigned long flags;
- // 检查DO资源
- if(equ_get_do_num(slot) == 0)
- {
- return -2;
- }
- // 保存输出值,在5ms中断中输出
- rt_irq_save(flags);
- g_do_flag = 1;
- if(is_on)
- {
- g_do[slot].on |= v;
- }
- else
- {
- g_do[slot].off |= v;
- }
- rt_irq_restore(flags);
- return 0;
- }
- /******************************************************************************
- 函数名称: do_kout_check
- 函数版本:
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 开出反校。
- 参数说明: 无
- 返回值: 结果
- 修改记录:
- */
- void io_do_check(void)
- {
- u16 now,fj;
- u32 us;
- #ifdef DO_KOUT_CHECK
- u8 index;
- // 取返校值,必须在下面时间点检查之
- index=g_equ_config_di[g_sw[0].di_cfg_index[SW_DI_KOCHK]].index;
- fj = gpio_di_fj(index)&0x01;//0x02;
- // 返回值只判断启动、分闸、合闸
- now = 0;
- if(g_do_status &(1<<DO_QD_KC))//预置反校DO_PWM_SW_QD
- {
- now |= 0x01;
- }
- //if(g_do_status &((1<<DO_PWM_SW_FZ)|(1<<DO_PWM_SW_HZ)))//动作反校
- //{
- //now |= 0x01;//0x02;
- //}
- #else
- // 取返校值,必须在下面时间点检查之
- fj = gpio_di_fj()&0x02;
- // 返回值只判断启动、分闸、合闸
- now = 0;
- if(g_do_status &(1<<DO_PWM_SW_QD))
- {
- //now |= 0x01;
- }
- if(g_do_status &((1<<DO_PWM_SW_FZ)|(1<<DO_PWM_SW_HZ)))
- {
- now |= 0x02;
- }
- #endif
- //开出动作20ms内不进行开出自检,
- //经实测启动继电器因为是继电器触点返校,其返回时间最长,但也小于10ms。
- //分合闸继电器是光耦返校,本身需要的时间可以忽略不计,但受启动继电器的影响
- us = ustimer_get_duration(g_do_start_time);
- if(us < 20*1000)
- {
- return ;
- }
- if (fj != now)
- {
- // rt_printf("返校失败:fj=%04x,now=%04x, g_do_status=%04x(us=%d)\r\n",fj,now, g_do_status,us);
- rt_err_set(ERR_CODE_DO_CHECK,0);
- return ;
- }
- }
- /******************************************************************************
- 函数名称: io_do_return
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 开出保持时间
- 参数说明: 无
- 返回值: 无
- 修改记录:
- */
- void io_do_return(void)
- {
- int i;
- u32 dly;
- for(i=0; i<DO_NUM; i++) //开出保持
- {
- if(g_do_status & (1<<i)) //正在开出
- {
- dly = ustimer_get_duration(g_do_st[i].us_on);
- // +2500是为了提高脉宽精度,因为此函数是在5ms(5000)中断中调用的.
- // 如果us_keep为0,表示此开出没有自动返回的需求,应忽略。
- if (((dly + 2500) > g_do_st[i].us_keep) && (g_do_st[i].us_keep>0))
- {
- dido_do_kz(0,i);
- }
- }
- }
- }
- /******************************************************************************
- 函数名称: dido_do_poll
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 是否开出巡检
- 参数说明: 无
- 返回值: 无
- 修改记录:
- */
- void dido_do_poll(void)
- {
- #if 1
- int i;
- // 真正开出
- if(g_do_flag)
- {
- g_do_flag = 0;
- for(i=0; i<EQU_SLOT_NUM_MAX; i++)
- {
- if(g_do[i].on)
- {
- _dido_do(i,g_do[i].on,1);
- g_do[i].on = 0;
- }
- if(g_do[i].off)
- {
- _dido_do(i,g_do[i].off,0);
- g_do[i].off = 0;
- }
- }
- }
- // 开出返回
- io_do_return();
- // 开出返校
- if(g_board_info[EQU_SLOT_KZ].do_num != 0)
- {
- #ifdef DO_KOUT_CHECK
- if((short)g_sw[0].di_cfg_index[SW_DI_KOCHK] != INDEX_INVALLID)
- {
- io_do_check();
- }
- #else
- //io_do_check();
- #endif
- }
- return;
- #endif
- }
- /******************************************************************************
- 函数名称: dido_qd_set_keeptime
- 函数版本: 01.01
- 创建作者: sunxi
- 创建日期: 2013-06-10
- 函数说明: 设置启动继电器的保持时间
- 参数说明: 无
- 返回值: 无
- 修改记录:
- */
- void dido_qd_set_keeptime(u32 us)
- {
- g_do_st[DO_QD_KC].us_keep = us;
- }
- /******************************************************************************
- 函数名称: get_di
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 开入防抖处理
- 参数说明: 无
- 返回值: 无
- 修改记录:
- */
- //unsigned int di_val;
- void dido_di_poll(SHM_SAMPLE_T *sample_data)
- {
- u32 di,di_num,slot;
- u64 us0;
- // 如果交流延时失电信号有,闭锁遥信
- if(pRunSet->dSDYX_T && g_run_stu.dcjlsd_t)
- {
- return;
- }
- us0 = ustimer_get_origin();
- // 主板,19个遥信
- slot = EQU_SLOT_KZ;
- di_num = equ_get_di_num(slot);
- // di = gpio_get_di();
- di = change_di_ch(~sample_data->yx_buf[0]);
- rt_printf("gpio_get_di:yx_buf[0]=%x di=%x\r\n",sample_data->yx_buf[0],di);
- _get_di(slot, di_num, di, sample_data->ts);
- rt_stat_other_in(6,ustimer_get_duration(us0));
- }
- /******************************************************************************
- 函数名称: dido_di_is_on
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 开入状态
- 参数说明: 无
- 返回值: 1:有开入,0:无开入
- 修改记录:
- */
- int dido_di_is_on(u8 slot,u8 index)
- {
- if(slot >= EQU_SLOT_NUM_MAX || index >= 64)
- {
- return 0;
- }
- if(index < 32)
- {
- if(g_di[slot].value[0]&(1<<index))
- {
- return 1;
- }
- }
- else
- {
- index -= 32;
- if(g_di[slot].value[1]&(1<<index))
- {
- return 1;
- }
- }
- return 0;
- }
- // 查看某个时间点下的开入值
- int dido_di_is_on_ts(u8 slot,u8 index,u32 ts)
- {
- int i,r;
- struct ts_index ts_i;
- if(slot >= EQU_SLOT_NUM_MAX || index >= 32)
- {
- return 0;
- }
- #if 0
- {
- static int cnt = 0;
- if(cnt++ < 16)
- rt_printf("slot=%d,index=%d,ts=%d.\r\n",slot,index,ts);
- }
- #endif
- ts_i.n = g_di[slot].ts_i[index].n - 1; //ts_i下是无值的,所以应该减1
- for(i=0;i<DIDO_TS_NUM;i++)
- {
- r = (int)(ts - g_di[slot].ts_t[index][ts_i.n]);
- if(r >= 0)
- {
- return g_di[slot].ts_v[index][ts_i.n];
- }
- ts_i.n--;
- }
- if(g_di[slot].value[0]&(1<<index))
- {
- return 1;
- }
- return 0;
- }
- int dido_do_kz(int on, unsigned int i)
- {
- if(on) // 开出,需启动启动继电器打开电源
- {
- if(i==DO_OUT0||i==DO_OUT1||i==DO_OUT5||i==DO_OUT6)
- {
- gpio_kout_do(on, DO_QD_KC-DO_OUT0); // 对应X4端子的DO0~DO7
- _io_do_status_update(1,DO_QD_KC);
- }
- }
- // if(i<=DO_PWM3)
- // {
- // gpio_pwm_do(on, i); // 对应X3端子的OUT3,分闸
- // _io_do_status_update(on,i);
- // }
- // else
- if(i==DO_QD_KC) //启动继电器出口
- {
- if(!on)
- {
- if(g_tRelay[0].zqd) // 如果保护启动,禁止关闭启动继电器
- {
- return -2;
- }
- if(g_do_status&(~(1<<DO_QD_KC))) //有其他开出,不收启动继电器
- {
- return -3;
- }
- }
- gpio_kout_do(on, i-DO_OUT0); // 对应X4端子的DO0~DO7
- _io_do_status_update(on,i);
- }
- else if ((i >= DO_OUT0) && (i <= DO_OUT7))
- {
- gpio_kout_do(on, i-DO_OUT0); // 对应X4端子的DO0~DO7
- _io_do_status_update(on,i);
- }
- else
- {
- rt_printf("dido_do_kz err(on=%d,i=%d).\r\n",on,i);
- }
- return 0;
- }
- /*------------------------------ 内部函数 -------------------------------------
- 内部函数以下划线‘_’开头,不需要检查参数的合法性.
- */
- static inline void _io_do_status_update(int on, unsigned int i)
- {
- if(on)
- {
- g_do_status |= (1<<i);
- g_do_st[i].us_on= ustimer_get_origin();
- }
- else
- {
- g_do_status &= ~(1<<i);
- }
- // 更新返校检查时间
- g_do_start_time = ustimer_get_origin();
- }
- static int _dido_do(u32 slot,u16 v,int is_on)
- {
- int i;
- // 循环检查开出位
- for(i=0; i<g_board_info[slot].do_num; i++)
- {
- // 如果对应开出位有效,开出。
- if(((v>>i) & 0x1))
- {
- dido_do_kz(is_on,equ_get_do_channel(i));
- }
- }
- if(((v>>g_board_info[slot].do_num) & 0x1)) // 启动继电器
- {
- dido_do_kz(is_on,DO_QD_KC);
- }
- return 0;
- }
- /******************************************************************************
- 函数名称: _get_di
- 函数版本: 01.01
- 创建作者:
- 创建日期: 2013-03-13
- 函数说明: 开入防抖处理
- 参数说明: 无
- 返回值:
- 修改记录:
- */
- #ifdef CN_AREA_GUANGXI//遥信全部为0
- u32 kktime_0=0;
- #endif
- static int _get_di(int slot,u16 di_num, u32 di, struct timespec ts)
- {
- int i,b_on;
- struct rtc_time_t ct;
- uint32 diff_nsec;
- // struct timespec ts;
- #if 0//#ifdef CN_AREA_GUANGXI//遥信全部为0,则关闭屏幕或者关机
- if(di==0)
- {
- kktime_0++;
- if(kktime_0 > 10)
- {
- #if 1
- g_run_stu.yxError=true; //遥信错误,关闭屏幕
- #else
- char *argv[] = {"poweroff", NULL};
- char *envp[] = { NULL };
- call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);//关机
- #endif
- return 0;
- }
- }
- else
- {
- g_run_stu.yxError=0;
- kktime_0=0;
- }
- #endif
- // 获取遥信值,并记录时间戳。
- // 用秒的低8位和纳秒的高24位合成32位时间戳
- // clk_time_get(&ts);
- // 循环处理每一个遥信
- for(i=0; i<di_num; i++)
- {
- struct di_struct *pt=&g_di_st[slot][i];
- // 处理当前变位遥信。
- b_on = (di&(1<<i))? 1:0;
- if(b_on^pt->b_on)
- {
- if(!pt->b_first_change)
- {
- pt->b_first_change=true;
- pt->tm_back=0;
- pt->tm_keep=0;
- // 记录变位的起始时刻点
- pt->ts_di = ts;
- pt->dt=g_adc_dots_data_count;
- #ifdef DIDO_TS_MODE
- pt->ts_tmp = ts;
- #endif
- }
- else
- {
- // 累计保持时间
- #ifdef DIDO_TS_MODE
- if(ts.tv_nsec >= pt->ts_tmp.tv_nsec)
- {
- diff_nsec = ts.tv_nsec - pt->ts_tmp.tv_nsec;
- }
- else
- {
- diff_nsec = 1000000000ul - pt->ts_tmp.tv_nsec + ts.tv_nsec;
- }
- if(diff_nsec > 312500ul)
- {
- diff_nsec = 156250ul;
- }
- pt->acc_nsec += diff_nsec;
- while(pt->acc_nsec >= 156250ul)
- {
- pt->tm_keep++;
- pt->acc_nsec -= 156250ul;
- }
- pt->ts_tmp = ts;
-
- // rt_printf("diff_nsec:%d, pt->tm_keep:%d\r\n", diff_nsec, pt->tm_keep);
- #else
- pt->tm_keep++;
- #endif
- pt->tm_back=0; // 现在返回门限是0.5us,所有必须在此清零。
- // 保持时间到,处理变位
- if(pt->tm_keep > pt->tm_filter)
- {
- // 记录遥信状态
- #if defined CN_AREA_GUANGXI || defined YX_DI_ERROR //广西遥信异常后,遥信屏蔽不保存,不上报
- if( g_run_stu.yxEnable==0 && b_on==0)
- {
- pt->type = SOE_TYPE_TST;
- pt->b_first_change=false;
- pt->tm_back=0;
- pt->tm_keep=0;
- return 0;
- }
- #endif
- pt->b_on = b_on;
- if(g_di[slot].inv[0] & (1<<i))
- {
- b_on = !b_on;
- }
- if(b_on)
- {
- g_di[slot].value[0] |= (1<<i);
- }
- else
- {
- g_di[slot].value[0] &= ~(1<<i);
- }
- // 记录SOE
- soe_record_yx((WORD)(i+(slot<<8)),b_on,&pt->ts_di);
- timespec_to_rtc(ts, &ct, 1);
- rt_printf("di=%x value[0]=%x\r\n",di,g_di[slot].value[0]);
- // 更新逻辑模型中的值
- sw_di_set(g_di_st[slot][i].owner,g_di_st[slot][i].type,b_on ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
- // 更新记录
- g_di[slot].ts_t[i][g_di[slot].ts_i[i].n] = pt->dt;
- g_di[slot].ts_v[i][g_di[slot].ts_i[i].n] = b_on;
- g_di[slot].ts_i[i].n++;
- //滤波处理数据复位
- pt->b_first_change=false;
- pt->tm_back=0;
- pt->tm_keep=0;
- }
- }
- }
- else if(pt->b_first_change)
- {
- // 变位返回处理
- pt->tm_back++;
- // 屏蔽下一行,
- // 最新逻辑,有效电平不连续可计数累加;
- // 无效电平连续超0.5ms复归,且不连续累加。
- //pt->tm_keep=0;
- // if(pt->tm_back > pt->tm_filter)
- if(pt->tm_back>4) // 针对高频振荡波测试优化,返回门限设置为500us附件(4*156=624us)。
- {
- pt->tm_back = 0;
- pt->tm_keep=0;
- pt->b_first_change = false;
- }
- }
- }
- return 0;
- }
- /*------------------------------ 测试函数 -------------------------------------
- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
- 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
- */
- // SOE信号发生器控制全局变量
- extern int g_soe_gen_state; // 状态,0停止,1初始化,2运行
- extern int g_soe_gen_on_us; // 导通时间
- extern int g_soe_gen_off_us; // 断开时间
- extern int g_soe_gen_seq_us; // 通道序列间隔时间
- #define SOE_GEN_NUM 8
- u32 g_soe_gen_count;
- u32 g_soe_gen_us0[SOE_GEN_NUM];
- u8 g_soe_gen_on[SOE_GEN_NUM];
- void dido_soe_gen(void)
- {
- int i;
- if(g_soe_gen_state == 0)
- {
- return;
- }
- else if(g_soe_gen_state == 1)
- {
- pit_156us_period_set(78.125);
- g_soe_gen_count = 0;
- for(i=0; i<SOE_GEN_NUM; i++)
- {
- g_soe_gen_us0[i] = g_soe_gen_seq_us*(i);
- g_soe_gen_on[i] = 0;
- g_soe_gen_state = 2;
- }
- }
- else if(dido_di_is_on(1,0))
- {
- for(i=0; i<SOE_GEN_NUM; i++)
- {
- if(g_soe_gen_on[i] == 0)
- {
- if((int)(g_soe_gen_count - g_soe_gen_us0[i]) >= g_soe_gen_off_us)
- {
- g_soe_gen_on[i] = 1;
- gpio_kout_do(1,i);
- g_soe_gen_us0[i] = g_soe_gen_count;
- }
- }
- else
- {
- if((int)(g_soe_gen_count - g_soe_gen_us0[i]) >= g_soe_gen_on_us)
- {
- g_soe_gen_on[i] = 0;
- gpio_kout_do(0,i);
- g_soe_gen_us0[i] = g_soe_gen_count;
- }
- }
- }
- }
- else
- {
- g_soe_gen_count = 0;
- for(i=0; i<SOE_GEN_NUM; i++)
- {
- g_soe_gen_us0[i] = g_soe_gen_seq_us*(i);
- g_soe_gen_on[i] = 0;
- g_soe_gen_state = 2;
- }
- }
- g_soe_gen_count++;
- }
- int dido_printf(void)
- {
- int i,slot,index;
- struct ts_index ts_i;
- rt_printf("槽号\t值\r\n");
- for(i=0; i<EQU_SLOT_NUM_MAX; i++) // xj 2015-5-4
- {
- rt_printf("%02d:\tvalue=0x%08lx_%08lx,inv=0x%08lx_%08lx\r\n",i,g_di[i].value[1],g_di[i].value[0],g_di[i].inv[1],g_di[i].inv[0]);
- }
- rt_printf("\r\n");
- slot = EQU_SLOT_MAIN;
- index = 1;
- ts_i.n = g_di[slot].ts_i[index].n;
- rt_printf("开入时间戳记录:slot=%d,index=%d,ts_i=%d.\r\n",slot,index,ts_i.n);
- rt_printf("序号\t值\t时间戳\r\n");
- ts_i.n = 0;
- for(i=0;i<DIDO_TS_NUM;i++)
- {
- rt_printf("%02d\t%d\t%08lu\r\n",ts_i.n,g_di[slot].ts_v[index][ts_i.n],g_di[slot].ts_t[index][ts_i.n]);
- ts_i.n++;
- }
- rt_printf("开出状态:0x%04x\r\n\r\n",g_do_status);
- rt_stat_printf(&g_stat_di_delay);
- rt_stat_printf(&g_stat_do_delay);
- return 0;
- }
- int dido_stat_reset(void)
- {
- rt_stat_init(&g_stat_di_delay,"di_delay");
- rt_stat_init(&g_stat_do_delay,"do_delay");
- return 0 ;
- }
- int dido_single_test(u8 slot, u8 point)
- {
- dido_do(slot,(1<<point),1);
- ustimer_delay(250*USTIMER_MS);
- dido_do(slot,(1<<point),0);
- return 0;
- }
- int dido_test(void)
- {
- static unsigned long us0 = 0;
- static char dido_test_pair[3][2] =
- {
- {1,3},
- {2,4},
- {5,5},
- };
- static char dido_test_di[32] =
- {
- 0,1,2,3,
- 0,1,2,3,
- 4,5,6,7,
- 4,5,6,7,
- 8,9,10,11,
- 8,9,10,11,
- 12,13,10,11,
- 12,13,12,13
- };
- int i,j,k,err_once,di_num;
- u32 slot_di,slot_do;
- if(g_test_on == 0)
- {
- return 0;
- }
- // 5秒处理一次
- if(ustimer_delay_origin2(&us0,10*USTIMER_SEC) != 1)
- {
- return 0;
- }
- rt_printf("dido_test begin...\r\n");
- ustimer_delay(1*USTIMER_SEC);
- #if 1
- // 测试开出板、开入板
- // 开出板逐一开出
- rt_printf("dido_test single.\r\n");
- err_once = 0;
- for(i=0; i<3; i++)
- {
- slot_do = dido_test_pair[i][0];
- slot_di = dido_test_pair[i][1];
- for(j=0;j<equ_get_do_num(slot_do); j++)
- {
- dido_do(slot_do,(1<<j),1);
- ustimer_delay(250*USTIMER_MS);
- di_num = equ_get_di_num(slot_di);
- if(slot_di == equ_get_slot_by_type(BOARD_TYPE_AUX))
- {
- di_num -= 1;
- }
- for(k=0;k<di_num; k++)
- {
- // 是否对应的开出点
- if(dido_test_di[k] == j)
- {
- if((g_di[slot_di].value[0] & (1<<k)) == 0)
- {
- err_once++;
- error_count++;
- rt_printf("dido_test on err(err=%d):i=%d,j=%d,k=%d,di=0x%08lx.\r\n",err_once,i,j,k,g_di[slot_di].value[0]);
- }
- }
- else
- {
- if((g_di[slot_di].value[0] & (1<<k)) != 0)
- {
- err_once++;
- error_count++;
- rt_printf("dido_test off err(err=%d):i=%d,j=%d,k=%d,di=0x%08lx.\r\n",err_once,i,j,k,g_di[slot_di].value[0]);
- }
- }
- }
- dido_do(slot_do,(1<<j),0);
- ustimer_delay(20*USTIMER_MS);
- watchdog_feed_mainloop();
- }
- }
- #endif
- rt_printf("\r\n开入变位时间超出次数:%lu\r\n",di_error_count);
- rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt\n");
- rt_stat_printf(&g_stat_di_delay);
- rt_printf("\r\n");
- for(i=0;i<EQU_SLOT_NUM_MAX;i++)
- {
- if(g_do_time[i].slot != 0)
- {
- rt_printf("do_time[%d]:diff_max=%lu,diff_out_count=%lu\r\n",
- g_do_time[i].slot,g_do_time[i].diff_max,g_do_time[i].diff_out_count);
- }
- }
- rt_printf("\r\n");
- rt_printf("dido_test end:err_once=%d,error_count=%lu!\r\n\r\n\r\n",err_once,error_count);
- return 0;
- }
- bool check_board_di_valid(u8 slot,u8 index)
- {
- u32 i;
- // 初始化取反标志
- index-=1;
- for(i=0; i< g_equ_config->di_num; i++)
- {
- if((g_equ_config_di[i].slot==1)&&(g_equ_config_di[i].index==index))
- {
- if(g_equ_config_di[i].type==0)return true;
- }
- }
- return false;
- }
- bool check_board_kc6_close(u8 slot,u8 index)
- {
- u32 i;
- // 初始化取反标志
- index-=1;
- for(i=0; i< g_equ_config->do_num; i++)
- {
- if((g_equ_config_do[i].slot==slot)&&(g_equ_config_do[i].index==index))
- {
- if(g_equ_config_do[i].type!=0)return true;
- }
- }
- return false;
- }
- #define DIGROUP 4
- #define V3_OUT_NUM 5
- int dido_auto_test_for_v3(char *buf,int num)
- {
- // 12个开入,用5个开出进行测试
- static char test_di[6][DIGROUP] =
- {
- {1, 6, 11,0},
- {2, 7, 12,0},
- {3, 8, 13,0},
- {4, 9, 14,0},
- {16, 0, 0,0},
- {5, 10, 15,0},
- };
- int i,j,k,err_once,flag,flag1,di_num, do_num;
- u32 slot_di,slot_do, di_result;
- u8 tmp[5],tmp_data[5];
- u8 di_ok[4] = {0};
- u8 do_errflag = 0;
- char dido_test_pair[num][2];
- unsigned long us_begin = 0;
- bool bkc6close=false;
- slot_do=0;
- bkc6close=check_board_kc6_close(1,6);
- dido_stat_reset();
- if(bkc6close)
- {
- dido_do(slot_do,(1<<5),1); // 开出6若焊接为常闭输出,先开出,打开节点
- ustimer_delay(100*USTIMER_MS);
- }
- // 取出板卡槽位
- for(i=0;i<(num*2);)
- {
- for(j=0;j<2;j++)
- {
- dido_test_pair[i/2][j] = buf[i];
- i++;
- }
- }
- flag = 0;
- flag1 = 0;
- memset(tmp,0,sizeof(tmp));
- memset(tmp_data,0,sizeof(tmp_data));
- memset(dido_buf,0,sizeof(dido_buf));
- rt_printf("dido_test begin...\r\n");
- err_once = 0;
- // 以组为循环
- for(i=0; i<num; i++)
- {
- slot_do = dido_test_pair[i][0];
- slot_di = dido_test_pair[i][1];
- // 槽位暂存
- dido_buf[i+i*13] = slot_do;
- dido_buf[i+i*13+5] = slot_di;
- // 取出对应槽位的板卡中DI和DO的数量
- di_num = equ_get_di_num(slot_di);
- do_num = equ_get_do_num(slot_do);
- //dido_do(slot_do,(1<<5),1); //磁保持继电器
- // 启动记时
- us_begin = ustimer_get_origin();
- // 逐一输出开出点
- for(j=0; j<V3_OUT_NUM; j++)
- {
- dido_do(slot_do,(1<<j),1);
- if(j==5&&bkc6close)
- {
- dido_do(slot_do,(1<<5),0); // 开出6若焊接为常闭输出,反操作为闭合
- }
- ustimer_delay(150*USTIMER_MS);
- memset(di_ok,0,sizeof(di_ok));
- do_errflag = DIGROUP;
- for (k=0; k<4; k++)
- {
- bool bIgnore=false;
- di_result = (g_di[slot_di].value[0] ^ g_di[slot_di].inv[0]);
- k+=i*2;
- if(test_di[j][k]==17)
- {
- bIgnore=check_board_di_valid(slot_di,17);
- }
- if(test_di[j][k]==18)
- {
- bIgnore=check_board_di_valid(slot_di,18);
- }
- if (!test_di[j][k]||bIgnore)
- {
- do_errflag--;
- }
- else
- {
- if (!(di_result & (1<<(test_di[j][k]-1)))) //对应开入无值
- {
- do_errflag--;
- di_ok[k] = test_di[j][k];
- }
- }
- }
- if (!do_errflag) //开出对应的所有开入都没有值,即代表该开出有问题
- {
- if (j<8)
- {
- dido_buf[i+i*13+1] |= (1<<j); //开出错误标志
- }
- else if (j<16)
- {
- dido_buf[i+i*13+2] |= (1<<(j-8)); //开出错误标志
- }
- rt_printf("dido_test do err:i=%d,j=%d,di=%d,di_l=0x%04lx,di_h=0x%04lx.\r\n",
- i,j,di_ok[0], g_di[slot_di].value[0],g_di[slot_di].value[1]);
- }
- else
- {
- for (k=0; k<4; k++)
- {
- if (!di_ok[k])
- continue;
- if ((di_ok[k]-1) < 8)
- {
- dido_buf[i+i*13+6] |= (1<<(di_ok[k]-1));
- }
- else if ((di_ok[k]-1) < 16)
- {
- dido_buf[i+i*13+7] |= (1<<(di_ok[k]-1-8));
- }
- else if ((di_ok[k]-1) < 24)
- {
- dido_buf[i+i*13+8] |= (1<<(di_ok[k]-1-16));
- }
- else if ((di_ok[k]-1) < 32)
- {
- dido_buf[i+i*13+9] |= (1<<(di_ok[k]-1-24));
- }
- else if ((di_ok[k]-1) < 40)
- {
- dido_buf[i+i*13+10] |= (1<<(di_ok[k]-1-32));
- }
- else if ((di_ok[k]-1) < 48)
- {
- dido_buf[i+i*13+11] |= (1<<(di_ok[k]-1-40));
- }
- else if ((di_ok[k]-1) < 56)
- {
- dido_buf[i+i*13+12] |= (1<<(di_ok[k]-1-48));
- }
- else if ((di_ok[k]-1) < 64)
- {
- dido_buf[i+i*13+13] |= (1<<(di_ok[k]-1-56));
- }
- rt_printf("dido_test di err:i=%d,j=%d,di=%d,di_l=0x%04lx,di_h=0x%04lx.\r\n",
- i,j,di_ok[k], g_di[slot_di].value[0],g_di[slot_di].value[1]);
- }
- }
- dido_do(slot_do,(1<<j),0);
- if(j==5&&bkc6close)
- {
- dido_do(slot_do,(1<<5),1); // 开出6若焊接为常闭输出,反操作为闭合
- }
- //if(j==4)
- //{
- //dido_do(slot_do,(1<<5),1); //磁保持继电器
- //}
- ustimer_delay(20*USTIMER_MS);
- watchdog_feed_mainloop();
- }
- }
- for(i=0;i<EQU_SLOT_NUM_MAX;i++)
- {
- if(g_do_time[i].slot != 0)
- {
- rt_printf("do_time[%d]:diff_max=%lu,diff_out_count=%lu\r\n",
- g_do_time[i].slot,g_do_time[i].diff_max,g_do_time[i].diff_out_count);
- }
- }
- rt_printf("dido_test end:err_once=%d,error_count=%lu!\r\n\r\n\r\n",err_once,error_count);
- return 0;
- }
- extern u32 g_brd_type_kz;
- int dido_auto_test(char *buf,int num)
- {
- #define KC_COUNT 11
- // 12个开入,用5个开出进行测试
- #if 0
- static char test_di[6][DIGROUP] =
- {
- {1, 6, 11,0},
- {2, 7, 12,0},
- {3, 8, 13,0},
- {4, 9, 14,0},
- {16, 0, 0,0},
- {5, 10, 15,0},
- };
- #endif
- static char test_di[KC_COUNT][DIGROUP] =
- {
- {1, 12, 23,0},
- {2, 13, 24,0},
- {3, 14, 0,0},
- {4, 15, 0,0},
- {5, 16, 0,0},
- {6, 17, 0,0},
- {7, 18, 0,0},
- {8, 19, 0,0},
- {9, 20, 0,0},
- {10,21, 0,0},
- {11,22, 0,0},
- // { 0, 0, 0,0}
- };
- u8 brd_v3[] = {22, 23};
- int i,j,k,err_once,flag,flag1,di_num, do_num;
- u32 slot_di,slot_do, di_result;
- u8 tmp[5],tmp_data[5];
- u8 di_ok[4] = {0};
- u8 do_errflag = 0;
- char dido_test_pair[num][2];
- unsigned long us_begin = 0;
- bool bkc6close=false;
- rt_printf("g_brd_type_kz = %lu\r\n ", g_brd_type_kz);
- rt_printf("g_equ_config->do_num = %lu\r\n ", g_equ_config->do_num);
- for(i=0; i<(int)sizeof(brd_v3); i++)
- {
- if(g_brd_type_kz+BOARD_TYPE_DFTU_KC00==brd_v3[i])//
- {
- rt_printf("auto_test_for_v3\r\n ");
- return (dido_auto_test_for_v3(buf, num));
- }
- }
- rt_printf("auto_test_for_v4\r\n ");
- //bkc6close=check_board_kc6_close(1,6);
- dido_stat_reset();
- if(bkc6close)
- {
- dido_do(1,(1<<5),1); // 开出6若焊接为常闭输出,先开出,打开节点
- ustimer_delay(100*USTIMER_MS);
- }
- // 取出板卡槽位
- for(i=0;i<(num*2);)
- {
- for(j=0;j<2;j++)
- {
- dido_test_pair[i/2][j] = buf[i];
- i++;
- }
- }
- flag = 0;
- flag1 = 0;
- memset(tmp,0,sizeof(tmp));
- memset(tmp_data,0,sizeof(tmp_data));
- memset(dido_buf,0,sizeof(dido_buf));
- rt_printf("dido_test begin...\r\n");
- err_once = 0;
- // 以组为循环
- for(i=0; i<num; i++)
- {
- slot_do = dido_test_pair[i][0];
- slot_di = dido_test_pair[i][1];
- // 槽位暂存
- dido_buf[i+i*13] = slot_do;
- dido_buf[i+i*13+5] = slot_di;
- // 取出对应槽位的板卡中DI和DO的数量
- di_num = equ_get_di_num(slot_di);
- do_num = equ_get_do_num(slot_do);
- //dido_do(slot_do,(1<<5),1); //磁保持继电器
- // 启动记时
- us_begin = ustimer_get_origin();
- // 逐一输出开出点
- for(j=0; j<KC_COUNT; j++)
- {
- dido_do(slot_do,(1<<j),1);
- if(j==5&&bkc6close)
- {
- dido_do(slot_do,(1<<5),0); // 开出6若焊接为常闭输出,反操作为闭合
- }
- ustimer_delay(150*USTIMER_MS);
- memset(di_ok,0,sizeof(di_ok));
- do_errflag = DIGROUP;
- for (k=0; k<4; k++)
- {
- bool bIgnore=false;
- di_result = (g_di[slot_di].value[0] ^ g_di[slot_di].inv[0]);
- k+=i*2;
- if(test_di[j][k]==17)
- {
- bIgnore=check_board_di_valid(slot_di,17);
- }
- if(test_di[j][k]==18)
- {
- bIgnore=check_board_di_valid(slot_di,18);
- }
- if (!test_di[j][k]||bIgnore)
- {
- do_errflag--;
- }
- else
- {
- if (!(di_result & (1<<(test_di[j][k]-1)))) //对应开入无值
- {
- do_errflag--;
- di_ok[k] = test_di[j][k];
- }
- }
- }
- if (!do_errflag) //开出对应的所有开入都没有值,即代表该开出有问题
- {
- if (j<8)
- {
- dido_buf[i+i*13+1] |= (1<<j); //开出错误标志
- }
- else if (j<16)
- {
- dido_buf[i+i*13+2] |= (1<<(j-8)); //开出错误标志
- }
- rt_printf("dido_test do err:i=%d,j=%d,di=%d,di_l=0x%04lx,di_h=0x%04lx.\r\n",
- i,j,di_ok[0], g_di[slot_di].value[0],g_di[slot_di].value[1]);
- }
- else
- {
- for (k=0; k<4; k++)
- {
- if (!di_ok[k])
- continue;
- if ((di_ok[k]-1) < 8)
- {
- dido_buf[i+i*13+6] |= (1<<(di_ok[k]-1));
- }
- else if ((di_ok[k]-1) < 16)
- {
- dido_buf[i+i*13+7] |= (1<<(di_ok[k]-1-8));
- }
- else if ((di_ok[k]-1) < 24)
- {
- dido_buf[i+i*13+8] |= (1<<(di_ok[k]-1-16));
- }
- else if ((di_ok[k]-1) < 32)
- {
- dido_buf[i+i*13+9] |= (1<<(di_ok[k]-1-24));
- }
- else if ((di_ok[k]-1) < 40)
- {
- dido_buf[i+i*13+10] |= (1<<(di_ok[k]-1-32));
- }
- else if ((di_ok[k]-1) < 48)
- {
- dido_buf[i+i*13+11] |= (1<<(di_ok[k]-1-40));
- }
- else if ((di_ok[k]-1) < 56)
- {
- dido_buf[i+i*13+12] |= (1<<(di_ok[k]-1-48));
- }
- else if ((di_ok[k]-1) < 64)
- {
- dido_buf[i+i*13+13] |= (1<<(di_ok[k]-1-56));
- }
- rt_printf("dido_test di err:i=%d,j=%d,di=%d,di_l=0x%04lx,di_h=0x%04lx.\r\n",
- i,j,di_ok[k], g_di[slot_di].value[0],g_di[slot_di].value[1]);
- }
- }
- dido_do(slot_do,(1<<j),0);
- if(j==5&&bkc6close)
- {
- dido_do(slot_do,(1<<5),1); // 开出6若焊接为常闭输出,反操作为闭合
- }
- //if(j==4)
- //{
- //dido_do(slot_do,(1<<5),1); //磁保持继电器
- //}
- ustimer_delay(20*USTIMER_MS);
- watchdog_feed_mainloop();
- }
- }
- for(i=0;i<EQU_SLOT_NUM_MAX;i++)
- {
- if(g_do_time[i].slot != 0)
- {
- rt_printf("do_time[%d]:diff_max=%lu,diff_out_count=%lu\r\n",
- g_do_time[i].slot,g_do_time[i].diff_max,g_do_time[i].diff_out_count);
- }
- }
- rt_printf("dido_test end:err_once=%d,error_count=%lu!\r\n\r\n\r\n",err_once,error_count);
- return 0;
- }
- #endif // GW_AREA_MAIN_2021
- /*------------------------------ 文件结束 -------------------------------------
- */
|