Refactored TDF processing PHP code to confirm to new TDF format
This commit is contained in:
@@ -0,0 +1,513 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
use Targets\TargetDescriptionFiles\Services\StringService;
|
||||
use Targets\TargetDescriptionFiles\TargetDescriptionFile;
|
||||
use Targets\TargetDescriptionFiles\MemorySegment;
|
||||
use Targets\TargetDescriptionFiles\MemorySegmentSection;
|
||||
use Targets\TargetDescriptionFiles\PhysicalInterface;
|
||||
use Targets\TargetPeripheral;
|
||||
use Targets\TargetRegister;
|
||||
use Targets\TargetRegisterGroup;
|
||||
|
||||
require_once __DIR__ . "/../TargetDescriptionFile.php";
|
||||
require_once __DIR__ . "/../Services/StringService.php";
|
||||
require_once __DIR__ . "/AvrFamily.php";
|
||||
require_once __DIR__ . "/AvrPhysicalInterface.php";
|
||||
require_once __DIR__ . "/Signature.php";
|
||||
require_once __DIR__ . "/DebugWireParameters.php";
|
||||
require_once __DIR__ . "/IspParameters.php";
|
||||
require_once __DIR__ . "/JtagParameters.php";
|
||||
require_once __DIR__ . "/PdiParameters.php";
|
||||
require_once __DIR__ . "/UpdiParameters.php";
|
||||
require_once __DIR__ . "/FuseBitsDescriptor.php";
|
||||
|
||||
class Avr8TargetDescriptionFile extends TargetDescriptionFile
|
||||
{
|
||||
private StringService $stringService;
|
||||
|
||||
public function __construct(?StringService $stringService = null)
|
||||
{
|
||||
$this->stringService = $stringService ?? new StringService();
|
||||
}
|
||||
|
||||
public function getAdditionalDeviceAttributes(): array
|
||||
{
|
||||
return [
|
||||
'avr-family' => $this->getAvrFamily()->value,
|
||||
];
|
||||
}
|
||||
|
||||
public function getSignature(): ?Signature
|
||||
{
|
||||
$byteZero = $this->getPropertyValue('signatures', 'signature0');
|
||||
$byteOne = $this->getPropertyValue('signatures', 'signature1');
|
||||
$byteTwo = $this->getPropertyValue('signatures', 'signature2');
|
||||
|
||||
if (!empty($byteZero) && !empty($byteOne) && !empty($byteTwo)) {
|
||||
$signature = new Signature();
|
||||
$signature->byteZero = $this->stringService->tryStringToInt($byteZero);
|
||||
$signature->byteOne = $this->stringService->tryStringToInt($byteOne);
|
||||
$signature->byteTwo = $this->stringService->tryStringToInt($byteTwo);
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAvrFamily(): ?AvrFamily
|
||||
{
|
||||
return AvrFamily::tryFrom($this->deviceAttributesByName['avr-family']);
|
||||
}
|
||||
|
||||
public function getSupportedPhysicalInterfaces(): array
|
||||
{
|
||||
$physicalInterfacesByName = [
|
||||
'isp' => AvrPhysicalInterface::ISP,
|
||||
'debugwire' => AvrPhysicalInterface::DEBUG_WIRE,
|
||||
'updi' => AvrPhysicalInterface::UPDI,
|
||||
'pdi' => AvrPhysicalInterface::PDI,
|
||||
'jtag' => AvrPhysicalInterface::JTAG,
|
||||
];
|
||||
|
||||
return array_filter(array_map(
|
||||
fn (PhysicalInterface $interface): ?AvrPhysicalInterface
|
||||
=> $physicalInterfacesByName[strtolower($interface->name ?? '')] ?? null,
|
||||
$this->physicalInterfaces
|
||||
));
|
||||
}
|
||||
|
||||
public function getSupportedDebugPhysicalInterfaces(): array
|
||||
{
|
||||
$physicalInterfacesByName = [
|
||||
'debugwire' => AvrPhysicalInterface::DEBUG_WIRE,
|
||||
'updi' => AvrPhysicalInterface::UPDI,
|
||||
'pdi' => AvrPhysicalInterface::PDI,
|
||||
'jtag' => AvrPhysicalInterface::JTAG,
|
||||
];
|
||||
|
||||
return array_filter(array_map(
|
||||
fn (PhysicalInterface $interface): ?AvrPhysicalInterface
|
||||
=> $physicalInterfacesByName[strtolower($interface->name ?? '')] ?? null,
|
||||
$this->physicalInterfaces
|
||||
));
|
||||
}
|
||||
|
||||
public function getDebugWireParameters(): DebugWireParameters
|
||||
{
|
||||
$output = new DebugWireParameters();
|
||||
|
||||
$programMemorySegment = $this->getProgramMemorySegment();
|
||||
if ($programMemorySegment instanceof MemorySegment) {
|
||||
$output->flashStartAddress = $programMemorySegment->startAddress;
|
||||
$output->flashSize = $programMemorySegment->size;
|
||||
$output->flashPageSize = $programMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$ramMemorySegment = $this->getRamSegment();
|
||||
if ($ramMemorySegment instanceof MemorySegment) {
|
||||
$output->ramStartAddress = $ramMemorySegment->startAddress;
|
||||
}
|
||||
|
||||
$output->bootSections = $this->getBootSections();
|
||||
|
||||
$eepromMemorySegment = $this->getEepromSegment();
|
||||
if ($eepromMemorySegment instanceof MemorySegment) {
|
||||
$output->eepromSize = $eepromMemorySegment->size;
|
||||
$output->eepromPageSize = $eepromMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$output->ocdRevision = $this->stringService->tryStringToInt($this->getPropertyValue('ocd', 'ocd_revision'));
|
||||
$output->ocdDataRegister = $this->stringService->tryStringToInt($this->getPropertyValue('ocd', 'ocd_datareg'));
|
||||
|
||||
$eepromPeripheral = $this->getTargetPeripheral('eeprom');
|
||||
|
||||
if ($eepromPeripheral instanceof TargetPeripheral) {
|
||||
$eepromAddressRegister = $eepromPeripheral->getRegister('eeprom', 'eear');
|
||||
|
||||
if ($eepromAddressRegister instanceof TargetRegister) {
|
||||
$output->eepromAddressRegisterLow = $eepromAddressRegister->address;
|
||||
$output->eepromAddressRegisterHigh = ($eepromAddressRegister->size == 2)
|
||||
? $eepromAddressRegister->address + 1
|
||||
: $eepromAddressRegister->address;
|
||||
|
||||
} else {
|
||||
$eepromAddressRegisterLow = $eepromPeripheral->getRegister('eeprom', 'eearl');
|
||||
$eepromAddressRegisterHigh = $eepromPeripheral->getRegister('eeprom', 'eearh');
|
||||
|
||||
if ($eepromAddressRegisterLow instanceof TargetRegister) {
|
||||
$output->eepromAddressRegisterLow = $eepromAddressRegisterLow->address;
|
||||
$output->eepromAddressRegisterHigh = $eepromAddressRegisterLow->address;
|
||||
}
|
||||
|
||||
if ($eepromAddressRegisterHigh instanceof TargetRegister) {
|
||||
$output->eepromAddressRegisterHigh = $eepromAddressRegisterHigh->address;
|
||||
}
|
||||
}
|
||||
|
||||
$eepromDataRegister = $eepromPeripheral->getRegister('eeprom', 'eedr');
|
||||
if ($eepromDataRegister instanceof TargetRegister) {
|
||||
$output->eepromDataRegisterAddress = $eepromDataRegister->address;
|
||||
}
|
||||
|
||||
$eepromControlRegister = $eepromPeripheral->getRegister('eeprom', 'eecr');
|
||||
if ($eepromControlRegister instanceof TargetRegister) {
|
||||
$output->eepromControlRegisterAddress = $eepromControlRegister->address;
|
||||
}
|
||||
}
|
||||
|
||||
$cpuPeripheral = $this->getTargetPeripheral('cpu');
|
||||
|
||||
if ($cpuPeripheral instanceof TargetPeripheral) {
|
||||
$spmcsRegister = $cpuPeripheral->getRegister('cpu', 'spmcsr')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'spmcr');
|
||||
|
||||
if ($spmcsRegister instanceof TargetRegister) {
|
||||
$output->spmcRegisterStartAddress = $spmcsRegister->address;
|
||||
}
|
||||
|
||||
$osccalRegister = $cpuPeripheral->getRegister('cpu', 'osccal')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'osccal0')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'osccal1')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'fosccal')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'sosccala');
|
||||
|
||||
if ($osccalRegister instanceof TargetRegister) {
|
||||
$output->osccalAddress = $osccalRegister->address;
|
||||
}
|
||||
}
|
||||
|
||||
if ($output->spmcRegisterStartAddress === null) {
|
||||
$bootLoaderPeripheral = $this->getTargetPeripheral('boot_load');
|
||||
|
||||
if ($bootLoaderPeripheral instanceof TargetPeripheral) {
|
||||
$spmcsRegister = $bootLoaderPeripheral->getRegister('boot_load', 'spmcr')
|
||||
?? $bootLoaderPeripheral->getRegister('boot_load', 'spmcsr');
|
||||
|
||||
if ($spmcsRegister instanceof TargetRegister) {
|
||||
$output->spmcRegisterStartAddress = $spmcsRegister->address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getIspParameters(): IspParameters
|
||||
{
|
||||
$output = new IspParameters();
|
||||
|
||||
$output->programModeTimeout = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_timeout')
|
||||
);
|
||||
$output->programModeStabilizationDelay = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_stabdelay')
|
||||
);
|
||||
$output->programModeCommandExecutionDelay = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_cmdexedelay')
|
||||
);
|
||||
$output->programModeSyncLoops = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_synchloops')
|
||||
);
|
||||
$output->programModeByteDelay = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_bytedelay')
|
||||
);
|
||||
$output->programModePollValue = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_pollvalue')
|
||||
);
|
||||
$output->programModePollIndex = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispenterprogmode_pollindex')
|
||||
);
|
||||
$output->programModePreDelay = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispleaveprogmode_predelay')
|
||||
);
|
||||
$output->programModePostDelay = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispleaveprogmode_postdelay')
|
||||
);
|
||||
$output->readSignaturePollIndex = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispreadsign_pollindex')
|
||||
);
|
||||
$output->readFusePollIndex = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispreadfuse_pollindex')
|
||||
);
|
||||
$output->readLockPollIndex = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('isp_interface', 'ispreadlock_pollindex')
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getJtagParameters(): JtagParameters
|
||||
{
|
||||
$output = new JtagParameters();
|
||||
|
||||
$programMemorySegment = $this->getProgramMemorySegment();
|
||||
if ($programMemorySegment instanceof MemorySegment) {
|
||||
$output->flashStartAddress = $programMemorySegment->startAddress;
|
||||
$output->flashSize = $programMemorySegment->size;
|
||||
$output->flashPageSize = $programMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$ramMemorySegment = $this->getRamSegment();
|
||||
if ($ramMemorySegment instanceof MemorySegment) {
|
||||
$output->ramStartAddress = $ramMemorySegment->startAddress;
|
||||
}
|
||||
|
||||
$output->bootSections = $this->getBootSections();
|
||||
|
||||
$eepromMemorySegment = $this->getEepromSegment();
|
||||
if ($eepromMemorySegment instanceof MemorySegment) {
|
||||
$output->eepromSize = $eepromMemorySegment->size;
|
||||
$output->eepromPageSize = $eepromMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$output->ocdRevision = $this->stringService->tryStringToInt($this->getPropertyValue('ocd', 'ocd_revision'));
|
||||
$output->ocdDataRegister = $this->stringService->tryStringToInt($this->getPropertyValue('ocd', 'ocd_datareg'));
|
||||
|
||||
$eepromPeripheral = $this->getTargetPeripheral('eeprom');
|
||||
|
||||
if ($eepromPeripheral instanceof TargetPeripheral) {
|
||||
$eepromAddressRegister = $eepromPeripheral->getRegister('eeprom', 'eear');
|
||||
|
||||
if ($eepromAddressRegister instanceof TargetRegister) {
|
||||
$output->eepromAddressRegisterLow = $eepromAddressRegister->address;
|
||||
$output->eepromAddressRegisterHigh = ($eepromAddressRegister->size == 2)
|
||||
? $eepromAddressRegister->address + 1
|
||||
: $eepromAddressRegister->address;
|
||||
|
||||
} else {
|
||||
$eepromAddressRegisterLow = $eepromPeripheral->getRegister('eeprom', 'eearl');
|
||||
$eepromAddressRegisterHigh = $eepromPeripheral->getRegister('eeprom', 'eearh');
|
||||
|
||||
if ($eepromAddressRegisterLow instanceof TargetRegister) {
|
||||
$output->eepromAddressRegisterLow = $eepromAddressRegisterLow->address;
|
||||
$output->eepromAddressRegisterHigh = $eepromAddressRegisterLow->address;
|
||||
}
|
||||
|
||||
if ($eepromAddressRegisterHigh instanceof TargetRegister) {
|
||||
$output->eepromAddressRegisterHigh = $eepromAddressRegisterHigh->address;
|
||||
}
|
||||
}
|
||||
|
||||
$eepromDataRegister = $eepromPeripheral->getRegister('eeprom', 'eedr');
|
||||
if ($eepromDataRegister instanceof TargetRegister) {
|
||||
$output->eepromDataRegisterAddress = $eepromDataRegister->address;
|
||||
}
|
||||
|
||||
$eepromControlRegister = $eepromPeripheral->getRegister('eeprom', 'eecr');
|
||||
if ($eepromControlRegister instanceof TargetRegister) {
|
||||
$output->eepromControlRegisterAddress = $eepromControlRegister->address;
|
||||
}
|
||||
}
|
||||
|
||||
$cpuPeripheral = $this->getTargetPeripheral('cpu');
|
||||
|
||||
if ($cpuPeripheral instanceof TargetPeripheral) {
|
||||
$spmcsRegister = $cpuPeripheral->getRegister('cpu', 'spmcsr')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'spmcr');
|
||||
|
||||
if ($spmcsRegister instanceof TargetRegister) {
|
||||
$output->spmcRegisterStartAddress = $spmcsRegister->address;
|
||||
}
|
||||
|
||||
$osccalRegister = $cpuPeripheral->getRegister('cpu', 'osccal')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'osccal0')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'osccal1')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'fosccal')
|
||||
?? $cpuPeripheral->getRegister('cpu', 'sosccala');
|
||||
|
||||
if ($osccalRegister instanceof TargetRegister) {
|
||||
$output->osccalAddress = $osccalRegister->address;
|
||||
}
|
||||
}
|
||||
|
||||
if ($output->spmcRegisterStartAddress === null) {
|
||||
$bootLoaderPeripheral = $this->getTargetPeripheral('boot_load');
|
||||
|
||||
if ($bootLoaderPeripheral instanceof TargetPeripheral) {
|
||||
$spmcsRegister = $bootLoaderPeripheral->getRegister('boot_load', 'spmcr')
|
||||
?? $bootLoaderPeripheral->getRegister('boot_load', 'spmcsr');
|
||||
|
||||
if ($spmcsRegister instanceof TargetRegister) {
|
||||
$output->spmcRegisterStartAddress = $spmcsRegister->address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getPdiParameters(): PdiParameters
|
||||
{
|
||||
$output = new PdiParameters();
|
||||
|
||||
$output->appSectionOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'app_section_offset')
|
||||
);
|
||||
$output->bootSectionOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'boot_section_offset')
|
||||
);
|
||||
$output->ramOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'datamem_offset')
|
||||
);
|
||||
$output->eepromOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'eeprom_offset')
|
||||
);
|
||||
$output->userSignaturesOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'user_signatures_offset')
|
||||
);
|
||||
$output->productSignaturesOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'prod_signatures_offset')
|
||||
);
|
||||
$output->fuseRegistersOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'fuse_registers_offset')
|
||||
);
|
||||
$output->lockRegistersOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'lock_registers_offset')
|
||||
);
|
||||
|
||||
$programMemorySegment = $this->getProgramMemorySegment();
|
||||
if ($programMemorySegment instanceof MemorySegment) {
|
||||
$output->flashPageSize = $programMemorySegment->pageSize;
|
||||
|
||||
$appSection = $programMemorySegment->getSection('app_section');
|
||||
if ($appSection instanceof MemorySegmentSection) {
|
||||
$output->appSectionSize = $appSection->size;
|
||||
}
|
||||
|
||||
$bootSection = $programMemorySegment->getSection('boot_section');
|
||||
if ($bootSection instanceof MemorySegmentSection) {
|
||||
$output->bootSectionSize = $bootSection->size;
|
||||
}
|
||||
}
|
||||
|
||||
$eepromMemorySegment = $this->getEepromSegment();
|
||||
if ($eepromMemorySegment instanceof MemorySegment) {
|
||||
$output->eepromSize = $eepromMemorySegment->size;
|
||||
$output->eepromPageSize = $eepromMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$nvmModuleRegisterGroup = $this->getTargetRegisterGroup('nvm', 'nvm');
|
||||
if ($nvmModuleRegisterGroup instanceof TargetRegisterGroup) {
|
||||
$output->nvmModuleBaseAddress = $nvmModuleRegisterGroup->baseAddress;
|
||||
}
|
||||
|
||||
$output->signatureOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('pdi_interface', 'signature_offset')
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getUpdiParameters(): UpdiParameters
|
||||
{
|
||||
$output = new UpdiParameters();
|
||||
|
||||
$output->programMemoryOffset = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('updi_interface', 'progmem_offset')
|
||||
);
|
||||
|
||||
$programMemorySegment = $this->getProgramMemorySegment();
|
||||
if ($programMemorySegment instanceof MemorySegment) {
|
||||
$output->flashSize = $programMemorySegment->size;
|
||||
$output->flashPageSize = $programMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$eepromMemorySegment = $this->getEepromSegment();
|
||||
if ($eepromMemorySegment instanceof MemorySegment) {
|
||||
$output->eepromStartAddress = $eepromMemorySegment->startAddress;
|
||||
$output->eepromSize = $eepromMemorySegment->size;
|
||||
$output->eepromPageSize = $eepromMemorySegment->pageSize;
|
||||
}
|
||||
|
||||
$output->nvmModuleBaseAddress = $this->getTargetRegisterGroup(
|
||||
'nvmctrl',
|
||||
'nvmctrl'
|
||||
)->baseAddress ?? null;
|
||||
|
||||
$output->ocdBaseAddress = $this->stringService->tryStringToInt(
|
||||
$this->getPropertyValue('updi_interface', 'ocd_base_addr')
|
||||
);
|
||||
|
||||
$signatureMemorySegment = $this->getMemorySegment(
|
||||
'data',
|
||||
'signatures'
|
||||
);
|
||||
if ($signatureMemorySegment instanceof MemorySegment) {
|
||||
$output->signatureSegmentStartAddress = $signatureMemorySegment->startAddress;
|
||||
}
|
||||
|
||||
$fuseMemorySegment = $this->getMemorySegment(
|
||||
'data',
|
||||
'fuses'
|
||||
);
|
||||
if ($fuseMemorySegment instanceof MemorySegment) {
|
||||
$output->fuseSegmentSize = $fuseMemorySegment->size;
|
||||
$output->fuseSegmentStartAddress = $fuseMemorySegment->startAddress;
|
||||
}
|
||||
|
||||
$lockbitsMemorySegment = $this->getMemorySegment(
|
||||
'data',
|
||||
'lockbits'
|
||||
);
|
||||
if ($lockbitsMemorySegment instanceof MemorySegment) {
|
||||
$output->lockbitsSegmentStartAddress = $lockbitsMemorySegment->startAddress;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getFuseBitsDescriptor(string $fuseBitFieldKey): ?FuseBitsDescriptor
|
||||
{
|
||||
$peripheral = $this->getTargetPeripheral('fuse') ?? $this->getTargetPeripheral('nvm');
|
||||
if ($peripheral instanceof TargetPeripheral) {
|
||||
$fuseRegisterGroup = $peripheral->getRegisterGroup('fuse')
|
||||
?? $peripheral->getRegisterGroup('nvm_fuses');
|
||||
|
||||
if ($fuseRegisterGroup instanceof TargetRegisterGroup) {
|
||||
foreach ($fuseRegisterGroup->registers as $fuseRegister) {
|
||||
foreach ($fuseRegister->bitFields as $bitField) {
|
||||
if ($bitField->key === $fuseBitFieldKey) {
|
||||
return new FuseBitsDescriptor($fuseRegister->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getProgramMemorySegment(): ?MemorySegment
|
||||
{
|
||||
return $this->getMemorySegment('prog', 'internal_program_memory');
|
||||
}
|
||||
|
||||
private function getRamSegment(): ?MemorySegment
|
||||
{
|
||||
return $this->getMemorySegment('data', 'internal_ram');
|
||||
}
|
||||
|
||||
private function getEepromSegment(): ?MemorySegment
|
||||
{
|
||||
return $this->getMemorySegment('data', 'internal_eeprom')
|
||||
?? $this->getMemorySegment('eeprom', 'internal_eeprom');
|
||||
}
|
||||
|
||||
private function getBootSections(): array
|
||||
{
|
||||
$output = [];
|
||||
|
||||
$bootSectionPropertyGroups = $this->getPropertyGroup('boot_sections')->subPropertyGroups ?? [];
|
||||
foreach ($bootSectionPropertyGroups as $propertyGroup) {
|
||||
$output[] = new BootSection(
|
||||
$this->stringService->tryStringToInt($propertyGroup->getPropertyValue('start_address')),
|
||||
$this->stringService->tryStringToInt($propertyGroup->getPropertyValue('size')),
|
||||
$this->stringService->tryStringToInt($propertyGroup->getPropertyValue('page_size'))
|
||||
);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
enum AvrFamily: string
|
||||
{
|
||||
case MEGA = 'MEGA';
|
||||
case TINY = 'TINY';
|
||||
case XMEGA = 'XMEGA';
|
||||
case DB = 'DB';
|
||||
case DA = 'DA';
|
||||
case DD = 'DD';
|
||||
case EA = 'EA';
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
enum AvrPhysicalInterface: string
|
||||
{
|
||||
case ISP = 'ISP';
|
||||
case JTAG = 'JTAG';
|
||||
case PDI = 'PDI';
|
||||
case UPDI = 'UPDI';
|
||||
case DEBUG_WIRE = 'DEBUG_WIRE';
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
class BootSection
|
||||
{
|
||||
public ?int $startAddress = null;
|
||||
public ?int $size = null;
|
||||
public ?int $pageSize = null;
|
||||
|
||||
public function __construct(
|
||||
?int $startAddress,
|
||||
?int $size,
|
||||
?int $pageSize
|
||||
) {
|
||||
$this->startAddress = $startAddress;
|
||||
$this->size = $size;
|
||||
$this->pageSize = $pageSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
require_once __DIR__ . '/BootSection.php';
|
||||
|
||||
class DebugWireParameters
|
||||
{
|
||||
public ?int $flashPageSize = null;
|
||||
public ?int $flashSize = null;
|
||||
public ?int $flashStartAddress = null;
|
||||
|
||||
/** @var BootSection[] */
|
||||
public array $bootSections = [];
|
||||
|
||||
public ?int $ramStartAddress = null;
|
||||
public ?int $eepromSize = null;
|
||||
public ?int $eepromPageSize = null;
|
||||
public ?int $ocdRevision = null;
|
||||
public ?int $ocdDataRegister = null;
|
||||
public ?int $eepromAddressRegisterHigh = null;
|
||||
public ?int $eepromAddressRegisterLow = null;
|
||||
public ?int $eepromControlRegisterAddress = null;
|
||||
public ?int $eepromDataRegisterAddress = null;
|
||||
public ?int $spmcRegisterStartAddress = null;
|
||||
public ?int $osccalAddress = null;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
class FuseBitsDescriptor
|
||||
{
|
||||
public ?string $fuseType = null;
|
||||
|
||||
public function __construct(?string $fuseType)
|
||||
{
|
||||
$this->fuseType = strtolower($fuseType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
class IspParameters
|
||||
{
|
||||
public ?int $programModeTimeout = null;
|
||||
public ?int $programModeStabilizationDelay = null;
|
||||
public ?int $programModeCommandExecutionDelay = null;
|
||||
public ?int $programModeSyncLoops = null;
|
||||
public ?int $programModeByteDelay = null;
|
||||
public ?int $programModePollValue = null;
|
||||
public ?int $programModePollIndex = null;
|
||||
public ?int $programModePreDelay = null;
|
||||
public ?int $programModePostDelay = null;
|
||||
public ?int $readSignaturePollIndex = null;
|
||||
public ?int $readFusePollIndex = null;
|
||||
public ?int $readLockPollIndex = null;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
require_once __DIR__ . '/BootSection.php';
|
||||
|
||||
class JtagParameters
|
||||
{
|
||||
public ?int $flashPageSize = null;
|
||||
public ?int $flashSize = null;
|
||||
public ?int $flashStartAddress = null;
|
||||
|
||||
/** @var BootSection[] */
|
||||
public array $bootSections = [];
|
||||
|
||||
public ?int $ramStartAddress = null;
|
||||
public ?int $eepromSize = null;
|
||||
public ?int $eepromPageSize = null;
|
||||
public ?int $ocdRevision = null;
|
||||
public ?int $ocdDataRegister = null;
|
||||
public ?int $eepromAddressRegisterHigh = null;
|
||||
public ?int $eepromAddressRegisterLow = null;
|
||||
public ?int $eepromControlRegisterAddress = null;
|
||||
public ?int $eepromDataRegisterAddress = null;
|
||||
public ?int $spmcRegisterStartAddress = null;
|
||||
public ?int $osccalAddress = null;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
class PdiParameters
|
||||
{
|
||||
public ?int $appSectionOffset = null;
|
||||
public ?int $bootSectionOffset = null;
|
||||
public ?int $eepromOffset = null;
|
||||
public ?int $fuseRegistersOffset = null;
|
||||
public ?int $lockRegistersOffset = null;
|
||||
public ?int $userSignaturesOffset = null;
|
||||
public ?int $productSignaturesOffset = null;
|
||||
public ?int $ramOffset = null;
|
||||
public ?int $appSectionSize = null;
|
||||
public ?int $bootSectionSize = null;
|
||||
public ?int $flashPageSize = null;
|
||||
public ?int $eepromSize = null;
|
||||
public ?int $eepromPageSize = null;
|
||||
public ?int $nvmModuleBaseAddress = null;
|
||||
public ?int $signatureOffset = null;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
class Signature
|
||||
{
|
||||
public ?int $byteZero = null;
|
||||
public ?int $byteOne = null;
|
||||
public ?int $byteTwo = null;
|
||||
|
||||
public function toHex(): string
|
||||
{
|
||||
if ($this->byteZero === null || $this->byteOne === null || $this->byteTwo === null) {
|
||||
throw new \Exception("Cannot generate hex string of incomplete AVR8 target signature.");
|
||||
}
|
||||
|
||||
return '0x' . substr('0' . dechex($this->byteZero), -2)
|
||||
. substr('0' . dechex($this->byteOne), -2)
|
||||
. substr('0' . dechex($this->byteTwo), -2)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Avr8;
|
||||
|
||||
class UpdiParameters
|
||||
{
|
||||
public ?int $programMemoryOffset = null;
|
||||
public ?int $flashPageSize = null;
|
||||
public ?int $eepromPageSize = null;
|
||||
public ?int $nvmModuleBaseAddress = null;
|
||||
public ?int $ocdBaseAddress = null;
|
||||
public ?int $flashSize = null;
|
||||
public ?int $eepromSize = null;
|
||||
public ?int $eepromStartAddress = null;
|
||||
public ?int $signatureSegmentStartAddress = null;
|
||||
public ?int $fuseSegmentStartAddress = null;
|
||||
public ?int $fuseSegmentSize = null;
|
||||
public ?int $lockbitsSegmentStartAddress = null;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/MemorySegment.php";
|
||||
|
||||
class AddressSpace
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?int $startAddress = null;
|
||||
public ?int $size = null;
|
||||
public ?string $endianness = null;
|
||||
|
||||
/** @var MemorySegment[] */
|
||||
public array $memorySegments = [];
|
||||
|
||||
public function __construct(?string $key, ?int $startAddress, ?int $size, ?string $endianness)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->startAddress = $startAddress;
|
||||
$this->size = $size;
|
||||
$this->endianness = $endianness;
|
||||
}
|
||||
|
||||
public function totalSegmentSize(): int
|
||||
{
|
||||
return array_sum(
|
||||
array_map(
|
||||
fn (MemorySegment $segment): int => (int) $segment->size,
|
||||
$this->memorySegments
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function segmentStartAddress(): int
|
||||
{
|
||||
return min(
|
||||
array_map(
|
||||
fn (MemorySegment $segment): int => (int) $segment->startAddress,
|
||||
$this->memorySegments
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function segmentEndAddress(): int
|
||||
{
|
||||
return max(
|
||||
array_map(
|
||||
fn (MemorySegment $segment): int => (int) $segment->startAddress + $segment->size - 1,
|
||||
$this->memorySegments
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
35
build/scripts/Targets/TargetDescriptionFiles/BitField.php
Normal file
35
build/scripts/Targets/TargetDescriptionFiles/BitField.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class BitField
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?string $description = null;
|
||||
public ?int $mask = null;
|
||||
public ?string $access = null;
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?string $description,
|
||||
?int $mask,
|
||||
?string $access
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->mask = $mask;
|
||||
$this->access = $access;
|
||||
}
|
||||
|
||||
public function intersectsWith(BitField $other): bool
|
||||
{
|
||||
return
|
||||
$this->mask !== null
|
||||
&& $other->mask !== null
|
||||
&& ($this->mask & $other->mask) !== 0
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/MemorySegmentType.php";
|
||||
require_once __DIR__ . "/MemorySegmentSection.php";
|
||||
|
||||
class MemorySegment
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?MemorySegmentType $type = null;
|
||||
public ?int $startAddress = null;
|
||||
public ?int $size = null;
|
||||
public ?int $pageSize = null;
|
||||
public ?string $access = null;
|
||||
|
||||
/** @var MemorySegmentSection[] */
|
||||
public array $sections = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?MemorySegmentType $type,
|
||||
?int $startAddress,
|
||||
?int $size,
|
||||
?int $pageSize,
|
||||
?string $access,
|
||||
array $sections
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->startAddress = $startAddress;
|
||||
$this->size = $size;
|
||||
$this->pageSize = $pageSize;
|
||||
$this->access = $access;
|
||||
$this->sections = $sections;
|
||||
}
|
||||
|
||||
public function getSection(string $sectionId): ?MemorySegmentSection
|
||||
{
|
||||
foreach ($this->sections as $section) {
|
||||
if ($section->key !== $sectionId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $section;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function contains(MemorySegment $other): bool
|
||||
{
|
||||
$endAddress = !is_null($this->startAddress) && !is_null($this->size)
|
||||
? ($this->startAddress + $this->size - 1) : null;
|
||||
$otherEndAddress = !is_null($other->startAddress) && !is_null($other->size)
|
||||
? ($other->startAddress + $other->size - 1) : null;
|
||||
|
||||
return
|
||||
$this->startAddress !== null
|
||||
&& $endAddress !== null
|
||||
&& $other->startAddress !== null
|
||||
&& $otherEndAddress !== null
|
||||
&& $this->startAddress <= $other->startAddress
|
||||
&& $endAddress >= $otherEndAddress
|
||||
;
|
||||
}
|
||||
|
||||
public function intersectsWith(MemorySegment $other): bool
|
||||
{
|
||||
$endAddress = !is_null($this->startAddress) && !is_null($this->size)
|
||||
? ($this->startAddress + $this->size - 1) : null;
|
||||
$otherEndAddress = !is_null($other->startAddress) && !is_null($other->size)
|
||||
? ($other->startAddress + $other->size - 1) : null;
|
||||
|
||||
return
|
||||
$this->startAddress !== null
|
||||
&& $endAddress !== null
|
||||
&& $other->startAddress !== null
|
||||
&& $otherEndAddress !== null
|
||||
&& (
|
||||
($other->startAddress <= $this->startAddress && $otherEndAddress >= $this->startAddress)
|
||||
|| ($other->startAddress >= $this->startAddress && $other->startAddress <= $endAddress)
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
public function totalSectionSize(): int
|
||||
{
|
||||
return array_sum(
|
||||
array_map(
|
||||
fn (MemorySegmentSection $section): int => (int) $section->size,
|
||||
$this->sections
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class MemorySegmentSection
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?int $startAddress = null;
|
||||
public ?int $size = null;
|
||||
|
||||
/** @var MemorySegmentSection[] */
|
||||
public array $subSections = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?int $startAddress,
|
||||
?int $size,
|
||||
array $subSections
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->startAddress = $startAddress;
|
||||
$this->size = $size;
|
||||
$this->subSections = $subSections;
|
||||
}
|
||||
|
||||
public function contains(MemorySegment $other): bool
|
||||
{
|
||||
$endAddress = !is_null($this->startAddress) && !is_null($this->size)
|
||||
? ($this->startAddress + $this->size - 1) : null;
|
||||
$otherEndAddress = !is_null($other->startAddress) && !is_null($other->size)
|
||||
? ($other->startAddress + $other->size - 1) : null;
|
||||
|
||||
return
|
||||
$this->startAddress !== null
|
||||
&& $endAddress !== null
|
||||
&& $other->startAddress !== null
|
||||
&& $otherEndAddress !== null
|
||||
&& $this->startAddress <= $other->startAddress
|
||||
&& $endAddress >= $otherEndAddress
|
||||
;
|
||||
}
|
||||
|
||||
public function intersectsWith(MemorySegmentSection $other): bool
|
||||
{
|
||||
$endAddress = !is_null($this->startAddress) && !is_null($this->size)
|
||||
? ($this->startAddress + $this->size - 1) : null;
|
||||
$otherEndAddress = !is_null($other->startAddress) && !is_null($other->size)
|
||||
? ($other->startAddress + $other->size - 1) : null;
|
||||
|
||||
return
|
||||
$this->startAddress !== null
|
||||
&& $endAddress !== null
|
||||
&& $other->startAddress !== null
|
||||
&& $otherEndAddress !== null
|
||||
&& (
|
||||
($other->startAddress <= $this->startAddress && $otherEndAddress >= $this->startAddress)
|
||||
|| ($other->startAddress >= $this->startAddress && $other->startAddress <= $endAddress)
|
||||
)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
enum MemorySegmentType: string
|
||||
{
|
||||
case ALIASED = 'aliased';
|
||||
case GENERAL_PURPOSE_REGISTERS = 'gp_registers';
|
||||
case EEPROM = 'eeprom';
|
||||
case FLASH = 'flash';
|
||||
case FUSES = 'fuses';
|
||||
case IO = 'io';
|
||||
case RAM = 'ram';
|
||||
case LOCKBITS = 'lockbits';
|
||||
case OSCCAL = 'osccal';
|
||||
case PRODUCTION_SIGNATURES = 'production_signatures';
|
||||
case SIGNATURES = 'signatures';
|
||||
case USER_SIGNATURES = 'user_signatures';
|
||||
}
|
||||
42
build/scripts/Targets/TargetDescriptionFiles/Module.php
Normal file
42
build/scripts/Targets/TargetDescriptionFiles/Module.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/RegisterGroup.php";
|
||||
|
||||
class Module
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?string $description = null;
|
||||
|
||||
/** @var RegisterGroup[] */
|
||||
public array $registerGroups = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?string $description,
|
||||
array $registerGroups,
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->registerGroups = $registerGroups;
|
||||
}
|
||||
|
||||
public function getRegisterGroup(array|string $keys): ?RegisterGroup
|
||||
{
|
||||
if (is_string($keys)) {
|
||||
$keys = explode('.', $keys);
|
||||
}
|
||||
|
||||
$firstLevelSubGroupId = array_shift($keys);
|
||||
foreach ($this->registerGroups as $registerGroup) {
|
||||
if ($registerGroup->key === $firstLevelSubGroupId) {
|
||||
return !empty($keys) ? $registerGroup->getSubGroup($keys) : $registerGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
45
build/scripts/Targets/TargetDescriptionFiles/Peripheral.php
Normal file
45
build/scripts/Targets/TargetDescriptionFiles/Peripheral.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/RegisterGroup.php";
|
||||
require_once __DIR__ . "/RegisterGroupReference.php";
|
||||
require_once __DIR__ . "/Signal.php";
|
||||
|
||||
class Peripheral
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?string $moduleKey = null;
|
||||
public ?string $moduleName = null;
|
||||
|
||||
/** @var RegisterGroupReference[] */
|
||||
public array $registerGroupReferences = [];
|
||||
|
||||
/** @var Signal[] */
|
||||
public array $signals = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?string $moduleKey,
|
||||
array $registerGroupReferences,
|
||||
array $signals
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->moduleKey = $moduleKey;
|
||||
$this->registerGroupReferences = $registerGroupReferences;
|
||||
$this->signals = $signals;
|
||||
}
|
||||
|
||||
public function getRegisterGroupReference(string $key): ?RegisterGroupReference
|
||||
{
|
||||
foreach ($this->registerGroupReferences as $reference) {
|
||||
if ($reference->key === $key) {
|
||||
return $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class PhysicalInterface
|
||||
{
|
||||
public ?string $name = null;
|
||||
public ?string $type = null;
|
||||
|
||||
public function __construct(?string $name, ?string $type)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
14
build/scripts/Targets/TargetDescriptionFiles/Pin.php
Normal file
14
build/scripts/Targets/TargetDescriptionFiles/Pin.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class Pin
|
||||
{
|
||||
public ?string $position = null;
|
||||
public ?string $pad = null;
|
||||
|
||||
public function __construct(?string $position, ?string $pad)
|
||||
{
|
||||
$this->position = $position;
|
||||
$this->pad = $pad;
|
||||
}
|
||||
}
|
||||
30
build/scripts/Targets/TargetDescriptionFiles/Pinout.php
Normal file
30
build/scripts/Targets/TargetDescriptionFiles/Pinout.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/PinoutType.php";
|
||||
require_once __DIR__ . "/Pin.php";
|
||||
|
||||
class Pinout
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?PinoutType $type = null;
|
||||
public ?string $function = null;
|
||||
|
||||
/** @var Pin[] */
|
||||
public array $pins = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?PinoutType $type,
|
||||
?string $function,
|
||||
array $pins
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->function = $function;
|
||||
$this->pins = $pins;
|
||||
}
|
||||
}
|
||||
14
build/scripts/Targets/TargetDescriptionFiles/PinoutType.php
Normal file
14
build/scripts/Targets/TargetDescriptionFiles/PinoutType.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
enum PinoutType: string
|
||||
{
|
||||
case SOIC = 'soic';
|
||||
case SSOP = 'ssop';
|
||||
case DIP = 'dip';
|
||||
case QFN = 'qfn';
|
||||
case MLF = 'mlf';
|
||||
case DUAL_ROW_QFN = 'drqfn';
|
||||
case QFP = 'qfp';
|
||||
case BGA = 'bga';
|
||||
}
|
||||
14
build/scripts/Targets/TargetDescriptionFiles/Property.php
Normal file
14
build/scripts/Targets/TargetDescriptionFiles/Property.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class Property
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $value = null;
|
||||
|
||||
public function __construct(?string $key, ?string $value)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/Property.php";
|
||||
|
||||
class PropertyGroup
|
||||
{
|
||||
public ?string $key = null;
|
||||
|
||||
/** @var Property[] */
|
||||
public array $properties = [];
|
||||
|
||||
/** @var PropertyGroup[] */
|
||||
public array $subPropertyGroups = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
array $subPropertyGroups,
|
||||
array $properties,
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->subPropertyGroups = $subPropertyGroups;
|
||||
$this->properties = $properties;
|
||||
}
|
||||
|
||||
public function getSubGroup(array|string $subGroupKeys): ?PropertyGroup
|
||||
{
|
||||
if (is_string($subGroupKeys)) {
|
||||
$subGroupKeys = explode('.', $subGroupKeys);
|
||||
}
|
||||
|
||||
$firstLevelSubGroupKey = array_shift($subGroupKeys);
|
||||
foreach ($this->subPropertyGroups as $subGroup) {
|
||||
if ($subGroup->key === $firstLevelSubGroupKey) {
|
||||
return !empty($subGroupKeys) ? $subGroup->getSubGroup($subGroupKeys) : $subGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getProperty(string $propertyKey): ?Property
|
||||
{
|
||||
foreach ($this->properties as $property) {
|
||||
if ($property->key === $propertyKey) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPropertyValue(string $propertyKey): ?string
|
||||
{
|
||||
return ($property = $this->getProperty($propertyKey)) instanceof Property ? $property->value : null;
|
||||
}
|
||||
}
|
||||
63
build/scripts/Targets/TargetDescriptionFiles/Register.php
Normal file
63
build/scripts/Targets/TargetDescriptionFiles/Register.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/BitField.php";
|
||||
|
||||
class Register
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?string $description = null;
|
||||
public ?int $offset = null;
|
||||
public ?int $size = null;
|
||||
public ?int $initialValue = null;
|
||||
public ?string $access = null;
|
||||
public ?bool $alternative = null;
|
||||
|
||||
/** @var BitField[] */
|
||||
public array $bitFieldsByName = [];
|
||||
|
||||
/** @var BitField[] */
|
||||
public array $bitFields = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?string $description,
|
||||
?int $offset,
|
||||
?int $size,
|
||||
?int $initialValue,
|
||||
?string $access,
|
||||
?bool $alternative,
|
||||
array $bitFields
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->offset = $offset;
|
||||
$this->size = $size;
|
||||
$this->initialValue = $initialValue;
|
||||
$this->access = $access;
|
||||
$this->alternative = $alternative;
|
||||
$this->bitFields = $bitFields;
|
||||
}
|
||||
|
||||
public function intersectsWith(Register $other): bool
|
||||
{
|
||||
$endAddress = !is_null($this->offset) && !is_null($this->size)
|
||||
? ($this->offset + $this->size - 1) : null;
|
||||
$otherEndAddress = !is_null($other->offset) && !is_null($other->size)
|
||||
? ($other->offset + $other->size - 1) : null;
|
||||
|
||||
return
|
||||
$this->offset !== null
|
||||
&& $endAddress !== null
|
||||
&& $other->offset !== null
|
||||
&& $otherEndAddress !== null
|
||||
&& (
|
||||
($other->offset <= $this->offset && $otherEndAddress >= $this->offset)
|
||||
|| ($other->offset >= $this->offset && $other->offset <= $endAddress)
|
||||
)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/Register.php";
|
||||
require_once __DIR__ . "/RegisterGroupReference.php";
|
||||
|
||||
class RegisterGroup
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?int $offset = null;
|
||||
|
||||
/** @var Register[] */
|
||||
public array $registersMappedByName = [];
|
||||
|
||||
/** @var Register[] */
|
||||
public array $registers = [];
|
||||
|
||||
/** @var RegisterGroup[] */
|
||||
public array $subGroups = [];
|
||||
|
||||
/** @var RegisterGroupReference[] */
|
||||
public array $subGroupReferences = [];
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?int $offset,
|
||||
array $registers,
|
||||
array $subGroups,
|
||||
array $subGroupReferences
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->offset = $offset;
|
||||
$this->registers = $registers;
|
||||
$this->subGroups = $subGroups;
|
||||
$this->subGroupReferences = $subGroupReferences;
|
||||
}
|
||||
|
||||
public function getRegister(array|string $keys): ?Register
|
||||
{
|
||||
if (is_string($keys)) {
|
||||
$keys = explode('.', $keys);
|
||||
}
|
||||
|
||||
$registerKey = array_pop($keys);
|
||||
$group = !empty($keys) > 1 ? $this->getSubGroup($keys) : $this;
|
||||
|
||||
if ($group instanceof RegisterGroup) {
|
||||
foreach ($group->registers as $register) {
|
||||
if ($register->key === $registerKey) {
|
||||
return $register;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getSubGroup(array|string $subGroupKeys): ?RegisterGroup
|
||||
{
|
||||
if (is_string($subGroupKeys)) {
|
||||
$subGroupKeys = explode('.', $subGroupKeys);
|
||||
}
|
||||
|
||||
$firstLevelSubGroupKey = array_shift($subGroupKeys);
|
||||
foreach ($this->subGroups as $subGroup) {
|
||||
if ($subGroup->key === $firstLevelSubGroupKey) {
|
||||
return !empty($subGroupKeys) ? $subGroup->getSubGroup($subGroupKeys) : $subGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
require_once __DIR__ . "/Register.php";
|
||||
|
||||
class RegisterGroupReference
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?string $registerGroupKey = null;
|
||||
public ?int $offset = null;
|
||||
public ?string $description = null;
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?string $registerGroupKey,
|
||||
?int $offset,
|
||||
?string $description
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->registerGroupKey = $registerGroupKey;
|
||||
$this->offset = $offset;
|
||||
$this->description = $description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles\Services;
|
||||
|
||||
class StringService
|
||||
{
|
||||
public function tryStringToInt(?string $value): ?int
|
||||
{
|
||||
if ($value === null || strlen($value) === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return stristr($value, '0x') !== false ? (int) hexdec($value) : (int) $value;
|
||||
}
|
||||
|
||||
public function tryIntToHex(?int $value, int $pad = 0): string
|
||||
{
|
||||
if ($value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '0x' . str_pad(strtoupper(dechex($value)), $pad, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
25
build/scripts/Targets/TargetDescriptionFiles/Signal.php
Normal file
25
build/scripts/Targets/TargetDescriptionFiles/Signal.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class Signal
|
||||
{
|
||||
public ?string $padId = null;
|
||||
public ?int $index = null;
|
||||
public ?string $function = null;
|
||||
public ?string $group = null;
|
||||
public ?string $field = null;
|
||||
|
||||
public function __construct(
|
||||
?string $padId,
|
||||
?int $index,
|
||||
?string $function,
|
||||
?string $group,
|
||||
?string $field
|
||||
) {
|
||||
$this->padId = $padId;
|
||||
$this->index = $index;
|
||||
$this->function = $function;
|
||||
$this->group = $group;
|
||||
$this->field = $field;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
use Targets\TargetPeripheral;
|
||||
use Targets\TargetRegister;
|
||||
use Targets\TargetRegisterBitField;
|
||||
use Targets\TargetRegisterGroup;
|
||||
|
||||
require_once __DIR__ . "/PropertyGroup.php";
|
||||
require_once __DIR__ . "/AddressSpace.php";
|
||||
require_once __DIR__ . "/PhysicalInterface.php";
|
||||
require_once __DIR__ . "/Peripheral.php";
|
||||
require_once __DIR__ . "/Signal.php";
|
||||
require_once __DIR__ . "/Module.php";
|
||||
require_once __DIR__ . "/RegisterGroup.php";
|
||||
require_once __DIR__ . "/RegisterGroupReference.php";
|
||||
require_once __DIR__ . "/Register.php";
|
||||
require_once __DIR__ . "/Pinout.php";
|
||||
require_once __DIR__ . "/Variant.php";
|
||||
require_once __DIR__ . "/TargetFamily.php";
|
||||
|
||||
require_once __DIR__ . "/../TargetPeripheral.php";
|
||||
require_once __DIR__ . "/../TargetRegisterGroup.php";
|
||||
require_once __DIR__ . "/../TargetRegister.php";
|
||||
require_once __DIR__ . "/../TargetRegisterBitField.php";
|
||||
|
||||
class TargetDescriptionFile
|
||||
{
|
||||
/** @var string[] */
|
||||
public array $deviceAttributesByName = [];
|
||||
|
||||
/** @var PropertyGroup[] */
|
||||
public array $propertyGroups = [];
|
||||
|
||||
/** @var AddressSpace[] */
|
||||
public array $addressSpaces = [];
|
||||
|
||||
/** @var PhysicalInterface[] */
|
||||
public array $physicalInterfaces = [];
|
||||
|
||||
/** @var Peripheral[] */
|
||||
public array $peripherals = [];
|
||||
|
||||
/** @var Module[] */
|
||||
public array $modules = [];
|
||||
|
||||
/** @var Pinout[] */
|
||||
public array $pinouts = [];
|
||||
|
||||
/** @var Variant[] */
|
||||
public array $variants = [];
|
||||
|
||||
public function getAdditionalDeviceAttributes(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->deviceAttributesByName['name'] ?? null;
|
||||
}
|
||||
|
||||
public function getFamily(): ?TargetFamily
|
||||
{
|
||||
return TargetFamily::tryFrom($this->deviceAttributesByName['family'] ?? null);
|
||||
}
|
||||
|
||||
public function getConfigurationValue(): ?string
|
||||
{
|
||||
return $this->deviceAttributesByName['configuration-value'] ?? null;
|
||||
}
|
||||
|
||||
public function getArchitecture(): ?string
|
||||
{
|
||||
return $this->deviceAttributesByName['architecture'] ?? null;
|
||||
}
|
||||
|
||||
public function getVendor(): ?string
|
||||
{
|
||||
return $this->deviceAttributesByName['vendor'] ?? null;
|
||||
}
|
||||
|
||||
public function getPropertyGroup(array|string $keys): ?PropertyGroup
|
||||
{
|
||||
if (is_string($keys)) {
|
||||
$keys = explode('.', $keys);
|
||||
}
|
||||
|
||||
$firstLevelGroupKey = array_shift($keys);
|
||||
foreach ($this->propertyGroups as $propertyGroup) {
|
||||
if ($propertyGroup->key === $firstLevelGroupKey) {
|
||||
return !empty($keys) ? $propertyGroup->getSubGroup($keys) : $propertyGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getProperty(array|string $propertyGroupKeys, $propertyKey): ?Property
|
||||
{
|
||||
return ($propertyGroup = $this->getPropertyGroup($propertyGroupKeys)) instanceof PropertyGroup
|
||||
? $propertyGroup->getProperty($propertyKey)
|
||||
: null;
|
||||
}
|
||||
|
||||
public function getPropertyValue(array|string $propertyGroupKeys, $propertyKey): ?string
|
||||
{
|
||||
return ($property = $this->getProperty($propertyGroupKeys, $propertyKey)) instanceof Property
|
||||
? $property->value
|
||||
: null;
|
||||
}
|
||||
|
||||
public function getAddressSpace(string $key): ?AddressSpace
|
||||
{
|
||||
foreach ($this->addressSpaces as $addressSpace) {
|
||||
if ($addressSpace->key != $key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $addressSpace;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMemorySegment(string $addressSpaceKey, string $memorySegmentKey): ?MemorySegment
|
||||
{
|
||||
if (($addressSpace = $this->getAddressSpace($addressSpaceKey)) instanceof AddressSpace) {
|
||||
foreach ($addressSpace->memorySegments as $memorySegment) {
|
||||
if ($memorySegment->key !== $memorySegmentKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $memorySegment;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMemorySegmentsFromAnyAddressSpace(string $key): ?MemorySegment
|
||||
{
|
||||
foreach ($this->addressSpaces as $addressSpace) {
|
||||
foreach ($addressSpace->memorySegments as $memorySegment) {
|
||||
if ($memorySegment->key === $key) {
|
||||
return $memorySegment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPeripheral(string $key): ?Peripheral
|
||||
{
|
||||
foreach ($this->peripherals as $peripheral) {
|
||||
if ($peripheral->key === $key) {
|
||||
return $peripheral;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all peripherals of a particular module
|
||||
*
|
||||
* @param string $moduleKey
|
||||
* @return Peripheral[]
|
||||
*/
|
||||
public function getPeripheralsOfModule(string $moduleKey): array
|
||||
{
|
||||
return array_filter(
|
||||
$this->peripherals,
|
||||
fn (Peripheral $peripheral): bool => $peripheral->moduleKey === $moduleKey
|
||||
);
|
||||
}
|
||||
|
||||
public function removePeripheral(string $key): void
|
||||
{
|
||||
$this->peripherals = array_filter(
|
||||
$this->peripherals,
|
||||
fn (Peripheral $peripheral): bool => $peripheral->key !== $key
|
||||
);
|
||||
}
|
||||
|
||||
public function getModule(string $key): ?Module
|
||||
{
|
||||
foreach ($this->modules as $module) {
|
||||
if ($module->key === $key) {
|
||||
return $module;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will rename the key of the given module, and update all associated peripherals.
|
||||
*
|
||||
* @param Module $module
|
||||
* @param string $newKey
|
||||
* @return void
|
||||
*/
|
||||
public function renameModuleKey(Module $module, string $newKey): void
|
||||
{
|
||||
foreach ($this->getPeripheralsOfModule($module->key) as $peripheral) {
|
||||
$peripheral->moduleKey = $newKey;
|
||||
}
|
||||
|
||||
$module->key = $newKey;
|
||||
}
|
||||
|
||||
public function getPinout(string $key): ?Pinout
|
||||
{
|
||||
foreach ($this->pinouts as $pinout) {
|
||||
if ($pinout->key === $key) {
|
||||
return $pinout;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTargetPeripheral(string $peripheralKey): ?TargetPeripheral
|
||||
{
|
||||
$peripheral = $this->getPeripheral($peripheralKey);
|
||||
return $peripheral instanceof Peripheral ? $this->targetPeripheralFromPeripheral($peripheral) : null;
|
||||
}
|
||||
|
||||
public function getTargetRegisterGroup(string $peripheralKey, array|string $registerGroupKeys): ?TargetRegisterGroup
|
||||
{
|
||||
$peripheral = $this->getPeripheral($peripheralKey);
|
||||
return $peripheral instanceof Peripheral
|
||||
? $this->targetPeripheralFromPeripheral($peripheral)->getRegisterGroup($registerGroupKeys)
|
||||
: null;
|
||||
}
|
||||
|
||||
public function getTargetRegister(
|
||||
string $peripheralKey,
|
||||
array|string $groupKeys,
|
||||
array|string $registerKeys
|
||||
): ?TargetRegister {
|
||||
return ($peripheral = $this->getPeripheral($peripheralKey)) instanceof Peripheral
|
||||
? $this->targetPeripheralFromPeripheral($peripheral)->getRegister($groupKeys, $registerKeys)
|
||||
: null;
|
||||
}
|
||||
|
||||
public function resolveRegisterGroupReference(
|
||||
RegisterGroupReference $registerGroupReference,
|
||||
string $moduleKey
|
||||
): ?RegisterGroup {
|
||||
$module = $this->getModule($moduleKey);
|
||||
return $module instanceof Module ? $module->getRegisterGroup($registerGroupReference->registerGroupKey) : null;
|
||||
}
|
||||
|
||||
private function targetPeripheralFromPeripheral(Peripheral $peripheral): TargetPeripheral
|
||||
{
|
||||
$output = new TargetPeripheral($peripheral->name, []);
|
||||
|
||||
foreach ($peripheral->registerGroupReferences as $registerGroupReference) {
|
||||
$registerGroup = $this->resolveRegisterGroupReference($registerGroupReference, $peripheral->moduleKey);
|
||||
if ($registerGroup instanceof RegisterGroup) {
|
||||
$output->registerGroups[] = $this->targetRegisterGroupFromRegisterGroup(
|
||||
$registerGroup,
|
||||
$registerGroupReference->offset ?? 0,
|
||||
$peripheral->moduleKey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function targetRegisterGroupFromRegisterGroup(
|
||||
RegisterGroup $registerGroup,
|
||||
int $addressOffset,
|
||||
string $moduleKey
|
||||
): TargetRegisterGroup {
|
||||
$addressOffset += $registerGroup->offset ?? 0;
|
||||
$output = new TargetRegisterGroup($registerGroup->key, $registerGroup->name, $addressOffset, [], []);
|
||||
|
||||
foreach ($registerGroup->subGroups as $subGroup) {
|
||||
$output->subGroups[] = $this->targetRegisterGroupFromRegisterGroup($subGroup, $addressOffset, $moduleKey);
|
||||
}
|
||||
|
||||
foreach ($registerGroup->subGroupReferences as $subGroupReference) {
|
||||
$subGroup = $this->resolveRegisterGroupReference($subGroupReference, $moduleKey);
|
||||
|
||||
if ($subGroup instanceof RegisterGroup) {
|
||||
$output->subGroups[] = $this->targetRegisterGroupFromRegisterGroup(
|
||||
$subGroup,
|
||||
$addressOffset,
|
||||
$moduleKey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($registerGroup->registers as $register) {
|
||||
$output->registers[] = $this->targetRegisterFromRegister($register, $addressOffset);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function targetRegisterFromRegister(Register $register, int $addressOffset): TargetRegister
|
||||
{
|
||||
return new TargetRegister(
|
||||
$register->key,
|
||||
$register->name,
|
||||
$addressOffset + $register->offset,
|
||||
$register->size,
|
||||
$register->description,
|
||||
array_map(
|
||||
fn (BitField $bitField): TargetRegisterBitField => $this->targetRegisterBitFieldFromBitField($bitField),
|
||||
$register->bitFields
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function targetRegisterBitFieldFromBitField(BitField $bitField): TargetRegisterBitField
|
||||
{
|
||||
return new TargetRegisterBitField(
|
||||
$bitField->key,
|
||||
$bitField->name,
|
||||
$bitField->description,
|
||||
$bitField->mask,
|
||||
$bitField->access
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
enum TargetFamily: string
|
||||
{
|
||||
case AVR_8 = 'AVR8';
|
||||
case RISC_V = 'RISCV';
|
||||
}
|
||||
16
build/scripts/Targets/TargetDescriptionFiles/Variant.php
Normal file
16
build/scripts/Targets/TargetDescriptionFiles/Variant.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace Targets\TargetDescriptionFiles;
|
||||
|
||||
class Variant
|
||||
{
|
||||
public ?string $name = null;
|
||||
public ?string $pinoutKey = null;
|
||||
public ?string $package = null;
|
||||
|
||||
public function __construct(?string $name, ?string $pinoutKey, ?string $package)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->pinoutKey = $pinoutKey;
|
||||
$this->package = $package;
|
||||
}
|
||||
}
|
||||
56
build/scripts/Targets/TargetPeripheral.php
Normal file
56
build/scripts/Targets/TargetPeripheral.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace Targets;
|
||||
|
||||
use Targets\TargetDescriptionFiles\TargetDescriptionFile;
|
||||
|
||||
require_once __DIR__ . "/TargetRegisterGroup.php";
|
||||
|
||||
/**
|
||||
* Do not confuse this with `TargetDescriptionFiles\Peripheral` - that class represents a <peripheral> element in a
|
||||
* TDF, meaning it only contains references to register groups and their respective offsets. Those register group
|
||||
* references are unresolved, meaning you can't access any of the referenced group's registers or subgroups.
|
||||
*
|
||||
* This class represents a **resolved** target peripheral - meaning all the referenced register groups are resolved,
|
||||
* along with their respective addresses. With this class, we can access all peripheral registers/register groups, and
|
||||
* their absolute addresses.
|
||||
*
|
||||
* This class is constructed from a `TargetDescriptionFiles\Peripheral` object.
|
||||
* @see TargetDescriptionFile::getTargetPeripheral() for more.
|
||||
*/
|
||||
class TargetPeripheral
|
||||
{
|
||||
public ?string $name = null;
|
||||
|
||||
/** @var TargetRegisterGroup[] */
|
||||
public array $registerGroups = [];
|
||||
|
||||
public function __construct(?string $name, array $registerGroups)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->registerGroups = $registerGroups;
|
||||
}
|
||||
|
||||
public function getRegisterGroup(array|string $keys): ?TargetRegisterGroup
|
||||
{
|
||||
if (is_string($keys)) {
|
||||
$keys = explode('.', $keys);
|
||||
}
|
||||
|
||||
$firstLevelSubGroupId = array_shift($keys);
|
||||
|
||||
foreach ($this->registerGroups as $registerGroup) {
|
||||
if ($registerGroup->key === $firstLevelSubGroupId) {
|
||||
return !empty($keys) ? $registerGroup->getSubGroup($keys) : $registerGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRegister(array|string $groupKeys, array|string $keys): ?TargetRegister
|
||||
{
|
||||
return ($group = $this->getRegisterGroup($groupKeys)) instanceof TargetRegisterGroup
|
||||
? ($register = $group->getRegister($keys)) instanceof TargetRegister ? $register : null
|
||||
: null;
|
||||
}
|
||||
}
|
||||
44
build/scripts/Targets/TargetRegister.php
Normal file
44
build/scripts/Targets/TargetRegister.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace Targets;
|
||||
|
||||
use Targets\TargetDescriptionFiles\TargetDescriptionFile;
|
||||
|
||||
require_once __DIR__ . "/TargetRegisterBitField.php";
|
||||
|
||||
/**
|
||||
* Do not confuse this with `TargetDescriptionFiles\Register` - that class represents a <register> element in a TDF,
|
||||
* which is part of some unresolved register group.
|
||||
*
|
||||
* This class represents a **resolved** target register, within a register group, within a target peripheral. With
|
||||
* this class, we can access the absolute address of the register.
|
||||
*
|
||||
* This class is constructed from a `TargetDescriptionFiles\Register` object.
|
||||
* @see TargetDescriptionFile::getTargetRegister() for more.
|
||||
*/
|
||||
class TargetRegister
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?int $address = null;
|
||||
public ?int $size = null;
|
||||
public ?string $description = null;
|
||||
|
||||
/** @var TargetRegisterBitField[] */
|
||||
public array $bitFields;
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?int $address,
|
||||
?int $size,
|
||||
?string $description,
|
||||
array $bitFields
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->address = $address;
|
||||
$this->size = $size;
|
||||
$this->description = $description;
|
||||
$this->bitFields = $bitFields;
|
||||
}
|
||||
}
|
||||
25
build/scripts/Targets/TargetRegisterBitField.php
Normal file
25
build/scripts/Targets/TargetRegisterBitField.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace Targets;
|
||||
|
||||
class TargetRegisterBitField
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?string $description = null;
|
||||
public ?int $mask = null;
|
||||
public ?string $access = null;
|
||||
|
||||
public function __construct(
|
||||
?string $key,
|
||||
?string $name,
|
||||
?string $description,
|
||||
?int $mask,
|
||||
?string $access
|
||||
) {
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->mask = $mask;
|
||||
$this->access = $access;
|
||||
}
|
||||
}
|
||||
75
build/scripts/Targets/TargetRegisterGroup.php
Normal file
75
build/scripts/Targets/TargetRegisterGroup.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Targets;
|
||||
|
||||
use Targets\TargetDescriptionFiles\TargetDescriptionFile;
|
||||
|
||||
require_once __DIR__ . "/TargetRegister.php";
|
||||
|
||||
/**
|
||||
* Do not confuse this with `TargetDescriptionFiles\RegisterGroup` - that class represents a <register-group> element
|
||||
* in a TDF. Any references to subgroups will be unresolved.
|
||||
*
|
||||
* This class represents a **resolved** target register group, within a target peripheral. With this class, we can
|
||||
* access all subgroups, including referenced subgroups, along with their registers.
|
||||
*
|
||||
* This class is constructed from a `TargetDescriptionFiles\RegisterGroup` object.
|
||||
* @see TargetDescriptionFile::getTargetRegisterGroup() for more.
|
||||
*/
|
||||
class TargetRegisterGroup
|
||||
{
|
||||
public ?string $key = null;
|
||||
public ?string $name = null;
|
||||
public ?int $baseAddress = null;
|
||||
|
||||
/** @var TargetRegisterGroup[] */
|
||||
public array $subGroups = [];
|
||||
|
||||
/** @var TargetRegister[] */
|
||||
public array $registers = [];
|
||||
|
||||
public function __construct(?string $key, ?string $name, ?int $baseAddress, array $subGroups, array $registers)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->name = $name;
|
||||
$this->baseAddress = $baseAddress;
|
||||
$this->subGroups = $subGroups;
|
||||
$this->registers = $registers;
|
||||
}
|
||||
|
||||
public function getRegister(array|string $keys): ?TargetRegister
|
||||
{
|
||||
if (is_string($keys)) {
|
||||
$keys = explode('.', $keys);
|
||||
}
|
||||
|
||||
$registerKey = array_pop($keys);
|
||||
$group = !empty($keys) > 1 ? $this->getSubGroup($keys) : $this;
|
||||
|
||||
if ($group instanceof TargetRegisterGroup) {
|
||||
foreach ($group->registers as $register) {
|
||||
if ($register->key === $registerKey) {
|
||||
return $register;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getSubGroup(array|string $subGroupKeys): ?TargetRegisterGroup
|
||||
{
|
||||
if (is_string($subGroupKeys)) {
|
||||
$subGroupKeys = explode('.', $subGroupKeys);
|
||||
}
|
||||
|
||||
$firstLevelSubGroupKey = array_shift($subGroupKeys);
|
||||
foreach ($this->subGroups as $subGroup) {
|
||||
if ($subGroup->key === $firstLevelSubGroupKey) {
|
||||
return !empty($subGroupKeys) ? $subGroup->getSubGroup($subGroupKeys) : $subGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user