/*! \file v_data_log.c \brief 4-õ êàíàëüíûé ëîããåð äëß îñöèëëîãðàôèðîâàíèß â ðåàëüíîì âðåìåíè TDataLog (ñì. TDataLog) \author Êîëëåêòèâ ÎÎÎ ÍÏÔ Âåêòîð \version v 2.01 18/09/2012 */ /** \addtogroup v_data_log */ /*@{*/ #include "DSP.h" #include "co_ODvars.h" #include "V_data_log.h" #include "CANOpen_drv.h" //! Ôîíîâûé îáðàáîò÷èê. /*! ðàáîòàåò â ôîíå. Íóæíî äëß óñòàíîâêè àäðåñîâ ïåðåìåííûõ ÷åðåç CAN. åñëè íåò CAN, ìîæíî çàïèñàòü íóæíûå àäðåñà âðó÷íóþ â TDataLog.dlog_iptr */ //! \memberof TDataLog void dlog_background_analizer(TDataLog *p) { //ïåðåâîä äëèíû ïðåäûñòîðèè èç % â òî÷êè p->trig_shift_int = (p->trig_shift&0xFFFFFF)>>16; //äåëàåì êîëè÷åñòâî òî÷åê if (p->trig_shift_int > 255) //îãðàíè÷èì p->trig_shift_int = 255; unsigned char mode; //åñëè íå ñòîèò õîòü îäèí èç ïåðâûõ øåñòè áèò control, //òî íè÷åãî àíàëèçèðîâàòü è äåëàòü íå íàäî if (!(p->control & 0x3F)) return; // ëþáîì ñëó÷àå ïåðåä âñåìè èçìåíåíèßìè //òîðìîçèì äàòàëîããåð. Èíà÷å îí ìîæåò íà÷àòü çàïèñûâàòü äàííûå ïî ïðåðûâàíèþ, //ïîêà òóò, â ôîíå, èäåò, ñêàæåì, çàïèñü àäðåñîâ. //È òîãäà â ëó÷øåì ñëó÷àå áóäåò êàøà èç äàííûõ, â õóäøåì - îñòàíîâ êîíòðîëëåðà //ïðè îáðàùåíèè ïî íåïðàâèëüíîìó àäðåñó. p->mode_reset = 0; p->valid_points_num = 0; //ò.ê. äàòàëîããåð îñòàíàâëèâàëñÿ (mode = 0), òî ïðåäûñòîðèÿ íåàêòóàëüíà, ò.ê. //1) çà âðåìÿ ñòîïà äàòàëîããåðà ìåæäó çàïèñàííîé ïðåäûñòîðèåé è íîâûìè äàííûìè áóäåò ðàçðûâ ïî âðåìåíè è //2) âûáðàííûå çàïèñûâàåìûå ïåðåìåííûå âîîáùå ìîãëè ñìåíèòüñÿ è ïðåäûñòîðèÿ îñòàíåòñÿ îò ñòàðûõ, à íîâûå äàííûå - îò íîâûõ //ñïðàøèâàåì àäðåñà ó äðàéâåðà CANopen #if DLOG_DATA_SIZE == 16 if (p->control & 1) if (!(p->dlog_iptr1 = (type_data*)co_getAddr(p->pco_vars, p->ind_subind1))) //åñëè àäðåñ=0 p->dlog_iptr1 = (type_data*)&p->ind_subind1; //ïóñòü óêàçûâàåò íà ind_subind if (p->control & 2) if (!(p->dlog_iptr2 = (type_data*)co_getAddr(p->pco_vars, p->ind_subind2))) p->dlog_iptr2 = (type_data*)&p->ind_subind2; if (p->control & 4) if (!(p->dlog_iptr3 = (type_data*)co_getAddr(p->pco_vars, p->ind_subind3))) p->dlog_iptr3 = (type_data*)&p->ind_subind3; if (p->control & 8) if (!(p->dlog_iptr4 = (type_data*)co_getAddr(p->pco_vars, p->ind_subind4))) p->dlog_iptr4 = (type_data*)&p->ind_subind4; #endif #if DLOG_DATA_SIZE == 32 if (p->control & 1) { if (co_getObjectInfo(p->pco_vars, p->ind_subind1, (TObjectInfo*)&p->object1Info) == 0) { p->object1Info.varAddr = (void*)(&p->ind_subind1); p->object1Info.varSize = 32; } } if (p->control & 2) { if (co_getObjectInfo(p->pco_vars, p->ind_subind2, (TObjectInfo*)&p->object2Info) == 0) { p->object2Info.varAddr = (void*)(&p->ind_subind2); p->object2Info.varSize = 32; } } if (p->control & 4) { if (co_getObjectInfo(p->pco_vars, p->ind_subind3, (TObjectInfo*)&p->object3Info) == 0) { p->object3Info.varAddr = (void*)(&p->ind_subind3); p->object3Info.varSize = 32; } } if (p->control & 8) { if (co_getObjectInfo(p->pco_vars, p->ind_subind4, (TObjectInfo*)&p->object4Info) == 0) { p->object4Info.varAddr = (void*)(&p->ind_subind4); p->object4Info.varSize = 32; } } p->highPartOfValue = 0; #endif p->WriteDelimiter = (p->control >> 16) & 0xFF; //ïðîðåæèâàíèå. Îãðàíè÷èâàåòñß 8þ áèòàìè mode = (p->control >> 4) & 3; //ðåæèì - 2 áèòà p->control = 0; //âñå îáðàáîòàëè, îáíóëßåì, ÷òîáû ïðè ñëåä. âûçîâå íå íà÷àòü îáðàáàòûâàòü ñíîâà dlog_set_mode(mode, p); //äëß óñòàíîâêè ðåæèìà âûçûâàåòñß ñïåö. ôóíêöèß. Íàïðßìóþ íåëüçß } //! ôóíêöèß äëß óñòàíîâêè mode_reset. //! ïðåäïîëàãàåòñß äëß óïðàâëåíèß ëîããåðîì èç äðóãèõ ìîäóëåé //! ïðîâåðßåò mode_reset íà âàëèäíîñòü è îáíóëßåò ñ÷åò÷èêè //! \memberof TDataLog void dlog_set_mode(Uint16 mode_reset, TDataLog *p) { if (mode_reset > 3) return; //â 1 ïåðåâîäèì òîëüêî åñëè òåêóùèé ðåæèì 2, ÷òîá ñèíõðîíèçèðîâàòüñß //ïî ïåðâîìó ñîáûòèþ (î÷åíü ïîëåçíî êîãäà ñîáûòèé ìíîãî) if (p->OneShotOperation == 1) { if ((mode_reset == 1)) { if (p->mode_reset == 2) p->mode_reset = mode_reset; else return; } } else p->mode_reset = mode_reset; if (mode_reset == 3) //Õîòèì ïåðåéòè â ðåæèì îäíîêðàòíîé çàïèñè 1024 òî÷åê. p->Wcounter = 0; //â ýòîì ðåæèìå íóæíî ïèñàòü ñ ïåðâîé òî÷êè ïåðâîãî ìàññèâà. Ñáðàñûâàåì ñ÷åò÷èê. //ïðè ñìåíå ðåæèìà â ëþáîì ñëó÷àå ñáðàñûâàåì ôëàã "äàííûå ãîòîâû" p->control &= ~(1 << 6); p->WriteDelimiterCounter = 0; #if DLOG_DATA_SIZE == 32 p->highPartOfValue = 0; #endif } //! Çàïèñûâàåò î÷åðåäíûå òî÷êè â ìàññèâû îñöèëëîãðàììû. //!Äîëæíà âûçûâàòüñß ñ çàäàííîé äèñêðåòèçàöèåé è çàíèìàåòñß çàïèñüþ ìàññèâîâ, //! ò.å. íåïîñðåäñòâåííî îñöèëëîãðàôèðîâàíèåì. Óìååò çàïèñûâàòü äàííûå //! â ìàññèâû ïî-ðàçíîìó â çàâèñèìîñòè îò âûáðàííîãî ðåæèìà ðàáîòû îñöèëëîãðàôà //! \memberof TDataLog void data_log_update(TDataLog *p) { //âåçäå èñïîüçóåòñß p-> , à íå p* - òàê áûñòðåå //ïðîðåæèâàíèå äàííûõ. Åñëè íå äîñòèãëè óñòàâêè WriteDelimiter, âûõîäèì //WriteDelimiter=1 - íå äåëèì //WriteDelimiter=2 - áåðåì êàæäóþ âòîðóþ if ((p->WriteDelimiterCounter++ + 1) < p->WriteDelimiter) return; else p->WriteDelimiterCounter = 0; if (p->mode_reset != p->mode_reset_prev) p->E=1; else p->E=0; p->mode_reset_prev = p->mode_reset; switch (p->mode_reset) { case 0: { p->Wcounter = 0; return; } case 1: //îäíîêðàòíàß çàïèñü - äîøëè äî êîíöà è ñòîï (ðåæèì 0) { //Ïðè âõîäå â ðåæèì ïîëó÷àåì òî÷êó ñðàáàòûâàíèÿ òðèããåðà (ýòî òåêóùèé Wcounter, ñ êîòîðûì ìû ñþäà çàøëè) è ðàññ÷èòûâàåì ïåðâóþ òî÷êó, îòíîñÿùóþñÿ ê äàííîé îñöå (èñõîäÿ èç òåêóùåé òî÷êè è çàäàííîé äëèíû ïðåäûñòîðèè) if (p->E==1) { p->prehistory_length = p->valid_points_num; //äëèíà ïðåäûñòîðèè ðàâíà êîëè÷åñòâó âàëèäíûõ òî÷åê if (p->prehistory_length > p->trig_shift_int) //åñëè ïðåäûñòîðèÿ äëèííåå çàäàííîãî, îãðàíè÷èì p->prehistory_length = p->trig_shift_int; #if DLOG_DATA_SIZE == 16 p->Wcounter &= 0xFE; p->prehistory_length &= 0xFE; p->first_point_written = (p->Wcounter - p->prehistory_length) & 0xFE; #endif #if DLOG_DATA_SIZE == 32 p->first_point_written = (p->Wcounter - p->prehistory_length) & 0xFF; p->highPartOfValue = 0; #endif } p->Wcounter &= 0xFF; //çàùèòà - åñëè âäðóã â counter íå âàëèäíîå çíà÷åíèå #if DLOG_DATA_SIZE == 16 p->dl_buffer1_adr[p->Wcounter] = *p->dlog_iptr1; p->dl_buffer2_adr[p->Wcounter] = *p->dlog_iptr2; p->dl_buffer3_adr[p->Wcounter] = *p->dlog_iptr3; p->dl_buffer4_adr[p->Wcounter] = *p->dlog_iptr4; #endif #if DLOG_DATA_SIZE == 32 p->dl_buffer1_adr[p->Wcounter] = p->object1Info.varSize == 16 ? *((int16*)p->object1Info.varAddr) : *((int32*)p->object1Info.varAddr); p->dl_buffer2_adr[p->Wcounter] = p->object2Info.varSize == 16 ? *((int16*)p->object2Info.varAddr) : *((int32*)p->object2Info.varAddr); p->dl_buffer3_adr[p->Wcounter] = p->object3Info.varSize == 16 ? *((int16*)p->object3Info.varAddr) : *((int32*)p->object3Info.varAddr); p->dl_buffer4_adr[p->Wcounter] = p->object4Info.varSize == 16 ? *((int16*)p->object4Info.varAddr) : *((int32*)p->object4Info.varAddr); #endif p->Wcounter++; p->Wcounter &= 0xFF; //åñëè ïðîøëè 256 òî÷åê, îáíóëèòñß if (p->Wcounter == p->first_point_written) //åñëè äîøëè äî ïîñëåäíåé çàïèñûâàåìîé òî÷êè { p->mode_reset = 0; //ðåæèì ÑÒÎÏ #if DLOG_DATA_SIZE == 16 p->control |= 192; // "äàííûå ãîòîâû" + "ïîääåðæèâàåòñÿ áëî÷íàÿ ïåðåäà÷à" #else p->control |= 192 | (1 << 8); // "äàííûå ãîòîâû" + "ïîääåðæèâàåòñÿ áëî÷íàÿ ïåðåäà÷à" + "32-áèòíûå äàííûå" #endif } return; } case 2: //çàïèñûâàåì ëîã ïî êðóãó { if (p->E == 1) { #if DLOG_DATA_SIZE == 32 p->highPartOfValue = 0; #endif } p->valid_points_num++; //ñ÷èòàåì êîëè÷åñòâî çàïèñàííûõ âàëèäíûõ òî÷åê ïðåäûñòîðèè if (p->valid_points_num > 256) //îãðàíè÷èâàåì p->valid_points_num = 256; p->Wcounter &= 0xFF; //çàùèòà - åñëè âäðóã â counter íå âàëèäíîå çíà÷åíèå #if DLOG_DATA_SIZE == 16 p->dl_buffer1_adr[p->Wcounter] = *p->dlog_iptr1; p->dl_buffer2_adr[p->Wcounter] = *p->dlog_iptr2; p->dl_buffer3_adr[p->Wcounter] = *p->dlog_iptr3; p->dl_buffer4_adr[p->Wcounter] = *p->dlog_iptr4; #endif #if DLOG_DATA_SIZE == 32 p->dl_buffer1_adr[p->Wcounter] = p->object1Info.varSize == 16 ? *((int16*)p->object1Info.varAddr) : *((int32*)p->object1Info.varAddr); p->dl_buffer2_adr[p->Wcounter] = p->object2Info.varSize == 16 ? *((int16*)p->object2Info.varAddr) : *((int32*)p->object2Info.varAddr); p->dl_buffer3_adr[p->Wcounter] = p->object3Info.varSize == 16 ? *((int16*)p->object3Info.varAddr) : *((int32*)p->object3Info.varAddr); p->dl_buffer4_adr[p->Wcounter] = p->object4Info.varSize == 16 ? *((int16*)p->object4Info.varAddr) : *((int32*)p->object4Info.varAddr); #endif p->Wcounter++; p->Wcounter &= 0xFF; //åñëè ïðîøëè 256 òî÷åê, îáíóëèòñß return; } case 3: //ðåæèì îäíîêðàòíîé çàïèñè 1024 òî÷åê { if (p->E==1) { p->first_point_written = 0; //ïèøåì ñ ïåðâîé òî÷êè, ïðåäûñòîðèÿ íå íóæíà. #if DLOG_DATA_SIZE == 32 p->highPartOfValue = 0; #endif } //ñ ó÷åòîì òîãî, ÷òî áóôåðû â ïàìßòè ðàñïîëîæåíû ïîñëåäîâàòåëüíî, //çàïèñûâàåì â ïåðâûé, "çàåçæàß" íà îñòàëüíûå òðè #if DLOG_DATA_SIZE == 16 p->dl_buffer1_adr[p->Wcounter] = *p->dlog_iptr1; #endif #if DLOG_DATA_SIZE == 32 p->dl_buffer1_adr[p->Wcounter] = p->object1Info.varSize == 16 ? *((int16*)p->object1Info.varAddr) : *((int32*)p->object1Info.varAddr); #endif p->Wcounter++; if (p->Wcounter >= 1024) //åñëè äîøëè äî êîíöà { p->mode_reset = 0; //ðåæèì ÑÒÎÏ #if DLOG_DATA_SIZE == 16 p->control |= 192; // "äàííûå ãîòîâû" + "ïîääåðæèâàåòñÿ áëî÷íàÿ ïåðåäà÷à" #else p->control |= 192 | (1 << 8); // "äàííûå ãîòîâû" + "ïîääåðæèâàåòñÿ áëî÷íàÿ ïåðåäà÷à" + "32-áèòíûå äàííûå" #endif } return; } } } /*@}*/