|
1 |
| -use super::Protection; |
| 1 | +use super::{BuildError, Protection, SvdError, ValidateLevel}; |
2 | 2 |
|
3 | 3 | /// An uniquely mapped address block to a peripheral
|
4 | 4 | #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
5 | 5 | #[derive(Clone, Debug, PartialEq)]
|
| 6 | +#[non_exhaustive] |
6 | 7 | pub struct AddressBlock {
|
7 | 8 | /// Specifies the start address of an address block relative to the peripheral [`baseAddress`](crate::Peripheral::base_address).
|
8 | 9 | pub offset: u32,
|
@@ -60,3 +61,104 @@ impl AddressBlockUsage {
|
60 | 61 | }
|
61 | 62 | }
|
62 | 63 | }
|
| 64 | + |
| 65 | +/// Builder for [`AddressBlock`] |
| 66 | +#[derive(Clone, Debug, Default, PartialEq)] |
| 67 | +pub struct AddressBlockBuilder { |
| 68 | + offset: Option<u32>, |
| 69 | + size: Option<u32>, |
| 70 | + usage: Option<AddressBlockUsage>, |
| 71 | + protection: Option<Protection>, |
| 72 | +} |
| 73 | + |
| 74 | +impl From<AddressBlock> for AddressBlockBuilder { |
| 75 | + fn from(d: AddressBlock) -> Self { |
| 76 | + Self { |
| 77 | + offset: Some(d.offset), |
| 78 | + size: Some(d.size), |
| 79 | + usage: Some(d.usage), |
| 80 | + protection: d.protection, |
| 81 | + } |
| 82 | + } |
| 83 | +} |
| 84 | + |
| 85 | +impl AddressBlockBuilder { |
| 86 | + /// Set the offset of the block |
| 87 | + pub fn offset(mut self, value: u32) -> Self { |
| 88 | + self.offset = Some(value); |
| 89 | + self |
| 90 | + } |
| 91 | + /// Set the size of the block |
| 92 | + pub fn size(mut self, value: u32) -> Self { |
| 93 | + self.size = Some(value); |
| 94 | + self |
| 95 | + } |
| 96 | + /// Set the usage of the block |
| 97 | + pub fn usage(mut self, value: AddressBlockUsage) -> Self { |
| 98 | + self.usage = Some(value); |
| 99 | + self |
| 100 | + } |
| 101 | + /// Set the protection of the block |
| 102 | + pub fn protection(mut self, value: Option<Protection>) -> Self { |
| 103 | + self.protection = value; |
| 104 | + self |
| 105 | + } |
| 106 | + /// Validate and build a [`AddressBlock`]. |
| 107 | + pub fn build(self, lvl: ValidateLevel) -> Result<AddressBlock, SvdError> { |
| 108 | + let mut de = AddressBlock { |
| 109 | + offset: self |
| 110 | + .offset |
| 111 | + .ok_or_else(|| BuildError::Uninitialized("offset".to_string()))?, |
| 112 | + size: self |
| 113 | + .size |
| 114 | + .ok_or_else(|| BuildError::Uninitialized("size".to_string()))?, |
| 115 | + usage: self |
| 116 | + .usage |
| 117 | + .ok_or_else(|| BuildError::Uninitialized("usage".to_string()))?, |
| 118 | + protection: self.protection, |
| 119 | + }; |
| 120 | + if !lvl.is_disabled() { |
| 121 | + de.validate(lvl)?; |
| 122 | + } |
| 123 | + Ok(de) |
| 124 | + } |
| 125 | +} |
| 126 | + |
| 127 | +impl AddressBlock { |
| 128 | + /// Make a builder for [`AddressBlock`] |
| 129 | + pub fn builder() -> AddressBlockBuilder { |
| 130 | + AddressBlockBuilder::default() |
| 131 | + } |
| 132 | + /// Modify an existing [`AddressBlock`] based on a [builder](AddressBlockBuilder). |
| 133 | + pub fn modify_from( |
| 134 | + &mut self, |
| 135 | + builder: AddressBlockBuilder, |
| 136 | + lvl: ValidateLevel, |
| 137 | + ) -> Result<(), SvdError> { |
| 138 | + if let Some(offset) = builder.offset { |
| 139 | + self.offset = offset; |
| 140 | + } |
| 141 | + if let Some(size) = builder.size { |
| 142 | + self.size = size; |
| 143 | + } |
| 144 | + if let Some(usage) = builder.usage { |
| 145 | + self.usage = usage; |
| 146 | + } |
| 147 | + if builder.protection.is_some() { |
| 148 | + self.protection = builder.protection; |
| 149 | + } |
| 150 | + if !lvl.is_disabled() { |
| 151 | + self.validate(lvl) |
| 152 | + } else { |
| 153 | + Ok(()) |
| 154 | + } |
| 155 | + } |
| 156 | + /// Validate the [`AddressBlock`]. |
| 157 | + /// |
| 158 | + /// # Notes |
| 159 | + /// |
| 160 | + /// This doesn't do anything. |
| 161 | + pub fn validate(&mut self, _lvl: ValidateLevel) -> Result<(), SvdError> { |
| 162 | + Ok(()) |
| 163 | + } |
| 164 | +} |
0 commit comments