@@ -634,6 +634,10 @@ def process_peripheral(self, pspec, peripheral, update_fields=True):
634634 p .delete_interrupt (ispec )
635635 else :
636636 p .delete_register (rspec )
637+ # Handle copy
638+ for rname in peripheral .get ("_copy" , {}):
639+ rderive = peripheral ["_copy" ][rname ]
640+ p .copy_register (rname , rderive )
637641 # Handle modifications
638642 for rspec in peripheral .get ("_modify" , {}):
639643 rmod = peripheral ["_modify" ][rspec ]
@@ -667,14 +671,15 @@ def process_peripheral(self, pspec, peripheral, update_fields=True):
667671 p .add_interrupt (iname , radd [iname ])
668672 else :
669673 p .add_register (rname , radd )
674+ # Handle derive
670675 for rname in peripheral .get ("_derive" , {}):
671676 rderive = peripheral ["_derive" ][rname ]
672677 if rname == "_registers" :
673678 for rname in rderive :
674679 p .derive_register (rname , rderive [rname ])
675- elif rname == "_interrupts " :
680+ elif rname == "_clusters " :
676681 raise NotImplementedError (
677- "deriving interrupts not implemented yet: {}" .format (rname )
682+ "deriving clusters not implemented yet: {}" .format (rname )
678683 )
679684 else :
680685 p .derive_register (rname , rderive )
@@ -803,6 +808,29 @@ def add_register(self, rname, radd):
803808 rnew .tail = "\n "
804809
805810 def derive_register (self , rname , rderive ):
811+ """
812+ Remove fields from rname and mark it as derivedFrom rderive.
813+ Update all derivedFrom referencing rname.
814+ """
815+ parent = self .ptag .find ("registers" )
816+ rtag = parent .find ("./register[name='{}']" .format (rname ))
817+ derived = parent .find ("./register[name='{}']" .format (rderive ))
818+ if rtag is None :
819+ raise SvdPatchError ("register {} not found" .format (rname ))
820+ if derived is None :
821+ raise SvdPatchError ("register {} not found" .format (rderive ))
822+ for value in list (rtag ):
823+ if value .tag in ("name" , "addressOffset" ):
824+ continue
825+ rtag .remove (value )
826+ for value in rtag :
827+ last = value
828+ last .tail = "\n "
829+ rtag .set ("derivedFrom" , rderive )
830+ for p in parent .findall ("./register[@derivedFrom='{}']" .format (rname )):
831+ p .set ("derivedFrom" , rderive )
832+
833+ def copy_register (self , rname , rderive ):
806834 """Add rname given by deriving from rsource to ptag"""
807835 parent = self .ptag .find ("registers" )
808836 if not "_from" in rderive :
0 commit comments