Files
Balsam_167/Source/Internal/bios.c
T
Andrey 31f92e89d9 Обновить сборку прошивки 166, TESTLAMP и кодировку исходников
Перенести настройки выпуска в JSON, добавить переносимый сценарий сборки и проверки BIN. Обновить конфигурации CCS, исходники в UTF-8, обработку TESTLAMP, образы прошивки и регрессионные проверки.
2026-10-17 14:36:59 +03:00

422 lines
12 KiB
C

/* Служебные команды доступа к памяти и загрузки. get_command
* проверяет завершённый RS-кадр и CRC перед диспетчеризацией в main.
* Произвольная запись памяти сервисной командой не проходит
* автомат фронтов СИФУ. Формат CMD_* согласован с загрузчиком ПК;
* нельзя перенумеровывать команды при расширении протокола.
*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "RS485.h"
#include "bios_dsp.h"
#include "crc16.h"
#include "spise2p.h"
#include "log_to_mem.h"
//#include "flash_tools.h"
//#include "spartan_tools.h"
//#include "big_dsp_module.h"
int flag_DEBUG = false; /* Флаг отладочного режима */
//static unsigned int *RecvPtr;
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
/**********************************************************/
/* Прототипы функций, используемых и определенных в файле */
/**********************************************************/
//static int _getbyte(int *addr, int offs);
unsigned int read_memory(unsigned long addr)
{
return (*(volatile int *)(addr));
}
void write_memory(unsigned long addr, unsigned int data)
{
(*(volatile int *)( addr )) = data;
}
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
int get_command(RS_DATA *rs_arr)
{
int cmd;
unsigned int crc, rcrc;
if(rs_arr->RS_DataReady) // Данные по RS пришли
{
rs_arr->RS_DataReady = false;
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
// Провераем длину команды дла считываниа CRC
if((RS_Len[cmd]<3) || (RS_Len[cmd]>MAX_RECEIVE_LENGTH))
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return -1;
}
if(cmd == CMD_LOAD) // Если команда загрузки
{
rs_arr->RS_PrevCmd = cmd;
return cmd; // Нет проверки crc
}
else // Все остальные команды
{
// Считываем crc из посылки
crc = (rs_arr->RS_Header[RS_Len[cmd]-1] << 8) |
(rs_arr->RS_Header[RS_Len[cmd]-2]) ;
}
// Рассчитываем crc из посылки
rcrc = 0xffff;
rcrc = get_crc_16( rcrc, rs_arr->RS_Header, (RS_Len[cmd]-2) );
if(crc == rcrc) // Провераем crc
{
rs_arr->RS_PrevCmd = cmd;
return cmd;
}
else
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
} }
return -1;
}
/** Стандартный ответ, без параметров */
void Answer(RS_DATA *rs_arr,int n)
{
int crc;
flag_DEBUG = true; // Флаг отладочного режима
rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR;
rs_arr->buffer[1] = n;
crc = 0xffff;
crc = get_crc_16( crc, rs_arr->buffer, 2);
rs_arr->buffer[2] = LOBYTE(crc);
rs_arr->buffer[3] = HIBYTE(crc);
rs_arr->buffer[4] = 0;
rs_arr->buffer[5] = 0;
RS_Send(rs_arr,rs_arr->buffer, 6);
}
/* Внутреннаа ф-циа */
static char _getbyte(unsigned int *addr, int32 offs)
{
unsigned int *address;
unsigned int byte;
address = addr + offs/2;
byte = *address;
if(offs%2) return LOBYTE(byte);
else return HIBYTE(byte);
}
/* начальные установки (не работает)*/
void init(RS_DATA *rs_arr)
{
/*
if(rs_arr->RS_Header[2]==3)
{
if (rs_arr->curr_baud!=57600)
{ RS_SetLineSpeed(rs_arr,57600);
rs_arr->curr_baud= 57600;
} }
if(rs_arr->RS_Header[2]==4)
{
if (rs_arr->curr_baud!=115200)
{ RS_SetLineSpeed(rs_arr,115200);
rs_arr->curr_baud= 115200;
} }
Answer(rs_arr,CMD_INIT);
rs_arr->BS_LoadOK = false;
*/
}
/**@name Комманды
* Комманды, вызываемые через последовательный канал
*/
//@{
/** Инициировать загрузку блока.
Настраивает прием блока данных */
void initload(RS_DATA *rs_arr)
{
unsigned long Address;
Address = rs_arr->RS_Header[5] & 0xFF;
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[3] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[2] & 0xFF);
rs_arr->RS_Length = rs_arr->RS_Header[9] & 0xFF;
rs_arr->RS_Length = (rs_arr->RS_Length<<8) | (rs_arr->RS_Header[8] & 0xFF);
rs_arr->RS_Length = (rs_arr->RS_Length<<8) | (rs_arr->RS_Header[7] & 0xFF);
rs_arr->RS_Length = (rs_arr->RS_Length<<8) | (rs_arr->RS_Header[6] & 0xFF);
rs_arr->RS_Length += 2;
rs_arr->pRS_RecvPtr = (unsigned int *)Address; //(unsigned int *)Address;
rs_arr->pRecvPtr = (unsigned int *)Address; //(unsigned int *)Address;
no_write = 1;
Answer(rs_arr,CMD_INITLOAD);
}
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
void load(RS_DATA *rs_arr)
{
unsigned int rcrc, crc;
crc = (_getbyte(rs_arr->pRecvPtr, rs_arr->RS_Length-1) << 8) +
_getbyte(rs_arr->pRecvPtr, rs_arr->RS_Length-2);
rs_arr->RS_Header[0] = rs_arr->addr_recive;
// CNTRL_ADDR;
rs_arr->RS_Header[1]=CMD_LOAD;
rcrc = 0xffff;
rcrc = get_crc_16( rcrc, rs_arr->RS_Header, 2);
rcrc = get_crc_16b( rcrc, rs_arr->pRecvPtr, rs_arr->RS_Length-2);
if(rcrc == crc)
{
Answer(rs_arr,CMD_LOAD);
rs_arr->BS_LoadOK = true;
}
else
{
rs_arr->BS_LoadOK = false;
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
} }
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
@see load */
void run (RS_DATA *rs_arr)
{
return;
}
/** Прочитать ачейку памати */
void peek(RS_DATA *rs_arr)
{
unsigned long Address;
unsigned int Data, crc;
flag_DEBUG = true; // Флаг отладочного режима
Address = rs_arr->RS_Header[5] & 0xFF;
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[3] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[2] & 0xFF);
if(Address<PROM_LEN)
Seeprom_read(Address,(unsigned int *)&Data,2);
else Data = read_memory(Address);
rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR;
rs_arr->buffer[1] = CMD_PEEK;
rs_arr->buffer[2] = LOBYTE(Data);
rs_arr->buffer[3] = HIBYTE(Data);
rs_arr->buffer[4] = LOBYTE(CpuTimer2.InterruptCount);
rs_arr->buffer[5] = HIBYTE(CpuTimer2.InterruptCount);
crc = 0xffff;
crc = get_crc_16(crc, rs_arr->buffer, 6);
rs_arr->buffer[6] = LOBYTE(crc);
rs_arr->buffer[7] = HIBYTE(crc);
rs_arr->buffer[8] = 0;
rs_arr->buffer[9] = 0;
RS_Send(rs_arr,rs_arr->buffer, 10);
}
/** Записать в ачейку памати */
void poke(RS_DATA *rs_arr)
{
unsigned long Address;
unsigned int Data;
Address = rs_arr->RS_Header[5] & 0xFF;
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[3] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[2] & 0xFF);
Data = 0;
Data = (Data<<8) | (rs_arr->RS_Header[7] & 0xFF);
Data = (Data<<8) | (rs_arr->RS_Header[6] & 0xFF);
if(Address<PROM_LEN)
Seeprom_write(Address,(unsigned int *)&Data,2);
else write_memory(Address,Data);
Answer(rs_arr,CMD_POKE);
}
/** Передать блок памати */
void upload(RS_DATA *rs_arr)
{
int32 Address, Length, crc;
no_write = 1; // Флаг отладочного режима
// stopp=1;
Address = rs_arr->RS_Header[5] & 0xFF;
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[3] & 0xFF);
Address = (Address<<8) | (rs_arr->RS_Header[2] & 0xFF);
Length = rs_arr->RS_Header[9] & 0xFF;
Length = (Length<<8) | (rs_arr->RS_Header[8] & 0xFF);
Length = (Length<<8) | (rs_arr->RS_Header[7] & 0xFF);
Length = (Length<<8) | (rs_arr->RS_Header[6] & 0xFF);
rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR;
rs_arr->buffer[1] = CMD_UPLOAD;
crc = 0xffff;
crc = get_crc_16( crc, rs_arr->buffer, 2);
crc = get_crc_16b( crc, (unsigned int *)Address, Length);
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
rs_arr->buffer[0] = CMD_UPLOAD;
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
RS_Wait4OK(rs_arr);
RS_BSend(rs_arr,(unsigned int*)Address, Length);
RS_Wait4OK(rs_arr);
rs_arr->buffer[0] = LOBYTE(crc);
rs_arr->buffer[1] = HIBYTE(crc);
rs_arr->buffer[2] = 0;
rs_arr->buffer[3] = 0;
RS_Send(rs_arr,rs_arr->buffer, 4+2);
}
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
@see load */
void xflash(RS_DATA *rs_arr)
{
return;
}
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
void tflash(RS_DATA *rs_arr)
{
// volatile unsigned long Address1,Address2;
// volatile unsigned long Length, LengthW;
/*
if(!rs_arr->BS_LoadOK)
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return;
}
Address1 = rs_arr->RS_Header[5] & 0xFF;
Address1 = (Address1<<8) | (rs_arr->RS_Header[4] & 0xFF);
Address1 = (Address1<<8) | (rs_arr->RS_Header[3] & 0xFF);
Address1 = (Address1<<8) | (rs_arr->RS_Header[2] & 0xFF);
Address2 = rs_arr->RS_Header[9] & 0xFF;
Address2 = (Address2<<8) | (rs_arr->RS_Header[8] & 0xFF);
Address2 = (Address2<<8) | (rs_arr->RS_Header[7] & 0xFF);
Address2 = (Address2<<8) | (rs_arr->RS_Header[6] & 0xFF);
Length = rs_arr->RS_Header[13] & 0xFF;
Length = (Length<<8) | (rs_arr->RS_Header[12] & 0xFF);
Length = (Length<<8) | (rs_arr->RS_Header[11] & 0xFF);
Length = (Length<<8) | (rs_arr->RS_Header[10] & 0xFF);
LengthW = Length/2;
if (LengthW*2<Length) LengthW++;
if( (Address2 < 0x100000) || (Address2 > 0x180000) || ((Address2+LengthW) > 0x180000) )
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return;
}
run_flash_data(Address1,Address2, LengthW );
Answer(rs_arr,CMD_TFLASH);
*/
return;
}
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
void extendbios(RS_DATA *rs_arr)
{
volatile unsigned long Address1,Address2,Length;
unsigned int code;
Address1 = rs_arr->RS_Header[5] & 0xFF;
Address1 = (Address1<<8) | (rs_arr->RS_Header[4] & 0xFF);
Address1 = (Address1<<8) | (rs_arr->RS_Header[3] & 0xFF);
Address1 = (Address1<<8) | (rs_arr->RS_Header[2] & 0xFF);
Address2 = rs_arr->RS_Header[9] & 0xFF;
Address2 = (Address2<<8) | (rs_arr->RS_Header[8] & 0xFF);
Address2 = (Address2<<8) | (rs_arr->RS_Header[7] & 0xFF);
Address2 = (Address2<<8) | (rs_arr->RS_Header[6] & 0xFF);
Length = rs_arr->RS_Header[13] & 0xFF;
Length = (Length<<8) | (rs_arr->RS_Header[12] & 0xFF);
Length = (Length<<8) | (rs_arr->RS_Header[11] & 0xFF);
Length = (Length<<8) | (rs_arr->RS_Header[10] & 0xFF);
code=rs_arr->RS_Header[14] & 0xFF;
switch ( code )
{
// Прошиваем EPROM Из RAM
case 4: Seeprom_write(Address1,(unsigned int*)Address2,Length);
break;
// Читаем из EPROM в RAM
case 5: Seeprom_read(Address1,(unsigned int*)Address2,Length);
break;
default:
return;
}
Answer(rs_arr,CMD_EXTEND);
return;
}
//@}