{-# LINE 1 "src/System/Hardware/MercuryApi/Records.hsc" #-}
{-# LANGUAGE OverloadedStrings, FlexibleInstances, DeriveDataTypeable #-}
module System.Hardware.MercuryApi.Records where

import Control.Applicative ( Applicative((<*>)), (<$>) )
import Control.Exception ( Exception, throwIO )
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Maybe ( mapMaybe, fromMaybe )
import Data.Monoid ( (<>) )
import Data.Text (Text)
import qualified Data.Text as T ( pack )
import qualified Data.Text.Encoding as T
    ( encodeUtf8, decodeUtf8With )
import qualified Data.Text.Encoding.Error as T ( lenientDecode )
import Data.Typeable ( Typeable )
import Data.Word ( Word8, Word16, Word32, Word64 )
import Foreign
    ( Int32,
      Ptr,
      nullPtr,
      plusPtr,
      Storable(alignment, peek, peekByteOff, poke, pokeByteOff, sizeOf),
      Bits((.&.), (.|.), shiftL),
      castPtr,
      with,
      toBool,
      fromBool,
      withArrayLen,
      pokeArray,
      peekArray,
      copyArray,
      allocaArray )
import Foreign.C ( CString )

import System.Hardware.MercuryApi.Enums





-- | A GPIO pin number.  On the M6e Nano, these are numbered 1-4.
type PinNumber = Word8

-- | An antenna number.  On the
-- <https://www.sparkfun.com/products/14066 SparkFun Simultaneous RFID Reader>,
-- there is a single antenna with the number 1.
type AntennaPort = Word8

-- | A 32-bit password (access or kill) in the Gen2 protocol.
type GEN2_Password = Word32

-- | milliseconds since 1\/1\/1970 UTC
type MillisecondsSinceEpoch = Word64

-- | Version number of the Mercury API C library.
apiVersion :: Text
apiVersion = "1.29.3.34"
{-# LINE 58 "src/System/Hardware/MercuryApi/Records.hsc" #-}

type CBool = Word8
{-# LINE 60 "src/System/Hardware/MercuryApi/Records.hsc" #-}
newtype ReaderEtc = ReaderEtc ()

cFalse, cTrue :: CBool
cFalse = 0
cTrue = 1

toBool' :: CBool -> Bool
toBool' = toBool

fromBool' :: Bool -> CBool
fromBool' = fromBool

sizeofReaderEtc :: Int
sizeofReaderEtc = (2368)
{-# LINE 74 "src/System/Hardware/MercuryApi/Records.hsc" #-}

uriPtr :: Ptr ReaderEtc -> CString
uriPtr = (\hsc_ptr -> hsc_ptr `plusPtr` 2361)
{-# LINE 77 "src/System/Hardware/MercuryApi/Records.hsc" #-}

-- I'm not sure what encoding MercuryApi uses for its strings.
-- I'm guessing UTF-8 for now, but the encoding is encapsulated in
-- these two functions (textFromBS and textToBS) so it can be
-- easily changed.
textFromBS :: ByteString -> Text
textFromBS = T.decodeUtf8With T.lenientDecode

textToBS :: Text -> ByteString
textToBS = T.encodeUtf8

textFromCString :: CString -> IO Text
textFromCString cs = textFromBS <$> B.packCString cs

-- | Indicates whether to read or write the lock bits in
-- 'TagOp_GEN2_BlockPermaLock'.
data ReadWrite = Read !Int       -- ^ number of words of lock bits to read
               | Write ![Word16] -- ^ lock bits to write
               deriving (Eq, Ord, Show, Read)

fromReadWrite :: ReadWrite -> (Word8, [Word16])
fromReadWrite (Read n) = (0, replicate n 0)
fromReadWrite (Write ws) = (1, ws)

toReadWrite :: (Word8, [Word16]) -> ReadWrite
toReadWrite (0, ws) = Read $ length ws
toReadWrite (1, ws) = Write ws
toReadWrite (x, _)  = error $ "didn't expect ReadWrite to be " ++ show x

-- This exception is never seen by the user.  It is caught
-- internally and turned into a MercuryException (with some added fields).
data ParamException = ParamException StatusType Status Text
  deriving (Eq, Ord, Show, Read, Typeable)

instance Exception ParamException

castLen' :: Integral a => a -> Text -> Int -> IO a
castLen' bound description x = do
  let tShow = T.pack . show
      maxLen = fromIntegral bound
  if x > maxLen
    then throwIO ( ParamException ERROR_TYPE_MISC ERROR_TOO_BIG $
                   description <> " had length " <> tShow x <>
                   " but maximum is " <> tShow maxLen )
    else return $ fromIntegral x

castLen :: (Integral a, Bounded a) => Text -> Int -> IO a
castLen = castLen' maxBound

-- | A ReadPlan record specifies the antennas, protocols, and filters
-- to use for a search (read).
--
-- Currently, only @SimpleReadPlan@ is supported.
data ReadPlan =
  SimpleReadPlan
  { rpWeight        :: !Word32          -- ^ The relative weight of this read plan
  , rpEnableAutonomousRead :: !Bool     -- ^ Option for Autonomous read
  , rpAntennas      :: ![AntennaPort]   -- ^ The list of antennas to read on
  , rpProtocol      :: !TagProtocol     -- ^ The protocol to use for reading
  , rpFilter        :: !(Maybe TagFilter) -- ^ The filter to apply to reading
  , rpTagop         :: !(Maybe TagOp)   -- ^ The tag operation to apply to
                                        -- each read tag
  , rpUseFastSearch :: !Bool            -- ^ Option to use the FastSearch
  , rpStopOnCount   :: !(Maybe Word32)  -- ^ Number of tags to be read
  , rpTriggerRead   :: !(Maybe [Word8]) -- ^ The list of GPI ports which should
                                        -- be used to trigger the read
  } deriving (Eq, Ord, Show, Read)

antennasInfo :: Ptr ReadPlan -> (Ptr List16, Word16, Ptr Word8, Text)
antennasInfo rp =
  ( (\hsc_ptr -> hsc_ptr `plusPtr` 16) rp
{-# LINE 148 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  , 32
{-# LINE 149 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  , (\hsc_ptr -> hsc_ptr `plusPtr` 96) rp
{-# LINE 150 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  , "rpAntennas"
  )

gpiListInfo :: Ptr ReadPlan -> (Ptr List16, Word16, Ptr Word8, Text)
gpiListInfo rp =
  ( (\hsc_ptr -> hsc_ptr `plusPtr` 80) rp
{-# LINE 156 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  , 16
{-# LINE 157 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  , (\hsc_ptr -> hsc_ptr `plusPtr` 128) rp
{-# LINE 158 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  , "rpTriggerRead"
  )

readPlanTypeSimple :: Word32
{-# LINE 162 "src/System/Hardware/MercuryApi/Records.hsc" #-}
readPlanTypeSimple = 1
{-# LINE 163 "src/System/Hardware/MercuryApi/Records.hsc" #-}

instance Storable ReadPlan where
  sizeOf _ = (744)
{-# LINE 166 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  poke p x = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p readPlanTypeSimple
{-# LINE 170 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 4) p (rpWeight x)
{-# LINE 171 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p
{-# LINE 172 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      (fromBool' $ rpEnableAutonomousRead x)
    pokeList16 (antennasInfo p) (rpAntennas x)
    (\hsc_ptr -> pokeByteOff hsc_ptr 32) p
{-# LINE 175 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      (fromTagProtocol $ rpProtocol x)
    case rpFilter x of
      Nothing -> (\hsc_ptr -> pokeByteOff hsc_ptr 40) p nullPtr
{-# LINE 178 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      Just f -> do
        (\hsc_ptr -> pokeByteOff hsc_ptr 144) p f
{-# LINE 180 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 40) p ((\hsc_ptr -> hsc_ptr `plusPtr` 144) p)
{-# LINE 181 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    case rpTagop x of
      Nothing -> (\hsc_ptr -> pokeByteOff hsc_ptr 48) p nullPtr
{-# LINE 183 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      Just op -> do
        (\hsc_ptr -> pokeByteOff hsc_ptr 360) p op
{-# LINE 185 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 48) p ((\hsc_ptr -> hsc_ptr `plusPtr` 360) p)
{-# LINE 186 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 56) p
{-# LINE 187 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      (fromBool' $ rpUseFastSearch x)
    let (stop, nTags) = case rpStopOnCount x of
                          Nothing -> (cFalse, 0)
                          Just n -> (cTrue, n)
    (\hsc_ptr -> pokeByteOff hsc_ptr 60) p stop
{-# LINE 192 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 64) p nTags
{-# LINE 193 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    let (enable, ports) = case rpTriggerRead x of
                            Nothing -> (cFalse, [])
                            Just ps -> (cTrue, ps)
    (\hsc_ptr -> pokeByteOff hsc_ptr 72) p enable
{-# LINE 197 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokeList16 (gpiListInfo p) ports

  peek p = do
    weight <- (\hsc_ptr -> peekByteOff hsc_ptr 4) p
{-# LINE 201 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    enableAutonomousRead <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 202 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    antennas <- peekList16 (antennasInfo p)
    protocol <- (\hsc_ptr -> peekByteOff hsc_ptr 32) p
{-# LINE 204 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    fPtr <- (\hsc_ptr -> peekByteOff hsc_ptr 40) p
{-# LINE 205 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    filt <- if fPtr == nullPtr
            then return Nothing
            else Just <$> peek fPtr
    opPtr <- (\hsc_ptr -> peekByteOff hsc_ptr 48) p
{-# LINE 209 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    op <- if opPtr == nullPtr
          then return Nothing
          else Just <$> peek opPtr
    useFastSearch <- (\hsc_ptr -> peekByteOff hsc_ptr 56) p
{-# LINE 213 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    stop <- (\hsc_ptr -> peekByteOff hsc_ptr 60) p
{-# LINE 214 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    stopOnCount <- if toBool' stop
                   then Just <$> (\hsc_ptr -> peekByteOff hsc_ptr 64) p
{-# LINE 216 "src/System/Hardware/MercuryApi/Records.hsc" #-}
                   else return Nothing
    enable <- (\hsc_ptr -> peekByteOff hsc_ptr 72) p
{-# LINE 218 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    triggerRead <- if toBool' enable
                   then Just <$> peekList16 (gpiListInfo p)
                   else return Nothing
    return $ SimpleReadPlan
      { rpWeight = weight
      , rpEnableAutonomousRead = toBool' enableAutonomousRead
      , rpAntennas = antennas
      , rpProtocol = toTagProtocol protocol
      , rpFilter = filt
      , rpTagop = op
      , rpUseFastSearch = toBool' useFastSearch
      , rpStopOnCount = stopOnCount
      , rpTriggerRead = triggerRead
      }

-- | Filter on EPC length, or on a Gen2 bank.
data FilterOn = FilterOnBank GEN2_Bank
              | FilterOnEpcLength
              deriving (Eq, Ord, Show, Read)

instance Storable FilterOn where
  sizeOf _ = (4)
{-# LINE 240 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  poke p FilterOnEpcLength = do
    let p' = castPtr p :: Ptr RawBank
    poke p' 6
{-# LINE 245 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p (FilterOnBank bank) = do
    let p' = castPtr p :: Ptr RawBank
    poke p' (fromBank bank)

  peek p = do
    x <- peek (castPtr p)
    if x == 6
{-# LINE 253 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      then return FilterOnEpcLength
      else return $ FilterOnBank $ toBank x

-- | Filter on EPC data, or on Gen2-specific information.
data TagFilter = TagFilterEPC TagData
               | TagFilterGen2
               { tfInvert        :: !Bool        -- ^ Whether to invert the
                                                 -- selection (deselect tags
                                                 -- that meet the comparison)
               , tfFilterOn      :: !FilterOn    -- ^ The memory bank in which
                                                 -- to compare the mask
               , tfBitPointer    :: !Word32      -- ^ The location (in bits) at
                                                 -- which to begin comparing
                                                 -- the mask
               , tfMaskBitLength :: !Word16      -- ^ The length (in bits) of
                                                 -- the mask
               , tfMask          :: !ByteString  -- ^ The mask value to compare
                                                 -- with the specified region
                                                 -- of tag memory, MSB first
               }
               deriving (Eq, Ord, Show, Read)

instance Storable TagFilter where
  sizeOf _ = (216)
{-# LINE 277 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  poke p (TagFilterEPC td) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p
{-# LINE 281 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      (0 :: Word32)
{-# LINE 282 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p td
{-# LINE 283 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p tf@(TagFilterGen2 {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p
{-# LINE 286 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      (1 :: Word32)
{-# LINE 287 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (fromBool' $ tfInvert tf)
{-# LINE 288 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (tfFilterOn tf)
{-# LINE 289 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 16) p (tfBitPointer tf)
{-# LINE 290 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 20) p (tfMaskBitLength tf)
{-# LINE 291 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    let maskLenBytes = fromIntegral $ (tfMaskBitLength tf + 7) `div` 8
        origLen = B.length (tfMask tf)
        bs = if origLen < maskLenBytes
               then tfMask tf <> B.pack (replicate (maskLenBytes - origLen) 0)
               else tfMask tf
    B.useAsCStringLen bs $ \(cs, len) -> do
      len' <- castLen' 128 "tfMask" len
{-# LINE 298 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      copyArray ((\hsc_ptr -> hsc_ptr `plusPtr` 88) p) cs (fromIntegral len')
{-# LINE 299 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 24) p ((\hsc_ptr -> hsc_ptr `plusPtr` 88) p)
{-# LINE 300 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  peek p = do
    ft <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p :: IO Word32
{-# LINE 303 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    case ft of
      0 ->
{-# LINE 305 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagFilterEPC <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 306 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      1 -> do
{-# LINE 307 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        bitLength <- (\hsc_ptr -> peekByteOff hsc_ptr 20) p
{-# LINE 308 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagFilterGen2
          <$> (toBool' <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 310 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 12) p
{-# LINE 311 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 16) p
{-# LINE 312 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> return bitLength
          <*> peekMask p bitLength

peekMask :: Ptr TagFilter -> Word16 -> IO ByteString
peekMask p bitLength = do
  let len = fromIntegral $ (bitLength + 7) `div` 8
  maskPtr <- (\hsc_ptr -> peekByteOff hsc_ptr 24) p
{-# LINE 319 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  B.packCStringLen (maskPtr, len)

packBits :: Num b => (a -> b) -> [a] -> b
packBits from flags = sum $ map from flags

unpackBits :: (Bounded a, Enum a, Num b, Bits b) => (a -> b) -> b -> [a]
unpackBits from x = mapMaybe f [minBound..maxBound]
  where f flag = if (x .&. from flag) == 0
                 then Nothing
                 else Just flag

packFlags :: [MetadataFlag] -> RawMetadataFlag
packFlags = packBits fromMetadataFlag

unpackFlags :: RawMetadataFlag -> [MetadataFlag]
unpackFlags = unpackBits fromMetadataFlag

packFlags16 :: [MetadataFlag] -> Word16
packFlags16 = fromIntegral . packFlags

unpackFlags16 :: Word16 -> [MetadataFlag]
unpackFlags16 = unpackFlags . fromIntegral

packExtraBanks :: [GEN2_Bank] -> RawBank
packExtraBanks = packBits fromExtraBank

unpackExtraBanks :: RawBank -> [GEN2_Bank]
unpackExtraBanks = unpackBits fromExtraBank

packLockBits :: [GEN2_LockBits] -> RawLockBits
packLockBits = packBits fromLockBits

unpackLockBits :: RawLockBits -> [GEN2_LockBits]
unpackLockBits = unpackBits fromLockBits

packLockBits16 :: [GEN2_LockBits] -> Word16
packLockBits16 = fromIntegral . packLockBits

unpackLockBits16 :: Word16 -> [GEN2_LockBits]
unpackLockBits16 = unpackLockBits . fromIntegral

peekArrayAsByteString :: Ptr Word8 -> Ptr Word8 -> IO ByteString
peekArrayAsByteString arrayPtr lenPtr = do
  len <- peek lenPtr
  B.packCStringLen (castPtr arrayPtr, fromIntegral len)

pokeArrayAsByteString :: Text
                      -> Word8
                      -> Ptr Word8
                      -> Ptr Word8
                      -> ByteString
                      -> IO ()
pokeArrayAsByteString desc maxLen arrayPtr lenPtr bs = do
  B.useAsCStringLen bs $ \(cs, len) -> do
    len' <- castLen' maxLen desc len
    copyArray arrayPtr (castPtr cs) (fromIntegral len')
    poke lenPtr len'

peekListAsByteString :: Ptr List16 -> IO ByteString
peekListAsByteString listPtr = do
  lst <- peek listPtr
  B.packCStringLen (castPtr $ l16_list lst, fromIntegral $ l16_len lst)

peekArrayAsList :: Storable a => Ptr a -> Ptr Word8 -> IO [a]
peekArrayAsList arrayPtr lenPtr = do
  len <- peek lenPtr
  peekArray (fromIntegral len) arrayPtr

peekListAsList :: Storable a => Ptr List16 -> Ptr a -> IO [a]
peekListAsList listPtr _ = do
  lst <- peek listPtr
  peekArray (fromIntegral $ l16_len lst) (castPtr $ l16_list lst)

pokeListAsList :: Storable a
               => Text
               -> Word16
               -> Ptr List16
               -> Ptr a
               -> [a]
               -> IO ()
pokeListAsList desc maxLen listPtr storage xs = do
  withArrayLen xs $ \len tmpPtr -> do
    len' <- castLen' maxLen desc len
    copyArray storage tmpPtr len
    let lst = List16
              { l16_list = castPtr storage
              , l16_max = maxLen
              , l16_len = len'
              }
    poke listPtr lst

peekMaybe :: (Storable a, Storable b)
          => (Ptr a -> IO a)
          -> (b -> Bool)
          -> Ptr a
          -> Ptr b
          -> IO (Maybe a)
peekMaybe oldPeek cond justP condP = do
  c <- peek condP
  if cond c
    then Just <$> oldPeek justP
    else return Nothing

pokeGen2TagData :: Ptr GEN2_TagData
                -> Ptr RawTagProtocol
                -> Maybe GEN2_TagData
                -> IO ()
pokeGen2TagData pGen2 _ mGen2 = do
  let gen2 = fromMaybe (GEN2_TagData B.empty) mGen2
  poke pGen2 gen2

peekSplit64 :: Ptr Word32 -> Ptr Word32 -> IO Word64
peekSplit64 pLow pHigh = do
  lo <- fromIntegral <$> peek pLow
  hi <- fromIntegral <$> peek pHigh
  return $ lo .|. (hi `shiftL` 32)

peekPtr :: Storable a => Ptr (Ptr a) -> Ptr a -> IO a
peekPtr pp _ = do
  p <- peek pp
  peek p

pokePtr :: Storable a => Ptr (Ptr a) -> Ptr a -> a -> IO ()
pokePtr pp p x = do
  poke p x
  poke pp p

pokeOr :: (Storable a, Bits a) => Ptr a -> a -> IO ()
pokeOr p x = do
  old <- peek p
  poke p (x .|. old)

data List16 =
  List16
  { l16_list :: !(Ptr ())
  , l16_max :: !(Word16)
  , l16_len :: !(Word16)
  }

instance Storable List16 where
  sizeOf _ = (16)
{-# LINE 460 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8
  peek p = List16
           <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 463 "src/System/Hardware/MercuryApi/Records.hsc" #-}
           <*> (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 464 "src/System/Hardware/MercuryApi/Records.hsc" #-}
           <*> (\hsc_ptr -> peekByteOff hsc_ptr 10) p
{-# LINE 465 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  poke p x = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (l16_list x)
{-# LINE 467 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (l16_max x)
{-# LINE 468 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 10) p (l16_len x)
{-# LINE 469 "src/System/Hardware/MercuryApi/Records.hsc" #-}

getList16 :: Storable a => (Ptr () -> IO ()) -> IO [a]
getList16 f = do
  let maxLen = maxBound :: Word16
  allocaArray (fromIntegral maxLen) $ \storage -> do
    let lst = List16
              { l16_list = castPtr storage
              , l16_max = maxLen
              , l16_len = 0
              }
    with lst $ \p -> do
      f (castPtr p)
      lst' <- peek p
      peekArray (fromIntegral (l16_len lst')) storage

setList16 :: Storable a => Text -> [a] -> (Ptr () -> IO ()) -> IO ()
setList16 t x f = do
  withArrayLen x $ \len storage -> do
    len' <- castLen t len
    let lst = List16
              { l16_list = castPtr storage
              , l16_max = len'
              , l16_len = len'
              }
    with lst $ \p -> f (castPtr p)

pokeList16 :: Storable a => (Ptr List16, Word16, Ptr a, Text) -> [a] -> IO ()
pokeList16 (lp, maxLen, storage, name) ws = do
  len <- castLen' maxLen name (length ws)
  poke lp $ List16
    { l16_list = castPtr storage
    , l16_max = maxLen
    , l16_len = len
    }
  pokeArray storage ws

peekList16 :: Storable a => (Ptr List16, Word16, Ptr a, Text) -> IO [a]
peekList16 (lp, _, _, _) = do
  lst <- peek lp
  peekArray (fromIntegral $ l16_len lst) (castPtr $ l16_list lst)

data List8 =
  List8
  { l8_list :: !(Ptr ())
  , l8_max :: !(Word8)
  , l8_len :: !(Word8)
  }

instance Storable List8 where
  sizeOf _ = (16)
{-# LINE 519 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8
  peek p = List8
           <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 522 "src/System/Hardware/MercuryApi/Records.hsc" #-}
           <*> (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 523 "src/System/Hardware/MercuryApi/Records.hsc" #-}
           <*> (\hsc_ptr -> peekByteOff hsc_ptr 9) p
{-# LINE 524 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  poke p x = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (l8_list x)
{-# LINE 526 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (l8_max x)
{-# LINE 527 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 9) p (l8_len x)
{-# LINE 528 "src/System/Hardware/MercuryApi/Records.hsc" #-}

getList8 :: Storable a => (Ptr () -> IO ()) -> IO [a]
getList8 f = do
  let maxLen = maxBound :: Word8
  allocaArray (fromIntegral maxLen) $ \storage -> do
    let lst = List8
              { l8_list = castPtr storage
              , l8_max = maxLen
              , l8_len = 0
              }
    with lst $ \p -> do
      f (castPtr p)
      lst' <- peek p
      peekArray (fromIntegral (l8_len lst')) storage

setList8 :: Storable a => Text -> [a] -> (Ptr () -> IO ()) -> IO ()
setList8 t x f = do
  withArrayLen x $ \len storage -> do
    len' <- castLen t len
    let lst = List8
              { l8_list = castPtr storage
              , l8_max = len'
              , l8_len = len'
              }
    with lst $ \p -> f (castPtr p)

pokeList8 :: Storable a => (Ptr List8, Word8, Ptr a, Text) -> [a] -> IO ()
pokeList8 (lp, maxLen, storage, name) ws = do
  len <- castLen' maxLen name (length ws)
  poke lp $ List8
    { l8_list = castPtr storage
    , l8_max = maxLen
    , l8_len = len
    }
  pokeArray storage ws

peekList8 :: Storable a => (Ptr List8, Word8, Ptr a, Text) -> IO [a]
peekList8 (lp, _, _, _) = do
  lst <- peek lp
  peekArray (fromIntegral $ l8_len lst) (castPtr $ l8_list lst)

-- | Gen2-specific per-tag data
newtype GEN2_TagData =
  GEN2_TagData
  { g2Pc :: ByteString -- ^ Tag PC
  } deriving (Eq, Ord, Show, Read)

instance Storable GEN2_TagData where
  sizeOf _ = (7)
{-# LINE 577 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  peek p =
    GEN2_TagData
      <$> peekArrayAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 1) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 0) p)
{-# LINE 582 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x = do
    pokeArrayAsByteString "pc" 6 ((\hsc_ptr -> hsc_ptr `plusPtr` 1) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 0) p) (g2Pc x)
{-# LINE 585 "src/System/Hardware/MercuryApi/Records.hsc" #-}

-- | A record to represent RFID tags.
data TagData =
  TagData
  { tdEpc :: !ByteString -- ^ Tag EPC
  , tdProtocol :: !TagProtocol -- ^ Protocol of the tag
  , tdCrc :: !Word16 -- ^ Tag CRC
  , tdGen2 :: !(Maybe (GEN2_TagData)) -- ^ Gen2-specific tag information
  } deriving (Eq, Ord, Show, Read)

instance Storable TagData where
  sizeOf _ = (80)
{-# LINE 597 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  peek p =
    TagData
      <$> peekArrayAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 0) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 68) p)
{-# LINE 602 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (toTagProtocol <$> (\hsc_ptr -> peekByteOff hsc_ptr 64) p)
{-# LINE 603 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (\hsc_ptr -> peekByteOff hsc_ptr 70) p
{-# LINE 604 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekMaybe (peek) (== (5 :: RawTagProtocol)) ((\hsc_ptr -> hsc_ptr `plusPtr` 72) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 64) p)
{-# LINE 605 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x = do
    pokeArrayAsByteString "epc" 62 ((\hsc_ptr -> hsc_ptr `plusPtr` 0) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 68) p) (tdEpc x)
{-# LINE 608 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 64) p (fromTagProtocol $ tdProtocol x)
{-# LINE 609 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 70) p (tdCrc x)
{-# LINE 610 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokeGen2TagData ((\hsc_ptr -> hsc_ptr `plusPtr` 72) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 64) p) (tdGen2 x)
{-# LINE 611 "src/System/Hardware/MercuryApi/Records.hsc" #-}

-- | The identity and state of a single GPIO pin.
data GpioPin =
  GpioPin
  { gpId :: !PinNumber -- ^ The ID number of the pin.
  , gpHigh :: !Bool -- ^ Whether the pin is in the high state.
  , gpOutput :: !Bool -- ^ The direction of the pin
  } deriving (Eq, Ord, Show, Read)

instance Storable GpioPin where
  sizeOf _ = (3)
{-# LINE 622 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  peek p =
    GpioPin
      <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 627 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (toBool' <$> (\hsc_ptr -> peekByteOff hsc_ptr 1) p)
{-# LINE 628 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (toBool' <$> (\hsc_ptr -> peekByteOff hsc_ptr 2) p)
{-# LINE 629 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (gpId x)
{-# LINE 632 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 1) p (fromBool' $ gpHigh x)
{-# LINE 633 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 2) p (fromBool' $ gpOutput x)
{-# LINE 634 "src/System/Hardware/MercuryApi/Records.hsc" #-}

-- | A record to represent a read of an RFID tag.
-- Provides access to the metadata of the read event,
-- such as the time of the read, the antenna that read the tag,
-- and the number of times the tag was seen by the air protocol.
data TagReadData =
  TagReadData
  { trTag :: !TagData -- ^ The tag that was read
  , trMetadataFlags :: ![MetadataFlag] -- ^ The set of metadata items below that are valid
  , trPhase :: !Word16 -- ^ Tag response phase
  , trAntenna :: !AntennaPort -- ^ Antenna where the tag was read
  , trGpio :: ![GpioPin] -- ^ State of GPIO pins at the moment of the tag read
  , trReadCount :: !Word32 -- ^ Number of times the tag was read
  , trRssi :: !Int32 -- ^ Strength of the signal received from the tag
  , trFrequency :: !Word32 -- ^ RF carrier frequency the tag was read with
  , trTimestamp :: !MillisecondsSinceEpoch -- ^ Absolute time of the read, in milliseconds since 1\/1\/1970 UTC
  , trData :: !ByteString -- ^ Data read from the tag
  , trEpcMemData :: !ByteString -- ^ Read EPC bank data bytes  (Only if 'GEN2_BANK_EPC' is present in 'opExtraBanks')
  , trTidMemData :: !ByteString -- ^ Read TID bank data bytes  (Only if 'GEN2_BANK_TID' is present in 'opExtraBanks')
  , trUserMemData :: !ByteString -- ^ Read USER bank data bytes  (Only if 'GEN2_BANK_USER' is present in 'opExtraBanks')
  , trReservedMemData :: !ByteString -- ^ Read RESERVED bank data bytes  (Only if 'GEN2_BANK_RESERVED' is present in 'opExtraBanks')
  } deriving (Eq, Ord, Show, Read)

instance Storable TagReadData where
  sizeOf _ = (896)
{-# LINE 659 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  peek p =
    TagReadData
      <$> (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 664 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (unpackFlags16 <$> (\hsc_ptr -> peekByteOff hsc_ptr 80) p)
{-# LINE 665 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (\hsc_ptr -> peekByteOff hsc_ptr 82) p
{-# LINE 666 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (\hsc_ptr -> peekByteOff hsc_ptr 84) p
{-# LINE 667 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekArrayAsList ((\hsc_ptr -> hsc_ptr `plusPtr` 85) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 133) p)
{-# LINE 668 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (\hsc_ptr -> peekByteOff hsc_ptr 136) p
{-# LINE 669 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (\hsc_ptr -> peekByteOff hsc_ptr 140) p
{-# LINE 670 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> (\hsc_ptr -> peekByteOff hsc_ptr 144) p
{-# LINE 671 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekSplit64 ((\hsc_ptr -> hsc_ptr `plusPtr` 148) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 152) p)
{-# LINE 672 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekListAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 160) p)
{-# LINE 673 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekListAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 176) p)
{-# LINE 674 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekListAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 192) p)
{-# LINE 675 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekListAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 208) p)
{-# LINE 676 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      <*> peekListAsByteString ((\hsc_ptr -> hsc_ptr `plusPtr` 224) p)
{-# LINE 677 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x = error "poke not implemented for TagReadData"

-- | An operation that can be performed on a tag.  Can be used
-- as an argument to 'System.Hardware.MercuryApi.executeTagOp',
-- or can be embedded into a 'System.Hardware.MercuryApi.ReadPlan'.
-- (However, on the M6e Nano, only 'TagOp_GEN2_ReadData' may be
-- embedded in a 'System.Hardware.MercuryApi.ReadPlan'.)
data TagOp =
    TagOp_GEN2_ReadData
    { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on
    , opExtraBanks :: ![GEN2_Bank] -- ^ Additional Gen2 memory banks to read from  (seems buggy, though; I\'ve had strange results with it)
    , opWordAddress :: !Word32 -- ^ Word address to start at
    , opLen :: !Word8 -- ^ Number of words to read
    }
  | TagOp_GEN2_WriteTag
    { opEpc :: !TagData -- ^ Tag EPC
    }
  | TagOp_GEN2_WriteData
    { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on
    , opWordAddress :: !Word32 -- ^ Word address to start at
    , opData :: ![Word16] -- ^ Data to write
    }
  | TagOp_GEN2_Lock
    { opMask :: ![GEN2_LockBits] -- ^ Bitmask indicating which lock bits to change
    , opAction :: ![GEN2_LockBits] -- ^ New values of each bit specified in the mask
    , opAccessPassword :: !GEN2_Password -- ^ Access Password to use to lock the tag
    }
  | TagOp_GEN2_Kill
    { opPassword :: !GEN2_Password -- ^ Kill password to use to kill the tag
    }
  | TagOp_GEN2_BlockWrite
    { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on
    , opWordPtr :: !Word32 -- ^ The word address to start at
    , opData :: ![Word16] -- ^ The data to write
    }
  | TagOp_GEN2_BlockErase
    { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on
    , opWordPtr :: !Word32 -- ^ The word address to start at
    , opWordCount :: !Word8 -- ^ Number of words to erase
    }
  | TagOp_GEN2_BlockPermaLock
    { opBank :: !GEN2_Bank -- ^ Gen2 memory bank to operate on
    , opBlockPtr :: !Word32 -- ^ The starting word address to lock
    , opReadWrite :: !ReadWrite -- ^ Read lock status or write it?
    }
  deriving (Eq, Ord, Show, Read)

instance Storable TagOp where
  sizeOf _ = (384)
{-# LINE 727 "src/System/Hardware/MercuryApi/Records.hsc" #-}
  alignment _ = 8

  peek p = do
    x <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p :: IO Word32
{-# LINE 731 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    case x of
      1 -> do
{-# LINE 733 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_ReadData
          <$> ((toBank . (.&. 3)) <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 735 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (unpackExtraBanks <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 736 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 12) p
{-# LINE 737 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 16) p
{-# LINE 738 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      0 -> do
{-# LINE 739 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_WriteTag
          <$> peekPtr ((\hsc_ptr -> hsc_ptr `plusPtr` 8) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p)
{-# LINE 741 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      2 -> do
{-# LINE 742 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_WriteData
          <$> ((toBank . (.&. 3)) <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 744 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 12) p
{-# LINE 745 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> peekListAsList ((\hsc_ptr -> hsc_ptr `plusPtr` 16) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p)
{-# LINE 746 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      3 -> do
{-# LINE 747 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_Lock
          <$> (unpackLockBits16 <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 749 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (unpackLockBits16 <$> (\hsc_ptr -> peekByteOff hsc_ptr 10) p)
{-# LINE 750 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 12) p
{-# LINE 751 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      4 -> do
{-# LINE 752 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_Kill
          <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 754 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      5 -> do
{-# LINE 755 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_BlockWrite
          <$> ((toBank . (.&. 3)) <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 757 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 12) p
{-# LINE 758 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> peekListAsList ((\hsc_ptr -> hsc_ptr `plusPtr` 16) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p)
{-# LINE 759 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      7 -> do
{-# LINE 760 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_BlockErase
          <$> ((toBank . (.&. 3)) <$> (\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 762 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 12) p
{-# LINE 763 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 16) p
{-# LINE 764 "src/System/Hardware/MercuryApi/Records.hsc" #-}
      6 -> do
{-# LINE 765 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        rw <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 766 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        ws <- peekListAsList ((\hsc_ptr -> hsc_ptr `plusPtr` 24) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p)
{-# LINE 767 "src/System/Hardware/MercuryApi/Records.hsc" #-}
        TagOp_GEN2_BlockPermaLock
          <$> ((toBank . (.&. 3)) <$> (\hsc_ptr -> peekByteOff hsc_ptr 12) p)
{-# LINE 769 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (\hsc_ptr -> peekByteOff hsc_ptr 16) p
{-# LINE 770 "src/System/Hardware/MercuryApi/Records.hsc" #-}
          <*> (return $ toReadWrite (rw, ws))

  poke p x@(TagOp_GEN2_ReadData {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (1 :: Word32)
{-# LINE 774 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (fromBank $ opBank x)
{-# LINE 775 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokeOr ((\hsc_ptr -> hsc_ptr `plusPtr` 8) p) (packExtraBanks $ opExtraBanks x)
{-# LINE 776 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (opWordAddress x)
{-# LINE 777 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 16) p (opLen x)
{-# LINE 778 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_WriteTag {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (0 :: Word32)
{-# LINE 781 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokePtr ((\hsc_ptr -> hsc_ptr `plusPtr` 8) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p) (opEpc x)
{-# LINE 782 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_WriteData {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (2 :: Word32)
{-# LINE 785 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (fromBank $ opBank x)
{-# LINE 786 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (opWordAddress x)
{-# LINE 787 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokeListAsList "data" 128 ((\hsc_ptr -> hsc_ptr `plusPtr` 16) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p) (opData x)
{-# LINE 788 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_Lock {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (3 :: Word32)
{-# LINE 791 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (packLockBits16 $ opMask x)
{-# LINE 792 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 10) p (packLockBits16 $ opAction x)
{-# LINE 793 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (opAccessPassword x)
{-# LINE 794 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_Kill {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (4 :: Word32)
{-# LINE 797 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (opPassword x)
{-# LINE 798 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_BlockWrite {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (5 :: Word32)
{-# LINE 801 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (fromBank $ opBank x)
{-# LINE 802 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (opWordPtr x)
{-# LINE 803 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokeListAsList "data" 128 ((\hsc_ptr -> hsc_ptr `plusPtr` 16) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p) (opData x)
{-# LINE 804 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_BlockErase {}) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (7 :: Word32)
{-# LINE 807 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p (fromBank $ opBank x)
{-# LINE 808 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (opWordPtr x)
{-# LINE 809 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 16) p (opWordCount x)
{-# LINE 810 "src/System/Hardware/MercuryApi/Records.hsc" #-}

  poke p x@(TagOp_GEN2_BlockPermaLock {}) = do
    let (rw, ws) = fromReadWrite $ opReadWrite x
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p (6 :: Word32)
{-# LINE 814 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) p rw
{-# LINE 815 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 12) p (fromBank $ opBank x)
{-# LINE 816 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 16) p (opBlockPtr x)
{-# LINE 817 "src/System/Hardware/MercuryApi/Records.hsc" #-}
    pokeListAsList "mask" 128 ((\hsc_ptr -> hsc_ptr `plusPtr` 24) p) ((\hsc_ptr -> hsc_ptr `plusPtr` 128) p) ws
{-# LINE 818 "src/System/Hardware/MercuryApi/Records.hsc" #-}

tagOpName :: TagOp -> Text
tagOpName TagOp_GEN2_ReadData {} = "TagOp_GEN2_ReadData"
tagOpName TagOp_GEN2_WriteTag {} = "TagOp_GEN2_WriteTag"
tagOpName TagOp_GEN2_WriteData {} = "TagOp_GEN2_WriteData"
tagOpName TagOp_GEN2_Lock {} = "TagOp_GEN2_Lock"
tagOpName TagOp_GEN2_Kill {} = "TagOp_GEN2_Kill"
tagOpName TagOp_GEN2_BlockWrite {} = "TagOp_GEN2_BlockWrite"
tagOpName TagOp_GEN2_BlockErase {} = "TagOp_GEN2_BlockErase"
tagOpName TagOp_GEN2_BlockPermaLock {} = "TagOp_GEN2_BlockPermaLock"