1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
--
-- Blink a LED on the Arduino Duemilanove using IDE libs from Atom/Haskell.
-- June 2010
-- By Lee Pike  (remove spaces)
-- BSD3
-- 

module Main where

import Language.Atom
import Language.Atom.Scheduling
import Data.Word

atomName = "blink"

-- | Invoke the Atom compiler.
main :: IO ()
main = do
  (schedule, _, _, _, _) <- compile atomName defaults { cCode = prePostCode } blink
  putStrLn $ reportSchedule schedule


varInit :: Type -> String -> String -> String
varInit t var val = cType t ++ " " ++ var ++ " = " ++ val ++ ";"

prePostCode :: [Name] -> [Name] -> [(Name, Type)] -> (String, String)
prePostCode _ _ _ =
    (unlines
    [ (varInit Int16 "ledPin" "13")
    , "void avr_blink(void);"
    ]
    , unlines
    [
      "void setup()   {"
    , "  // initialize the digital pin as an output:"
    , "  pinMode(ledPin, OUTPUT);"
    , "}"
    , ""
    , "void avr_blink() {"
    , "  digitalWrite(ledPin, state." ++ atomName ++ ".on);"
    , "}   // set the LED on or off"
    , ""
    , "void loop() {"
    ,  "  " ++ atomName ++ "();"
    , "}"
    ]
    )

-- How many cycles is a phase?
ph :: Int
ph = 40000

-- Simple Atom to toggle an LED, leaving it on 8 times as long as it's off.
blink :: Atom ()
blink = do
  on <- bool "on" True

  period ph $ phase 0 $ atom "blinkOn" $ do
    call "avr_blink"
    on <== not_ (value on)

  period ph $ phase (quot ph 8) $ atom "blinkOff" $ do
    call "avr_blink"
    on <== not_ (value on)