motorcontroldemo_028/Vsrc/V_event_log.c
2019-07-29 08:18:57 +03:00

253 lines
7.9 KiB
C

/*!
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 <main.h>
//!<Ïðîòîêîëèðîâàíèå àâàðèé
//Ïðîöåäóðû çàïèñè ñîáûòèé â ýíåðãîíåçàâèñèìóþ ôëåøêó î÷åíü äîëãèå (ñâÿçàíî ñ òàéìèíãàìè 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;i<p->SPI_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((TEventFIFO*)&(p->FIFO),&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((TEventFIFO*)&(p->FIFO),&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
/*@}*/