diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# Version [0.1.3.0](https://github.com/DistRap/data-svd/compare/0.1.2.0...0.1.3.0) (2026-07-28)
+
+* Handle missing register size tag, using device size as a fallback
+* Allow missing device resetValue, with zero default
+
 # Version [0.1.2.0](https://github.com/DistRap/data-svd/compare/0.1.1.0...0.1.2.0) (2024-02-09)
 
 * Added few more continuity check ignores due to aliased fields in stm32-rs
diff --git a/data-svd.cabal b/data-svd.cabal
--- a/data-svd.cabal
+++ b/data-svd.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                data-svd
-version:             0.1.2.0
+version:             0.1.3.0
 synopsis:            SVD (System view description) file handling
 description:         Parse, print, diff SVD files
 homepage:            https://github.com/DistRap/data-svd
diff --git a/src/Data/SVD/IO.hs b/src/Data/SVD/IO.hs
--- a/src/Data/SVD/IO.hs
+++ b/src/Data/SVD/IO.hs
@@ -12,10 +12,13 @@
 import Data.Hashable (Hashable)
 import Data.SVD.Types (Device)
 import GHC.Generics (Generic)
-import Text.XML.HXT.Core (readString, runX, (>>>))
+import Text.XML.HXT.Core (readString, (>>>))
+import Text.XML.HXT.Arrow.XmlState.RunIOStateArrow (runXIOState, initialState)
 
+import qualified Control.Monad
 import qualified Data.Bool
 import qualified Data.ByteString.Char8
+import qualified Data.Either
 import qualified Data.Hashable
 import qualified Data.Serialize
 import qualified Data.SVD.Dim
@@ -93,9 +96,11 @@
         Right x -> pure x
     else do
       res <- parseSVDFromString opts s
-      Data.ByteString.Char8.writeFile
-        caFile
-        $ Data.Serialize.encode res
+      Control.Monad.unless
+        (Data.Either.isLeft res)
+        $ Data.ByteString.Char8.writeFile
+            caFile
+            $ Data.Serialize.encode res
       pure res
 
 parseSVDFromString
@@ -103,7 +108,10 @@
   -> String
   -> IO (Either String Device)
 parseSVDFromString SVDOptions{..} s = do
-  res <- runX (readString [] s >>> Data.SVD.Parse.svd)
+  res <-
+    runXIOState
+      (initialState 0)
+      (readString [] s >>> Data.SVD.Parse.svd)
   case res of
     [] -> pure $ Left "No device parsed"
     [x] ->
diff --git a/src/Data/SVD/Parse.hs b/src/Data/SVD/Parse.hs
--- a/src/Data/SVD/Parse.hs
+++ b/src/Data/SVD/Parse.hs
@@ -17,6 +17,11 @@
 
 import qualified Safe
 
+-- Store deviceSize in user state
+-- so we can use it as a default
+-- if register size is not set
+type SVDArrow a b = IOStateArrow Int a b
+
 -- atTag doesn't uses deep here
 atTag :: ArrowXml cat => String -> cat (NTree XNode) XmlTree
 atTag tag = getChildren >>> hasName tag
@@ -41,7 +46,7 @@
   . filter ( not . (`elem` ['\n', '\t', '\r']))
 
 -- | SVD XML parser
-svd :: ArrowXml cat => cat (NTree XNode) Device
+svd :: SVDArrow (NTree XNode) Device
 svd = atTag "device" >>>
   proc x -> do
     --name <- text <<< hasName "name" <<< getChildren -< x
@@ -50,13 +55,13 @@
     desc <- textAtTag "description" -< x
     addressUnitBits' <- textAtTag "addressUnitBits" -< x
     width' <- textAtTag "width" -< x
-    size' <- textAtTag "size" -< x
-    resetValue' <- textAtTag "resetValue" -< x
+    deviceSize <- arr read <<< textAtTag "size" -< x
+    _ <- setUserState -< deviceSize
+    resetValue' <- withDefault (textAtTag "resetValue") "0" -< x
     resetMask' <- textAtTag "resetMask" -< x
 
     let deviceAddressUnitBits = read addressUnitBits'
         deviceWidth = read width'
-        deviceSize = read size'
         deviceResetValue = read resetValue'
         deviceResetMask = read resetMask'
         deviceDescription = filterCrap desc
@@ -65,7 +70,8 @@
 
     returnA -< Device{..}
 
-parsePeripheral :: ArrowXml cat => cat (NTree XNode) Peripheral
+parsePeripheral
+  :: SVDArrow (NTree XNode) Peripheral
 parsePeripheral = atTag "peripheral" >>>
   proc x -> do
     -- only these three avail for derived peripherals
@@ -117,8 +123,7 @@
     returnA -< Interrupt{..}
 
 parseCluster
