Округлить делитель SCI по формуле аппаратуры, настроить вход RX и обработку ошибок FIFO. Добавить диагностические поля и проверки модели, установить 9600 бод для RS485 при Owen. Сохранить скрипт сборки, обновлённый образ прошивки и карту линковки.
385 lines
29 KiB
C
385 lines
29 KiB
C
/* Порядок запуска периферии и обслуживание команд в главном цикле. Русские пояснения сохранены в UTF-8. */
|
||
/* Подключает "DSP2833x_Device.h": поставляемое TI описание Device для семейства C2833x. */
|
||
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
||
|
||
/* Подключает "cntrl_adr.h": собственный и универсальный адрес устройства. */
|
||
#include "cntrl_adr.h"
|
||
/* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */
|
||
#include "RS485.h"
|
||
/* Подключает "BIOS_DSP.h": настройки и интерфейс BIOS_DSP. */
|
||
#include "BIOS_DSP.h"
|
||
/* Подключает "Message.h": настройки и интерфейс Message. */
|
||
#include "Message.h"
|
||
/* Подключает "filter_bat2.h": накопительный фильтр измерительных каналов. */
|
||
#include "filter_bat2.h"
|
||
/* Подключает "measure.h": обработка датчиков, вычисление величин и миллисекундный такт системы. */
|
||
#include "measure.h"
|
||
/* Подключает "package.h": адреса устройств, типы плат и псевдонимы технологических регистров. */
|
||
#include "package.h"
|
||
|
||
/* Подключает "spise2p.h": драйвер SPI EEPROM, адресация, страницы и автомат завершения операций. */
|
||
#include "spise2p.h"
|
||
|
||
/* Подключает "tools.h": настройка внешней памяти и служебные задержки. */
|
||
#include "tools.h"
|
||
/* Подключает "peripher.h": перемычки режима платы, дискретные входы и выходы. */
|
||
#include "peripher.h"
|
||
/* Подключает "ADC.h": настройка АЦП, обработка преобразований и первичная фильтрация измерений. */
|
||
#include "ADC.h"
|
||
/* Подключает "DAC.h": выход ЦАП и автомат защиты нагрузки с проверкой напряжения и свежести CAN. */
|
||
#include "DAC.h"
|
||
|
||
/* Подключает "ecan.h": штатный eCAN и отдельный служебный обмен УМП/GAS. */
|
||
#include "ecan.h"
|
||
/* Подключает "kanal.h": последовательный вывод данных канала индикации. */
|
||
#include "kanal.h"
|
||
/* Подключает "pulto.h": обмен и индикация пульта. */
|
||
#include "pulto.h"
|
||
/* Подключает "log_to_mem.h": двухбанковый регистратор событий нагрузки во внешней RAM. */
|
||
#include "log_to_mem.h"
|
||
|
||
/* Подключает "measure.h": обработка датчиков, вычисление величин и миллисекундный такт системы. */
|
||
#include "measure.h"
|
||
/* Объявляет интерфейс функции DSP28x_usDelay; реализация вызывается через этот прототип. */
|
||
extern void DSP28x_usDelay(Uint32 Count);
|
||
|
||
/* Назначает обработчик Timer1 по типу платы и задаёт период основного такта. */
|
||
void timer_Init()
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Разрешение записи в защищённые регистры периферии. */
|
||
EALLOW; // This is needed to write to EALLOW protected registers
|
||
/* Проверяет if(Desk==dsk_EPLT) PieVectTable.XINT13 = &cpu_timer1_isr_PULT; последующий оператор выполняется только при истинном условии. */
|
||
if(Desk==dsk_EPLT) PieVectTable.XINT13 = &cpu_timer1_isr_PULT;
|
||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||
else PieVectTable.XINT13 = &cpu_timer1_isr_SENS;
|
||
/* Закрытие доступа к защищённым регистрам периферии. */
|
||
EDIS; // This is needed to disable write to EALLOW protected registers
|
||
|
||
/* Вызывает ConfigCpuTimer с аргументами (&CpuTimer1, SYSCLKOUT/1000000, 1000000/READY_FREQ) в текущей последовательности операций. */
|
||
ConfigCpuTimer(&CpuTimer1, SYSCLKOUT/1000000, 1000000/READY_FREQ);
|
||
/* Записывает CpuTimer1Regs.TCR.all значением 0x4020; представление регистра целым словом без разбиения на битовые поля. */
|
||
CpuTimer1Regs.TCR.all = 0x4020; // Use write-only instruction to set TSS bit = 0
|
||
/* Устанавливает биты IER значением M_INT13; регистр разрешения прерываний ядра C28x. */
|
||
IER |= M_INT13;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||
void main()
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Объявляет i — данные i; j — данные j; mask — маска. */
|
||
int i,j,mask;
|
||
/* Объявляет cancount — данные cancount; cancell — данные cancell; rscount — данные rscount. */
|
||
static unsigned int cancount[2], cancell[2], rscount;
|
||
/* Объявляет rs — данные rs. Хранит указатель на данные. */
|
||
RS_DATA * rs;
|
||
/* Объявляет presbyt — данные presbyt. Начальное значение задаётся справа от знака равенства. */
|
||
int presbyt=0;
|
||
|
||
/* Инициализирует модуль вызовом InitSysCtrl(); перед его дальнейшим использованием. */
|
||
InitSysCtrl();
|
||
|
||
// Disable CPU interrupts and clear all CPU interrupt flags:
|
||
/* Запрет маскируемых прерываний ядра. */
|
||
DINT;
|
||
|
||
/* Инициализирует модуль вызовом InitPieCtrl(); перед его дальнейшим использованием. */
|
||
InitPieCtrl();
|
||
|
||
/* Записывает IER значением 0x0000; регистр разрешения прерываний ядра C28x. */
|
||
IER = 0x0000;
|
||
/* Записывает IFR значением 0x0000; регистр ожидающих прерываний ядра C28x. */
|
||
IFR = 0x0000;
|
||
|
||
/* Инициализирует модуль вызовом InitPieVectTable(); перед его дальнейшим использованием. */
|
||
InitPieVectTable();
|
||
/* Вызывает init_zone7. Настраивает временные параметры внешней шины XINTF Zone7 для RAM регистратора. */
|
||
init_zone7();
|
||
|
||
/* Вызывает get_Mode. Определяет адрес и тип платы по аппаратным перемычкам и задаёт рабочий режим. */
|
||
get_Mode();
|
||
/* Вызывает InitCan. Настраивает eCAN, скорость, почтовые ящики и маршрутизацию прерываний для выбранного режима платы. */
|
||
InitCan(0,Mode);
|
||
|
||
/* Вызывает create_uart_vars. Инициализирует структуры обоих SCI и таблицу длин команд. */
|
||
create_uart_vars(sizeof(CMD_TO_TMS));
|
||
/* Вызывает setup_uart. Настраивает выбранный SCI, скорость и обработчики прерываний. */
|
||
setup_uart(COM_1,115200);
|
||
|
||
/* Проверяет if(Owen)setup_uart(COM_2,57600); последующий оператор выполняется только при истинном условии. */
|
||
if(Owen)setup_uart(COM_2,9600);
|
||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||
else setup_uart(COM_2,115200);
|
||
|
||
/* Инициализирует модуль вызовом InitSeeprom(); перед его дальнейшим использованием. */
|
||
InitSeeprom();
|
||
|
||
/* Вызывает setup_leds_line с аргументами () в текущей последовательности операций. */
|
||
setup_leds_line();
|
||
/* Вызывает led1_on с аргументами () в текущей последовательности операций. */
|
||
led1_on();
|
||
/* Вызывает led2_off с аргументами () в текущей последовательности операций. */
|
||
led2_off();
|
||
/* Цикл for (i=0;i<10;i++); задаёт начальное значение, условие продолжения и шаг перебора. */
|
||
for (i=0;i<10;i++)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Вызывает pause_us. Формирует задержку в микросекундах через калиброванную функцию DSP28x_usDelay. */
|
||
pause_us(50000);
|
||
/* Вызывает led2_toggle с аргументами () в текущей последовательности операций. */
|
||
led2_toggle();
|
||
/* Вызывает led1_toggle с аргументами () в текущей последовательности операций. */
|
||
led1_toggle();
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
/* Вызывает led1_off с аргументами () в текущей последовательности операций. */
|
||
led1_off();
|
||
/* Вызывает led2_off с аргументами () в текущей последовательности операций. */
|
||
led2_off();
|
||
/* Вызывает unsetup_leds_line с аргументами () в текущей последовательности операций. */
|
||
unsetup_leds_line();
|
||
|
||
/* Вызывает clear_mem. Обнуляет выделенный диапазон внешней RAM журнала и задаёт границы кольцевого буфера. */
|
||
clear_mem();
|
||
/* Вызывает ump_log_init. Явно инициализирует оба банка регистратора до включения IRQ; повторный старт записи архив не стирает. */
|
||
ump_log_init();
|
||
Load_control_init(); /* Explicit initialization before IRQ. */ /* Вызывает Load_control_init. Сбрасывает все переменные автомата нагрузки до разрешения прерываний; COFF не обнуляет всю .ebss. */
|
||
/* Вызывает set_cntrl_addr. Устанавливает собственный и универсальный адрес для проверки адресованных команд. */
|
||
set_cntrl_addr(Mode,16);
|
||
/* Вызывает timer_Init. Назначает обработчик Timer1 по типу платы и задаёт период основного такта. */
|
||
timer_Init();
|
||
/* Вызывает EnableInterrupts с аргументами () в текущей последовательности операций. */
|
||
EnableInterrupts();
|
||
|
||
/* Проверяет if(Desk!=dsk_EPLT); последующий оператор выполняется только при истинном условии. */
|
||
if(Desk!=dsk_EPLT)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Вызывает setup_adc. Настраивает каналы, последовательность преобразований и запуск АЦП. */
|
||
setup_adc();
|
||
/* Инициализирует модуль вызовом Init_sensors(); перед его дальнейшим использованием. */
|
||
Init_sensors();
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
/* Инициализирует модуль вызовом Init_packMask(); перед его дальнейшим использованием. */
|
||
Init_packMask();
|
||
|
||
/* Вызывает Load_params. Читает сохранённые регистры из области параметров EEPROM и применяет настройки платы. */
|
||
Load_params();
|
||
/* Инициализирует модуль вызовом Init_sensors_more(); перед его дальнейшим использованием. */
|
||
Init_sensors_more();
|
||
|
||
/* Проверяет if(Desk==dsk_LOAD); последующий оператор выполняется только при истинном условии. */
|
||
if(Desk==dsk_LOAD)
|
||
/* Вызывает Setup_DAC_time. Вычисляет такты ЦАП; для недопустимого сохранённого тайм-аута CAN возвращает 600 мс. */
|
||
Setup_DAC_time();
|
||
|
||
/* Записывает LastMode значением Mode; последний режим платы, технологический регистр 126. */
|
||
LastMode = Mode;
|
||
|
||
/* Разрешение записи в защищённые регистры периферии. */
|
||
EALLOW;
|
||
/* Записывает SysCtrlRegs.WDCR значением 0x2F; данные WDCR. */
|
||
SysCtrlRegs.WDCR= 0x2F;
|
||
/* Закрытие доступа к защищённым регистрам периферии. */
|
||
EDIS;
|
||
|
||
/* Записывает READY значением 1; данные READY. */
|
||
READY=1;
|
||
|
||
/* Повторяет или ожидает, пока выполняется while(1). */
|
||
while(1)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Чтение логгера по CAN не блокирует цикл управления. */
|
||
/* Вызывает UMP_CAN_service. В главном цикле готовит замороженный ответ служебного CAN и отправляет его двухсловными фрагментами. */
|
||
UMP_CAN_service();
|
||
/* Проверяет if(CanGO); последующий оператор выполняется только при истинном условии. */
|
||
if(CanGO)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает CanGO значением 0; CAN GO. */
|
||
CanGO=0;
|
||
|
||
/* Проверяет if(Owncount); последующий оператор выполняется только при истинном условии. */
|
||
if(Owncount)
|
||
/* Проверяет if(++rscount>=Owncount); последующий оператор выполняется только при истинном условии. */
|
||
if(++rscount>=Owncount)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает rscount значением 0; данные rscount. */
|
||
rscount=0;
|
||
/* Вызывает SendCommandModbus4 с аргументами (&rs_b) в текущей последовательности операций. */
|
||
SendCommandModbus4(&rs_b);
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Цикл for(i=0;i<2;i++); задаёт начальное значение, условие продолжения и шаг перебора. */
|
||
for(i=0;i<2;i++)
|
||
/* Проверяет if(++cancount[i] >= Cancount[i]); последующий оператор выполняется только при истинном условии. */
|
||
if(++cancount[i] >= Cancount[i])
|
||
/* Проверяет if(Cancount[i] и cancount[0]); последующий оператор выполняется только при истинном условии. */
|
||
if(Cancount[i] && cancount[0])
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает cancount[i] значением 0; данные cancount. */
|
||
cancount[i] = 0;
|
||
|
||
/* Повторяет или ожидает, пока выполняется while(1). */
|
||
while(1)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Проверяет if(cancell[i] >= 0x80) cancell[i]=0; последующий оператор выполняется только при истинном условии. */
|
||
if(cancell[i] >= 0x80) cancell[i]=0;
|
||
/* Записывает mask значением Maska[i][cancell[i]/16] >> (cancell[i]%16); маска. */
|
||
mask = Maska[i][cancell[i]/16] >> (cancell[i]%16);
|
||
/* Проверяет if(!mask) cancell[i] = (cancell[i] + 0x10) & 0xFFF0; последующий оператор выполняется только при истинном условии. */
|
||
if(!mask) cancell[i] = (cancell[i] + 0x10) & 0xFFF0;
|
||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||
else
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Повторяет или ожидает, пока выполняется while(!(mask & 1)). */
|
||
while(!(mask & 1))
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Изменяет счётчик в выражении cancell[i]++; mask >>= 1; на один для следующего шага. */
|
||
cancell[i]++; mask >>= 1;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
/* Прерывает ближайший цикл или ветвь switch и продолжает после него. */
|
||
break;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
} }
|
||
/* Вызывает CAN_send. Упаковывает адрес и технологические слова в штатный CAN-кадр и запускает передачу mailbox. */
|
||
CAN_send(0,modbus,cancell[i]);
|
||
/* Увеличивает cancell[i] значением 3; данные cancell. */
|
||
cancell[i]+=3;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
} }
|
||
|
||
/* Проверяет if(cDefParam); последующий оператор выполняется только при истинном условии. */
|
||
if(cDefParam)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает cDefParam значением 0; данные cDefParam. */
|
||
cDefParam=0;
|
||
/* По команде восстановления записывает заводские параметры; для LOAD тайм-аут свежести CAN становится 2000 мс. */
|
||
Default_params();
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Проверяет if(cSaveParam); последующий оператор выполняется только при истинном условии. */
|
||
if(cSaveParam)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает cSaveParam значением 0; данные cSaveParam. */
|
||
cSaveParam=0;
|
||
/* Вызывает Save_params. Сохраняет технологические регистры в область параметров, отделённую от загрузочного образа EEPROM. */
|
||
Save_params();
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Проверяет if(cLoadParam); последующий оператор выполняется только при истинном условии. */
|
||
if(cLoadParam)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает cLoadParam значением 0; данные cLoadParam. */
|
||
cLoadParam=0;
|
||
/* Вызывает Load_params. Читает сохранённые регистры из области параметров EEPROM и применяет настройки платы. */
|
||
Load_params();
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Проверяет if(cKoefCalc); последующий оператор выполняется только при истинном условии. */
|
||
if(cKoefCalc)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает cKoefCalc значением 0; данные cKoefCalc. */
|
||
cKoefCalc=0;
|
||
/* Вызывает calc_sensor_koef с аргументами () в текущей последовательности операций. */
|
||
calc_sensor_koef();
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Вызывает get_Buttons. Считывает кнопки, обновляет флаги команд и учитывает текущий тип платы. */
|
||
get_Buttons();
|
||
|
||
/* Проверяет if(Desk==dsk_COMM); последующий оператор выполняется только при истинном условии. */
|
||
if(Desk==dsk_COMM)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Проверяет if(!bTermoCal & presbyt) cSaveParam=1; последующий оператор выполняется только при истинном условии. */
|
||
if(!bTermoCal & presbyt) cSaveParam=1;
|
||
/* Записывает presbyt значением bTermoCal; данные presbyt. */
|
||
presbyt = bTermoCal;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
}
|
||
|
||
/* Timer1 owns START/STOP/permission and the DAC ramp together.
|
||
* Main must not re-enable the output during a protected reload. */
|
||
|
||
/* Снимок после обновления входов и формирования пусковых выходов. */
|
||
/* Вызывает ump_log_io. Обслуживает изменения дискретных входов и выходов из главного цикла. */
|
||
ump_log_io();
|
||
|
||
/* Цикл for(i=0;i<2;i++); задаёт начальное значение, условие продолжения и шаг перебора. */
|
||
for(i=0;i<2;i++)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Проверяет if(i) rs = &rs_a; последующий оператор выполняется только при истинном условии. */
|
||
if(i) rs = &rs_a;
|
||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||
else rs = &rs_b;
|
||
|
||
/* Записывает j значением get_command(rs); данные j. */
|
||
j = get_command(rs);
|
||
|
||
/* Проверяет if(j!=-1); последующий оператор выполняется только при истинном условии. */
|
||
if(j!=-1)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Записывает Lonely значением 0; данные Lonely. */
|
||
Lonely=0;
|
||
/* Вызывает led2_toggle с аргументами () в текущей последовательности операций. */
|
||
led2_toggle();
|
||
/* Вызывает switch с аргументами (j) в текущей последовательности операций. */
|
||
switch(j)
|
||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||
{
|
||
/* Ветвь выбора для CMD_INIT; выполняется при совпадении селектора switch. */
|
||
case CMD_INIT: init(rs); break; // начальные установки
|
||
/* Ветвь выбора для CMD_INITLOAD; выполняется при совпадении селектора switch. */
|
||
case CMD_INITLOAD: initload(rs); break; // настройка загрузки
|
||
/* Ветвь выбора для CMD_RUN; выполняется при совпадении селектора switch. */
|
||
case CMD_RUN: run(rs); break; // загрузить блок
|
||
/* Ветвь выбора для CMD_LOAD; выполняется при совпадении селектора switch. */
|
||
case CMD_LOAD: load(rs); break; // загрузить блок
|
||
/* Ветвь выбора для CMD_PEEK; выполняется при совпадении селектора switch. */
|
||
case CMD_PEEK: peek(rs); break; // прочитать ачейку памати
|
||
/* Ветвь выбора для CMD_POKE; выполняется при совпадении селектора switch. */
|
||
case CMD_POKE: poke(rs); break; // записать в ачейку памати
|
||
/* Ветвь выбора для CMD_UPLOAD; выполняется при совпадении селектора switch. */
|
||
case CMD_UPLOAD: upload(rs); break; // передать блок памати
|
||
/* Ветвь выбора для CMD_EXTEND; выполняется при совпадении селектора switch. */
|
||
case CMD_EXTEND: extendbios(rs); break; // расширенные команды дла биоса
|
||
|
||
/* Ветвь выбора для CMD_TFLASH; выполняется при совпадении селектора switch. */
|
||
case CMD_TFLASH: tflash(rs); break; // прошить TMS
|
||
|
||
/* Ветвь выбора для CMD_MODBUS_3; выполняется при совпадении селектора switch. */
|
||
case CMD_MODBUS_3: ReceiveCommandModbus3(rs); break;
|
||
/* Ветвь выбора для CMD_MODBUS_6; выполняется при совпадении селектора switch. */
|
||
case CMD_MODBUS_6: ReceiveCommandModbus6(rs); break;
|
||
/* Ветвь выбора для ANS_MODBUS_4; выполняется при совпадении селектора switch. */
|
||
case ANS_MODBUS_4: ReceiveAnswerModbus4(rs); break;
|
||
|
||
|
||
/* Обрабатывает значения селектора, для которых нет отдельной ветви case. */
|
||
default: break;
|
||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||
} } } } }
|
||
|