module Data.SVD.Types where
import Data.List
import qualified Data.Set as Set
data Device = Device {
deviceName :: String
, deviceVersion :: String
, deviceDescription :: String
, deviceAddressUnitBits :: Int
, deviceWidth :: Int
, deviceSize :: Int
, deviceResetValue :: Int
, deviceResetMask :: Int
, devicePeripherals :: [Peripheral]
} deriving (Eq, Ord, Show)
data Peripheral = Peripheral {
periphName :: String
, periphDescription :: String
, periphDerivedFrom :: Maybe String
, periphGroupName :: String
, periphBaseAddress :: Int
, periphAddressBlock :: Maybe AddressBlock
, periphInterrupts :: [Interrupt]
, periphRegisters :: [Register]
} deriving (Eq, Ord, Show)
data AddressBlock = AddressBlock {
addressBlockOffset :: Int
, addressBlockSize :: Int
, addressBlockUsage :: String
} deriving (Eq, Ord, Show)
data Interrupt = Interrupt {
interruptName :: String
, interruptDescription :: String
, interruptValue :: Int
} deriving (Eq, Ord, Show)
data Register = Register {
regName :: String
, regDisplayName :: String
, regDescription :: String
, regAddressOffset :: Int
, regSize :: Int
, regAccess :: AccessType
, regResetValue :: Int
, regFields :: [Field]
} deriving (Eq, Ord, Show)
data AccessType = ReadOnly | WriteOnly | ReadWrite | WriteOnce | ReadWriteOnce
deriving (Eq, Ord, Show)
data Field = Field {
fieldName :: String
, fieldDescription :: String
, fieldBitOffset :: Int
, fieldBitWidth :: Int
, fieldReserved :: Bool
} deriving (Eq, Ord, Show)
toAccessType "read-only" = ReadOnly
toAccessType "write-only" = WriteOnly
toAccessType "read-write" = ReadWrite
toAccessType "writeOnce" = WriteOnce
toAccessType "read-writeOnce" = ReadWriteOnce
toAccessType x = error $ "Unable to read AccessType" ++ x
procFields f = reverse $ sortByOffset (f ++ missingAsReserved)
where
missingAsReserved = reserved $ conts $ Set.toList missing
reserved = map (\(offset, width) -> Field "_" "Reserved" offset width True)
conts x = case cont x of
[] -> []
s -> [(head s, length s)] ++ conts (drop (length s) x)
missing = all `Set.difference` existing
all = Set.fromList [0..31]
existing = Set.fromList $ flip concatMap (sortByOffset f) $
\Field{..} -> [fieldBitOffset .. (fieldBitOffset + fieldBitWidth 1)]
sortByOffset = sortOn fieldBitOffset
cont (x:y:xs) | (x + 1 == y) = [x] ++ cont (y:xs)
cont (x:xs) = [x]
cont [] = []
mapPeriphs f Device{..} = map f devicePeripherals
mapRegs f Peripheral{..} = map f periphRegisters
mapFields f Register{..} = map f regFields
mapDevFields f d = concat $ concat $ flip mapPeriphs d $ mapRegs $ mapFields f