Atom & Arduino :: First Program (pt. 2)

Last time we talked about a few changes I made to Atom. This time we’re going to start writing some programs. Our first one will be pretty simple.

First, we need a short C file (this is the only C code, besides the #include‘s and the prototype we use in blink.h, we need to write our selves):

#include "blink.h"

/* PORTB corresponds some how to Pin 13. We get
 * a blinking LED on the board. We can also plug
 * an LED into Pin 13 and the GND pins. */
void setLED(uint8_t value)
{
    PORTB = 0xFF * !!value;
}

/* main only needs to continously call blink_atom(). */
int main(int argc, char * argv[])
{
    while(1)
    {
        blink_atom();
    }
}

Next, lets make Main in our Haskell file, pull in some modules, and define the AtomConfig:

module Main where

import Language.Atom
import Data.Word

-- Override some default values
cfg = AtomConfig {
    -- This pulls some stuff in we use below.
    cIncludes = Just ["blink.h"],

    -- The (u)intXX_t types are defined in
    -- stdint.h--which we include from blink.h
    cTyper    = Just $ t -> case t of
                                Bool   -> "uint8_t"
                                Int8   -> "int8_t"
                                Int16  -> "int16_t"
                                Int32  -> "int32_t"
                                Int64  -> "int64_t"
                                Word8  -> "uint8_t"
                                Word16 -> "uint16_t"
                                Word32 -> "uint32_t"
                                Word64 -> "uint64_t"
                                Float  -> "float"
                                Double -> "double"
}

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.

Lets take a look at that:

-- Simple Atom to toggle an LED
blink :: Atom ()
blink = do
    -- Is the LED currently on? (Assume it starts False/off)
    isOn    <- bool "isOn" False

    -- Does the toggle counter need a reset? (Assume it starts False/no)
    doReset <- bool "doReset" False

    -- Initialize the toggle counter to delayCycles
    toggle  . 0
        toggle <== value toggle - 1

    -- Checks if we need to perform a toggle
    -- reset, and performs it when we need one.
    period 2 $ atom "reset" $ do
        cond $ value doReset
        doReset <== Const False
        toggle  <== Const delayCycles

    -- Checks if the toggle counter has expired.
    -- Toggles the LED if it has, then requests
    -- a reset.
    period 2 $ atom "flip" $ do
        cond $ value toggle <=. 0
        setLED isOn
        isOn <== (not_ $ value isOn)
        doReset <== Const True

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:

-- An action (basically raw C code) to set the value
-- of the LED. setLED() is defined in blink.c.
setLED :: V Bool -> Atom ()
setLED v = action ([x] -> "setLED(" ++ x ++ ")") [v']
    where v' = ue . value $ v

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.

Here are links to the files we’ve dicussed today:

Posted in atom | Tagged , | 5 Comments

Atom & Arduino :: Some Hacking (pt. 1)

When Tom Hawkins released the Atom package, I stole my friend’s Arduino Diecimila to see if I could get some Atom-generated code to work. Turns out it wasn’t that hard! I’ll be detailing this in the next few posts. I’m going to use this first post to point out two things I changed in atom-0.0.2.

  • By default, Atom hardcodes the C types which correspond to the Atom types. This means that an Int32 is always defined as signed int. Unfortunately, the ATmega168 CPU and the avr-gcc compiler define a signed int as an Int16. I needed a way to customize these types.
  • Even though an Atom action can refer to an external function, I wasn’t able to see a nice way to have Atom plop a #include in the generated code. I added this ability as well.

My changes only end up affecting two exposed functions. To facilitate the include files and the C types, I added an AtomConfig data type (this can be found in Language.Atom.Code).

data AtomConfig = AtomConfig {
    cIncludes :: Maybe [String],
    cTyper    :: Maybe (Type -> String)
}

I also changed the type signature of writeC. It now reads as:

writeC :: Name -> Maybe AtomConfig -> [[[Rule]]] -> [UV] -> IO ()

Now, we don’t actually have to call writeC our selves [1. At least, I haven’t seen a reason to yet–perhaps this should not be exposed?], but it does get called by compile from Language.Atom.Compile. The compile function now has this type signature:

compile :: Name -> Maybe AtomConfig -> Atom () -> IO ()

Other than the example in Language.Atom.Example, this is the only visible code that I changed.

Here’s how you use the AtomConfig type:

cType :: Type -> String
cType t = case t of
  Bool   -> "uint8_t"
  Int8   -> "int8_t"
  Int16  -> "int16_t"
  Int32  -> "int32_t"
  Int64  -> "int64_t"
  Word8  -> "uint8_t"
  Word16 -> "uint16_t"
  Word32 -> "uint32_t"
  Word64 -> "uint64_t"
  Float  -> "float"
  Double -> "double"

cfg = AtomConfig {
    cIncludes = Just ["blink.h"],
    cTyper    = Just cType
}

First, we define a function that takes a Type and produces a string representing the C type. We build the config with an optional list of include files [2. These includes are the kinds that use quotes, not angle brackets. We’ll see #include "blink.h" rather than #include <blink.h>.] and an optional typing function. If Nothing is passed to both fields, then Atom will not use any include files and will use the built in type converter.

In the next post, we’ll start building a simple program: blink an LED hooked up to some I/O pins on the Arduino.

I’ve posted a diff of my changes to atom-0.0.2. Any criticisms are welcome.

Posted in Distraction | Tagged , | 7 Comments

My TODO List

I’m making this public so that I will be hounded if fail to complete these tasks or find some one to do these for me (hint hint):

  • Write a Haskel FFI interface for libdnet.
  • Write a Haskell FFI inteface for libgcrypt.
  • Finish a GUI for Scurry.
  • Start working on my portaudio FFI interface again.

There, I said it, and now it’s public. Some one hold me to this please!

Posted in Uncategorized | Tagged , , , | 1 Comment

“Shelle of prayers and Ceremonies”

“Right,” said Om. “Now…listen. Do you know how gods get power?”

“By people believing in them,” said Brutha. “Millions of people believe in you.”

Om hesitated.

All right, all right. We are here and it is now. Sooner or later he’ll find out for himself…

“They don’t believe,” said Om.

“But-”

“It’s happened before,” said the tortoise. “Dozens of times. D’you know Abraxas found the lost city of Ee? Very strange carvings, he says. Belief, he says. Belief shifts. People start out believing in the god and end up believing in the structure.”

“I don’t understand,” said Brutha.

“Let me put it another way,” said the tortoise. “I am your God, right?”

“Yes.”

“And you’ll obey me.”

“Yes.”

“Good. Now take a rock and go and kill Vorbis.”

Brutha didn’t move.

“I’m sure you heard me,” said Om.

“But he’ll…he’s…the Quisition would-”

“Now you know what I mean,” said the tortoise. “You’re more afraid of him than you are of me, now. Abraxas says here: `Around the Godde there forms a Shelle of prayers and Ceremonies and Buildings and Priestes and Authority, until at Last the Godde Dies. Ande this maye notte be noticed.’ “

Terry Pratchett – Small Gods

Posted in Distraction | Tagged , | Leave a comment

Happy… UNIX TIME DATE THINGY DAY!

$ while true; do date +%s; sleep 1; done
1234567883
1234567884
1234567885
1234567886
1234567887
1234567888
1234567889
1234567890

Posted in Uncategorized | Tagged , | 1 Comment

Scurry: What is it?

Scurry is a non-trivial piece of software (at least in my mind), but the roll it plays isn’t all that hard to understand. I describe it as a “Resilient P2P VPN,” what does that mean? Well, the VPN part isn’t too hard.

Wikipedia (at least at the time of writing) describes a VPN as:

A virtual private network (VPN) is a computer network in which some of the links between nodes are carried by open connections or virtual circuits in some larger network (e.g., the Internet) as opposed to their conduction across a single private network.

Usually, a VPN is used to access corporate resources from off site (a dial-in VPN which lets you access servers or printers from somewhere other than the office building you work in). In a less professional environment, VPN’s are used to play older video games that don’t support direct internet gameplay. This less professional use was what I originally had in mind when writing Scurry.

The other interesting pieces of Scurry are its resillience and the P2P (peer to peer) nature. There is no single point of failure in Scurry networks and hosts don’t have to access a specific central server to gain access to the network.

We’ll talk about both of these pieces more in the future.

For those interested:

Posted in Scurry | Tagged , , | Leave a comment

Distraction: Fun with diagrams!

I’ve finally sat down and played with Brent Yorgey’s diagrams package. Every once in a while, I just want to write something fun–some feel good code. Well, I had so much fun, I want to describe what I made.

It’s nothing complex or strange, it’s just a few shapes with some colors! (But the colors are so shiny and happy!)

Lets start from the top:

numCols, numRows :: Int
numCols = 23
numRows = 5

Here, we just defined how many shapes wide and how many shapes tall we want our resulting diagram to be. Lets define main next:

main :: IO ()
main = renderAs SVG "out2.svg" (Width width) dgram
    where width = (fromIntegral numCols) * 30

Alright, we know what numCols is, and we see width defined in the where clause, but what is dgram?

dgram :: Diagram
dgram = vcat $ take numRows rows
    where rows = map hcat $ plines crps

dgram is the top level diagram we’re rendering. vcat is a vertical concatenation of several other diagrams. We take a specific number of rows from rows–the horizontal concatenation (hcat) of whatever is generated by plines crps–and concatenate them together vertically.

Alright, we seem to be almost there now. What is plines?

plines :: [Diagram] -> [[Diagram]]
plines [] = []
plines pls = let (l,ls) = splitAt numCols pls
             in l : (plines ls)

As it turns out, plines is just a cheap chunking function with a fixed chunk size. All this does is turn a list into a list of lists with the same length. If the sublists were concatenated back together again, you’d have your original list.

We’ve seen everything plines has to offer, what about crps?

crps :: [Diagram]
crps = zipWith fillColor cs rps
    where rps = zipWith rotate rs ps
          rs = cycle . map (/ 4) $ [1..4]                 -- 4 rotations
          ps = cycle . map (flip regPoly 1) $ [3..7]      -- 5 polygons
          cs = cycle [red,black,green,blue,yellow,violet] -- 6 colors

Hey! This is more interesting! Lets look a little closer at what’s happening here.

The ps symbol defines an infinite list of cycling polygons. We use the regular polygon (regPoly) function to generate polygons with 3, 4, 5, 6, and 7 sides. The cs symbol is just defining an infinite list of colors–nothing too complex here. The rs symbol is a cycling list of 1/4, 2/4, 3/4, and 4/4. These are used as rotations in terms of turns.

Now, what is that rps symbol? Lets see, we are zipping rs and ps together using the function rotate which accepts a Double representing a fraction of a turn and a Diagram to rotate. So, rps is an infinite list of cycling polygons where each successive polygon is rotated one quarter turn more than the previous.

This means that crps is an infinite list of cycling polygons each rotated one quarter turn more than the previous polygon but and each polygon has a cycling fill color! Neat!

So what does this look like?

Colorful cycling rotating polygons!

I don’t know about you, but that takes me back to grade school. Sometimes a little bit of happy code can brighten your day!

Links to source files and SVG images:
Original, not quite as cool, attempt and its SVG rendering.
Finished colorful one and its SVG rendering.

Posted in Distraction | Tagged , | Leave a comment