@@ -2,7 +2,8 @@ use crate::common::svd_reader;
2
2
use crate :: common:: { str_utils, svd_utils} ;
3
3
use anyhow:: { Context , Result } ;
4
4
use std:: { fs:: File , io:: Read , path:: Path } ;
5
- use svd_parser:: svd:: { Cluster , Field , Peripheral , Register , RegisterCluster , RegisterInfo } ;
5
+ use svd:: PeripheralInfo ;
6
+ use svd_parser:: svd:: { self , Cluster , Field , Peripheral , Register , RegisterCluster , RegisterInfo } ;
6
7
7
8
/// Output sorted text of every peripheral, register, field, and interrupt
8
9
/// in the device, such that automated diffing is possible.
@@ -29,18 +30,30 @@ fn to_text(peripherals: &[Peripheral]) -> String {
29
30
let mut mmap: Vec < String > = vec ! [ ] ;
30
31
31
32
for p in peripherals {
32
- get_peripheral ( p, & mut mmap) ;
33
- get_interrupts ( p, & mut mmap) ;
34
- let registers = get_periph_registers ( p, peripherals) ;
35
- get_registers ( p. base_address , registers. as_ref ( ) , "" , & mut mmap) ;
33
+ match p {
34
+ Peripheral :: Single ( p) => {
35
+ get_peripheral ( p, & mut mmap) ;
36
+ get_interrupts ( p, & mut mmap) ;
37
+ let registers = get_periph_registers ( p, peripherals) ;
38
+ get_registers ( p. base_address , registers. as_ref ( ) , "" , & mut mmap) ;
39
+ }
40
+ Peripheral :: Array ( p, d) => {
41
+ for pi in svd:: peripheral:: expand ( p, d) {
42
+ get_peripheral ( & pi, & mut mmap) ;
43
+ get_interrupts ( & pi, & mut mmap) ;
44
+ let registers = get_periph_registers ( & pi, peripherals) ;
45
+ get_registers ( pi. base_address , registers. as_ref ( ) , "" , & mut mmap) ;
46
+ }
47
+ }
48
+ }
36
49
}
37
50
38
51
mmap. sort ( ) ;
39
52
mmap. join ( "\n " )
40
53
}
41
54
42
55
fn get_periph_registers < ' a > (
43
- peripheral : & ' a Peripheral ,
56
+ peripheral : & ' a PeripheralInfo ,
44
57
peripheral_list : & ' a [ Peripheral ] ,
45
58
) -> & ' a Option < Vec < RegisterCluster > > {
46
59
match & peripheral. derived_from {
@@ -58,7 +71,7 @@ fn get_periph_registers<'a>(
58
71
}
59
72
}
60
73
61
- fn get_peripheral ( peripheral : & Peripheral , mmap : & mut Vec < String > ) {
74
+ fn get_peripheral ( peripheral : & PeripheralInfo , mmap : & mut Vec < String > ) {
62
75
let text = format ! (
63
76
"{} A PERIPHERAL {}" ,
64
77
str_utils:: format_address( peripheral. base_address) ,
@@ -67,7 +80,7 @@ fn get_peripheral(peripheral: &Peripheral, mmap: &mut Vec<String>) {
67
80
mmap. push ( text) ;
68
81
}
69
82
70
- fn get_interrupts ( peripheral : & Peripheral , mmap : & mut Vec < String > ) {
83
+ fn get_interrupts ( peripheral : & PeripheralInfo , mmap : & mut Vec < String > ) {
71
84
for i in & peripheral. interrupt {
72
85
let description = str_utils:: get_description ( & i. description ) ;
73
86
let text = format ! (
@@ -86,10 +99,6 @@ fn derived_str(dname: &Option<String>) -> String {
86
99
}
87
100
}
88
101
89
- fn replace_idx ( name : & str , idx : & str ) -> String {
90
- name. replace ( "[%s]" , idx) . replace ( "%s" , idx)
91
- }
92
-
93
102
fn get_registers (
94
103
base_address : u64 ,
95
104
registers : Option < & Vec < RegisterCluster > > ,
@@ -100,56 +109,54 @@ fn get_registers(
100
109
for r in registers {
101
110
match & r {
102
111
RegisterCluster :: Register ( r) => {
103
- let description = str_utils:: get_description ( & r. description ) ;
104
112
let access = svd_utils:: access_with_brace ( r. properties . access ) ;
105
- let first_addr = base_address + r . address_offset as u64 ;
113
+ let derived = derived_str ( & r . derived_from ) ;
106
114
match r {
107
115
Register :: Single ( r) => {
108
- let addr = str_utils:: format_address ( first_addr) ;
116
+ let addr =
117
+ str_utils:: format_address ( base_address + r. address_offset as u64 ) ;
109
118
let rname = r. name . to_string ( ) + suffix;
110
- let derived = derived_str ( & r. derived_from ) ;
119
+ let description = str_utils :: get_description ( & r. description ) ;
111
120
let text = format ! (
112
121
"{addr} B REGISTER {rname}{derived}{access}: {description}"
113
122
) ;
114
123
mmap. push ( text) ;
115
124
get_fields ( r, & addr, mmap) ;
116
125
}
117
126
Register :: Array ( r, d) => {
118
- let derived = derived_str ( & r. derived_from ) ;
119
- for ( i, idx) in d. indexes ( ) . enumerate ( ) {
127
+ for ri in svd:: register:: expand ( r, d) {
120
128
let addr = str_utils:: format_address (
121
- first_addr + ( i as u64 ) * ( d . dim_increment as u64 ) ,
129
+ base_address + ri . address_offset as u64 ,
122
130
) ;
123
- let rname = replace_idx ( & r . name , & idx ) ;
124
- let description = replace_idx ( & description, & idx ) ;
131
+ let rname = & ri . name ;
132
+ let description = str_utils :: get_description ( & ri . description ) ;
125
133
let text = format ! (
126
134
"{addr} B REGISTER {rname}{derived}{access}: {description}"
127
135
) ;
128
136
mmap. push ( text) ;
129
- get_fields ( r , & addr, mmap) ;
137
+ get_fields ( & ri , & addr, mmap) ;
130
138
}
131
139
}
132
140
}
133
141
}
134
142
RegisterCluster :: Cluster ( c) => {
135
- let description = str_utils:: get_description ( & c. description ) ;
136
- let first_addr = base_address + c. address_offset as u64 ;
143
+ let derived = derived_str ( & c. derived_from ) ;
137
144
match c {
138
145
Cluster :: Single ( c) => {
139
- let addr = str_utils:: format_address ( first_addr) ;
146
+ let caddr = base_address + c. address_offset as u64 ;
147
+ let addr = str_utils:: format_address ( caddr) ;
140
148
let cname = & c. name ;
141
- let derived = derived_str ( & c. derived_from ) ;
149
+ let description = str_utils :: get_description ( & c. description ) ;
142
150
let text = format ! ( "{addr} B CLUSTER {cname}{derived}: {description}" ) ;
143
151
mmap. push ( text) ;
144
- get_registers ( first_addr , Some ( & c. children ) , "" , mmap) ;
152
+ get_registers ( caddr , Some ( & c. children ) , "" , mmap) ;
145
153
}
146
154
Cluster :: Array ( c, d) => {
147
- let derived = derived_str ( & c. derived_from ) ;
148
- for ( i, idx) in d. indexes ( ) . enumerate ( ) {
149
- let caddr = first_addr + ( i as u64 ) * ( d. dim_increment as u64 ) ;
155
+ for ( ci, idx) in svd:: cluster:: expand ( c, d) . zip ( d. indexes ( ) ) {
156
+ let caddr = base_address + ci. address_offset as u64 ;
150
157
let addr = str_utils:: format_address ( caddr) ;
151
- let cname = replace_idx ( & c . name , & idx ) ;
152
- let description = replace_idx ( & description, & idx ) ;
158
+ let cname = & ci . name ;
159
+ let description = str_utils :: get_description ( & ci . description ) ;
153
160
let text =
154
161
format ! ( "{addr} B CLUSTER {cname}{derived}: {description}" ) ;
155
162
mmap. push ( text) ;
@@ -166,26 +173,25 @@ fn get_registers(
166
173
fn get_fields ( register : & RegisterInfo , addr : & str , mmap : & mut Vec < String > ) {
167
174
if let Some ( fields) = & register. fields {
168
175
for f in fields {
169
- let description = str_utils :: get_description ( & f. description ) ;
176
+ let derived = derived_str ( & f. derived_from ) ;
170
177
let access = svd_utils:: access_with_brace ( f. access ) ;
171
178
match f {
172
179
Field :: Single ( f) => {
173
- let bit_offset = f. bit_range . offset ;
174
- let bit_width = f. bit_range . width ;
180
+ let bit_offset = f. bit_offset ( ) ;
181
+ let bit_width = f. bit_width ( ) ;
175
182
let fname = & f. name ;
176
- let derived = derived_str ( & f. derived_from ) ;
183
+ let description = str_utils :: get_description ( & f. description ) ;
177
184
let text = format ! (
178
185
"{addr} C FIELD {bit_offset:02}w{bit_width:02} {fname}{derived}{access}: {description}"
179
186
) ;
180
187
mmap. push ( text) ;
181
188
}
182
189
Field :: Array ( f, d) => {
183
- let derived = derived_str ( & f. derived_from ) ;
184
- for ( i, idx) in d. indexes ( ) . enumerate ( ) {
185
- let bit_offset = f. bit_range . offset + ( i as u32 ) * d. dim_increment ;
186
- let bit_width = f. bit_range . width ;
187
- let fname = replace_idx ( & f. name , & idx) ;
188
- let description = replace_idx ( & description, & idx) ;
190
+ for fi in svd:: field:: expand ( f, d) {
191
+ let bit_offset = fi. bit_offset ( ) ;
192
+ let bit_width = fi. bit_width ( ) ;
193
+ let fname = & fi. name ;
194
+ let description = str_utils:: get_description ( & fi. description ) ;
189
195
let text = format ! (
190
196
"{addr} C FIELD {bit_offset:02}w{bit_width:02} {fname}{derived}{access}: {description}"
191
197
) ;
0 commit comments