-  :: ArrowXml cat
-  => cat (NTree XNode) Cluster
+  :: SVDArrow (NTree XNode) Cluster
 parseCluster = atTag "cluster" >>>
   proc x -> do
     clusterName <- textAtTag "name" -< x
@@ -152,8 +157,7 @@
     returnA -< Dimension{..}
 
 parseRegister
-  :: ArrowXml cat
-  => cat (NTree XNode) Register
+  :: SVDArrow (NTree XNode) Register
 parseRegister = atTag "register" >>>
   proc x -> do
     regName <- textAtTag "name" -< x
@@ -161,7 +165,9 @@
     desc <- textAtTagOrEmpty "description" -< x
 
     offset <- textAtTag "addressOffset" -< x
-    size <- textAtTag "size" -< x
+    mSize <- withDefault (arr Just <<< arr read <<< textAtTag "size") Nothing -< x
+    defSize <- getUserState -< ()
+
     access <- withDefault (textAtTag "access") "read-write" -< x
 
     regResetValue <- withDefault (arr (Just . read) <<< textAtTag "resetValue") Nothing -< x
@@ -170,9 +176,9 @@
     regDimension <- withDefault (arr Just  <<< parseDimension) Nothing -< x
 
     let regAddressOffset = read offset
-        regSize = read size
         regAccess = toAccessType access
         regDescription = filterCrap desc
+        regSize = Data.Maybe.fromMaybe defSize mSize
 
     returnA -< Register{..}
 
diff --git a/src/Data/SVD/Util.hs b/src/Data/SVD/Util.hs
--- a/src/Data/SVD/Util.hs
+++ b/src/Data/SVD/Util.hs
@@ -136,29 +136,32 @@
 -- Some ignores
 -- TIM2.CNT, TIM5.CNT is 32 bit but has an aliased UIFCPY field
 continuityCheckReg d p r
-  | d ^. name `elem` [ "STM32F730", "STM32F745", "STM32F750", "STM32F765"
-                     , "STM32F7x2", "STM32F7x3", "STM32F7x6", "STM32F7x7", "STM32F7x9" ]
+  | (   "STM32F7" `Data.List.isPrefixOf` (d ^. name)
+     || "STM32U5" `Data.List.isPrefixOf` (d ^. name)
+     || "STM32H7" `Data.List.isPrefixOf` (d ^. name)
+    )
   && p ^. name `elem` [ "TIM2", "TIM5" ]
   && r ^. name == "CNT" = pure r
 -- similar for Gs
 --
 continuityCheckReg d p r
-  | d ^. name `elem` [ "STM32G431xx", "STM32G441xx", "STM32G471xx", "STM32G473xx"
-                     , "STM32G474xx", "STM32G483xx", "STM32G484xx", "STM32G491xx", "STM32G4A1xx" ]
+  | "STM32G4" `Data.List.isPrefixOf` (d ^. name)
   && p ^. name == "TIM2" && r ^. name == "CNT" = pure r
 -- G4 TIM2.CCR5, might be a bug in stm32-rs
 continuityCheckReg d p r
-  | d ^. name `elem` [ "STM32G431xx", "STM32G441xx", "STM32G471xx", "STM32G473xx"
-                     , "STM32G474xx", "STM32G483xx", "STM32G484xx", "STM32G491xx", "STM32G4A1xx" ]
+  | "STM32G4" `Data.List.isPrefixOf` (d ^. name)
   && p ^. name == "TIM2" && r ^. name == "CCR5" = pure r
 -- F101, F103 TIM10.CCMR1_Output aliased OC1FE field
 continuityCheckReg d p r
   | d ^. name `elem` [ "STM32F101", "STM32F103" ]
   && p ^. name == "TIM10" && r ^. name == "CCMR1_Output" = pure r
 continuityCheckReg d p r
-  | d ^. name == "STM32H73x"
+  | "STM32H7" `Data.List.isPrefixOf` (d ^. name)
   && p ^. name == "CRYP" && r ^. name == "K2LR" = pure r
 continuityCheckReg d p r
+  | "STM32H7" `Data.List.isPrefixOf` (d ^. name)
+  && p ^. name == "ADC3" && r ^. name == "CFGR" = pure r
+continuityCheckReg d p r
   | (d ^. name == "STM32L0x2" || d ^. name == "STM32L0x3")
   && p ^.name == "PWR" && r ^. name == "CR" = pure r
 continuityCheckReg d p r
@@ -168,7 +171,7 @@
   | d ^. name == "STM32L4P5"
   && p ^.name == "SAI1" && r ^. name == "CR1" = pure r
 continuityCheckReg d p r
-  | d ^. name == "STM32L4P5"
+  | (d ^. name == "STM32L4P5" || d ^. name == "STM32L4R9")
   && p ^.name == "FLASH" && r ^. name == "ECCR" = pure r
 continuityCheckReg d p r
   | d ^. name == "STM32WB55"
