/****************************************************************/ /* 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 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; } //@}