Сохранить русские комментарии и настройки проекта в UTF-8

Добавить пояснения к исходникам, заголовкам TI, настройкам CCS и существующим проверкам. Зафиксировать правила кодировки, обзор модулей и аудит комментариев.
This commit is contained in:
2026-10-12 12:24:48 +03:00
parent 378e06a281
commit f741741cf8
137 changed files with 21576 additions and 2134 deletions
+278 -35
View File
@@ -1,294 +1,490 @@
/* Штатный eCAN и отдельный служебный обмен УМП/GAS. Русские пояснения сохранены в UTF-8. */
/* Подключает "DSP2833x_Device.h": поставляемое TI описание Device для семейства C2833x. */
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
/* Подключает "DSP2833x_SWPrioritizedIsrLevels.h": поставляемое TI описание SWPrioritizedIsrLevels для семейства C2833x. */
#include "DSP2833x_SWPrioritizedIsrLevels.h"
/* Подключает "filter_bat2.h": накопительный фильтр измерительных каналов. */
#include "filter_bat2.h"
/* Подключает "measure.h": обработка датчиков, вычисление величин и миллисекундный такт системы. */
#include "measure.h"
/* Подключает "package.h": адреса устройств, типы плат и псевдонимы технологических регистров. */
#include "package.h" // DSP281x Headerfile Include File
/* Подключает "ecan.h": штатный eCAN и отдельный служебный обмен УМП/GAS. */
#include "ecan.h" // DSP281x Headerfile Include File
/* Подключает "tools.h": настройка внешней памяти и служебные задержки. */
#include "tools.h" // DSP281x Headerfile Include File
/* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */
#include "RS485.h"
/* Подключает "message.h": обработка Modbus, заводские параметры и сохранение настроек. */
#include "message.h"
/* Подключает "peripher.h": перемычки режима платы, дискретные входы и выходы. */
#include "peripher.h"
/* Подключает "log_to_mem.h": двухбанковый регистратор событий нагрузки во внешней RAM. */
#include "log_to_mem.h"
/* Подключает "DAC.h": выход ЦАП и автомат защиты нагрузки с проверкой напряжения и свежести CAN. */
#include "DAC.h"
/* Подключает "ump_can_protocol.h": настройки и интерфейс ump_can_protocol. */
#include "ump_can_protocol.h"
/* Подключает "gas167.h": дополнительная карта GAS 167/v1 только для новой EEPROM M95M02. */
#include "gas167.h"
// Prototype statements for functions found within this file.
/* Принимает CAN в прерывании, разбирает служебный запрос или передаёт данные штатному протоколу. */
interrupt void CANa_handler(void);
/* Объявляет интерфейс функции CANa_reset_err; реализация вызывается через этот прототип. */
interrupt void CANa_reset_err(void);
// Global variable for this example
/* Объявляет ErrorCount — ошибка число. */
Uint32 ErrorCount;
/* Объявляет MessageReceivedCount — Message Received число. */
Uint32 MessageReceivedCount;
/* Объявляет MessageTransivedCount — Message Transived число. Начальное значение задаётся справа от знака равенства. */
Uint32 MessageTransivedCount=0;
/* Объявляет TestMbox1 — данные TestMbox1. Начальное значение задаётся справа от знака равенства. */
Uint32 TestMbox1 = 0;
/* Объявляет TestMbox2 — данные TestMbox2. Начальное значение задаётся справа от знака равенства. */
Uint32 TestMbox2 = 0;
/* Объявляет TestMbox3 — данные TestMbox3. Начальное значение задаётся справа от знака равенства. */
Uint32 TestMbox3 = 0;
/* Объявляет CanTimeOutErrorTR — CAN Time Out ошибка TR. Начальное значение задаётся справа от знака равенства. */
int CanTimeOutErrorTR = 0;
/* Объявляет wait — данные wait. Начальное значение задаётся справа от знака равенства. */
int wait=0;
/* MBOX2 выделен под ответы регистратора; штатный MBOX0 продолжает
* передавать технологические данные независимо. ISR только ставит запрос,
* а снимок и отправка короткими шагами выполняются в основном цикле. */
/* MBOX2 выделен под ответы регистратора; штатный MBOX0 продолжает
* передавать технологические данные независимо. ISR только ставит запрос,
* а снимок и отправка короткими шагами выполняются в основном цикле. */
/* Объявляет ump_can_pending — флаг ожидающего запроса служебного CAN между ISR и главным циклом. volatile требует фактического чтения или записи при каждом доступе. */
static volatile unsigned int ump_can_pending;
/* Объявляет ump_can_tag — ump CAN tag; ump_can_address — ump CAN адрес; ump_can_value — ump CAN value. volatile требует фактического чтения или записи при каждом доступе. */
static volatile unsigned int ump_can_tag, ump_can_address, ump_can_value;
/* Объявляет ump_can_reply — замороженные слова ответа служебного CAN. */
static unsigned int ump_can_reply[UMP_CAN_MAX_WORDS];
/* Объявляет ump_can_length — ump CAN длина; ump_can_index — ump CAN index; ump_can_reply_tag — ump CAN reply tag. */
static unsigned int ump_can_length, ump_can_index, ump_can_reply_tag;
/* Объявляет ump_can_waiting — ump CAN waiting. */
static unsigned int ump_can_waiting;
/* Объявляет ump_can_sent_at — время последней передачи фрагмента ответа CAN. */
static unsigned long ump_can_sent_at;
/* Настраивает eCAN, скорость, почтовые ящики и маршрутизацию прерываний для выбранного режима платы. */
void InitCan(int Port, int DevNum)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
struct ECAN_REGS ECanShadow;
/* Описывает структуру ECAN_REGS ECanShadow;; порядок полей определяет расположение данных. */
struct ECAN_REGS ECanShadow;
/* Продолжает список аргументов, полей или выражение volatile struct ECAN_REGS * ECanRegs;; порядок элементов сохраняется. */
volatile struct ECAN_REGS * ECanRegs;
/* Продолжает список аргументов, полей или выражение volatile struct ECAN_MBOXES * ECanMboxes;; порядок элементов сохраняется. */
volatile struct ECAN_MBOXES * ECanMboxes;
/* Продолжает список аргументов, полей или выражение volatile struct MOTO_REGS * ECanMOTORegs;; порядок элементов сохраняется. */
volatile struct MOTO_REGS * ECanMOTORegs;
/* Объявляет id — данные id. Начальное значение задаётся справа от знака равенства. */
long id = 0x80BA0000;
/* Изменяет счётчик в выражении DevNum--; на один для следующего шага. */
DevNum--;
/* Проверяет if(DevNum<0)DevNum=0; последующий оператор выполняется только при истинном условии. */
if(DevNum<0)DevNum=0;
/* Проверяет if(DevNum>15)DevNum=15; последующий оператор выполняется только при истинном условии. */
if(DevNum>15)DevNum=15;
// Configure CAN pins using GPIO regs here
/* Разрешение записи в защищённые регистры периферии. */
EALLOW;
/* Записывает ECanRegs значением &ECanaRegs; E CAN Regs. */
ECanRegs = &ECanaRegs;
/* Записывает ECanMboxes значением &ECanaMboxes; E CAN Mboxes. */
ECanMboxes = &ECanaMboxes;
/* Записывает ECanMOTORegs значением &ECanaMOTORegs; E CAN MOTO Regs. */
ECanMOTORegs = &ECanaMOTORegs;
/* Записывает GpioCtrlRegs.GPAMUX2.bit.GPIO30 значением 1; аппаратная линия ввода/вывода GPIO30. */
GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;
/* Записывает GpioCtrlRegs.GPAMUX2.bit.GPIO31 значением 1; аппаратная линия ввода/вывода GPIO31. */
GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;
// Configure the eCAN RX and TX pins for eCAN transmissions
/* Записывает ECanRegs->CANTIOC.all значением 8; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANTIOC.all = 8; // only 3rd bit, TXFUNC, is significant
/* Записывает ECanRegs->CANRIOC.all значением 8; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANRIOC.all = 8; // only 3rd bit, RXFUNC, is significant
// Specify that 8 bits will be sent/received
/* Записывает ECanMboxes->MBOX0.MSGCTRL.all значением 0x00000008; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX0.MSGCTRL.all = 0x00000008;
/* Записывает ECanMboxes->MBOX1.MSGCTRL.all значением 0x00000008; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX1.MSGCTRL.all = 0x00000008;
/* Записывает ECanMboxes->MBOX2.MSGCTRL.all значением 0x00000008; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX2.MSGCTRL.all = 0x00000008;
// Disable all Mailboxes
// Required before writing the MSGIDs
/* Записывает ECanRegs->CANME.all значением 0; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANME.all = 0;
// задаем адрес 0 ащикa на передачу
ECanMboxes->MBOX0.MSGID.all = id + 0x10 + DevNum;
// задаем адрес 0 ащикa на передачу
/* Записывает ECanMboxes->MBOX0.MSGID.all значением id + 0x10 + DevNum; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX0.MSGID.all = id + 0x10 + DevNum;
// задаем адрес 1 ащикa на прием
ECanMboxes->MBOX1.MSGID.all = id + DevNum; //поменать!!!! 1 и 0!!!
// задаем адрес 1 ащикa на прием
/* Записывает ECanMboxes->MBOX1.MSGID.all значением id + DevNum; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX1.MSGID.all = id + DevNum; //поменать!!!! 1 и 0!!!
// MBOX0 и MBOX2 передают данные; MBOX1 принимает команды.
// MBOX0 и MBOX2 передают данные; MBOX1 принимает команды.
/* Записывает ECanMboxes->MBOX2.MSGID.all значением id + 0x20 + DevNum; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX2.MSGID.all = id + 0x20 + DevNum;
/* Записывает ECanRegs->CANMD.all значением 0xFFFFFFFA; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANMD.all = 0xFFFFFFFA;
// Включаем три mailbox: телеметрия, команды и ответы логгера.
// Включаем три mailbox: телеметрия, команды и ответы логгера.
/* Записывает ECanRegs->CANME.all значением 0x00000007; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANME.all = 0x00000007;
// Clear all TAn bits
/* Записывает ECanRegs->CANTA.all значением 0xFFFFFFFF; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANTA.all = 0xFFFFFFFF;
// Clear all RMPn bits
/* Записывает ECanRegs->CANRMP.all значением 0xFFFFFFFF; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANRMP.all = 0xFFFFFFFF;
// Clear all interrupt flag bits
/* Записывает ECanRegs->CANGIF0.all значением 0xFFFFFFFF; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANGIF0.all = 0xFFFFFFFF;
/* Записывает ECanRegs->CANGIF1.all значением 0xFFFFFFFF; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANGIF1.all = 0xFFFFFFFF;
// Clear all error and status bits
/* Записывает ECanRegs->CANES.all значением 0xffffffff; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANES.all=0xffffffff;
// Request permission to change the configuration registers
/* Записывает ECanShadow.CANMC.all значением 0; представление регистра целым словом без разбиения на битовые поля. */
ECanShadow.CANMC.all = 0;
/* Записывает ECanShadow.CANMC.bit.MBCC значением 1; данные MBCC. */
ECanShadow.CANMC.bit.MBCC = 1; // Mailbox timestamp counter clear bit
/* Записывает ECanShadow.CANMC.bit.TCC значением 1; данные TCC. */
ECanShadow.CANMC.bit.TCC = 1; // Time stamp counter MSB clear bit
/* Записывает ECanShadow.CANMC.bit.SCB значением 1; данные SCB. */
ECanShadow.CANMC.bit.SCB = 1; // eCAN mode (reqd to access 32 mailboxes)
/* Записывает ECanShadow.CANMC.bit.WUBA значением 1; данные WUBA. */
ECanShadow.CANMC.bit.WUBA = 1; // Wake up on bus activity
/* Записывает ECanShadow.CANMC.bit.ABO значением 1; данные ABO. */
ECanShadow.CANMC.bit.ABO = 1; // Auto bus on
ECanShadow.CANMC.bit.CCR = 1;
/* Записывает ECanShadow.CANMC.bit.CCR значением 1; данные CCR. */
ECanShadow.CANMC.bit.CCR = 1;
// ECanShadow.CANMC.bit.STM = 1; // self-test loop-back
/* Записывает ECanRegs->CANMC.all значением ECanShadow.CANMC.all; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANMC.all = ECanShadow.CANMC.all;
/* Повторяет или ожидает, пока выполняется while(!ECanRegs->CANES.bit.CCE);. */
while(!ECanRegs->CANES.bit.CCE); // Wait for CCE bit to be set..
// настриваем скорость CAN
// настриваем скорость CAN
/* Записывает ECanShadow.CANBTC.all значением ECanRegs->CANBTC.all; представление регистра целым словом без разбиения на битовые поля. */
ECanShadow.CANBTC.all = ECanRegs->CANBTC.all;
/* Записывает ECanShadow.CANBTC.bit.SJWREG значением 1; данные SJWREG. */
ECanShadow.CANBTC.bit.SJWREG=1;
/* Записывает ECanShadow.CANBTC.bit.BRPREG значением (CLKMULT * 3) - 1; данные BRPREG. */
ECanShadow.CANBTC.bit.BRPREG = (CLKMULT * 3) - 1;
/* Записывает ECanShadow.CANBTC.bit.TSEG1REG значением 15; данные TSEG1REG. */
ECanShadow.CANBTC.bit.TSEG1REG = 15;
/* Записывает ECanShadow.CANBTC.bit.TSEG2REG значением 2; данные TSEG2REG. */
ECanShadow.CANBTC.bit.TSEG2REG = 2;
/* Записывает ECanRegs->CANBTC.all значением ECanShadow.CANBTC.all; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANBTC.all = ECanShadow.CANBTC.all;
/* Записывает ECanShadow.CANMC.bit.CCR значением 0; данные CCR. */
ECanShadow.CANMC.bit.CCR = 0; // Set CCR = 0
/* Записывает ECanRegs->CANMC.all значением ECanShadow.CANMC.all; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANMC.all = ECanShadow.CANMC.all;
/* Повторяет или ожидает, пока выполняется while(ECanRegs->CANES.bit.CCE);. */
while(ECanRegs->CANES.bit.CCE); // Wait for CCE bit to be cleared..
// задаем таймауты дла ожиданиа отправки получениа посылки
// задаем таймауты дла ожиданиа отправки получениа посылки
/* Записывает ECanMOTORegs->MOTO0 значением 550000; E CAN MOTO Regs 0. */
ECanMOTORegs->MOTO0 = 550000;
/* Записывает ECanMOTORegs->MOTO1 значением 550000; E CAN MOTO Regs 1. */
ECanMOTORegs->MOTO1 = 550000;
/* Записывает ECanRegs->CANTOC.all значением 1; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANTOC.all = 1;
/* Записывает ECanRegs->CANTOS.all значением 0; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANTOS.all = 0; // clear all time-out flags
/* Записывает ECanRegs->CANTSC значением 0; E CAN Regs CANTSC. */
ECanRegs->CANTSC = 0; // clear time-out counter
/* Записывает ECanShadow.CANGIM.all значением 0; представление регистра целым словом без разбиения на битовые поля. */
ECanShadow.CANGIM.all = 0;
/* Записывает ECanRegs->CANMIM.all значением 2; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANMIM.all = 2; // Enable interrupts of box 1
/* Записывает ECanRegs->CANMIL.all значением 0x00000000; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANMIL.all = 0x00000000; // All mailbox interrupts are generated on interrupt line 0.
/* Записывает ECanShadow.CANGIM.bit.I0EN значением 1; данные I0EN. */
ECanShadow.CANGIM.bit.I0EN = 1;
/* Записывает ECanShadow.CANGIM.bit.MTOM значением 1; данные MTOM. */
ECanShadow.CANGIM.bit.MTOM = 1;
/* Записывает ECanShadow.CANGIM.bit.I1EN значением 1; данные I1EN. */
ECanShadow.CANGIM.bit.I1EN = 1;
/* Записывает ECanShadow.CANGIM.bit.GIL значением 1; данные GIL. */
ECanShadow.CANGIM.bit.GIL = 1;
/* Записывает ECanRegs->CANGIM.all значением ECanShadow.CANGIM.all; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANGIM.all = ECanShadow.CANGIM.all;
/* Записывает PieVectTable.ECAN0INTA значением &CANa_handler; данные ECAN0INTA. */
PieVectTable.ECAN0INTA = &CANa_handler;
/* Записывает PieCtrlRegs.PIEIER9.bit.INTx5 значением 1; данные INTx5. */
PieCtrlRegs.PIEIER9.bit.INTx5=1; // PIE Group 9, INT6
/* Записывает PieVectTable.ECAN1INTA значением &CANa_reset_err; данные ECAN1INTA. */
PieVectTable.ECAN1INTA = &CANa_reset_err;
/* Записывает PieCtrlRegs.PIEIER9.bit.INTx6 значением 1; данные INTx6. */
PieCtrlRegs.PIEIER9.bit.INTx6=1; // PIE Group 9, INT6
/* Устанавливает биты IER значением M_INT9; регистр разрешения прерываний ядра C28x. */
IER |= M_INT9; // Enable CPU INT
/* Закрытие доступа к защищённым регистрам периферии. */
EDIS;
// завершили настройку CAN ащиков
// завершили настройку CAN ащиков
/* Записывает MessageReceivedCount значением 0; Message Received число. */
MessageReceivedCount = 0;
/* Записывает ErrorCount значением 0; ошибка число. */
ErrorCount = 0;
/* Записывает CanTimeOutErrorTR значением 0; CAN Time Out ошибка TR. */
CanTimeOutErrorTR=0;
/* Записывает MessageTransivedCount значением 0; Message Transived число. */
MessageTransivedCount=0;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Упаковывает адрес и технологические слова в штатный CAN-кадр и запускает передачу mailbox. */
void CAN_send(int Port, int data[], int Addr)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
/* Объявляет hiword — данные hiword; loword — данные loword. */
unsigned long hiword,loword;
/* Продолжает список аргументов, полей или выражение volatile struct ECAN_REGS * ECanRegs;; порядок элементов сохраняется. */
volatile struct ECAN_REGS * ECanRegs;
/* Продолжает список аргументов, полей или выражение volatile struct ECAN_MBOXES * ECanMboxes;; порядок элементов сохраняется. */
volatile struct ECAN_MBOXES * ECanMboxes;
/* Записывает ECanRegs значением &ECanaRegs; E CAN Regs. */
ECanRegs = &ECanaRegs;
/* Записывает ECanMboxes значением &ECanaMboxes; E CAN Mboxes. */
ECanMboxes = &ECanaMboxes;
/* Проверяет if(wait); последующий оператор выполняется только при истинном условии. */
if(wait)
/* Проверяет if(!(ECanRegs->CANTA.all & 1)); последующий оператор выполняется только при истинном условии. */
if(!(ECanRegs->CANTA.all & 1))
/* Проверяет if(!(ECanRegs->CANAA.all & 1)); последующий оператор выполняется только при истинном условии. */
if(!(ECanRegs->CANAA.all & 1))
/* Завершает CAN_send без возвращаемого значения. */
return;
/* Записывает ECanRegs->CANTA.all значением 1; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANTA.all = 1;
/* Записывает ECanRegs->CANAA.all значением 1; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANAA.all = 1;
/* Записывает hiword значением ((((Uint32) Addr ) & 0xffff)<<16)| 0xE0000000 |; данные hiword. */
hiword= ((((Uint32) Addr ) & 0xffff)<<16)| 0xE0000000 |
/* Продолжает список аргументов, полей или выражение ((((Uint32)data[Addr ]) & 0xffff) );; порядок элементов сохраняется. */
((((Uint32)data[Addr ]) & 0xffff) );
/* Записывает loword значением ((((Uint32)data[Addr+1]) & 0xffff)<<16)|; данные loword. */
loword= ((((Uint32)data[Addr+1]) & 0xffff)<<16)|
/* Продолжает список аргументов, полей или выражение ((((Uint32)data[Addr+2]) & 0xffff) );; порядок элементов сохраняется. */
((((Uint32)data[Addr+2]) & 0xffff) );
/* Записывает ECanMboxes->MBOX0.MDH.all значением hiword; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX0.MDH.all = hiword;
/* Записывает ECanMboxes->MBOX0.MDL.all значением loword; представление регистра целым словом без разбиения на битовые поля. */
ECanMboxes->MBOX0.MDL.all = loword;
/* Разрешение записи в защищённые регистры периферии. */
EALLOW;
/* Записывает ECanRegs->CANTSC значением 0; E CAN Regs CANTSC. */
ECanRegs->CANTSC = 0; // clear time-out counter
/* Закрытие доступа к защищённым регистрам периферии. */
EDIS;
ECanRegs->CANTRS.all = 1; // запустить передачу
/* Записывает ECanRegs->CANTRS.all значением 1; представление регистра целым словом без разбиения на битовые поля. */
ECanRegs->CANTRS.all = 1; // запустить передачу
/* Записывает wait значением 1; данные wait. */
wait=1;
/* Вызывает led1_toggle с аргументами () в текущей последовательности операций. */
led1_toggle();
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Начинает функцию Handlai; назначение модуля — штатный eCAN и отдельный служебный обмен УМП/GAS. */
void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
/* Объявляет adr — данные adr. */
unsigned int adr;
/* Объявляет bit — представление регистра отдельными битовыми полями. */
unsigned int bit[3];
/* Объявляет hiword — данные hiword; loword — данные loword. */
unsigned long hiword,loword;
/* Объявляет Data — данные. */
int Data[3];
/* Записывает Lonely значением 0; данные Lonely. */
Lonely=0;
/* Записывает hiword значением ECanMboxes->MBOX1.MDH.all; данные hiword. */
hiword = ECanMboxes->MBOX1.MDH.all;
/* Записывает loword значением ECanMboxes->MBOX1.MDL.all; данные loword. */
loword = ECanMboxes->MBOX1.MDL.all;
/* Служебный запрос логгера не является командой УМП и сам не должен
* заполнять журнал CAN-событиями при онлайн-чтении. Короткие кадры
* отбрасываются: незаполненные байты mailbox могли остаться от прошлого. */
/* Служебный запрос логгера не является командой УМП и сам не должен
* заполнять журнал CAN-событиями при онлайн-чтении. Короткие кадры
* отбрасываются: незаполненные байты mailbox могли остаться от прошлого. */
/* Проверяет if ((unsigned int)(hiword >> 16) == UMP_CAN_MARKER); последующий оператор выполняется только при истинном условии. */
if ((unsigned int)(hiword >> 16) == UMP_CAN_MARKER) {
/* Проверяет if (ECanMboxes->MBOX1.MSGCTRL.bit.DLC == 8 и (hiword & 0xFF00UL)); последующий оператор выполняется только при истинном условии. */
if (ECanMboxes->MBOX1.MSGCTRL.bit.DLC == 8 && (hiword & 0xFF00UL)) {
/* Записывает ump_can_tag значением (unsigned int)hiword; ump CAN tag. */
ump_can_tag = (unsigned int)hiword;
/* Записывает ump_can_address значением (unsigned int)(loword >> 16); ump CAN адрес. */
ump_can_address = (unsigned int)(loword >> 16);
/* Записывает ump_can_value значением (unsigned int)loword; ump CAN value. */
ump_can_value = (unsigned int)loword;
/* Записывает ump_can_pending значением 1; флаг ожидающего запроса служебного CAN между ISR и главным циклом. */
ump_can_pending = 1;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Завершает Handlai без возвращаемого значения. */
return;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Записывает adr значением (hiword >> 16); данные adr. */
adr = (hiword >> 16);
/* Записывает bit[0] значением adr & 0x8000; представление регистра отдельными битовыми полями. */
bit[0] = adr & 0x8000;
/* Записывает bit[1] значением adr & 0x4000; представление регистра отдельными битовыми полями. */
bit[1] = adr & 0x4000;
/* Записывает bit[2] значением adr & 0x2000; представление регистра отдельными битовыми полями. */
bit[2] = adr & 0x2000;
/* Оставляет биты маски adr значением 0x1fff; данные adr. */
adr &= 0x1fff;
/* Записывает Data[0] значением (hiword ) & 0xffff; данные. */
Data[0] = (hiword ) & 0xffff;
/* Записывает Data[1] значением (loword>>16) & 0xffff; данные. */
Data[1] = (loword>>16) & 0xffff;
/* Записывает Data[2] значением (loword ) & 0xffff; данные. */
Data[2] = (loword ) & 0xffff;
/* Проверяет if(bit[0]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */
if(bit[0]) if(adr < ANSWER_LEN &&
/* Записывает modbus[adr] значением Data[0]; adr++; массив технологических регистров; слово int на C28x занимает 16 бит. */
!(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[0]; adr++;
/* Проверяет if(bit[1]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */
if(bit[1]) if(adr < ANSWER_LEN &&
/* Записывает modbus[adr] значением Data[1]; adr++; массив технологических регистров; слово int на C28x занимает 16 бит. */
!(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[1]; adr++;
/* Проверяет if(bit[2]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */
if(bit[2]) if(adr < ANSWER_LEN &&
/* Записывает modbus[adr] значением Data[2]; массив технологических регистров; слово int на C28x занимает 16 бит. */
!(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[2];
/* Фиксируем применённую команду до выхода из обработчика CAN. */
/* Фиксируем применённую команду до выхода из обработчика CAN. */
/* A short frame cannot confirm voltage freshness. Service frames
* UMP_MARKER return above and do not refresh this timeout. */
/* Проверяет if (ECanMboxes->MBOX1.MSGCTRL.bit.DLC == 8); последующий оператор выполняется только при истинном условии. */
if (ECanMboxes->MBOX1.MSGCTRL.bit.DLC == 8)
/* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */
Load_voltage_can((unsigned int)(hiword >> 16), Data[0], Data[1], Data[2]);
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
ump_log_can((unsigned int)(hiword >> 16), Data[0], Data[1], Data[2]);
/* Вызывает led2_toggle с аргументами () в текущей последовательности операций. */
led2_toggle();
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Принимает CAN в прерывании, разбирает служебный запрос или передаёт данные штатному протоколу. */
interrupt void CANa_handler(void)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
// Set interrupt priority:
/* Объявляет TempPIEIER — сохранённая маска разрешённых прерываний группы PIE. volatile требует фактического чтения или записи при каждом доступе. Начальное значение задаётся справа от знака равенства. */
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
/* Устанавливает биты IER значением M_INT9; регистр разрешения прерываний ядра C28x. */
IER |= M_INT9;
/* Оставляет биты маски IER значением MINT9; регистр разрешения прерываний ядра C28x. */
IER &= MINT9; // Set "global" priority
/* Оставляет биты маски PieCtrlRegs.PIEIER9.all значением MG95; представление регистра целым словом без разбиения на битовые поля. */
PieCtrlRegs.PIEIER9.all &= MG95; // Set "group" priority
/* Записывает PieCtrlRegs.PIEACK.all значением 0xFFFF; представление регистра целым словом без разбиения на битовые поля. */
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
/* Разрешение маскируемых прерываний ядра. */
EINT;
/* Вызывает Handlai с аргументами (&ECanaMboxes) в текущей последовательности операций. */
Handlai(&ECanaMboxes);
/* Записывает ECanaRegs.CANRMP.all значением 2; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANRMP.all = 2;
/* Устанавливает биты PieCtrlRegs.PIEACK.bit.ACK9 значением 1; данные ACK9. */
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
// Restore registers saved:
/* Запрет маскируемых прерываний ядра. */
DINT;
/* Записывает PieCtrlRegs.PIEIER9.all значением TempPIEIER; представление регистра целым словом без разбиения на битовые поля. */
PieCtrlRegs.PIEIER9.all = TempPIEIER;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Начинает функцию CANa_reset_err; назначение модуля — штатный eCAN и отдельный служебный обмен УМП/GAS. */
interrupt void CANa_reset_err(void)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
// Set interrupt priority:
/* Объявляет TempPIEIER — сохранённая маска разрешённых прерываний группы PIE. volatile требует фактического чтения или записи при каждом доступе. Начальное значение задаётся справа от знака равенства. */
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
/* Устанавливает биты IER значением M_INT9; регистр разрешения прерываний ядра C28x. */
IER |= M_INT9;
/* Оставляет биты маски IER значением MINT9; регистр разрешения прерываний ядра C28x. */
IER &= MINT9; // Set "global" priority
/* Оставляет биты маски PieCtrlRegs.PIEIER9.all значением MG96; представление регистра целым словом без разбиения на битовые поля. */
PieCtrlRegs.PIEIER9.all &= MG96; // Set "group" priority
/* Записывает PieCtrlRegs.PIEACK.all значением 0xFFFF; представление регистра целым словом без разбиения на битовые поля. */
PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts
/* Разрешение маскируемых прерываний ядра. */
EINT;
/* Записывает ECanaRegs.CANTRR.all значением 1; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANTRR.all = 1;
/* Изменяет счётчик в выражении CanTimeOutErrorTR++; на один для следующего шага. */
CanTimeOutErrorTR++;
/* Устанавливает биты PieCtrlRegs.PIEACK.bit.ACK9 значением 1; данные ACK9. */
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
// Restore registers saved:
/* Запрет маскируемых прерываний ядра. */
DINT;
/* Записывает PieCtrlRegs.PIEIER9.all значением TempPIEIER; представление регистра целым словом без разбиения на битовые поля. */
PieCtrlRegs.PIEIER9.all = TempPIEIER;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
//===========================================================================
@@ -296,59 +492,106 @@ interrupt void CANa_reset_err(void)
//===========================================================================
/* Один вызов обслуживает максимум один кадр и никогда не ждёт ACK в цикле.
* Снимок фиксируется один раз на запрос: CAN-фрагменты не смешивают
* значения до/после переключения кольцевого банка. Новые запросы забираем
* после завершения предыдущего ответа. GUI держит только один запрос. */
/* Один вызов обслуживает максимум один кадр и никогда не ждёт ACK в цикле.
* Снимок фиксируется один раз на запрос: CAN-фрагменты не смешивают
* значения до/после переключения кольцевого банка. Новые запросы забираем
* после завершения предыдущего ответа. GUI держит только один запрос. */
/* В главном цикле готовит замороженный ответ служебного CAN и отправляет его двухсловными фрагментами. */
void UMP_CAN_service(void)
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
{
/* Объявляет saved — данные saved; tag — данные tag; address — адрес; value — данные value; error — ошибка. */
unsigned int saved, tag, address, value, error;
/* Объявляет hiword — данные hiword; loword — данные loword. */
uint32_t hiword, loword;
/* Проверяет if (ump_can_waiting); последующий оператор выполняется только при истинном условии. */
if (ump_can_waiting) {
/* Проверяет if (ECanaRegs.CANTA.all & 4UL); последующий оператор выполняется только при истинном условии. */
if (ECanaRegs.CANTA.all & 4UL) {
/* Записывает ECanaRegs.CANTA.all значением 4UL; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANTA.all = 4UL;
/* Записывает ump_can_waiting значением 0; ump CAN waiting. */
ump_can_waiting = 0;
/* Проверяет else if ((ECanaRegs.CANAA.all & 4UL) или; последующий оператор выполняется только при истинном условии. */
} else if ((ECanaRegs.CANAA.all & 4UL) ||
/* Продолжает список аргументов, полей или выражение ((unsigned long)CpuTimer1.InterruptCount - ump_can_sent_at > 250UL)) {; порядок элементов сохраняется. */
((unsigned long)CpuTimer1.InterruptCount - ump_can_sent_at > 250UL)) {
/* Нет подтверждения шины: отменяем только служебный mailbox.
* GUI обнаружит неполный ответ по тайм-ауту; управление MBOX0
* и приём команд MBOX1 продолжаются. */
/* Нет подтверждения шины: отменяем только служебный mailbox.
* GUI обнаружит неполный ответ по тайм-ауту; управление MBOX0
* и приём команд MBOX1 продолжаются. */
/* Записывает ECanaRegs.CANTRR.all значением 4UL; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANTRR.all = 4UL;
/* До фактического завершения отмены mailbox не переиспользуем. */
/* До фактического завершения отмены mailbox не переиспользуем. */
/* Проверяет if (!(ECanaRegs.CANAA.all & 4UL)) return; последующий оператор выполняется только при истинном условии. */
if (!(ECanaRegs.CANAA.all & 4UL)) return;
/* Записывает ECanaRegs.CANAA.all значением 4UL; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANAA.all = 4UL;
/* Записывает ump_can_waiting значением 0; ump CAN waiting. */
ump_can_waiting = 0;
/* Записывает ump_can_length значением 0; ump CAN длина. */
ump_can_length = 0;
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
} else return;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Проверяет if (ump_can_index >= ump_can_length и ump_can_pending); последующий оператор выполняется только при истинном условии. */
if (ump_can_index >= ump_can_length && ump_can_pending) {
/* Записывает saved значением __disable_interrupts(); данные saved. */
saved = __disable_interrupts();
/* Записывает tag значением ump_can_tag; address = ump_can_address; value = ump_can_value; данные tag. */
tag = ump_can_tag; address = ump_can_address; value = ump_can_value;
/* Записывает ump_can_pending значением 0; флаг ожидающего запроса служебного CAN между ISR и главным циклом. */
ump_can_pending = 0;
/* Проверяет if (address >= 0x1300U и address < 0x1308U); последующий оператор выполняется только при истинном условии. */
if (address >= 0x1300U && address < 0x1308U)
/* Записывает ump_can_length значением Load_protection_prepare(tag & 0xFF, address, value, ump_can_reply, &error); ump CAN длина. */
ump_can_length = Load_protection_prepare(tag & 0xFF, address, value, ump_can_reply, &error);
/* Условие компиляции EEPROM_M95M02: выбранный блок включается в текущий вариант прошивки. */
#if EEPROM_M95M02
/* Проверяет else if (gas167_contains(address)); последующий оператор выполняется только при истинном условии. */
else if (gas167_contains(address))
/* Записывает ump_can_length значением gas167_prepare(tag & 0xFF, address, value, 1, ump_can_reply, &error); ump CAN длина. */
ump_can_length = gas167_prepare(tag & 0xFF, address, value, 1, ump_can_reply, &error);
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
#endif
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
else ump_can_length = ump_can_prepare(tag & 0xFF, address, value, ump_can_reply, &error);
/* Записывает ump_can_reply_tag значением (tag & 0xFF00) | error; ump CAN reply tag. */
ump_can_reply_tag = (tag & 0xFF00) | error;
/* Записывает ump_can_index значением 0; ump CAN index. */
ump_can_index = 0;
/* Вызывает __restore_interrupts с аргументами (saved) в текущей последовательности операций. */
__restore_interrupts(saved);
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Проверяет if (ump_can_index >= ump_can_length) return; последующий оператор выполняется только при истинном условии. */
if (ump_can_index >= ump_can_length) return;
/* Перед следующим фрагментом уступаем штатной телеметрии MBOX0. */
/* Перед следующим фрагментом уступаем штатной телеметрии MBOX0. */
/* Проверяет if (ECanaRegs.CANTRS.all & 1UL) return; последующий оператор выполняется только при истинном условии. */
if (ECanaRegs.CANTRS.all & 1UL) return;
/* Проверяет if (!ump_tms28335_fragment(ump_can_reply, ump_can_length, ump_can_index/2,; последующий оператор выполняется только при истинном условии. */
if (!ump_tms28335_fragment(ump_can_reply, ump_can_length, ump_can_index/2,
/* Продолжает список аргументов, полей или выражение ump_can_reply_tag >> 8, ump_can_reply_tag & 255U, &loword, &hiword)) {; порядок элементов сохраняется. */
ump_can_reply_tag >> 8, ump_can_reply_tag & 255U, &loword, &hiword)) {
/* Записывает ump_can_length значением 0; ump CAN длина. */
ump_can_length = 0;
/* Завершает UMP_CAN_service без возвращаемого значения. */
return;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}
/* Записывает ECanaRegs.CANTA.all значением 4UL; ECanaRegs.CANAA.all = 4UL; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANTA.all = 4UL; ECanaRegs.CANAA.all = 4UL;
/* Записывает ECanaMboxes.MBOX2.MDH.all значением hiword; представление регистра целым словом без разбиения на битовые поля. */
ECanaMboxes.MBOX2.MDH.all = hiword;
/* Записывает ECanaMboxes.MBOX2.MDL.all значением loword; представление регистра целым словом без разбиения на битовые поля. */
ECanaMboxes.MBOX2.MDL.all = loword;
/* Записывает ump_can_sent_at значением CpuTimer1.InterruptCount; время последней передачи фрагмента ответа CAN. */
ump_can_sent_at = CpuTimer1.InterruptCount;
/* Записывает ECanaRegs.CANTRS.all значением 4UL; представление регистра целым словом без разбиения на битовые поля. */
ECanaRegs.CANTRS.all = 4UL;
/* Записывает ump_can_waiting значением 1; ump CAN waiting. */
ump_can_waiting = 1;
/* Увеличивает ump_can_index значением 2; ump CAN index. */
ump_can_index += 2;
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
}