@@ -87,59 +87,78 @@ pub fn render(
87
87
88
88
// erc: *E*ither *R*egister or *C*luster
89
89
let ercs = p. registers . as_ref ( ) . map ( |x| x. as_ref ( ) ) . unwrap_or ( & [ ] [ ..] ) ;
90
- let registers: & [ & Register ] = & util:: only_registers ( & ercs) [ ..] ;
91
90
92
- // make a pass to expand derived registers. Ideally, for the most minimal
91
+ // make a pass to expand derived registers and clusters . Ideally, for the most minimal
93
92
// code size, we'd do some analysis to figure out if we can 100% reuse the
94
93
// code that we're deriving from. For the sake of proving the concept, we're
95
94
// just going to emit a second copy of the accessor code. It'll probably
96
95
// get inlined by the compiler anyway, right? :-)
97
96
98
97
// Build a map so that we can look up registers within this peripheral
99
- let mut reg_map = HashMap :: new ( ) ;
100
- for r in registers {
101
- reg_map . insert ( & r . name , svd_parser :: svd :: register :: Register :: clone ( r ) ) ;
98
+ let mut erc_map = HashMap :: new ( ) ;
99
+ for erc in ercs {
100
+ erc_map . insert ( util :: erc_name ( erc ) , erc . clone ( ) ) ;
102
101
}
103
102
104
- // Build up an alternate erc list by expanding any derived registers
105
- let mut alt_erc : Vec < RegisterCluster > = registers
103
+ // Build up an alternate erc list by expanding any derived registers/clusters
104
+ let ercs : Vec < RegisterCluster > = ercs
106
105
. iter ( )
107
- . filter_map ( |r | match r . derived_from {
106
+ . filter_map ( |erc | match util :: erc_derived_from ( erc ) {
108
107
Some ( ref derived) => {
109
- let ancestor = match reg_map . get ( derived) {
110
- Some ( r ) => r ,
108
+ let ancestor = match erc_map . get ( derived) {
109
+ Some ( erc ) => erc ,
111
110
None => {
112
111
eprintln ! (
113
- "register {} derivedFrom missing register {}" ,
114
- r. name, derived
112
+ "register/cluster {} derivedFrom missing register/cluster {}" ,
113
+ util:: erc_name( erc) ,
114
+ derived
115
115
) ;
116
116
return None ;
117
117
}
118
118
} ;
119
119
120
- match * ancestor {
121
- Register :: Array ( ref info, ref array_info) => Some ( RegisterCluster :: Register (
122
- Register :: Array ( r. derive_from ( info) , array_info. clone ( ) ) ,
123
- ) ) ,
124
- Register :: Single ( ref info) => Some ( RegisterCluster :: Register (
125
- Register :: Single ( r. derive_from ( info) ) ,
126
- ) ) ,
120
+ match ( erc, ancestor) {
121
+ ( RegisterCluster :: Register ( reg) , RegisterCluster :: Register ( other_reg) ) => {
122
+ match other_reg {
123
+ Register :: Array ( ref info, ref array_info) => {
124
+ Some ( RegisterCluster :: Register ( Register :: Array (
125
+ reg. derive_from ( info) ,
126
+ array_info. clone ( ) ,
127
+ ) ) )
128
+ }
129
+ Register :: Single ( ref info) => Some ( RegisterCluster :: Register (
130
+ Register :: Single ( reg. derive_from ( info) ) ,
131
+ ) ) ,
132
+ }
133
+ }
134
+ (
135
+ RegisterCluster :: Cluster ( cluster) ,
136
+ RegisterCluster :: Cluster ( other_cluster) ,
137
+ ) => match other_cluster {
138
+ Cluster :: Array ( ref info, ref array_info) => Some ( RegisterCluster :: Cluster (
139
+ Cluster :: Array ( cluster. derive_from ( info) , array_info. clone ( ) ) ,
140
+ ) ) ,
141
+ Cluster :: Single ( ref info) => Some ( RegisterCluster :: Cluster (
142
+ Cluster :: Single ( cluster. derive_from ( info) ) ,
143
+ ) ) ,
144
+ } ,
145
+ _ => {
146
+ eprintln ! (
147
+ "{} can't derive from {}" ,
148
+ util:: erc_name( erc) ,
149
+ util:: erc_name( ancestor)
150
+ ) ;
151
+ None
152
+ }
127
153
}
128
154
}
129
- None => Some ( RegisterCluster :: Register ( ( * r ) . clone ( ) ) ) ,
155
+ None => Some ( erc . clone ( ) ) ,
130
156
} )
131
157
. collect ( ) ;
132
158
133
- // Now add the clusters to our alternate erc list
134
- let clusters = util:: only_clusters ( ercs) ;
135
- for cluster in & clusters {
136
- alt_erc. push ( RegisterCluster :: Cluster ( ( * cluster) . clone ( ) ) ) ;
137
- }
138
-
139
159
// And revise registers, clusters and ercs to refer to our expanded versions
140
- let registers: & [ & Register ] = & util:: only_registers ( & alt_erc) [ ..] ;
141
- let clusters = util:: only_clusters ( ercs) ;
142
- let ercs = & alt_erc;
160
+ let registers: & [ & Register ] = & util:: only_registers ( & ercs) [ ..] ;
161
+ let clusters = util:: only_clusters ( & ercs) ;
143
162
144
163
// No `struct RegisterBlock` can be generated
145
164
if registers. is_empty ( ) && clusters. is_empty ( ) {
@@ -151,7 +170,7 @@ pub fn render(
151
170
152
171
// Push any register or cluster blocks into the output
153
172
let mut mod_items = TokenStream :: new ( ) ;
154
- mod_items. extend ( register_or_cluster_block ( ercs, & defaults, None , nightly) ?) ;
173
+ mod_items. extend ( register_or_cluster_block ( & ercs, & defaults, None , nightly) ?) ;
155
174
156
175
// Push all cluster related information into the peripheral module
157
176
for c in & clusters {
0 commit comments