packages feed

atom-msp430 (empty) → 0.5.0

raw patch · 9 files changed

+271/−0 lines, 9 filesdep +atomdep +basedep +mtlsetup-changed

Dependencies added: atom, base, mtl

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2013 Daniel Buckmaster
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+ Language/Atom/MSP430.hs view
@@ -0,0 +1,16 @@+module Language.Atom.MSP430 (
+    module Language.Atom,
+    module Language.Atom.MSP430.Watchdog,
+    module Language.Atom.MSP430.DigitalIO,
+    module Language.Atom.MSP430.TimerA,
+    module Language.Atom.MSP430.Interrupts,
+    module Language.Atom.MSP430.Compile
+ ) where
+
+import Language.Atom
+import Language.Atom.MSP430.Watchdog
+import Language.Atom.MSP430.DigitalIO
+import Language.Atom.MSP430.TimerA
+import Language.Atom.MSP430.Interrupts
+import Language.Atom.MSP430.Compile
+
+ Language/Atom/MSP430/Compile.hs view
@@ -0,0 +1,133 @@+module Language.Atom.MSP430.Compile (
+    MSP430Compilation (..),
+    mspProgram, wiringProgram, simpleProgram, energiaProgram,
+    mspCompile
+ ) where
+
+import Language.Atom
+import Control.Monad
+import System.IO
+
+-- | Program information. It specifies the functions that should be used in specific
+--   roles in the compiled code, as well as other configuration information.
+data MSP430Compilation = MSP430Compilation {
+    setupFn :: Maybe (Atom ()),           -- ^ Function called once when the MCU starts up.
+    setupFnName :: String,                -- ^ Name of the setup function in the generated code.
+    loopFn :: Maybe (Atom ()),            -- ^ Function called in a busy loop after setup.
+    loopFnName :: String,                 -- ^ Name of the loop function in the generated code.
+    timerAISR :: Maybe (Atom ()),         -- ^ Function to run when a TimerA CCR interrupt happens.
+    timerAISRName :: String,              -- ^ Name of the TimerA interrupt function in the generated code.
+    watchdogISR :: Maybe (Atom ()),       -- ^ Function to call when the WDT interrupts.
+    watchdogISRName :: String,            -- ^ Name of the WDT interrupt function in the generated code.
+    port1ISR :: Maybe (Atom ()),          -- ^ Function to call when there is a PORT1 interrupt.
+    port1ISRName :: String,               -- ^ Name of the PORT1 interrupt function.
+    port2ISR :: Maybe (Atom ()),          -- ^ Function to call when there is a PORT2 interrupt.
+    port2ISRName :: String,               -- ^ Name of the PORT2 interrupt function.
+    mainFile :: String,                   -- ^ Name of the main file to generate.
+    emitMainFn :: Bool                    -- ^ Add a main function calling setup and loop?
+ }
+
+-- | Default program to construct your own programs from. Contains Nothing and generates a
+--   basic main.c. Use it by overriding the functions it generates, and optionally their names.
+mspProgram = MSP430Compilation {
+    setupFn = Nothing,
+    setupFnName = "setup",
+    loopFn = Nothing,
+    loopFnName = "loop",
+    timerAISR = Nothing,
+    timerAISRName = "timerAISR",
+    watchdogISR = Nothing,
+    watchdogISRName = "wdtISR",
+    port1ISR = Nothing,
+    port1ISRName = "p1ISR",
+    port2ISR = Nothing,
+    port2ISRName = "p2ISR",
+    mainFile = "main.c",
+    emitMainFn = True
+ }
+
+-- | Easy settings for a Wiring-style program with setup and loop functions. Expects a device extension
+--   for header files - i.e. running with "g2231" wihh generate files that #include "msp430g2231.h"
+wiringProgram s l = mspProgram {
+    setupFn = Just s,
+    loopFn = Just l
+ }
+
+-- | Easy settings for a program with just a setup function.
+simpleProgram s = mspProgram {
+    setupFn = Just s
+ }
+
+-- | Easy settings for a program with setup and loop, but no main function.
+energiaProgram s l = mspProgram {
+    setupFn = Just s,
+    loopFn = Just l,
+    emitMainFn = False
+ }
+
+-- | Compile a program given by the compilation specification. Compiles all functions into library files
+--   and then generates a main file which calls these functions in the appropriate way.
+mspCompile :: String -> MSP430Compilation -> IO ()
+mspCompile h c = do
+    let headers = unlines $ map (\h -> "#include \"msp430" ++ h ++ ".h\"") [h]
+    let compile' = maybeCompile defaults {
+        cRuleCoverage = False,
+        cAssert = False,
+        cCode = \_ _ _ -> (headers, "")
+     }
+    compile' (setupFnName c) (setupFn c)
+    compile' (loopFnName c) (loopFn c)
+    compile' (timerAISRName c) (timerAISR c)
+    compile' (watchdogISRName c) (watchdogISR c)
+    compile' (port1ISRName c) (port1ISR c)
+    compile' (port2ISRName c) (port2ISR c)
+    putStrLn $ "Generating " ++ mainFile c ++ "..."
+    hFlush stdout
+    withFile (mainFile c) WriteMode $ \h -> do
+        let put = hPutStrLn h
+        let header' = maybeHeader h
+        let interrupt' = maybeInterrupt h
+        header' (setupFnName c) (setupFn c)
+        header' (loopFnName c) (loopFn c)
+        header' (timerAISRName c) (timerAISR c)
+        header' (watchdogISRName c) (watchdogISR c)
+        header' (port1ISRName c) (port1ISR c)
+        header' (port2ISRName c) (port2ISR c)
+        when (emitMainFn c) $ do
+            put headers
+            put "\nint main(void) {"
+            case setupFn c of
+                Just f -> put $ "    " ++ setupFnName c ++ "();"
+                Nothing -> return ()
+            case loopFn c of
+                Just f -> put $ "    while(1) " ++ loopFnName c ++ "();"
+                Nothing -> return ()
+            put "    return 0;"
+            put "}\n"
+        interrupt' (watchdogISR c) (watchdogISRName c) "WDT_VECTOR"
+        interrupt' (timerAISR c)   (timerAISRName c)   "TIMERA0_VECTOR"
+        interrupt' (port1ISR c)    (port1ISRName c)    "PORT1_VECTOR"
+        interrupt' (port2ISR c)    (port2ISRName c)    "PORT2_VECTOR"
+    return ()
+
+maybeCompile s n f = case f of
+    Nothing -> return ()
+    Just fn -> do
+        putStrLn $ "Compiling " ++ n ++ "..."
+        hFlush stdout
+        compile n s fn
+        return ()
+
+maybeHeader h header f = case f of
+    Just _ -> hPutStrLn h $ "#include \"" ++ header ++ ".h\""
+    Nothing -> return ()
+
+maybeInterrupt h a n v = case a of
+    Just _ -> do
+        let put = hPutStrLn h
+        put $ "#pragma vector=" ++ v
+        put $ "__interrupt void __" ++ n ++ "(void) {"
+        put $ "    " ++ n ++ "();"
+        put   "}\n"
+    Nothing -> return ()
+
+ Language/Atom/MSP430/DigitalIO.hs view
@@ -0,0 +1,24 @@+module Language.Atom.MSP430.DigitalIO where
+
+import Language.Atom
+
+port1In         = word8' "P1IN"  -- ^ Read the value of PORT1 pins when used in input mode.
+port1Out        = word8' "P1OUT" -- ^ Set the values of PORT1 pins when used in output mode.
+port1Dir        = word8' "P1DIR" -- ^ Choose the input/output modes of PORT1 pins (1 = output).
+port1Resistors  = word8' "P1REN" -- ^ Enable pullup/pulldown resistors of PORT1 pins.
+port1Function   = word8' "P1SEL" -- ^ 
+
+port1InterruptEnable = word8' "P1IE"      -- ^ Enable interrupts for PORT1 pins in input mode.
+port1InterruptFlags  = word8' "P1IFG"     -- ^ Interrupt flags for PORT1 pins. A flag is set when an interrupt occurs; you should clear it manually.
+port1InterruptEdgeSelect = word8' "P1IES" -- ^ Interrupt edge select: if set to 1, the pin responds to a falling edge.
+
+port2In         = word8' "P2IN"  -- ^ Read the value of PORT2 pins when used in input mode.
+port2Out        = word8' "P2OUT" -- ^ Set the values of PORT2 pins when used in output mode.
+port2Dir        = word8' "P2DIR" -- ^ Choose the input/output modes of PORT2 pins (2 = output).
+port2Resistors  = word8' "P2REN" -- ^ Enable pullup/pulldown resistors of PORT2 pins.
+port2Function   = word8' "P2SEL" -- ^ 
+
+port2InterruptEnable = word8' "P2IE"      -- ^ Enable interrupts for PORT2 pins in input mode.
+port2InterruptFlags  = word8' "P2IFG"     -- ^ Interrupt flags for PORT2 pins. A flag is set when an interrupt occurs; you should clear it manually.
+port2InterruptEdgeSelect = word8' "P2IES" -- ^ Interrupt edge select: if set to 2, the pin responds to a falling edge.
+
+ Language/Atom/MSP430/Interrupts.hs view
@@ -0,0 +1,6 @@+module Language.Atom.MSP430.Interrupts where
+
+import Language.Atom
+
+interruptEnable = word8' "IE1"  -- ^ Global interrupt vector.
+interruptFlags  = word8' "IFG1" -- ^ Global interrupt flags.
+ Language/Atom/MSP430/TimerA.hs view
@@ -0,0 +1,25 @@+module Language.Atom.MSP430.TimerA where
+
+import Language.Atom
+import Data.Word
+
+taSource           = 0x0000 :: Word16 -- ^ Source Timer A from TACLK.
+taSourceACLK       = 0x0100 :: Word16 -- ^ Source Timer A from ACLK.
+taSourceSMCLK      = 0x0200 :: Word16 -- ^ Source Timer A from SMCLK.
+taSourceINCLK      = 0x0300 :: Word16 -- ^ Source Timer A from INCLK.
+taClear            = 0x0004 :: Word16 -- ^ Clear Timer A (reset it to 0).
+taInterruptEnabled = 0x0002 :: Word16 -- ^ Enable the Timer A interrupt.
+taStopMode         = 0x0000 :: Word16 -- ^ Stop the timer from counting.
+taUpMode           = 0x0010 :: Word16 -- ^ Timer counts from 0 to TACCR0.
+taContinuousMode   = 0x0020 :: Word16 -- ^ Timer counts from 0 to 0xFFFF.
+taUpDownMode       = 0x0030 :: Word16 -- ^ Timer counts from 0 to TACCR0 to 0.
+taSourceDiv1       = 0x0000 :: Word16 -- ^ Divide timer input source by 1.
+taSourceDiv2       = 0x0040 :: Word16 -- ^ Divide timer input source by 2.
+taSourceDiv4       = 0x0080 :: Word16 -- ^ Divide timer input source by 4.
+taSourceDiv8       = 0x00C0 :: Word16 -- ^ Divide timer input source by 8.
+
+taCCRInterrupt = 0x0010 :: Word16 -- ^ Interrupt on a Timer A CCR.
+
+timerAControl = word16' "TACTL" -- ^ Timer A control register.
+timerACCR0 = word16' "TACCR0"   -- ^ Timer A capture/compare register 0.
+timerACCC0 = word16' "TACCTL0"  -- ^ Timer A capture/compare control register 0.
+ Language/Atom/MSP430/Watchdog.hs view
@@ -0,0 +1,21 @@+module Language.Atom.MSP430.Watchdog where
+
+import Language.Atom
+import Data.Word
+
+wdtPassword      = 0x5A00 :: Word16 -- ^ Password bits to change the waychdog settings. Include this in every write to 'watchdog'.
+wdtHold          = 0x0080 :: Word16 -- ^ Stop the watchdog timer.
+wdtNMIFalling    = 0x0040 :: Word16 -- ^ NMI interrupt on falling edge.
+wdtNMI           = 0x0020 :: Word16 -- ^ NMI interrupt.
+wdtIntervalMode  = 0x0010 :: Word16 -- ^ Use the timer as an interval counter with interrupt.
+wdtClearCounter  = 0x0008 :: Word16 -- ^ Clear the WDT counter when in interval mode.
+wdtUseAuxClock   = 0x0004 :: Word16 -- ^ Source WDT from ACLK.
+wdtSourceDiv15   = 0x0000 :: Word16 -- ^ Divide the timer input by 2^15.
+wdtSourceDiv13   = 0x0001 :: Word16 -- ^ Divide the timer input by 2^13.
+wdtSourceDiv9    = 0x0002 :: Word16 -- ^ Divide the timer input by 2^9.
+wdtSourceDiv6    = 0x0003 :: Word16 -- ^ Divide the timer input by 2^6.
+
+wdtInterruptEnable    = 0x01 :: Word8 -- ^ Enable the WDT interrupt in 'interruptEnable'.
+wdtNMIInterruptEnable = 0x10 :: Word8 -- ^ Enable the WDT's NMI interrupt in 'interruptEnable'.
+
+watchdog = word16' "WDTCTL" -- ^ Watchdog control register.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ atom-msp430.cabal view
@@ -0,0 +1,24 @@+name:                atom-msp430
+version:             0.5.0
+synopsis:            Convenience functions for using Atom with the MSP430 microcontroller family.
+-- description:         
+homepage:            https://github.com/eightyeight/atom-msp430
+license:             MIT
+license-file:        LICENSE
+author:              Daniel Buckmaster
+maintainer:          dan.buckmaster@gmail.com
+-- copyright:           
+category:            Embedded
+build-type:          Simple
+cabal-version:       >=1.8
+
+library
+  exposed-modules:     Language.Atom.MSP430,
+                       Language.Atom.MSP430.Watchdog,
+                       Language.Atom.MSP430.DigitalIO,
+                       Language.Atom.MSP430.TimerA,
+                       Language.Atom.MSP430.Interrupts,
+                       Language.Atom.MSP430.Compile
+  build-depends:       base ==4.5.*,
+                       mtl,
+                       atom >= 1.0.12