/*! Copyright 2017 ÀÎ "ÍÈÈÝÒ" è ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ" Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. \file V_event_log.c \brief Ñîõðàíåíèå ñîáûòèé è âðåìåíè âîçíèêíîâåíèß â ÝíÎÇÓ Èñïîëüçóåòñß äðàéâåð ðàáîòû ñ ýíåðãîíåçàâèñèìîé ïàìßòüþ Ïîýòîìó âûçîâ init(); äîëæåí áûòü ïîñëå èíèöèàëèçàöèè ÝíÎÇÓ \author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru \version v 1.0 2009_01_20 */ /** \addtogroup W_event_log */ /*@{*/ #ifdef __cplusplus extern "C" { #endif #include //!<Ïðîòîêîëèðîâàíèå àâàðèé //Ïðîöåäóðû çàïèñè ñîáûòèé â ýíåðãîíåçàâèñèìóþ ôëåøêó î÷åíü äîëãèå (ñâÿçàíî ñ òàéìèíãàìè I2C-èíòåðôåéñà //è áîëüøèì îáúåìîì äàííûõ, ïåðåäàâàåìûì ïî I2C â ïðîöåññå çàïèñè). //Ïîýòîìó àëãîðèòì ðàáîòû òàêîé: //Åñëè íóæíî ïðî÷èòàòü àâàðèþ [Logger_Event_Read] (ñðî÷íî ñ÷èòûâàòü àâàðèþ èç áàíêà íå òðåáóåòñÿ) - //îíà ÷èòàåòñÿ â ôîíîâîì öèêëå ïðÿìèêîì èç ÝíÎÇÓ. //Åñëè íóæíî çàïèñàòü àâàðèþ â áàíê [Logger_Event_Write] - â ïðåðûâàíèè (íàïðèìåð, 1ìñ) äàííûå àâàðèè ïèøóòñÿ â FIFO; //çàòåì â ôîíîâîì öèêëå [Logger_Background_Calc] àâàðèè ÷èòàþòñÿ èç FIFO [Event_FIFO_Read] //(ïî îäíî çà 1 ôîíîâûé öèêë) è ïèøóòñÿ â ÝíÎÇÓ. //ïðî÷èòàòü ñîáûòèå èç FIFO (äëÿ äàëüíåéøåé çàïèñè â ÝíÎÇÓ). Uint16 Event_FIFO_Read(TEventFIFO* p,TEvent* ev) { if (p->busy_flag > 0) return EVENT_FIFO_BUSY; //âûñòàâëßåì ôëàæîê ðàáîòû ñ FIFO p->busy_flag = 1; if (p->number_of_msgs == 0) { //îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO p->busy_flag = 0; return EVENT_FIFO_EMPTY; } //÷èòàåì äàííûå èç FIFO ev->ev_code = p->msg_array[(p->read_ptr)].ev_code; ev->ev_time = p->msg_array[(p->read_ptr)].ev_time; ev->ev_num = p->msg_array[(p->read_ptr)].ev_num; //ïîäãîòîâêà FIFO ê ñëåäóþùåìó âûçîâó p->read_ptr++; if (p->read_ptr >= p->size) p->read_ptr = 0; p->number_of_msgs--; //îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO p->busy_flag = 0; return EVENT_FIFO_SUCCESSFUL; } //Çàïèñàòü ñîáûòèå â FIFO (âûçûâàåòñÿ â Logger_Event_Write, â ïðåðûâàíèè) Uint16 Event_FIFO_Write(TEventFIFO* p,TEvent* ev) { if (p->busy_flag > 0) return EVENT_FIFO_BUSY; //âûñòàâëßåì ôëàæîê ðàáîòû ñ FIFO p->busy_flag = 1; if (p->number_of_msgs == p->size) { //îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO p->busy_flag = 0; return EVENT_FIFO_FULL; } //çàïèñûâàåì äàííûå â FIFO p->msg_array[(p->write_ptr)].ev_code = ev->ev_code; p->msg_array[(p->write_ptr)].ev_time = ev->ev_time; p->msg_array[(p->write_ptr)].ev_num = ev->ev_num; //ïîäãîòîâêà FIFO ê ñëåäóþùåìó âûçîâó p->write_ptr++; if (p->write_ptr >= p->size)p->write_ptr = 0; p->number_of_msgs++; //îñâîáîæäàåì ôëàã ðàáîòû ñ FIFO p->busy_flag = 0; return EVENT_FIFO_SUCCESSFUL; } //èíèöèàëèçàöèÿ (åñëè áàíê çàáèò ìóñîðîì - âñå äàííûå FFFF, î÷èùàåì åãî) void Logger_Init(TLogger* p,Uint16 BS,Uint16 SA,Uint32* tptr) { TEvent tmp; Uint16 i; Uint16 last_log_num = 0; Uint16 last_log_index = 0; //èíèöèàëèçèðóåì âíóòðåííèå ïåðåìåííûå p->SPI_buf_size = BS; p->SPI_start_addr = SA; p->time_ptr = tptr; //äàëåå íóæíî ïðîñêàíèðîâàòü áóôåð â ÝíÎÇÓ - íàéòè ïîñëåäíþþ UserMem.MemStartAddr = p->SPI_start_addr; UserMem.data_length = 0; for (i=0;iSPI_buf_size;i++) { //÷èòàåì íîìåð UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&tmp.ev_num); UserMem.data_length = LOG_NUM_LENGTH; UserMem.read(&UserMem); //÷èòàåì âðåìß UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&tmp.ev_time); UserMem.data_length = LOG_TIME_LENGTH; UserMem.read(&UserMem); //÷èòàåì êîä UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&tmp.ev_code); UserMem.data_length = LOG_CODE_LENGTH; UserMem.read(&UserMem); //äåëàåì íåîáõîäèìûå ïðîâåðêè //åñëè âñå ïîëß 0xFFFF, òî ÷èñòèì âñþ ïàìßòü if ((tmp.ev_num == 0xFFFF) && (tmp.ev_time == 0xFFFFFFFF) && (tmp.ev_code == 0xFFFF)) { //÷èñòèì p->clear(p); //èíèöèàëèçèðóåì ïåðåìåííûå p->INTERNAL_last_log_num = 0; p->INTERNAL_last_log_index = 0; return; } //èùåì ïîñëåäíþþ çàïèñü if (last_log_num < tmp.ev_num) { last_log_num = tmp.ev_num; last_log_index = i; } } p->INTERNAL_last_log_num = last_log_num; p->INTERNAL_last_log_index = last_log_index; } //ôóíêöèß î÷èñòêè áóôåðà â ÝíÎÇÓ void Logger_Clear(TLogger* p) { Uint16 zero = 0; UserMem.MemStartAddr = p->SPI_start_addr; UserMem.MCUStartAddr = (Uint16*)(&zero); UserMem.data_length = 1; for (int i=0;i<(p->SPI_buf_size * (LOG_LENGTH));i++) { UserMem.write(&UserMem); UserMem.MemStartAddr++; } p->INTERNAL_last_log_index = 0; p->INTERNAL_last_log_num = 0; } //áûñòðàß ôóíêöèß çàïèñè ñîáûòèß â FIFO Uint16 Logger_Event_Write(TLogger* p,Uint16 code) { TEvent event; //ôîðìèðóåì äàííûå __disable_irq(); event.ev_time = *(p->time_ptr); event.ev_code = code; event.ev_num = ++p->INTERNAL_last_log_num; p->INTERNAL_last_log_code = code; __enable_irq(); //ïèøåì â FIFO return p->FIFO.write((struct SEventFIFO*)&(p->FIFO),(TEvent*)&event); } //ïðî÷èòàòü àâàðèþ èç áàíêà, ñëîæèòü äàííûå â TEvent* event void Logger_Event_Read(TLogger* p,Uint16 shift_index,TEvent* event) { Uint16 correction = 0; //ïðîâåðßåì ïðàâèëüíîñòü çàïðîñà if (shift_index > (p->SPI_buf_size - 1)) return; //ââîä êîððåêöèè äëß îðãàíèçàöèè êîëüöà if (((int16)p->INTERNAL_last_log_index - (int16)shift_index) < 0) correction = p->SPI_buf_size; //÷òåíèå íîìåðà UserMem.MemStartAddr = p->SPI_start_addr + ((p->INTERNAL_last_log_index - shift_index + correction)*(LOG_LENGTH)); UserMem.MCUStartAddr = (Uint16*)(&(event->ev_num)); UserMem.data_length = LOG_NUM_LENGTH; UserMem.read(&UserMem); //÷òåíèå âðåìåíè UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&(event->ev_time)); UserMem.data_length = LOG_TIME_LENGTH; UserMem.read(&UserMem); //÷òåíèå êîäà UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&(event->ev_code)); UserMem.data_length = LOG_CODE_LENGTH; UserMem.read(&UserMem); } //ôóíêöèß îáðàáîòêè FIFO è çàïèñè àâàðèé â ÝíÎÇÓ. Åñëè â FIFO ÷òî-òî êëàëè - çàïèøåì âî ôëåøêó. //Åñëè FIFO çàíÿòà èëè ïóñòàÿ - îòäûõàåì. void Logger_Background_Calc(TLogger* p) { Uint16 ret; TEvent event; //÷òîáû íå ñèëüíî çàòîðìàæèâàòü ôîíîâûé öèêë áóäåì çàïèñûâàòü ïî 1 çàïèñè çà ðàç ret = p->FIFO.read((struct SEventFIFO*)&(p->FIFO),(TEvent*)&event); if (ret == EVENT_FIFO_SUCCESSFUL) { //ïèøåì â ÝíÎÇÓ if (p->INTERNAL_last_log_index >= (p->SPI_buf_size - 1)) p->INTERNAL_last_log_index = 0; else p->INTERNAL_last_log_index++; //çàïèñü íîìåðà UserMem.MemStartAddr = p->SPI_start_addr + (p->INTERNAL_last_log_index)*(LOG_LENGTH); UserMem.MCUStartAddr = (Uint16*)(&(event.ev_num)); UserMem.data_length = LOG_NUM_LENGTH; UserMem.write(&UserMem); //çàïèñü âðåìåíè UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&(event.ev_time)); UserMem.data_length = LOG_TIME_LENGTH; UserMem.write(&UserMem); //çàïèñü êîäà UserMem.MemStartAddr += UserMem.data_length; UserMem.MCUStartAddr = (Uint16*)(&(event.ev_code)); UserMem.data_length = LOG_CODE_LENGTH; UserMem.write(&UserMem); } } //ôóíêöèÿ ïðîâåðêè è çàïèñè âèñÿùèõ â äàííûé ìîìåíò ôëàãîâ àâàðèé //Ïîñëåäîâàòåëüíî ñìîòðèòñÿ êàæäûé áèò ñëîâ àâàðèé è, åñëè îí âçâåäåí, íî åùå íå çàïèñàí, ïðîèçâîäèòñÿ çàïèñü. void Logger_ms_Calc(TLogger* p){ } #ifdef __cplusplus } // Extern "C" #endif /*@}*/