451 lines
11 KiB
C
451 lines
11 KiB
C
/****************************************************************/
|
|
/* TMS320C32 */
|
|
/* ====== BIOS, ÊËÀÈÍ, ÊËÂÑÏ ====== */
|
|
/* ÖÍÈÈ ÑÝÒ (ñ) 1998-2000 ã. */
|
|
/****************************************************************
|
|
Bios.c
|
|
**************************************************************
|
|
Îñíîâíûå êîììàíäû BIOS *
|
|
äëà ðàáîòû ñ RS232
|
|
****************************************************************/
|
|
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
|
#include "RS485.h"
|
|
#include "bios_dsp.h"
|
|
#include "crc16.h"
|
|
#include "spise2p.h"
|
|
#include "i2c.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;
|
|
|
|
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>=0x20000000)
|
|
{
|
|
Address&=0xFFFFFFF;
|
|
Data = I2CA_ReadData(Address);
|
|
}
|
|
else
|
|
if(Address>=0x10000000)
|
|
{
|
|
Address&=0xFFFFFFF;
|
|
Seeprom_read(Address,(unsigned int *)&Data,2);
|
|
}
|
|
else
|
|
{
|
|
Address&=0xFFFFFFF;
|
|
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] = 0;//LOBYTE(CpuTimer2.InterruptCount);
|
|
rs_arr->buffer[5] = 0;//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>=0x2000000)
|
|
{
|
|
Address&=0xFFFFFF;
|
|
I2CA_WriteData(Address,Data);
|
|
}
|
|
else
|
|
if(Address>=0x1000000)
|
|
{
|
|
Address&=0xFFFFFF;
|
|
Seeprom_write(Address,(unsigned int *)&Data,2);
|
|
}
|
|
else
|
|
{
|
|
Address&=0xFFFFFF;
|
|
write_memory(Address,Data);
|
|
}
|
|
|
|
Answer(rs_arr,CMD_POKE);
|
|
}
|
|
|
|
/** Ïåðåäàòü áëîê ïàìàòè */
|
|
void upload(RS_DATA *rs_arr)
|
|
{
|
|
int32 Address, Length, crc;
|
|
|
|
flag_DEBUG = true; // Ôëàã îòëàäî÷íîãî ðåæèìà
|
|
// 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;
|
|
}
|
|
|
|
//@}
|