Update CCS12 peripheral firmware and documentation

This commit is contained in:
2026-09-04 19:34:10 +03:00
parent 55bee25b4f
commit 8cd81736cf
56 changed files with 3808 additions and 504 deletions

View File

@@ -1,12 +1,22 @@
/**
* @file bios.c
* @brief Сервисные команды удалённого доступа к памяти и загрузки программы.
*
* Реализует разбор BIOS-команд, формирование ответов, чтение/запись памяти,
* загрузку блоков и запуск кода через транспорт RS-485. Адреса и размеры
* приходят извне, поэтому корректность пакета и CRC должна быть подтверждена
* до вызова обработчиков. Прямой доступ к памяти преднамеренно использует
* volatile и требует адресов из допустимой карты памяти контроллера.
*/
/****************************************************************/
/* TMS320C32 */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/* ====== BIOS, КЛАИН, КЛВСП ====== */
/* ЦНИИ СЭТ (с) 1998-2000 г. */
/****************************************************************
Bios.c
**************************************************************
Основные комманды BIOS *
дла работы с RS232
Основные комманды BIOS *
дла работы с RS232
****************************************************************/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "RS485.h"
@@ -18,82 +28,95 @@
//#include "spartan_tools.h"
//#include "big_dsp_module.h"
int flag_DEBUG = false; /* Флаг отладочного режима */
int flag_DEBUG = false; /* Флаг отладочного режима */
//static unsigned int *RecvPtr;
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
/**********************************************************/
/* Прототипы функций, используемых и определенных в файле */
/* Прототипы функций, используемых и определенных в файле */
/**********************************************************/
//static int _getbyte(int *addr, int offs);
/** @brief Читает одно volatile-слово из физического адресного пространства DSP. */
unsigned int read_memory(unsigned long addr)
{
return (*(volatile int *)(addr));
}
/** @brief Записывает одно слово data по физическому адресу addr. */
void write_memory(unsigned long addr, unsigned int data)
{
(*(volatile int *)( addr )) = data;
}
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
/**
* @brief Проверяет и диспетчеризует полностью принятый сервисный кадр.
* @param rs_arr Порт и буфер принятой команды.
* @return Код распознанной команды либо признак ошибки кадра.
* @details Проверяет адрес, длину и CRC, затем вызывает обработчик CMD_*.
*/
int get_command(RS_DATA *rs_arr)
{
int cmd;
unsigned int crc, rcrc;
if(rs_arr->RS_DataReady) // Данные по RS пришли
if(rs_arr->RS_DataReady) // Данные по RS пришли
{
rs_arr->RS_DataReady = false;
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
// Провераем длину команды дла считываниа CRC
// Провераем длину команды дла считываниа CRC
if((RS_Len[cmd]<3) || (RS_Len[cmd]>MAX_RECEIVE_LENGTH))
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return -1;
}
if(cmd == CMD_LOAD) // Если команда загрузки
if(cmd == CMD_LOAD) // Если команда загрузки
{
rs_arr->RS_PrevCmd = cmd;
return cmd; // Нет проверки crc
return cmd; // Нет проверки crc
}
else // Все остальные команды
else // Все остальные команды
{
// Считываем crc из посылки
// Считываем crc из посылки
crc = (rs_arr->RS_Header[RS_Len[cmd]-1] << 8) |
(rs_arr->RS_Header[RS_Len[cmd]-2]) ;
}
// Рассчитываем crc из посылки
// Рассчитываем crc из посылки
rcrc = 0xffff;
rcrc = get_crc_16( rcrc, rs_arr->RS_Header, (RS_Len[cmd]-2) );
if(crc == rcrc) // Провераем crc
if(crc == rcrc) // Провераем crc
{
rs_arr->RS_PrevCmd = cmd;
return cmd;
}
else
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
} }
return -1;
}
/** Стандартный ответ, без параметров */
/** Стандартный ответ, без параметров */
/**
* @brief Добавляет CRC и отправляет n слов ответа через исходный порт.
* @param rs_arr Порт, через который пришёл запрос.
* @param n Число информационных слов до CRC.
*/
void Answer(RS_DATA *rs_arr,int n)
{
int crc;
flag_DEBUG = true; // Флаг отладочного режима
flag_DEBUG = true; // Флаг отладочного режима
rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR;
rs_arr->buffer[1] = n;
@@ -109,7 +132,7 @@ void Answer(RS_DATA *rs_arr,int n)
RS_Send(rs_arr,rs_arr->buffer, 6);
}
/* Внутреннаа ф-циа */
/* Внутреннаа ф-циа */
static char _getbyte(unsigned int *addr, int32 offs)
{
unsigned int *address;
@@ -122,7 +145,8 @@ static char _getbyte(unsigned int *addr, int32 offs)
}
/* начальные установки (не работает)*/
/* начальные установки (не работает)*/
/** @brief Сбрасывает параметры текущей загрузочной сессии и подтверждает команду. */
void init(RS_DATA *rs_arr)
{
/*
@@ -145,13 +169,18 @@ void init(RS_DATA *rs_arr)
*/
}
/**@name Комманды
* Комманды, вызываемые через последовательный канал
/**@name Комманды
* Комманды, вызываемые через последовательный канал
*/
//@{
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/** Инициировать загрузку блока.
Настраивает прием блока данных */
/**
* @brief Принимает заголовок нового образа и подготавливает диапазон загрузки.
* @details Из кадра извлекаются начальный адрес, длина и контрольные параметры;
* запись данных разрешается только после успешной проверки заголовка.
*/
void initload(RS_DATA *rs_arr)
{
unsigned long Address;
@@ -175,8 +204,12 @@ void initload(RS_DATA *rs_arr)
Answer(rs_arr,CMD_INITLOAD);
}
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/** Загрузка блока.
Вызываетса после загрузки блока через RS */
/**
* @brief Записывает очередную порцию образа по текущему адресу загрузки.
* @post Рабочий адрес и остаток длины продвинуты на принятый блок.
*/
void load(RS_DATA *rs_arr)
{
unsigned int rcrc, crc;
@@ -201,27 +234,32 @@ void load(RS_DATA *rs_arr)
else
{
rs_arr->BS_LoadOK = false;
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
} }
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
/** Выполнить программу в формате Serial Boot.
@precondition Должна быть произведена загрузка блока
Адрес программы беретса из заголовка и
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
@see load */
/** @brief Подтверждает команду и передаёт управление загруженной программе. */
void run (RS_DATA *rs_arr)
{
return;
}
/** Прочитать ачейку памати */
/** Прочитать ачейку памати */
/**
* @brief Возвращает содержимое заданного диапазона памяти.
* @warning Диапазон должен быть предварительно разрешён протокольным уровнем.
*/
void peek(RS_DATA *rs_arr)
{
unsigned long Address;
unsigned int Data, crc;
flag_DEBUG = true; // Флаг отладочного режима
flag_DEBUG = true; // Флаг отладочного режима
Address = rs_arr->RS_Header[5] & 0xFF;
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
@@ -254,7 +292,8 @@ void peek(RS_DATA *rs_arr)
}
/** Записать в ачейку памати */
/** Записать в ачейку памати */
/** @brief Записывает данные команды в заданную область памяти и отвечает статусом. */
void poke(RS_DATA *rs_arr)
{
unsigned long Address;
@@ -276,12 +315,13 @@ void poke(RS_DATA *rs_arr)
Answer(rs_arr,CMD_POKE);
}
/** Передать блок памати */
/** Передать блок памати */
/** @brief Передаёт ведущему очередной блок ранее выбранной области памяти. */
void upload(RS_DATA *rs_arr)
{
int32 Address, Length, crc;
no_write = 1; // Флаг отладочного режима
no_write = 1; // Флаг отладочного режима
// stopp=1;
Address = rs_arr->RS_Header[5] & 0xFF;
@@ -301,10 +341,10 @@ void upload(RS_DATA *rs_arr)
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_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
rs_arr->buffer[0] = CMD_UPLOAD;
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
RS_Wait4OK(rs_arr);
RS_BSend(rs_arr,(unsigned int*)Address, Length);
@@ -318,22 +358,24 @@ void upload(RS_DATA *rs_arr)
}
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
/** Прошить XILINX.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
так же смотрит магическое слово в начале прошивки
@see load */
/** @brief Обрабатывает совместимую команду программирования внешней логики. */
void xflash(RS_DATA *rs_arr)
{
return;
}
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
/** @brief Обрабатывает команду программирования памяти целевого контроллера. */
void tflash(RS_DATA *rs_arr)
{
// volatile unsigned long Address1,Address2;
@@ -341,7 +383,7 @@ void tflash(RS_DATA *rs_arr)
/*
if(!rs_arr->BS_LoadOK)
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return;
}
@@ -366,7 +408,7 @@ void tflash(RS_DATA *rs_arr)
if( (Address2 < 0x100000) || (Address2 > 0x180000) || ((Address2+LengthW) > 0x180000) )
{
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_Line_to_receive(rs_arr); // режим приема RS485
RS_SetBitMode(rs_arr,9);
return;
}
@@ -378,11 +420,15 @@ void tflash(RS_DATA *rs_arr)
return;
}
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
/** Прошить TMS.
@precondition Должна быть произведена загрузка блока
Адрес и длина прошивки беретса из заголовка и
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
@see load */
/**
* @brief Выполняет расширенную BIOS-команду, не входящую в базовый набор.
* @details Подкоманда и её аргументы извлекаются из принятого сервисного кадра.
*/
void extendbios(RS_DATA *rs_arr)
{
volatile unsigned long Address1,Address2,Length;
@@ -407,10 +453,10 @@ void extendbios(RS_DATA *rs_arr)
switch ( code )
{
// Прошиваем EPROM Из RAM
// Прошиваем EPROM Из RAM
case 4: Seeprom_write(Address1,(unsigned int*)Address2,Length);
break;
// Читаем из EPROM в RAM
// Читаем из EPROM в RAM
case 5: Seeprom_read(Address1,(unsigned int*)Address2,Length);
break;