Implemented parsing for new register-group-instance element in TDF scripts
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
namespace Targets\TargetDescriptionFiles;
|
namespace Targets\TargetDescriptionFiles;
|
||||||
|
|
||||||
require_once __DIR__ . "/RegisterGroup.php";
|
require_once __DIR__ . "/RegisterGroup.php";
|
||||||
require_once __DIR__ . "/RegisterGroupReference.php";
|
require_once __DIR__ . "/RegisterGroupInstance.php";
|
||||||
require_once __DIR__ . "/Signal.php";
|
require_once __DIR__ . "/Signal.php";
|
||||||
|
|
||||||
class Peripheral
|
class Peripheral
|
||||||
@@ -12,8 +12,8 @@ class Peripheral
|
|||||||
public ?string $moduleKey = null;
|
public ?string $moduleKey = null;
|
||||||
public ?string $moduleName = null;
|
public ?string $moduleName = null;
|
||||||
|
|
||||||
/** @var RegisterGroupReference[] */
|
/** @var RegisterGroupInstance[] */
|
||||||
public array $registerGroupReferences = [];
|
public array $registerGroupInstances = [];
|
||||||
|
|
||||||
/** @var Signal[] */
|
/** @var Signal[] */
|
||||||
public array $signals = [];
|
public array $signals = [];
|
||||||
@@ -22,21 +22,21 @@ class Peripheral
|
|||||||
?string $key,
|
?string $key,
|
||||||
?string $name,
|
?string $name,
|
||||||
?string $moduleKey,
|
?string $moduleKey,
|
||||||
array $registerGroupReferences,
|
array $registerGroupInstances,
|
||||||
array $signals
|
array $signals
|
||||||
) {
|
) {
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->moduleKey = $moduleKey;
|
$this->moduleKey = $moduleKey;
|
||||||
$this->registerGroupReferences = $registerGroupReferences;
|
$this->registerGroupInstances = $registerGroupInstances;
|
||||||
$this->signals = $signals;
|
$this->signals = $signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRegisterGroupReference(string $key): ?RegisterGroupReference
|
public function getRegisterGroupInstance(string $key): ?RegisterGroupInstance
|
||||||
{
|
{
|
||||||
foreach ($this->registerGroupReferences as $reference) {
|
foreach ($this->registerGroupInstances as $instance) {
|
||||||
if ($reference->key === $key) {
|
if ($instance->key === $key) {
|
||||||
return $reference;
|
return $instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
namespace Targets\TargetDescriptionFiles;
|
||||||
|
|
||||||
|
require_once __DIR__ . "/Register.php";
|
||||||
|
|
||||||
|
class RegisterGroupInstance
|
||||||
|
{
|
||||||
|
public ?string $key = null;
|
||||||
|
public ?string $name = null;
|
||||||
|
public ?string $registerGroupKey = null;
|
||||||
|
public ?string $addressSpaceKey = null;
|
||||||
|
public ?int $offset = null;
|
||||||
|
public ?string $description = null;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
?string $key,
|
||||||
|
?string $name,
|
||||||
|
?string $registerGroupKey,
|
||||||
|
?string $addressSpaceKey,
|
||||||
|
?int $offset,
|
||||||
|
?string $description
|
||||||
|
) {
|
||||||
|
$this->key = $key;
|
||||||
|
$this->name = $name;
|
||||||
|
$this->registerGroupKey = $registerGroupKey;
|
||||||
|
$this->addressSpaceKey = $addressSpaceKey;
|
||||||
|
$this->offset = $offset;
|
||||||
|
$this->description = $description;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ use Targets\TargetDescriptionFiles\MemorySegment;
|
|||||||
use Targets\TargetDescriptionFiles\MemorySegmentSection;
|
use Targets\TargetDescriptionFiles\MemorySegmentSection;
|
||||||
use Targets\TargetDescriptionFiles\Module;
|
use Targets\TargetDescriptionFiles\Module;
|
||||||
use Targets\TargetDescriptionFiles\Peripheral;
|
use Targets\TargetDescriptionFiles\Peripheral;
|
||||||
|
use Targets\TargetDescriptionFiles\RegisterGroupInstance;
|
||||||
use Targets\TargetDescriptionFiles\Property;
|
use Targets\TargetDescriptionFiles\Property;
|
||||||
use Targets\TargetDescriptionFiles\PropertyGroup;
|
use Targets\TargetDescriptionFiles\PropertyGroup;
|
||||||
use Targets\TargetDescriptionFiles\Register;
|
use Targets\TargetDescriptionFiles\Register;
|
||||||
@@ -687,26 +688,26 @@ class ValidationService
|
|||||||
$failures[] = 'Missing module key';
|
$failures[] = 'Missing module key';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($peripheral->registerGroupReferences) && empty($peripheral->signals)) {
|
if (empty($peripheral->registerGroupInstances) && empty($peripheral->signals)) {
|
||||||
$failures[] = 'Empty - no register group references or signals';
|
$failures[] = 'Empty - no register group instances or signals';
|
||||||
}
|
}
|
||||||
|
|
||||||
$processedChildKeys = [];
|
$processedChildKeys = [];
|
||||||
foreach ($peripheral->registerGroupReferences as $registerGroupReference) {
|
foreach ($peripheral->registerGroupInstances as $registerGroupInstance) {
|
||||||
$failures = array_merge(
|
$failures = array_merge(
|
||||||
$failures,
|
$failures,
|
||||||
$this->validateRegisterGroupReference(
|
$this->validateRegisterGroupInstance(
|
||||||
$registerGroupReference,
|
$registerGroupInstance,
|
||||||
$peripheral->moduleKey ?? '',
|
$peripheral->moduleKey ?? '',
|
||||||
$tdf
|
$tdf
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($registerGroupReference->key !== null && in_array($registerGroupReference->key, $processedChildKeys)) {
|
if ($registerGroupInstance->key !== null && in_array($registerGroupInstance->key, $processedChildKeys)) {
|
||||||
$failures[] = 'Duplicate register group reference key ("' . $registerGroupReference->key . '") detected';
|
$failures[] = 'Duplicate register group instance key ("' . $registerGroupInstance->key . '") detected';
|
||||||
}
|
}
|
||||||
|
|
||||||
$processedChildKeys[] = $registerGroupReference->key;
|
$processedChildKeys[] = $registerGroupInstance->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($peripheral->signals as $signal) {
|
foreach ($peripheral->signals as $signal) {
|
||||||
@@ -719,6 +720,64 @@ class ValidationService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function validateRegisterGroupInstance(
|
||||||
|
RegisterGroupInstance $registerGroupInstance,
|
||||||
|
string $moduleKey,
|
||||||
|
TargetDescriptionFile $tdf
|
||||||
|
): array {
|
||||||
|
$failures = [];
|
||||||
|
|
||||||
|
if (empty($registerGroupInstance->key)) {
|
||||||
|
$failures[] = 'Missing key';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mb_check_encoding((string) $registerGroupInstance->key, 'ASCII')) {
|
||||||
|
$failures[] = 'Key contains non ASCII characters';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_contains((string) $registerGroupInstance->key, ' ')) {
|
||||||
|
$failures[] = 'Key contains at least one period space';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_contains((string) $registerGroupInstance->key, '.')) {
|
||||||
|
$failures[] = 'Key contains at least one period (".") character';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($registerGroupInstance->registerGroupKey)) {
|
||||||
|
$failures[] = 'Missing register group key';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($registerGroupInstance->name)) {
|
||||||
|
$failures[] = 'Missing name';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($registerGroupInstance->offset === null) {
|
||||||
|
$failures[] = 'Missing offset';
|
||||||
|
|
||||||
|
} elseif ($registerGroupInstance->offset > 0xFFFFFFFF) {
|
||||||
|
$failures[] = 'Offset exceeds 32-bit unsigned integer';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($registerGroupInstance->addressSpaceKey)) {
|
||||||
|
$failures[] = 'Missing address space key';
|
||||||
|
|
||||||
|
} elseif ($tdf->getAddressSpace($registerGroupInstance->addressSpaceKey) === null) {
|
||||||
|
$failures[] = 'Could not find address space "' . $registerGroupInstance->addressSpaceKey
|
||||||
|
. '" - check address space key';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tdf->resolveRegisterGroupInstance($registerGroupInstance, $moduleKey) === null) {
|
||||||
|
$failures[] = 'Could not resolve register group instance "' . $registerGroupInstance->key
|
||||||
|
. '" - check register group key ("' . $registerGroupInstance->registerGroupKey . '")';
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_map(
|
||||||
|
fn (string $failure): string => 'Register group instance (group key: "'
|
||||||
|
. $registerGroupInstance->registerGroupKey . '") validation failure: ' . $failure,
|
||||||
|
$failures
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected function validateSignal(Signal $signal): array
|
protected function validateSignal(Signal $signal): array
|
||||||
{
|
{
|
||||||
$failures = [];
|
$failures = [];
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use Targets\TargetDescriptionFiles\MemorySegmentSection;
|
|||||||
use Targets\TargetDescriptionFiles\MemorySegmentType;
|
use Targets\TargetDescriptionFiles\MemorySegmentType;
|
||||||
use Targets\TargetDescriptionFiles\Module;
|
use Targets\TargetDescriptionFiles\Module;
|
||||||
use Targets\TargetDescriptionFiles\Peripheral;
|
use Targets\TargetDescriptionFiles\Peripheral;
|
||||||
|
use Targets\TargetDescriptionFiles\RegisterGroupInstance;
|
||||||
use Targets\TargetDescriptionFiles\PhysicalInterface;
|
use Targets\TargetDescriptionFiles\PhysicalInterface;
|
||||||
use Targets\TargetDescriptionFiles\Property;
|
use Targets\TargetDescriptionFiles\Property;
|
||||||
use Targets\TargetDescriptionFiles\PropertyGroup;
|
use Targets\TargetDescriptionFiles\PropertyGroup;
|
||||||
@@ -325,8 +326,8 @@ class FromXmlService
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($childNode->nodeName === 'register-group-reference') {
|
if ($childNode->nodeName === 'register-group-instance') {
|
||||||
$output->registerGroupReferences[] = $this->registerGroupReferenceFromElement($childNode);
|
$output->registerGroupInstances[] = $this->registerGroupInstanceFromElement($childNode);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +357,20 @@ class FromXmlService
|
|||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function registerGroupInstanceFromElement(DOMElement $element): RegisterGroupInstance
|
||||||
|
{
|
||||||
|
$attributes = $this->getNodeAttributesByName($element);
|
||||||
|
|
||||||
|
return new RegisterGroupInstance(
|
||||||
|
$attributes['key'] ?? null,
|
||||||
|
$attributes['name'] ?? null,
|
||||||
|
$attributes['register-group-key'] ?? null,
|
||||||
|
$attributes['address-space-key'] ?? null,
|
||||||
|
$this->stringService->tryStringToInt($attributes['offset'] ?? null),
|
||||||
|
$attributes['description'] ?? null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function signalFromElement(DOMElement $element): Signal
|
public function signalFromElement(DOMElement $element): Signal
|
||||||
{
|
{
|
||||||
$attributes = $this->getNodeAttributesByName($element);
|
$attributes = $this->getNodeAttributesByName($element);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use Targets\TargetDescriptionFiles\MemorySegment;
|
|||||||
use Targets\TargetDescriptionFiles\MemorySegmentSection;
|
use Targets\TargetDescriptionFiles\MemorySegmentSection;
|
||||||
use Targets\TargetDescriptionFiles\Module;
|
use Targets\TargetDescriptionFiles\Module;
|
||||||
use Targets\TargetDescriptionFiles\Peripheral;
|
use Targets\TargetDescriptionFiles\Peripheral;
|
||||||
|
use Targets\TargetDescriptionFiles\RegisterGroupInstance;
|
||||||
use Targets\TargetDescriptionFiles\PhysicalInterface;
|
use Targets\TargetDescriptionFiles\PhysicalInterface;
|
||||||
use Targets\TargetDescriptionFiles\Pin;
|
use Targets\TargetDescriptionFiles\Pin;
|
||||||
use Targets\TargetDescriptionFiles\Pinout;
|
use Targets\TargetDescriptionFiles\Pinout;
|
||||||
@@ -135,8 +136,8 @@ class ToXmlService
|
|||||||
$element->setAttribute('name', $peripheral->name);
|
$element->setAttribute('name', $peripheral->name);
|
||||||
$element->setAttribute('module-key', $peripheral->moduleKey);
|
$element->setAttribute('module-key', $peripheral->moduleKey);
|
||||||
|
|
||||||
foreach ($peripheral->registerGroupReferences as $registerGroupReference) {
|
foreach ($peripheral->registerGroupInstances as $registerGroupInstance) {
|
||||||
$element->append($this->registerGroupReferenceToXml($registerGroupReference, $document));
|
$element->append($this->registerGroupInstanceToXml($registerGroupInstance, $document));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($peripheral->signals)) {
|
if (!empty($peripheral->signals)) {
|
||||||
@@ -151,6 +152,25 @@ class ToXmlService
|
|||||||
return $element;
|
return $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function registerGroupInstanceToXml(
|
||||||
|
RegisterGroupInstance $registerGroupInstance,
|
||||||
|
DOMDocument $document
|
||||||
|
): DOMElement {
|
||||||
|
$element = $document->createElement('register-group-instance');
|
||||||
|
$element->setAttribute('key', $registerGroupInstance->key);
|
||||||
|
$element->setAttribute('name', $registerGroupInstance->name);
|
||||||
|
|
||||||
|
if (!empty($registerGroupInstance->description)) {
|
||||||
|
$element->setAttribute('description', $registerGroupInstance->description);
|
||||||
|
}
|
||||||
|
|
||||||
|
$element->setAttribute('register-group-key', $registerGroupInstance->registerGroupKey);
|
||||||
|
$element->setAttribute('address-space-key', $registerGroupInstance->addressSpaceKey);
|
||||||
|
$element->setAttribute('offset', $this->stringService->tryIntToHex($registerGroupInstance->offset));
|
||||||
|
|
||||||
|
return $element;
|
||||||
|
}
|
||||||
|
|
||||||
public function signalToXml(Signal $signal, DOMDocument $document): DOMElement
|
public function signalToXml(Signal $signal, DOMDocument $document): DOMElement
|
||||||
{
|
{
|
||||||
$element = $document->createElement('signal');
|
$element = $document->createElement('signal');
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ require_once __DIR__ . "/PropertyGroup.php";
|
|||||||
require_once __DIR__ . "/AddressSpace.php";
|
require_once __DIR__ . "/AddressSpace.php";
|
||||||
require_once __DIR__ . "/PhysicalInterface.php";
|
require_once __DIR__ . "/PhysicalInterface.php";
|
||||||
require_once __DIR__ . "/Peripheral.php";
|
require_once __DIR__ . "/Peripheral.php";
|
||||||
|
require_once __DIR__ . "/RegisterGroupInstance.php";
|
||||||
require_once __DIR__ . "/Signal.php";
|
require_once __DIR__ . "/Signal.php";
|
||||||
require_once __DIR__ . "/Module.php";
|
require_once __DIR__ . "/Module.php";
|
||||||
require_once __DIR__ . "/RegisterGroup.php";
|
require_once __DIR__ . "/RegisterGroup.php";
|
||||||
@@ -246,6 +247,14 @@ class TargetDescriptionFile
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function resolveRegisterGroupInstance(
|
||||||
|
RegisterGroupInstance $registerGroupInstance,
|
||||||
|
string $moduleKey
|
||||||
|
): ?RegisterGroup {
|
||||||
|
$module = $this->getModule($moduleKey);
|
||||||
|
return $module instanceof Module ? $module->getRegisterGroup($registerGroupInstance->registerGroupKey) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public function resolveRegisterGroupReference(
|
public function resolveRegisterGroupReference(
|
||||||
RegisterGroupReference $registerGroupReference,
|
RegisterGroupReference $registerGroupReference,
|
||||||
string $moduleKey
|
string $moduleKey
|
||||||
@@ -258,12 +267,12 @@ class TargetDescriptionFile
|
|||||||
{
|
{
|
||||||
$output = new TargetPeripheral($peripheral->name, []);
|
$output = new TargetPeripheral($peripheral->name, []);
|
||||||
|
|
||||||
foreach ($peripheral->registerGroupReferences as $registerGroupReference) {
|
foreach ($peripheral->registerGroupInstances as $registerGroupInstance) {
|
||||||
$registerGroup = $this->resolveRegisterGroupReference($registerGroupReference, $peripheral->moduleKey);
|
$registerGroup = $this->resolveRegisterGroupInstance($registerGroupInstance, $peripheral->moduleKey);
|
||||||
if ($registerGroup instanceof RegisterGroup) {
|
if ($registerGroup instanceof RegisterGroup) {
|
||||||
$output->registerGroups[] = $this->targetRegisterGroupFromRegisterGroup(
|
$output->registerGroups[] = $this->targetRegisterGroupFromRegisterGroup(
|
||||||
$registerGroup,
|
$registerGroup,
|
||||||
$registerGroupReference->offset ?? 0,
|
$registerGroupInstance->offset ?? 0,
|
||||||
$peripheral->moduleKey
|
$peripheral->moduleKey
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user