Фронты START/STOP обрабатываются при принятии командного слова CAN/RS, а окончание импульса обслуживается таймером. STOP имеет приоритет, перекрытие выходов исключено, сохранена защита от самопуска при включении. Загрузка параметров больше не подменяет живые команды нагрузки. Добавлены подробные русские комментарии во все собственные C-модули и основные заголовки, описание поведения и host-тест автомата. Обновлены файлы прошивки. Полная сборка TI 22.6.1.LTS и тесты пройдены; проверка на физической плате не выполнялась.
422 lines
11 KiB
C
422 lines
11 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;
|
|
}
|
|
|
|
//@}
|