@@ -282,6 +282,165 @@ def is_reserved(self):
282282 return 'reserved' in self .name .lower ()
283283
284284
285+ class SVDRegisterCluster (SVDElement ):
286+ """Represent a register cluster in the tree"""
287+
288+ def __init__ (self , name , derived_from , description , address_offset , size ,
289+ alternate_cluster , header_struct_name ,
290+ access , protection , reset_value , reset_mask , register ,
291+ cluster ):
292+ SVDElement .__init__ (self )
293+
294+ # When deriving a register, it is mandatory to specify at least the name, the description,
295+ # and the addressOffset
296+ self .derived_from = derived_from
297+ self .name = name
298+ self .description = description
299+ self .address_offset = address_offset
300+
301+ self ._alternate_cluster = alternate_cluster
302+ self ._header_struct_name = header_struct_name
303+ self ._size = size
304+ self ._access = access
305+ self ._protection = protection
306+ self ._reset_value = reset_value
307+ self ._reset_mask = reset_mask
308+ self ._register = register
309+ self ._cluster = cluster
310+
311+ # make parent association
312+ for cluster in self ._cluster :
313+ cluster .parent = self
314+
315+ def __getattr__ (self , attr ):
316+ return self ._lookup_possibly_derived_attribute (attr )
317+
318+ def updated_register (self , reg , clu ):
319+ new_reg = SVDRegister (
320+ name = "{}_{}" .format (clu .name , reg .name ),
321+ fields = reg .fields ,
322+ derived_from = reg .derived_from ,
323+ description = reg .description ,
324+ address_offset = clu .address_offset + reg .address_offset ,
325+ size = reg .size ,
326+ access = reg .access ,
327+ protection = reg .protection ,
328+ reset_value = reg .reset_value ,
329+ reset_mask = reg .reset_mask ,
330+ display_name = reg .display_name ,
331+ alternate_group = reg .alternate_group ,
332+ modified_write_values = reg .modified_write_values ,
333+ read_action = reg .read_action ,
334+ )
335+ new_reg .parent = self
336+ return new_reg
337+
338+ @property
339+ def registers (self ):
340+ for reg in self ._register :
341+ yield self .updated_register (reg , self )
342+ for cluster in self ._cluster :
343+ for reg in cluster .registers :
344+ yield self .updated_register (reg , self )
345+
346+ def get_derived_from (self ):
347+ # TODO: add support for dot notation derivedFrom
348+ if self .derived_from is None :
349+ return None
350+
351+ for register in self .parent .registers :
352+ if register .name == self .derived_from :
353+ return register
354+
355+ raise KeyError ("Unable to find derived_from: %r" % self .derived_from )
356+
357+ def is_reserved (self ):
358+ return 'reserved' in self .name .lower ()
359+
360+
361+ class SVDRegisterClusterArray (SVDElement ):
362+ """Represent a register cluster in the tree"""
363+
364+ def __init__ (self , name , derived_from , description , address_offset , size ,
365+ alternate_cluster , header_struct_name ,
366+ dim , dim_indices , dim_increment ,
367+ access , protection , reset_value , reset_mask , register ,
368+ cluster ):
369+ SVDElement .__init__ (self )
370+
371+ # When deriving a register, it is mandatory to specify at least the name, the description,
372+ # and the addressOffset
373+ self .derived_from = derived_from
374+ self .name = name
375+ self .description = description
376+ self .address_offset = address_offset
377+ self .dim = dim
378+ self .dim_indices = dim_indices
379+ self .dim_increment = dim_increment
380+
381+ self ._alternate_cluster = alternate_cluster
382+ self ._header_struct_name = header_struct_name
383+ self ._size = size
384+ self ._access = access
385+ self ._protection = protection
386+ self ._reset_value = reset_value
387+ self ._reset_mask = reset_mask
388+ self ._register = register
389+ self ._cluster = cluster
390+
391+ # make parent association
392+ for register in self ._register :
393+ register .parent = self
394+ for cluster in self ._cluster :
395+ cluster .parent = self
396+
397+ def __getattr__ (self , attr ):
398+ return self ._lookup_possibly_derived_attribute (attr )
399+
400+ def updated_register (self , reg , clu , i ):
401+ new_reg = SVDRegister (
402+ name = "{}_{}" .format (clu .name % i , reg .name ),
403+ fields = reg .fields ,
404+ derived_from = reg .derived_from ,
405+ description = reg .description ,
406+ address_offset = clu .address_offset + reg .address_offset + i * clu .dim_increment ,
407+ size = reg .size ,
408+ access = reg .access ,
409+ protection = reg .protection ,
410+ reset_value = reg .reset_value ,
411+ reset_mask = reg .reset_mask ,
412+ display_name = reg .display_name ,
413+ alternate_group = reg .alternate_group ,
414+ modified_write_values = reg .modified_write_values ,
415+ read_action = reg .read_action ,
416+ )
417+ new_reg .parent = self
418+ return new_reg
419+
420+ @property
421+ def registers (self ):
422+ for i in six .moves .range (self .dim ):
423+ for reg in self ._register :
424+ yield self .updated_register (reg , self , i )
425+ for cluster in self ._cluster :
426+ for reg in cluster .registers :
427+ yield self .updated_register (reg , cluster , i )
428+
429+ def get_derived_from (self ):
430+ # TODO: add support for dot notation derivedFrom
431+ if self .derived_from is None :
432+ return None
433+
434+ for register in self .parent .registers :
435+ if register .name == self .derived_from :
436+ return register
437+
438+ raise KeyError ("Unable to find derived_from: %r" % self .derived_from )
439+
440+ def is_reserved (self ):
441+ return 'reserved' in self .name .lower ()
442+
443+
285444class SVDAddressBlock (SVDElement ):
286445 def __init__ (self , offset , size , usage ):
287446 SVDElement .__init__ (self )
@@ -298,9 +457,12 @@ def __init__(self, name, value):
298457
299458
300459class SVDPeripheral (SVDElement ):
301- def __init__ (self , name , version , derived_from , description , prepend_to_name , base_address , address_block ,
302- interrupts , registers , register_arrays , size , access , protection , reset_value , reset_mask ,
303- group_name , append_to_name , disable_condition ):
460+ def __init__ (self , name , version , derived_from , description ,
461+ prepend_to_name , base_address , address_block ,
462+ interrupts , registers , register_arrays , size , access ,
463+ protection , reset_value , reset_mask ,
464+ group_name , append_to_name , disable_condition ,
465+ clusters ):
304466 SVDElement .__init__ (self )
305467
306468 # items with underscore are potentially derived
@@ -322,6 +484,7 @@ def __init__(self, name, version, derived_from, description, prepend_to_name, ba
322484 self ._group_name = group_name
323485 self ._append_to_name = append_to_name
324486 self ._disable_condition = disable_condition
487+ self ._clusters = clusters
325488
326489 # make parent association for complex node types
327490 for i in _none_as_empty (self ._interrupts ):
@@ -339,6 +502,8 @@ def registers(self):
339502 regs .append (reg )
340503 for arr in self ._lookup_possibly_derived_attribute ('register_arrays' ):
341504 regs .extend (arr .registers )
505+ for cluster in self ._lookup_possibly_derived_attribute ('clusters' ):
506+ regs .extend (cluster .registers )
342507 return regs
343508
344509 def get_derived_from (self ):
0 commit comments