Добавлен CAN-доступ к регистратору УМП через отдельный канал ответов
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
void InitCan(int Port, int DevNum);
|
||||
void CAN_send(int Port, int data[], int Addr);
|
||||
extern int CAN_input_data[];
|
||||
|
||||
/* Íåáëîêèðóþùàÿ ïåðåäà÷à îòâåòîâ ëîããåðà îòäåëüíûì CAN mailbox. */
|
||||
void UMP_CAN_service(void);
|
||||
|
||||
39
Source/Internal/Include/ump_can_protocol.h
Normal file
39
Source/Internal/Include/ump_can_protocol.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Ñëóæåáíûé CAN-ïðîòîêîë ëîããåðà ÓÌÏ. Íå èñïîëüçóåò àäðåñà 0..127
|
||||
* òåõíîëîãè÷åñêîãî îáìåíà. Ôîðìàò ïîëåçíûõ äàííûõ ñîâìåñòèì ñ ïîðÿäêîì
|
||||
* ñëîâ ñòàðîãî CAN: MDL (ñëîâà 1,2), çàòåì MDH (ìàðêåð, ñëîâî 0).
|
||||
* Çàïðîñ: ìàðêåð 0x1F00, ñëîâî 0 = token:8 | function:8,
|
||||
* ñëîâà 1,2 = àäðåñ ðàñøèðåíèÿ è ÷èñëî ñëîâ/çàïèñûâàåìîå çíà÷åíèå.
|
||||
* Îòâåòû: ìàðêåð 0x1F00 + íîìåð ôðàãìåíòà, ñëîâî 0 = token:8 | error:8,
|
||||
* ñëîâà 1,2 = äâà ñëîâà åäèíîãî çàôèêñèðîâàííîãî ñíèìêà.
|
||||
* Áèòû ìàñêè çàïèñè â çàãîëîâêå çàïðîñà ðàâíû íóëþ: ñòàðàÿ ïëàòà
|
||||
* èãíîðèðóåò çàïðîñ, íå èçìåíÿÿ òåõíîëîãè÷åñêèå ðåãèñòðû. */
|
||||
#ifndef UMP_CAN_PROTOCOL_H
|
||||
#define UMP_CAN_PROTOCOL_H
|
||||
#include "log_to_mem.h"
|
||||
#define UMP_CAN_MARKER 0x1F00U
|
||||
#define UMP_CAN_MAX_WORDS 124U
|
||||
|
||||
/* Âûçûâàþùèé êîä çàùèùàåò âåñü ñíèìîê îò IRQ. Ôóíêöèÿ íå æä¸ò CAN è
|
||||
* íå ïèøåò çà ïðåäåëàìè reply[124]. Îøèáêè âîçâðàùàþòñÿ îòäåëüíûì êàäðîì. */
|
||||
static unsigned int ump_can_prepare(unsigned int function, unsigned int address,
|
||||
unsigned int value, unsigned int *reply, unsigned int *error)
|
||||
{
|
||||
unsigned int i;
|
||||
*error = 0;
|
||||
if (function == 3) {
|
||||
if (!((address == UMP_LOG_BASE && value == 16) ||
|
||||
(address == UMP_LOG_DATA && (value == 40 || value == 80 || value == 120)) ||
|
||||
(address == UMP_LOG_LIVE && value == 124))) *error = 2;
|
||||
else {
|
||||
for (i = 0; i < value; i++) reply[i] = ump_log_read(address+i);
|
||||
return value;
|
||||
}
|
||||
} else if (function == 6) {
|
||||
if (address < UMP_LOG_BASE || address > UMP_LOG_BASE+3) *error = 2;
|
||||
else if (!ump_log_write(address, value)) *error = 3;
|
||||
} else *error = 1;
|
||||
/* Äëÿ çàïèñè âîçâðàùàåì ýõî àäðåñà è çíà÷åíèÿ, äëÿ îøèáêè — å¸ êîíòåêñò. */
|
||||
reply[0] = address; reply[1] = value;
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "message.h"
|
||||
#include "peripher.h"
|
||||
#include "log_to_mem.h"
|
||||
#include "ump_can_protocol.h"
|
||||
|
||||
|
||||
// Prototype statements for functions found within this file.
|
||||
@@ -31,6 +32,16 @@ int CanTimeOutErrorTR = 0;
|
||||
|
||||
int wait=0;
|
||||
|
||||
/* MBOX2 âûäåëåí ïîä îòâåòû ðåãèñòðàòîðà; øòàòíûé MBOX0 ïðîäîëæàåò
|
||||
* ïåðåäàâàòü òåõíîëîãè÷åñêèå äàííûå íåçàâèñèìî. ISR òîëüêî ñòàâèò çàïðîñ,
|
||||
* à ñíèìîê è îòïðàâêà êîðîòêèìè øàãàìè âûïîëíÿþòñÿ â îñíîâíîì öèêëå. */
|
||||
static volatile unsigned int ump_can_pending;
|
||||
static volatile unsigned int ump_can_tag, ump_can_address, ump_can_value;
|
||||
static unsigned int ump_can_reply[UMP_CAN_MAX_WORDS];
|
||||
static unsigned int ump_can_length, ump_can_index, ump_can_reply_tag;
|
||||
static unsigned int ump_can_waiting;
|
||||
static unsigned long ump_can_sent_at;
|
||||
|
||||
void InitCan(int Port, int DevNum)
|
||||
{
|
||||
struct ECAN_REGS ECanShadow;
|
||||
@@ -62,6 +73,7 @@ void InitCan(int Port, int DevNum)
|
||||
// Specify that 8 bits will be sent/received
|
||||
ECanMboxes->MBOX0.MSGCTRL.all = 0x00000008;
|
||||
ECanMboxes->MBOX1.MSGCTRL.all = 0x00000008;
|
||||
ECanMboxes->MBOX2.MSGCTRL.all = 0x00000008;
|
||||
|
||||
// Disable all Mailboxes
|
||||
// Required before writing the MSGIDs
|
||||
@@ -73,11 +85,12 @@ void InitCan(int Port, int DevNum)
|
||||
// çàäàåì àäðåñ 1 àùèêa íà ïðèåì
|
||||
ECanMboxes->MBOX1.MSGID.all = id + DevNum; //ïîìåíàòü!!!! 1 è 0!!!
|
||||
|
||||
// задаем режимы работы ащикa 0 на передачу, остальные на прием
|
||||
ECanRegs->CANMD.all = 0xFFFFFFFE;
|
||||
// MBOX0 è MBOX2 ïåðåäàþò äàííûå; MBOX1 ïðèíèìàåò êîìàíäû.
|
||||
ECanMboxes->MBOX2.MSGID.all = id + 0x20 + DevNum;
|
||||
ECanRegs->CANMD.all = 0xFFFFFFFA;
|
||||
|
||||
// выбираем только 2 ащикa дла работы, остальные запрещаем
|
||||
ECanRegs->CANME.all = 0x00000003;
|
||||
// Âêëþ÷àåì òðè mailbox: òåëåìåòðèÿ, êîìàíäû è îòâåòû ëîããåðà.
|
||||
ECanRegs->CANME.all = 0x00000007;
|
||||
|
||||
// Clear all TAn bits
|
||||
ECanRegs->CANTA.all = 0xFFFFFFFF;
|
||||
@@ -197,6 +210,18 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
|
||||
hiword = ECanMboxes->MBOX1.MDH.all;
|
||||
loword = ECanMboxes->MBOX1.MDL.all;
|
||||
|
||||
/* Ñëóæåáíûé çàïðîñ ëîããåðà íå ÿâëÿåòñÿ êîìàíäîé ÓÌÏ è ñàì íå äîëæåí
|
||||
* çàïîëíÿòü æóðíàë CAN-ñîáûòèÿìè ïðè îíëàéí-÷òåíèè. Êîðîòêèå êàäðû
|
||||
* îòáðàñûâàþòñÿ: íåçàïîëíåííûå áàéòû mailbox ìîãëè îñòàòüñÿ îò ïðîøëîãî. */
|
||||
if ((unsigned int)(hiword >> 16) == UMP_CAN_MARKER) {
|
||||
if (ECanMboxes->MBOX1.MSGCTRL.bit.DLC == 8) {
|
||||
ump_can_tag = (unsigned int)hiword;
|
||||
ump_can_address = (unsigned int)(loword >> 16);
|
||||
ump_can_value = (unsigned int)loword;
|
||||
ump_can_pending = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
adr = (hiword >> 16);
|
||||
|
||||
bit[0] = adr & 0x8000;
|
||||
@@ -260,3 +285,52 @@ interrupt void CANa_reset_err(void)
|
||||
//===========================================================================
|
||||
// No more.
|
||||
//===========================================================================
|
||||
|
||||
|
||||
/* Îäèí âûçîâ îáñëóæèâàåò ìàêñèìóì îäèí êàäð è íèêîãäà íå æä¸ò ACK â öèêëå.
|
||||
* Ñíèìîê ôèêñèðóåòñÿ îäèí ðàç íà çàïðîñ: CAN-ôðàãìåíòû íå ñìåøèâàþò
|
||||
* çíà÷åíèÿ äî/ïîñëå ïåðåêëþ÷åíèÿ êîëüöåâîãî áàíêà. Íîâûå çàïðîñû çàáèðàåì
|
||||
* ïîñëå çàâåðøåíèÿ ïðåäûäóùåãî îòâåòà. GUI äåðæèò òîëüêî îäèí çàïðîñ. */
|
||||
void UMP_CAN_service(void)
|
||||
{
|
||||
unsigned int saved, tag, address, value, error;
|
||||
unsigned long hiword, loword;
|
||||
if (ump_can_waiting) {
|
||||
if (ECanaRegs.CANTA.all & 4UL) {
|
||||
ECanaRegs.CANTA.all = 4UL;
|
||||
ump_can_waiting = 0;
|
||||
} else if ((ECanaRegs.CANAA.all & 4UL) ||
|
||||
((unsigned long)CpuTimer1.InterruptCount - ump_can_sent_at > 250UL)) {
|
||||
/* Íåò ïîäòâåðæäåíèÿ øèíû: îòìåíÿåì òîëüêî ñëóæåáíûé mailbox.
|
||||
* GUI îáíàðóæèò íåïîëíûé îòâåò ïî òàéì-àóòó; óïðàâëåíèå MBOX0
|
||||
* è ïðè¸ì êîìàíä MBOX1 ïðîäîëæàþòñÿ. */
|
||||
ECanaRegs.CANTRR.all = 4UL;
|
||||
/* Äî ôàêòè÷åñêîãî çàâåðøåíèÿ îòìåíû mailbox íå ïåðåèñïîëüçóåì. */
|
||||
if (!(ECanaRegs.CANAA.all & 4UL)) return;
|
||||
ECanaRegs.CANAA.all = 4UL;
|
||||
ump_can_waiting = 0;
|
||||
ump_can_length = 0;
|
||||
} else return;
|
||||
}
|
||||
if (ump_can_index >= ump_can_length && ump_can_pending) {
|
||||
saved = __disable_interrupts();
|
||||
tag = ump_can_tag; address = ump_can_address; value = ump_can_value;
|
||||
ump_can_pending = 0;
|
||||
ump_can_length = ump_can_prepare(tag & 0xFF, address, value, ump_can_reply, &error);
|
||||
ump_can_reply_tag = (tag & 0xFF00) | error;
|
||||
ump_can_index = 0;
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
if (ump_can_index >= ump_can_length) return;
|
||||
/* Ïåðåä ñëåäóþùèì ôðàãìåíòîì óñòóïàåì øòàòíîé òåëåìåòðèè MBOX0. */
|
||||
if (ECanaRegs.CANTRS.all & 1UL) return;
|
||||
hiword = ((unsigned long)(UMP_CAN_MARKER + ump_can_index/2) << 16) | ump_can_reply_tag;
|
||||
loword = ((unsigned long)ump_can_reply[ump_can_index] << 16) | ump_can_reply[ump_can_index+1];
|
||||
ECanaRegs.CANTA.all = 4UL; ECanaRegs.CANAA.all = 4UL;
|
||||
ECanaMboxes.MBOX2.MDH.all = hiword;
|
||||
ECanaMboxes.MBOX2.MDL.all = loword;
|
||||
ump_can_sent_at = CpuTimer1.InterruptCount;
|
||||
ECanaRegs.CANTRS.all = 4UL;
|
||||
ump_can_waiting = 1;
|
||||
ump_can_index += 2;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ void main()
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Чтение логгера по CAN не блокирует цикл управления. */
|
||||
UMP_CAN_service();
|
||||
if(CanGO)
|
||||
{
|
||||
CanGO=0;
|
||||
|
||||
Reference in New Issue
Block a user