Learning About Atmel RZRAVEN
Description:
Introduction
ATAVRRZRAVEN 2.4 GHz Evaluation and Starter Kit product page
Product Links
- ATmega3290 -- product page for microcontroller used for the LCD control (and more?).
- AVR Studio 4.14 Release Candidate 1 -- This has a slightly more recent version of the Wireless tools (1.0.0.5 vs 1.0.0.2). (Main Atmel Betaware page.)
USB Reverse Engineering Links
- USBSnoop 1.8 -- I used this version of the USB Sniffer, there are also earlier USBSnoop and more recent USBSnoop versions (the latter requires .Net).
- USB RE Guides: "Howto...Write an initialization function for your webcam", USBSnoop Reverse Engineering, "Reverse engineering Windows USB device drivers for the purpose of creating compatible device drivers for Linux"
libusb and PyUSB links
- missle.py -- USB missle launch control, real example of how to send messages, connect etc. (I cargo-culted a couple of initialisation things from this.)
Issues
- Context menu says "Sent message to all" instead of "Send message to all".
- Sniffer doesn't seem to work at the same time as the coordinator.
- To read the temperature the Debug option needs to be disabled on the Raven every time it reboots.
- Can't read all messages in inbox?
(Response)
Code
- test_raven_usb_20080415.py -- Initial proof-of-concept hacky code to connect to the Raven USB Dongle from Python. (Has been tested on Mac OS X 10.2, should work anywhere libusb/PyUSB does.) Requires: libusb, PyUSB. (Previous version: test_raven_usb.py)
- rzusbstickcommon_hh.py -- A Python module auto-generated from defines found in rzusbstickcommon.hh useful for packet decoding etc.
Running on Linux
(Update: Word from Atmel is this will be able to be supported under libusb. Seems likely. :-) See above.)
All the software supplied from Atmel appears to be Windows only. The underlying USB implementation based on WinDriver does seem to have a Linux version also. WinDriver 9.20 USB User's Manual.
It seems Xilinx hardware/software may use a similar implementation, see these for possible pointers:
- http://ubuntuforums.org/showthread.php?t=369873
- http://ubuntuforums.org/showthread.php?t=119418
- http://ubuntuforums.org/archive/index.php/t-250363.html
- https://wiki.kip.uni-heidelberg.de/KIPwiki/index.php/EDV:Xilinx-USB-Treiber
- http://stefan.endrullis.de/en/xilinx_ise_8.2_ubuntu.html
The driver seems to use 'windrvr6.o' or platform specific variations thereof.
Tools
At this stage all the firmware appears to be binary only. So in order to do some poking around:
- Ascii Coded heX Utility -- functional but rough editor for Intel Hex files.
- ReAVR - Disassembler for AVR -- doesn't recognise the files as valid Intel Hex files unless have have a '.hex' extension added.
- m3290def.inc -- Defines for assembly language usage with ATmega3290 (used to make output of ReAVR more comprehensible). @@ TODO Add my ReAVR user defines file here.
- AVR assembly language -- Very brief overview.
- revava - Atmel AVR Disassembler -- Didn't compile with g++-4 but with some fiddling got it "running" with g++-3.3. It choked on long filenames in error states, and requires the Flash size to be increased. For some reason it choked on output also, so pretty much gave up on it.
- vAVRdisasm - Free AVR Disassembler -- Untested.
- AVRdis the disassembler -- Written in Modula2 and untested.
- BIEW - Binary vIEW project -- NOTE: Keyboard shortcuts are different under Unix, read the end of the online docs! (Includes AVR disassembler.)
- diStorm64 -- Python disassembler library for AMD64 (thoughts about porting?)
Project Log
- ( 29 March 2008 )
- Kit arrives.
- Successfully get communication between computer and two Raven boards working. (Send messages, read temperature.)
- Investigated possibility of running on Linux. Seems like the underlying USB driver (WinDriver) has a Linux implementation. The rfservicesserver.exe tool appears to use libavrtools.dll which in turn uses wdapi811.dll (?) for USB communication. I used OllyDbg to determine this.
- Looked for utilities to convert Intel Hex files (the '.a90' files the firmware is supplied as) back into straight binary and assembly. I ended up using srecord which has the capability buried within it to convert .hex into a binary:
srec_cat 3290.infile.hex -intel -o 3290.outfile.bin -Binary
- srecord is packaged for Ubuntu. There is a Debian bug report for ITP: hex2bin -- Converts Motorola and Intel Hex files to binary which is apparently another option, although a comment mentions objcopy -Iihex -Obinary in.hex out.bin should work also (untested by me).
- Found LCD display text in the 3290 firmware file—edited piece of display text but have not yet tested the firmware.
- Successfully power one Raven from external power. Use 4 x 1.5V AA Batteries in a holder connected to the two left-most pins on the lower edge of the Raven board. (Pin 1: External 5V-12V, Pin 2: External 0V.) As documented in AVR2016: RZRAVEN Hardware User's Guide (page 6).
- Whoops. So, I managed a successful firmware upgrade with the standard firmware, so I thought I'd try one with my edited version. (All I did was change the startup screen from "RAVEN" to "CRAVE"!) And now it won't join the network... :-( (But it does say CRAVE...)
- ( 30 March 2008 )
- Looked into both the RF service and Wireless software to see if references to RAVEN were hard-coded there but found nothing.
- Started using Simple TCP proxy/pipe 0.4.3 (stcppipe.zip) to log communication between RF service and Wireless software. Partial success. Wrote small Python test to connect but couldn't get a response.
- Command line to execute TCP Proxy: stcppipe.exe -b 192.168.7.7 -d foo 127.0.0.1 27001 27000 And the RF service should be started rfservicesserver.exe 127.0.0.1 27001 and the Wireless software should connect to 192.168.7.7 (or whatever your IP is). (The directory foo is the output directory for the capture logs.)
- Something like this Python script "should" work but doesn't: (It'll "connect" but hang on recv and also only seems to connect every second time.)
import socket import time s = socket.socket() s.connect(("127.0.0.1", 27000)) s.send("\xaa\x02\x00\x00\x41") time.sleep(0.5) print repr(s.recv(1)) s.close()
- ( 31 March 2008 )
- Thanks to UsbSnoop, Python and libusb, I have successfully connected the Raven USB Stick on my Mac OS X 10.2 machine and configured it enough to enable a Raven remote device to connect to the network!
- Successfully detected device joining the network and sending a text message to it.
- Worked out how to create a text message packet and can now create arbitrary messages from it—still some unknown sections though.
- Successfully sent text message from Raven remote to USB stick—required an ACK message in order for the display to show "SENT".
- I seem to be missing every second message to the USB stick in certain situations.
- From my investigations I have two USBSnoop logs—although neither have a clean disconnect, cos I kinda forgot. :-) avr-raven-notes-usbsnoop.log avr-raven-notes-2-usbsnoop.log From memory they both have Host --> Remote text messages but the second one also has Remote --> Host text message.
- Have uploaded test_raven_usb.py for others to try. I have so far only tested it on Mac OS X 10.2 but it should in theory work where-ever libusb/PyUSB work.
- I still get "usb.USBError: usb_bulk_read: An error occured during read (see messages above)" errors on occassion—possibly due to not a large enough read buffer?
- ( 1 April 2008 )
- Successfully read the temperature from the Raven (no, really!). Haven't uploaded updated code yet.
- ( 8 April 2008 )
- Seemingly successfully soldered headers for the bottom connector (J401) and the 3290 ISP connector—it was not without incident however. I would suggest trying a solder smaller than 1.0mm for the 0.05" pitch ISP connector. (I used one of the supplied 10-pin JTAG connectors with 2 pins removed from each end.)
- I used the supplied adapter to connect a AVRISP programmer to the board—pins 7 and 8 on the adapter get bent by the AVRISP connector.
- The version of avrdude I am using (5.4) doesn't support the ATmega3290P used on the Raven but does support the ATmega3290 non-P version. According to the avrdude patch that adds ATMega3290P support, outside of the signature the two devices are identical and I was successfully able to access the device (*) by specifying the part as an ATmega3290 and overriding the signature check with the '-F' option. (* I also needed the other fix mentioned below.)
- There is a message "avrdude: please define PAGEL and BS2 signals in the configuration file for part ATMEGA3290" but that doesn't seem to prevent anything that I tried from working.
- ... @@ TODO : Finish this entry regarding the second fix: ATmega324P with AVRDUDE, bug #22699: Errors in AVR910 Device Codes
- Here are the command lines that worked for me (reference):
## Connect and start terminal #avrdude -p atmega3290 -c avrisp -P /dev/ttyS0 -t -v -F ## Dump the flash of the chip to file #avrdude -p atmega3290 -c avrisp -P /dev/ttyS0 -v -F -U flash:r:"3290.download.b0rked.bin":r ## Upload the original hex firmware to the chip (the '-e' isn't strictly necessary) #avrdude -p atmega3290 -c avrisp -P /dev/ttyS0 -v -F -e -U flash:w:"../3290.infile.hex"
- ( 23 May 2008 )
- Quick add of the new (April) version of code, by request. The temperature reading code is buried in a comment.
- ( 24 May 2008 )
- Downloaded and began to read Raven documentation. (Now linked from product page.)
- AFAICT the host side source isn't available.
- There are many typos.
- The commands seem to be listed in include/application/rzusbstick/rzusbstickcommon.hh which doesn't seem to be linked into the documentation.
- The commands I've encountered so far are listed as:
// Stream and Events. #define EVENT_STREAM_AC_DATA 0x50 #define EVENT_SNIFFER_SCAN_COMPLETE 0x51 #define EVENT_SNIFFER_ERROR 0x52 #define EVENT_NWK_DATA 0x53 #define EVENT_NWK_JOIN 0x54 #define EVENT_NWK_LEAVE 0x55
- Incidentally, I realised yesterday that there was a much better way of parsing the USB data—I think the second byte is the length of the complete data packet (including the first two bytes). I need to rewrite the parsing code with that in mind.
- ( 25 May 2008 )
- Working on rewriting the code to handle things in a more documented manner.
- Use this to enable libusb debugging:
export USB_DEBUG=3
- I can't get the USB stick to be connected reliably on Ubuntu 7.10 (?).
- Compiling the 3290 source is about 107% of the available flash with gcc. By ifdef'ing a bunch of functionality I can get it to fit but "nothing" seems to happen when I upload. It could be due to running out of RAM. Uploading the .hex file didn't work, I needed to use the .elf file. (This was compiled via AVR Studio on Windows.)
- I uploaded the latest 3290 firmware but it seems to get stuck waiting for the 128 to boot—presumably with the correct version. Guess I'll need to solder the 128 ISP connector.
- ( 26 May 2008 )
- I realised that the reason why things got b0rked with my custom firmware was because the bootloader wasn't being written (I think).
- It seems like GCC produces a bootloader ~8KB (which won't fit) rather than 4KB.
- By hacking out most of the bootloader functionality I was able to create a bootloader (AVRRAVEN_3290p_BOOTLOADER.hex--(un)helpfully, I think this version actually turns the LED off) that turned on the red LED when it starts.
- I then managed to get a simple program that flashed the LED (my3290.hex) uploaded after merging (merged.hex) it with the bootloader, using this command (I had srecord (SREC) installed previously):
srec_cat my3290.hex -intel AVRRAVEN_3290p_BOOTLOADER.hex -intel -offset 0x7000 -o merged.hex -intel
- The 0x7000 offset is required to place the bootloader in the correct location—assuming a 2048 word (4096 byte) bootloader. (From memory I had to delete an odd memory address from near the end of the bootloader hex file.)
- The merged file was then uploaded with:
avrdude -p atmega3290 -c avrisp -P /dev/ttyS0 -v -F -e -U flash:w:"merged.hex"
- As a matter of interest, here is the information about the merged file:
$ srec_info merged.hex -intel Format: Intel Hexadecimal (MCS-86) Start: 00000000 Data: 0000 - 00E1 7000 - 7B71
- Because the source is the hacked up version of the main project I haven't yet worked out the best way to put it here. (Yeah, I know that's a weak excuse.)
- I've successfully hacked up the original application enough that I can "fit" it into the flash (app_merged.hex)--except I haven't really because I'm not actually activating the functionality that's left (I think I tried, but it didn't work—probably from something I ifdef'd out earlier—I probably need to start the "trimming" process from the beginning.). What I have done though is get the LED to flash, the Raven symbol to flash and display a handful of other symbols. Unfortunately I haven't got the text display working yet—but I do have ~30 symbols to debug the problem with!
- ( Site down for around a month )
- ( 7 July 2008 )
- I have discovered the (Rev C.?) boards have a bug in that the ISP for the 1284p doesn't have connections on VCC and GND. Atmel has confirmed this problem and suggest jumping the VCC & GND connections from the 3290p header.
- For reference, here is the pin out for the Atmel 6-pin ISP Header (and 10-pin): (Original source)
- I seem to have successfully made the fix for the 1284p ISP header but now need to find a version of avrdude to support the ATmega1284/ATmega1284p. ( See 9 July 2008 entry for photos )
- *Finally*! I have managed to resurrect my b0rked Raven. By reflashing the beta 1284p firmware I have managed to revive the device. So, I guess it must have been some problem with the firmware when I tried to upload my modified 3290p, which is strange.
- I haven't yet found an avrdude version that will upload to 1284p, I used AVR Studio on Windows to upload. (I also upgraded my AVRISP programmer at to the 2.0a (?) firmware as otherwise AVR Studio complained.
- The new firmware seems to "work". Odd things: The name of the device seems to be "N" by default. It doesn't seem to record audio. Raven sound no longer plays for mail by default (by design I seem to recall). Debug seems to still be enable by default so no valid temperature reading by default (new state seems to be preserved through power off though).
- I uploaded the "default" firmware from the Wireless Tools contextual menu but when I "upgraded" it seems it uploaded my original non-working modified CRAVE firmware instead! So, I had to reflash things again... :-/
- In order for avrdude to recognise the ATmega1284p the device details need to be added to the avrdude.conf (actually avrdude.conf.in) file. AFAICT there is nowhere that fully documents how this is actually done, it seems that some data can be extracted by script from the ATmega1284P.xml file supplied with AVR Studio but the rest needs to come from the datasheet?
- The tools to auto-extract some of the data comes from tools directory. (A patch is currently required for xsltproc on my Ubuntu install: bug #21798: Fix both XSLT scripts. (See also: get-dw-params.xsl and get-hv-params.xsl patch)) Using get-hv-params.xsl like so:
$ xsltproc get-hv-params.xsl ATmega1284P.xml
produces
pp_controlstack = 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; hventerstabdelay = 100; progmodedelay = 0; latchcycles = 6; togglevtg = 1; poweroffdelay = 15; resetdelayms = 1; resetdelayus = 0; hvleavestabdelay = 15; chiperasepulsewidth = 0; chiperasepolltimeout = 10; programfusepulsewidth = 0; programfusepolltimeout = 5; programlockpulsewidth = 0; programlockpolltimeout = 5;
- Nothing seems to get generated by running:
$ xsltproc get-dw-params.xsl ATmega1284P.xml
- Significantly more data seems to be required for a complete entry however.
- A recent avrfreaks thread points to what appears to be avrgcc compilable Raven code:
The source code is available in the project release folder under the respective folders. In order to compile the source code provided, WinAVR GCC compiler is a required plug-in to AVR Studio.
- So the Raven AVR2002 code compiles out of the box with avrgcc. And I edited it to change the initial text and make it beep, and it works... Until it doesn't work, when the LCD display goes all screwy. But now I can get the official Atmel firmware to do that too... So now it's starting to look like hardware again... :-( Gah.
- Maybe it's not the hardware (or it's a combination)... Perhaps it's a bad interrupt or something? (Or maybe I need to actually make sure the fuses match exactly...) It definitely starts to run (I can see text scrolling) but then the display gets corrupted, but then when text is redrawn (e.g. by using the joystick) it seems to work okay—in some cases (when it's just weird text, but not if the display itself is half drawn?).
- Anyway, the code I'm editing is in: AVR2002/res_raven_lcd/res_3290
- A patch against raven3290.c that I'm playing with is:
--- raven3290.c.orig 2008-07-07 23:21:19.000000000 +1200 +++ raven3290.c 2008-07-08 00:16:31.000000000 +1200 @@ -133,7 +133,11 @@ const tmenu_item menu_items[21]; #else // !DOXYGEN /** @brief This is the menu text in Flash. See menu_items[] for menu operation. */ +#if 1 +const char menu_text0[] PROGMEM = "DONKEY8"; +#else const char menu_text0[] PROGMEM = "RES 1.0"; +#endif const char menu_text1[] PROGMEM = "SETUP"; const char menu_text2[] PROGMEM = "CHANNEL"; const char menu_text3[] PROGMEM = "POWER"; @@ -233,6 +237,13 @@ // and draw it lcd_puts_P(menu.text); + lcd_puts_P(PSTR("W00T BOOP DOOP")); + +#if 1 +#include "beep.h" + beep(); +#endif + for (;;) { // Make sure interrupts are always on
- Run this to compile the firmware (note it appears to have no bootloader):
make -f Makefile.linux
- Oh, and as I suspected might be the case, the upgraded AVRISP doesn't run with the previous command line I used (it now needs to refer to avrisp2 or similar):
avrdude -p atmega3290 -c avrisp2 -P /dev/ttyS0 -v -F -e -U flash:w:raven-3290.hex
- Hey, sometimes randomly reading the source pays off! See AVR2002/res_raven_lcd/res_3290/uart.c :
/** @brief This displays a time out message to the user based on the paramter reason x. @param x Reason for USART time out. */ void timeout_msg(uint8_t x) { char str[20] = "TO "; dectoascii(x, str+3); lcd_puts(str); }
- So, gah, I shoulda listened to that gut instinct that made me think it was talking to me and grepped earlier... :-/ I assume the reason the timeout occurs is because the 1284p firmware isn't what it's expecting. (Still doesn't explain the other odd corruption though.) (Also doesn't explain why it's possible for the timeout not to occur if you time power/reset in a particular way...)
- Thus, TO = Time Out, in this case for reason (1), (and also explains why the red LED doesn't light):
// Check for SOF ch = get_char_rx(); if (ch != SOF_CHAR) return timeout_msg(1); // turn on nose LED for activity indicator led_on();
- Note that at least some of the other display corruption issue might be related to accidentally brushing against or touching the pins at the top of the LCD display itself.
- Thus, with this new (replacement) patch, I have something that seems to reliably display text (wow, progress!):
--- raven3290.c.orig 2008-07-07 23:21:19.000000000 +1200 +++ raven3290.c 2008-07-08 00:50:51.000000000 +1200 @@ -133,7 +133,11 @@ const tmenu_item menu_items[21]; #else // !DOXYGEN /** @brief This is the menu text in Flash. See menu_items[] for menu operation. */ +#if 1 +const char menu_text0[] PROGMEM = "DONKEY8"; +#else const char menu_text0[] PROGMEM = "RES 1.0"; +#endif const char menu_text1[] PROGMEM = "SETUP"; const char menu_text2[] PROGMEM = "CHANNEL"; const char menu_text3[] PROGMEM = "POWER"; @@ -222,7 +226,9 @@ key_init(); +#if 0 uart_init(); +#endif sei(); @@ -233,6 +239,13 @@ // and draw it lcd_puts_P(menu.text); + lcd_puts_P(PSTR("W00T BOOP DOOP")); + +#if 1 +#include "beep.h" + beep(); +#endif + for (;;) { // Make sure interrupts are always on
- ( 9 July 2008 )
- Here's some photos of my fix for the ATmega1284p ISP header issue—although the close-up is a bit out of focus (you can also see the expansion headers I added along the bottom edge):
- Photo of the top of my Atmel Raven Power and IO expansion board—uses 4 x AA battery for external power, but doesn't yet make use of the IO pin expansion (the observant will note I'm two sockets short on the header):
- Photo of the bottom of my Atmel Raven Power and IO expansion board:
- Poor photo of the expansion board in action with my custom scrolling LCD text—which the camera didn't like:
- Uploaded rzusbstickcommon_hh.py (see "Code" section above).
- ( 21 July 2008 )
- Happy birthday to me!
- Also, my USBtinyISP I made a while back seems to work now. Thus I can upload the firmware from a lappy via USB with:
avrdude -p atmega3290p -c usbtiny -v -U flash:w:"raven-3290.hex"
- ( 26 July 2008 )
- Pulled original AVR2017 source into SVN and tested with modified Makefile with options from avrfreaks thread. 3290 bootloader still too big. USBtinyISP isn't reliably programming board—works with the raven-3290.hex but not, for example, with the AVRRAVEN_3290P.a90 firmware.