packages feed

Lambdaya (empty) → 0.1.0.0

raw patch · 5 files changed

+1054/−0 lines, 5 filesdep +basedep +mtldep +unixsetup-changed

Dependencies added: base, mtl, unix

Files

+ LICENSE view
@@ -0,0 +1,165 @@+                  GNU LESSER GENERAL PUBLIC LICENSE+                       Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.+++  This version of the GNU Lesser General Public License incorporates+the terms and conditions of version 3 of the GNU General Public+License, supplemented by the additional permissions listed below.++  0. Additional Definitions.++  As used herein, "this License" refers to version 3 of the GNU Lesser+General Public License, and the "GNU GPL" refers to version 3 of the GNU+General Public License.++  "The Library" refers to a covered work governed by this License,+other than an Application or a Combined Work as defined below.++  An "Application" is any work that makes use of an interface provided+by the Library, but which is not otherwise based on the Library.+Defining a subclass of a class defined by the Library is deemed a mode+of using an interface provided by the Library.++  A "Combined Work" is a work produced by combining or linking an+Application with the Library.  The particular version of the Library+with which the Combined Work was made is also called the "Linked+Version".++  The "Minimal Corresponding Source" for a Combined Work means the+Corresponding Source for the Combined Work, excluding any source code+for portions of the Combined Work that, considered in isolation, are+based on the Application, and not on the Linked Version.++  The "Corresponding Application Code" for a Combined Work means the+object code and/or source code for the Application, including any data+and utility programs needed for reproducing the Combined Work from the+Application, but excluding the System Libraries of the Combined Work.++  1. Exception to Section 3 of the GNU GPL.++  You may convey a covered work under sections 3 and 4 of this License+without being bound by section 3 of the GNU GPL.++  2. Conveying Modified Versions.++  If you modify a copy of the Library, and, in your modifications, a+facility refers to a function or data to be supplied by an Application+that uses the facility (other than as an argument passed when the+facility is invoked), then you may convey a copy of the modified+version:++   a) under this License, provided that you make a good faith effort to+   ensure that, in the event an Application does not supply the+   function or data, the facility still operates, and performs+   whatever part of its purpose remains meaningful, or++   b) under the GNU GPL, with none of the additional permissions of+   this License applicable to that copy.++  3. Object Code Incorporating Material from Library Header Files.++  The object code form of an Application may incorporate material from+a header file that is part of the Library.  You may convey such object+code under terms of your choice, provided that, if the incorporated+material is not limited to numerical parameters, data structure+layouts and accessors, or small macros, inline functions and templates+(ten or fewer lines in length), you do both of the following:++   a) Give prominent notice with each copy of the object code that the+   Library is used in it and that the Library and its use are+   covered by this License.++   b) Accompany the object code with a copy of the GNU GPL and this license+   document.++  4. Combined Works.++  You may convey a Combined Work under terms of your choice that,+taken together, effectively do not restrict modification of the+portions of the Library contained in the Combined Work and reverse+engineering for debugging such modifications, if you also do each of+the following:++   a) Give prominent notice with each copy of the Combined Work that+   the Library is used in it and that the Library and its use are+   covered by this License.++   b) Accompany the Combined Work with a copy of the GNU GPL and this license+   document.++   c) For a Combined Work that displays copyright notices during+   execution, include the copyright notice for the Library among+   these notices, as well as a reference directing the user to the+   copies of the GNU GPL and this license document.++   d) Do one of the following:++       0) Convey the Minimal Corresponding Source under the terms of this+       License, and the Corresponding Application Code in a form+       suitable for, and under terms that permit, the user to+       recombine or relink the Application with a modified version of+       the Linked Version to produce a modified Combined Work, in the+       manner specified by section 6 of the GNU GPL for conveying+       Corresponding Source.++       1) Use a suitable shared library mechanism for linking with the+       Library.  A suitable mechanism is one that (a) uses at run time+       a copy of the Library already present on the user's computer+       system, and (b) will operate properly with a modified version+       of the Library that is interface-compatible with the Linked+       Version.++   e) Provide Installation Information, but only if you would otherwise+   be required to provide such information under section 6 of the+   GNU GPL, and only to the extent that such information is+   necessary to install and execute a modified version of the+   Combined Work produced by recombining or relinking the+   Application with a modified version of the Linked Version. (If+   you use option 4d0, the Installation Information must accompany+   the Minimal Corresponding Source and Corresponding Application+   Code. If you use option 4d1, you must provide the Installation+   Information in the manner specified by section 6 of the GNU GPL+   for conveying Corresponding Source.)++  5. Combined Libraries.++  You may place library facilities that are a work based on the+Library side by side in a single library together with other library+facilities that are not Applications and are not covered by this+License, and convey such a combined library under terms of your+choice, if you do both of the following:++   a) Accompany the combined library with a copy of the same work based+   on the Library, uncombined with any other library facilities,+   conveyed under the terms of this License.++   b) Give prominent notice with the combined library that part of it+   is a work based on the Library, and explaining where to find the+   accompanying uncombined form of the same work.++  6. Revised Versions of the GNU Lesser General Public License.++  The Free Software Foundation may publish revised and/or new versions+of the GNU Lesser General Public License from time to time. Such new+versions will be similar in spirit to the present version, but may+differ in detail to address new problems or concerns.++  Each version is given a distinguishing version number. If the+Library as you received it specifies that a certain numbered version+of the GNU Lesser General Public License "or any later version"+applies to it, you have the option of following the terms and+conditions either of that published version or of any later version+published by the Free Software Foundation. If the Library as you+received it does not specify a version number of the GNU Lesser+General Public License, you may choose any version of the GNU Lesser+General Public License ever published by the Free Software Foundation.++  If the Library as you received it specifies that a proxy can decide+whether future versions of the GNU Lesser General Public License shall+apply, that proxy's public statement of acceptance of any version is+permanent authorization for you to choose that version for the+Library.
+ Lambdaya.cabal view
@@ -0,0 +1,77 @@+-- Initial redpitaya.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++-- The name of the package.+name:                Lambdaya++-- The package version.  See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary:      +-+------- breaking API changes+--                   | | +----- non-breaking API additions+--                   | | | +--- code changes with no API change+version:             0.1.0.0++-- A short (one-line) description of the package.+synopsis: Library for RedPitaya         ++-- A longer description of the package.+description: Native library for RedPitaya that runs on RedPitaya.+++-- The license under which the package is released.+license:             LGPL-3++-- The file containing the license text.+license-file:        LICENSE++-- The package author(s).+author:              Luka Rahne++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer:          luka.rahne@gmail.com++-- A copyright notice.+-- copyright:           ++category:            System++build-type:          Simple++-- Extra files to be distributed with the package, such as examples or a +-- README.+-- extra-source-files:  ++-- Constraint on the version of Cabal needed to build this package.+cabal-version:       >=1.10++source-repository head+  type:     git+  location: https://github.com/ra1u/Lambdaya.git+++library+  -- Modules exported by the library.+  exposed-modules: System.RedPitaya.Fpga, System.RedPitaya.Tutorial+  +  -- Modules included in this library but not exported.+  -- other-modules:  +  +  -- LANGUAGE extensions used by modules in this package.+  -- other-extensions:    +  +  -- Other library packages from which modules are imported.+  build-depends:    +    base >= 3 && < 5, +    mtl >= 2 && < 3, +    unix >= 2 && < 3+  +  -- Directories containing source files.+  hs-source-dirs:      src+  +  -- Base language which the package is written in.+  default-language:    Haskell2010+  +  -- build-tools: c2hs +  -- include-dirs: include
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/System/RedPitaya/Fpga.hs view
@@ -0,0 +1,680 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- | +-- <http://redpitaya.com/ Red Pitaya> native library for accessing Fpga++module System.RedPitaya.Fpga (+    Fpga,+    Registry,+    Channel,+    withOpenFpga,+    -- * Housekeeping+    -- | various housekeeping and Gpio functions+    fpgaId,+    dna,+    setExpDirP,+    getExpDirP,+    setExpDirN,+    getExpDirN,+    setExpOutP,+    setExpOutN,+    getExpInP,+    getExpInN,+    -- single pin functions+    GpioType(..),+    GpioDirection(..),+    PinNum,+    setExpDir,+    GpioValue(..),+    setExpOut,+    getExpOut,+    setLed,+    getLed,+    -- * Oscilloscope+    -- | functions for accessing oscilloscope features+    resetWriteSM,+    triggerNow,+    TriggerSource(..),+    setOscTrigger,+    triggerDelayEnded,+    setTreshold,+    getTreshold,+    setDelayAfterTrigger,+    getDelayAfterTrigger,+    setOscDecimationRaw,+    getOscDecimationRaw,+    OscDecimation(..),+    setOscDecimation,+    getOscWpCurrent,+    getOscWpTrigger,+    getOscHysteresis,+    setOscHysteresis,+    enableOscDecimationAvarage,+    setEqualFilter,+    getEqualFilter,+    setAxiLowerAddress,+    getAxiLowerAddress,+    setAxiUpperAddress,+    getAxiUpperAddress,+    setAxiDelayAfterTrigger,+    getAxiDelayAfterTrigger,+    enableAxiMaster,+    getAxiWritePtrTrigger,+    getAxiWritePtrCurrent,+    getOscBuffer,+    -- * Arbitrary Signal Generator (ASG)+    getAsgOption,+    setAsgOption,+    setAsgOptionBExtGatRep,+    getAsgOptionBExtGatRep,+    setAsgAmplitudeScale,+    setAsgAmplitudeOffset,+    setAsgCounterWrap,+    setAsgCounterStartOffset,+    setAsgCounterStep,+    getAsgCounterReadPtr,+    setAsgCounterReadPtr,+    getAsgNumReadCycles,+    setAsgNumReadCycles,+    getAsgNumRepetitions,+    setAsgNumRepetitions,+    getAsgBurstDelay,+    setAsgBurstDelay,+    -- * Plumbing+    -- | low level functions for direct Fpga access, used to extend interface+    Page,+    Offset,+    fpgaRead,+    fpgaWrite,+    fpgaFmap,+    pokeFpgaArray,+    peekFpgaArray+)   +where++import Foreign.C.Types+import Foreign.Ptr+import Foreign.Marshal.Array+import System.Posix.IO+import Data.Int+import Data.Word+import Data.Bits+import Foreign.Storable++import Control.Monad+import Control.Applicative+import Control.Monad.State  ++++fpgaPageSize = 0x100000+fpgaMapSize = 0x100000 * 8+addrAms = 0x40000000++type FpgaPtr = Ptr ()+type FpgaState = FpgaPtr++-- | type representing fpga memory offset from page+type Offset = Int+-- | type representing fpga memory page+type Page = Int+-- | type representing fpga registry+type Registry = Word32+-- | Fpga monad is hidden behind this type+type StateMonad a = StateT FpgaState IO  a++-- | Environment where one can read and write Fpga registries+newtype Fpga a = Fpga (StateMonad a) +    deriving (Functor,Applicative, Monad,MonadIO, MonadFix, MonadPlus, Alternative)++-- | Redpitaya Channel A or B.+data Channel = A | B++getStateType :: Fpga a -> StateMonad a+getStateType (Fpga s) = s ++-- Constructor+fpgaState a = Fpga ( StateT a )++runFpga :: Fpga a -> FpgaState -> IO (a,FpgaState) +runFpga (Fpga s) = runStateT s++store ::  FpgaState -> Fpga ()+store v = fpgaState $ \x -> ( return ((),v) )++getState :: Fpga FpgaState+getState = fpgaState $  \x -> ( return  (x,x) )++getPtr :: Fpga FpgaPtr+getPtr = getState+++-- | This function handles initialising Fpga memory mapping and+-- evaluates 'Fpga' action.+withOpenFpga :: Fpga a -> IO a+withOpenFpga act = do+    fd <- openFd  "/dev/mem" ReadWrite Nothing defaultFileFlags+    setFdOption fd SynchronousWrites True+    p <- mmap nullPtr fpgaMapSize (c'PROT_READ + c'PROT_WRITE ) c'MAP_SHARED (fromIntegral fd) addrAms+    (r,s) <- runFpga act p+    munmap p fpgaMapSize+    return r+++-- | get raw pointer on fpga registry calculated from page, offset +-- and internal state that holds memory mapped pointer+getOffsetPtr :: Page -> Offset -> Fpga (Ptr Registry)+getOffsetPtr page offset = +    -- offset on getPtr +    (\memmap -> plusPtr memmap (page * fpgaPageSize + offset)) <$> getPtr+++-- | direct read from fpga registry+fpgaRead :: Page -> Offset -> Fpga Registry+fpgaRead page offset = do+    p <- getOffsetPtr page offset+    liftIO $ peek p++-- | direct write in fpga registry+fpgaWrite :: Page ->  Offset -> Registry -> Fpga ()+fpgaWrite page offset reg = do+    p <- getOffsetPtr page offset+    liftIO $ poke p reg++-- | apply transformation on fpga registry value +fpgaFmap :: Page ->  Offset -> (Registry -> Registry) -> Fpga ()+fpgaFmap page offset f = do+    reg <- fpgaRead page offset+    fpgaWrite page offset (f reg)++-- | write array in fpga memory+pokeFpgaArray :: Page -> Offset -> [Registry] -> Fpga ()+pokeFpgaArray page offset xs =  do+    p <- getOffsetPtr page offset+    liftIO $ pokeArray p xs++-- | read array from fpga memory, passing page, offset and length+peekFpgaArray :: Page -> Offset -> Int -> Fpga [Registry]+peekFpgaArray page offset len = do+    p <- getOffsetPtr page offset+    liftIO $ peekArray len p++++---------------------------------------------------------+-- * Housekeeping memory map++-- | get ID ,  0 prototype , 1 release+fpgaId :: Fpga Registry+fpgaId = fpgaRead 0 0++-- | get DNA+dna :: Fpga Integer+dna = do+    dna1 <- fromIntegral <$> fpgaRead 0 4+    dna2 <- fromIntegral <$> fpgaRead 0 8+    return $ dna1 + (2^32)*dna2++-- | set expansion connector direction P registry+--+-- 1 out , 0 in  +setExpDirP :: Registry -> Fpga ()+setExpDirP = fpgaWrite 0 0x10++-- | get expansion connector direction P registry+--+-- 1 out , 0 in +getExpDirP :: Fpga Registry+getExpDirP = fpgaRead 0 0x10++-- | set expansion connector direction N registry+--+-- 1 out , 0 in +setExpDirN :: Registry -> Fpga ()+setExpDirN = fpgaWrite 0 0x14++-- | get expansion connector direction N registry+--+-- 1 out , 0 in +getExpDirN :: Fpga Registry+getExpDirN = fpgaRead 0 0x14++-- | expansion connector  P output registry value+setExpOutP :: Registry -> Fpga ()+setExpOutP = fpgaWrite 0 0x18++-- | expansion connector  P output registry value+getExpOutP :: Fpga Registry+getExpOutP = fpgaRead 0 0x18++-- | expansion connector  N output registry value+setExpOutN :: Registry -> Fpga ()+setExpOutN = fpgaWrite 0 0x1C++-- | expansion connector  N output registry value+getExpOutN :: Fpga Registry+getExpOutN = fpgaRead 0 0x1C++-- | expansion connector  P input registry value+getExpInP :: Fpga Registry+getExpInP =  fpgaRead 0 0x20++-- | expansion connector  N input registry value+getExpInN :: Fpga Registry+getExpInN =  fpgaRead 0 0x24++-- | type of gpio can be either P on N+data GpioType =+    -- | P gpio+    P | +    -- | N gpio+    N+    deriving (Show)++class ToBool b where +    toBool :: b -> Bool ++setBitValue :: (Bits a,ToBool b) => b -> Int  -> a -> a+setBitValue b+    | toBool b = flip setBit+    | otherwise = flip clearBit++-- | represent gpio direction, that can be either Input or Output+data GpioDirection =+    Input | +    Output+    deriving (Show)++instance ToBool GpioDirection where+    toBool Input = True+    toBool Output = False+++-- | type representing pin number+type PinNum = Int++-- | Sets direction of pin+setExpDir :: GpioType -> GpioDirection -> PinNum ->  Fpga ()+setExpDir N d p = setBitValue d p <$> getExpDirN  >>= setExpDirN+setExpDir P d p = setBitValue d p <$> getExpDirP  >>= setExpDirP+++-- | represent gpio value that can be either Hi or Low +data GpioValue =+    Low | +    Hi+    deriving (Show)++instance ToBool GpioValue where+    toBool Low = False+    toBool Hi = True++-- | Sets outout value of pin+setExpOut :: GpioType -> GpioValue -> PinNum ->  Fpga ()+-- read using getExpOutN , fmap over setBitValue and bind in setExpOutX+setExpOut N v p = setBitValue v p <$> getExpOutN  >>= setExpOutN+setExpOut P v p = setBitValue v p <$> getExpOutP  >>= setExpOutP+++toGpioValue :: Bool -> GpioValue+toGpioValue True = Hi+toGpioValue False = Low++-- | Sets output value of single pin+getExpOut :: GpioType  -> PinNum ->  Fpga GpioValue+getExpOut N p = (\x -> toGpioValue ( testBit x p )) <$> getExpOutN+getExpOut P p = (\x -> toGpioValue ( testBit x p )) <$> getExpOutP++-- | write in led registry+setLed :: Registry -> Fpga ()+setLed = fpgaWrite 0 0x30++-- | read in led registry+getLed :: Fpga Registry+getLed = fpgaRead 0 0x30++---------------------------------------+-- * Oscilloscope++osciloscpeFpgaPage :: Int+osciloscpeFpgaPage = 1++fpgaWriteOsc = fpgaWrite osciloscpeFpgaPage+fpgaReadOsc = fpgaRead osciloscpeFpgaPage+++-- | reset write state machine for oscilloscope+resetWriteSM :: Fpga ()+resetWriteSM = fpgaWriteOsc 0 2++-- | start writing data into memory (ARM trigger).+triggerNow :: Fpga ()+triggerNow = fpgaWriteOsc 0 1++-- | oscilloscope trigger selection+data TriggerSource = +    -- | trig immediately+    Immediately  +    -- | ch A threshold positive edge+    | ChAPositiveEdge +    -- | ch A threshold negative edge+    | ChANegativeEdge +    -- | ch B threshold positive edge+    | ChBPositiveEdge +    -- | ch B threshold negative edge+    | ChBNegativeEdge +    -- | external trigger positive edge - DIO0_P pin+    | ExtPositiveEdge +    -- | external trigger negative edge+    | ExtNegaitveEdge +    -- | arbitrary wave generator application positive edge+    | AWGPositiveEdge +    -- | arbitrary wave generator application negative edge+    | AWGNegativeEdge +    deriving (Show)++-- | set oscilloscope trigger+setOscTrigger :: TriggerSource -> Fpga ()+setOscTrigger Immediately     = setOscTriggerHelper 1+setOscTrigger ChAPositiveEdge = setOscTriggerHelper 2+setOscTrigger ChANegativeEdge = setOscTriggerHelper 3+setOscTrigger ChBPositiveEdge = setOscTriggerHelper 4+setOscTrigger ChBNegativeEdge = setOscTriggerHelper 5+setOscTrigger ExtPositiveEdge = setOscTriggerHelper 6+setOscTrigger ExtNegaitveEdge = setOscTriggerHelper 7+setOscTrigger AWGPositiveEdge = setOscTriggerHelper 8+setOscTrigger AWGNegativeEdge = setOscTriggerHelper 9+++setOscTriggerHelper :: Registry -> Fpga ()+setOscTriggerHelper = fpgaWriteOsc 0x4+++-- | when trigger delay is value becomes 'True'+triggerDelayEnded :: Fpga Bool+triggerDelayEnded = (==0) <$> fpgaReadOsc 0x4++-- | Ch x threshold, makes trigger when ADC value cross this value+setTreshold :: Channel -> Registry -> Fpga ()+setTreshold A = fpgaWriteOsc 0x8+setTreshold B = fpgaWriteOsc 0xc++-- | gets ch x threshold+getTreshold :: Channel -> Fpga Registry+getTreshold A = fpgaReadOsc 0x8+getTreshold B = fpgaReadOsc 0xc++-- | Number of decimated data after trigger written into memory+setDelayAfterTrigger :: Registry -> Fpga ()+setDelayAfterTrigger = fpgaWriteOsc 0x10++-- | gets delay after trigger value+getDelayAfterTrigger :: Fpga Registry+getDelayAfterTrigger = fpgaReadOsc 0x10++-- | sets oscilloscope decimation registry, allows only+-- 1,8, 64,1024,8192,65536. If other value is written data will NOT be correct.+setOscDecimationRaw :: Registry -> Fpga ()+setOscDecimationRaw =  fpgaWriteOsc 0x14++-- | oscilloscope decimation registry value+getOscDecimationRaw :: Fpga Registry+getOscDecimationRaw =  fpgaReadOsc 0x14++-- | oscilloscope decimation+data OscDecimation = +    OscDec1  +    | OscDec8+    | OscDec64 +    | OscDec1024+    | OscDec8192+    | OscDec65536+    deriving (Show)++-- | set oscilloscope decimation+setOscDecimation :: OscDecimation -> Fpga ()+setOscDecimation OscDec1 = setOscDecimationRaw 1+setOscDecimation OscDec8 = setOscDecimationRaw 8+setOscDecimation OscDec64 = setOscDecimationRaw 64+setOscDecimation OscDec1024 = setOscDecimationRaw 1024+setOscDecimation OscDec8192 = setOscDecimationRaw 8192+setOscDecimation OscDec65536 = setOscDecimationRaw 65536++-- | write pointer - current+getOscWpCurrent:: Fpga Registry+getOscWpCurrent = fpgaReadOsc 0x18++-- | write pointer - trigger+getOscWpTrigger :: Fpga Registry+getOscWpTrigger = fpgaReadOsc 0x1C++-- | ch x hysteresis+getOscHysteresis :: Channel -> Fpga Registry+getOscHysteresis A = fpgaReadOsc 0x20+getOscHysteresis B = fpgaReadOsc 0x24++-- | set ch x hysteresis+setOscHysteresis :: Channel -> Registry -> Fpga ()+setOscHysteresis A = fpgaWriteOsc 0x20+setOscHysteresis B = fpgaWriteOsc 0x24++-- | Enable signal average at decimation True enables, False disables+enableOscDecimationAvarage :: Bool -> Fpga ()+enableOscDecimationAvarage True = fpgaWriteOsc 0x28 1+enableOscDecimationAvarage False = fpgaWriteOsc 0x28 0++-- | set ch A equalization filter, takes array with coefficients [AA,BB,KK,PP]+setEqualFilter :: Channel -> [Registry] -> Fpga ()+setEqualFilter A = pokeFpgaArray osciloscpeFpgaPage 0x30 . take 4+setEqualFilter B = pokeFpgaArray osciloscpeFpgaPage 0x40 . take 4++-- | get ch x equalization filter, return array with coefficients [AA,BB,KK,PP]+getEqualFilter :: Channel -> Fpga [Registry]+getEqualFilter A = peekFpgaArray osciloscpeFpgaPage 0x30 4+getEqualFilter B = peekFpgaArray osciloscpeFpgaPage 0x40 4+++setAxiGeneric' :: Offset -> Channel -> Registry -> Fpga ()+setAxiGeneric' offest A = fpgaWriteOsc offest+setAxiGeneric' offest B = fpgaWriteOsc (offest+0x20)++getAxiGeneric' :: Offset -> Channel -> Fpga Registry+getAxiGeneric' offest A = fpgaReadOsc offest+getAxiGeneric' offest B = fpgaReadOsc (offest+0x20)+++-- | starting writing address ch x - CH x AXI lower address+setAxiLowerAddress :: Channel -> Registry -> Fpga ()+setAxiLowerAddress = setAxiGeneric' 0x50++-- | read - starting writing address ch x - CH x AXI lower address+getAxiLowerAddress :: Channel ->  Fpga Registry+getAxiLowerAddress = getAxiGeneric' 0x50++-- | starting writing address ch x - CH x AXI lower address+setAxiUpperAddress :: Channel ->  Registry -> Fpga ()+setAxiUpperAddress = setAxiGeneric' 0x54++-- | read - starting writing address ch x - CH x AXI lower address+getAxiUpperAddress :: Channel ->  Fpga Registry+getAxiUpperAddress = getAxiGeneric' 0x54++-- | read - Number of decimated data after trigger written into memory+getAxiDelayAfterTrigger :: Channel -> Fpga Registry+getAxiDelayAfterTrigger = getAxiGeneric' 0x58++-- | set umber of decimated data after trigger written into memory+setAxiDelayAfterTrigger :: Channel -> Registry -> Fpga ()+setAxiDelayAfterTrigger = setAxiGeneric' 0x58++-- | Enable AXI master+enableAxiMaster :: Channel -> Bool -> Fpga ()+enableAxiMaster ch True = setAxiGeneric' 0x5c ch 1+enableAxiMaster ch False = setAxiGeneric' 0x5c ch 0++-- | Write pointer for ch x at time when trigger arrived+getAxiWritePtrTrigger :: Channel -> Fpga Registry+getAxiWritePtrTrigger = getAxiGeneric' 0x60++-- | current write pointer for ch x+getAxiWritePtrCurrent :: Channel -> Fpga Registry+getAxiWritePtrCurrent = getAxiGeneric' 0x64+++-- | reads oscilloscope buffer for channel x from Fpga passing offset and length. +-- buffer should fit within 16k sampling range.+-- Returns  less than requested data if trying to read over the bounds.+getOscBuffer :: Channel -> Offset -> Int -> Fpga [Registry]+getOscBuffer chan off len = peekFpgaArray osciloscpeFpgaPage (off' + (chOff chan)) len'+                          where+                            off' = max 0 off+                            len' = min (0x10000 - off) len+                            chOff A = 0x10000 +                            chOff B = 0x20000++--------------------------------------------------------------------++-- ASG+-- | Set registry with value passed as tuple of bit offests+-- | setBits (fromBit,toBit) value rin = ..+setBits :: (Int,Int) -> Registry -> Registry -> Registry+setBits (fromBit,toBit) value rin = valueShift .|. hole+    where +        ones = complement 0 :: Registry+        maskShift = xor (shiftL ones fromBit) (shiftL ones (toBit+1))  +        hole = complement maskShift .&. rin+        valueShift = ( shiftL value fromBit ) .&. maskShift++-- | read bits  range from registy+getBits :: (Int,Int) -> Registry -> Registry+getBits (fromBit,toBit) value = shiftR andV fromBit+    where+        ones = complement 0 :: Registry+        maskShift = xor (shiftL ones fromBit) (shiftL ones (toBit+1))  +        andV = maskShift .&. value+++type FpgaSet = Registry -> Fpga ()+type FpgaGet = Fpga Registry ++asgFpgaPage = 2+++fpgaWriteAsg :: Offset -> Registry -> Fpga ()+fpgaWriteAsg = fpgaWrite asgFpgaPage++fpgaReadAsg :: Offset -> Fpga Registry+fpgaReadAsg = fpgaRead asgFpgaPage++fpgaFmapAsg :: Offset -> (Registry -> Registry) -> Fpga ()+fpgaFmapAsg = fpgaFmap asgFpgaPage++fpgaWriteAsgChannel :: Offset -> Channel -> Registry -> Fpga ()+fpgaWriteAsgChannel offset A = fpgaWriteAsg   offset+fpgaWriteAsgChannel offset B = fpgaWriteAsg ( offset + 0x20)++fpgaReadAsgChannel :: Offset -> Channel -> Fpga Registry+fpgaReadAsgChannel offset A = fpgaReadAsg   offset+fpgaReadAsgChannel offset B = fpgaReadAsg ( offset + 0x20)++fpgaFmapAsgChannel :: Offset -> (Registry -> Registry) -> Channel -> Fpga ()+fpgaFmapAsgChannel offset f A = fpgaFmapAsg   offset f+fpgaFmapAsgChannel offset f B = fpgaFmapAsg ( offset + 0x20) f+++-- | get ASGoption registry+getAsgOption :: Fpga Registry+getAsgOption = fpgaReadAsg 0x0++-- | set ASG option registry+setAsgOption :: Registry -> Fpga ()+setAsgOption = fpgaWriteAsg 0x0+++-- | ch B external gated repetitions, +-- registry can be either 0x0 or 0x1+setAsgOptionBExtGatRep :: Registry -> Fpga ()+setAsgOptionBExtGatRep reg = fpgaFmapAsg 0 ( setBits (24,24) reg)++-- | get ch B external gated repetitions, +-- registry can be either 0x0 or 0x1+getAsgOptionBExtGatRep :: Fpga Registry+getAsgOptionBExtGatRep =  getBits (24,24) <$> getAsgOption++-- | TODO others++-- | todo other registries++-- | Ch x amplitude scale (14 bist) - out = (data*scale)/0x2000 + offset+setAsgAmplitudeScale :: Channel -> Registry -> Fpga ()+setAsgAmplitudeScale ch reg = fpgaFmapAsgChannel 0x4 ( setBits (16,29) reg ) ch++-- | Ch x amplitude offset (14 bits) - out  = (data*scale)/0x2000 + offset +setAsgAmplitudeOffset :: Channel -> Registry -> Fpga ()+setAsgAmplitudeOffset ch reg = fpgaFmapAsgChannel 0x4 ( setBits (0,13) reg ) ch++-- | Ch x counter wrap - Value where counter wraps around. Depends on SM wrap setting. +-- If it is 1 new value is  get by wrap, if value is 0 counter goes to offset value.+-- 16 bits for decimals.+setAsgCounterWrap :: Channel -> Registry -> Fpga ()+setAsgCounterWrap = fpgaWriteAsgChannel  0x8+++-- | Ch x Counter start offset. Start offset when trigger arrives. 16 bits for decimals.+setAsgCounterStartOffset :: Channel -> Registry -> Fpga ()+setAsgCounterStartOffset = fpgaWriteAsgChannel 0xc++-- | Ch x counter step. 16 bits for decimals.+setAsgCounterStep :: Channel -> Registry -> Fpga ()+setAsgCounterStep = fpgaWriteAsgChannel 0x10++-- | get ch x buffer current read pointer+getAsgCounterReadPtr :: Channel -> Fpga Registry+getAsgCounterReadPtr = fpgaReadAsgChannel 0x14++-- | set ch x buffer current read pointer+setAsgCounterReadPtr :: Channel -> Registry -> Fpga ()+setAsgCounterReadPtr = fpgaWriteAsgChannel 0x14++-- | get ch x number of read cycles in one burst+getAsgNumReadCycles :: Channel -> Fpga Registry+getAsgNumReadCycles = fpgaReadAsgChannel 0x18++-- | set ch x number of read cycles in one burst+setAsgNumReadCycles :: Channel -> Registry -> Fpga ()+setAsgNumReadCycles = fpgaWriteAsgChannel 0x18++-- | get ch x number of read cycles in one burst+getAsgNumRepetitions :: Channel -> Fpga Registry+getAsgNumRepetitions = fpgaReadAsgChannel  0x1a++-- | set ch x number of read cycles in one burst+setAsgNumRepetitions :: Channel -> Registry -> Fpga ()+setAsgNumRepetitions = fpgaWriteAsgChannel 0x1a++-- | get ch x delay between burst repetitions, granularity=1us+getAsgBurstDelay :: Channel -> Fpga Registry+getAsgBurstDelay = fpgaReadAsgChannel 0x20++-- | set ch x delay between burst repetitions, granularity=1us+setAsgBurstDelay :: Channel -> Registry -> Fpga ()+setAsgBurstDelay = fpgaWriteAsgChannel 0x20++---------- mmap bindings++foreign import ccall "mmap" mmap+  :: Ptr () -> CSize -> CInt -> CInt-> CInt-> CInt -> IO (Ptr ())++foreign import ccall "munmap" munmap+  :: Ptr () -> CSize -> IO CInt++c'PROT_EXEC = 4+c'PROT_NONE = 0+c'PROT_READ = 1+c'PROT_WRITE = 2+c'MAP_FIXED = 16+c'MAP_PRIVATE = 2+c'MAP_SHARED = 1+c'MAP_FAILED = wordPtrToPtr 4294967295++        
+ src/System/RedPitaya/Tutorial.hs view
@@ -0,0 +1,130 @@+++-- | +module System.RedPitaya.Tutorial (+{-| +== tutorial for System.Readpitaya Libraray+#tutorial-for-system.readpitaya-libraray#++System.Readpitaya is native haskell library for+<http://redpitaya.com/ redpitaya> that enables direct bindings on+<https://github.com/RedPitaya/RedPitaya/blob/master/fpga/doc/RedPitaya_HDL_memory_map.odt?raw=true FPGA>.+This library is aimed to run on redpitaya and is inteded for use with+crosscompiler.++To build and run code and examples you need cross-ghc compiler for armel+processor.++Here it is simpel an minimal example to use library++> import System.RedPitaya.Fpga+>+> main = withOpenFpga (setLed 0x55) ++withOpenFpga is function, that takes Fpga operation and executes it. It+handels opening and closing of FPGA resources so it is advisable that+that all operation are executed inside and @withOpenFpga@ gets called+only once.++If you take look of prototype setLed you can see that it has protype+@setLed :: Registry -> Fpga ()@ And that can be understand that it takes+@Registy@ (that is 32 bit unsigned integer) and returns @Fpga ()@.+@Fpga a@ is type that can run in @withOpenFpga@ function. @()@ is empty+or void value that is retured after @setLed@ gets called. What @setLed@+does it takes writes registry value at apropriate addres in fpga+registry map described in document FPGA metioned in first section.++In our next example we will build program that displays value that is+written in this registry using function @getLed@++> import System.RedPitaya.Fpga+> import Numeric (showHex)+>+> main = do+>     reg <- withOpenFpga getLed+>     putStrLn ( show reg)++here @reg@ is value can get \"get\" from @withOpenFpga@. Function+@withOpenFpga@ has prototype of \'Fpga a -> IO a\'. That mean that+returns same value as it is returned from executing last command+executed in block. In our case that is just function @getLed@. Since+@getLed :: Fpga Registry@ that mean that ir returns @Fpga Registry@+type.++@IO Registry@ (@a@ in definition of @withOpenFpga@ becomes @Registry@).+We haven\'t mentioned @IO a@ before but that is type one can execute+commands like @putStrLn@ with.++> import System.RedPitaya.Fpga+> import Numeric (showHex)+>+> main = do+>     reg <- withOpenFpga ( do+>                             setLed 0x44+>                             r <- getLed+>                             return r+>                         )+>     putStrLn ( show reg )++This code runs two @do@ blocks. One handles IO type where types @IO a@+are running and other do block with type \'Fpga a\'. If one needs to run+IO types inside Fpga block he\/she needs to change IO type to Fpga type+using function liftIO.++> import System.RedPitaya.Fpga+> import Numeric (showHex)+> import Control.Monad.IO.Class (liftIO)+>+> main = do+>     withOpenFpga $ do+>             setLed 0x44+>             reg <- getLed +>             liftIO $ putStrLn $ show reg+>     putStrLn "done"++In this example we also use build in operator @$@ that works as a+brackets to to the end.++> liftIO $ putStrLn $ showHex reg "" +> -- is same as+> liftIO ( putStrLn ( showHex reg "" ))++If you like to know more about operator @$@ or any other standard+functions used, you can use invaluable search engine+<https://www.haskell.org/hoogle/?hoogle=%24 Hoogle> where is link on+haddock manuals with description and link to source code. Similar search+engines are also availabe at <http://hayoo.fh-wedel.de/ Hayoo!> and+<https://www.stackage.org/ Stackage>.++Lets do some more tricks with diodes and using standard++> import System.RedPitaya.Fpga+> import Control.Concurrent (threadDelay)+> import Data.Bits+> import Control.Monad.IO.Class (liftIO)+>+> knightRider n = do+>     let ledn = 1 + abs ((mod n 12) - 6) -- 6,5,4,3,2,1,2,3,4,5,6,7,6,5,4,3,2,1,2,3,4,5,6,7,6,5...+>     setLed ( shiftL 1 ledn )+>     liftIO ( threadDelay (30000) )+>     knightRider (n + 1)+>+> main = withOpenFpga (knightRider 0)++@knightRider@ is function that gets caled each time with next+integer.@ledn@ in generated in way that provides numbering in apropriate+order. shiftL function . Next @threadDelay@ delays execution, by 30000+microseconds and since @nightRider@ runs inside @withOpenFpga@ we have+to use @liftIO@ just to make type compatible. Finaly we call+@nightRider@ with next number and whole procees repeats.++So far we covered lot if of stuff on how to use this library. Even+though all examples were reading and writing to led registry you can be+sure that all function provided by library that has type signature+@Registry -> Fpga ()@ works and can be used just like @setLed@ and all+functions with type signature @Fpga Registry@ works like getLed.++-} +)+where+import System.RedPitaya.Fpga