Files

261 lines
7.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file main.c
* @brief Точка входа и основной диспетчер периферийной прошивки Balsam 167.
*
* Выполняет инициализацию тактирования, GPIO, интерфейсов и измерительных
* модулей, выбирает обработчик Timer1 по типу платы и затем координирует CAN,
* RS-485, команды и контроль состояния. Порядок инициализации важен: глобальные
* прерывания разрешаются только после настройки таблицы PIE и зависимых блоков.
*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "cntrl_adr.h"
#include "RS485.h"
#include "BIOS_DSP.h"
#include "Message.h"
#include "filter_bat2.h"
#include "measure.h"
#include "package.h"
#include "spise2p.h"
#include "tools.h"
#include "peripher.h"
#include "ADC.h"
#include "DAC.h"
#include "ecan.h"
#include "kanal.h"
#include "pulto.h"
#include "log_to_mem.h"
#include "measure.h"
extern void DSP28x_usDelay(Uint32 Count);
/**
* @brief Настраивает CPU Timer1 и выбирает его ISR по роли платы.
* @details Для пульта используется cpu_timer1_isr_PULT(), для остальных ролей
* — измерительный cpu_timer1_isr_SENS(). Период равен одному тику READY_FREQ.
* @pre Desk уже считан из конфигурационных GPIO.
* @post Вектор XINT13 установлен, Timer1 запущен, CPU INT13 разрешён.
*/
void timer_Init()
{
EALLOW; // This is needed to write to EALLOW protected registers
if(Desk==dsk_EPLT) PieVectTable.XINT13 = &cpu_timer1_isr_PULT;
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);
CpuTimer1Regs.TCR.all = 0x4020; // Use write-only instruction to set TSS bit = 0
IER |= M_INT13;
}
/**
* @brief Инициализирует устройство и выполняет бесконечный диспетчерский цикл.
*
* @details Последовательно поднимает системное тактирование, внешнюю память,
* PIE, GPIO, UART, EEPROM, CAN, АЦП и таймеры. Затем обслуживает завершённые
* RS-485 кадры, сервисные команды, CAN-периодику, кнопки и контроль связи.
* Точные ветви исполнения определяются Desk и опциями package.h.
*
* @warning Порядок запуска существенен: ISR не должны сработать до создания
* буферов, установки векторов и инициализации разделяемого состояния.
*/
void main()
{
int i,j,mask;
static unsigned int cancount[2], cancell[2], rscount;
static int preCstart=1,preCstop=1;
RS_DATA * rs;
int presbyt=0;
InitSysCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
/* Конфигурация PIE и периферии выполняется при запрещённых прерываниях CPU. */
DINT;
/* После сброса PIE источники разрешаются отдельно каждым драйвером. */
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
init_zone7();
/* Роль платы определяет дальнейшую разводку ADC, GPIO и Timer1 ISR. */
get_Mode();
InitCan(0,Mode);
create_uart_vars(sizeof(CMD_TO_TMS));
setup_uart(COM_1,115200);
if(Owen)setup_uart(COM_2,57600);
else setup_uart(COM_2,115200);
InitSeeprom();
setup_leds_line();
led1_on();
led2_off();
for (i=0;i<10;i++)
{
pause_us(50000);
led2_toggle();
led1_toggle();
}
led1_off();
led2_off();
unsetup_leds_line();
clear_mem();
set_cntrl_addr(Mode,16);
timer_Init();
/* Все базовые векторы и транспортные состояния готовы к обслуживанию ISR. */
EnableInterrupts();
if(Desk!=dsk_EPLT)
{
setup_adc();
Init_sensors();
}
Init_packMask();
Load_params();
Init_sensors_more();
if(Desk==dsk_LOAD)
Setup_DAC_time();
LastMode = Mode;
EALLOW;
SysCtrlRegs.WDCR= 0x2F;
EDIS;
/* READY разрешает измерительному ADC ISR использовать накопленные данные. */
READY=1;
/* Foreground-цикл обрабатывает события, подготовленные ISR и таймерами. */
while(1)
{
if(CanGO)
{
CanGO=0;
if(Owncount)
if(++rscount>=Owncount)
{
rscount=0;
SendCommandModbus4(&rs_b);
}
for(i=0;i<2;i++)
if(++cancount[i] >= Cancount[i])
if(Cancount[i] && cancount[0])
{
cancount[i] = 0;
while(1)
{
if(cancell[i] >= 0x80) cancell[i]=0;
mask = Maska[i][cancell[i]/16] >> (cancell[i]%16);
if(!mask) cancell[i] = (cancell[i] + 0x10) & 0xFFF0;
else
{
while(!(mask & 1))
{
cancell[i]++; mask >>= 1;
}
break;
} }
CAN_send(0,modbus,cancell[i]);
cancell[i]+=3;
} }
if(cDefParam)
{
cDefParam=0;
Default_params();
}
if(cSaveParam)
{
cSaveParam=0;
Save_params();
}
if(cLoadParam)
{
cLoadParam=0;
Load_params();
}
if(cKoefCalc)
{
cKoefCalc=0;
calc_sensor_koef();
}
get_Buttons();
if(Desk==dsk_COMM)
{
if(!bTermoCal & presbyt) cSaveParam=1;
presbyt = bTermoCal;
}
if(Desk==dsk_LOAD)
{
if(cUMPstart & !preCstart)
{
set_START_DPTB(); set_RES_OUT_2();
IMPowse = READY_FREQ;
}
preCstart = cUMPstart;
if(cUMPreset & !preCstop)
{
set_STOP_DPTB(); clear_RES_OUT_2();
IMPowse = READY_FREQ;
}
preCstop = cUMPreset;
if(!IMPowse) { clear_START_DPTB(); clear_STOP_DPTB(); }
}
for(i=0;i<2;i++)
{
if(i) rs = &rs_a;
else rs = &rs_b;
j = get_command(rs);
if(j!=-1)
{
Lonely=0;
led2_toggle();
switch(j)
{
case CMD_INIT: init(rs); break; // начальные установки
case CMD_INITLOAD: initload(rs); break; // настройка загрузки
case CMD_RUN: run(rs); break; // загрузить блок
case CMD_LOAD: load(rs); break; // загрузить блок
case CMD_PEEK: peek(rs); break; // прочитать ачейку памати
case CMD_POKE: poke(rs); break; // записать в ачейку памати
case CMD_UPLOAD: upload(rs); break; // передать блок памати
case CMD_EXTEND: extendbios(rs); break; // расширенные команды дла биоса
case CMD_TFLASH: tflash(rs); break; // прошить TMS
case CMD_MODBUS_3: ReceiveCommandModbus3(rs); break;
case CMD_MODBUS_6: ReceiveCommandModbus6(rs); break;
case ANS_MODBUS_4: ReceiveAnswerModbus4(rs); break;
default: break;
} } } } }