We reference the C include file blink.h. This is here to pull in some utility AVR chip utility functions and “stdint.h” (which defines uint8_t and friends). We also prototype the blink_atom function Atom will eventually define. We’ll go over what to do with this in just a bit.

Next we define main:

-- Main just has to compile the Atom expression
main :: IO ()
main = compile "blink_atom" (Just cfg) blink

Remember that the version of compile used here is not the version included with atom-0.0.2. This is the altered version we discussed earlier.

The first argument tells Atom what to name the top level function–in this case, blink_atom. You’ll notice that this was the function prototyped in blink.h. Secondly, we pass the config we just defined. If one does not wish to define any include files or override the default C types, it’s perfectly fine to pass Nothing here instead–the defaults will be used.

The last argument, blink, is the name of the Atom ()–the type used to describe our system–we’re about to define.

cond acts as a guard. It ensures that the boolean statement passed to it is true before allowing the rest of the atom to execute. <== is the assignment operator. We’ll discuss period in more depth later, but for now, you just need to know that something with a period of 2 will run every other tick[1. A tick is a single call to the blink_atom which is the top level Atom function.] through the system whereas something with a period of 3 will run every third tick.

delayCycles refers to the number of cycles through the main loop we want to wait before toggling the state of the LED. Since this particular CPU is running at about 16Mhz, we define this as some relatively large number:

-- How many cycles do we want to delay before
-- we flip the LED?
delayCycles :: Word16
delayCycles = 30000

setLED describes how to call the corresponding setLED C function we defined in blink.c. Lets look at the type signature of action:

action :: ([String] -> String) -> [UE] -> Atom ()

So, it expects, for its first argument, a function which takes a list of Strings and returns a String. Its second is a list of “untyped expressions”, and it produces an Atom.

Atom takes the list of UE’s, converts them into the C symbols (often times something like “e1” or “e2”), and then passes them to the provided function for inclusion in some C statment. We can see this at work in the code snippet below:

Here, we take a Bool, and we pass it to the setLED function, which, presumably, turns the LED on when True, and turns it off when False.

This has been a brief discussion of the Haskell code needed to generate the C code for the Arduino board. Next time, we’ll investigate the C code that was generated (along with some other artifacts) and how they correspond to the Haskell we have written.