Electronics, Embedded Systems, and Software are my breakfast, lunch, and dinner.
Recently, I got my hands on a Raspberry Pi and one of the first things I wanted to do with it was to turn it into my complete AVR development environment. As part of that I wanted to make avrdude be able to program an AVR directly from the Raspberry Pi with no programmer. I know there is this linuxgpio programmer type that was recently added, but it is so recent that it isn't yet included in the repos and it also requires a compile-time option to enable it. I noticed that the Raspberry Pi happens to expose its SPI interface on its expansion header and so I thought to myself, "Why not use this thing instead of bitbanging GPIOs? Wouldn't that be more efficient?" Thus, I began to decipher the avrdude code and write my addition. My hope is that things like this will allow the Raspberry Pi to be used to explore further embedded development for those who want to get into microcontrollers, but blew all their money on the Raspberry Pi. Also, in keeping with the purpose that the Raspberry Pi was originally designed for, using it like this makes it fairly simple for people in educational surroundings to expand into different aspects of small computer and embedded device programming.
As my addition to avrdude, I created a new programmer type called "linuxspi" which uses the userspace SPI drivers available since around Linux ~2.6 or so to talk to a programmer. It also requires an additional GPIO to operate as the reset. My initial thought was to use the chip select as the reset output, but sadly, the documentation for the SPI functions mentioned that the chip enable line is only held low so long as the transaction is going. While I guess I could compress all the transactions avrdude makes into one giant burst of data, this would be very error prone and isn't compatible with avrdude's program structure. So, the GPIO route was chosen. It just uses the sysfs endpoints found in /sys/class/gpio to manipulate a GPIO chosen in avrdude.conf into either being in a hi-z input state or an output low state. This way, the reset can be connected via a resistor to Vcc and then the Raspberry Pi just holds reset down when it needs to program the device. Another consequence which I will mention here of choosing to use the Linux SPI drivers is that this should actually be compatible with any Linux-based device that exposes its SPI or has an AVR connected to the SPI; not just the Raspberry Pi.
So, down to the nitty gritty: How can I use it? Well, at the moment it is in a github repository at https://github.com/kcuzner/avrdude. As with any project that uses the expansion header on the Raspberry Pi, there is a risk that a mistake could cause your Raspberry Pi to die (or let out the magic smoke, so to speak). I assume no responsibility for any damage that may occur as a result of following these directions or using my addition to avrdude. Just be careful when doing anything involving hooking stuff up to the expansion port and use common sense. Remember to measure twice and cut once. So, with that out of the way, I will proceed to outline here the basic steps for installation and usage.
The best option here until I bother creating packages for it is to do a git clone directly into a directory on the Raspberry Pi and build it from there on the Raspberry Pi itself. I remember having to install the following packages to get it to compile (If I missed any, let me know):
Also, if your system doesn't have a header at "linux/spi/spidev.h" in your path, you probably need to install that driver. I was using Arch Linux and it already had the driver there, so for all I know its always installed. You also should take a look to make sure that "/dev/spidev0.0" and "/dev/spidev0.1" or something like that exist. Those are the sort of endpoints that are to be used with this. If they do not exist, try executing a "sudo modprobe spi_bcm2708". If the endpoints still aren't there after that, then SPI support probably isn't installed or enabled for your kernel.
After cloning the repo and installing those packages, run the "./boostrap" script which is found in the avrdude directory. This will run all the autoconf things and create the build scripts. The next step is to run "./configure" and wait for it to complete. After the configure script, it should say whether or not "linuxspi" is enabled or disabled. If it is disabled, it was not able to find the header I mentioned before. Then run "make" and wait for it to complete. Remember that the Raspberry Pi is a single core ARM processor and so building may take a while. Afterwards, simply do "sudo make install" and you will magically have avrdude installed on your computer in /usr/local. It would probably be worthwhile to note here that you probably want to uninstall any avrdude you may have had installed previously either manually or through a package manager. The one here is built on top of the latest version (as of May 26th, 2013), so it should work quite well and be all up to date and stuff for just using it like a normal avrdude. I made no changes to any of the programmer types other than the one I added.
To check to see if the avrdude you have is the right one, you should see an output similar to the following if you run this command (tiny-tim is the name of my Raspberry Pi until I think of something better):
1kcuzner@tiny-tim:~/avrdude/avrdude$ avrdude -c ?type
2
3Valid programmer types are:
4 arduino = Arduino programmer
5 avr910 = Serial programmers using protocol described in application note AVR910
6 avrftdi = Interface to the MPSSE Engine of FTDI Chips using libftdi.
7 buspirate = Using the Bus Pirate's SPI interface for programming
8 buspirate_bb = Using the Bus Pirate's bitbang interface for programming
9 butterfly = Atmel Butterfly evaluation board; Atmel AppNotes AVR109, AVR911
10 butterfly_mk = Mikrokopter.de Butterfly
11 dragon_dw = Atmel AVR Dragon in debugWire mode
12 dragon_hvsp = Atmel AVR Dragon in HVSP mode
13 dragon_isp = Atmel AVR Dragon in ISP mode
14 dragon_jtag = Atmel AVR Dragon in JTAG mode
15 dragon_pdi = Atmel AVR Dragon in PDI mode
16 dragon_pp = Atmel AVR Dragon in PP mode
17 ftdi_syncbb = FT245R/FT232R Synchronous BitBangMode Programmer
18 jtagmki = Atmel JTAG ICE mkI
19 jtagmkii = Atmel JTAG ICE mkII
20 jtagmkii_avr32 = Atmel JTAG ICE mkII in AVR32 mode
21 jtagmkii_dw = Atmel JTAG ICE mkII in debugWire mode
22 jtagmkii_isp = Atmel JTAG ICE mkII in ISP mode
23 jtagmkii_pdi = Atmel JTAG ICE mkII in PDI mode
24 jtagice3 = Atmel JTAGICE3
25 jtagice3_pdi = Atmel JTAGICE3 in PDI mode
26 jtagice3_dw = Atmel JTAGICE3 in debugWire mode
27 jtagice3_isp = Atmel JTAGICE3 in ISP mode
28 linuxgpio = GPIO bitbanging using the Linux sysfs interface (not available)
29 linuxspi = SPI using Linux spidev driver
30 par = Parallel port bitbanging
31 pickit2 = Microchip's PICkit2 Programmer
32 serbb = Serial port bitbanging
33 stk500 = Atmel STK500 Version 1.x firmware
34 stk500generic = Atmel STK500, autodetect firmware version
35 stk500v2 = Atmel STK500 Version 2.x firmware
36 stk500hvsp = Atmel STK500 V2 in high-voltage serial programming mode
37 stk500pp = Atmel STK500 V2 in parallel programming mode
38 stk600 = Atmel STK600
39 stk600hvsp = Atmel STK600 in high-voltage serial programming mode
40 stk600pp = Atmel STK600 in parallel programming mode
41 usbasp = USBasp programmer, see http://www.fischl.de/usbasp/
42 usbtiny = Driver for "usbtiny"-type programmers
43 wiring = http://wiring.org.co/, Basically STK500v2 protocol, with some glue to trigger the bootloader.
Note that right under "linuxgpio" there is now a "linuxspi" driver. If it says "(not available)" after the "linuxspi" description, "./configure" was not able to find the "linux/spi/spidev.h" file and did not compile the linuxspi programmer into avrdude.
There is a little bit of configuration that happens here on the Raspberry Pi side before proceeding to wiring it up. You must now decide which GPIO to sacrifice to be the reset pin. I chose 25 because it is next to the normal chip enable pins, but it doesn't matter which you choose. To change which pin is to be used, you need to edit "/usr/local/etc/avrdude.conf" (it will be just "/etc/avrdude.conf" if it wasn't built and installed manually like above). Find the section of the file that looks like so:
1programmer
2 id = "linuxspi";
3 desc = "Use Linux SPI device in /dev/spidev*";
4 type = "linuxspi";
5 reset = 25;
6;
The "reset = " line needs to be changed to have the number of the GPIO that you have decided to turn into the reset pin for the programmer. The default is 25, but that's just because of my selfishness in not wanting to set it to something more generic and having to then edit the file every time I re-installed avrdude. Perhaps a better default would be "0" since that will cause the programmer to say that it hasn't been set up yet.
After setting up avrdude.conf to your desired configuration, you can now connect the appropriate wires from your Raspberry Pi's header to your microchip. A word of extreme caution: The Raspberry Pi's GPIOs are NOT 5V tolerant, and that includes the SPI pins . You must do either one of two things: a) Run the AVR and everything around it at 3.3V so that you never see 5V on ANY of the Raspberry Pi pins at any time (including after programming is completed and the device is running) or b) Use a level translator between the AVR and the SPI. I happen to have a level translator lying around (its a fun little TSSOP I soldered to a breakout board a few years back), but I decided to go the 3.3V route since I was trying to get this thing to work. If you have not ever had to hook up in-circuit serial programming to your AVR before, perhaps this would be a great time to learn. You need to consult the datasheet for your AVR and find the pins named RESET (bar above it), MOSI, MISO, and SCK. These 4 pins are connected so that RESET goes to your GPIO with a pullup resistor to the Vcc on your AVR, MOSI goes to the similarly named MOSI on the Raspberry Pi header, MISO goes to the like-named pin on the header, and SCK goes to the SPI clock pin (named SCLK on the diagram on elinux.org). After doing this and double checking to make sure 5V will never be present to the Raspberry Pi , you can power on your AVR and it should be able to be programmed through avrdude. Here is a demonstration of me loading a simple test program I made that flashes the PORTD LEDs:
1kcuzner@tiny-tim:~/avrdude/avrdude$ sudo avrdude -c linuxspi -p m48 -P /dev/spidev0.0 -U flash:w:../blink.hex
2[sudo] password for kcuzner:
3
4avrdude: AVR device initialized and ready to accept instructions
5
6Reading | ################################################## | 100% 0.00s
7
8avrdude: Device signature = 0x1e9205
9avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
10 To disable this feature, specify the -D option.
11avrdude: erasing chip
12avrdude: reading input file "../blink.hex"
13avrdude: input file ../blink.hex auto detected as Intel Hex
14avrdude: writing flash (2282 bytes):
15
16Writing | ################################################## | 100% 0.75s
17
18avrdude: 2282 bytes of flash written
19avrdude: verifying flash memory against ../blink.hex:
20avrdude: load data flash data from input file ../blink.hex:
21avrdude: input file ../blink.hex auto detected as Intel Hex
22avrdude: input file ../blink.hex contains 2282 bytes
23avrdude: reading on-chip flash data:
24
25Reading | ################################################## | 100% 0.56s
26
27avrdude: verifying ...
28avrdude: 2282 bytes of flash verified
29
30avrdude: safemode: Fuses OK
31
32avrdude done. Thank you.
There are two major things to note here:
Other than that, usage is pretty straightforward and should be the same as if you were using any other programmer type.
As issues crop up, I hope to add improvements like changing the clock frequency and maybe someday adding TPI support (not sure if necessary since this is using the dedicated SPI and as far as I know, TPI doesn't use SPI).
I hope that those using this can find it helpful in their fun and games with the Raspberry Pi. If there are any issues compiling and stuff, either open an issue on github or mention it in the comments here.
For the greater part of this week I have been trapped in a car driving across the United States for my sister's wedding. Of course, I had my trusty netbook with me and so I decided to do some programming. After discovering that I had unwittingly installed tons of documentation in my /usr/share/doc folder (don't you love those computer explorations that actually reveal something?), I started building yet another rendition of Tetris in Python. I did several things differently this time and the code is actually readable and I feel like some structure things I learned/discovered/re-discovered should be shared here.
One problem that has constantly plagued my weak attempts at games has been an inability to do menus and manage whether the game is paused or not in a reasonably simple manner. Of course, I could always hack something together, but I could also write the whole thing in assembly language or maybe write it all as one big function in C. The issue is that if I program myself into a hole, I usually end up giving up a bit unless I am getting paid (then I generally bother thinking before programming so that I don't waste people's time). After finishing the game logic and actually getting things to work with the game itself, I remembered a funny tutorial I was once doing for OGRE which introduced a very simple game engine. The concept was one of a "stack" of game states. Using this stack, your main program basically injects input into and then asks a rendering from the state on the top of the stack. The states manipulate the stack, pushing a new state or popping themselves. When the stack is empty, the program exits.
My game state stack works by using an initial state that loads the resources (the render section gives back a loading screen). After it finishes loading the resources, it asks the manager to pop itself from the stack and then push on the main menu state. The menu state is quite simple: It displays several options where each option either does something immediate (like popping the menu from the stack to end the program in the case of the Quit option) or something more complex (like pushing a sub-menu state on to create a new game with some settings). After that there are states for playing the game, viewing the high scores, etc.
The main awesome thing about this structure is that switching states is so easy. Want to pause the game? Just push on a state that doesn't do anything until it receives a key input or something, after which it pops itself. Feel like doing a complex menu system? The stack keeps track of the "breadcrumbs" so to speak. Never before have I been able to actually create an easily extensible/modification-friendly game menu/management system that doesn't leave me with a headache later trying to understand it or unravel my spaghetti code.
The second awesome thing is that this helps encourage an inversion of control. Rather than the state itself dictating when it gets input or when it renders something, the program on top of it can choose whether it wants to render that state or whether it wants to give input to that state. I ended up using the render function like a game loop function as well and so if I wanted a state to sort of "pause" execution, I could simply stop telling it to render (usually by just pushing a state on top of it). My main program (in Python) was about 25 lines long and took care of setting up the window, starting the game states, and then just injecting input into the game state and asking the state to render a window. The states themselves could choose how they wanted to render the window or even if they wanted to (that gets into the event bubbling section which is next). It is so much easier to operate that way as the components are loosely tied to one another and there is a clear relationship between them. The program owns the states and the states know nothing about about the program driving them...only that their input comes from somewhere and the renderings they are occasionally asked to do go somewhere.
When making my Tetris game, I wanted an easy to way to know when to update or redraw the screen rather than always redrawing it. My idea was to create an event system that would "notice" when the game changed somehow: whether a block had moved or maybe the score changed. I remembered of two event systems that I really really liked: C#'s event keyword plus delegate thing and Javascript's event bubbling system. Some people probably hate both of those, but I have learned to love them. Mainly, its just because I'm new to this sort of thing and am still being dazzled by their plethora of uses. Using some knowledge I gleaned from my database abstraction project about the fun data model special function names in Python, I created the following:
1class EventDispatcher(object):
2 """
3 Event object which operates like C# events
4
5 "event += handler" adds a handler to this event
6 "event -= handler" removes a handler from this event
7 "event(obj)" calls all of the handlers, passing the passed object
8
9 Events may be temporarily suppressed by using them in a with
10 statement. The context returned will be this event object.
11 """
12 def __init__(self):
13 """
14 Initializes a new event
15 """
16 self.__handlers = []
17 self.__supress_count = 0
18 def __call__(self, e):
19 if self.__supress_count > 0:
20 return
21 for h in self.__handlers:
22 h(e)
23 def __iadd__(self, other):
24 if other not in self.__handlers:
25 self.__handlers.append(other)
26 return self
27 def __isub__(self, other):
28 self.__handlers.remove(other)
29 return self
30 def __enter__(self):
31 self.__supress_count += 1
32 return self
33 def __exit__(self, exc_type, exc_value, traceback):
34 self.__supress_count -= 1
My first thought when making this was to do it like C# events: super flexible, but no defined "way" to do them. The event dispatcher uses the same syntax as the C# events (+=, -= or __iadd__, __isub__) to add/remove handlers and also to call each handler (() or __call__). It also has the added functionality of optionally suppressing events by using them inside a "with" statement (which may actually be breaking the pattern, but I needed it to avoid some interesting redrawing issues). I would add EventDispatcher objects to represent each type of event that I wanted to catch and then pass an Event object into the event to send it off to the listening functions. However, I ran into an issue with this: Although I was able to cut down the number of events being sent and how far they propagated, I would occasionally lose events. The issue this caused is that my renderer was listening to find out where it should "erase" blocks and where it should "add" blocks and it would sometimes seem to forget to erase some of the blocks. I later discovered that I had simply forgotten to call the event during a certain function which was called periodically to move the Tetris blocks down, but even so, it got my started on the next thing which I feel is better.
Javascript events work by specifying types of events, a "target" or object in the focus of the event, and arguments that get passed along with the event. The events then "bubble" upward through the DOM, firing first for a child and then for the parent of that child until it reaches the top element. The advantage of this is that if one wants to know, for example, if the screen has been clicked, a listener doesn't have to listen at the lowest leaf element of each branch of the DOM; it can simply listen at the top element and wait for the "click" event to "bubble" upwards through the tree. After my aforementioned issue I initially thought that I was missing events because my structure was flawed, so I ended up re-using the above class to implement event bubbling by doing the following:
1class Event(object):
2 """
3 Instance of an event to be dispatched
4 """
5 def __init__(self, target, name, *args, **kwargs):
6 self.target = target
7 self.name = name
8 self.args = args
9 self.kwargs = kwargs
10
11class EventedObject(object):
12 def __init__(self, parent=None):
13 self.__parent = parent
14 self.event = EventDispatcher()
15 self.event += self.__on_event
16 def __on_event(self, e):
17 if hasattr(self.__parent, 'event'):
18 self.__parent.event(e)
19 @property
20 def parent(self):
21 return self.__parent
22 @parent.setter
23 def parent(self, value):
24 l = self.parent
25 self.__parent = value
26 self.event(Event(self, "parent-changed", current=self.parent, last=l))
The example here is the object from which all of my moving game objects (blocks, polyominoes, the game grid, etc) derive from. It defines a single EventDispatcher, through which Event objects are passed. It listens to its own event and when it hears something, it activates its parent's event, passing through the same object that it received. The advantage here is that by listening to just one "top" object, all of the events that occurred for the child objects are passed to whatever handler is attached to the top object's dispatcher. In my specific implementation I had each block send an Event up the pipeline when the were moved, each polyomino send an Event when it was moved or rotated, and the game send an Event when the score, level, or line count was changed. By having my renderer listen to just the game object's EventDispatcher I was able to intercept all of these events at one location.
The disadvantage with this particular method is that each movement has a potentially high computational cost. All of my events are synchronous since Python doesn't do true multithreading and I didn't need a high performance implementation. It's just method calls, but there is a potential for a stack overflow if either a chain of parents has a loop somewhere or if I simply have too tall of an object tree. If I attach too many listeners to a single EventDispatcher, it will also slow things down.
Another problem I have here has to do with memory leaks which I believe I have (I haven't tested it and this is entirely in my head, thinking about the issues). Since I am asking the EventDispatcher to add a handler which is a bound method to the object which owns it, there is a loop there. In the event that I forget all references to the EventedObject, the reference count will never decrease to 0 since the EventDispatcher inside the EventedObject still holds a reference to that same EventedObject inside the bound method. I would think that this could cause garbage collection to never happen. Of course, they could make the garbage collector really smart and notice that the dependency tree here is a nice orphan tree detached from the rest and can all be collected. However, if it is a dumb garbage collector, it will probably keep it around. This isn't a new issue for me: I ran into it with doing something like this on one of my C# projects. However, the way I solved it there was to implement the IDisposable interface and upon disposal, unsubscribe from all events that created a circular dependency. The problem there was worse because there wasn't a direct exclusive link between the two objects like there is with this one (here one is a property of the other (strong link) and the other only references a bound method to its partner (weak...kinda...link)).
Overall, even though there are those disadvantages, I feel that the advantage gained by having all the events in one place is worth it. In the future I will create "filters" that can be attached to handlers as they are subscribed to avoid calling the handlers for events that don't match their filter. This is similar to Javascript in that handlers can be used to catch one specific type of event. However, mine differs in that in the spirit of Python duck typing, I decided to make no distinction between types of events outside of a string name that identifies what it is. Since I only had one EventDispatcher per object, it makes sense to only have one type of event that will be fed to its listeners. The individual events can then just be differentiated by a property value. While this feels flaky to me since I usually feel most comfortable with strong typing systems, it seems to be closer to what Python is trying to do.
I eventually will put up this Tetris implementation as a gist or repository on github (probably just a gist unless it gets huge...which it could). So far I have learned a great deal about game design and structure, so this should get interesting as I explore other things like networking and such.