Revert "Video6 uploaded"
This commit is contained in:
330
Pcb-1-lan9252/EEPROM_generator/src/generators/EEPROM.js
Normal file
330
Pcb-1-lan9252/EEPROM_generator/src/generators/EEPROM.js
Normal file
@@ -0,0 +1,330 @@
|
||||
/**
|
||||
* SOES EEPROM generator
|
||||
* EEPROM .bin / .hex code generation logic
|
||||
|
||||
* This tool serves as:
|
||||
- EtherCAT Slave Information XML + EEPROM binary generator
|
||||
- SOES code generator
|
||||
|
||||
* Victor Sluiter 2013-2018
|
||||
* Kuba Buda 2020-2021
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
// ####################### EEPROM generating ####################### //
|
||||
|
||||
function hex_generator(form, stringOnly=false)
|
||||
{
|
||||
//WORD ADDRESS 0-7
|
||||
var record = getConfigDataBytes(form);
|
||||
if (stringOnly) { return getConfigDataString(record, form.ESC.value); }
|
||||
|
||||
/** Takes form, returns config data:
|
||||
* first 16 bytes (8 words) with check sum */
|
||||
function getConfigDataBytes(form) {
|
||||
const recordLength = parseInt(form.EEPROMsize.value);
|
||||
var record = new Uint8Array(recordLength);
|
||||
record.fill(0xFF);
|
||||
//Start of EEPROM contents; A lot of information can be found in 5.4 of ETG1000.6
|
||||
let pdiControl = 0x05;
|
||||
const spiMode = parseInt(form.SPImode.value); // valid values ara 0, 1, 2 or 3
|
||||
let reserved_0x05 = 0x0000;
|
||||
|
||||
switch(form.ESC.value) {
|
||||
case SupportedESC.AX58100:
|
||||
reserved_0x05 = 0x001A; // enable IO for SPI driver on AX58100:
|
||||
// Write 0x1A value (INT edge pulse length, 8 mA Control + IO 9:0 Drive Select) to 0x0A (Host Interface Extend Setting and Drive Strength
|
||||
break;
|
||||
case SupportedESC.LAN9252:
|
||||
pdiControl = 0x80;
|
||||
break;
|
||||
case SupportedESC.LAN9253_Beckhoff:
|
||||
reserved_0x05 = 0xC040; // enable ERRLED, STATE_RUNLED and MI Write
|
||||
// in ASIC CONFIGURATION REGISTER: 0142h-0143h (refer to DS00003421A-page 268)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//WORD ADDRESS 0-7
|
||||
writeEEPROMbyte_byteaddress(pdiControl, 0, record); //PDI control: SPI slave (mapped to register 0x0140)
|
||||
writeEEPROMbyte_byteaddress(0x06, 1, record); //ESC configuration: Distributed clocks Sync Out and Latch In enabled (mapped register 0x0141)
|
||||
writeEEPROMbyte_byteaddress(spiMode, 2, record); //SPI mode (mapped to register 0x0150)
|
||||
writeEEPROMbyte_byteaddress(0x44, 3, record); //SYNC /LATCH configuration (mapped to 0x0151). Make both Syncs output
|
||||
writeEEPROMword_wordaddress(0x0064, 2, record); //Syncsignal Pulselenght in 10ns units(mapped to 0x0982:0x0983)
|
||||
writeEEPROMword_wordaddress(0x00, 3, record); //Extended PDI configuration (none for SPI slave)(0x0152:0x0153)
|
||||
writeEEPROMword_wordaddress(0x00, 4, record); //Configured Station Alias (0x0012:0x0013)
|
||||
writeEEPROMword_wordaddress(reserved_0x05, 5, record); //Reserved, 0 (when not AX58100)
|
||||
writeEEPROMword_wordaddress(0, 6, record); //Reserved, 0
|
||||
const crc = FindCRC(record, 14);
|
||||
writeEEPROMword_wordaddress(crc, 7, record); //CRC
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
//WORD ADDRESS 8-15
|
||||
writeEEPROMDword_wordaddress(parseInt(form.VendorID.value),8,record); //CoE 0x1018:01
|
||||
writeEEPROMDword_wordaddress(parseInt(form.ProductCode.value),10,record); //CoE 0x1018:02
|
||||
writeEEPROMDword_wordaddress(parseInt(form.RevisionNumber.value),12,record);//CoE 0x1018:03
|
||||
writeEEPROMDword_wordaddress(parseInt(form.SerialNumber.value),14,record); //CoE 0x1018:04
|
||||
//WORD ADDRESS 16-23
|
||||
writeEEPROMword_wordaddress(0,16,record); //Execution Delay Time; units?
|
||||
writeEEPROMword_wordaddress(0,17,record); //Port0 Delay Time; units?
|
||||
writeEEPROMword_wordaddress(0,18,record); //Port1 Delay Time; units?
|
||||
writeEEPROMword_wordaddress(0,19,record); //Reserved, zero
|
||||
writeEEPROMword_wordaddress(0,20,record); //Bootstrap Rx mailbox offset //Bootstrap not supported
|
||||
writeEEPROMword_wordaddress(0,21,record); //Bootstrap Rx mailbox size
|
||||
writeEEPROMword_wordaddress(0,22,record); //Bootstrap Tx mailbox offset
|
||||
writeEEPROMword_wordaddress(0,23,record); //Bootstrap Tx mailbox size
|
||||
//WORD ADDRESS 24-...
|
||||
writeEEPROMword_wordaddress(parseInt(form.RxMailboxOffset.value),24,record); //Standard Rx mailbox offset
|
||||
writeEEPROMword_wordaddress(parseInt(form.MailboxSize.value),25,record); //Standard Rx mailbox size
|
||||
writeEEPROMword_wordaddress(parseInt(form.TxMailboxOffset.value),26,record); //Standard Tx mailbox offset
|
||||
writeEEPROMword_wordaddress(parseInt(form.MailboxSize.value),27,record); //Standard Tx mailbox size
|
||||
writeEEPROMword_wordaddress(0x04,28,record); //CoE protocol, see Table18 in ETG1000.6
|
||||
for (var count = 29; count <= 61; count++) { //fill reserved area with zeroes
|
||||
writeEEPROMword_wordaddress(0,count,record);
|
||||
}
|
||||
writeEEPROMword_wordaddress((Math.floor(parseInt(form.EEPROMsize.value)/128))-1,62,record); //EEPROM size
|
||||
writeEEPROMword_wordaddress(1,63,record); //Version
|
||||
////////////////////////////////////
|
||||
/// Vendor Specific Info //
|
||||
////////////////////////////////////
|
||||
|
||||
//Strings
|
||||
var array_of_strings = [form.TextDeviceType.value, form.TextGroupType.value, form.ImageName.value, form.TextDeviceName.value];
|
||||
var offset = 0;
|
||||
offset = writeEEPROMstrings(record, 0x80, array_of_strings); //See ETG1000.6 Table20
|
||||
//General info
|
||||
offset = writeEEPROMgeneral_settings(form,offset,record); //See ETG1000.6 Table21
|
||||
//FMMU
|
||||
offset = writeFMMU(form,offset, record); //see Table 22 ETG1000.6
|
||||
//SyncManagers
|
||||
offset = writeSyncManagers(form, offset, record); //See Table 23 ETG1000.6
|
||||
//End of EEPROM contents
|
||||
const eepromSize = getForm().EEPROMsize.value;
|
||||
|
||||
return record;
|
||||
|
||||
/** See ETG1000.6 Table20 for Category string */
|
||||
function writeEEPROMstrings(record, offset, a_strings)
|
||||
{
|
||||
var number_of_strings = a_strings.length;
|
||||
var total_string_data_length = 0;
|
||||
var length_is_even;
|
||||
for(var strcounter = 0; strcounter < number_of_strings ; strcounter++)
|
||||
{
|
||||
total_string_data_length += a_strings[strcounter].length //add length of strings
|
||||
}
|
||||
total_string_data_length += number_of_strings; //for each string a byte is needed to indicate the length
|
||||
total_string_data_length += 1; //for byte to give 'number of strings'
|
||||
if(total_string_data_length %2) //if length is even (ends at word boundary)
|
||||
length_is_even = false;
|
||||
else
|
||||
length_is_even = true;
|
||||
writeEEPROMword_wordaddress(0x000A, offset/2, record); //Type: STRING
|
||||
writeEEPROMword_wordaddress(Math.ceil(total_string_data_length/2), (offset/2) + 1, record); //write length of complete package
|
||||
offset += 4; //2 words written
|
||||
writeEEPROMbyte_byteaddress(number_of_strings, offset++, record);
|
||||
for(var strcounter = 0; strcounter < number_of_strings ; strcounter++)
|
||||
{
|
||||
writeEEPROMbyte_byteaddress(a_strings[strcounter].length, offset++, record);
|
||||
for(var charcounter = 0 ; charcounter < a_strings[strcounter].length ; charcounter++)
|
||||
{
|
||||
writeEEPROMbyte_byteaddress(a_strings[strcounter].charCodeAt(charcounter), offset++, record);
|
||||
}
|
||||
}
|
||||
if(length_is_even == false)
|
||||
{
|
||||
writeEEPROMbyte_byteaddress(0, offset++, record);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
/** See ETG1000.6 Table21 */
|
||||
function writeEEPROMgeneral_settings(form,offset,record)
|
||||
{
|
||||
const General_category = 0x1E; // value: 30d
|
||||
const categorysize = 0x10;
|
||||
//Clear memory region
|
||||
for(let wordcount = 0; wordcount < categorysize + 2; wordcount++) {
|
||||
writeEEPROMword_wordaddress(0, (offset/2) + wordcount, record);
|
||||
}
|
||||
//write code 30, 'General type'. See ETG1000.6, Table 19
|
||||
writeEEPROMword_wordaddress(General_category, offset/2, record);
|
||||
//write length of General Category data
|
||||
writeEEPROMword_wordaddress(categorysize, 1+(offset/2), record);
|
||||
offset +=4;
|
||||
writeEEPROMbyte_byteaddress(2,offset++,record);//index to string for Group Info
|
||||
writeEEPROMbyte_byteaddress(3,offset++,record);//index to string for Image Name
|
||||
writeEEPROMbyte_byteaddress(1,offset++,record);//index to string for Device Order Number
|
||||
writeEEPROMbyte_byteaddress(4,offset++,record);//index to string for Device Name Information
|
||||
offset++; //byte 4 is reserved
|
||||
writeEEPROMbyte_byteaddress(getCOEdetails(form),offset++,record);//CoE Details
|
||||
writeEEPROMbyte_byteaddress(0,offset++,record); //Enable FoE
|
||||
writeEEPROMbyte_byteaddress(0,offset++,record); //Enable EoE
|
||||
writeEEPROMbyte_byteaddress(0,offset++,record); //reserved
|
||||
writeEEPROMbyte_byteaddress(0,offset++,record); //reserved
|
||||
writeEEPROMbyte_byteaddress(0,offset++,record); //reserved
|
||||
writeEEPROMbyte_byteaddress(0,offset++,record); //flags (Bit0: Enable SafeOp, Bit1: Enable notLRW
|
||||
writeEEPROMword_wordaddress(0x0000, offset/2, record); //current consumption in mA
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(0x0000, offset/2, record); //2 pad bytes
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(getPhysicalPort(form), offset/2, record);
|
||||
offset += 2;
|
||||
offset += 14; //14 pad bytes
|
||||
return offset;
|
||||
}
|
||||
/** See ETG1000.6 Table 22 */
|
||||
function writeFMMU(form, offset, record)
|
||||
{
|
||||
const FMMU_category = 0x28 // 40d
|
||||
writeEEPROMword_wordaddress(FMMU_category,offset/2,record);
|
||||
offset += 2;
|
||||
const length = 2 //length = 2 word = 4bytes: 3 FMMU's + padding
|
||||
//length = 1 word = 2bytes: 2 FMMU's.
|
||||
writeEEPROMword_wordaddress(length, offset/2, record);
|
||||
offset += 2;
|
||||
writeEEPROMbyte_byteaddress(1, offset++, record); //FMMU0 used for Outputs; see Table 22 ETG1000.6
|
||||
writeEEPROMbyte_byteaddress(2, offset++, record); //FMMU1 used for Inputs; see Table 22 ETG1000.6
|
||||
writeEEPROMbyte_byteaddress(3, offset++, record); //FMMU2 used for Mailbox State
|
||||
writeEEPROMbyte_byteaddress(0, offset++, record); //padding, disable FMMU4 if exists
|
||||
|
||||
return offset;
|
||||
}
|
||||
/** See Table 23 ETG1000.6 */
|
||||
function writeSyncManagers(form, offset, record)
|
||||
{
|
||||
const SyncManager_category = 0x29 // 41d
|
||||
writeEEPROMword_wordaddress(SyncManager_category, offset/2, record); //SyncManager
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(0x10, offset/2, record); //size of structure category
|
||||
offset += 2;
|
||||
//SM0
|
||||
writeEEPROMword_wordaddress(parseInt(form.RxMailboxOffset.value),offset/2, record); //Physical start address
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(parseInt(form.MailboxSize.value),offset/2, record); //Physical size
|
||||
offset += 2;
|
||||
writeEEPROMbyte_byteaddress(0x26,offset++, record); //Mode of operation
|
||||
writeEEPROMbyte_byteaddress(0,offset++, record); //don't care
|
||||
writeEEPROMbyte_byteaddress(1,offset++, record); //Enable Syncmanager; bit0: enable, bit 1: fixed content, bit 2: virtual SyncManager, bit 3: Op Only
|
||||
writeEEPROMbyte_byteaddress(1,offset++, record); //SyncManagerType; 0: not used, 1: Mbx out, 2: Mbx In, 3: PDO, 4: PDI
|
||||
//SM1
|
||||
writeEEPROMword_wordaddress(parseInt(form.TxMailboxOffset.value),offset/2, record); //Physical start address
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(parseInt(form.MailboxSize.value),offset/2, record); //Physical size
|
||||
offset += 2;
|
||||
writeEEPROMbyte_byteaddress(0x22,offset++, record); //Mode of operation
|
||||
writeEEPROMbyte_byteaddress(0,offset++, record); //don't care
|
||||
writeEEPROMbyte_byteaddress(1,offset++, record); //Enable Syncmanager; bit0: enable, bit 1: fixed content, bit 2: virtual SyncManager, bit 3: Op Only
|
||||
writeEEPROMbyte_byteaddress(2,offset++, record); //SyncManagerType; 0: not used, 1: Mbx out, 2: Mbx In, 3: PDO, 4: PDI
|
||||
//SM2
|
||||
writeEEPROMword_wordaddress(parseInt(form.SM2Offset.value),offset/2, record); //Physical start address
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(0,offset/2, record); //Physical size
|
||||
offset += 2;
|
||||
writeEEPROMbyte_byteaddress(0x24,offset++, record); //Mode of operation
|
||||
writeEEPROMbyte_byteaddress(0,offset++, record); //don't care
|
||||
writeEEPROMbyte_byteaddress(1,offset++, record); //Enable Syncmanager; bit0: enable, bit 1: fixed content, bit 2: virtual SyncManager, bit 3: Op Only
|
||||
writeEEPROMbyte_byteaddress(3,offset++, record); //SyncManagerType; 0: not used, 1: Mbx out, 2: Mbx In, 3: PDO, 4: PDI
|
||||
//SM3
|
||||
writeEEPROMword_wordaddress(parseInt(form.SM3Offset.value),offset/2, record); //Physical start address
|
||||
offset += 2;
|
||||
writeEEPROMword_wordaddress(0,offset/2, record); //Physical size
|
||||
offset += 2;
|
||||
writeEEPROMbyte_byteaddress(0x20,offset++, record); //Mode of operation
|
||||
writeEEPROMbyte_byteaddress(0,offset++, record); //don't care
|
||||
writeEEPROMbyte_byteaddress(1,offset++, record); //Enable Syncmanager; bit0: enable, bit 1: fixed content, bit 2: virtual SyncManager, bit 3: Op Only
|
||||
writeEEPROMbyte_byteaddress(4,offset++, record); //SyncManagerType; 0: not used, 1: Mbx out, 2: Mbx In, 3: PDO, 4: PDI
|
||||
return offset;
|
||||
}
|
||||
function getCOEdetails(form)
|
||||
{
|
||||
let coedetails = 0;
|
||||
if(form.CoeDetailsEnableSDO.checked) coedetails |= 0x01; //Enable SDO
|
||||
if(form.CoeDetailsEnableSDOInfo.checked) coedetails |= 0x02; //Enable SDO Info
|
||||
if(form.CoeDetailsEnablePDOAssign.checked) coedetails |= 0x04; //Enable PDO Assign
|
||||
if(form.CoeDetailsEnablePDOConfiguration.checked) coedetails |= 0x08; //Enable PDO Configuration
|
||||
if(form.CoeDetailsEnableUploadAtStartup.checked) coedetails |= 0x10; //Enable Upload at startup
|
||||
if(form.CoeDetailsEnableSDOCompleteAccess.checked) coedetails |= 0x20; //Enable SDO complete access
|
||||
return coedetails;
|
||||
}
|
||||
/** ETG1000.6 Table 21 */
|
||||
function getPhysicalPort(form)
|
||||
{
|
||||
let portinfo = 0;
|
||||
let physicals = [form.Port3Physical.value, form.Port2Physical.value, form.Port1Physical.value, form.Port0Physical.value];
|
||||
for (var physicalcounter = 0; physicalcounter < physicals.length ; physicalcounter++)
|
||||
{
|
||||
portinfo = (portinfo << 4); //shift previous result
|
||||
switch(physicals[physicalcounter])
|
||||
{
|
||||
case 'Y':
|
||||
case 'H':
|
||||
portinfo |= 0x01; //MII
|
||||
break;
|
||||
case 'K':
|
||||
portinfo |= 0x03; //EBUS
|
||||
break;
|
||||
default:
|
||||
portinfo |= 0; //No connection
|
||||
}
|
||||
}
|
||||
return portinfo;
|
||||
}
|
||||
|
||||
/** computes crc value */
|
||||
function FindCRC(data,datalen) {
|
||||
var i,j;
|
||||
var c;
|
||||
var CRC=0xFF;
|
||||
var genPoly = 0x07;
|
||||
for (j=0; j<datalen; j++)
|
||||
{
|
||||
c = data[j];
|
||||
CRC ^= c;
|
||||
for(i = 0; i<8; i++)
|
||||
if(CRC & 0x80 )
|
||||
CRC = (CRC << 1) ^ genPoly;
|
||||
else
|
||||
CRC <<= 1;
|
||||
CRC &= 0xff;
|
||||
}
|
||||
return CRC;
|
||||
}
|
||||
|
||||
function writeEEPROMbyte_byteaddress(byte, address, record)
|
||||
{
|
||||
record[address] = byte;
|
||||
}
|
||||
|
||||
function writeEEPROMbyte_wordaddress(byte, address, record)
|
||||
{
|
||||
record[address*2] = byte;
|
||||
}
|
||||
|
||||
function writeEEPROMword_wordaddress(word, address, record)
|
||||
{//little endian word storage!
|
||||
record[ address*2 ] = word&0xFF;
|
||||
record[1 + (address*2)] = (word>>8) & 0xFF;
|
||||
}
|
||||
|
||||
function writeEEPROMDword_wordaddress(word, address, record)
|
||||
{//little endian word storage!
|
||||
record[ address*2 ] = word&0xFF;
|
||||
record[1 + (address*2)] = (word>>8) & 0xFF;
|
||||
record[2 + (address*2)] = (word>>16) & 0xFF;
|
||||
record[3 + (address*2)] = (word>>24) & 0xFF;
|
||||
}
|
||||
|
||||
/** takes bytes array and count, returns ConfigData string */
|
||||
function getConfigDataString(record, esc) {
|
||||
const configdata_bytecount = new Set(configOnReservedBytes).has(esc) ? 14 : 7;
|
||||
|
||||
var configdata = '';
|
||||
for (var bytecount = 0; bytecount < configdata_bytecount; bytecount++) {
|
||||
configdata += (record[bytecount] + 0x100).toString(16).slice(-2).toUpperCase();
|
||||
}
|
||||
return configdata;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user