/****************************************************************/ /* 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 "log_to_mem.h" /**********************************************************/ /* Прототипы функций, используемых и определенных в файле */ /**********************************************************/ //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; 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); } /**@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); } } /** Прочитать ачейку памати */ void peek(RS_DATA *rs_arr) { unsigned long Address; unsigned int Data[2], crc; 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[0]= I2CA_ReadData(Address); DSP28x_usDelay(500); Data[1]= I2CA_ReadData(Address+1); DSP28x_usDelay(500); } else if(Address>=0x10000000) { Address&=0xFFFFFFF; Seeprom_read(Address,Data,4); } else { Address&=0xFFFFFFF; Data[0] = read_memory(Address); Data[1] = read_memory(Address+1); } rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR; rs_arr->buffer[1] = CMD_PEEK; rs_arr->buffer[2] = LOBYTE(Data[0]); rs_arr->buffer[3] = HIBYTE(Data[0]); rs_arr->buffer[4] = 0; rs_arr->buffer[5] = 0; /* rs_arr->buffer[2] = LOBYTE(Data[1]); rs_arr->buffer[3] = HIBYTE(Data[1]); rs_arr->buffer[4] = LOBYTE(Data[0]); rs_arr->buffer[5] = HIBYTE(Data[0]); */ 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; Read_Log = 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); Read_Log = 0; } /** Прошить TMS. @precondition Должна быть произведена загрузка блока Адрес и длина прошивки беретса из заголовка и сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load @see load */ void extendbios(RS_DATA *rs_arr) { volatile unsigned long Address1,Address2,Length; unsigned int code, mem; 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; mem =rs_arr->RS_Header[15] & 0xFF; switch ( code ) { // Прошиваем EPROM Из RAM case 4: Seeprom_write(Address1,(unsigned int*)Address2,Length); break; // Читаем из EPROM в RAM case 5: if(mem) I2CA_ReadBlock(Address1,(unsigned int*)Address2,Length); else Seeprom_read(Address1,(unsigned int *)Address2,Length); break; default: return; } Answer(rs_arr,CMD_EXTEND); return; } //@}