<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.emfcamp.org/2014/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jburgess777</id>
	<title>Electromagnetic Field - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.emfcamp.org/2014/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jburgess777"/>
	<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/wiki/Special:Contributions/Jburgess777"/>
	<updated>2026-04-21T15:12:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3763</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3763"/>
		<updated>2014-10-01T23:35:17Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Atmel ICE Basic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Atmel ICE Basic ==&lt;br /&gt;
If you use an Atmel ICE then the cable needs to be connected so that it runs over the top of the board. The red stripe indicates pin 1. &lt;br /&gt;
[[File:CIMG1383.JPG|300pix|thumb|center|text-top|TiLDA connected to Atmel ICE Basic]]&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark openocd]$ sudo openocd -f interface/cmsis-dap.cfg -f target/at91sam3XXX.cfg &lt;br /&gt;
Open On-Chip Debugger 0.9.0-dev-00161-g9c47dc9-dirty (2014-09-30-23:42)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'cmsis-dap'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : CMSIS-DAP: SWD  Supported&lt;br /&gt;
Info : CMSIS-DAP: JTAG Supported&lt;br /&gt;
Info : CMSIS-DAP: Interface Initialised (SWD)&lt;br /&gt;
Info : CMSIS-DAP: FW Version = 01.00.0021&lt;br /&gt;
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1&lt;br /&gt;
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)&lt;br /&gt;
Info : CMSIS-DAP: Interface ready&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : IDCODE 0x2ba01477&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
====Alternative (Debian/Ubuntu) ====&lt;br /&gt;
&lt;br /&gt;
To do this you can download the code from http://sourceforge.net/projects/openocd/files/openocd/0.8.0/ and apply this patch http://openocd.zylin.com/#/c/2301/3/src/rtos/rtos.c,cm . &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
sudo apt-get install libusb-dev libusb-1.0-0-dev&lt;br /&gt;
./configure --enable-armjtagew&lt;br /&gt;
make &lt;br /&gt;
sudo make install&lt;br /&gt;
./configure &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CMSIS DAP ===&lt;br /&gt;
If you us an an CMSIS DAP compliant adapter such as the [[http://uk.farnell.com/atmel/atatmel-ice-basic/debugger-atmel-arm-avr-basic-kit/dp/2407172 Atmel ICE]] then OpenOCD can be run with &amp;lt;code&amp;gt;interface/cmsis-dap.cfg&amp;lt;/code&amp;gt; e.g.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f interface/cmsis-dap.cfg -f target/at91sam3XXX.cfg&lt;br /&gt;
Open On-Chip Debugger 0.9.0-dev-00161-g9c47dc9-dirty (2014-09-30-23:42)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'cmsis-dap'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : CMSIS-DAP: SWD  Supported&lt;br /&gt;
Info : CMSIS-DAP: JTAG Supported&lt;br /&gt;
Info : CMSIS-DAP: Interface Initialised (SWD)&lt;br /&gt;
Info : CMSIS-DAP: FW Version = 01.00.0021&lt;br /&gt;
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1&lt;br /&gt;
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)&lt;br /&gt;
Info : CMSIS-DAP: Interface ready&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : IDCODE 0x2ba01477&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This seems to be a little slower at single-stepping the code than the Olimex adapter but is a little cheaper and in theory provides a more flexible debug interface (SWD).&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* &amp;lt;strike&amp;gt;Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** Fixed by applying this patch to OpenOCD http://openocd.zylin.com/#/c/2303/&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3762</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3762"/>
		<updated>2014-10-01T23:34:02Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Atmel ICE Basic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Atmel ICE Basic ==&lt;br /&gt;
If you use an Atmel ICE then the cable needs to be connected so that it runs over the top of the board. The red stripe indicates pin 1. &lt;br /&gt;
[[File:CIMG1383.JPG|300pix|thumb|center|text-top|TiLDA connected to Atmel ICe Basic]]&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark openocd]$ sudo openocd -f interface/cmsis-dap.cfg -f target/at91sam3XXX.cfg &lt;br /&gt;
Open On-Chip Debugger 0.9.0-dev-00161-g9c47dc9-dirty (2014-09-30-23:42)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'cmsis-dap'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : CMSIS-DAP: SWD  Supported&lt;br /&gt;
Info : CMSIS-DAP: JTAG Supported&lt;br /&gt;
Info : CMSIS-DAP: Interface Initialised (SWD)&lt;br /&gt;
Info : CMSIS-DAP: FW Version = 01.00.0021&lt;br /&gt;
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1&lt;br /&gt;
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)&lt;br /&gt;
Info : CMSIS-DAP: Interface ready&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : IDCODE 0x2ba01477&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
====Alternative (Debian/Ubuntu) ====&lt;br /&gt;
&lt;br /&gt;
To do this you can download the code from http://sourceforge.net/projects/openocd/files/openocd/0.8.0/ and apply this patch http://openocd.zylin.com/#/c/2301/3/src/rtos/rtos.c,cm . &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
sudo apt-get install libusb-dev libusb-1.0-0-dev&lt;br /&gt;
./configure --enable-armjtagew&lt;br /&gt;
make &lt;br /&gt;
sudo make install&lt;br /&gt;
./configure &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CMSIS DAP ===&lt;br /&gt;
If you us an an CMSIS DAP compliant adapter such as the [[http://uk.farnell.com/atmel/atatmel-ice-basic/debugger-atmel-arm-avr-basic-kit/dp/2407172 Atmel ICE]] then OpenOCD can be run with &amp;lt;code&amp;gt;interface/cmsis-dap.cfg&amp;lt;/code&amp;gt; e.g.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f interface/cmsis-dap.cfg -f target/at91sam3XXX.cfg&lt;br /&gt;
Open On-Chip Debugger 0.9.0-dev-00161-g9c47dc9-dirty (2014-09-30-23:42)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'cmsis-dap'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : CMSIS-DAP: SWD  Supported&lt;br /&gt;
Info : CMSIS-DAP: JTAG Supported&lt;br /&gt;
Info : CMSIS-DAP: Interface Initialised (SWD)&lt;br /&gt;
Info : CMSIS-DAP: FW Version = 01.00.0021&lt;br /&gt;
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1&lt;br /&gt;
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)&lt;br /&gt;
Info : CMSIS-DAP: Interface ready&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : IDCODE 0x2ba01477&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This seems to be a little slower at single-stepping the code than the Olimex adapter but is a little cheaper and in theory provides a more flexible debug interface (SWD).&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* &amp;lt;strike&amp;gt;Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** Fixed by applying this patch to OpenOCD http://openocd.zylin.com/#/c/2303/&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3761</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3761"/>
		<updated>2014-10-01T23:29:06Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* CMSIS DAP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Atmel ICE Basic ==&lt;br /&gt;
If you use an Atmel ICE then the cable needs to be connected so that it runs over the top of the board. The red stripe indicates pin 1. &lt;br /&gt;
[[File:CIMG1383.JPG|300pix|thumb|center|text-top|TiLDA connected to Atmel ICe Basic]]&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
====Alternative (Debian/Ubuntu) ====&lt;br /&gt;
&lt;br /&gt;
To do this you can download the code from http://sourceforge.net/projects/openocd/files/openocd/0.8.0/ and apply this patch http://openocd.zylin.com/#/c/2301/3/src/rtos/rtos.c,cm . &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
sudo apt-get install libusb-dev libusb-1.0-0-dev&lt;br /&gt;
./configure --enable-armjtagew&lt;br /&gt;
make &lt;br /&gt;
sudo make install&lt;br /&gt;
./configure &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CMSIS DAP ===&lt;br /&gt;
If you us an an CMSIS DAP compliant adapter such as the [[http://uk.farnell.com/atmel/atatmel-ice-basic/debugger-atmel-arm-avr-basic-kit/dp/2407172 Atmel ICE]] then OpenOCD can be run with &amp;lt;code&amp;gt;interface/cmsis-dap.cfg&amp;lt;/code&amp;gt; e.g.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f interface/cmsis-dap.cfg -f target/at91sam3XXX.cfg&lt;br /&gt;
Open On-Chip Debugger 0.9.0-dev-00161-g9c47dc9-dirty (2014-09-30-23:42)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'cmsis-dap'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : CMSIS-DAP: SWD  Supported&lt;br /&gt;
Info : CMSIS-DAP: JTAG Supported&lt;br /&gt;
Info : CMSIS-DAP: Interface Initialised (SWD)&lt;br /&gt;
Info : CMSIS-DAP: FW Version = 01.00.0021&lt;br /&gt;
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1&lt;br /&gt;
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)&lt;br /&gt;
Info : CMSIS-DAP: Interface ready&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : IDCODE 0x2ba01477&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This seems to be a little slower at single-stepping the code than the Olimex adapter but is a little cheaper and in theory provides a more flexible debug interface (SWD).&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* &amp;lt;strike&amp;gt;Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** Fixed by applying this patch to OpenOCD http://openocd.zylin.com/#/c/2303/&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3760</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3760"/>
		<updated>2014-10-01T23:15:39Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* OpenOCD configuration file */ Add openocd atmel ice info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Atmel ICE Basic ==&lt;br /&gt;
If you use an Atmel ICE then the cable needs to be connected so that it runs over the top of the board. The red stripe indicates pin 1. &lt;br /&gt;
[[File:CIMG1383.JPG|300pix|thumb|center|text-top|TiLDA connected to Atmel ICe Basic]]&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
====Alternative (Debian/Ubuntu) ====&lt;br /&gt;
&lt;br /&gt;
To do this you can download the code from http://sourceforge.net/projects/openocd/files/openocd/0.8.0/ and apply this patch http://openocd.zylin.com/#/c/2301/3/src/rtos/rtos.c,cm . &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
sudo apt-get install libusb-dev libusb-1.0-0-dev&lt;br /&gt;
./configure --enable-armjtagew&lt;br /&gt;
make &lt;br /&gt;
sudo make install&lt;br /&gt;
./configure &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== CMSIS DAP ===&lt;br /&gt;
If you us an an CMSIS DAP compliant adapter such as the Atmel ICE then OpenOCD can be run with &amp;lt;code&amp;gt;interface/cmsis-dap.cfg&amp;lt;/code&amp;gt; e.g.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f interface/cmsis-dap.cfg -f target/at91sam3XXX.cfg&lt;br /&gt;
Open On-Chip Debugger 0.9.0-dev-00161-g9c47dc9-dirty (2014-09-30-23:42)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'cmsis-dap'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : CMSIS-DAP: SWD  Supported&lt;br /&gt;
Info : CMSIS-DAP: JTAG Supported&lt;br /&gt;
Info : CMSIS-DAP: Interface Initialised (SWD)&lt;br /&gt;
Info : CMSIS-DAP: FW Version = 01.00.0021&lt;br /&gt;
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1&lt;br /&gt;
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)&lt;br /&gt;
Info : CMSIS-DAP: Interface ready&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : IDCODE 0x2ba01477&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* &amp;lt;strike&amp;gt;Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** Fixed by applying this patch to OpenOCD http://openocd.zylin.com/#/c/2303/&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3759</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3759"/>
		<updated>2014-10-01T23:09:09Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Olimex adapter and USB-TINY-H */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Atmel ICE Basic ==&lt;br /&gt;
If you use an Atmel ICE then the cable needs to be connected so that it runs over the top of the board. The red stripe indicates pin 1. &lt;br /&gt;
[[File:CIMG1383.JPG|300pix|thumb|center|text-top|TiLDA connected to Atmel ICe Basic]]&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
====Alternative (Debian/Ubuntu) ====&lt;br /&gt;
&lt;br /&gt;
To do this you can download the code from http://sourceforge.net/projects/openocd/files/openocd/0.8.0/ and apply this patch http://openocd.zylin.com/#/c/2301/3/src/rtos/rtos.c,cm . &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
sudo apt-get install libusb-dev libusb-1.0-0-dev&lt;br /&gt;
./configure --enable-armjtagew&lt;br /&gt;
make &lt;br /&gt;
sudo make install&lt;br /&gt;
./configure &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* &amp;lt;strike&amp;gt;Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** Fixed by applying this patch to OpenOCD http://openocd.zylin.com/#/c/2303/&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=File:CIMG1383.JPG&amp;diff=3758</id>
		<title>File:CIMG1383.JPG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=File:CIMG1383.JPG&amp;diff=3758"/>
		<updated>2014-10-01T23:04:09Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: TilDA Connected to Atmel ICE&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TilDA Connected to Atmel ICE&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3757</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3757"/>
		<updated>2014-10-01T22:39:50Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Running the gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; 2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If the software cannot initialize the radio then try again, something seems to prevent the radio from working on the first attempt. If it still doesn't work after a couple of attempts then check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far the badge network should be sending messages which will be picked up by the badge. Turn on badge, wait for a minute or two and then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the current time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Setting the name on your badge ===&lt;br /&gt;
Each badge has a unique hardware ID which was programned into the CPU by Atmel. This hardware ID is sent to the MCP when the badge asks it to assign a badge ID. This unique hardware ID ensures that you will get the same badge ID each time you reset the badge. The MCP store this in the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The badgeID app mentions registering on a web page but we don't have this available. Instead you can add your name and nickname directly into the database and the MCP will tell your badge to display this name next time it registers. You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again, check this in the badge app. Now return to the home screen and hold the badge vertically, like it is hanging on a lanyard, with the two large holes in the PCB at the top. When the EMF logo appears your name should now be shown at the top of the screen.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notification messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=Memories&amp;diff=3753</id>
		<title>Memories</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=Memories&amp;diff=3753"/>
		<updated>2014-10-01T21:30:06Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Photos */ remove double http://&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{link-banner}}&lt;br /&gt;
Please add links to any photos, videos, etc. of EMF2014 you have ([https://wiki-archive.emfcamp.org/2012/articles/d/o/c/Documentation.html like we did in 2012]).&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
Please add links in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*[https://www.emfcamp.org EMF Website]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would look like:&lt;br /&gt;
&lt;br /&gt;
*[https://www.emfcamp.org EMF Website]&lt;br /&gt;
&lt;br /&gt;
==Before Event==&lt;br /&gt;
Set up, planning, etc.&lt;br /&gt;
&lt;br /&gt;
===Articles/Blogs===&lt;br /&gt;
*[http://hackaday.com/2014/08/16/tilda-mke-the-emf-2014-badge/ Hackaday on the badge]&lt;br /&gt;
*[http://makezine.com/2014/08/15/the-amazing-emf-conference-badge/ Make magazine on the badge]&lt;br /&gt;
*[http://www.arrl.org/news/view/emf-2014-it-takes-an-amateur-radio-village ARRL: It Takes an Amateur Radio Village]&lt;br /&gt;
*[http://www.element14.com/community/groups/maker-hacker-inventor-and-hobbyist/content?filterID=contentstatus%5Bpublished%5D~language~language%5Bcpl%5D&amp;amp;query=emfcamp: Element14 Community Blog Replications]&lt;br /&gt;
*[http://www.webtrickery.com/emf-2014/ @w1bble Blog post with a few pics of before / during / after EMF]&lt;br /&gt;
&lt;br /&gt;
===Photos===&lt;br /&gt;
*[https://www.flickr.com/photos/chaoticeunoia/15047294495/ Kitty's photographs incl take down]&lt;br /&gt;
*[https://wiki.sonologic.net/Images/EMF2014 gmc's crappy phone cam pics]&lt;br /&gt;
*[https://plus.google.com/u/0/photos/104882304117764204022/albums/6055585085939539041 OXHACK putting the E in emc]&lt;br /&gt;
*[http://www.webtrickery.com/emf-2014/ @w1bble's few pics of before / during / after EMF]&lt;br /&gt;
&lt;br /&gt;
===Videos===&lt;br /&gt;
&lt;br /&gt;
==During Event==&lt;br /&gt;
The event itself.&lt;br /&gt;
&lt;br /&gt;
===Articles/Blogs===&lt;br /&gt;
*[http://www.bbc.co.uk/news/technology-29011895 Manic Modder: Inside Ben Heck's world of bonsai computing (BBC)]&lt;br /&gt;
*[http://www.bbc.co.uk/news/technology-29011889 Electromagnetic Field: Can geeks get kids into science? (BBC)]&lt;br /&gt;
*[http://www.theguardian.com/technology/2014/sep/03/electromagnetic-field-camp-emfcamp-drones-arduino-burning-man Electromagnetic Field: the UK's Burning Man? (The Guardian)]&lt;br /&gt;
*[https://storify.com/pikesley/things-i-overheard-at-emf-camp-2014 Overheard at EMF2014]&lt;br /&gt;
*[https://storify.com/pikesley/how-to-emf How to EMF]&lt;br /&gt;
*[http://motherboard.vice.com/read/the-emojli-creators-say-you-shouldnt-make-an-app The Creators of Emojli: Don't Build an App (Motherboard/Vice)]&lt;br /&gt;
*[http://motherboard.vice.com/read/inside-uks-electromagnetic-field-festival Not Your 'Traditional Hacker Camp': Inside Electromagnetic Field Festival (Motherboard/Vice)]&lt;br /&gt;
*[http://motherboard.vice.com/read/a-call-for-geeks-to-hijack-politics The British MP Who Wants Geeks to Hijack the Politics of Surveillance (Motherboard/Vice)]&lt;br /&gt;
*[http://jhaand.nl/2014/09/emf2014-electro-magnetic-fields-hacker-festival-2014/ #EMF2014 (ELECTRO MAGNETIC FIELDS HACKER FESTIVAL 2014)]&lt;br /&gt;
*[http://squirmelia.livejournal.com/453051.html Glitch Art Workshop]&lt;br /&gt;
*[http://www.mscroggs.co.uk/blog/12 MScroggs' Flexagons talk]&lt;br /&gt;
*[http://shadow.cat/blog/mark-keating/2014/13-emf/ EMF Memories]&lt;br /&gt;
*[http://motherboard.vice.com/read/the-maker-movement-is-leaving-a-trail-of-tiny-plastic-rabbits-in-its-wake The Maker Movement is Leaving a Trail of Tiny Plastic Rabbits in its Wake]&lt;br /&gt;
&lt;br /&gt;
===Photos===&lt;br /&gt;
If you have uploaded any photos to Flickr, we would love if you also add them to the group - [https://flic.kr/g/pGAy6]&lt;br /&gt;
&lt;br /&gt;
*[https://plus.google.com/photos/113943934552095226264/albums/6054537668273419873 Saturday] - [[User:TCMSLP|TCMSLP]]&lt;br /&gt;
*[https://twitter.com/search?q=emfcamp&amp;amp;src=typd&amp;amp;mode=photos Twitter photos]&lt;br /&gt;
*[https://plus.google.com/photos/+MatthewCopperwaite/albums/6053636538009652657 Friday] [https://plus.google.com/photos/+MatthewCopperwaite/albums/6053636954715546161 Saturday] [https://plus.google.com/u/0/photos/+MatthewCopperwaite/albums/6054110412172875841 Sunday] - [[User:YaMatt|YaMatt]] ([[User talk:YaMatt|talk]])&lt;br /&gt;
*[https://plus.google.com/photos/112777126606198038716/albums/6054213887214967841?authkey=CJinnqObgtShMw Various photos including Kite mapping, The Grid and drone wars]&lt;br /&gt;
*[https://www.flickr.com/photos/matstace/sets/72157647043339236/ matstace's flickr ]&lt;br /&gt;
*[https://plus.google.com/u/0/b/107012837690078606602/photos/107012837690078606602/albums/6054051185457665105 LPRS &amp;amp; The Real Wireless Mike]&lt;br /&gt;
* [[Installations:TheGrid|TheGrid]]: I (Cillian) will retweet everything I can find at [https://twitter.com/__thegrid].&lt;br /&gt;
* some photospheres: [http://bit.ly/1lwrv26]  [http://bit.ly/1redupW]  [http://bit.ly/W6ukuE]  [http://bit.ly/W6umCI] [http://bit.ly/1tK8NXx]&lt;br /&gt;
* [https://www.flickr.com/photos/barnoid/sets/72157646690458589 Barnoid's photos]&lt;br /&gt;
* [https://www.flickr.com/photos/nicecupoftea/sets/72157647140464951/ Libby's photos]&lt;br /&gt;
* [https://www.flickr.com/photos/choffee/sets/72157646533985179/ Choffee's photos]&lt;br /&gt;
* [https://wiki.sonologic.net/Images/EMF2014 gmc's crappy phone cam pics]&lt;br /&gt;
* [https://www.flickr.com/photos/nottinghack/sets/72157646710169057/ nottinghack flickr stuff]&lt;br /&gt;
* [https://www.flickr.com/photos/sophigarrett/sets/72157646845220777 Sophie's photos]&lt;br /&gt;
* [https://foto.pho.be/20140904-emfetc/ murble's photos]&lt;br /&gt;
* [https://www.flickr.com/photos/stanto/sets/72157647239775945 [[User:Stanto]]'s pics]&lt;br /&gt;
* [https://www.flickr.com/photos/chaoticeunoia/sets/72157646903781435 [[User:Maow]]'s photos]&lt;br /&gt;
* [https://www.flickr.com/photos/unnamedculprit/sets/72157646813614377/ Matt Gray's photos]&lt;br /&gt;
* [http://fotos.hq.phicoh.net/emfcamp2014/ Phicoh's photos]&lt;br /&gt;
*[http://skippy.org.uk/hacman-hits-emf-2014/ HACman hits EMF 2014 Skippy's Random Ramblings]&lt;br /&gt;
*[https://plus.google.com/photos/104753983975472200241/albums/6055964521070184017 Jarkman's photos]&lt;br /&gt;
* [https://www.google.co.uk/maps/place/Bletchley/@51.966934,-0.79379,3a,75y,57.89h,88.07t/data=!3m5!1e1!3m3!1sFO0ZbJLF2jEAAAQYCZD53A!2e0!3e11!4m2!3m1!1s0x487655170067b787:0x6ce4726b7fb4281 Amateur Radio Village Photoshere] by Paul [[User:M0TZO|M0TZO]]&lt;br /&gt;
&lt;br /&gt;
===Videos===&lt;br /&gt;
* [http://www.bbc.co.uk/news/technology-29011898 The most future-proof profession? (BBC)]&lt;br /&gt;
* [https://www.youtube.com/watch?v=wfy_zdZbTUI Laser cutter - Just Add Sharks]&lt;br /&gt;
* [https://www.flickr.com/photos/barnoid/14905261730/ TOG Duck vs BigHak Race]&lt;br /&gt;
* [https://www.youtube.com/watch?v=tualAybVbT4 Camp Holland Timelapse]&lt;br /&gt;
* [[Installations:TheGrid|TheGrid]]: [https://www.youtube.com/watch?v=bbUKrVY6BFA Me] ([[User:Pikesley|Pikesley]]) (also [http://share.gifyoutube.com/YO1GMG.gif as a gif]), and [https://vine.co/v/OB5z299EjUW Ulrich] ([[User:Rico|Rico]])&lt;br /&gt;
* [https://www.flickr.com/photos/barnoid/15115548641/ Arriving on golf cart trailer]&lt;br /&gt;
* [https://www.youtube.com/watch?v=K_kjqArTKww Bar Bot]&lt;br /&gt;
* [https://www.youtube.com/watch?v=kcrgaEGLusY More Bar Bot]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8XTEpqlPzjE EMF Camp Saturday Aerial Tour]&lt;br /&gt;
* [https://www.youtube.com/watch?v=TCpmI0c8jZ8 EMF Camp Setup Aerial Tour and Crash]&lt;br /&gt;
* [https://www.youtube.com/watch?v=DFlOloCsxuA Rabbit The Soul Eater]&lt;br /&gt;
* [https://www.youtube.com/watch?v=x5KH4bUt8X8 Tom Scott's bit on the alcohol fogger]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8CESVHwJ95Q Ben Heck's Extreme Camping Chair Episode] [25min] [[https://www.youtube.com/watch?v=BzgWG-AOSMk Trailer]]&lt;br /&gt;
* [https://www.youtube.com/watch?v=GsyhGHUEt-k Emojli: Behind the Scenes and Why You Should Never Build An App]&lt;br /&gt;
&lt;br /&gt;
===Audio Recordings===&lt;br /&gt;
* &amp;quot;Spray Whisky On Me&amp;quot; EMFM Radio Show: it is doubtful we can publish the copyrighted songs but I hope to edit a copy of the 2am Sunday morning show when it is available.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=Memories&amp;diff=3752</id>
		<title>Memories</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=Memories&amp;diff=3752"/>
		<updated>2014-10-01T21:28:04Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Articles/Blogs */ remove double http://&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{link-banner}}&lt;br /&gt;
Please add links to any photos, videos, etc. of EMF2014 you have ([https://wiki-archive.emfcamp.org/2012/articles/d/o/c/Documentation.html like we did in 2012]).&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
Please add links in the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*[https://www.emfcamp.org EMF Website]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would look like:&lt;br /&gt;
&lt;br /&gt;
*[https://www.emfcamp.org EMF Website]&lt;br /&gt;
&lt;br /&gt;
==Before Event==&lt;br /&gt;
Set up, planning, etc.&lt;br /&gt;
&lt;br /&gt;
===Articles/Blogs===&lt;br /&gt;
*[http://hackaday.com/2014/08/16/tilda-mke-the-emf-2014-badge/ Hackaday on the badge]&lt;br /&gt;
*[http://makezine.com/2014/08/15/the-amazing-emf-conference-badge/ Make magazine on the badge]&lt;br /&gt;
*[http://www.arrl.org/news/view/emf-2014-it-takes-an-amateur-radio-village ARRL: It Takes an Amateur Radio Village]&lt;br /&gt;
*[http://www.element14.com/community/groups/maker-hacker-inventor-and-hobbyist/content?filterID=contentstatus%5Bpublished%5D~language~language%5Bcpl%5D&amp;amp;query=emfcamp: Element14 Community Blog Replications]&lt;br /&gt;
*[http://www.webtrickery.com/emf-2014/ @w1bble Blog post with a few pics of before / during / after EMF]&lt;br /&gt;
&lt;br /&gt;
===Photos===&lt;br /&gt;
*[https://www.flickr.com/photos/chaoticeunoia/15047294495/ Kitty's photographs incl take down]&lt;br /&gt;
*[https://wiki.sonologic.net/Images/EMF2014 gmc's crappy phone cam pics]&lt;br /&gt;
*[https://plus.google.com/u/0/photos/104882304117764204022/albums/6055585085939539041 OXHACK putting the E in emc]&lt;br /&gt;
*[http://http://www.webtrickery.com/emf-2014/ @w1bble's few pics of before / during / after EMF]&lt;br /&gt;
&lt;br /&gt;
===Videos===&lt;br /&gt;
&lt;br /&gt;
==During Event==&lt;br /&gt;
The event itself.&lt;br /&gt;
&lt;br /&gt;
===Articles/Blogs===&lt;br /&gt;
*[http://www.bbc.co.uk/news/technology-29011895 Manic Modder: Inside Ben Heck's world of bonsai computing (BBC)]&lt;br /&gt;
*[http://www.bbc.co.uk/news/technology-29011889 Electromagnetic Field: Can geeks get kids into science? (BBC)]&lt;br /&gt;
*[http://www.theguardian.com/technology/2014/sep/03/electromagnetic-field-camp-emfcamp-drones-arduino-burning-man Electromagnetic Field: the UK's Burning Man? (The Guardian)]&lt;br /&gt;
*[https://storify.com/pikesley/things-i-overheard-at-emf-camp-2014 Overheard at EMF2014]&lt;br /&gt;
*[https://storify.com/pikesley/how-to-emf How to EMF]&lt;br /&gt;
*[http://motherboard.vice.com/read/the-emojli-creators-say-you-shouldnt-make-an-app The Creators of Emojli: Don't Build an App (Motherboard/Vice)]&lt;br /&gt;
*[http://motherboard.vice.com/read/inside-uks-electromagnetic-field-festival Not Your 'Traditional Hacker Camp': Inside Electromagnetic Field Festival (Motherboard/Vice)]&lt;br /&gt;
*[http://motherboard.vice.com/read/a-call-for-geeks-to-hijack-politics The British MP Who Wants Geeks to Hijack the Politics of Surveillance (Motherboard/Vice)]&lt;br /&gt;
*[http://jhaand.nl/2014/09/emf2014-electro-magnetic-fields-hacker-festival-2014/ #EMF2014 (ELECTRO MAGNETIC FIELDS HACKER FESTIVAL 2014)]&lt;br /&gt;
*[http://squirmelia.livejournal.com/453051.html Glitch Art Workshop]&lt;br /&gt;
*[http://www.mscroggs.co.uk/blog/12 MScroggs' Flexagons talk]&lt;br /&gt;
*[http://shadow.cat/blog/mark-keating/2014/13-emf/ EMF Memories]&lt;br /&gt;
*[http://motherboard.vice.com/read/the-maker-movement-is-leaving-a-trail-of-tiny-plastic-rabbits-in-its-wake The Maker Movement is Leaving a Trail of Tiny Plastic Rabbits in its Wake]&lt;br /&gt;
&lt;br /&gt;
===Photos===&lt;br /&gt;
If you have uploaded any photos to Flickr, we would love if you also add them to the group - [https://flic.kr/g/pGAy6]&lt;br /&gt;
&lt;br /&gt;
*[https://plus.google.com/photos/113943934552095226264/albums/6054537668273419873 Saturday] - [[User:TCMSLP|TCMSLP]]&lt;br /&gt;
*[https://twitter.com/search?q=emfcamp&amp;amp;src=typd&amp;amp;mode=photos Twitter photos]&lt;br /&gt;
*[https://plus.google.com/photos/+MatthewCopperwaite/albums/6053636538009652657 Friday] [https://plus.google.com/photos/+MatthewCopperwaite/albums/6053636954715546161 Saturday] [https://plus.google.com/u/0/photos/+MatthewCopperwaite/albums/6054110412172875841 Sunday] - [[User:YaMatt|YaMatt]] ([[User talk:YaMatt|talk]])&lt;br /&gt;
*[https://plus.google.com/photos/112777126606198038716/albums/6054213887214967841?authkey=CJinnqObgtShMw Various photos including Kite mapping, The Grid and drone wars]&lt;br /&gt;
*[https://www.flickr.com/photos/matstace/sets/72157647043339236/ matstace's flickr ]&lt;br /&gt;
*[https://plus.google.com/u/0/b/107012837690078606602/photos/107012837690078606602/albums/6054051185457665105 LPRS &amp;amp; The Real Wireless Mike]&lt;br /&gt;
* [[Installations:TheGrid|TheGrid]]: I (Cillian) will retweet everything I can find at [https://twitter.com/__thegrid].&lt;br /&gt;
* some photospheres: [http://bit.ly/1lwrv26]  [http://bit.ly/1redupW]  [http://bit.ly/W6ukuE]  [http://bit.ly/W6umCI] [http://bit.ly/1tK8NXx]&lt;br /&gt;
* [https://www.flickr.com/photos/barnoid/sets/72157646690458589 Barnoid's photos]&lt;br /&gt;
* [https://www.flickr.com/photos/nicecupoftea/sets/72157647140464951/ Libby's photos]&lt;br /&gt;
* [https://www.flickr.com/photos/choffee/sets/72157646533985179/ Choffee's photos]&lt;br /&gt;
* [https://wiki.sonologic.net/Images/EMF2014 gmc's crappy phone cam pics]&lt;br /&gt;
* [https://www.flickr.com/photos/nottinghack/sets/72157646710169057/ nottinghack flickr stuff]&lt;br /&gt;
* [https://www.flickr.com/photos/sophigarrett/sets/72157646845220777 Sophie's photos]&lt;br /&gt;
* [https://foto.pho.be/20140904-emfetc/ murble's photos]&lt;br /&gt;
* [https://www.flickr.com/photos/stanto/sets/72157647239775945 [[User:Stanto]]'s pics]&lt;br /&gt;
* [https://www.flickr.com/photos/chaoticeunoia/sets/72157646903781435 [[User:Maow]]'s photos]&lt;br /&gt;
* [https://www.flickr.com/photos/unnamedculprit/sets/72157646813614377/ Matt Gray's photos]&lt;br /&gt;
* [http://fotos.hq.phicoh.net/emfcamp2014/ Phicoh's photos]&lt;br /&gt;
*[http://skippy.org.uk/hacman-hits-emf-2014/ HACman hits EMF 2014 Skippy's Random Ramblings]&lt;br /&gt;
*[https://plus.google.com/photos/104753983975472200241/albums/6055964521070184017 Jarkman's photos]&lt;br /&gt;
* [https://www.google.co.uk/maps/place/Bletchley/@51.966934,-0.79379,3a,75y,57.89h,88.07t/data=!3m5!1e1!3m3!1sFO0ZbJLF2jEAAAQYCZD53A!2e0!3e11!4m2!3m1!1s0x487655170067b787:0x6ce4726b7fb4281 Amateur Radio Village Photoshere] by Paul [[User:M0TZO|M0TZO]]&lt;br /&gt;
&lt;br /&gt;
===Videos===&lt;br /&gt;
* [http://www.bbc.co.uk/news/technology-29011898 The most future-proof profession? (BBC)]&lt;br /&gt;
* [https://www.youtube.com/watch?v=wfy_zdZbTUI Laser cutter - Just Add Sharks]&lt;br /&gt;
* [https://www.flickr.com/photos/barnoid/14905261730/ TOG Duck vs BigHak Race]&lt;br /&gt;
* [https://www.youtube.com/watch?v=tualAybVbT4 Camp Holland Timelapse]&lt;br /&gt;
* [[Installations:TheGrid|TheGrid]]: [https://www.youtube.com/watch?v=bbUKrVY6BFA Me] ([[User:Pikesley|Pikesley]]) (also [http://share.gifyoutube.com/YO1GMG.gif as a gif]), and [https://vine.co/v/OB5z299EjUW Ulrich] ([[User:Rico|Rico]])&lt;br /&gt;
* [https://www.flickr.com/photos/barnoid/15115548641/ Arriving on golf cart trailer]&lt;br /&gt;
* [https://www.youtube.com/watch?v=K_kjqArTKww Bar Bot]&lt;br /&gt;
* [https://www.youtube.com/watch?v=kcrgaEGLusY More Bar Bot]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8XTEpqlPzjE EMF Camp Saturday Aerial Tour]&lt;br /&gt;
* [https://www.youtube.com/watch?v=TCpmI0c8jZ8 EMF Camp Setup Aerial Tour and Crash]&lt;br /&gt;
* [https://www.youtube.com/watch?v=DFlOloCsxuA Rabbit The Soul Eater]&lt;br /&gt;
* [https://www.youtube.com/watch?v=x5KH4bUt8X8 Tom Scott's bit on the alcohol fogger]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8CESVHwJ95Q Ben Heck's Extreme Camping Chair Episode] [25min] [[https://www.youtube.com/watch?v=BzgWG-AOSMk Trailer]]&lt;br /&gt;
* [https://www.youtube.com/watch?v=GsyhGHUEt-k Emojli: Behind the Scenes and Why You Should Never Build An App]&lt;br /&gt;
&lt;br /&gt;
===Audio Recordings===&lt;br /&gt;
* &amp;quot;Spray Whisky On Me&amp;quot; EMFM Radio Show: it is doubtful we can publish the copyrighted songs but I hope to edit a copy of the 2am Sunday morning show when it is available.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3745</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3745"/>
		<updated>2014-09-24T23:58:20Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Setting the name on your badge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; 2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far the badge network should be sending messages which will be picked up by the badge. Turn on badge, wait for a minute or two and then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the current time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Setting the name on your badge ===&lt;br /&gt;
Each badge has a unique hardware ID which was programned into the CPU by Atmel. This hardware ID is sent to the MCP when the badge asks it to assign a badge ID. This unique hardware ID ensures that you will get the same badge ID each time you reset the badge. The MCP store this in the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The badgeID app mentions registering on a web page but we don't have this available. Instead you can add your name and nickname directly into the database and the MCP will tell your badge to display this name next time it registers. You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again, check this in the badge app. Now return to the home screen and hold the badge vertically, like it is hanging on a lanyard, with the two large holes in the PCB at the top. When the EMF logo appears your name should now be shown at the top of the screen.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notification messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3744</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3744"/>
		<updated>2014-09-24T23:45:33Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* The first signs of communication with the badge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; 2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far the badge network should be sending messages which will be picked up by the badge. Turn on badge, wait for a minute or two and then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the current time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Setting the name on your badge ===&lt;br /&gt;
Each badge has a unique hardware ID which was programned into the CPU by Atmel. This hardware ID is sent to the MCP when the badge asks it to assign a badge ID. This unique hardware ID ensures that you will get the same badge ID each time you reset the badge. The MCP store this in the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The badgeID app mentions registering on a web page but we don't have this available. Instead you can add your name and nickname directlry into the database and the MCP will tell your badge to display this name next time it registers. You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. &lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it is hanging on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top of the screen.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notification messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3743</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3743"/>
		<updated>2014-09-24T23:43:55Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Running the gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; 2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Setting the name on your badge ===&lt;br /&gt;
Each badge has a unique hardware ID which was programned into the CPU by Atmel. This hardware ID is sent to the MCP when the badge asks it to assign a badge ID. This unique hardware ID ensures that you will get the same badge ID each time you reset the badge. The MCP store this in the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The badgeID app mentions registering on a web page but we don't have this available. Instead you can add your name and nickname directlry into the database and the MCP will tell your badge to display this name next time it registers. You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. &lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it is hanging on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top of the screen.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notification messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3742</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3742"/>
		<updated>2014-09-24T23:40:02Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Notication messages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Setting the name on your badge ===&lt;br /&gt;
Each badge has a unique hardware ID which was programned into the CPU by Atmel. This hardware ID is sent to the MCP when the badge asks it to assign a badge ID. This unique hardware ID ensures that you will get the same badge ID each time you reset the badge. The MCP store this in the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The badgeID app mentions registering on a web page but we don't have this available. Instead you can add your name and nickname directlry into the database and the MCP will tell your badge to display this name next time it registers. You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. &lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it is hanging on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top of the screen.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notification messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3741</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3741"/>
		<updated>2014-09-24T23:39:42Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Registering the badge with your name */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Setting the name on your badge ===&lt;br /&gt;
Each badge has a unique hardware ID which was programned into the CPU by Atmel. This hardware ID is sent to the MCP when the badge asks it to assign a badge ID. This unique hardware ID ensures that you will get the same badge ID each time you reset the badge. The MCP store this in the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
The badgeID app mentions registering on a web page but we don't have this available. Instead you can add your name and nickname directlry into the database and the MCP will tell your badge to display this name next time it registers. You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. &lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it is hanging on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top of the screen.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3740</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3740"/>
		<updated>2014-09-24T23:32:55Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
== Using the badge network ==&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3739</id>
		<title>TiLDA MKe</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3739"/>
		<updated>2014-09-24T23:28:21Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Run your own wireless badge network */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA MKe project, Code name &amp;quot;ElectroMagnetic Boogaloo&amp;quot;, is being headed by [[User:Dpslwk|'RepRap' Matt]] and [[User:thinkl33t|Bob]]&lt;br /&gt;
[[File:IMG_0474.jpg|500px|right|thumb|Front]]&lt;br /&gt;
[[File:Badge_Front.png|right|thumb|Front]]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/E_(mathematical_constant) Why MKe?]&lt;br /&gt;
&lt;br /&gt;
Please Note: There are a couple of minor hardware and some firmware issues that might be effecting your badge. If you've let the magic smoke out of your charge controller or have tried to re-flash and ended up with nothing but a couple of dimly glowing lights then DO NOT DESPAIR -It's recoverable and fixes, documentation and lots of firmware are still being produced :)&lt;br /&gt;
&lt;br /&gt;
=Aim= &lt;br /&gt;
The main aim of the 2014 badge is to give camp attendees live schedule updates and notifications. As with the original TiLDA we wanted to keep with an Arduino compatible platform that will allow badge hacking during and after the camp. As with the previous badge all code and design files are available.&lt;br /&gt;
&lt;br /&gt;
==Battery Warning==&lt;br /&gt;
'''Always make sure you plug your battery in the right way round!'''  If you don't, the charge controller will let out its magic smoke and die / become damaged and die later.  The badge itself will still work, but it wont have the ability to charge anymore.  &lt;br /&gt;
&lt;br /&gt;
We think this is the cause of the charge controller issues a small number of badges had at the event was due to this mistake being made during final assembly on-site. &lt;br /&gt;
&lt;br /&gt;
'''Lithium Batteries are dangerous!'''  While these batteries are better protected than the MK1 batteries, they are still scary.  Do not short your battery, and if it starts bulging or gets punctured, '''DO NOT USE IT AGAIN''' and dispose of it properly.&lt;br /&gt;
&lt;br /&gt;
==Features and Functions==&lt;br /&gt;
[[File:Badge_Back.png|right|thumb|Back]]&lt;br /&gt;
* Torch mode - Press the light button next to the screen. It will only light up fully if it's hung upside down to avoid blinding&lt;br /&gt;
* Snake&lt;br /&gt;
* Tetris&lt;br /&gt;
&lt;br /&gt;
'''Please note that there's a known issue with the badge freezing'''. We're trying to work out what's causing this, but in the meantime pressing &amp;quot;reset&amp;quot; should get the badge back to life. Help with debugging is highly welcome!&lt;br /&gt;
&lt;br /&gt;
== How to get going ==&lt;br /&gt;
=== Set up your environment ===&lt;br /&gt;
* Plug your badge into your computer via USB&lt;br /&gt;
* Download Arduino IDE 1.5.7 from http://arduino.cc/en/main/software#toc3&lt;br /&gt;
* “git clone” or download TiLDA source code from https://github.com/emfcamp/Mk2-Firmware&lt;br /&gt;
* Start the Arduino IDE. &lt;br /&gt;
* Now you have to change the sketchbook-folder to be the folder you just cloned. To do this use File | Preferences | “Set Sketchbook location”. On MacOS, this is Arduino | Preferences &lt;br /&gt;
* Restart the Arduino IDE&lt;br /&gt;
* Open sketch “EMF2014”&lt;br /&gt;
* Set Tools | Board to MKe v0.333 (RTOS Core)&lt;br /&gt;
* Set Tools | Port to correct port (you might have to research this - some operating systems like Windows require you to install drivers or become a member of a certain group)&lt;br /&gt;
** On MacOS this is will start /dev/tty.usbmodem with 4 digits, and change for each port&lt;br /&gt;
** On Linux this is usually /dev/ttyACM0 but may be a higher number if you have other USB Serial devices&lt;br /&gt;
* Hit the upload button&lt;br /&gt;
* Wait&lt;br /&gt;
* Woohoo - You just successfully uploaded code to your badge&lt;br /&gt;
&lt;br /&gt;
=== Your first “Hello world” app ===&lt;br /&gt;
There’s a “HelloWorldApp.cpp” file in which you can play around. In order for it to show up on the Homescreen you have to uncomment line 51 in AppManager.cpp and flash the changed code to the badge. Great app pull requests are appreciated!&lt;br /&gt;
&lt;br /&gt;
If you are still using the Arduino IDE at this point, note that it will not let you edit the .cpp and .h files that are needed to create Apps for the badge. To force the IDE to re-compile/re-read any files you've edited using an external editor, make sure to go to the File -&amp;gt; Preferences dialog box, and check the &amp;quot;Use external editor&amp;quot; checkbox.&lt;br /&gt;
&lt;br /&gt;
=== Why are things so different from standard Arduino code? ===&lt;br /&gt;
We’re using a library called FreeRTOS that allows us to multitask - something that’s normally not possible with standard Arduino code. This allows us to run multiple tasks at the same time. FreeRTOS uses preemptive scheduling to switch between the task. Due to this we have to be very careful about how we do some things. For example we can’t just define interrupts for buttons in every task (imagine the mess!) or write to the serial port directly (your task might stop in the middle of the message). &lt;br /&gt;
&lt;br /&gt;
We’ve also spend quite a lot of time to make the build-in components as easy to use as possible without having every task to write lots of boilerplate code. If you feel like using the build-in components on the badge, chances are we already wrote a wrapper for them that is already used by one of the other tasks. &lt;br /&gt;
&lt;br /&gt;
Have a look at the “Documentation” section in this document for a full list of API functions. You will avoid a lot of headaches if you stick to those.&lt;br /&gt;
=== How to use the badge with pure Arduino code ===&lt;br /&gt;
If you prefer you can always start from scratch without FreeRTOS or any of our code, just keep in mind that you won’t be able to receive messages via radio or use any of the API features we already added. Just start a new sketch in the Arduino IDE for that and get going. If you want to load the main firmware again just change the sketch to “EMF2014” and upload again.&lt;br /&gt;
=== Debugging and Gotchas ===&lt;br /&gt;
* The USB serial is set up to 115200 baud. There are lots of terminals that can connect to them. See below for how to enable the debug logging.&lt;br /&gt;
* If you can’t revive a badge you can short the two erase pins and press the reset button while holding it down.&lt;br /&gt;
* Avoid busy waiting, use FreeRTOS queues and Tilda::delay() instead&lt;br /&gt;
* Don’t use low level functions like interrupts or serial ports directly unless you really, really know how FreeRTOS will handle them. For general logging you can use Tilda::log()&lt;br /&gt;
* If sending code to the badge using the Arduino IDE &amp;quot;Upload&amp;quot; button fails, even though the /dev/ttyACM0 (linux com port) is there, just retry, twice if neccessary.&lt;br /&gt;
&lt;br /&gt;
=== Code structure ===&lt;br /&gt;
* FreeRTOS has the concept of “Tasks” which work like threads. We’ve wrappered them in a class called “Task” (for background stuff) and “Apps” (for foreground, one-at-a-time things)&lt;br /&gt;
* Everything needs to be in the main EMF2014 folder. Subfolders are not allowed. This is an Arduino IDE restriction :(&lt;br /&gt;
=== Radio infrastructure ===&lt;br /&gt;
The radio infrastructure is distributed between DKs. Every “gateway” has a Raspberry Pi with two Ciseco USB radios. We never had the chance to actually try it with a large number of badges in the same spot, so please don’t expect it to work perfectly.&lt;br /&gt;
&lt;br /&gt;
=== Your own wireless badge network ===&lt;br /&gt;
[[DIY TiLDA Badge Network]] has instructions on how to setup your own private badge network using a RaspberryPi and two Ciseco radios.&lt;br /&gt;
&lt;br /&gt;
=== Contribute ===&lt;br /&gt;
Send us a pull request via [https://github.com/emfcamp/Mk2-Firmware GitHub] - We’ll do our best to review and merge the good ones during EMF so others can use them.&lt;br /&gt;
&lt;br /&gt;
=Hardware=&lt;br /&gt;
&lt;br /&gt;
The following hardware has been included on the badge.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/microcontrollers/arm/sam3x.aspx Atmel ATSAM3X8E]&lt;br /&gt;
** This is the same chip as the [http://arduino.cc/en/Main/ArduinoBoardDue Arduino Due] and gives us the base platform for the badge&lt;br /&gt;
** 32bit ARM Cortex M3 * 84MHz&lt;br /&gt;
** 512KBytes Flash RAM&lt;br /&gt;
** 96KBytes of SRAM&lt;br /&gt;
* A 128x64 pixel monochrome LCD display&lt;br /&gt;
* [http://shop.ciseco.co.uk/srf-wireless-rf-radio-surface-mount/ Ciseco SRF Radio]&lt;br /&gt;
** 868Mhz RF Transceiver&lt;br /&gt;
** Simple UART interface&lt;br /&gt;
** Low power sleep mode&lt;br /&gt;
* [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] 3-axis Accelerometer and 3-axis gyro&lt;br /&gt;
** I2C interface&lt;br /&gt;
** Tri-Axis angular rate sensor (gyro) with a sensitivity up to 131 LSBs/dps and a full-scale range of ±250, ±500, ±1000, and ±2000dps&lt;br /&gt;
** Tri-Axis accelerometer with a programmable full scale range of ±2g, ±4g, ±8g and ±16g&lt;br /&gt;
** Digital Motion Processing™ (DMP™) engine offloads complex MotionFusion, sensor timing synchronisation and gesture detection&lt;br /&gt;
* PMIC &amp;amp; LiPo&lt;br /&gt;
* Joystick&lt;br /&gt;
* Buttons&lt;br /&gt;
* RGB LEDs&lt;br /&gt;
* IR&lt;br /&gt;
* Arduino Headers&lt;br /&gt;
* Pads for wearable tech&lt;br /&gt;
&lt;br /&gt;
= Firmware Documentation =&lt;br /&gt;
== Debugging ==&lt;br /&gt;
===Enabling the USB serial debug log messages===&lt;br /&gt;
To enable the debug logging you must uncomment the following line in [https://github.com/emfcamp/Mk2-Firmware/blob/master/hardware/emfcamp/sam/libraries/debug/debug.h#L42 hardware/emfcamp/sam/libraries/debug/debug.h]&lt;br /&gt;
&lt;br /&gt;
 // Enable debug task and output&lt;br /&gt;
 // #define DEBUG 1&lt;br /&gt;
&lt;br /&gt;
===Tilda::log(String text)===&lt;br /&gt;
&lt;br /&gt;
This logs “text” to the serial console. To read it connect to it via the Arduino IDE Serial Monitor. Don’t use “SerialUSB.println” or similar -- it’s not thread-safe and you might end up with utter nonsense.&lt;br /&gt;
&lt;br /&gt;
===Debugging using the JTAG interface===&lt;br /&gt;
The JTAG interface on the board provides powerful debugging facilities like breakpoints, backtraces, dumping memory, inspecting variables, checking task states, catching exeptions etc. To make this to work requires additional hardware and software, see [[TiLDA Debugging using JTAG]].&lt;br /&gt;
&lt;br /&gt;
== Buttons ==&lt;br /&gt;
The badge has 8 buttons: Up, Down, Left, Right, Center (on the joystick), A, B and Light. You can use arduino-style “digitalRead(BUTTON_RIGHT)” to read the current status of any button, but you can’t define your own interrupt (because we already did that). This doesn’t mean you can’t wait for a certain button to be pressed, it just means you have to approach it slightly differently:&lt;br /&gt;
&lt;br /&gt;
Example: A simple app displaying the button code&lt;br /&gt;
 void ButtonApp::task() {&lt;br /&gt;
     ButtonSubscription allButtons = Tilda::createButtonSubscription(LIGHT | A | B | UP | DOWN | LEFT | RIGHT | CENTER);&lt;br /&gt;
 &lt;br /&gt;
     while(true) {&lt;br /&gt;
         Button button = allButtons.waitForPress(1000);&lt;br /&gt;
         if (button == A) {&lt;br /&gt;
             debug::log(“You pressed button A”);&lt;br /&gt;
         } else if (button == LEFT) {&lt;br /&gt;
             debug::log(“You pressed LEFT”);&lt;br /&gt;
         } else if (button == NONE) {&lt;br /&gt;
             debug::log(“No button has been pressed in 1000ms”); &lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription Tilda::createButtonSubscription(&amp;lt;buttons&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
Registers a subscriptions for a defined set of buttons and returns a ButtonSubscription. Multiple Buttons can be combined via “|” (see example above). One button can not be subscribed by more than 10 subscriptions (which shouldn’t really happen, but keep it in mind). &lt;br /&gt;
&lt;br /&gt;
Don’t use this function in a constructor, it requires FreeRTOS to be running. Using it inside the task() function is the only safe place for it.&lt;br /&gt;
&lt;br /&gt;
===Button ButtonSubscription::waitForPress(TimeInTicks timeout)===&lt;br /&gt;
&lt;br /&gt;
This is normally called in a loop. It causes the task to block until one of the buttons has been pressed. If the timeout occurs before any button has been pressed “NONE” will be returned. &lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::waitForPress()===&lt;br /&gt;
&lt;br /&gt;
The same as above, but without the timeout.&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::clear()===&lt;br /&gt;
&lt;br /&gt;
This should be called after an App has been suspended, just before it’s going to be resumed. It causes the Queue to be cleared which could otherwise lead to buttons being reported that have been pressed while other apps were in the foreground. Have a look at the FlashLightApp for an example.&lt;br /&gt;
&lt;br /&gt;
==LEDs==&lt;br /&gt;
===Tilda::setLedColor(Led led, Color color);===&lt;br /&gt;
===Tilde::setLedColor(Color color);===&lt;br /&gt;
&lt;br /&gt;
Sets the color of all or one led. Color is an object that takes red, green and blue as a value between 0 and 255 each. If no led is defined both leds will be set to the same color.&lt;br /&gt;
&lt;br /&gt;
Example: A simple color-changing task&lt;br /&gt;
 void ColorfulTask::task() {&lt;br /&gt;
     while(true) {&lt;br /&gt;
         Tilda::setLedColor(LED1, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::setLedColor(LED2, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The Display Library is based on GLCDv3 (http://playground.arduino.cc/Code/GLCDks0108), docs (http://code.google.com/p/glcd-arduino/source/browse/trunk/glcd/doc/GLCD_Documentation.pdf) but adapted to support our screen.  The Init routine is called in the setup, and the LCDTask takes care of ensuring the screen is updated every 40ms if required (Unlike the original GLCD library, screen updates are decoupled from the graphics routines.)&lt;br /&gt;
&lt;br /&gt;
Also available is M2tklib (https://code.google.com/p/m2tklib/) which is a nice toolkit library.  Further details on using this will come later, but expect the main loop to be handled for you, and just passing the menu structure you require for your app.&lt;br /&gt;
&lt;br /&gt;
Right now, you can call the GLCD functions directly with GLCD.DrawBitmap() for example.  This is going to change to be accessed through the GUITask class in the near future, to ensure only one task at a time writes to the screen.  Expect this to be simply GUITask in place of GLCD, along with a registering a redraw call back to GUITask. The bitmap format, by the way, is rather unconventional but there are a couple of utility scripts to convert popular formats down in the hacking section below - you can grab the SponsorsApp.h as an example and swap out the bitmap array with one of your choosing.&lt;br /&gt;
&lt;br /&gt;
Extra features that are included, GLCD.SetRotation() will handle rotation of the screen for you, and GLCD.CurrentWidth() and GLCD.CurrentHeight will give you the correct Width and Height for the current orientation.  GLCD.Width and GLCD.Height constants are not available, and the GLCD predefined Text areas will not be rotated for you, if you require this define your own text areas.&lt;br /&gt;
&lt;br /&gt;
Note that one function was not ported to the badge version of GLCD, &amp;quot;Printf&amp;quot;, you'll have to cope without it.&lt;br /&gt;
&lt;br /&gt;
== Sound == &lt;br /&gt;
There's a piezo on the board, but we haven't added code for it to the current firmware. Pull requests are very welcome!&lt;br /&gt;
&lt;br /&gt;
== IMU ==&lt;br /&gt;
=== Tilda::getOrientation ===&lt;br /&gt;
returns &amp;quot; ORIENTATION_HELD&amp;quot;, &amp;quot;ORIENTATION_RIGHT&amp;quot; (joystick to the right of the screen), &amp;quot;ORIENTATION_HUNG&amp;quot; or &amp;quot;ORIENTATION_LEFT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Flash Storage ==&lt;br /&gt;
We have 2mb of flash storage, but we're not using it in the main firmware - Please get this working!&lt;br /&gt;
== Data: Schedule ==&lt;br /&gt;
===Tilda::getDataStore().getSchedule(day, location) ===&lt;br /&gt;
== Date: Weather Forecast ==&lt;br /&gt;
===Tilda::getDataStore().getWeatherForecast()===&lt;br /&gt;
== Radio ==&lt;br /&gt;
There's no way of sending messages in the current version of the firmware, sorry :(&lt;br /&gt;
&lt;br /&gt;
== Time ==&lt;br /&gt;
&lt;br /&gt;
=== Tilda::delay(uint16_t delayInMs) === &lt;br /&gt;
&lt;br /&gt;
Works like Arduino’s delay(), but is FreeRTOS-safe. It’s safe to use this function before FreeRTOS has started.&lt;br /&gt;
&lt;br /&gt;
=== tilda::getClock() ===&lt;br /&gt;
&lt;br /&gt;
Returns an instance of https://github.com/MarkusLange/Arduino-Due-RTC-Library/blob/master/rtc_clock.h&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
===uint16_t tilda::getBadgeId()===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==2.12. Battery==&lt;br /&gt;
===float TiLDA::getBatteryVoltage()===&lt;br /&gt;
Returns the current voltage as a float&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getBatteryPercent()===&lt;br /&gt;
Returns the current voltage as a percentage&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getChargeState()===&lt;br /&gt;
Returns the charge state&lt;br /&gt;
&lt;br /&gt;
0 Charging&lt;br /&gt;
1 Not Charging&lt;br /&gt;
&lt;br /&gt;
=Hacking=&lt;br /&gt;
To use our board definition you will need to first get the Arduino 1.5.7 IDE from [http://arduino.cc/en/Main/Software#toc3 here]&amp;lt;br/&amp;gt;&lt;br /&gt;
Next you can download the TiLDA MKe Firmware project from either the [https://github.com/emfcamp/Mk2-Firmware github repo] or via [https://github.com/emfcamp/Mk2-Firmware/archive/master.zip direct download]&amp;lt;br/&amp;gt;&lt;br /&gt;
Now copy the &amp;quot;hardware&amp;quot; folder to your Sketchbook folder, this is usually ~/Sketchbook/&amp;lt;br&amp;gt;&lt;br /&gt;
or&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternative option is to set the Arduino 1.5.7 sketchbook folder to the Mk2-Firmware directory.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the Arduino IDE and your will be able to select TiLDA MKe v0.333 for the Tools-&amp;gt;Board menu&lt;br /&gt;
&lt;br /&gt;
* Draft 3d print-able and laser-able case files [http://www.thingiverse.com/thing:436815 here]&lt;br /&gt;
* A Python script (via [https://twitter.com/trotmaster99 @trotmaster99]) that converts a monochrome bitmap image into a format suitable for the Tilda can be found [http://pastebin.com/8XeazQjT here].&lt;br /&gt;
* A similar script in Perl to create TiLDA MKe fullscreen bitmaps from XBM: -&lt;br /&gt;
&amp;lt;div style =&amp;quot;height:200px;overflow-x:hidden;overflow-y:auto;border: 4px solid orange;&amp;quot;&amp;gt;&lt;br /&gt;
'''xbm2mke.pl by [[User:Msemtd]]'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!perl -w&lt;br /&gt;
use strict;&lt;br /&gt;
# Little script to convert a regular XBM to TiLDA MKe bitmap&lt;br /&gt;
# only tested with fullscreen bitmaps!&lt;br /&gt;
# Hot file handle magic...&lt;br /&gt;
select((select(STDERR), $| = 1)[0]);&lt;br /&gt;
select((select(STDOUT), $| = 1)[0]);&lt;br /&gt;
sub t(@);&lt;br /&gt;
sub d($);&lt;br /&gt;
sub chug($);&lt;br /&gt;
my $f = shift;&lt;br /&gt;
#~ $f = 'blankish.xbm' if not $f;&lt;br /&gt;
if(not defined $f or not $f =~ /^(.*)\.xbm$/i){&lt;br /&gt;
    die &amp;quot;Usage: gimme an XBM file dude!\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
my $name = $1;&lt;br /&gt;
t &amp;quot;Reading file '$f'...&amp;quot;;&lt;br /&gt;
my $data = chug($f);&lt;br /&gt;
t &amp;quot;OK&amp;quot;;&lt;br /&gt;
my @lines = split /^/, $data;&lt;br /&gt;
@lines = grep{chomp; s/^\s+//; s/\s+$//; length;} @lines;&lt;br /&gt;
#~ t d \@lines;&lt;br /&gt;
my($width, $height) = (0,0);&lt;br /&gt;
my @head = @lines[0..5];&lt;br /&gt;
foreach(@head){&lt;br /&gt;
    if(/_width\s+(\d+)/){$width = $1;}&lt;br /&gt;
    if(/_height\s+(\d+)/){$height = $1;}&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;width x height = $width x $height&amp;quot;;&lt;br /&gt;
my @k;&lt;br /&gt;
foreach(@lines){ push @k, split /,/; }&lt;br /&gt;
@k = grep { s/^.*(0x[0-9A-Fa-f]{1,2}).*$/$1/o; /(0x[0-9A-Fa-f]{1,2})/o } @k;&lt;br /&gt;
#~ t d \@k;&lt;br /&gt;
my $bc = scalar(@k);&lt;br /&gt;
t &amp;quot;Pulled out $bc hex bytes&amp;quot;;&lt;br /&gt;
if($bc != $width * $height / 8) {&lt;br /&gt;
    die &amp;quot;byte count $bc does not match that expected for w x h&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;OK - reorder bytes for MKe bitmap&amp;quot;;&lt;br /&gt;
my $wb = int($width/8) + (($width &amp;amp; 0x07) ? 1: 0);&lt;br /&gt;
t &amp;quot;width in whole bytes for $width pixels = $wb&amp;quot;;&lt;br /&gt;
my @mke;&lt;br /&gt;
for(my $col = 0; $col &amp;lt; $wb; $col++){&lt;br /&gt;
    for(my $row = $height - 1; $row &amp;gt;= 0; $row--){&lt;br /&gt;
        my $idx = ($row * $wb) + $col;&lt;br /&gt;
        my $val = $k[$idx];&lt;br /&gt;
        #~ t &amp;quot;Column $col + Row $row = idx $idx = $val&amp;quot;;&lt;br /&gt;
        push @mke, $val;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
my $out = &amp;quot;static const uint8_t &amp;quot;.uc($name).&amp;quot;_BM[] = {\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $width, // width\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $height , // height\n&amp;quot;;&lt;br /&gt;
#~ $out .= join(&amp;quot;, &amp;quot;, @mke);&lt;br /&gt;
while(scalar @mke){&lt;br /&gt;
	$out .= join(&amp;quot;, &amp;quot;, splice(@mke, 0, 16)).&amp;quot;,\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
$out .= &amp;quot;};\n&amp;quot;;&lt;br /&gt;
# meh, just print it out&lt;br /&gt;
t $out;&lt;br /&gt;
&lt;br /&gt;
sub t(@) {&lt;br /&gt;
    foreach (@_) {&lt;br /&gt;
       print STDOUT &amp;quot;$_\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
sub d($) {&lt;br /&gt;
    require Data::Dumper;&lt;br /&gt;
    my $s = $_[0];&lt;br /&gt;
    my $d = Data::Dumper::Dumper($s);&lt;br /&gt;
    $d =~ s/^\$VAR1 =\s*//;&lt;br /&gt;
    $d =~ s/;$//;&lt;br /&gt;
    chomp $d;&lt;br /&gt;
    return $d;&lt;br /&gt;
}&lt;br /&gt;
sub chug($) {&lt;br /&gt;
  my $filename = shift;&lt;br /&gt;
  local *F;&lt;br /&gt;
  open F, &amp;quot;&amp;lt; $filename&amp;quot; or die &amp;quot;Couldn't open `$filename': $!&amp;quot;;&lt;br /&gt;
  local $/ = undef;&lt;br /&gt;
  return &amp;lt;F&amp;gt;;&lt;br /&gt;
}  # F automatically closed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;span id=github&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Source =&lt;br /&gt;
&lt;br /&gt;
All the source code and designs are on openly available on Github:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Hardware Hardware] - the full board design&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Documentation Documentation] - a dump of relevant parts datasheets&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Firmware Firmware] - source code for the badge software&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Software Software] - server-side software for the network&lt;br /&gt;
&lt;br /&gt;
If you want to help, point your IRC client to #tilda on Freenode.&lt;br /&gt;
&lt;br /&gt;
[[Category: Badges]]&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3738</id>
		<title>TiLDA MKe</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3738"/>
		<updated>2014-09-24T23:27:37Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Run your own wirelss badge network */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA MKe project, Code name &amp;quot;ElectroMagnetic Boogaloo&amp;quot;, is being headed by [[User:Dpslwk|'RepRap' Matt]] and [[User:thinkl33t|Bob]]&lt;br /&gt;
[[File:IMG_0474.jpg|500px|right|thumb|Front]]&lt;br /&gt;
[[File:Badge_Front.png|right|thumb|Front]]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/E_(mathematical_constant) Why MKe?]&lt;br /&gt;
&lt;br /&gt;
Please Note: There are a couple of minor hardware and some firmware issues that might be effecting your badge. If you've let the magic smoke out of your charge controller or have tried to re-flash and ended up with nothing but a couple of dimly glowing lights then DO NOT DESPAIR -It's recoverable and fixes, documentation and lots of firmware are still being produced :)&lt;br /&gt;
&lt;br /&gt;
=Aim= &lt;br /&gt;
The main aim of the 2014 badge is to give camp attendees live schedule updates and notifications. As with the original TiLDA we wanted to keep with an Arduino compatible platform that will allow badge hacking during and after the camp. As with the previous badge all code and design files are available.&lt;br /&gt;
&lt;br /&gt;
==Battery Warning==&lt;br /&gt;
'''Always make sure you plug your battery in the right way round!'''  If you don't, the charge controller will let out its magic smoke and die / become damaged and die later.  The badge itself will still work, but it wont have the ability to charge anymore.  &lt;br /&gt;
&lt;br /&gt;
We think this is the cause of the charge controller issues a small number of badges had at the event was due to this mistake being made during final assembly on-site. &lt;br /&gt;
&lt;br /&gt;
'''Lithium Batteries are dangerous!'''  While these batteries are better protected than the MK1 batteries, they are still scary.  Do not short your battery, and if it starts bulging or gets punctured, '''DO NOT USE IT AGAIN''' and dispose of it properly.&lt;br /&gt;
&lt;br /&gt;
==Features and Functions==&lt;br /&gt;
[[File:Badge_Back.png|right|thumb|Back]]&lt;br /&gt;
* Torch mode - Press the light button next to the screen. It will only light up fully if it's hung upside down to avoid blinding&lt;br /&gt;
* Snake&lt;br /&gt;
* Tetris&lt;br /&gt;
&lt;br /&gt;
'''Please note that there's a known issue with the badge freezing'''. We're trying to work out what's causing this, but in the meantime pressing &amp;quot;reset&amp;quot; should get the badge back to life. Help with debugging is highly welcome!&lt;br /&gt;
&lt;br /&gt;
== How to get going ==&lt;br /&gt;
=== Set up your environment ===&lt;br /&gt;
* Plug your badge into your computer via USB&lt;br /&gt;
* Download Arduino IDE 1.5.7 from http://arduino.cc/en/main/software#toc3&lt;br /&gt;
* “git clone” or download TiLDA source code from https://github.com/emfcamp/Mk2-Firmware&lt;br /&gt;
* Start the Arduino IDE. &lt;br /&gt;
* Now you have to change the sketchbook-folder to be the folder you just cloned. To do this use File | Preferences | “Set Sketchbook location”. On MacOS, this is Arduino | Preferences &lt;br /&gt;
* Restart the Arduino IDE&lt;br /&gt;
* Open sketch “EMF2014”&lt;br /&gt;
* Set Tools | Board to MKe v0.333 (RTOS Core)&lt;br /&gt;
* Set Tools | Port to correct port (you might have to research this - some operating systems like Windows require you to install drivers or become a member of a certain group)&lt;br /&gt;
** On MacOS this is will start /dev/tty.usbmodem with 4 digits, and change for each port&lt;br /&gt;
** On Linux this is usually /dev/ttyACM0 but may be a higher number if you have other USB Serial devices&lt;br /&gt;
* Hit the upload button&lt;br /&gt;
* Wait&lt;br /&gt;
* Woohoo - You just successfully uploaded code to your badge&lt;br /&gt;
&lt;br /&gt;
=== Your first “Hello world” app ===&lt;br /&gt;
There’s a “HelloWorldApp.cpp” file in which you can play around. In order for it to show up on the Homescreen you have to uncomment line 51 in AppManager.cpp and flash the changed code to the badge. Great app pull requests are appreciated!&lt;br /&gt;
&lt;br /&gt;
If you are still using the Arduino IDE at this point, note that it will not let you edit the .cpp and .h files that are needed to create Apps for the badge. To force the IDE to re-compile/re-read any files you've edited using an external editor, make sure to go to the File -&amp;gt; Preferences dialog box, and check the &amp;quot;Use external editor&amp;quot; checkbox.&lt;br /&gt;
&lt;br /&gt;
=== Why are things so different from standard Arduino code? ===&lt;br /&gt;
We’re using a library called FreeRTOS that allows us to multitask - something that’s normally not possible with standard Arduino code. This allows us to run multiple tasks at the same time. FreeRTOS uses preemptive scheduling to switch between the task. Due to this we have to be very careful about how we do some things. For example we can’t just define interrupts for buttons in every task (imagine the mess!) or write to the serial port directly (your task might stop in the middle of the message). &lt;br /&gt;
&lt;br /&gt;
We’ve also spend quite a lot of time to make the build-in components as easy to use as possible without having every task to write lots of boilerplate code. If you feel like using the build-in components on the badge, chances are we already wrote a wrapper for them that is already used by one of the other tasks. &lt;br /&gt;
&lt;br /&gt;
Have a look at the “Documentation” section in this document for a full list of API functions. You will avoid a lot of headaches if you stick to those.&lt;br /&gt;
=== How to use the badge with pure Arduino code ===&lt;br /&gt;
If you prefer you can always start from scratch without FreeRTOS or any of our code, just keep in mind that you won’t be able to receive messages via radio or use any of the API features we already added. Just start a new sketch in the Arduino IDE for that and get going. If you want to load the main firmware again just change the sketch to “EMF2014” and upload again.&lt;br /&gt;
=== Debugging and Gotchas ===&lt;br /&gt;
* The USB serial is set up to 115200 baud. There are lots of terminals that can connect to them. See below for how to enable the debug logging.&lt;br /&gt;
* If you can’t revive a badge you can short the two erase pins and press the reset button while holding it down.&lt;br /&gt;
* Avoid busy waiting, use FreeRTOS queues and Tilda::delay() instead&lt;br /&gt;
* Don’t use low level functions like interrupts or serial ports directly unless you really, really know how FreeRTOS will handle them. For general logging you can use Tilda::log()&lt;br /&gt;
* If sending code to the badge using the Arduino IDE &amp;quot;Upload&amp;quot; button fails, even though the /dev/ttyACM0 (linux com port) is there, just retry, twice if neccessary.&lt;br /&gt;
&lt;br /&gt;
=== Code structure ===&lt;br /&gt;
* FreeRTOS has the concept of “Tasks” which work like threads. We’ve wrappered them in a class called “Task” (for background stuff) and “Apps” (for foreground, one-at-a-time things)&lt;br /&gt;
* Everything needs to be in the main EMF2014 folder. Subfolders are not allowed. This is an Arduino IDE restriction :(&lt;br /&gt;
=== Radio infrastructure ===&lt;br /&gt;
The radio infrastructure is distributed between DKs. Every “gateway” has a Raspberry Pi with two Ciseco USB radios. We never had the chance to actually try it with a large number of badges in the same spot, so please don’t expect it to work perfectly.&lt;br /&gt;
&lt;br /&gt;
=== Run your own wireless badge network ===&lt;br /&gt;
[[DIY TiLDA Badge Network]] has instructions on how to setup your own private badge network using a RaspberryPi and two Ciseco radios.&lt;br /&gt;
&lt;br /&gt;
=== Contribute ===&lt;br /&gt;
Send us a pull request via [https://github.com/emfcamp/Mk2-Firmware GitHub] - We’ll do our best to review and merge the good ones during EMF so others can use them.&lt;br /&gt;
&lt;br /&gt;
=Hardware=&lt;br /&gt;
&lt;br /&gt;
The following hardware has been included on the badge.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/microcontrollers/arm/sam3x.aspx Atmel ATSAM3X8E]&lt;br /&gt;
** This is the same chip as the [http://arduino.cc/en/Main/ArduinoBoardDue Arduino Due] and gives us the base platform for the badge&lt;br /&gt;
** 32bit ARM Cortex M3 * 84MHz&lt;br /&gt;
** 512KBytes Flash RAM&lt;br /&gt;
** 96KBytes of SRAM&lt;br /&gt;
* A 128x64 pixel monochrome LCD display&lt;br /&gt;
* [http://shop.ciseco.co.uk/srf-wireless-rf-radio-surface-mount/ Ciseco SRF Radio]&lt;br /&gt;
** 868Mhz RF Transceiver&lt;br /&gt;
** Simple UART interface&lt;br /&gt;
** Low power sleep mode&lt;br /&gt;
* [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] 3-axis Accelerometer and 3-axis gyro&lt;br /&gt;
** I2C interface&lt;br /&gt;
** Tri-Axis angular rate sensor (gyro) with a sensitivity up to 131 LSBs/dps and a full-scale range of ±250, ±500, ±1000, and ±2000dps&lt;br /&gt;
** Tri-Axis accelerometer with a programmable full scale range of ±2g, ±4g, ±8g and ±16g&lt;br /&gt;
** Digital Motion Processing™ (DMP™) engine offloads complex MotionFusion, sensor timing synchronisation and gesture detection&lt;br /&gt;
* PMIC &amp;amp; LiPo&lt;br /&gt;
* Joystick&lt;br /&gt;
* Buttons&lt;br /&gt;
* RGB LEDs&lt;br /&gt;
* IR&lt;br /&gt;
* Arduino Headers&lt;br /&gt;
* Pads for wearable tech&lt;br /&gt;
&lt;br /&gt;
= Firmware Documentation =&lt;br /&gt;
== Debugging ==&lt;br /&gt;
===Enabling the USB serial debug log messages===&lt;br /&gt;
To enable the debug logging you must uncomment the following line in [https://github.com/emfcamp/Mk2-Firmware/blob/master/hardware/emfcamp/sam/libraries/debug/debug.h#L42 hardware/emfcamp/sam/libraries/debug/debug.h]&lt;br /&gt;
&lt;br /&gt;
 // Enable debug task and output&lt;br /&gt;
 // #define DEBUG 1&lt;br /&gt;
&lt;br /&gt;
===Tilda::log(String text)===&lt;br /&gt;
&lt;br /&gt;
This logs “text” to the serial console. To read it connect to it via the Arduino IDE Serial Monitor. Don’t use “SerialUSB.println” or similar -- it’s not thread-safe and you might end up with utter nonsense.&lt;br /&gt;
&lt;br /&gt;
===Debugging using the JTAG interface===&lt;br /&gt;
The JTAG interface on the board provides powerful debugging facilities like breakpoints, backtraces, dumping memory, inspecting variables, checking task states, catching exeptions etc. To make this to work requires additional hardware and software, see [[TiLDA Debugging using JTAG]].&lt;br /&gt;
&lt;br /&gt;
== Buttons ==&lt;br /&gt;
The badge has 8 buttons: Up, Down, Left, Right, Center (on the joystick), A, B and Light. You can use arduino-style “digitalRead(BUTTON_RIGHT)” to read the current status of any button, but you can’t define your own interrupt (because we already did that). This doesn’t mean you can’t wait for a certain button to be pressed, it just means you have to approach it slightly differently:&lt;br /&gt;
&lt;br /&gt;
Example: A simple app displaying the button code&lt;br /&gt;
 void ButtonApp::task() {&lt;br /&gt;
     ButtonSubscription allButtons = Tilda::createButtonSubscription(LIGHT | A | B | UP | DOWN | LEFT | RIGHT | CENTER);&lt;br /&gt;
 &lt;br /&gt;
     while(true) {&lt;br /&gt;
         Button button = allButtons.waitForPress(1000);&lt;br /&gt;
         if (button == A) {&lt;br /&gt;
             debug::log(“You pressed button A”);&lt;br /&gt;
         } else if (button == LEFT) {&lt;br /&gt;
             debug::log(“You pressed LEFT”);&lt;br /&gt;
         } else if (button == NONE) {&lt;br /&gt;
             debug::log(“No button has been pressed in 1000ms”); &lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription Tilda::createButtonSubscription(&amp;lt;buttons&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
Registers a subscriptions for a defined set of buttons and returns a ButtonSubscription. Multiple Buttons can be combined via “|” (see example above). One button can not be subscribed by more than 10 subscriptions (which shouldn’t really happen, but keep it in mind). &lt;br /&gt;
&lt;br /&gt;
Don’t use this function in a constructor, it requires FreeRTOS to be running. Using it inside the task() function is the only safe place for it.&lt;br /&gt;
&lt;br /&gt;
===Button ButtonSubscription::waitForPress(TimeInTicks timeout)===&lt;br /&gt;
&lt;br /&gt;
This is normally called in a loop. It causes the task to block until one of the buttons has been pressed. If the timeout occurs before any button has been pressed “NONE” will be returned. &lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::waitForPress()===&lt;br /&gt;
&lt;br /&gt;
The same as above, but without the timeout.&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::clear()===&lt;br /&gt;
&lt;br /&gt;
This should be called after an App has been suspended, just before it’s going to be resumed. It causes the Queue to be cleared which could otherwise lead to buttons being reported that have been pressed while other apps were in the foreground. Have a look at the FlashLightApp for an example.&lt;br /&gt;
&lt;br /&gt;
==LEDs==&lt;br /&gt;
===Tilda::setLedColor(Led led, Color color);===&lt;br /&gt;
===Tilde::setLedColor(Color color);===&lt;br /&gt;
&lt;br /&gt;
Sets the color of all or one led. Color is an object that takes red, green and blue as a value between 0 and 255 each. If no led is defined both leds will be set to the same color.&lt;br /&gt;
&lt;br /&gt;
Example: A simple color-changing task&lt;br /&gt;
 void ColorfulTask::task() {&lt;br /&gt;
     while(true) {&lt;br /&gt;
         Tilda::setLedColor(LED1, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::setLedColor(LED2, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The Display Library is based on GLCDv3 (http://playground.arduino.cc/Code/GLCDks0108), docs (http://code.google.com/p/glcd-arduino/source/browse/trunk/glcd/doc/GLCD_Documentation.pdf) but adapted to support our screen.  The Init routine is called in the setup, and the LCDTask takes care of ensuring the screen is updated every 40ms if required (Unlike the original GLCD library, screen updates are decoupled from the graphics routines.)&lt;br /&gt;
&lt;br /&gt;
Also available is M2tklib (https://code.google.com/p/m2tklib/) which is a nice toolkit library.  Further details on using this will come later, but expect the main loop to be handled for you, and just passing the menu structure you require for your app.&lt;br /&gt;
&lt;br /&gt;
Right now, you can call the GLCD functions directly with GLCD.DrawBitmap() for example.  This is going to change to be accessed through the GUITask class in the near future, to ensure only one task at a time writes to the screen.  Expect this to be simply GUITask in place of GLCD, along with a registering a redraw call back to GUITask. The bitmap format, by the way, is rather unconventional but there are a couple of utility scripts to convert popular formats down in the hacking section below - you can grab the SponsorsApp.h as an example and swap out the bitmap array with one of your choosing.&lt;br /&gt;
&lt;br /&gt;
Extra features that are included, GLCD.SetRotation() will handle rotation of the screen for you, and GLCD.CurrentWidth() and GLCD.CurrentHeight will give you the correct Width and Height for the current orientation.  GLCD.Width and GLCD.Height constants are not available, and the GLCD predefined Text areas will not be rotated for you, if you require this define your own text areas.&lt;br /&gt;
&lt;br /&gt;
Note that one function was not ported to the badge version of GLCD, &amp;quot;Printf&amp;quot;, you'll have to cope without it.&lt;br /&gt;
&lt;br /&gt;
== Sound == &lt;br /&gt;
There's a piezo on the board, but we haven't added code for it to the current firmware. Pull requests are very welcome!&lt;br /&gt;
&lt;br /&gt;
== IMU ==&lt;br /&gt;
=== Tilda::getOrientation ===&lt;br /&gt;
returns &amp;quot; ORIENTATION_HELD&amp;quot;, &amp;quot;ORIENTATION_RIGHT&amp;quot; (joystick to the right of the screen), &amp;quot;ORIENTATION_HUNG&amp;quot; or &amp;quot;ORIENTATION_LEFT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Flash Storage ==&lt;br /&gt;
We have 2mb of flash storage, but we're not using it in the main firmware - Please get this working!&lt;br /&gt;
== Data: Schedule ==&lt;br /&gt;
===Tilda::getDataStore().getSchedule(day, location) ===&lt;br /&gt;
== Date: Weather Forecast ==&lt;br /&gt;
===Tilda::getDataStore().getWeatherForecast()===&lt;br /&gt;
== Radio ==&lt;br /&gt;
There's no way of sending messages in the current version of the firmware, sorry :(&lt;br /&gt;
&lt;br /&gt;
== Time ==&lt;br /&gt;
&lt;br /&gt;
=== Tilda::delay(uint16_t delayInMs) === &lt;br /&gt;
&lt;br /&gt;
Works like Arduino’s delay(), but is FreeRTOS-safe. It’s safe to use this function before FreeRTOS has started.&lt;br /&gt;
&lt;br /&gt;
=== tilda::getClock() ===&lt;br /&gt;
&lt;br /&gt;
Returns an instance of https://github.com/MarkusLange/Arduino-Due-RTC-Library/blob/master/rtc_clock.h&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
===uint16_t tilda::getBadgeId()===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==2.12. Battery==&lt;br /&gt;
===float TiLDA::getBatteryVoltage()===&lt;br /&gt;
Returns the current voltage as a float&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getBatteryPercent()===&lt;br /&gt;
Returns the current voltage as a percentage&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getChargeState()===&lt;br /&gt;
Returns the charge state&lt;br /&gt;
&lt;br /&gt;
0 Charging&lt;br /&gt;
1 Not Charging&lt;br /&gt;
&lt;br /&gt;
=Hacking=&lt;br /&gt;
To use our board definition you will need to first get the Arduino 1.5.7 IDE from [http://arduino.cc/en/Main/Software#toc3 here]&amp;lt;br/&amp;gt;&lt;br /&gt;
Next you can download the TiLDA MKe Firmware project from either the [https://github.com/emfcamp/Mk2-Firmware github repo] or via [https://github.com/emfcamp/Mk2-Firmware/archive/master.zip direct download]&amp;lt;br/&amp;gt;&lt;br /&gt;
Now copy the &amp;quot;hardware&amp;quot; folder to your Sketchbook folder, this is usually ~/Sketchbook/&amp;lt;br&amp;gt;&lt;br /&gt;
or&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternative option is to set the Arduino 1.5.7 sketchbook folder to the Mk2-Firmware directory.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the Arduino IDE and your will be able to select TiLDA MKe v0.333 for the Tools-&amp;gt;Board menu&lt;br /&gt;
&lt;br /&gt;
* Draft 3d print-able and laser-able case files [http://www.thingiverse.com/thing:436815 here]&lt;br /&gt;
* A Python script (via [https://twitter.com/trotmaster99 @trotmaster99]) that converts a monochrome bitmap image into a format suitable for the Tilda can be found [http://pastebin.com/8XeazQjT here].&lt;br /&gt;
* A similar script in Perl to create TiLDA MKe fullscreen bitmaps from XBM: -&lt;br /&gt;
&amp;lt;div style =&amp;quot;height:200px;overflow-x:hidden;overflow-y:auto;border: 4px solid orange;&amp;quot;&amp;gt;&lt;br /&gt;
'''xbm2mke.pl by [[User:Msemtd]]'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!perl -w&lt;br /&gt;
use strict;&lt;br /&gt;
# Little script to convert a regular XBM to TiLDA MKe bitmap&lt;br /&gt;
# only tested with fullscreen bitmaps!&lt;br /&gt;
# Hot file handle magic...&lt;br /&gt;
select((select(STDERR), $| = 1)[0]);&lt;br /&gt;
select((select(STDOUT), $| = 1)[0]);&lt;br /&gt;
sub t(@);&lt;br /&gt;
sub d($);&lt;br /&gt;
sub chug($);&lt;br /&gt;
my $f = shift;&lt;br /&gt;
#~ $f = 'blankish.xbm' if not $f;&lt;br /&gt;
if(not defined $f or not $f =~ /^(.*)\.xbm$/i){&lt;br /&gt;
    die &amp;quot;Usage: gimme an XBM file dude!\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
my $name = $1;&lt;br /&gt;
t &amp;quot;Reading file '$f'...&amp;quot;;&lt;br /&gt;
my $data = chug($f);&lt;br /&gt;
t &amp;quot;OK&amp;quot;;&lt;br /&gt;
my @lines = split /^/, $data;&lt;br /&gt;
@lines = grep{chomp; s/^\s+//; s/\s+$//; length;} @lines;&lt;br /&gt;
#~ t d \@lines;&lt;br /&gt;
my($width, $height) = (0,0);&lt;br /&gt;
my @head = @lines[0..5];&lt;br /&gt;
foreach(@head){&lt;br /&gt;
    if(/_width\s+(\d+)/){$width = $1;}&lt;br /&gt;
    if(/_height\s+(\d+)/){$height = $1;}&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;width x height = $width x $height&amp;quot;;&lt;br /&gt;
my @k;&lt;br /&gt;
foreach(@lines){ push @k, split /,/; }&lt;br /&gt;
@k = grep { s/^.*(0x[0-9A-Fa-f]{1,2}).*$/$1/o; /(0x[0-9A-Fa-f]{1,2})/o } @k;&lt;br /&gt;
#~ t d \@k;&lt;br /&gt;
my $bc = scalar(@k);&lt;br /&gt;
t &amp;quot;Pulled out $bc hex bytes&amp;quot;;&lt;br /&gt;
if($bc != $width * $height / 8) {&lt;br /&gt;
    die &amp;quot;byte count $bc does not match that expected for w x h&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;OK - reorder bytes for MKe bitmap&amp;quot;;&lt;br /&gt;
my $wb = int($width/8) + (($width &amp;amp; 0x07) ? 1: 0);&lt;br /&gt;
t &amp;quot;width in whole bytes for $width pixels = $wb&amp;quot;;&lt;br /&gt;
my @mke;&lt;br /&gt;
for(my $col = 0; $col &amp;lt; $wb; $col++){&lt;br /&gt;
    for(my $row = $height - 1; $row &amp;gt;= 0; $row--){&lt;br /&gt;
        my $idx = ($row * $wb) + $col;&lt;br /&gt;
        my $val = $k[$idx];&lt;br /&gt;
        #~ t &amp;quot;Column $col + Row $row = idx $idx = $val&amp;quot;;&lt;br /&gt;
        push @mke, $val;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
my $out = &amp;quot;static const uint8_t &amp;quot;.uc($name).&amp;quot;_BM[] = {\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $width, // width\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $height , // height\n&amp;quot;;&lt;br /&gt;
#~ $out .= join(&amp;quot;, &amp;quot;, @mke);&lt;br /&gt;
while(scalar @mke){&lt;br /&gt;
	$out .= join(&amp;quot;, &amp;quot;, splice(@mke, 0, 16)).&amp;quot;,\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
$out .= &amp;quot;};\n&amp;quot;;&lt;br /&gt;
# meh, just print it out&lt;br /&gt;
t $out;&lt;br /&gt;
&lt;br /&gt;
sub t(@) {&lt;br /&gt;
    foreach (@_) {&lt;br /&gt;
       print STDOUT &amp;quot;$_\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
sub d($) {&lt;br /&gt;
    require Data::Dumper;&lt;br /&gt;
    my $s = $_[0];&lt;br /&gt;
    my $d = Data::Dumper::Dumper($s);&lt;br /&gt;
    $d =~ s/^\$VAR1 =\s*//;&lt;br /&gt;
    $d =~ s/;$//;&lt;br /&gt;
    chomp $d;&lt;br /&gt;
    return $d;&lt;br /&gt;
}&lt;br /&gt;
sub chug($) {&lt;br /&gt;
  my $filename = shift;&lt;br /&gt;
  local *F;&lt;br /&gt;
  open F, &amp;quot;&amp;lt; $filename&amp;quot; or die &amp;quot;Couldn't open `$filename': $!&amp;quot;;&lt;br /&gt;
  local $/ = undef;&lt;br /&gt;
  return &amp;lt;F&amp;gt;;&lt;br /&gt;
}  # F automatically closed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;span id=github&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Source =&lt;br /&gt;
&lt;br /&gt;
All the source code and designs are on openly available on Github:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Hardware Hardware] - the full board design&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Documentation Documentation] - a dump of relevant parts datasheets&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Firmware Firmware] - source code for the badge software&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Software Software] - server-side software for the network&lt;br /&gt;
&lt;br /&gt;
If you want to help, point your IRC client to #tilda on Freenode.&lt;br /&gt;
&lt;br /&gt;
[[Category: Badges]]&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3737</id>
		<title>TiLDA MKe</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3737"/>
		<updated>2014-09-24T23:27:21Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Radio infrastructure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA MKe project, Code name &amp;quot;ElectroMagnetic Boogaloo&amp;quot;, is being headed by [[User:Dpslwk|'RepRap' Matt]] and [[User:thinkl33t|Bob]]&lt;br /&gt;
[[File:IMG_0474.jpg|500px|right|thumb|Front]]&lt;br /&gt;
[[File:Badge_Front.png|right|thumb|Front]]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/E_(mathematical_constant) Why MKe?]&lt;br /&gt;
&lt;br /&gt;
Please Note: There are a couple of minor hardware and some firmware issues that might be effecting your badge. If you've let the magic smoke out of your charge controller or have tried to re-flash and ended up with nothing but a couple of dimly glowing lights then DO NOT DESPAIR -It's recoverable and fixes, documentation and lots of firmware are still being produced :)&lt;br /&gt;
&lt;br /&gt;
=Aim= &lt;br /&gt;
The main aim of the 2014 badge is to give camp attendees live schedule updates and notifications. As with the original TiLDA we wanted to keep with an Arduino compatible platform that will allow badge hacking during and after the camp. As with the previous badge all code and design files are available.&lt;br /&gt;
&lt;br /&gt;
==Battery Warning==&lt;br /&gt;
'''Always make sure you plug your battery in the right way round!'''  If you don't, the charge controller will let out its magic smoke and die / become damaged and die later.  The badge itself will still work, but it wont have the ability to charge anymore.  &lt;br /&gt;
&lt;br /&gt;
We think this is the cause of the charge controller issues a small number of badges had at the event was due to this mistake being made during final assembly on-site. &lt;br /&gt;
&lt;br /&gt;
'''Lithium Batteries are dangerous!'''  While these batteries are better protected than the MK1 batteries, they are still scary.  Do not short your battery, and if it starts bulging or gets punctured, '''DO NOT USE IT AGAIN''' and dispose of it properly.&lt;br /&gt;
&lt;br /&gt;
==Features and Functions==&lt;br /&gt;
[[File:Badge_Back.png|right|thumb|Back]]&lt;br /&gt;
* Torch mode - Press the light button next to the screen. It will only light up fully if it's hung upside down to avoid blinding&lt;br /&gt;
* Snake&lt;br /&gt;
* Tetris&lt;br /&gt;
&lt;br /&gt;
'''Please note that there's a known issue with the badge freezing'''. We're trying to work out what's causing this, but in the meantime pressing &amp;quot;reset&amp;quot; should get the badge back to life. Help with debugging is highly welcome!&lt;br /&gt;
&lt;br /&gt;
== How to get going ==&lt;br /&gt;
=== Set up your environment ===&lt;br /&gt;
* Plug your badge into your computer via USB&lt;br /&gt;
* Download Arduino IDE 1.5.7 from http://arduino.cc/en/main/software#toc3&lt;br /&gt;
* “git clone” or download TiLDA source code from https://github.com/emfcamp/Mk2-Firmware&lt;br /&gt;
* Start the Arduino IDE. &lt;br /&gt;
* Now you have to change the sketchbook-folder to be the folder you just cloned. To do this use File | Preferences | “Set Sketchbook location”. On MacOS, this is Arduino | Preferences &lt;br /&gt;
* Restart the Arduino IDE&lt;br /&gt;
* Open sketch “EMF2014”&lt;br /&gt;
* Set Tools | Board to MKe v0.333 (RTOS Core)&lt;br /&gt;
* Set Tools | Port to correct port (you might have to research this - some operating systems like Windows require you to install drivers or become a member of a certain group)&lt;br /&gt;
** On MacOS this is will start /dev/tty.usbmodem with 4 digits, and change for each port&lt;br /&gt;
** On Linux this is usually /dev/ttyACM0 but may be a higher number if you have other USB Serial devices&lt;br /&gt;
* Hit the upload button&lt;br /&gt;
* Wait&lt;br /&gt;
* Woohoo - You just successfully uploaded code to your badge&lt;br /&gt;
&lt;br /&gt;
=== Your first “Hello world” app ===&lt;br /&gt;
There’s a “HelloWorldApp.cpp” file in which you can play around. In order for it to show up on the Homescreen you have to uncomment line 51 in AppManager.cpp and flash the changed code to the badge. Great app pull requests are appreciated!&lt;br /&gt;
&lt;br /&gt;
If you are still using the Arduino IDE at this point, note that it will not let you edit the .cpp and .h files that are needed to create Apps for the badge. To force the IDE to re-compile/re-read any files you've edited using an external editor, make sure to go to the File -&amp;gt; Preferences dialog box, and check the &amp;quot;Use external editor&amp;quot; checkbox.&lt;br /&gt;
&lt;br /&gt;
=== Why are things so different from standard Arduino code? ===&lt;br /&gt;
We’re using a library called FreeRTOS that allows us to multitask - something that’s normally not possible with standard Arduino code. This allows us to run multiple tasks at the same time. FreeRTOS uses preemptive scheduling to switch between the task. Due to this we have to be very careful about how we do some things. For example we can’t just define interrupts for buttons in every task (imagine the mess!) or write to the serial port directly (your task might stop in the middle of the message). &lt;br /&gt;
&lt;br /&gt;
We’ve also spend quite a lot of time to make the build-in components as easy to use as possible without having every task to write lots of boilerplate code. If you feel like using the build-in components on the badge, chances are we already wrote a wrapper for them that is already used by one of the other tasks. &lt;br /&gt;
&lt;br /&gt;
Have a look at the “Documentation” section in this document for a full list of API functions. You will avoid a lot of headaches if you stick to those.&lt;br /&gt;
=== How to use the badge with pure Arduino code ===&lt;br /&gt;
If you prefer you can always start from scratch without FreeRTOS or any of our code, just keep in mind that you won’t be able to receive messages via radio or use any of the API features we already added. Just start a new sketch in the Arduino IDE for that and get going. If you want to load the main firmware again just change the sketch to “EMF2014” and upload again.&lt;br /&gt;
=== Debugging and Gotchas ===&lt;br /&gt;
* The USB serial is set up to 115200 baud. There are lots of terminals that can connect to them. See below for how to enable the debug logging.&lt;br /&gt;
* If you can’t revive a badge you can short the two erase pins and press the reset button while holding it down.&lt;br /&gt;
* Avoid busy waiting, use FreeRTOS queues and Tilda::delay() instead&lt;br /&gt;
* Don’t use low level functions like interrupts or serial ports directly unless you really, really know how FreeRTOS will handle them. For general logging you can use Tilda::log()&lt;br /&gt;
* If sending code to the badge using the Arduino IDE &amp;quot;Upload&amp;quot; button fails, even though the /dev/ttyACM0 (linux com port) is there, just retry, twice if neccessary.&lt;br /&gt;
&lt;br /&gt;
=== Code structure ===&lt;br /&gt;
* FreeRTOS has the concept of “Tasks” which work like threads. We’ve wrappered them in a class called “Task” (for background stuff) and “Apps” (for foreground, one-at-a-time things)&lt;br /&gt;
* Everything needs to be in the main EMF2014 folder. Subfolders are not allowed. This is an Arduino IDE restriction :(&lt;br /&gt;
=== Radio infrastructure ===&lt;br /&gt;
The radio infrastructure is distributed between DKs. Every “gateway” has a Raspberry Pi with two Ciseco USB radios. We never had the chance to actually try it with a large number of badges in the same spot, so please don’t expect it to work perfectly.&lt;br /&gt;
&lt;br /&gt;
=== Run your own wirelss badge network ===&lt;br /&gt;
[[DIY TiLDA Badge Network]] has instructions on how to setup your own private badge network using a RaspberryPi and two Ciseco radios.&lt;br /&gt;
&lt;br /&gt;
=== Contribute ===&lt;br /&gt;
Send us a pull request via [https://github.com/emfcamp/Mk2-Firmware GitHub] - We’ll do our best to review and merge the good ones during EMF so others can use them.&lt;br /&gt;
&lt;br /&gt;
=Hardware=&lt;br /&gt;
&lt;br /&gt;
The following hardware has been included on the badge.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/microcontrollers/arm/sam3x.aspx Atmel ATSAM3X8E]&lt;br /&gt;
** This is the same chip as the [http://arduino.cc/en/Main/ArduinoBoardDue Arduino Due] and gives us the base platform for the badge&lt;br /&gt;
** 32bit ARM Cortex M3 * 84MHz&lt;br /&gt;
** 512KBytes Flash RAM&lt;br /&gt;
** 96KBytes of SRAM&lt;br /&gt;
* A 128x64 pixel monochrome LCD display&lt;br /&gt;
* [http://shop.ciseco.co.uk/srf-wireless-rf-radio-surface-mount/ Ciseco SRF Radio]&lt;br /&gt;
** 868Mhz RF Transceiver&lt;br /&gt;
** Simple UART interface&lt;br /&gt;
** Low power sleep mode&lt;br /&gt;
* [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] 3-axis Accelerometer and 3-axis gyro&lt;br /&gt;
** I2C interface&lt;br /&gt;
** Tri-Axis angular rate sensor (gyro) with a sensitivity up to 131 LSBs/dps and a full-scale range of ±250, ±500, ±1000, and ±2000dps&lt;br /&gt;
** Tri-Axis accelerometer with a programmable full scale range of ±2g, ±4g, ±8g and ±16g&lt;br /&gt;
** Digital Motion Processing™ (DMP™) engine offloads complex MotionFusion, sensor timing synchronisation and gesture detection&lt;br /&gt;
* PMIC &amp;amp; LiPo&lt;br /&gt;
* Joystick&lt;br /&gt;
* Buttons&lt;br /&gt;
* RGB LEDs&lt;br /&gt;
* IR&lt;br /&gt;
* Arduino Headers&lt;br /&gt;
* Pads for wearable tech&lt;br /&gt;
&lt;br /&gt;
= Firmware Documentation =&lt;br /&gt;
== Debugging ==&lt;br /&gt;
===Enabling the USB serial debug log messages===&lt;br /&gt;
To enable the debug logging you must uncomment the following line in [https://github.com/emfcamp/Mk2-Firmware/blob/master/hardware/emfcamp/sam/libraries/debug/debug.h#L42 hardware/emfcamp/sam/libraries/debug/debug.h]&lt;br /&gt;
&lt;br /&gt;
 // Enable debug task and output&lt;br /&gt;
 // #define DEBUG 1&lt;br /&gt;
&lt;br /&gt;
===Tilda::log(String text)===&lt;br /&gt;
&lt;br /&gt;
This logs “text” to the serial console. To read it connect to it via the Arduino IDE Serial Monitor. Don’t use “SerialUSB.println” or similar -- it’s not thread-safe and you might end up with utter nonsense.&lt;br /&gt;
&lt;br /&gt;
===Debugging using the JTAG interface===&lt;br /&gt;
The JTAG interface on the board provides powerful debugging facilities like breakpoints, backtraces, dumping memory, inspecting variables, checking task states, catching exeptions etc. To make this to work requires additional hardware and software, see [[TiLDA Debugging using JTAG]].&lt;br /&gt;
&lt;br /&gt;
== Buttons ==&lt;br /&gt;
The badge has 8 buttons: Up, Down, Left, Right, Center (on the joystick), A, B and Light. You can use arduino-style “digitalRead(BUTTON_RIGHT)” to read the current status of any button, but you can’t define your own interrupt (because we already did that). This doesn’t mean you can’t wait for a certain button to be pressed, it just means you have to approach it slightly differently:&lt;br /&gt;
&lt;br /&gt;
Example: A simple app displaying the button code&lt;br /&gt;
 void ButtonApp::task() {&lt;br /&gt;
     ButtonSubscription allButtons = Tilda::createButtonSubscription(LIGHT | A | B | UP | DOWN | LEFT | RIGHT | CENTER);&lt;br /&gt;
 &lt;br /&gt;
     while(true) {&lt;br /&gt;
         Button button = allButtons.waitForPress(1000);&lt;br /&gt;
         if (button == A) {&lt;br /&gt;
             debug::log(“You pressed button A”);&lt;br /&gt;
         } else if (button == LEFT) {&lt;br /&gt;
             debug::log(“You pressed LEFT”);&lt;br /&gt;
         } else if (button == NONE) {&lt;br /&gt;
             debug::log(“No button has been pressed in 1000ms”); &lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription Tilda::createButtonSubscription(&amp;lt;buttons&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
Registers a subscriptions for a defined set of buttons and returns a ButtonSubscription. Multiple Buttons can be combined via “|” (see example above). One button can not be subscribed by more than 10 subscriptions (which shouldn’t really happen, but keep it in mind). &lt;br /&gt;
&lt;br /&gt;
Don’t use this function in a constructor, it requires FreeRTOS to be running. Using it inside the task() function is the only safe place for it.&lt;br /&gt;
&lt;br /&gt;
===Button ButtonSubscription::waitForPress(TimeInTicks timeout)===&lt;br /&gt;
&lt;br /&gt;
This is normally called in a loop. It causes the task to block until one of the buttons has been pressed. If the timeout occurs before any button has been pressed “NONE” will be returned. &lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::waitForPress()===&lt;br /&gt;
&lt;br /&gt;
The same as above, but without the timeout.&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::clear()===&lt;br /&gt;
&lt;br /&gt;
This should be called after an App has been suspended, just before it’s going to be resumed. It causes the Queue to be cleared which could otherwise lead to buttons being reported that have been pressed while other apps were in the foreground. Have a look at the FlashLightApp for an example.&lt;br /&gt;
&lt;br /&gt;
==LEDs==&lt;br /&gt;
===Tilda::setLedColor(Led led, Color color);===&lt;br /&gt;
===Tilde::setLedColor(Color color);===&lt;br /&gt;
&lt;br /&gt;
Sets the color of all or one led. Color is an object that takes red, green and blue as a value between 0 and 255 each. If no led is defined both leds will be set to the same color.&lt;br /&gt;
&lt;br /&gt;
Example: A simple color-changing task&lt;br /&gt;
 void ColorfulTask::task() {&lt;br /&gt;
     while(true) {&lt;br /&gt;
         Tilda::setLedColor(LED1, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::setLedColor(LED2, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The Display Library is based on GLCDv3 (http://playground.arduino.cc/Code/GLCDks0108), docs (http://code.google.com/p/glcd-arduino/source/browse/trunk/glcd/doc/GLCD_Documentation.pdf) but adapted to support our screen.  The Init routine is called in the setup, and the LCDTask takes care of ensuring the screen is updated every 40ms if required (Unlike the original GLCD library, screen updates are decoupled from the graphics routines.)&lt;br /&gt;
&lt;br /&gt;
Also available is M2tklib (https://code.google.com/p/m2tklib/) which is a nice toolkit library.  Further details on using this will come later, but expect the main loop to be handled for you, and just passing the menu structure you require for your app.&lt;br /&gt;
&lt;br /&gt;
Right now, you can call the GLCD functions directly with GLCD.DrawBitmap() for example.  This is going to change to be accessed through the GUITask class in the near future, to ensure only one task at a time writes to the screen.  Expect this to be simply GUITask in place of GLCD, along with a registering a redraw call back to GUITask. The bitmap format, by the way, is rather unconventional but there are a couple of utility scripts to convert popular formats down in the hacking section below - you can grab the SponsorsApp.h as an example and swap out the bitmap array with one of your choosing.&lt;br /&gt;
&lt;br /&gt;
Extra features that are included, GLCD.SetRotation() will handle rotation of the screen for you, and GLCD.CurrentWidth() and GLCD.CurrentHeight will give you the correct Width and Height for the current orientation.  GLCD.Width and GLCD.Height constants are not available, and the GLCD predefined Text areas will not be rotated for you, if you require this define your own text areas.&lt;br /&gt;
&lt;br /&gt;
Note that one function was not ported to the badge version of GLCD, &amp;quot;Printf&amp;quot;, you'll have to cope without it.&lt;br /&gt;
&lt;br /&gt;
== Sound == &lt;br /&gt;
There's a piezo on the board, but we haven't added code for it to the current firmware. Pull requests are very welcome!&lt;br /&gt;
&lt;br /&gt;
== IMU ==&lt;br /&gt;
=== Tilda::getOrientation ===&lt;br /&gt;
returns &amp;quot; ORIENTATION_HELD&amp;quot;, &amp;quot;ORIENTATION_RIGHT&amp;quot; (joystick to the right of the screen), &amp;quot;ORIENTATION_HUNG&amp;quot; or &amp;quot;ORIENTATION_LEFT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Flash Storage ==&lt;br /&gt;
We have 2mb of flash storage, but we're not using it in the main firmware - Please get this working!&lt;br /&gt;
== Data: Schedule ==&lt;br /&gt;
===Tilda::getDataStore().getSchedule(day, location) ===&lt;br /&gt;
== Date: Weather Forecast ==&lt;br /&gt;
===Tilda::getDataStore().getWeatherForecast()===&lt;br /&gt;
== Radio ==&lt;br /&gt;
There's no way of sending messages in the current version of the firmware, sorry :(&lt;br /&gt;
&lt;br /&gt;
== Time ==&lt;br /&gt;
&lt;br /&gt;
=== Tilda::delay(uint16_t delayInMs) === &lt;br /&gt;
&lt;br /&gt;
Works like Arduino’s delay(), but is FreeRTOS-safe. It’s safe to use this function before FreeRTOS has started.&lt;br /&gt;
&lt;br /&gt;
=== tilda::getClock() ===&lt;br /&gt;
&lt;br /&gt;
Returns an instance of https://github.com/MarkusLange/Arduino-Due-RTC-Library/blob/master/rtc_clock.h&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
===uint16_t tilda::getBadgeId()===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==2.12. Battery==&lt;br /&gt;
===float TiLDA::getBatteryVoltage()===&lt;br /&gt;
Returns the current voltage as a float&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getBatteryPercent()===&lt;br /&gt;
Returns the current voltage as a percentage&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getChargeState()===&lt;br /&gt;
Returns the charge state&lt;br /&gt;
&lt;br /&gt;
0 Charging&lt;br /&gt;
1 Not Charging&lt;br /&gt;
&lt;br /&gt;
=Hacking=&lt;br /&gt;
To use our board definition you will need to first get the Arduino 1.5.7 IDE from [http://arduino.cc/en/Main/Software#toc3 here]&amp;lt;br/&amp;gt;&lt;br /&gt;
Next you can download the TiLDA MKe Firmware project from either the [https://github.com/emfcamp/Mk2-Firmware github repo] or via [https://github.com/emfcamp/Mk2-Firmware/archive/master.zip direct download]&amp;lt;br/&amp;gt;&lt;br /&gt;
Now copy the &amp;quot;hardware&amp;quot; folder to your Sketchbook folder, this is usually ~/Sketchbook/&amp;lt;br&amp;gt;&lt;br /&gt;
or&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternative option is to set the Arduino 1.5.7 sketchbook folder to the Mk2-Firmware directory.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the Arduino IDE and your will be able to select TiLDA MKe v0.333 for the Tools-&amp;gt;Board menu&lt;br /&gt;
&lt;br /&gt;
* Draft 3d print-able and laser-able case files [http://www.thingiverse.com/thing:436815 here]&lt;br /&gt;
* A Python script (via [https://twitter.com/trotmaster99 @trotmaster99]) that converts a monochrome bitmap image into a format suitable for the Tilda can be found [http://pastebin.com/8XeazQjT here].&lt;br /&gt;
* A similar script in Perl to create TiLDA MKe fullscreen bitmaps from XBM: -&lt;br /&gt;
&amp;lt;div style =&amp;quot;height:200px;overflow-x:hidden;overflow-y:auto;border: 4px solid orange;&amp;quot;&amp;gt;&lt;br /&gt;
'''xbm2mke.pl by [[User:Msemtd]]'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!perl -w&lt;br /&gt;
use strict;&lt;br /&gt;
# Little script to convert a regular XBM to TiLDA MKe bitmap&lt;br /&gt;
# only tested with fullscreen bitmaps!&lt;br /&gt;
# Hot file handle magic...&lt;br /&gt;
select((select(STDERR), $| = 1)[0]);&lt;br /&gt;
select((select(STDOUT), $| = 1)[0]);&lt;br /&gt;
sub t(@);&lt;br /&gt;
sub d($);&lt;br /&gt;
sub chug($);&lt;br /&gt;
my $f = shift;&lt;br /&gt;
#~ $f = 'blankish.xbm' if not $f;&lt;br /&gt;
if(not defined $f or not $f =~ /^(.*)\.xbm$/i){&lt;br /&gt;
    die &amp;quot;Usage: gimme an XBM file dude!\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
my $name = $1;&lt;br /&gt;
t &amp;quot;Reading file '$f'...&amp;quot;;&lt;br /&gt;
my $data = chug($f);&lt;br /&gt;
t &amp;quot;OK&amp;quot;;&lt;br /&gt;
my @lines = split /^/, $data;&lt;br /&gt;
@lines = grep{chomp; s/^\s+//; s/\s+$//; length;} @lines;&lt;br /&gt;
#~ t d \@lines;&lt;br /&gt;
my($width, $height) = (0,0);&lt;br /&gt;
my @head = @lines[0..5];&lt;br /&gt;
foreach(@head){&lt;br /&gt;
    if(/_width\s+(\d+)/){$width = $1;}&lt;br /&gt;
    if(/_height\s+(\d+)/){$height = $1;}&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;width x height = $width x $height&amp;quot;;&lt;br /&gt;
my @k;&lt;br /&gt;
foreach(@lines){ push @k, split /,/; }&lt;br /&gt;
@k = grep { s/^.*(0x[0-9A-Fa-f]{1,2}).*$/$1/o; /(0x[0-9A-Fa-f]{1,2})/o } @k;&lt;br /&gt;
#~ t d \@k;&lt;br /&gt;
my $bc = scalar(@k);&lt;br /&gt;
t &amp;quot;Pulled out $bc hex bytes&amp;quot;;&lt;br /&gt;
if($bc != $width * $height / 8) {&lt;br /&gt;
    die &amp;quot;byte count $bc does not match that expected for w x h&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;OK - reorder bytes for MKe bitmap&amp;quot;;&lt;br /&gt;
my $wb = int($width/8) + (($width &amp;amp; 0x07) ? 1: 0);&lt;br /&gt;
t &amp;quot;width in whole bytes for $width pixels = $wb&amp;quot;;&lt;br /&gt;
my @mke;&lt;br /&gt;
for(my $col = 0; $col &amp;lt; $wb; $col++){&lt;br /&gt;
    for(my $row = $height - 1; $row &amp;gt;= 0; $row--){&lt;br /&gt;
        my $idx = ($row * $wb) + $col;&lt;br /&gt;
        my $val = $k[$idx];&lt;br /&gt;
        #~ t &amp;quot;Column $col + Row $row = idx $idx = $val&amp;quot;;&lt;br /&gt;
        push @mke, $val;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
my $out = &amp;quot;static const uint8_t &amp;quot;.uc($name).&amp;quot;_BM[] = {\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $width, // width\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $height , // height\n&amp;quot;;&lt;br /&gt;
#~ $out .= join(&amp;quot;, &amp;quot;, @mke);&lt;br /&gt;
while(scalar @mke){&lt;br /&gt;
	$out .= join(&amp;quot;, &amp;quot;, splice(@mke, 0, 16)).&amp;quot;,\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
$out .= &amp;quot;};\n&amp;quot;;&lt;br /&gt;
# meh, just print it out&lt;br /&gt;
t $out;&lt;br /&gt;
&lt;br /&gt;
sub t(@) {&lt;br /&gt;
    foreach (@_) {&lt;br /&gt;
       print STDOUT &amp;quot;$_\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
sub d($) {&lt;br /&gt;
    require Data::Dumper;&lt;br /&gt;
    my $s = $_[0];&lt;br /&gt;
    my $d = Data::Dumper::Dumper($s);&lt;br /&gt;
    $d =~ s/^\$VAR1 =\s*//;&lt;br /&gt;
    $d =~ s/;$//;&lt;br /&gt;
    chomp $d;&lt;br /&gt;
    return $d;&lt;br /&gt;
}&lt;br /&gt;
sub chug($) {&lt;br /&gt;
  my $filename = shift;&lt;br /&gt;
  local *F;&lt;br /&gt;
  open F, &amp;quot;&amp;lt; $filename&amp;quot; or die &amp;quot;Couldn't open `$filename': $!&amp;quot;;&lt;br /&gt;
  local $/ = undef;&lt;br /&gt;
  return &amp;lt;F&amp;gt;;&lt;br /&gt;
}  # F automatically closed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;span id=github&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Source =&lt;br /&gt;
&lt;br /&gt;
All the source code and designs are on openly available on Github:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Hardware Hardware] - the full board design&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Documentation Documentation] - a dump of relevant parts datasheets&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Firmware Firmware] - source code for the badge software&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Software Software] - server-side software for the network&lt;br /&gt;
&lt;br /&gt;
If you want to help, point your IRC client to #tilda on Freenode.&lt;br /&gt;
&lt;br /&gt;
[[Category: Badges]]&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3736</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3736"/>
		<updated>2014-09-24T23:22:49Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Ideas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas and areas for improvement ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3735</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3735"/>
		<updated>2014-09-24T23:20:07Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Web interface */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://RPi-IP-Address:8888/index.html&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3734</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3734"/>
		<updated>2014-09-24T23:19:32Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Update public key in badge firmware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
This will output the information you need to add to the firmware source code:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware.&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  http://RPi-IP-Address:8888/index.html&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3733</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3733"/>
		<updated>2014-09-24T23:18:01Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Running the gateway */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). &lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
==== Why two radios? ====&lt;br /&gt;
The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
==== MCP radio messages ====&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
==== The first signs of communication with the badge ====&lt;br /&gt;
Once you have reached this far you, the badge network should be sending messages which will be picked up by the badge. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware. &lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  http://RPi-IP-Address:8888/index.html&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3732</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3732"/>
		<updated>2014-09-24T23:11:10Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges. The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
&lt;br /&gt;
If you have got this far then you have now got the badge network running. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware. &lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  http://RPi-IP-Address:8888/index.html&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3731</id>
		<title>DIY TiLDA Badge Network</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=DIY_TiLDA_Badge_Network&amp;diff=3731"/>
		<updated>2014-09-24T23:10:35Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: Describe steps of how to build your own TiLDA badge network&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The steps below allow you to setup your own private wireless badge network for your TiLDA badge to connect to. The wireless network lets the badge display the current time, display your name and send notification messages to the badge.&lt;br /&gt;
&lt;br /&gt;
There are quite a lot of steps to getting this working. The instructions below assume the following hardware and software:&lt;br /&gt;
* TiLDA Mke&lt;br /&gt;
* Raspberry Pi, PSU, keyboard HDMI cable, monitor/TV, Ethernet cable or Wifi&lt;br /&gt;
* 2 Ciseco radios: USB + Slice of Radio (for RPi), or a second USB radio instead&lt;br /&gt;
* Internet connection for downloading new packages&lt;br /&gt;
* 4GB SD Card (or larger)&lt;br /&gt;
&lt;br /&gt;
If you don't have a Raspberry Pi then you may be able to substitute it with another Linux PC. You might also use two Ciseco USB radios instead. &lt;br /&gt;
&lt;br /&gt;
== Network architecture ==&lt;br /&gt;
The key components of the badge network are:&lt;br /&gt;
* Master control program (MCP), this stores a central copy of all information and generates the content of the radio messages.&lt;br /&gt;
* Gateways, these have the radios and pass the radio messages to and from the MCP.&lt;br /&gt;
* Database, this stores the registered gateways, badges and users.&lt;br /&gt;
* Web server, this provides a status page and web API &lt;br /&gt;
* some example scripts which use the web API to send special messages to the badges&lt;br /&gt;
&lt;br /&gt;
For the purposes of these instructions we run all this software on a single RaspberryPi. These instructions are simplified to assume you just want to run this network for yourself and willing to run everything as the 'pi' user. &lt;br /&gt;
&lt;br /&gt;
== Installation steps ==&lt;br /&gt;
=== Installing initial OS and hardware install ===&lt;br /&gt;
* Download http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2014-09-12/2014-09-09-wheezy-raspbian.zip&lt;br /&gt;
* Write to SD card&lt;br /&gt;
* Plug SD card into Rpi&lt;br /&gt;
* Connect Slice Of Radio&lt;br /&gt;
* Connect USB Ciseco radio&lt;br /&gt;
* Connect keyboard&lt;br /&gt;
* Use Ethernet cable to connect RPi to your network&lt;br /&gt;
* Connect HDMI to TV/Monitor&lt;br /&gt;
* Power On&lt;br /&gt;
&lt;br /&gt;
=== OS configuration ===&lt;br /&gt;
When the RPi has booted it will present the raspi-config UI. By default, the raspian software will try to use the serial port connected to the radio for a serial console and this must be disabled otherwise we cannot use the radio:&lt;br /&gt;
* Select 'Advanced'&lt;br /&gt;
* Select 'A7 Serial - Enable/Disable shell and kernel messages on the serial connection'&lt;br /&gt;
* Choose No&lt;br /&gt;
* Select &amp;quot;expand filesystem&amp;quot; option&lt;br /&gt;
* Select &amp;quot;finish&amp;quot; + and say yes to &amp;quot;reboot now?&amp;quot;&lt;br /&gt;
Wait for RPi to reboot&lt;br /&gt;
After reboot you can choose whether you want to carry on with HDMI + local keyboard or SSH to device using the IP address that is displayed.&lt;br /&gt;
The default login for the RPi is &amp;quot;pi&amp;quot; + &amp;quot;raspberry&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Package installation ===&lt;br /&gt;
The software relies on several packages which must be downloaded and installed. The installation will take some time. Ignore any errors about being unable to contact the Wolfram package repository.&lt;br /&gt;
  sudo apt-get update&lt;br /&gt;
  sudo apt-get install -y python-pip python-dev python-requests postgresql postgresql-server-dev-9.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checkout Mk2-Software ===&lt;br /&gt;
The forked copy of the software below has a few additions to make the setup and installation work using these instructions&lt;br /&gt;
  cd ~&lt;br /&gt;
  git clone --branch diy-badge-network https://github.com/jburgess777/Mk2-Software.git&lt;br /&gt;
&lt;br /&gt;
=== PostgreSQL database configuration ===&lt;br /&gt;
We must add a 'pi' user and create a 'schedule' database used to store information about the gateways, badges and users. The final command will emit several lines of messages as it creates various tables and indexes.&lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  sudo -u postgres createuser -D -R -S pi&lt;br /&gt;
  sudo -u postgres createdb -O pi schedule&lt;br /&gt;
  psql -f schedule.sql schedule&lt;br /&gt;
&lt;br /&gt;
=== Setup python software packages ===&lt;br /&gt;
The badge network softwre relies on several python libraries which must be downloaded and built&lt;br /&gt;
  sudo ./setup.py develop&lt;br /&gt;
&lt;br /&gt;
=== Generate radio message signing keys ===&lt;br /&gt;
The messages sent across the badge network are signed with a cryptographic key to ensure that the badges only accept messages from an authorized network. Since we don't have the keys that are in the current TiLDA firmware we must create our own.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make signer&lt;br /&gt;
  make keys.txt&lt;br /&gt;
  make keys.sh&lt;br /&gt;
&lt;br /&gt;
=== Running the MCP software ===&lt;br /&gt;
Before starting the MCP we must first load the keys we generated above. When the MCP is started it will display messages about its configuration and start listening for gateways to connect. &lt;br /&gt;
  cd ~/Mk2-Software&lt;br /&gt;
  source lib/keys.sh&lt;br /&gt;
  mcp.py&lt;br /&gt;
&lt;br /&gt;
=== Running the gateway ===&lt;br /&gt;
Open another connection to the Pi (or switch tty with alt-Fx keys and login as 'pi'). When you start the gateway it opens up the serial ports for the two radios and configures them to communicate with the badges. The first radio is used solely to broadcast discovery information to notify the badges about the existance of the gateway. All gateways transmit on the same discovery channel and the badge will connect to the gateway with the strongest signal (RSSI). These discovery messages include information about the channel used by the second radio and the time.  Once the badge chooses a gateway it will switch to the channel which is unique to the gateway. This second radio will be used for all future communcation between the badge and the network.&lt;br /&gt;
  gateway.py localhost&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 19:46:46,700 - UsbRadios - INFO - Found radio: /dev/ttyACM0, speed 115200&lt;br /&gt;
  2014-09-24 19:46:46,734 - UsbRadios - INFO - Found radio: /dev/ttyAMA0, speed 9600&lt;br /&gt;
  2014-09-24 19:46:46,741 - UsbRadios - INFO - Entering AT mode...&lt;br /&gt;
  2014-09-24 19:46:47,955 - UsbRadios - INFO - Reading information for /dev/ttyACM0&lt;br /&gt;
  2014-09-24 19:46:48,065 - UsbRadios - INFO - Firmware: 0.51B USB&lt;br /&gt;
  2014-09-24 19:46:49,428 - UsbRadios - INFO - Reading information for /dev/ttyAMA0&lt;br /&gt;
  2014-09-24 19:46:49,557 - UsbRadios - INFO - Firmware: 0.90B SORSRF&lt;br /&gt;
  2014-09-24 19:46:50,569 - main - INFO - MAC: 202481588515999&lt;br /&gt;
  2014-09-24 19:46:50,698 - main - INFO - Established connection to mcp&lt;br /&gt;
  2014-09-24 19:46:50,718 - Gateway - INFO - Transmitter started&lt;br /&gt;
  2014-09-24 19:46:52,764 - UsbRadios - INFO - Configuring radio 0 with [u'ATPK08', u'ATCN02', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:54,081 - UsbRadios - INFO - Applied command 'ATPK08' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,191 - UsbRadios - INFO - Applied command 'ATCN02' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,321 - UsbRadios - INFO - Applied command 'ATAC' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,449 - UsbRadios - INFO - Applied command 'ATDN' to radio 0, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:54,452 - UsbRadios - INFO - Configuring radio 1 with [u'ATPK3A', u'ATCN06', u'ATAC', u'ATDN']&lt;br /&gt;
  2014-09-24 19:46:55,819 - UsbRadios - INFO - Applied command 'ATPK3A' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:55,939 - UsbRadios - INFO - Applied command 'ATCN06' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,077 - UsbRadios - INFO - Applied command 'ATAC' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,214 - UsbRadios - INFO - Applied command 'ATDN' to radio 1, got 'OK'&lt;br /&gt;
  2014-09-24 19:46:56,226 - Gateway - INFO - Receiver started&lt;br /&gt;
  2014-09-24 19:46:56,767 - UsbRadios - DEBUG - Packet send via radio 0: 100&lt;br /&gt;
  2014-09-24 19:47:01,625 - UsbRadios - DEBUG - Packet send via radio 0: 200&lt;br /&gt;
  ... more radio messages every 5 seconds&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If the software cannot initialize the radio then double check that you completed the first setup step which told you to turn off the serial console.&lt;br /&gt;
&lt;br /&gt;
The MCP instructs each geateway to send a packet every 5 seconds. This packet includes timing information telling the badges when they should communicate back to the gateway. The content of these messages is displayed in the MCP output:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:&amp;quot;*&amp;quot;, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window_to_all_connections&amp;quot;, &amp;quot;num_queues&amp;quot;:1, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;payload_len&amp;quot;:4, &amp;quot;rid&amp;quot;:45057, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  {&amp;quot;cid&amp;quot;:1, &amp;quot;duration_in_sec&amp;quot;:5.2, &amp;quot;event&amp;quot;:&amp;quot;add_transmit_window&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;DataQueue&amp;quot;, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  b0010000000488e69316cbed2390e1f92ccd85016af2a55000b61abbf83a6ddf77fdb7b1c175803a163cb68a852fb5ddba9f6129329259fe581b&lt;br /&gt;
  b0010000138800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  {&amp;quot;event&amp;quot;:&amp;quot;pause_connection_for_duration&amp;quot;, &amp;quot;origin&amp;quot;:&amp;quot;MainChannelSender&amp;quot;, &amp;quot;pause_until&amp;quot;:1411588017.319312, &amp;quot;time&amp;quot;:&amp;quot;2014-09-24 19:46:52&amp;quot;}&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The first 2 bytes of all radio messages indicate the message type, or RID. This is 'b001' for the packets above. &lt;br /&gt;
&lt;br /&gt;
If you have got this far then you have now got the badge network running. Turn on badge and wait for a minute or two then press up/down button to refresh the display. With any luck the &amp;quot;Welcome&amp;quot; at the top of the screen will be replaced with the time and some status messages will appear at the bottom of the screen showing a randomly generated gateway ID and the radio signal strength.&lt;br /&gt;
&lt;br /&gt;
=== Update public key in badge firmware ===&lt;br /&gt;
During one of the earlier steps we generated a random key for the radio messages in this badge network. The default badge firmware only trusts messages signed by the official EMF camp signing key which we don't have. To get any further we need to update the public key in the badge firmware to make it trust the messages from your new MCP.&lt;br /&gt;
  cd ~/Mk2-Software/lib&lt;br /&gt;
  make keys.c&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  # To make your badge trust messages signed by your&lt;br /&gt;
  # new key pair you must replace the public key in&lt;br /&gt;
  # EMF2014Config.h with:&lt;br /&gt;
  &lt;br /&gt;
  const uint8_t EMF_PUBLIC_KEY[40] = {&lt;br /&gt;
    ... lots of hex numbers ...&lt;br /&gt;
  };&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Open the EMF2014Config.h from the Mk2-Firmware/EMD2014 sketch. Find and replace the EMF_PUBLIC_KEY with the one that was printed above. Open the arduino IDE, connect your badge to via USB, build &amp;amp; flash the new firmware. &lt;br /&gt;
&lt;br /&gt;
=== Registering the badge on the network ===&lt;br /&gt;
After you have installed the firmware above the badge will reboot. Wait a few minutes and this time the badge should register itself to the network. The output on the gateway program should show it receiving messages from the badge, beginning &amp;quot;9002...&amp;quot;. These messages are the badge requesting a badge ID from the MCP:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  2014-09-24 20:08:37,274 - UsbRadios - DEBUG - Packet send via radio 0: 26100&lt;br /&gt;
  2014-09-24 20:08:42,274 - UsbRadios - DEBUG - Packet send via radio 0: 26200&lt;br /&gt;
  2014-09-24 20:08:47,274 - UsbRadios - DEBUG - Packet send via radio 0: 26300&lt;br /&gt;
  2014-09-24 20:08:50,303 - Gateway - DEBUG - Received packet with rssi -42: 0a&lt;br /&gt;
  2014-09-24 20:08:52,273 - UsbRadios - DEBUG - Packet send via radio 0: 26400&lt;br /&gt;
  2014-09-24 20:08:56,250 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:08:58,274 - UsbRadios - DEBUG - Packet send via radio 0: 26500&lt;br /&gt;
  2014-09-24 20:09:01,825 - Gateway - DEBUG - Received packet with rssi -42: 90020000203132503834353631343031333030360000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  2014-09-24 20:09:03,274 - UsbRadios - DEBUG - Packet send via radio 0: 26600&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The MCP window should show it transmitting the signed response packets starting &amp;quot;b002...&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  b002000000268f1f16ee0a4f5fe7dcb4a69bacdc0f4038c87d368dc2527a26fe7f86a232e0804bf10645afe414a90d122d8241e200f464f2d7cf&lt;br /&gt;
  b0022031325038343536313430313330303600010000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now select the BadeID app on your TiLDA then it should now say that it has been assigned badge ID EMF0001.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
The MCP software runs a web interface and API on port 8888, point your web browser at:&lt;br /&gt;
  http://RPi-IP-Address:8888/index.html&lt;br /&gt;
&lt;br /&gt;
=== Registering the badge with your name ===&lt;br /&gt;
When the badge was assigned an ID it was added to the 'badge' table in the database:&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  pi@raspberrypi ~ $ psql schedule&lt;br /&gt;
  psql (9.1.13)&lt;br /&gt;
  Type &amp;quot;help&amp;quot; for help.&lt;br /&gt;
  &lt;br /&gt;
  schedule=&amp;gt; select * from badge;&lt;br /&gt;
   id |               hwid               | date | gwid &lt;br /&gt;
  ----+----------------------------------+------+------&lt;br /&gt;
    1 | 20313250383435363134303133303036 |      |    1&lt;br /&gt;
  (1 row)&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
You can tell the MCP to associate this badge with your name by adding an entry in the 'user' table it in the DB (unfortunately the web frontend for this is not available). You can personalize the name and nickname however the LCD can only display strings of up to 10 characters. The EMF0001 badge ID is the one that your badge should have obtained earlier.&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  schedule=&amp;gt; INSERT INTO &amp;quot;user&amp;quot; VALUES ( 'My Name', 'Nickname', 'EMF0001' );&lt;br /&gt;
  INSERT 0 1&lt;br /&gt;
  schedule=&amp;gt; \q&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
To make your badge learn this new name you must hit reset and wait for it to acquire its badge ID again. Each badge has a unique ID which is progammed into the CPU by Atmel. This is used to identify the badge when it registers itself.&lt;br /&gt;
&lt;br /&gt;
Check that the badge app is displaying the EMF0001 ID again. Now return to the home screen and hold the badge vertically, like it would hang on the lanard, with the two large holes in the PCB at the top. When the EMF logo appears your name should be shown at the top.&lt;br /&gt;
&lt;br /&gt;
=== Notication messages ===&lt;br /&gt;
The badges and network have the ability to send a text message to a specific badge, or to all badges. The command below sends a message to all badges and this should appear on your badge after a few seconds delay:&lt;br /&gt;
  cd ~/Mk2-Software/emfbroadcaster&lt;br /&gt;
  ./flashmsg.py &amp;quot;Hello from my DIY badge network&amp;quot;&lt;br /&gt;
Or a message to a specific badge number:&lt;br /&gt;
  ./dm.py 1 &amp;quot;message to badge one&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Weather ===&lt;br /&gt;
The &amp;lt;code&amp;gt;weather.py&amp;lt;/code&amp;gt; script will send weather updates but you must register for a Met Office API key and place this in the &amp;lt;code&amp;gt;~/Mk2-Software/etc/secret_config.json&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
=== Schedule ===&lt;br /&gt;
The &amp;lt;code&amp;gt;schedule.py&amp;lt;/code&amp;gt; script broadcasts schedule update to the badge. This requires additional information to be added to an 'event' table in the database. There is currently no documentation on how to do this.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
* The badge notification messages include LED and sound fields to make the user aware of the alert but these are not implemented in badge firmware.&lt;br /&gt;
* The badge sends a packet on RID 9004 which indicates its battery status. Currently the MCP prints a message saying it received this but does nothing else with it. It might be interesting to log the battery information and RSSI into a file or database as an example of how to collect data from the badges.&lt;br /&gt;
* Enhance the EMFTris and Snake apps to tell the MCP about the highscores. Record in a log and create a web page showing the highscores for each badge. &lt;br /&gt;
* The current badge architecture was designed around the needs of a large distributed system. In an isolated network it would be nice to have a special mode which works with just a single radio. Or perhaps send the data to the badge via the USB serial so no radio is necessary at all.&lt;br /&gt;
* Add a voting app which broadcasts a question to all badges, shows the choices on the screen and uses a button to select. Send the response back to the MCP and display the results on a web page.&lt;br /&gt;
* The original Mk2-Software relies on a special radio firmware mode 'ATZD3' which indicates the end of paket boundary and RSSI. This firmware was specially made by Ciseco for EMFCamp and this feature is not present in the standard radios. The forked Mk2-Software has some tweaks to make it work with the standard firmware but this lacks the RSSI information and may not work with multiple badges. It might be possible to use one of the other radio debug modes (ATZD1 or ATZD2) which the public firmware supports to provide the same information as ATZD3.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3728</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3728"/>
		<updated>2014-09-18T19:23:45Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Known issues */ Add patch for switching threads automatically in GDB&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* &amp;lt;strike&amp;gt;Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&amp;lt;/strike&amp;gt;&lt;br /&gt;
** Fixed by applying this patch to OpenOCD http://openocd.zylin.com/#/c/2303/&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3727</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3727"/>
		<updated>2014-09-17T20:56:43Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Known issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* GDB hits an assert if you detach the target and asks whether you want a core dump.&lt;br /&gt;
** This appears to be: https://sourceware.org/bugzilla/show_bug.cgi?id=12228&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3726</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3726"/>
		<updated>2014-09-17T20:41:03Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* OpenOCD configuration file */ simplify tilda.cfg, update example for openocd-0.8.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Recommended for OpenOCD-0.7&lt;br /&gt;
# script interface/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# Recommended for OpenOCD-0.8&lt;br /&gt;
script interface/ftdi/olimex-arm-usb-tiny-h.cfg&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
script target/at91sam3XXX.cfg&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -rtos FreeRTOS&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
OpenOCD uses libusb to access the device and may need to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.8.0 (2014-09-17-20:52)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* On exit GDB hits an assert and asks whether you want a core dump.&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3714</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3714"/>
		<updated>2014-09-15T23:37:01Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Prerequisites */ Add reference to header part code from schematic, it looks the same as what I used&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
** or Harwin M50-3500542 (part number from the TiLDA schematic)&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. I combined two of the example which came with the package to produce the file I use below. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Olimex ARM-USB-TINY-H&lt;br /&gt;
#&lt;br /&gt;
# http://www.olimex.com/dev/arm-usb-tiny-h.html&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
interface ft2232&lt;br /&gt;
ft2232_device_desc &amp;quot;Olimex OpenOCD JTAG ARM-USB-TINY-H&amp;quot;&lt;br /&gt;
ft2232_layout olimex-jtag&lt;br /&gt;
ft2232_vid_pid 0x15ba 0x002a&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
#&lt;br /&gt;
# at91sam3u4e&lt;br /&gt;
# at91sam3u2e&lt;br /&gt;
# at91sam3u1e&lt;br /&gt;
# at91sam3u4c&lt;br /&gt;
# at91sam3u2c&lt;br /&gt;
# at91sam3u1c&lt;br /&gt;
#&lt;br /&gt;
# at91sam3s4c&lt;br /&gt;
# at91sam3s4b&lt;br /&gt;
# at91sam3s4a&lt;br /&gt;
# at91sam3s2c&lt;br /&gt;
# at91sam3s2b&lt;br /&gt;
# at91sam3s2a&lt;br /&gt;
# at91sam3s1c&lt;br /&gt;
# at91sam3s1b&lt;br /&gt;
# at91sam3s1a&lt;br /&gt;
#&lt;br /&gt;
# at91sam3A4C&lt;br /&gt;
# at91sam3A8C&lt;br /&gt;
# at91sam3X4C&lt;br /&gt;
# at91sam3X4E&lt;br /&gt;
# at91sam3X8C&lt;br /&gt;
# at91sam3X8E&lt;br /&gt;
# at91sam3X8H&lt;br /&gt;
if { [info exists CHIPNAME] } {&lt;br /&gt;
   set _CHIPNAME $CHIPNAME&lt;br /&gt;
} else {&lt;br /&gt;
   set _CHIPNAME sam3&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if { [info exists ENDIAN] } {&lt;br /&gt;
   set _ENDIAN $ENDIAN&lt;br /&gt;
} else {&lt;br /&gt;
   set _ENDIAN little&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# JTAG speed should be &amp;lt;= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz&lt;br /&gt;
#&lt;br /&gt;
# Since we may be running of an RC oscilator, we crank down the speed a&lt;br /&gt;
# bit more to be on the safe side. Perhaps superstition, but if are&lt;br /&gt;
# running off a crystal, we can run closer to the limit. Note&lt;br /&gt;
# that there can be a pretty wide band where things are more or less stable.&lt;br /&gt;
&lt;br /&gt;
adapter_khz 500&lt;br /&gt;
&lt;br /&gt;
adapter_nsrst_delay 100&lt;br /&gt;
jtag_ntrst_delay 100&lt;br /&gt;
&lt;br /&gt;
#jtag scan chain&lt;br /&gt;
if { [info exists CPUTAPID] } {&lt;br /&gt;
   set _CPUTAPID $CPUTAPID&lt;br /&gt;
} else {&lt;br /&gt;
   set _CPUTAPID 0x4ba00477&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID&lt;br /&gt;
&lt;br /&gt;
set _TARGETNAME $_CHIPNAME.cpu&lt;br /&gt;
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME -rtos FreeRTOS&lt;br /&gt;
&lt;br /&gt;
# 16K is plenty, the smallest chip has this much&lt;br /&gt;
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -event gdb-flash-erase-start {&lt;br /&gt;
    halt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# if srst is not fitted use SYSRESETREQ to&lt;br /&gt;
# perform a soft reset&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
The version of OpenOCD I'm using uses libusb to access the device. I needed to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.7.0 (2014-09-14-17:34)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m3 reset_config sysresetreq&lt;br /&gt;
Info : max TCK change to: 30000 kHz&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The OpenOCD-0.8.0 release adds a new ftdi driver which the [https://www.olimex.com/Products/ARM/JTAG/_resources/ARM-USB-TINY_and_TINY_H_manual.pdf Olimex TINY manual] now recommends is used instead:&lt;br /&gt;
&lt;br /&gt;
 Please note that since OpenOCD 0.8.0 FTDI drivers are recommended!&lt;br /&gt;
 It was quite the opposite before 0.8.0 when LibUSB drivers were&lt;br /&gt;
 suggested as default.&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* On exit GDB hits an assert and asks whether you want a core dump.&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3713</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3713"/>
		<updated>2014-09-15T21:48:51Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Known issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. I combined two of the example which came with the package to produce the file I use below. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Olimex ARM-USB-TINY-H&lt;br /&gt;
#&lt;br /&gt;
# http://www.olimex.com/dev/arm-usb-tiny-h.html&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
interface ft2232&lt;br /&gt;
ft2232_device_desc &amp;quot;Olimex OpenOCD JTAG ARM-USB-TINY-H&amp;quot;&lt;br /&gt;
ft2232_layout olimex-jtag&lt;br /&gt;
ft2232_vid_pid 0x15ba 0x002a&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
#&lt;br /&gt;
# at91sam3u4e&lt;br /&gt;
# at91sam3u2e&lt;br /&gt;
# at91sam3u1e&lt;br /&gt;
# at91sam3u4c&lt;br /&gt;
# at91sam3u2c&lt;br /&gt;
# at91sam3u1c&lt;br /&gt;
#&lt;br /&gt;
# at91sam3s4c&lt;br /&gt;
# at91sam3s4b&lt;br /&gt;
# at91sam3s4a&lt;br /&gt;
# at91sam3s2c&lt;br /&gt;
# at91sam3s2b&lt;br /&gt;
# at91sam3s2a&lt;br /&gt;
# at91sam3s1c&lt;br /&gt;
# at91sam3s1b&lt;br /&gt;
# at91sam3s1a&lt;br /&gt;
#&lt;br /&gt;
# at91sam3A4C&lt;br /&gt;
# at91sam3A8C&lt;br /&gt;
# at91sam3X4C&lt;br /&gt;
# at91sam3X4E&lt;br /&gt;
# at91sam3X8C&lt;br /&gt;
# at91sam3X8E&lt;br /&gt;
# at91sam3X8H&lt;br /&gt;
if { [info exists CHIPNAME] } {&lt;br /&gt;
   set _CHIPNAME $CHIPNAME&lt;br /&gt;
} else {&lt;br /&gt;
   set _CHIPNAME sam3&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if { [info exists ENDIAN] } {&lt;br /&gt;
   set _ENDIAN $ENDIAN&lt;br /&gt;
} else {&lt;br /&gt;
   set _ENDIAN little&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# JTAG speed should be &amp;lt;= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz&lt;br /&gt;
#&lt;br /&gt;
# Since we may be running of an RC oscilator, we crank down the speed a&lt;br /&gt;
# bit more to be on the safe side. Perhaps superstition, but if are&lt;br /&gt;
# running off a crystal, we can run closer to the limit. Note&lt;br /&gt;
# that there can be a pretty wide band where things are more or less stable.&lt;br /&gt;
&lt;br /&gt;
adapter_khz 500&lt;br /&gt;
&lt;br /&gt;
adapter_nsrst_delay 100&lt;br /&gt;
jtag_ntrst_delay 100&lt;br /&gt;
&lt;br /&gt;
#jtag scan chain&lt;br /&gt;
if { [info exists CPUTAPID] } {&lt;br /&gt;
   set _CPUTAPID $CPUTAPID&lt;br /&gt;
} else {&lt;br /&gt;
   set _CPUTAPID 0x4ba00477&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID&lt;br /&gt;
&lt;br /&gt;
set _TARGETNAME $_CHIPNAME.cpu&lt;br /&gt;
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME -rtos FreeRTOS&lt;br /&gt;
&lt;br /&gt;
# 16K is plenty, the smallest chip has this much&lt;br /&gt;
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -event gdb-flash-erase-start {&lt;br /&gt;
    halt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# if srst is not fitted use SYSRESETREQ to&lt;br /&gt;
# perform a soft reset&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
The version of OpenOCD I'm using uses libusb to access the device. I needed to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.7.0 (2014-09-14-17:34)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m3 reset_config sysresetreq&lt;br /&gt;
Info : max TCK change to: 30000 kHz&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The OpenOCD-0.8.0 release adds a new ftdi driver which the [https://www.olimex.com/Products/ARM/JTAG/_resources/ARM-USB-TINY_and_TINY_H_manual.pdf Olimex TINY manual] now recommends is used instead:&lt;br /&gt;
&lt;br /&gt;
 Please note that since OpenOCD 0.8.0 FTDI drivers are recommended!&lt;br /&gt;
 It was quite the opposite before 0.8.0 when LibUSB drivers were&lt;br /&gt;
 suggested as default.&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
== Known issues ==&lt;br /&gt;
* Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* On exit GDB hits an assert and asks whether you want a core dump.&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3712</id>
		<title>TiLDA MKe</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3712"/>
		<updated>2014-09-15T21:46:06Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Debugging */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA MKe project, Code name &amp;quot;ElectroMagnetic Boogaloo&amp;quot;, is being headed by [[User:Dpslwk|'RepRap' Matt]] and [[User:thinkl33t|Bob]]&lt;br /&gt;
[[File:IMG_0474.jpg|500px|right|thumb|Front]]&lt;br /&gt;
[[File:Badge_Front.png|right|thumb|Front]]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/E_(mathematical_constant) Why MKe?]&lt;br /&gt;
&lt;br /&gt;
Please Note: There are a couple of minor hardware and some firmware issues that might be effecting your badge. If you've let the magic smoke out of your charge controller or have tried to re-flash and ended up with nothing but a couple of dimly glowing lights then DO NOT DESPAIR -It's recoverable and fixes, documentation and lots of firmware are still being produced :)&lt;br /&gt;
&lt;br /&gt;
=Aim= &lt;br /&gt;
The main aim of the 2014 badge is to give camp attendees live schedule updates and notifications. As with the original TiLDA we wanted to keep with an Arduino compatible platform that will allow badge hacking during and after the camp. As with the previous badge all code and design files are available.&lt;br /&gt;
&lt;br /&gt;
==Battery Warning==&lt;br /&gt;
'''Always make sure you plug your battery in the right way round!'''  If you don't, the charge controller will let out its magic smoke and die / become damaged and die later.  The badge itself will still work, but it wont have the ability to charge anymore.  &lt;br /&gt;
&lt;br /&gt;
We think this is the cause of the charge controller issues a small number of badges had at the event was due to this mistake being made during final assembly on-site. &lt;br /&gt;
&lt;br /&gt;
'''Lithium Batteries are dangerous!'''  While these batteries are better protected than the MK1 batteries, they are still scary.  Do not short your battery, and if it starts bulging or gets punctured, '''DO NOT USE IT AGAIN''' and dispose of it properly.&lt;br /&gt;
&lt;br /&gt;
==Features and Functions==&lt;br /&gt;
[[File:Badge_Back.png|right|thumb|Back]]&lt;br /&gt;
* Torch mode - Press the light button next to the screen. It will only light up fully if it's hung upside down to avoid blinding&lt;br /&gt;
* Snake&lt;br /&gt;
* Tetris&lt;br /&gt;
&lt;br /&gt;
'''Please note that there's a known issue with the badge freezing'''. We're trying to work out what's causing this, but in the meantime pressing &amp;quot;reset&amp;quot; should get the badge back to life. Help with debugging is highly welcome!&lt;br /&gt;
&lt;br /&gt;
== How to get going ==&lt;br /&gt;
=== Set up your environment ===&lt;br /&gt;
* Plug your badge into your computer via USB&lt;br /&gt;
* Download Arduino IDE 1.5.7 from http://arduino.cc/en/main/software#toc3&lt;br /&gt;
* “git clone” or download TiLDA source code from https://github.com/emfcamp/Mk2-Firmware&lt;br /&gt;
* Start the Arduino IDE. &lt;br /&gt;
* Now you have to change the sketchbook-folder to be the folder you just cloned. To do this use File | Preferences | “Set Sketchbook location”. On MacOS, this is Arduino | Preferences &lt;br /&gt;
* Restart the Arduino IDE&lt;br /&gt;
* Open sketch “EMF2014”&lt;br /&gt;
* Set Tools | Board to MKe v0.333 (RTOS Core)&lt;br /&gt;
* Set Tools | Port to correct port (you might have to research this - some operating systems like Windows require you to install drivers or become a member of a certain group)&lt;br /&gt;
** On MacOS this is will start /dev/tty.usbmodem with 4 digits, and change for each port&lt;br /&gt;
** On Linux this is usually /dev/ttyACM0 but may be a higher number if you have other USB Serial devices&lt;br /&gt;
* Hit the upload button&lt;br /&gt;
* Wait&lt;br /&gt;
* Woohoo - You just successfully uploaded code to your badge&lt;br /&gt;
&lt;br /&gt;
=== Your first “Hello world” app ===&lt;br /&gt;
There’s a “HelloWorldApp.cpp” file in which you can play around. In order for it to show up on the Homescreen you have to uncomment line 51 in AppManager.cpp and flash the changed code to the badge. Great app pull requests are appreciated!&lt;br /&gt;
&lt;br /&gt;
If you are still using the Arduino IDE at this point, note that it will not let you edit the .cpp and .h files that are needed to create Apps for the badge. To force the IDE to re-compile/re-read any files you've edited using an external editor, make sure to go to the File -&amp;gt; Preferences dialog box, and check the &amp;quot;Use external editor&amp;quot; checkbox.&lt;br /&gt;
&lt;br /&gt;
=== Why are things so different from standard Arduino code? ===&lt;br /&gt;
We’re using a library called FreeRTOS that allows us to multitask - something that’s normally not possible with standard Arduino code. This allows us to run multiple tasks at the same time. FreeRTOS uses preemptive scheduling to switch between the task. Due to this we have to be very careful about how we do some things. For example we can’t just define interrupts for buttons in every task (imagine the mess!) or write to the serial port directly (your task might stop in the middle of the message). &lt;br /&gt;
&lt;br /&gt;
We’ve also spend quite a lot of time to make the build-in components as easy to use as possible without having every task to write lots of boilerplate code. If you feel like using the build-in components on the badge, chances are we already wrote a wrapper for them that is already used by one of the other tasks. &lt;br /&gt;
&lt;br /&gt;
Have a look at the “Documentation” section in this document for a full list of API functions. You will avoid a lot of headaches if you stick to those.&lt;br /&gt;
=== How to use the badge with pure Arduino code ===&lt;br /&gt;
If you prefer you can always start from scratch without FreeRTOS or any of our code, just keep in mind that you won’t be able to receive messages via radio or use any of the API features we already added. Just start a new sketch in the Arduino IDE for that and get going. If you want to load the main firmware again just change the sketch to “EMF2014” and upload again.&lt;br /&gt;
=== Debugging and Gotchas ===&lt;br /&gt;
* The USB serial is set up to 115200 baud. There are lots of terminals that can connect to them. See below for how to enable the debug logging.&lt;br /&gt;
* If you can’t revive a badge you can short the two erase pins and press the reset button while holding it down.&lt;br /&gt;
* Avoid busy waiting, use FreeRTOS queues and Tilda::delay() instead&lt;br /&gt;
* Don’t use low level functions like interrupts or serial ports directly unless you really, really know how FreeRTOS will handle them. For general logging you can use Tilda::log()&lt;br /&gt;
* If sending code to the badge using the Arduino IDE &amp;quot;Upload&amp;quot; button fails, even though the /dev/ttyACM0 (linux com port) is there, just retry, twice if neccessary.&lt;br /&gt;
&lt;br /&gt;
=== Code structure ===&lt;br /&gt;
* FreeRTOS has the concept of “Tasks” which work like threads. We’ve wrappered them in a class called “Task” (for background stuff) and “Apps” (for foreground, one-at-a-time things)&lt;br /&gt;
* Everything needs to be in the main EMF2014 folder. Subfolders are not allowed. This is an Arduino IDE restriction :(&lt;br /&gt;
=== Radio infrastructure ===&lt;br /&gt;
The radio infrastructure is distributed between DKs. Every “gateway” has a Raspberry Pi with two Ciseco USB radios. We never had the chance to actually try it with a large number of badges in the same spot, so please don’t expect it to work perfectly.&lt;br /&gt;
&lt;br /&gt;
=== Contribute ===&lt;br /&gt;
Send us a pull request via [https://github.com/emfcamp/Mk2-Firmware GitHub] - We’ll do our best to review and merge the good ones during EMF so others can use them.&lt;br /&gt;
&lt;br /&gt;
=Hardware=&lt;br /&gt;
&lt;br /&gt;
The following hardware has been included on the badge.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/microcontrollers/arm/sam3x.aspx Atmel ATSAM3X8E]&lt;br /&gt;
** This is the same chip as the [http://arduino.cc/en/Main/ArduinoBoardDue Arduino Due] and gives us the base platform for the badge&lt;br /&gt;
** 32bit ARM Cortex M3 * 84MHz&lt;br /&gt;
** 512KBytes Flash RAM&lt;br /&gt;
** 96KBytes of SRAM&lt;br /&gt;
* A 128x64 pixel monochrome LCD display&lt;br /&gt;
* [http://shop.ciseco.co.uk/srf-wireless-rf-radio-surface-mount/ Ciseco SRF Radio]&lt;br /&gt;
** 868Mhz RF Transceiver&lt;br /&gt;
** Simple UART interface&lt;br /&gt;
** Low power sleep mode&lt;br /&gt;
* [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] 3-axis Accelerometer and 3-axis gyro&lt;br /&gt;
** I2C interface&lt;br /&gt;
** Tri-Axis angular rate sensor (gyro) with a sensitivity up to 131 LSBs/dps and a full-scale range of ±250, ±500, ±1000, and ±2000dps&lt;br /&gt;
** Tri-Axis accelerometer with a programmable full scale range of ±2g, ±4g, ±8g and ±16g&lt;br /&gt;
** Digital Motion Processing™ (DMP™) engine offloads complex MotionFusion, sensor timing synchronisation and gesture detection&lt;br /&gt;
* PMIC &amp;amp; LiPo&lt;br /&gt;
* Joystick&lt;br /&gt;
* Buttons&lt;br /&gt;
* RGB LEDs&lt;br /&gt;
* IR&lt;br /&gt;
* Arduino Headers&lt;br /&gt;
* Pads for wearable tech&lt;br /&gt;
&lt;br /&gt;
= Firmware Documentation =&lt;br /&gt;
== Debugging ==&lt;br /&gt;
===Enabling the USB serial debug log messages===&lt;br /&gt;
To enable the debug logging you must uncomment the following line in [https://github.com/emfcamp/Mk2-Firmware/blob/master/hardware/emfcamp/sam/libraries/debug/debug.h#L42 hardware/emfcamp/sam/libraries/debug/debug.h]&lt;br /&gt;
&lt;br /&gt;
 // Enable debug task and output&lt;br /&gt;
 // #define DEBUG 1&lt;br /&gt;
&lt;br /&gt;
===Tilda::log(String text)===&lt;br /&gt;
&lt;br /&gt;
This logs “text” to the serial console. To read it connect to it via the Arduino IDE Serial Monitor. Don’t use “SerialUSB.println” or similar -- it’s not thread-safe and you might end up with utter nonsense.&lt;br /&gt;
&lt;br /&gt;
===Debugging using the JTAG interface===&lt;br /&gt;
The JTAG interface on the board provides powerful debugging facilities like breakpoints, backtraces, dumping memory, inspecting variables, checking task states, catching exeptions etc. To make this to work requires additional hardware and software, see [[TiLDA Debugging using JTAG]].&lt;br /&gt;
&lt;br /&gt;
== Buttons ==&lt;br /&gt;
The badge has 8 buttons: Up, Down, Left, Right, Center (on the joystick), A, B and Light. You can use arduino-style “digitalRead(BUTTON_RIGHT)” to read the current status of any button, but you can’t define your own interrupt (because we already did that). This doesn’t mean you can’t wait for a certain button to be pressed, it just means you have to approach it slightly differently:&lt;br /&gt;
&lt;br /&gt;
Example: A simple app displaying the button code&lt;br /&gt;
 void ButtonApp::task() {&lt;br /&gt;
     ButtonSubscription allButtons = Tilda::createButtonSubscription(LIGHT | A | B | UP | DOWN | LEFT | RIGHT | CENTER);&lt;br /&gt;
 &lt;br /&gt;
     while(true) {&lt;br /&gt;
         Button button = allButtons.waitForPress(1000);&lt;br /&gt;
         if (button == A) {&lt;br /&gt;
             debug::log(“You pressed button A”);&lt;br /&gt;
         } else if (button == LEFT) {&lt;br /&gt;
             debug::log(“You pressed LEFT”);&lt;br /&gt;
         } else if (button == NONE) {&lt;br /&gt;
             debug::log(“No button has been pressed in 1000ms”); &lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription Tilda::createButtonSubscription(&amp;lt;buttons&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
Registers a subscriptions for a defined set of buttons and returns a ButtonSubscription. Multiple Buttons can be combined via “|” (see example above). One button can not be subscribed by more than 10 subscriptions (which shouldn’t really happen, but keep it in mind). &lt;br /&gt;
&lt;br /&gt;
Don’t use this function in a constructor, it requires FreeRTOS to be running. Using it inside the task() function is the only safe place for it.&lt;br /&gt;
&lt;br /&gt;
===Button ButtonSubscription::waitForPress(TimeInTicks timeout)===&lt;br /&gt;
&lt;br /&gt;
This is normally called in a loop. It causes the task to block until one of the buttons has been pressed. If the timeout occurs before any button has been pressed “NONE” will be returned. &lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::waitForPress()===&lt;br /&gt;
&lt;br /&gt;
The same as above, but without the timeout.&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::clear()===&lt;br /&gt;
&lt;br /&gt;
This should be called after an App has been suspended, just before it’s going to be resumed. It causes the Queue to be cleared which could otherwise lead to buttons being reported that have been pressed while other apps were in the foreground. Have a look at the FlashLightApp for an example.&lt;br /&gt;
&lt;br /&gt;
==LEDs==&lt;br /&gt;
===Tilda::setLedColor(Led led, Color color);===&lt;br /&gt;
===Tilde::setLedColor(Color color);===&lt;br /&gt;
&lt;br /&gt;
Sets the color of all or one led. Color is an object that takes red, green and blue as a value between 0 and 255 each. If no led is defined both leds will be set to the same color.&lt;br /&gt;
&lt;br /&gt;
Example: A simple color-changing task&lt;br /&gt;
 void ColorfulTask::task() {&lt;br /&gt;
     while(true) {&lt;br /&gt;
         Tilda::setLedColor(LED1, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::setLedColor(LED2, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The Display Library is based on GLCDv3 (http://playground.arduino.cc/Code/GLCDks0108), docs (http://code.google.com/p/glcd-arduino/source/browse/trunk/glcd/doc/GLCD_Documentation.pdf) but adapted to support our screen.  The Init routine is called in the setup, and the LCDTask takes care of ensuring the screen is updated every 40ms if required (Unlike the original GLCD library, screen updates are decoupled from the graphics routines.)&lt;br /&gt;
&lt;br /&gt;
Also available is M2tklib (https://code.google.com/p/m2tklib/) which is a nice toolkit library.  Further details on using this will come later, but expect the main loop to be handled for you, and just passing the menu structure you require for your app.&lt;br /&gt;
&lt;br /&gt;
Right now, you can call the GLCD functions directly with GLCD.DrawBitmap() for example.  This is going to change to be accessed through the GUITask class in the near future, to ensure only one task at a time writes to the screen.  Expect this to be simply GUITask in place of GLCD, along with a registering a redraw call back to GUITask. The bitmap format, by the way, is rather unconventional but there are a couple of utility scripts to convert popular formats down in the hacking section below - you can grab the SponsorsApp.h as an example and swap out the bitmap array with one of your choosing.&lt;br /&gt;
&lt;br /&gt;
Extra features that are included, GLCD.SetRotation() will handle rotation of the screen for you, and GLCD.CurrentWidth() and GLCD.CurrentHeight will give you the correct Width and Height for the current orientation.  GLCD.Width and GLCD.Height constants are not available, and the GLCD predefined Text areas will not be rotated for you, if you require this define your own text areas.&lt;br /&gt;
&lt;br /&gt;
Note that one function was not ported to the badge version of GLCD, &amp;quot;Printf&amp;quot;, you'll have to cope without it.&lt;br /&gt;
&lt;br /&gt;
== Sound == &lt;br /&gt;
There's a piezo on the board, but we haven't added code for it to the current firmware. Pull requests are very welcome!&lt;br /&gt;
&lt;br /&gt;
== IMU ==&lt;br /&gt;
=== Tilda::getOrientation ===&lt;br /&gt;
returns &amp;quot; ORIENTATION_HELD&amp;quot;, &amp;quot;ORIENTATION_RIGHT&amp;quot; (joystick to the right of the screen), &amp;quot;ORIENTATION_HUNG&amp;quot; or &amp;quot;ORIENTATION_LEFT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Flash Storage ==&lt;br /&gt;
We have 2mb of flash storage, but we're not using it in the main firmware - Please get this working!&lt;br /&gt;
== Data: Schedule ==&lt;br /&gt;
===Tilda::getDataStore().getSchedule(day, location) ===&lt;br /&gt;
== Date: Weather Forecast ==&lt;br /&gt;
===Tilda::getDataStore().getWeatherForecast()===&lt;br /&gt;
== Radio ==&lt;br /&gt;
There's no way of sending messages in the current version of the firmware, sorry :(&lt;br /&gt;
&lt;br /&gt;
== Time ==&lt;br /&gt;
&lt;br /&gt;
=== Tilda::delay(uint16_t delayInMs) === &lt;br /&gt;
&lt;br /&gt;
Works like Arduino’s delay(), but is FreeRTOS-safe. It’s safe to use this function before FreeRTOS has started.&lt;br /&gt;
&lt;br /&gt;
=== tilda::getClock() ===&lt;br /&gt;
&lt;br /&gt;
Returns an instance of https://github.com/MarkusLange/Arduino-Due-RTC-Library/blob/master/rtc_clock.h&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
===uint16_t tilda::getBadgeId()===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==2.12. Battery==&lt;br /&gt;
===float TiLDA::getBatteryVoltage()===&lt;br /&gt;
Returns the current voltage as a float&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getBatteryPercent()===&lt;br /&gt;
Returns the current voltage as a percentage&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getChargeState()===&lt;br /&gt;
Returns the charge state&lt;br /&gt;
&lt;br /&gt;
0 Charging&lt;br /&gt;
1 Not Charging&lt;br /&gt;
&lt;br /&gt;
=Hacking=&lt;br /&gt;
To use our board definition you will need to first get the Arduino 1.5.7 IDE from [http://arduino.cc/en/Main/Software#toc3 here]&amp;lt;br/&amp;gt;&lt;br /&gt;
Next you can download the TiLDA MKe Firmware project from either the [https://github.com/emfcamp/Mk2-Firmware github repo] or via [https://github.com/emfcamp/Mk2-Firmware/archive/master.zip direct download]&amp;lt;br/&amp;gt;&lt;br /&gt;
Now copy the &amp;quot;hardware&amp;quot; folder to your Sketchbook folder, this is usually ~/Sketchbook/&amp;lt;br&amp;gt;&lt;br /&gt;
or&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternative option is to set the Arduino 1.5.7 sketchbook folder to the Mk2-Firmware directory.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the Arduino IDE and your will be able to select TiLDA MKe v0.333 for the Tools-&amp;gt;Board menu&lt;br /&gt;
&lt;br /&gt;
* Draft 3d print-able and laser-able case files [http://www.thingiverse.com/thing:436815 here]&lt;br /&gt;
* A Python script (via [https://twitter.com/trotmaster99 @trotmaster99]) that converts a monochrome bitmap image into a format suitable for the Tilda can be found [http://pastebin.com/8XeazQjT here].&lt;br /&gt;
* A similar script in Perl to create TiLDA MKe fullscreen bitmaps from XBM: -&lt;br /&gt;
&amp;lt;div style =&amp;quot;height:200px;overflow-x:hidden;overflow-y:auto;border: 4px solid orange;&amp;quot;&amp;gt;&lt;br /&gt;
'''xbm2mke.pl by [[User:Msemtd]]'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!perl -w&lt;br /&gt;
use strict;&lt;br /&gt;
# Little script to convert a regular XBM to TiLDA MKe bitmap&lt;br /&gt;
# only tested with fullscreen bitmaps!&lt;br /&gt;
# Hot file handle magic...&lt;br /&gt;
select((select(STDERR), $| = 1)[0]);&lt;br /&gt;
select((select(STDOUT), $| = 1)[0]);&lt;br /&gt;
sub t(@);&lt;br /&gt;
sub d($);&lt;br /&gt;
sub chug($);&lt;br /&gt;
my $f = shift;&lt;br /&gt;
#~ $f = 'blankish.xbm' if not $f;&lt;br /&gt;
if(not defined $f or not $f =~ /^(.*)\.xbm$/i){&lt;br /&gt;
    die &amp;quot;Usage: gimme an XBM file dude!\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
my $name = $1;&lt;br /&gt;
t &amp;quot;Reading file '$f'...&amp;quot;;&lt;br /&gt;
my $data = chug($f);&lt;br /&gt;
t &amp;quot;OK&amp;quot;;&lt;br /&gt;
my @lines = split /^/, $data;&lt;br /&gt;
@lines = grep{chomp; s/^\s+//; s/\s+$//; length;} @lines;&lt;br /&gt;
#~ t d \@lines;&lt;br /&gt;
my($width, $height) = (0,0);&lt;br /&gt;
my @head = @lines[0..5];&lt;br /&gt;
foreach(@head){&lt;br /&gt;
    if(/_width\s+(\d+)/){$width = $1;}&lt;br /&gt;
    if(/_height\s+(\d+)/){$height = $1;}&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;width x height = $width x $height&amp;quot;;&lt;br /&gt;
my @k;&lt;br /&gt;
foreach(@lines){ push @k, split /,/; }&lt;br /&gt;
@k = grep { s/^.*(0x[0-9A-Fa-f]{1,2}).*$/$1/o; /(0x[0-9A-Fa-f]{1,2})/o } @k;&lt;br /&gt;
#~ t d \@k;&lt;br /&gt;
my $bc = scalar(@k);&lt;br /&gt;
t &amp;quot;Pulled out $bc hex bytes&amp;quot;;&lt;br /&gt;
if($bc != $width * $height / 8) {&lt;br /&gt;
    die &amp;quot;byte count $bc does not match that expected for w x h&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;OK - reorder bytes for MKe bitmap&amp;quot;;&lt;br /&gt;
my $wb = int($width/8) + (($width &amp;amp; 0x07) ? 1: 0);&lt;br /&gt;
t &amp;quot;width in whole bytes for $width pixels = $wb&amp;quot;;&lt;br /&gt;
my @mke;&lt;br /&gt;
for(my $col = 0; $col &amp;lt; $wb; $col++){&lt;br /&gt;
    for(my $row = $height - 1; $row &amp;gt;= 0; $row--){&lt;br /&gt;
        my $idx = ($row * $wb) + $col;&lt;br /&gt;
        my $val = $k[$idx];&lt;br /&gt;
        #~ t &amp;quot;Column $col + Row $row = idx $idx = $val&amp;quot;;&lt;br /&gt;
        push @mke, $val;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
my $out = &amp;quot;static const uint8_t &amp;quot;.uc($name).&amp;quot;_BM[] = {\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $width, // width\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $height , // height\n&amp;quot;;&lt;br /&gt;
#~ $out .= join(&amp;quot;, &amp;quot;, @mke);&lt;br /&gt;
while(scalar @mke){&lt;br /&gt;
	$out .= join(&amp;quot;, &amp;quot;, splice(@mke, 0, 16)).&amp;quot;,\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
$out .= &amp;quot;};\n&amp;quot;;&lt;br /&gt;
# meh, just print it out&lt;br /&gt;
t $out;&lt;br /&gt;
&lt;br /&gt;
sub t(@) {&lt;br /&gt;
    foreach (@_) {&lt;br /&gt;
       print STDOUT &amp;quot;$_\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
sub d($) {&lt;br /&gt;
    require Data::Dumper;&lt;br /&gt;
    my $s = $_[0];&lt;br /&gt;
    my $d = Data::Dumper::Dumper($s);&lt;br /&gt;
    $d =~ s/^\$VAR1 =\s*//;&lt;br /&gt;
    $d =~ s/;$//;&lt;br /&gt;
    chomp $d;&lt;br /&gt;
    return $d;&lt;br /&gt;
}&lt;br /&gt;
sub chug($) {&lt;br /&gt;
  my $filename = shift;&lt;br /&gt;
  local *F;&lt;br /&gt;
  open F, &amp;quot;&amp;lt; $filename&amp;quot; or die &amp;quot;Couldn't open `$filename': $!&amp;quot;;&lt;br /&gt;
  local $/ = undef;&lt;br /&gt;
  return &amp;lt;F&amp;gt;;&lt;br /&gt;
}  # F automatically closed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;span id=github&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Source =&lt;br /&gt;
&lt;br /&gt;
All the source code and designs are on openly available on Github:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Hardware Hardware] - the full board design&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Documentation Documentation] - a dump of relevant parts datasheets&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Firmware Firmware] - source code for the badge software&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Software Software] - server-side software for the network&lt;br /&gt;
&lt;br /&gt;
If you want to help, point your IRC client to #tilda on Freenode.&lt;br /&gt;
&lt;br /&gt;
[[Category: Badges]]&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3711</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3711"/>
		<updated>2014-09-15T21:33:27Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Build and flash the badge firmware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. I combined two of the example which came with the package to produce the file I use below. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Olimex ARM-USB-TINY-H&lt;br /&gt;
#&lt;br /&gt;
# http://www.olimex.com/dev/arm-usb-tiny-h.html&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
interface ft2232&lt;br /&gt;
ft2232_device_desc &amp;quot;Olimex OpenOCD JTAG ARM-USB-TINY-H&amp;quot;&lt;br /&gt;
ft2232_layout olimex-jtag&lt;br /&gt;
ft2232_vid_pid 0x15ba 0x002a&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
#&lt;br /&gt;
# at91sam3u4e&lt;br /&gt;
# at91sam3u2e&lt;br /&gt;
# at91sam3u1e&lt;br /&gt;
# at91sam3u4c&lt;br /&gt;
# at91sam3u2c&lt;br /&gt;
# at91sam3u1c&lt;br /&gt;
#&lt;br /&gt;
# at91sam3s4c&lt;br /&gt;
# at91sam3s4b&lt;br /&gt;
# at91sam3s4a&lt;br /&gt;
# at91sam3s2c&lt;br /&gt;
# at91sam3s2b&lt;br /&gt;
# at91sam3s2a&lt;br /&gt;
# at91sam3s1c&lt;br /&gt;
# at91sam3s1b&lt;br /&gt;
# at91sam3s1a&lt;br /&gt;
#&lt;br /&gt;
# at91sam3A4C&lt;br /&gt;
# at91sam3A8C&lt;br /&gt;
# at91sam3X4C&lt;br /&gt;
# at91sam3X4E&lt;br /&gt;
# at91sam3X8C&lt;br /&gt;
# at91sam3X8E&lt;br /&gt;
# at91sam3X8H&lt;br /&gt;
if { [info exists CHIPNAME] } {&lt;br /&gt;
   set _CHIPNAME $CHIPNAME&lt;br /&gt;
} else {&lt;br /&gt;
   set _CHIPNAME sam3&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if { [info exists ENDIAN] } {&lt;br /&gt;
   set _ENDIAN $ENDIAN&lt;br /&gt;
} else {&lt;br /&gt;
   set _ENDIAN little&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# JTAG speed should be &amp;lt;= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz&lt;br /&gt;
#&lt;br /&gt;
# Since we may be running of an RC oscilator, we crank down the speed a&lt;br /&gt;
# bit more to be on the safe side. Perhaps superstition, but if are&lt;br /&gt;
# running off a crystal, we can run closer to the limit. Note&lt;br /&gt;
# that there can be a pretty wide band where things are more or less stable.&lt;br /&gt;
&lt;br /&gt;
adapter_khz 500&lt;br /&gt;
&lt;br /&gt;
adapter_nsrst_delay 100&lt;br /&gt;
jtag_ntrst_delay 100&lt;br /&gt;
&lt;br /&gt;
#jtag scan chain&lt;br /&gt;
if { [info exists CPUTAPID] } {&lt;br /&gt;
   set _CPUTAPID $CPUTAPID&lt;br /&gt;
} else {&lt;br /&gt;
   set _CPUTAPID 0x4ba00477&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID&lt;br /&gt;
&lt;br /&gt;
set _TARGETNAME $_CHIPNAME.cpu&lt;br /&gt;
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME -rtos FreeRTOS&lt;br /&gt;
&lt;br /&gt;
# 16K is plenty, the smallest chip has this much&lt;br /&gt;
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -event gdb-flash-erase-start {&lt;br /&gt;
    halt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# if srst is not fitted use SYSRESETREQ to&lt;br /&gt;
# perform a soft reset&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
The version of OpenOCD I'm using uses libusb to access the device. I needed to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.7.0 (2014-09-14-17:34)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m3 reset_config sysresetreq&lt;br /&gt;
Info : max TCK change to: 30000 kHz&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The OpenOCD-0.8.0 release adds a new ftdi driver which the [https://www.olimex.com/Products/ARM/JTAG/_resources/ARM-USB-TINY_and_TINY_H_manual.pdf Olimex TINY manual] now recommends is used instead:&lt;br /&gt;
&lt;br /&gt;
 Please note that since OpenOCD 0.8.0 FTDI drivers are recommended!&lt;br /&gt;
 It was quite the opposite before 0.8.0 when LibUSB drivers were&lt;br /&gt;
 suggested as default.&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is &amp;lt;code&amp;gt;EMF2014.cpp.elf&amp;lt;/code&amp;gt; and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
* Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* On exit GDB hits an assert and asks whether you want a core dump.&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3710</id>
		<title>TiLDA Debugging using JTAG</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_Debugging_using_JTAG&amp;diff=3710"/>
		<updated>2014-09-15T21:29:19Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: How to setup and use a JTAG debugger with TiLDA&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA badge has a JTAG port which can be used to perform remote firmware debugging. With the right hardware and software you can use this to run a GDB session on your development machine to insert breakpoints, inspect memory and poke around with the firmware running on the badge just like it was a local process running on your machine. &lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
''I started the list below with the parts that worked for me. Feel free to add alternatives if you know they work for you.''&lt;br /&gt;
* X86-64 Linux machine for building the firmware and running GDB&lt;br /&gt;
* TiLDA badge&lt;br /&gt;
** Plus micro USB cable for connecting TiLDA to development machine&lt;br /&gt;
* JTAG header, 10 way (2 x 5 pins) 0.05&amp;quot; (or 1.27mm) through hole&lt;br /&gt;
** e.g. Samtec FTS-105-01-L-D&lt;br /&gt;
* Fine tipped soldering iron&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/ Olimex ARM-USB-TINY-H] USB JTAG Interface&lt;br /&gt;
** Plus USB type A to B cable (the original &amp;amp; large square plug)&lt;br /&gt;
* [https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-20-10/ Olimex ARM-JTAG-20-10] 20pin to 10pin adapter&lt;br /&gt;
* [http://openocd.sourceforge.net/ OpenOCD] software.&lt;br /&gt;
** This can control the Olimex JTAG interface and implements the GDB remote server protocol to talk with the debugger&lt;br /&gt;
* GDB&lt;br /&gt;
** I used gdb-7.7.1-18.fc20.x86_64.&lt;br /&gt;
* Arduino 1.5.7 tools&lt;br /&gt;
** For building &amp;amp; installing the firmware image&lt;br /&gt;
&lt;br /&gt;
== Attach JTAG Header to badge ==&lt;br /&gt;
The header must be attached on the correct side of the board otherwise it won't work. The pins on the two sides of the header are slightly different, one side is tin coated and appears silver/grey. These are the ones you should be soldering. The gold plated side should to be used by the connector.&lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header.jpg|150px|thumb|center|text-top|JTAG header before being soldered on to the board]]&lt;br /&gt;
[[File:jtag-header-in-place-highlight.jpg|300px|thumb|center|text-top|TiLDA with new JTAG header highlighted]]&lt;br /&gt;
&lt;br /&gt;
Flip the board upside down and solder pins from the LCD side. The pitch is only 1.27mm (0.05&amp;quot;) which is half the size of most normal connectors so you need a steady hand. After you have soldered the pins it is a good idea to test for any short circuits before you power it on. &lt;br /&gt;
&lt;br /&gt;
[[File:jtag-header-solder-side.jpg|200px|thumb|center|text-top|Header soldered on LCD side of the board]]&lt;br /&gt;
&lt;br /&gt;
== Olimex adapter and USB-TINY-H ==&lt;br /&gt;
The cable from the Olimex adaper should be connected to the header so that the cable runs away from the board. Once again you may wish to check the connections appear to be the right way around, e.g. pin 1 on the adapter board connects to the 3v3 test point on the TiLDA. Connect the 20 pin side of the adapter into the main USB-TINY, this is keyed so it only fits one way around.&lt;br /&gt;
&lt;br /&gt;
[[File:board-with-adapter.jpg|300px|thumb|center|text-top|TiLDA connected to Olimex TINY-Y]]&lt;br /&gt;
&lt;br /&gt;
Plug the USB-TINY into a USB port on your machine. The 'dmesg' output should report something like:&lt;br /&gt;
&lt;br /&gt;
 usb 2-2: new high-speed USB device number 111 using ehci-pci&lt;br /&gt;
 usb 2-2: New USB device found, idVendor=15ba, idProduct=002a&lt;br /&gt;
 usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3&lt;br /&gt;
 usb 2-2: Product: Olimex OpenOCD JTAG ARM-USB-TINY-H&lt;br /&gt;
 usb 2-2: SerialNumber: OLXxxxxx&lt;br /&gt;
&lt;br /&gt;
== Install OpenOCD ==&lt;br /&gt;
I started with the current version available in the Fedora package repository (openocd-0.7.0-3.fc20.x86_64). Other Linux distros are likely to have packaged too. &lt;br /&gt;
&lt;br /&gt;
=== OpenOCD stack pointer bug ===&lt;br /&gt;
After I got everything running I noticed that the GDB backtraces would show the current function (PC) and the caller (LR) but all further stack entries were missing. After some debugging I found that OpenOCD was incorrectly calculating the stack pointer when it tried to align it. I applied a quick fix to disable the broken alignment code:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
--- openocd-0.7.0/src/rtos/rtos.c.bak   2014-09-14 17:28:10.000000000 +0100&lt;br /&gt;
+++ openocd-0.7.0/src/rtos/rtos.c       2014-09-14 17:29:39.000000000 +0100&lt;br /&gt;
@@ -454,12 +454,16 @@&lt;br /&gt;
        tmp_str_ptr = *hex_reg_list;&lt;br /&gt;
        new_stack_ptr = stack_ptr - stacking-&amp;gt;stack_growth_direction *&lt;br /&gt;
                stacking-&amp;gt;stack_registers_size;&lt;br /&gt;
+#if 0&lt;br /&gt;
+       // This code gives bad results for already aligned pointers&lt;br /&gt;
+       // and negative stack growth&lt;br /&gt;
        if (stacking-&amp;gt;stack_alignment != 0) {&lt;br /&gt;
                /* Align new stack pointer to x byte boundary */&lt;br /&gt;
                new_stack_ptr =&lt;br /&gt;
                        (new_stack_ptr &amp;amp; (~((int64_t) stacking-&amp;gt;stack_alignment - 1))) +&lt;br /&gt;
                        ((stacking-&amp;gt;stack_growth_direction == -1) ? stacking-&amp;gt;stack_alignment : 0);&lt;br /&gt;
        }&lt;br /&gt;
+#endif&lt;br /&gt;
        for (i = 0; i &amp;lt; stacking-&amp;gt;num_output_registers; i++) {&lt;br /&gt;
                int j;&lt;br /&gt;
                for (j = 0; j &amp;lt; stacking-&amp;gt;register_offsets[i].width_bits/8; j++) {&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I reported the bug to the OpenOCD developers and proper fix will hopefully arrive in the trunk code soon: http://openocd.zylin.com/#/c/2301/ (an initial fix was committed but has since been reverted because it was broken for a different case).&lt;br /&gt;
&lt;br /&gt;
== OpenOCD configuration file ==&lt;br /&gt;
OpenOCD requires a set of configuration commands describing both the JTAG adapter and the target CPU/board. I combined two of the example which came with the package to produce the file I use below. Copy this into a file called tilda.cfg:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Olimex ARM-USB-TINY-H&lt;br /&gt;
#&lt;br /&gt;
# http://www.olimex.com/dev/arm-usb-tiny-h.html&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
interface ft2232&lt;br /&gt;
ft2232_device_desc &amp;quot;Olimex OpenOCD JTAG ARM-USB-TINY-H&amp;quot;&lt;br /&gt;
ft2232_layout olimex-jtag&lt;br /&gt;
ft2232_vid_pid 0x15ba 0x002a&lt;br /&gt;
&lt;br /&gt;
# script for ATMEL sam3, a CORTEX-M3 chip&lt;br /&gt;
#&lt;br /&gt;
# at91sam3u4e&lt;br /&gt;
# at91sam3u2e&lt;br /&gt;
# at91sam3u1e&lt;br /&gt;
# at91sam3u4c&lt;br /&gt;
# at91sam3u2c&lt;br /&gt;
# at91sam3u1c&lt;br /&gt;
#&lt;br /&gt;
# at91sam3s4c&lt;br /&gt;
# at91sam3s4b&lt;br /&gt;
# at91sam3s4a&lt;br /&gt;
# at91sam3s2c&lt;br /&gt;
# at91sam3s2b&lt;br /&gt;
# at91sam3s2a&lt;br /&gt;
# at91sam3s1c&lt;br /&gt;
# at91sam3s1b&lt;br /&gt;
# at91sam3s1a&lt;br /&gt;
#&lt;br /&gt;
# at91sam3A4C&lt;br /&gt;
# at91sam3A8C&lt;br /&gt;
# at91sam3X4C&lt;br /&gt;
# at91sam3X4E&lt;br /&gt;
# at91sam3X8C&lt;br /&gt;
# at91sam3X8E&lt;br /&gt;
# at91sam3X8H&lt;br /&gt;
if { [info exists CHIPNAME] } {&lt;br /&gt;
   set _CHIPNAME $CHIPNAME&lt;br /&gt;
} else {&lt;br /&gt;
   set _CHIPNAME sam3&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if { [info exists ENDIAN] } {&lt;br /&gt;
   set _ENDIAN $ENDIAN&lt;br /&gt;
} else {&lt;br /&gt;
   set _ENDIAN little&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# JTAG speed should be &amp;lt;= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz&lt;br /&gt;
#&lt;br /&gt;
# Since we may be running of an RC oscilator, we crank down the speed a&lt;br /&gt;
# bit more to be on the safe side. Perhaps superstition, but if are&lt;br /&gt;
# running off a crystal, we can run closer to the limit. Note&lt;br /&gt;
# that there can be a pretty wide band where things are more or less stable.&lt;br /&gt;
&lt;br /&gt;
adapter_khz 500&lt;br /&gt;
&lt;br /&gt;
adapter_nsrst_delay 100&lt;br /&gt;
jtag_ntrst_delay 100&lt;br /&gt;
&lt;br /&gt;
#jtag scan chain&lt;br /&gt;
if { [info exists CPUTAPID] } {&lt;br /&gt;
   set _CPUTAPID $CPUTAPID&lt;br /&gt;
} else {&lt;br /&gt;
   set _CPUTAPID 0x4ba00477&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID&lt;br /&gt;
&lt;br /&gt;
set _TARGETNAME $_CHIPNAME.cpu&lt;br /&gt;
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME -rtos FreeRTOS&lt;br /&gt;
&lt;br /&gt;
# 16K is plenty, the smallest chip has this much&lt;br /&gt;
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0&lt;br /&gt;
&lt;br /&gt;
$_TARGETNAME configure -event gdb-flash-erase-start {&lt;br /&gt;
    halt&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# if srst is not fitted use SYSRESETREQ to&lt;br /&gt;
# perform a soft reset&lt;br /&gt;
cortex_m reset_config sysresetreq&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run OpenOCD ===&lt;br /&gt;
The version of OpenOCD I'm using uses libusb to access the device. I needed to run with sudo for it to work. If everything is connected together and the badge is powered on then you should see it detecting the CPU core as shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ sudo openocd -f tilda.cfg&lt;br /&gt;
Open On-Chip Debugger 0.7.0 (2014-09-14-17:34)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
        http://openocd.sourceforge.net/doc/doxygen/bugs.html&lt;br /&gt;
Info : only one transport option; autoselect 'jtag'&lt;br /&gt;
adapter speed: 500 kHz&lt;br /&gt;
adapter_nsrst_delay: 100&lt;br /&gt;
jtag_ntrst_delay: 100&lt;br /&gt;
cortex_m3 reset_config sysresetreq&lt;br /&gt;
Info : max TCK change to: 30000 kHz&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : JTAG tap: sam3.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)&lt;br /&gt;
Info : sam3.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The OpenOCD-0.8.0 release adds a new ftdi driver which the [https://www.olimex.com/Products/ARM/JTAG/_resources/ARM-USB-TINY_and_TINY_H_manual.pdf Olimex TINY manual] now recommends is used instead:&lt;br /&gt;
&lt;br /&gt;
 Please note that since OpenOCD 0.8.0 FTDI drivers are recommended!&lt;br /&gt;
 It was quite the opposite before 0.8.0 when LibUSB drivers were&lt;br /&gt;
 suggested as default.&lt;br /&gt;
&lt;br /&gt;
== Patch TiLDA firmware for OpenOCD FreeRTOS detection ==&lt;br /&gt;
The OpenOCD code knows how to find the FreeRTOS tasks and can use this to make each task running on the badge as a different thread in GDB. To make this work you need to apply a small patch to the TiLDA code. &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
diff --git a/EMF2014/TiLDATask.cpp b/EMF2014/TiLDATask.cpp&lt;br /&gt;
index 2cdc08d..701f940 100644&lt;br /&gt;
--- a/EMF2014/TiLDATask.cpp&lt;br /&gt;
+++ b/EMF2014/TiLDATask.cpp&lt;br /&gt;
@@ -58,6 +58,8 @@&lt;br /&gt;
 #include &amp;quot;logo.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TiLDA_64x128.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
+// Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+unsigned portBASE_TYPE uxTopUsedPriority;&lt;br /&gt;
 &lt;br /&gt;
 TiLDATask::TiLDATask() {&lt;br /&gt;
 &lt;br /&gt;
@@ -68,6 +70,10 @@ String TiLDATask::getName() const {&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void TiLDATask::task() {&lt;br /&gt;
+&lt;br /&gt;
+    // Hack to make FreeRTOS support work in OpenOCD&lt;br /&gt;
+    uxTopUsedPriority = configMAX_PRIORITIES - 1;&lt;br /&gt;
+&lt;br /&gt;
     Tilda::_realTimeClock = new RTC_clock(RC);&lt;br /&gt;
     Tilda::_appManager = new AppManager;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
This adds a variable that the OpenOCD expects to be able to read from the target to determine how many queues are being used by the FreeRTOS scheduler. This was present in older FreeRTOS release but has since been removed.&lt;br /&gt;
&lt;br /&gt;
== Build and flash the badge firmware ==&lt;br /&gt;
To make the debugger work you must be sure that the firmware running on the badge exactly matches the source code and binary objects that you have locally on your development machine. I recommend you apply the patch from the previous section, build the TiLDA firmware and upload it to your badge before you go any further.&lt;br /&gt;
&lt;br /&gt;
In the Arduino IDE you should build firmware (EMF2014 sketch) and upload it via the USB port on the TiLDA badge. (I have not attempted to upload firmware via the JTAG interface but that should be possible as well). The IDE writes a copy of the object files and the final executable to a directory in /tmp whenever you build the code. The firmware image file is called EMF2014.cpp.elf and you want to find the most recently built one, e.g.&lt;br /&gt;
&lt;br /&gt;
 [jburgess@shark]$ ls -lt /tmp/build*/EMF2014.cpp.elf | head -n 1&lt;br /&gt;
 -rwxrwxr-x. 1 jburgess jburgess 1475463 Sep 14 22:53 /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
&lt;br /&gt;
== Running GDB ==&lt;br /&gt;
First locate the EMF2014.cpp.elf file mentioned in the previous section. Run gdb with this file and with any luck it should be able to load it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[jburgess@shark tmp]$ gdb /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf&lt;br /&gt;
GNU gdb (GDB) Fedora 7.7.1-18.fc20&lt;br /&gt;
Copyright (C) 2014 Free Software Foundation, Inc.&lt;br /&gt;
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;br /&gt;
This is free software: you are free to change and redistribute it.&lt;br /&gt;
There is NO WARRANTY, to the extent permitted by law.  Type &amp;quot;show copying&amp;quot;&lt;br /&gt;
and &amp;quot;show warranty&amp;quot; for details.&lt;br /&gt;
This GDB was configured as &amp;quot;x86_64-redhat-linux-gnu&amp;quot;.&lt;br /&gt;
Type &amp;quot;show configuration&amp;quot; for configuration details.&lt;br /&gt;
For bug reporting instructions, please see:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.&lt;br /&gt;
Find the GDB manual and other documentation resources online at:&lt;br /&gt;
&amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&lt;br /&gt;
For help, type &amp;quot;help&amp;quot;.&lt;br /&gt;
Type &amp;quot;apropos word&amp;quot; to search for commands related to &amp;quot;word&amp;quot;...&lt;br /&gt;
Reading symbols from /tmp/build9091009552223609902.tmp/EMF2014.cpp.elf...done.&lt;br /&gt;
(gdb) &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check debug symbols ===&lt;br /&gt;
Next try some simple commands to see whether GDB knows where symbols are located in the binary and source:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info line main&lt;br /&gt;
Line 43 of &amp;quot;/home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/cores/rtos/main.cpp&amp;quot; starts at address 0x8fe78 &amp;lt;main()&amp;gt; and ends at 0x8fe7a &amp;lt;main()+2&amp;gt;.&lt;br /&gt;
(gdb) list main&lt;br /&gt;
38&lt;br /&gt;
39      /*&lt;br /&gt;
40       * \brief Main entry point of Arduino application&lt;br /&gt;
41       */&lt;br /&gt;
42      int main( void )&lt;br /&gt;
43      {&lt;br /&gt;
44              init();&lt;br /&gt;
45&lt;br /&gt;
46              initVariant();&lt;br /&gt;
47&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If something goes wrong at this point you could try using the copy of GDB provided with the arduino tools instead, e.g. &amp;lt;code&amp;gt;arduino-1.5.7/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-gdb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attach GDB to OpenOCD ===&lt;br /&gt;
The OpenOCD supports a couple of different interfaces. Before we try GDB we should first stop the CPU using the basic control interface and tell it to halt the CPU:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
$ telnet localhost 4444&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
Open On-Chip Debugger&lt;br /&gt;
&amp;gt; halt&lt;br /&gt;
target state: halted&lt;br /&gt;
target halted due to debug-request, current mode: Thread &lt;br /&gt;
xPSR: 0x61000000 pc: 0x000870ba psp: 0x20074a30&lt;br /&gt;
&amp;gt; &lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To continue execution you can run &amp;quot;resume&amp;quot;. Make sure you run &amp;quot;halt&amp;quot; to leave the target in the stopped before attaching GDB. Normally when GDB attaches it should stop the target automatically but this isn't working at the moment. If the target is running then you may when GDB attaches then you may see some odd behaviour.&lt;br /&gt;
&lt;br /&gt;
The OpenOCD software runs a target server on localhost:3333 which we can ask GDB to attach to:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) target extended-remote localhost:3333&lt;br /&gt;
Remote debugging using localhost:3333&lt;br /&gt;
0x000870ba in prvCheckTasksWaitingTermination () at /home/jburgess/Documents/emf/Mk2-Firmware/hardware/emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
2839                    while( uxTasksDeleted &amp;gt; ( UBaseType_t ) 0U )&lt;br /&gt;
(gdb) &lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List FreeRTOS tasks ===&lt;br /&gt;
To list the running tasks you can use &amp;quot;info threads&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) info threads&lt;br /&gt;
[New Thread 537348080]&lt;br /&gt;
[New Thread 537396632]&lt;br /&gt;
[New Thread 537402416]&lt;br /&gt;
[New Thread 537394216]&lt;br /&gt;
[New Thread 537405232]&lt;br /&gt;
[New Thread 537393096]&lt;br /&gt;
[New Thread 537348848]&lt;br /&gt;
[New Thread 537398824]&lt;br /&gt;
[New Thread 537400224]&lt;br /&gt;
[New Thread 537346984]&lt;br /&gt;
[New Thread 537403512]&lt;br /&gt;
[New Thread 537397728]&lt;br /&gt;
[New Thread 537395312]&lt;br /&gt;
  Id   Target Id         Frame &lt;br /&gt;
  14   Thread 537395312 (MessageCh) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  13   Thread 537397728 (RadioTran) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  12   Thread 537403512 (IMUTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  11   Thread 537346984 (TiLDATask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  10   Thread 537400224 (GUI) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  9    Thread 537398824 (LCD) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  8    Thread 537348848 (Tmr Svc) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  7    Thread 537393096 (RGBTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  6    Thread 537405232 (HomeScree) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  5    Thread 537394216 (BatterySa) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  4    Thread 537402416 (PMICTask) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  3    Thread 537396632 (RadioRece) 0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
  2    Thread 537348080 (IDLE :  : Running) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
* 1    Thread 537401320 (AppOpener) 0x000870ba in prvCheckTasksWaitingTermination ()&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/tasks.c:2839&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Most threads should claim to be in &amp;quot;vPortYield()&amp;quot; which is one of the OS routines that a task will call when it wants to sleep for a while.Select a task and you can obtain its backtrace:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
(gdb) thread 6&lt;br /&gt;
[Switching to thread 6 (Thread 537405232)]&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
385             __asm volatile( &amp;quot;isb&amp;quot; );&lt;br /&gt;
(gdb) bt&lt;br /&gt;
#0  0x00086750 in vPortYield () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:385&lt;br /&gt;
#1  0x00085c60 in xEventGroupWaitBits (xEventGroup=0x20082b78, uxBitsToWaitFor=1, xClearOnExit=0, xWaitForAllBits=0, xTicksToWait=&amp;lt;optimized out&amp;gt;)&lt;br /&gt;
    at emfcamp/sam/libraries/FreeRTOS_ARM/utility/event_groups.c:357&lt;br /&gt;
#2  0x0008453e in HomeScreenApp::task (this=0x20082710) at /tmp/build9091009552223609902.tmp/HomeScreenApp.cpp:157&lt;br /&gt;
#3  0x000818b4 in Task::taskCaller (this=0x20082710) at /tmp/build9091009552223609902.tmp/Task.cpp:78&lt;br /&gt;
#4  0x00081906 in Task::_task (self=&amp;lt;optimized out&amp;gt;) at /tmp/build9091009552223609902.tmp/Task.cpp:87&lt;br /&gt;
#5  0x00086768 in ulPortSetInterruptMask () at emfcamp/sam/libraries/FreeRTOS_ARM/utility/port.c:423&lt;br /&gt;
Backtrace stopped: previous frame identical to this frame (corrupt stack?)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
=== Known issues ===&lt;br /&gt;
* Normally when you hit a breakpoint GDB will automatically switch to the thread that hit it. This is not happening at the moment. If you interrupt the code or hit a breakpoint you may have to manually switch threads. The 'info threads' puts &amp;quot;Running&amp;quot; next to task being executed and this is probably the one you need to switch to.&lt;br /&gt;
* When you attach and detach GDB doesn't automatically halt/resume the target. You can do this manually using the interface on port 3333 or just tell GDB to continue, then interrupt to stop it.&lt;br /&gt;
* On exit GDB hits an assert and asks whether you want a core dump.&lt;br /&gt;
* I had a problem where the badge kept stopping at a breakpoint that I set in a previous GDB session and I was unable to fix it without power cycling the badge and restarting GDB &amp;amp; OpenOCD.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=File:Jtag-header-solder-side.jpg&amp;diff=3709</id>
		<title>File:Jtag-header-solder-side.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=File:Jtag-header-solder-side.jpg&amp;diff=3709"/>
		<updated>2014-09-15T21:20:29Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: Close up showing the JTAG header soldered on the LCD side of the TiLDA.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Close up showing the JTAG header soldered on the LCD side of the TiLDA.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=File:Board-with-adapter.jpg&amp;diff=3708</id>
		<title>File:Board-with-adapter.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=File:Board-with-adapter.jpg&amp;diff=3708"/>
		<updated>2014-09-15T21:15:24Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: TiLDA connected to Olimex Tiny JTAG debugger&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TiLDA connected to Olimex Tiny JTAG debugger&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=File:Jtag-header.jpg&amp;diff=3707</id>
		<title>File:Jtag-header.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=File:Jtag-header.jpg&amp;diff=3707"/>
		<updated>2014-09-15T20:57:51Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: The JTAG header before being soldered to the board&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The JTAG header before being soldered to the board&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=File:Jtag-header-in-place-highlight.jpg&amp;diff=3706</id>
		<title>File:Jtag-header-in-place-highlight.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=File:Jtag-header-in-place-highlight.jpg&amp;diff=3706"/>
		<updated>2014-09-15T20:54:44Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: Shows a TiLDA with the JTAG header soldered on.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shows a TiLDA with the JTAG header soldered on.&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3705</id>
		<title>TiLDA MKe</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=TiLDA_MKe&amp;diff=3705"/>
		<updated>2014-09-14T23:18:54Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: Add comment on setting #define DEBUG 1 for USB serial logging&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TiLDA MKe project, Code name &amp;quot;ElectroMagnetic Boogaloo&amp;quot;, is being headed by [[User:Dpslwk|'RepRap' Matt]] and [[User:thinkl33t|Bob]]&lt;br /&gt;
[[File:IMG_0474.jpg|500px|right|thumb|Front]]&lt;br /&gt;
[[File:Badge_Front.png|right|thumb|Front]]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/E_(mathematical_constant) Why MKe?]&lt;br /&gt;
&lt;br /&gt;
Please Note: There are a couple of minor hardware and some firmware issues that might be effecting your badge. If you've let the magic smoke out of your charge controller or have tried to re-flash and ended up with nothing but a couple of dimly glowing lights then DO NOT DESPAIR -It's recoverable and fixes, documentation and lots of firmware are still being produced :)&lt;br /&gt;
&lt;br /&gt;
=Aim= &lt;br /&gt;
The main aim of the 2014 badge is to give camp attendees live schedule updates and notifications. As with the original TiLDA we wanted to keep with an Arduino compatible platform that will allow badge hacking during and after the camp. As with the previous badge all code and design files are available.&lt;br /&gt;
&lt;br /&gt;
==Battery Warning==&lt;br /&gt;
'''Always make sure you plug your battery in the right way round!'''  If you don't, the charge controller will let out its magic smoke and die / become damaged and die later.  The badge itself will still work, but it wont have the ability to charge anymore.  &lt;br /&gt;
&lt;br /&gt;
We think this is the cause of the charge controller issues a small number of badges had at the event was due to this mistake being made during final assembly on-site. &lt;br /&gt;
&lt;br /&gt;
'''Lithium Batteries are dangerous!'''  While these batteries are better protected than the MK1 batteries, they are still scary.  Do not short your battery, and if it starts bulging or gets punctured, '''DO NOT USE IT AGAIN''' and dispose of it properly.&lt;br /&gt;
&lt;br /&gt;
==Features and Functions==&lt;br /&gt;
[[File:Badge_Back.png|right|thumb|Back]]&lt;br /&gt;
* Torch mode - Press the light button next to the screen. It will only light up fully if it's hung upside down to avoid blinding&lt;br /&gt;
* Snake&lt;br /&gt;
* Tetris&lt;br /&gt;
&lt;br /&gt;
'''Please note that there's a known issue with the badge freezing'''. We're trying to work out what's causing this, but in the meantime pressing &amp;quot;reset&amp;quot; should get the badge back to life. Help with debugging is highly welcome!&lt;br /&gt;
&lt;br /&gt;
== How to get going ==&lt;br /&gt;
=== Set up your environment ===&lt;br /&gt;
* Plug your badge into your computer via USB&lt;br /&gt;
* Download Arduino IDE 1.5.7 from http://arduino.cc/en/main/software#toc3&lt;br /&gt;
* “git clone” or download TiLDA source code from https://github.com/emfcamp/Mk2-Firmware&lt;br /&gt;
* Start the Arduino IDE. &lt;br /&gt;
* Now you have to change the sketchbook-folder to be the folder you just cloned. To do this use File | Preferences | “Set Sketchbook location”. On MacOS, this is Arduino | Preferences &lt;br /&gt;
* Restart the Arduino IDE&lt;br /&gt;
* Open sketch “EMF2014”&lt;br /&gt;
* Set Tools | Board to MKe v0.333 (RTOS Core)&lt;br /&gt;
* Set Tools | Port to correct port (you might have to research this - some operating systems like Windows require you to install drivers or become a member of a certain group)&lt;br /&gt;
** On MacOS this is will start /dev/tty.usbmodem with 4 digits, and change for each port&lt;br /&gt;
** On Linux this is usually /dev/ttyACM0 but may be a higher number if you have other USB Serial devices&lt;br /&gt;
* Hit the upload button&lt;br /&gt;
* Wait&lt;br /&gt;
* Woohoo - You just successfully uploaded code to your badge&lt;br /&gt;
&lt;br /&gt;
=== Your first “Hello world” app ===&lt;br /&gt;
There’s a “HelloWorldApp.cpp” file in which you can play around. In order for it to show up on the Homescreen you have to uncomment line 51 in AppManager.cpp and flash the changed code to the badge. Great app pull requests are appreciated!&lt;br /&gt;
&lt;br /&gt;
If you are still using the Arduino IDE at this point, note that it will not let you edit the .cpp and .h files that are needed to create Apps for the badge. To force the IDE to re-compile/re-read any files you've edited using an external editor, make sure to go to the File -&amp;gt; Preferences dialog box, and check the &amp;quot;Use external editor&amp;quot; checkbox.&lt;br /&gt;
&lt;br /&gt;
=== Why are things so different from standard Arduino code? ===&lt;br /&gt;
We’re using a library called FreeRTOS that allows us to multitask - something that’s normally not possible with standard Arduino code. This allows us to run multiple tasks at the same time. FreeRTOS uses preemptive scheduling to switch between the task. Due to this we have to be very careful about how we do some things. For example we can’t just define interrupts for buttons in every task (imagine the mess!) or write to the serial port directly (your task might stop in the middle of the message). &lt;br /&gt;
&lt;br /&gt;
We’ve also spend quite a lot of time to make the build-in components as easy to use as possible without having every task to write lots of boilerplate code. If you feel like using the build-in components on the badge, chances are we already wrote a wrapper for them that is already used by one of the other tasks. &lt;br /&gt;
&lt;br /&gt;
Have a look at the “Documentation” section in this document for a full list of API functions. You will avoid a lot of headaches if you stick to those.&lt;br /&gt;
=== How to use the badge with pure Arduino code ===&lt;br /&gt;
If you prefer you can always start from scratch without FreeRTOS or any of our code, just keep in mind that you won’t be able to receive messages via radio or use any of the API features we already added. Just start a new sketch in the Arduino IDE for that and get going. If you want to load the main firmware again just change the sketch to “EMF2014” and upload again.&lt;br /&gt;
=== Debugging and Gotchas ===&lt;br /&gt;
* The USB serial is set up to 115200 baud. There are lots of terminals that can connect to them. See below for how to enable the debug logging.&lt;br /&gt;
* If you can’t revive a badge you can short the two erase pins and press the reset button while holding it down.&lt;br /&gt;
* Avoid busy waiting, use FreeRTOS queues and Tilda::delay() instead&lt;br /&gt;
* Don’t use low level functions like interrupts or serial ports directly unless you really, really know how FreeRTOS will handle them. For general logging you can use Tilda::log()&lt;br /&gt;
* If sending code to the badge using the Arduino IDE &amp;quot;Upload&amp;quot; button fails, even though the /dev/ttyACM0 (linux com port) is there, just retry, twice if neccessary.&lt;br /&gt;
&lt;br /&gt;
=== Code structure ===&lt;br /&gt;
* FreeRTOS has the concept of “Tasks” which work like threads. We’ve wrappered them in a class called “Task” (for background stuff) and “Apps” (for foreground, one-at-a-time things)&lt;br /&gt;
* Everything needs to be in the main EMF2014 folder. Subfolders are not allowed. This is an Arduino IDE restriction :(&lt;br /&gt;
=== Radio infrastructure ===&lt;br /&gt;
The radio infrastructure is distributed between DKs. Every “gateway” has a Raspberry Pi with two Ciseco USB radios. We never had the chance to actually try it with a large number of badges in the same spot, so please don’t expect it to work perfectly.&lt;br /&gt;
&lt;br /&gt;
=== Contribute ===&lt;br /&gt;
Send us a pull request via [https://github.com/emfcamp/Mk2-Firmware GitHub] - We’ll do our best to review and merge the good ones during EMF so others can use them.&lt;br /&gt;
&lt;br /&gt;
=Hardware=&lt;br /&gt;
&lt;br /&gt;
The following hardware has been included on the badge.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/microcontrollers/arm/sam3x.aspx Atmel ATSAM3X8E]&lt;br /&gt;
** This is the same chip as the [http://arduino.cc/en/Main/ArduinoBoardDue Arduino Due] and gives us the base platform for the badge&lt;br /&gt;
** 32bit ARM Cortex M3 * 84MHz&lt;br /&gt;
** 512KBytes Flash RAM&lt;br /&gt;
** 96KBytes of SRAM&lt;br /&gt;
* A 128x64 pixel monochrome LCD display&lt;br /&gt;
* [http://shop.ciseco.co.uk/srf-wireless-rf-radio-surface-mount/ Ciseco SRF Radio]&lt;br /&gt;
** 868Mhz RF Transceiver&lt;br /&gt;
** Simple UART interface&lt;br /&gt;
** Low power sleep mode&lt;br /&gt;
* [http://www.invensense.com/mems/gyro/mpu6050.html MPU-6050] 3-axis Accelerometer and 3-axis gyro&lt;br /&gt;
** I2C interface&lt;br /&gt;
** Tri-Axis angular rate sensor (gyro) with a sensitivity up to 131 LSBs/dps and a full-scale range of ±250, ±500, ±1000, and ±2000dps&lt;br /&gt;
** Tri-Axis accelerometer with a programmable full scale range of ±2g, ±4g, ±8g and ±16g&lt;br /&gt;
** Digital Motion Processing™ (DMP™) engine offloads complex MotionFusion, sensor timing synchronisation and gesture detection&lt;br /&gt;
* PMIC &amp;amp; LiPo&lt;br /&gt;
* Joystick&lt;br /&gt;
* Buttons&lt;br /&gt;
* RGB LEDs&lt;br /&gt;
* IR&lt;br /&gt;
* Arduino Headers&lt;br /&gt;
* Pads for wearable tech&lt;br /&gt;
&lt;br /&gt;
= Firmware Documentation =&lt;br /&gt;
== Debugging ==&lt;br /&gt;
===Enabling the USB serial debug log messages===&lt;br /&gt;
To enable the debug logging you must uncomment the following line in [https://github.com/emfcamp/Mk2-Firmware/blob/master/hardware/emfcamp/sam/libraries/debug/debug.h#L42 hardware/emfcamp/sam/libraries/debug/debug.h]&lt;br /&gt;
&lt;br /&gt;
 // Enable debug task and output&lt;br /&gt;
 // #define DEBUG 1&lt;br /&gt;
&lt;br /&gt;
===Tilda::log(String text)===&lt;br /&gt;
&lt;br /&gt;
This logs “text” to the serial console. To read it connect to it via the Arduino IDE Serial Monitor. Don’t use “SerialUSB.println” or similar -- it’s not thread-safe and you might end up with utter nonsense.&lt;br /&gt;
== Buttons ==&lt;br /&gt;
The badge has 8 buttons: Up, Down, Left, Right, Center (on the joystick), A, B and Light. You can use arduino-style “digitalRead(BUTTON_RIGHT)” to read the current status of any button, but you can’t define your own interrupt (because we already did that). This doesn’t mean you can’t wait for a certain button to be pressed, it just means you have to approach it slightly differently:&lt;br /&gt;
&lt;br /&gt;
Example: A simple app displaying the button code&lt;br /&gt;
 void ButtonApp::task() {&lt;br /&gt;
     ButtonSubscription allButtons = Tilda::createButtonSubscription(LIGHT | A | B | UP | DOWN | LEFT | RIGHT | CENTER);&lt;br /&gt;
 &lt;br /&gt;
     while(true) {&lt;br /&gt;
         Button button = allButtons.waitForPress(1000);&lt;br /&gt;
         if (button == A) {&lt;br /&gt;
             debug::log(“You pressed button A”);&lt;br /&gt;
         } else if (button == LEFT) {&lt;br /&gt;
             debug::log(“You pressed LEFT”);&lt;br /&gt;
         } else if (button == NONE) {&lt;br /&gt;
             debug::log(“No button has been pressed in 1000ms”); &lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription Tilda::createButtonSubscription(&amp;lt;buttons&amp;gt;)===&lt;br /&gt;
&lt;br /&gt;
Registers a subscriptions for a defined set of buttons and returns a ButtonSubscription. Multiple Buttons can be combined via “|” (see example above). One button can not be subscribed by more than 10 subscriptions (which shouldn’t really happen, but keep it in mind). &lt;br /&gt;
&lt;br /&gt;
Don’t use this function in a constructor, it requires FreeRTOS to be running. Using it inside the task() function is the only safe place for it.&lt;br /&gt;
&lt;br /&gt;
===Button ButtonSubscription::waitForPress(TimeInTicks timeout)===&lt;br /&gt;
&lt;br /&gt;
This is normally called in a loop. It causes the task to block until one of the buttons has been pressed. If the timeout occurs before any button has been pressed “NONE” will be returned. &lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::waitForPress()===&lt;br /&gt;
&lt;br /&gt;
The same as above, but without the timeout.&lt;br /&gt;
&lt;br /&gt;
===ButtonSubscription::clear()===&lt;br /&gt;
&lt;br /&gt;
This should be called after an App has been suspended, just before it’s going to be resumed. It causes the Queue to be cleared which could otherwise lead to buttons being reported that have been pressed while other apps were in the foreground. Have a look at the FlashLightApp for an example.&lt;br /&gt;
&lt;br /&gt;
==LEDs==&lt;br /&gt;
===Tilda::setLedColor(Led led, Color color);===&lt;br /&gt;
===Tilde::setLedColor(Color color);===&lt;br /&gt;
&lt;br /&gt;
Sets the color of all or one led. Color is an object that takes red, green and blue as a value between 0 and 255 each. If no led is defined both leds will be set to the same color.&lt;br /&gt;
&lt;br /&gt;
Example: A simple color-changing task&lt;br /&gt;
 void ColorfulTask::task() {&lt;br /&gt;
     while(true) {&lt;br /&gt;
         Tilda::setLedColor(LED1, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 255, 0}); // Green&lt;br /&gt;
         Tilda::setLedColor(LED2, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
         Tilda::setLedColor(LED1, {0, 0, 255}); // Blue&lt;br /&gt;
         Tilda::setLedColor(LED2, {255, 0, 0}); // Red&lt;br /&gt;
         Tilda::delay(300);&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Display==&lt;br /&gt;
&lt;br /&gt;
The Display Library is based on GLCDv3 (http://playground.arduino.cc/Code/GLCDks0108), docs (http://code.google.com/p/glcd-arduino/source/browse/trunk/glcd/doc/GLCD_Documentation.pdf) but adapted to support our screen.  The Init routine is called in the setup, and the LCDTask takes care of ensuring the screen is updated every 40ms if required (Unlike the original GLCD library, screen updates are decoupled from the graphics routines.)&lt;br /&gt;
&lt;br /&gt;
Also available is M2tklib (https://code.google.com/p/m2tklib/) which is a nice toolkit library.  Further details on using this will come later, but expect the main loop to be handled for you, and just passing the menu structure you require for your app.&lt;br /&gt;
&lt;br /&gt;
Right now, you can call the GLCD functions directly with GLCD.DrawBitmap() for example.  This is going to change to be accessed through the GUITask class in the near future, to ensure only one task at a time writes to the screen.  Expect this to be simply GUITask in place of GLCD, along with a registering a redraw call back to GUITask. The bitmap format, by the way, is rather unconventional but there are a couple of utility scripts to convert popular formats down in the hacking section below - you can grab the SponsorsApp.h as an example and swap out the bitmap array with one of your choosing.&lt;br /&gt;
&lt;br /&gt;
Extra features that are included, GLCD.SetRotation() will handle rotation of the screen for you, and GLCD.CurrentWidth() and GLCD.CurrentHeight will give you the correct Width and Height for the current orientation.  GLCD.Width and GLCD.Height constants are not available, and the GLCD predefined Text areas will not be rotated for you, if you require this define your own text areas.&lt;br /&gt;
&lt;br /&gt;
Note that one function was not ported to the badge version of GLCD, &amp;quot;Printf&amp;quot;, you'll have to cope without it.&lt;br /&gt;
&lt;br /&gt;
== Sound == &lt;br /&gt;
There's a piezo on the board, but we haven't added code for it to the current firmware. Pull requests are very welcome!&lt;br /&gt;
&lt;br /&gt;
== IMU ==&lt;br /&gt;
=== Tilda::getOrientation ===&lt;br /&gt;
returns &amp;quot; ORIENTATION_HELD&amp;quot;, &amp;quot;ORIENTATION_RIGHT&amp;quot; (joystick to the right of the screen), &amp;quot;ORIENTATION_HUNG&amp;quot; or &amp;quot;ORIENTATION_LEFT&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Flash Storage ==&lt;br /&gt;
We have 2mb of flash storage, but we're not using it in the main firmware - Please get this working!&lt;br /&gt;
== Data: Schedule ==&lt;br /&gt;
===Tilda::getDataStore().getSchedule(day, location) ===&lt;br /&gt;
== Date: Weather Forecast ==&lt;br /&gt;
===Tilda::getDataStore().getWeatherForecast()===&lt;br /&gt;
== Radio ==&lt;br /&gt;
There's no way of sending messages in the current version of the firmware, sorry :(&lt;br /&gt;
&lt;br /&gt;
== Time ==&lt;br /&gt;
&lt;br /&gt;
=== Tilda::delay(uint16_t delayInMs) === &lt;br /&gt;
&lt;br /&gt;
Works like Arduino’s delay(), but is FreeRTOS-safe. It’s safe to use this function before FreeRTOS has started.&lt;br /&gt;
&lt;br /&gt;
=== tilda::getClock() ===&lt;br /&gt;
&lt;br /&gt;
Returns an instance of https://github.com/MarkusLange/Arduino-Due-RTC-Library/blob/master/rtc_clock.h&lt;br /&gt;
&lt;br /&gt;
==Settings==&lt;br /&gt;
===uint16_t tilda::getBadgeId()===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==2.12. Battery==&lt;br /&gt;
===float TiLDA::getBatteryVoltage()===&lt;br /&gt;
Returns the current voltage as a float&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getBatteryPercent()===&lt;br /&gt;
Returns the current voltage as a percentage&lt;br /&gt;
&lt;br /&gt;
===uint8_t TiLDA::getChargeState()===&lt;br /&gt;
Returns the charge state&lt;br /&gt;
&lt;br /&gt;
0 Charging&lt;br /&gt;
1 Not Charging&lt;br /&gt;
&lt;br /&gt;
=Hacking=&lt;br /&gt;
To use our board definition you will need to first get the Arduino 1.5.7 IDE from [http://arduino.cc/en/Main/Software#toc3 here]&amp;lt;br/&amp;gt;&lt;br /&gt;
Next you can download the TiLDA MKe Firmware project from either the [https://github.com/emfcamp/Mk2-Firmware github repo] or via [https://github.com/emfcamp/Mk2-Firmware/archive/master.zip direct download]&amp;lt;br/&amp;gt;&lt;br /&gt;
Now copy the &amp;quot;hardware&amp;quot; folder to your Sketchbook folder, this is usually ~/Sketchbook/&amp;lt;br&amp;gt;&lt;br /&gt;
or&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternative option is to set the Arduino 1.5.7 sketchbook folder to the Mk2-Firmware directory.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Start the Arduino IDE and your will be able to select TiLDA MKe v0.333 for the Tools-&amp;gt;Board menu&lt;br /&gt;
&lt;br /&gt;
* Draft 3d print-able and laser-able case files [http://www.thingiverse.com/thing:436815 here]&lt;br /&gt;
* A Python script (via [https://twitter.com/trotmaster99 @trotmaster99]) that converts a monochrome bitmap image into a format suitable for the Tilda can be found [http://pastebin.com/8XeazQjT here].&lt;br /&gt;
* A similar script in Perl to create TiLDA MKe fullscreen bitmaps from XBM: -&lt;br /&gt;
&amp;lt;div style =&amp;quot;height:200px;overflow-x:hidden;overflow-y:auto;border: 4px solid orange;&amp;quot;&amp;gt;&lt;br /&gt;
'''xbm2mke.pl by [[User:Msemtd]]'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!perl -w&lt;br /&gt;
use strict;&lt;br /&gt;
# Little script to convert a regular XBM to TiLDA MKe bitmap&lt;br /&gt;
# only tested with fullscreen bitmaps!&lt;br /&gt;
# Hot file handle magic...&lt;br /&gt;
select((select(STDERR), $| = 1)[0]);&lt;br /&gt;
select((select(STDOUT), $| = 1)[0]);&lt;br /&gt;
sub t(@);&lt;br /&gt;
sub d($);&lt;br /&gt;
sub chug($);&lt;br /&gt;
my $f = shift;&lt;br /&gt;
#~ $f = 'blankish.xbm' if not $f;&lt;br /&gt;
if(not defined $f or not $f =~ /^(.*)\.xbm$/i){&lt;br /&gt;
    die &amp;quot;Usage: gimme an XBM file dude!\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
my $name = $1;&lt;br /&gt;
t &amp;quot;Reading file '$f'...&amp;quot;;&lt;br /&gt;
my $data = chug($f);&lt;br /&gt;
t &amp;quot;OK&amp;quot;;&lt;br /&gt;
my @lines = split /^/, $data;&lt;br /&gt;
@lines = grep{chomp; s/^\s+//; s/\s+$//; length;} @lines;&lt;br /&gt;
#~ t d \@lines;&lt;br /&gt;
my($width, $height) = (0,0);&lt;br /&gt;
my @head = @lines[0..5];&lt;br /&gt;
foreach(@head){&lt;br /&gt;
    if(/_width\s+(\d+)/){$width = $1;}&lt;br /&gt;
    if(/_height\s+(\d+)/){$height = $1;}&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;width x height = $width x $height&amp;quot;;&lt;br /&gt;
my @k;&lt;br /&gt;
foreach(@lines){ push @k, split /,/; }&lt;br /&gt;
@k = grep { s/^.*(0x[0-9A-Fa-f]{1,2}).*$/$1/o; /(0x[0-9A-Fa-f]{1,2})/o } @k;&lt;br /&gt;
#~ t d \@k;&lt;br /&gt;
my $bc = scalar(@k);&lt;br /&gt;
t &amp;quot;Pulled out $bc hex bytes&amp;quot;;&lt;br /&gt;
if($bc != $width * $height / 8) {&lt;br /&gt;
    die &amp;quot;byte count $bc does not match that expected for w x h&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
t &amp;quot;OK - reorder bytes for MKe bitmap&amp;quot;;&lt;br /&gt;
my $wb = int($width/8) + (($width &amp;amp; 0x07) ? 1: 0);&lt;br /&gt;
t &amp;quot;width in whole bytes for $width pixels = $wb&amp;quot;;&lt;br /&gt;
my @mke;&lt;br /&gt;
for(my $col = 0; $col &amp;lt; $wb; $col++){&lt;br /&gt;
    for(my $row = $height - 1; $row &amp;gt;= 0; $row--){&lt;br /&gt;
        my $idx = ($row * $wb) + $col;&lt;br /&gt;
        my $val = $k[$idx];&lt;br /&gt;
        #~ t &amp;quot;Column $col + Row $row = idx $idx = $val&amp;quot;;&lt;br /&gt;
        push @mke, $val;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
my $out = &amp;quot;static const uint8_t &amp;quot;.uc($name).&amp;quot;_BM[] = {\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $width, // width\n&amp;quot;&lt;br /&gt;
	.&amp;quot;    $height , // height\n&amp;quot;;&lt;br /&gt;
#~ $out .= join(&amp;quot;, &amp;quot;, @mke);&lt;br /&gt;
while(scalar @mke){&lt;br /&gt;
	$out .= join(&amp;quot;, &amp;quot;, splice(@mke, 0, 16)).&amp;quot;,\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
$out .= &amp;quot;};\n&amp;quot;;&lt;br /&gt;
# meh, just print it out&lt;br /&gt;
t $out;&lt;br /&gt;
&lt;br /&gt;
sub t(@) {&lt;br /&gt;
    foreach (@_) {&lt;br /&gt;
       print STDOUT &amp;quot;$_\n&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
sub d($) {&lt;br /&gt;
    require Data::Dumper;&lt;br /&gt;
    my $s = $_[0];&lt;br /&gt;
    my $d = Data::Dumper::Dumper($s);&lt;br /&gt;
    $d =~ s/^\$VAR1 =\s*//;&lt;br /&gt;
    $d =~ s/;$//;&lt;br /&gt;
    chomp $d;&lt;br /&gt;
    return $d;&lt;br /&gt;
}&lt;br /&gt;
sub chug($) {&lt;br /&gt;
  my $filename = shift;&lt;br /&gt;
  local *F;&lt;br /&gt;
  open F, &amp;quot;&amp;lt; $filename&amp;quot; or die &amp;quot;Couldn't open `$filename': $!&amp;quot;;&lt;br /&gt;
  local $/ = undef;&lt;br /&gt;
  return &amp;lt;F&amp;gt;;&lt;br /&gt;
}  # F automatically closed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;span id=github&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Source =&lt;br /&gt;
&lt;br /&gt;
All the source code and designs are on openly available on Github:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Hardware Hardware] - the full board design&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Documentation Documentation] - a dump of relevant parts datasheets&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Firmware Firmware] - source code for the badge software&lt;br /&gt;
* [https://github.com/emfcamp/Mk2-Software Software] - server-side software for the network&lt;br /&gt;
&lt;br /&gt;
If you want to help, point your IRC client to #tilda on Freenode.&lt;br /&gt;
&lt;br /&gt;
[[Category: Badges]]&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=Feedback&amp;diff=3551</id>
		<title>Feedback</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=Feedback&amp;diff=3551"/>
		<updated>2014-09-03T23:51:06Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: /* Stuff that could be improved */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{link-banner}}&lt;br /&gt;
Please let us know what went well and what didn't go well at EMF this year. We really do care about your feedback and we'll try and improve this for next time.&lt;br /&gt;
&lt;br /&gt;
Add your feedback below:&lt;br /&gt;
&lt;br /&gt;
== Good Stuff ==&lt;br /&gt;
&lt;br /&gt;
* Location&lt;br /&gt;
* Badges&lt;br /&gt;
* Variety of talks [+1]&lt;br /&gt;
* Showers [+∞]&lt;br /&gt;
* Hand washing facilities&lt;br /&gt;
** putting the showers (with hot water in handbasins) next to toilets v.good&lt;br /&gt;
* Parking&lt;br /&gt;
* Shuttle trailer to car park&lt;br /&gt;
** ... and shuttle to BLY railway station. Made coming by public transport a doddle.&lt;br /&gt;
* Power &amp;amp; data infrastructure - pretty much rock solid throughout! [+2]&lt;br /&gt;
* Speedy response of volunteers/organisers to problem resolution&lt;br /&gt;
* Service at the bar was good (while the drinks lasted), and it was very nice to have ''multiple'' indoor social spaces, esp for people who wanted a quieter lounge as well as louder bar.&lt;br /&gt;
** Being able to check beer availability on the till website was awesome!&lt;br /&gt;
* Floor panel roads [+4]&lt;br /&gt;
* String lights (cut through to showers was awesome!) [+1]&lt;br /&gt;
* Ability to hire tables/chairs/marquees/hay bales etc. - were all good quality, too. [+1]&lt;br /&gt;
* Kids workshops [+1]&lt;br /&gt;
* Arcade!&lt;br /&gt;
* Friendliness of other attendees&lt;br /&gt;
* First aid&lt;br /&gt;
* Shop - selling books of speakers was a really nice idea, and it was good to talk to speakers &amp;amp; do signing there afterwards.&lt;br /&gt;
* That spinning music installation.&lt;br /&gt;
* Lighting - I didn't have to turn my torch on at all, but it was still dark enough in my tent to sleep.&lt;br /&gt;
* Club Mate.&lt;br /&gt;
* Ring making workshop&lt;br /&gt;
* Lake was pretty&lt;br /&gt;
* Supportive atmosphere for speakers and very nice feedback afterwards&lt;br /&gt;
* Water: plentiful flow, tasty water, cool dispensers [+1]&lt;br /&gt;
** Hand soap by taps (udders?)&lt;br /&gt;
* Keeping toilet paper supplies topped up in all the toilets&lt;br /&gt;
* Nice choice of real ales and proper cider&lt;br /&gt;
* Lasershow + Chiptunes in Tent A&lt;br /&gt;
* Tschunk&lt;br /&gt;
* Everything that Dimitri brought along&lt;br /&gt;
* EMF CTF: Like getting lock pickers to cook your food, playing IRL replay,relay and pre-play attacks and memory corruption, sadly no real-life cross-site scripting :)&lt;br /&gt;
&lt;br /&gt;
== Stuff that could be improved ==&lt;br /&gt;
&lt;br /&gt;
* Buy more beer! [[User:Russ|Russ]] ([[User talk:Russ|talk]]) [+1]&lt;br /&gt;
** No firkins next time, kils only! --[[User:Sde|Sde]] ([[User talk:Sde|talk]])&lt;br /&gt;
* Toilets... 'nuff said!  [[User:AndyB|AndyB]] ([[User talk:AndyB|talk]]) [+2]&lt;br /&gt;
** Agreed - I've seen portakabins (like the shower blocks) that containing proper flushing loos. They're ''much'' less stinky and likely to block up than the portaloos we had, which didn't always seem willing to drop their loads into their collection tanks, leading to nastiness and health hazards (even without the pumping contractor being rubbish)&lt;br /&gt;
** Additionally, LIGHTS in the toilets.  Having to use my phone / badge as a torch to see what was going on while i cleaned off the toilet before sitting down was particularly difficult. [[User:Thinkl33t|Thinkl33t]] ([[User talk:Thinkl33t|talk]]) 20:05, 1 September 2014 (UTC)&lt;br /&gt;
** thunderboxes2go.co.uk are good and know how to handle local authority problems, they have done shambala for 10+ years - high enough capacity to not need emptying during the event [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
** Maybe ask Cambridge &amp;amp; District CAMRA who provided the toilets for Cambridge 41st beer festival - they had some fairly nice flushing toilets which came on a trailer, a bit like the posh wash showers. I think Jonty mentioned that a lot of providers were put off by the fact that we're a festival. Well, if these guys are ok with providing for a beer festival, they must be pretty brave! -[[User:Alecjw]]&lt;br /&gt;
** Definite vote for the trailer-style flushing toilets, with multiple cubicles (+sinks, lights and mirrors) on one tow-along trailer, just like the showers. I've seen these at MANY festivals - though, granted, usually only in 'posh' camping/press/VIP areas. Should be possible if you manage to convince the providers that we're not a rowdy bunch of drunken teenagers!&lt;br /&gt;
** A clue to the problem with the chemical toilets is in the name: no chemical sanitiser/deodoriser was used in any toilet I tried. Adding Elsan or similar to the toilets would probably have made them much more acceptable. [[User:PhilSwinbank|PhilSwinbank]] ([[User talk:PhilSwinbank|talk]]) 22:18, 3 September 2014 (UTC)&lt;br /&gt;
* Make sure that drinking water is clearly labelled as such&lt;br /&gt;
* More food and drink options&lt;br /&gt;
** Eg. non-caffeine / low or no sugar options&lt;br /&gt;
** Chips!&lt;br /&gt;
** Jacket potato vendor&lt;br /&gt;
** Healthy 'green' food&lt;br /&gt;
** also possibly going on later, a lot of the places shut up shop quite early.&lt;br /&gt;
** A late night vendor would be fantastic - doesn't have to be fancy food, but just something hot to eat after 9pm [+2]&lt;br /&gt;
* Survey positions of lanes/tents/DKs as early as possible before items arrive and mark out.--[[User:Sully|Sully]] ([[User talk:Sully|talk]]) 12:06, 1 September 2014 (UTC)&lt;br /&gt;
** This was planned but we were let down by the rather poor state of mobile GIS software. &lt;br /&gt;
*** there are multiple open source solutions for mapping, try https://umap.openstreetmap.fr/en/ or reach to out myself or #openstreetmap, there are many OSM'ers in the UK,  [[User:Jburgess777|Jburgess777]] ([[User talk:Jburgess777|talk]]).&lt;br /&gt;
* Similar to this, measure for fence panels and drop stillage appropriately, to avoid the need to carry loads of them right up the camping field by hand&lt;br /&gt;
* Make it longer! There was loads of cool stuff I didn't have change to check out :( After all that work everyone does, it was a shame I couldn't experience it all! ([[User:Chewie|Chewie]])&lt;br /&gt;
* Visibility of presentations in tents (brighter projectors/darker tents??) ([[User:StuartL]]) [+2]&lt;br /&gt;
* washing points over drains/soakaway so the ground doesn't get muddy ([[User:Chewie|Chewie]]) [+3]&lt;br /&gt;
* Mark out/allocate spaces for villages who had pinpointed locations on maps ([[User:Markp]]) [+1]&lt;br /&gt;
* Use more plasma screens in stages instead of projectors ([[User:Markp]]).  Or (better, as then the speaker can point to things) black fabric shades for the screen or marquee roof&lt;br /&gt;
* Improved arrangements for washing and washing up (and handling the waste water from that) [+1]&lt;br /&gt;
* Provide sanitizer gel dispensers at water points and near loos [+1]&lt;br /&gt;
* Have the schedule linked off the EMF main page&lt;br /&gt;
* Distribute and display paper schedules (even if their might be some last-minute changes) [+2]&lt;br /&gt;
** Or have small screens at the entrances to tents showing what's currently on &amp;amp; what's next.&lt;br /&gt;
* Much more workshop activity (more hands-on electronics and physical making) [+5]&lt;br /&gt;
* Do have component vendors (maybe at their cost for marquee/power/space)&lt;br /&gt;
** This is very difficult without a clear list of what will sell, as CPC was arranged to appear but wanted advisement ([[User:Stanto]])&lt;br /&gt;
* Pick a flatter site (for ease of disabled access)&lt;br /&gt;
* Ask speakers for bio's to include with their abstracts.  Given them an abstract length up-front instead of editing it in an ad hoc way.  Confirm acceptance to speakers and workshop organisers earlier.&lt;br /&gt;
** Do this after talks have been accepted. I didn't write my talk so didn't know details until I got the OK.&lt;br /&gt;
* Make and enforce a clear music curfew (say from midnight or 1am or 2am to 8 or 9am or 10am), to defend those sleeping from (eg) the technoevangelists and the drunk [+4]&lt;br /&gt;
** Perhaps try to select a site next time where we can make part of the site to be a quiet area, eg a part surrounded by trees for natural sound insulation. Then enforce a noise curfew there. I'm not keen on the idea of having a noise curfew covering the entire camp though. [[User:Alecjw]] [+1]&lt;br /&gt;
** Seconding enforced quiet/family camping area, but no overall noise curfew. It didn't take long to get away from the worst noise, and the end of the field by the kids' area was incredibly quiet (though strangely empty!!)&lt;br /&gt;
* Loos not so near food vendors (pong + visible urinals offputting) [+5]&lt;br /&gt;
* stronger enforcement/signage of quiet camping area [+4]&lt;br /&gt;
* an explicit invitation (with clear instructions) to report Code of Conduct violations in open ceremony, brochure, Twitter, etc. We had no direct reports to Team Comfort, but several anecdotal tweets after the event -- when it's much too late. [[User:Martind|Martind]] ([[User talk:Martind|talk]]) 20:58, 1 September 2014 (UTC) [+1]&lt;br /&gt;
* quieter, less-enclosed and more spacious bar (I suffer from social anxiety when I'm closed in with crowds, so I had a very sober emf!).  [[User:Jane C|Jane C]]&lt;br /&gt;
** perhaps an outdoor seating area if a larger marquee is too costly.&lt;br /&gt;
* use our collective knowledge of technology to sort accessibility issues &lt;br /&gt;
**ring-fence money for things like closed-loop in the stages early on. &lt;br /&gt;
**ask people about their access requirements much earlier on - e.g. when they buy a ticket - so that there is more time to meet these requirements (or reach a workable compromise)&lt;br /&gt;
**Build some kind of working system for preventing able-bodied people from using the disabled loos and showers (radar keys that only work when the loo is empty?) [[User:Jane C|Jane C]]&lt;br /&gt;
* Info desk didn't seem to have the details wrt. volunteers, so when I volunteered I was sent out and found I wasn't needed.  Suggest splitting the job - having a volunteer team leader (or several, in shifts) whose job it is to know who is where and also to make sure nobody gets stuck on a gate for 12 hours (eg. rotating people to more interesting places every couple of hours). ([[User:TonyHoyle|TonyHoyle]])&lt;br /&gt;
* Also similar to this, a register of 'on call' people - excess volunteers who can deal with sudden demands for people (esp. in the case of fire I can imagine this would be extremely useful - you'd potentially need to cordon off a largish area very quickly, and that takes people.  More mundane reasons would be a talk/workshop accumulating a large queue that needs managing). ([[User:TonyHoyle|TonyHoyle]])&lt;br /&gt;
* add GPS or other location aware technology like BTLE/iBeacon to the badges for automatic now/next notifications [[User:Jburgess777|Jburgess777]] ([[User talk:Jburgess777|talk]]).&lt;br /&gt;
&lt;br /&gt;
==Suggestions==&lt;br /&gt;
* Ask for an optional email address for each ticket to go on your announce only mailing list.  Only the person that bought the tickets got your emails and they were slow to forward them on meaning most messages were received too late.&lt;br /&gt;
* Ask for age of children when booking, to give better planning stats for workshops etc. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* A talk (a bit like lightning talks) where people are given 5-10 minutes to share what they did with the previous event's badge. (If someone sends me the competition winners/runners up, I'll co-ordinate it) [[User:MatS|MatS]] ([[User talk:MatS|talk]]) 07:54, 1 September 2014 (UTC)&lt;br /&gt;
* Pre-paid accounts for spending money on food/beer/whatever to negate need for cash ([[User:Markp]])&lt;br /&gt;
* Have a fleet of communal wheel-barrows to help people transport their stuff from car to campsite [+1]&lt;br /&gt;
** Stepney City Farm have a fleet of broken wheelbarrows – fix ’em, use ’em, everybody wins! ([[User:Andylolz]])&lt;br /&gt;
** Or purchase some sack trolleys&lt;br /&gt;
* contactless payment gear for food, beer, workshops&lt;br /&gt;
** We had contactless payment for beer! (And we also offered cashback.) We should have messaged that better. Contactless payment for other things is complex, as we don't really control them. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
* forewarn food vendors to expect all-day demand, not just mealtimes, so they can stock and staff appropriately [+1]&lt;br /&gt;
** food vendors were pretty much *events* caterers, used to feeding people snacks/lunch, we need *festival* caterers who are used to feeding people who are staying for a number of days. thethalicafe.co.uk? bedouin tent (shambala)? +late night options [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
*** It's really difficult to get caterers. Now we're a bit better known it's getting easier. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
* pinboard (offline) notice board everyone can contribute to (lost property, mini event notices eg rocket launches, would like to meet.., etc) [+1]&lt;br /&gt;
* Ask people who want to give workshops if they'd be happy to give more than one session - the blacksmiths' output was extreme, but even giving two or three sessions would greatly increase the % of attendees who could sign up.&lt;br /&gt;
* Sign-ups some kind of &amp;quot;express preference&amp;quot; systems, so most people (including those who don't check email regularly) can get at least one of their top choices, rather than first-come-first-served.&lt;br /&gt;
* Board games tent in the evenings [+4]&lt;br /&gt;
* Poker tent&lt;br /&gt;
* Be less ambitious with badge functionality [+3]&lt;br /&gt;
** And provide full documentation of features/functionality [+1]&lt;br /&gt;
** And sample code for each function&lt;br /&gt;
** Perhaps a back-to-basics through-hole design that comes with soldering iron, solder and instructions?&lt;br /&gt;
** I think we might build on this design for the next event. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
** Software that doesn't involve an OS (but rather more conventional Arduinoery) might be more easily hackable by others during/after the event? Especially given libraries for people to do amusing things with the peer-to-peer radio...&lt;br /&gt;
* EMF is unlike other festivals - for a large number of people, carrying kit to/from car is impractical and security walking every car through site is time-consuming and volunteer-intensive (not to mention the fact that cars driving off site weren't walked off). Suggest that the parking area is directly next to and easily accessible from the camping area (e.g. just separated by hay bales to stop cars driving on to the camping area).&lt;br /&gt;
** As a village/car user you could generally provide your own security person walking in front of the car. This works 2 fold: 1) security doesn't need to walk for you 2) less waiting time for you since you already provide someone to walk.&lt;br /&gt;
** The plan for this was to allow people to drive onto site on the Thursday evening. It wasn't very well communicated and we had a *very* tight setup schedule so we needed to reduce this as much as possible. This is ultimately an issue with our setup schedule&lt;br /&gt;
** It wouldn't work on this site, but for some locations it might be possible to have a drop-off point close to camping (with a limited number of cars at one time), better idea than having cars (ignition source) close to tents. Some people were taking the mickey on Monday morning, many people driving onto site that could have carried things instead tying up volunteer resources to escort them.&lt;br /&gt;
* Provide job descriptions for traffic control, parking and entrance gatehouse. Instructions were handed from volunteer to volunteer by word of mouth and whilst common sense prevailed, it would have been useful to have instructions as to what to do under certain circumstances and a list of answers to FAQs, e.g.:&lt;br /&gt;
** What if somebody didn't have a parking ticket and wanted to park?&lt;br /&gt;
** What if somebody was just dropping off - where should they do this?&lt;br /&gt;
** What times were shuttle buses running?&lt;br /&gt;
** What times the gates were open/closed?&lt;br /&gt;
** Have a priority queue for people with machine readable tickets (ie paper!)&lt;br /&gt;
* Add suggested age ranges for all workshops, some of the &amp;quot;adult&amp;quot; workshops were also very suitable for children (e.g. electronic fashion, solar pv) or could have been run once in main workshop once in kid's area [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Bolt the fence from the right side, I know we didn't even want it at all but local authorities can be fussy, I've been at a festival before who did the same and they made them fix it during the event.. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Want the good coffee on Monday morning, especially for drivers :) Maybe in the car park to help persuade people off site. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Would be good to have eggs, fresh milk, bacon at the shop (there was a comment like &amp;quot;we don't have eggs, they break too easily&amp;quot; - so charge extra to cover this, though it's probably not as bad as you think..) [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
** Morrisons did a tent with Milk, Bread, Burgers, BBQs etc @ http://www.festivalofcycling.org/expo/name/morrisons/, might be worth asking them? [[User:Jburgess777|Jburgess777]] ([[User talk:Jburgess777|talk]])&lt;br /&gt;
* Start ticket sales (a couple of months?) earlier, maybe with a slightly bigger difference between early ticket prices and full price to encourage attendees to get in early (which in turn would improve cashflow) [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]]) [+1]&lt;br /&gt;
* Start ticket sales *now* whilst you have all the publicity or at least have a page up where people can register to be emailed once the next event has tickets for sale.  That way you get your current mailing list + everyone else who has only just learned about it as your audience. [[User:Alteralias|Alteralias]]&lt;br /&gt;
* Cluster the talks into related-topic sessions&lt;br /&gt;
* Volunteering stuff ([[User:HughePaul|HughePaul]])&lt;br /&gt;
** Whiteboard in info tent for current issues / tasks, handover&lt;br /&gt;
** Have info tent next to security tent so both can be available at the same time and all the time.&lt;br /&gt;
*** The info tent and the gatehouse/security tent could be two sides of the same erection.&lt;br /&gt;
** have predefined named people in shifts for head of / coordination of volunteering (could also double as an info/security tent staff)&lt;br /&gt;
** maybe stream some talks in info tent so they don't feel like they are missing things&lt;br /&gt;
** more formal defined (and communicated) lost-property form and procedure&lt;br /&gt;
** define volunteer job roles to make handovers easier and so we know what we are meant to be doing&lt;br /&gt;
* Have dedicated blog / tweet / website updating person/team&lt;br /&gt;
* big screen with latest official event update tweets&lt;br /&gt;
* info about getting DISconnected from DKs and leaving the site in vehicles&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=Feedback&amp;diff=3550</id>
		<title>Feedback</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=Feedback&amp;diff=3550"/>
		<updated>2014-09-03T23:45:19Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{link-banner}}&lt;br /&gt;
Please let us know what went well and what didn't go well at EMF this year. We really do care about your feedback and we'll try and improve this for next time.&lt;br /&gt;
&lt;br /&gt;
Add your feedback below:&lt;br /&gt;
&lt;br /&gt;
== Good Stuff ==&lt;br /&gt;
&lt;br /&gt;
* Location&lt;br /&gt;
* Badges&lt;br /&gt;
* Variety of talks [+1]&lt;br /&gt;
* Showers [+∞]&lt;br /&gt;
* Hand washing facilities&lt;br /&gt;
** putting the showers (with hot water in handbasins) next to toilets v.good&lt;br /&gt;
* Parking&lt;br /&gt;
* Shuttle trailer to car park&lt;br /&gt;
** ... and shuttle to BLY railway station. Made coming by public transport a doddle.&lt;br /&gt;
* Power &amp;amp; data infrastructure - pretty much rock solid throughout! [+2]&lt;br /&gt;
* Speedy response of volunteers/organisers to problem resolution&lt;br /&gt;
* Service at the bar was good (while the drinks lasted), and it was very nice to have ''multiple'' indoor social spaces, esp for people who wanted a quieter lounge as well as louder bar.&lt;br /&gt;
** Being able to check beer availability on the till website was awesome!&lt;br /&gt;
* Floor panel roads [+4]&lt;br /&gt;
* String lights (cut through to showers was awesome!) [+1]&lt;br /&gt;
* Ability to hire tables/chairs/marquees/hay bales etc. - were all good quality, too. [+1]&lt;br /&gt;
* Kids workshops [+1]&lt;br /&gt;
* Arcade!&lt;br /&gt;
* Friendliness of other attendees&lt;br /&gt;
* First aid&lt;br /&gt;
* Shop - selling books of speakers was a really nice idea, and it was good to talk to speakers &amp;amp; do signing there afterwards.&lt;br /&gt;
* That spinning music installation.&lt;br /&gt;
* Lighting - I didn't have to turn my torch on at all, but it was still dark enough in my tent to sleep.&lt;br /&gt;
* Club Mate.&lt;br /&gt;
* Ring making workshop&lt;br /&gt;
* Lake was pretty&lt;br /&gt;
* Supportive atmosphere for speakers and very nice feedback afterwards&lt;br /&gt;
* Water: plentiful flow, tasty water, cool dispensers [+1]&lt;br /&gt;
** Hand soap by taps (udders?)&lt;br /&gt;
* Keeping toilet paper supplies topped up in all the toilets&lt;br /&gt;
* Nice choice of real ales and proper cider&lt;br /&gt;
* Lasershow + Chiptunes in Tent A&lt;br /&gt;
* Tschunk&lt;br /&gt;
* Everything that Dimitri brought along&lt;br /&gt;
* EMF CTF: Like getting lock pickers to cook your food, playing IRL replay,relay and pre-play attacks and memory corruption, sadly no real-life cross-site scripting :)&lt;br /&gt;
&lt;br /&gt;
== Stuff that could be improved ==&lt;br /&gt;
&lt;br /&gt;
* Buy more beer! [[User:Russ|Russ]] ([[User talk:Russ|talk]]) [+1]&lt;br /&gt;
** No firkins next time, kils only! --[[User:Sde|Sde]] ([[User talk:Sde|talk]])&lt;br /&gt;
* Toilets... 'nuff said!  [[User:AndyB|AndyB]] ([[User talk:AndyB|talk]]) [+2]&lt;br /&gt;
** Agreed - I've seen portakabins (like the shower blocks) that containing proper flushing loos. They're ''much'' less stinky and likely to block up than the portaloos we had, which didn't always seem willing to drop their loads into their collection tanks, leading to nastiness and health hazards (even without the pumping contractor being rubbish)&lt;br /&gt;
** Additionally, LIGHTS in the toilets.  Having to use my phone / badge as a torch to see what was going on while i cleaned off the toilet before sitting down was particularly difficult. [[User:Thinkl33t|Thinkl33t]] ([[User talk:Thinkl33t|talk]]) 20:05, 1 September 2014 (UTC)&lt;br /&gt;
** thunderboxes2go.co.uk are good and know how to handle local authority problems, they have done shambala for 10+ years - high enough capacity to not need emptying during the event [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
** Maybe ask Cambridge &amp;amp; District CAMRA who provided the toilets for Cambridge 41st beer festival - they had some fairly nice flushing toilets which came on a trailer, a bit like the posh wash showers. I think Jonty mentioned that a lot of providers were put off by the fact that we're a festival. Well, if these guys are ok with providing for a beer festival, they must be pretty brave! -[[User:Alecjw]]&lt;br /&gt;
** Definite vote for the trailer-style flushing toilets, with multiple cubicles (+sinks, lights and mirrors) on one tow-along trailer, just like the showers. I've seen these at MANY festivals - though, granted, usually only in 'posh' camping/press/VIP areas. Should be possible if you manage to convince the providers that we're not a rowdy bunch of drunken teenagers!&lt;br /&gt;
** A clue to the problem with the chemical toilets is in the name: no chemical sanitiser/deodoriser was used in any toilet I tried. Adding Elsan or similar to the toilets would probably have made them much more acceptable. [[User:PhilSwinbank|PhilSwinbank]] ([[User talk:PhilSwinbank|talk]]) 22:18, 3 September 2014 (UTC)&lt;br /&gt;
* Make sure that drinking water is clearly labelled as such&lt;br /&gt;
* More food and drink options&lt;br /&gt;
** Eg. non-caffeine / low or no sugar options&lt;br /&gt;
** Chips!&lt;br /&gt;
** Jacket potato vendor&lt;br /&gt;
** Healthy 'green' food&lt;br /&gt;
** also possibly going on later, a lot of the places shut up shop quite early.&lt;br /&gt;
** A late night vendor would be fantastic - doesn't have to be fancy food, but just something hot to eat after 9pm [+2]&lt;br /&gt;
* Survey positions of lanes/tents/DKs as early as possible before items arrive and mark out.--[[User:Sully|Sully]] ([[User talk:Sully|talk]]) 12:06, 1 September 2014 (UTC)&lt;br /&gt;
** This was planned but we were let down by the rather poor state of mobile GIS software. &lt;br /&gt;
*** there are multiple open source solutions for mapping, try https://umap.openstreetmap.fr/en/ or reach to out myself or #openstreetmap, there are many OSM'ers in the UK,  [[User:Jburgess777|Jburgess777]] ([[User talk:Jburgess777|talk]]).&lt;br /&gt;
* Similar to this, measure for fence panels and drop stillage appropriately, to avoid the need to carry loads of them right up the camping field by hand&lt;br /&gt;
* Make it longer! There was loads of cool stuff I didn't have change to check out :( After all that work everyone does, it was a shame I couldn't experience it all! ([[User:Chewie|Chewie]])&lt;br /&gt;
* Visibility of presentations in tents (brighter projectors/darker tents??) ([[User:StuartL]]) [+2]&lt;br /&gt;
* washing points over drains/soakaway so the ground doesn't get muddy ([[User:Chewie|Chewie]]) [+3]&lt;br /&gt;
* Mark out/allocate spaces for villages who had pinpointed locations on maps ([[User:Markp]]) [+1]&lt;br /&gt;
* Use more plasma screens in stages instead of projectors ([[User:Markp]]).  Or (better, as then the speaker can point to things) black fabric shades for the screen or marquee roof&lt;br /&gt;
* Improved arrangements for washing and washing up (and handling the waste water from that) [+1]&lt;br /&gt;
* Provide sanitizer gel dispensers at water points and near loos [+1]&lt;br /&gt;
* Have the schedule linked off the EMF main page&lt;br /&gt;
* Distribute and display paper schedules (even if their might be some last-minute changes) [+2]&lt;br /&gt;
** Or have small screens at the entrances to tents showing what's currently on &amp;amp; what's next.&lt;br /&gt;
* Much more workshop activity (more hands-on electronics and physical making) [+5]&lt;br /&gt;
* Do have component vendors (maybe at their cost for marquee/power/space)&lt;br /&gt;
** This is very difficult without a clear list of what will sell, as CPC was arranged to appear but wanted advisement ([[User:Stanto]])&lt;br /&gt;
* Pick a flatter site (for ease of disabled access)&lt;br /&gt;
* Ask speakers for bio's to include with their abstracts.  Given them an abstract length up-front instead of editing it in an ad hoc way.  Confirm acceptance to speakers and workshop organisers earlier.&lt;br /&gt;
** Do this after talks have been accepted. I didn't write my talk so didn't know details until I got the OK.&lt;br /&gt;
* Make and enforce a clear music curfew (say from midnight or 1am or 2am to 8 or 9am or 10am), to defend those sleeping from (eg) the technoevangelists and the drunk [+4]&lt;br /&gt;
** Perhaps try to select a site next time where we can make part of the site to be a quiet area, eg a part surrounded by trees for natural sound insulation. Then enforce a noise curfew there. I'm not keen on the idea of having a noise curfew covering the entire camp though. [[User:Alecjw]] [+1]&lt;br /&gt;
** Seconding enforced quiet/family camping area, but no overall noise curfew. It didn't take long to get away from the worst noise, and the end of the field by the kids' area was incredibly quiet (though strangely empty!!)&lt;br /&gt;
* Loos not so near food vendors (pong + visible urinals offputting) [+5]&lt;br /&gt;
* stronger enforcement/signage of quiet camping area [+4]&lt;br /&gt;
* an explicit invitation (with clear instructions) to report Code of Conduct violations in open ceremony, brochure, Twitter, etc. We had no direct reports to Team Comfort, but several anecdotal tweets after the event -- when it's much too late. [[User:Martind|Martind]] ([[User talk:Martind|talk]]) 20:58, 1 September 2014 (UTC) [+1]&lt;br /&gt;
* quieter, less-enclosed and more spacious bar (I suffer from social anxiety when I'm closed in with crowds, so I had a very sober emf!).  [[User:Jane C|Jane C]]&lt;br /&gt;
** perhaps an outdoor seating area if a larger marquee is too costly.&lt;br /&gt;
* use our collective knowledge of technology to sort accessibility issues &lt;br /&gt;
**ring-fence money for things like closed-loop in the stages early on. &lt;br /&gt;
**ask people about their access requirements much earlier on - e.g. when they buy a ticket - so that there is more time to meet these requirements (or reach a workable compromise)&lt;br /&gt;
**Build some kind of working system for preventing able-bodied people from using the disabled loos and showers (radar keys that only work when the loo is empty?) [[User:Jane C|Jane C]]&lt;br /&gt;
* Info desk didn't seem to have the details wrt. volunteers, so when I volunteered I was sent out and found I wasn't needed.  Suggest splitting the job - having a volunteer team leader (or several, in shifts) whose job it is to know who is where and also to make sure nobody gets stuck on a gate for 12 hours (eg. rotating people to more interesting places every couple of hours). ([[User:TonyHoyle|TonyHoyle]])&lt;br /&gt;
* Also similar to this, a register of 'on call' people - excess volunteers who can deal with sudden demands for people (esp. in the case of fire I can imagine this would be extremely useful - you'd potentially need to cordon off a largish area very quickly, and that takes people.  More mundane reasons would be a talk/workshop accumulating a large queue that needs managing). ([[User:TonyHoyle|TonyHoyle]])&lt;br /&gt;
&lt;br /&gt;
==Suggestions==&lt;br /&gt;
* Ask for an optional email address for each ticket to go on your announce only mailing list.  Only the person that bought the tickets got your emails and they were slow to forward them on meaning most messages were received too late.&lt;br /&gt;
* Ask for age of children when booking, to give better planning stats for workshops etc. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* A talk (a bit like lightning talks) where people are given 5-10 minutes to share what they did with the previous event's badge. (If someone sends me the competition winners/runners up, I'll co-ordinate it) [[User:MatS|MatS]] ([[User talk:MatS|talk]]) 07:54, 1 September 2014 (UTC)&lt;br /&gt;
* Pre-paid accounts for spending money on food/beer/whatever to negate need for cash ([[User:Markp]])&lt;br /&gt;
* Have a fleet of communal wheel-barrows to help people transport their stuff from car to campsite [+1]&lt;br /&gt;
** Stepney City Farm have a fleet of broken wheelbarrows – fix ’em, use ’em, everybody wins! ([[User:Andylolz]])&lt;br /&gt;
** Or purchase some sack trolleys&lt;br /&gt;
* contactless payment gear for food, beer, workshops&lt;br /&gt;
** We had contactless payment for beer! (And we also offered cashback.) We should have messaged that better. Contactless payment for other things is complex, as we don't really control them. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
* forewarn food vendors to expect all-day demand, not just mealtimes, so they can stock and staff appropriately [+1]&lt;br /&gt;
** food vendors were pretty much *events* caterers, used to feeding people snacks/lunch, we need *festival* caterers who are used to feeding people who are staying for a number of days. thethalicafe.co.uk? bedouin tent (shambala)? +late night options [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
*** It's really difficult to get caterers. Now we're a bit better known it's getting easier. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
* pinboard (offline) notice board everyone can contribute to (lost property, mini event notices eg rocket launches, would like to meet.., etc) [+1]&lt;br /&gt;
* Ask people who want to give workshops if they'd be happy to give more than one session - the blacksmiths' output was extreme, but even giving two or three sessions would greatly increase the % of attendees who could sign up.&lt;br /&gt;
* Sign-ups some kind of &amp;quot;express preference&amp;quot; systems, so most people (including those who don't check email regularly) can get at least one of their top choices, rather than first-come-first-served.&lt;br /&gt;
* Board games tent in the evenings [+4]&lt;br /&gt;
* Poker tent&lt;br /&gt;
* Be less ambitious with badge functionality [+3]&lt;br /&gt;
** And provide full documentation of features/functionality [+1]&lt;br /&gt;
** And sample code for each function&lt;br /&gt;
** Perhaps a back-to-basics through-hole design that comes with soldering iron, solder and instructions?&lt;br /&gt;
** I think we might build on this design for the next event. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
** Software that doesn't involve an OS (but rather more conventional Arduinoery) might be more easily hackable by others during/after the event? Especially given libraries for people to do amusing things with the peer-to-peer radio...&lt;br /&gt;
* EMF is unlike other festivals - for a large number of people, carrying kit to/from car is impractical and security walking every car through site is time-consuming and volunteer-intensive (not to mention the fact that cars driving off site weren't walked off). Suggest that the parking area is directly next to and easily accessible from the camping area (e.g. just separated by hay bales to stop cars driving on to the camping area).&lt;br /&gt;
** As a village/car user you could generally provide your own security person walking in front of the car. This works 2 fold: 1) security doesn't need to walk for you 2) less waiting time for you since you already provide someone to walk.&lt;br /&gt;
** The plan for this was to allow people to drive onto site on the Thursday evening. It wasn't very well communicated and we had a *very* tight setup schedule so we needed to reduce this as much as possible. This is ultimately an issue with our setup schedule&lt;br /&gt;
** It wouldn't work on this site, but for some locations it might be possible to have a drop-off point close to camping (with a limited number of cars at one time), better idea than having cars (ignition source) close to tents. Some people were taking the mickey on Monday morning, many people driving onto site that could have carried things instead tying up volunteer resources to escort them.&lt;br /&gt;
* Provide job descriptions for traffic control, parking and entrance gatehouse. Instructions were handed from volunteer to volunteer by word of mouth and whilst common sense prevailed, it would have been useful to have instructions as to what to do under certain circumstances and a list of answers to FAQs, e.g.:&lt;br /&gt;
** What if somebody didn't have a parking ticket and wanted to park?&lt;br /&gt;
** What if somebody was just dropping off - where should they do this?&lt;br /&gt;
** What times were shuttle buses running?&lt;br /&gt;
** What times the gates were open/closed?&lt;br /&gt;
** Have a priority queue for people with machine readable tickets (ie paper!)&lt;br /&gt;
* Add suggested age ranges for all workshops, some of the &amp;quot;adult&amp;quot; workshops were also very suitable for children (e.g. electronic fashion, solar pv) or could have been run once in main workshop once in kid's area [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Bolt the fence from the right side, I know we didn't even want it at all but local authorities can be fussy, I've been at a festival before who did the same and they made them fix it during the event.. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Want the good coffee on Monday morning, especially for drivers :) Maybe in the car park to help persuade people off site. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Would be good to have eggs, fresh milk, bacon at the shop (there was a comment like &amp;quot;we don't have eggs, they break too easily&amp;quot; - so charge extra to cover this, though it's probably not as bad as you think..) [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
** Morrisons did a tent with Milk, Bread, Burgers, BBQs etc @ http://www.festivalofcycling.org/expo/name/morrisons/, might be worth asking them? [[User:Jburgess777|Jburgess777]] ([[User talk:Jburgess777|talk]])&lt;br /&gt;
* Start ticket sales (a couple of months?) earlier, maybe with a slightly bigger difference between early ticket prices and full price to encourage attendees to get in early (which in turn would improve cashflow) [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]]) [+1]&lt;br /&gt;
* Start ticket sales *now* whilst you have all the publicity or at least have a page up where people can register to be emailed once the next event has tickets for sale.  That way you get your current mailing list + everyone else who has only just learned about it as your audience. [[User:Alteralias|Alteralias]]&lt;br /&gt;
* Cluster the talks into related-topic sessions&lt;br /&gt;
* Volunteering stuff ([[User:HughePaul|HughePaul]])&lt;br /&gt;
** Whiteboard in info tent for current issues / tasks, handover&lt;br /&gt;
** Have info tent next to security tent so both can be available at the same time and all the time.&lt;br /&gt;
*** The info tent and the gatehouse/security tent could be two sides of the same erection.&lt;br /&gt;
** have predefined named people in shifts for head of / coordination of volunteering (could also double as an info/security tent staff)&lt;br /&gt;
** maybe stream some talks in info tent so they don't feel like they are missing things&lt;br /&gt;
** more formal defined (and communicated) lost-property form and procedure&lt;br /&gt;
** define volunteer job roles to make handovers easier and so we know what we are meant to be doing&lt;br /&gt;
* Have dedicated blog / tweet / website updating person/team&lt;br /&gt;
* big screen with latest official event update tweets&lt;br /&gt;
* info about getting DISconnected from DKs and leaving the site in vehicles&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
	<entry>
		<id>https://wiki.emfcamp.org/2014/w/index.php?title=Feedback&amp;diff=3549</id>
		<title>Feedback</title>
		<link rel="alternate" type="text/html" href="https://wiki.emfcamp.org/2014/w/index.php?title=Feedback&amp;diff=3549"/>
		<updated>2014-09-03T23:32:28Z</updated>

		<summary type="html">&lt;p&gt;Jburgess777: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{link-banner}}&lt;br /&gt;
Please let us know what went well and what didn't go well at EMF this year. We really do care about your feedback and we'll try and improve this for next time.&lt;br /&gt;
&lt;br /&gt;
Add your feedback below:&lt;br /&gt;
&lt;br /&gt;
== Good Stuff ==&lt;br /&gt;
&lt;br /&gt;
* Location&lt;br /&gt;
* Badges&lt;br /&gt;
* Variety of talks [+1]&lt;br /&gt;
* Showers [+∞]&lt;br /&gt;
* Hand washing facilities&lt;br /&gt;
** putting the showers (with hot water in handbasins) next to toilets v.good&lt;br /&gt;
* Parking&lt;br /&gt;
* Shuttle trailer to car park&lt;br /&gt;
** ... and shuttle to BLY railway station. Made coming by public transport a doddle.&lt;br /&gt;
* Power &amp;amp; data infrastructure - pretty much rock solid throughout! [+2]&lt;br /&gt;
* Speedy response of volunteers/organisers to problem resolution&lt;br /&gt;
* Service at the bar was good (while the drinks lasted), and it was very nice to have ''multiple'' indoor social spaces, esp for people who wanted a quieter lounge as well as louder bar.&lt;br /&gt;
** Being able to check beer availability on the till website was awesome!&lt;br /&gt;
* Floor panel roads [+4]&lt;br /&gt;
* String lights (cut through to showers was awesome!) [+1]&lt;br /&gt;
* Ability to hire tables/chairs/marquees/hay bales etc. - were all good quality, too. [+1]&lt;br /&gt;
* Kids workshops [+1]&lt;br /&gt;
* Arcade!&lt;br /&gt;
* Friendliness of other attendees&lt;br /&gt;
* First aid&lt;br /&gt;
* Shop - selling books of speakers was a really nice idea, and it was good to talk to speakers &amp;amp; do signing there afterwards.&lt;br /&gt;
* That spinning music installation.&lt;br /&gt;
* Lighting - I didn't have to turn my torch on at all, but it was still dark enough in my tent to sleep.&lt;br /&gt;
* Club Mate.&lt;br /&gt;
* Ring making workshop&lt;br /&gt;
* Lake was pretty&lt;br /&gt;
* Supportive atmosphere for speakers and very nice feedback afterwards&lt;br /&gt;
* Water: plentiful flow, tasty water, cool dispensers [+1]&lt;br /&gt;
** Hand soap by taps (udders?)&lt;br /&gt;
* Keeping toilet paper supplies topped up in all the toilets&lt;br /&gt;
* Nice choice of real ales and proper cider&lt;br /&gt;
* Lasershow + Chiptunes in Tent A&lt;br /&gt;
* Tschunk&lt;br /&gt;
* Everything that Dimitri brought along&lt;br /&gt;
* EMF CTF: Like getting lock pickers to cook your food, playing IRL replay,relay and pre-play attacks and memory corruption, sadly no real-life cross-site scripting :)&lt;br /&gt;
&lt;br /&gt;
== Stuff that could be improved ==&lt;br /&gt;
&lt;br /&gt;
* Buy more beer! [[User:Russ|Russ]] ([[User talk:Russ|talk]]) [+1]&lt;br /&gt;
** No firkins next time, kils only! --[[User:Sde|Sde]] ([[User talk:Sde|talk]])&lt;br /&gt;
* Toilets... 'nuff said!  [[User:AndyB|AndyB]] ([[User talk:AndyB|talk]]) [+2]&lt;br /&gt;
** Agreed - I've seen portakabins (like the shower blocks) that containing proper flushing loos. They're ''much'' less stinky and likely to block up than the portaloos we had, which didn't always seem willing to drop their loads into their collection tanks, leading to nastiness and health hazards (even without the pumping contractor being rubbish)&lt;br /&gt;
** Additionally, LIGHTS in the toilets.  Having to use my phone / badge as a torch to see what was going on while i cleaned off the toilet before sitting down was particularly difficult. [[User:Thinkl33t|Thinkl33t]] ([[User talk:Thinkl33t|talk]]) 20:05, 1 September 2014 (UTC)&lt;br /&gt;
** thunderboxes2go.co.uk are good and know how to handle local authority problems, they have done shambala for 10+ years - high enough capacity to not need emptying during the event [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
** Maybe ask Cambridge &amp;amp; District CAMRA who provided the toilets for Cambridge 41st beer festival - they had some fairly nice flushing toilets which came on a trailer, a bit like the posh wash showers. I think Jonty mentioned that a lot of providers were put off by the fact that we're a festival. Well, if these guys are ok with providing for a beer festival, they must be pretty brave! -[[User:Alecjw]]&lt;br /&gt;
** Definite vote for the trailer-style flushing toilets, with multiple cubicles (+sinks, lights and mirrors) on one tow-along trailer, just like the showers. I've seen these at MANY festivals - though, granted, usually only in 'posh' camping/press/VIP areas. Should be possible if you manage to convince the providers that we're not a rowdy bunch of drunken teenagers!&lt;br /&gt;
** A clue to the problem with the chemical toilets is in the name: no chemical sanitiser/deodoriser was used in any toilet I tried. Adding Elsan or similar to the toilets would probably have made them much more acceptable. [[User:PhilSwinbank|PhilSwinbank]] ([[User talk:PhilSwinbank|talk]]) 22:18, 3 September 2014 (UTC)&lt;br /&gt;
* Make sure that drinking water is clearly labelled as such&lt;br /&gt;
* More food and drink options&lt;br /&gt;
** Eg. non-caffeine / low or no sugar options&lt;br /&gt;
** Chips!&lt;br /&gt;
** Jacket potato vendor&lt;br /&gt;
** Healthy 'green' food&lt;br /&gt;
** also possibly going on later, a lot of the places shut up shop quite early.&lt;br /&gt;
** A late night vendor would be fantastic - doesn't have to be fancy food, but just something hot to eat after 9pm [+2]&lt;br /&gt;
* Survey positions of lanes/tents/DKs as early as possible before items arrive and mark out.--[[User:Sully|Sully]] ([[User talk:Sully|talk]]) 12:06, 1 September 2014 (UTC)&lt;br /&gt;
** This was planned but we were let down by the rather poor state of mobile GIS software. &lt;br /&gt;
* Similar to this, measure for fence panels and drop stillage appropriately, to avoid the need to carry loads of them right up the camping field by hand&lt;br /&gt;
* Make it longer! There was loads of cool stuff I didn't have change to check out :( After all that work everyone does, it was a shame I couldn't experience it all! ([[User:Chewie|Chewie]])&lt;br /&gt;
* Visibility of presentations in tents (brighter projectors/darker tents??) ([[User:StuartL]]) [+2]&lt;br /&gt;
* washing points over drains/soakaway so the ground doesn't get muddy ([[User:Chewie|Chewie]]) [+3]&lt;br /&gt;
* Mark out/allocate spaces for villages who had pinpointed locations on maps ([[User:Markp]]) [+1]&lt;br /&gt;
* Use more plasma screens in stages instead of projectors ([[User:Markp]]).  Or (better, as then the speaker can point to things) black fabric shades for the screen or marquee roof&lt;br /&gt;
* Improved arrangements for washing and washing up (and handling the waste water from that) [+1]&lt;br /&gt;
* Provide sanitizer gel dispensers at water points and near loos [+1]&lt;br /&gt;
* Have the schedule linked off the EMF main page&lt;br /&gt;
* Distribute and display paper schedules (even if their might be some last-minute changes) [+2]&lt;br /&gt;
** Or have small screens at the entrances to tents showing what's currently on &amp;amp; what's next.&lt;br /&gt;
* Much more workshop activity (more hands-on electronics and physical making) [+5]&lt;br /&gt;
* Do have component vendors (maybe at their cost for marquee/power/space)&lt;br /&gt;
** This is very difficult without a clear list of what will sell, as CPC was arranged to appear but wanted advisement ([[User:Stanto]])&lt;br /&gt;
* Pick a flatter site (for ease of disabled access)&lt;br /&gt;
* Ask speakers for bio's to include with their abstracts.  Given them an abstract length up-front instead of editing it in an ad hoc way.  Confirm acceptance to speakers and workshop organisers earlier.&lt;br /&gt;
** Do this after talks have been accepted. I didn't write my talk so didn't know details until I got the OK.&lt;br /&gt;
* Make and enforce a clear music curfew (say from midnight or 1am or 2am to 8 or 9am or 10am), to defend those sleeping from (eg) the technoevangelists and the drunk [+4]&lt;br /&gt;
** Perhaps try to select a site next time where we can make part of the site to be a quiet area, eg a part surrounded by trees for natural sound insulation. Then enforce a noise curfew there. I'm not keen on the idea of having a noise curfew covering the entire camp though. [[User:Alecjw]] [+1]&lt;br /&gt;
** Seconding enforced quiet/family camping area, but no overall noise curfew. It didn't take long to get away from the worst noise, and the end of the field by the kids' area was incredibly quiet (though strangely empty!!)&lt;br /&gt;
* Loos not so near food vendors (pong + visible urinals offputting) [+5]&lt;br /&gt;
* stronger enforcement/signage of quiet camping area [+4]&lt;br /&gt;
* an explicit invitation (with clear instructions) to report Code of Conduct violations in open ceremony, brochure, Twitter, etc. We had no direct reports to Team Comfort, but several anecdotal tweets after the event -- when it's much too late. [[User:Martind|Martind]] ([[User talk:Martind|talk]]) 20:58, 1 September 2014 (UTC) [+1]&lt;br /&gt;
* quieter, less-enclosed and more spacious bar (I suffer from social anxiety when I'm closed in with crowds, so I had a very sober emf!).  [[User:Jane C|Jane C]]&lt;br /&gt;
** perhaps an outdoor seating area if a larger marquee is too costly.&lt;br /&gt;
* use our collective knowledge of technology to sort accessibility issues &lt;br /&gt;
**ring-fence money for things like closed-loop in the stages early on. &lt;br /&gt;
**ask people about their access requirements much earlier on - e.g. when they buy a ticket - so that there is more time to meet these requirements (or reach a workable compromise)&lt;br /&gt;
**Build some kind of working system for preventing able-bodied people from using the disabled loos and showers (radar keys that only work when the loo is empty?) [[User:Jane C|Jane C]]&lt;br /&gt;
* Info desk didn't seem to have the details wrt. volunteers, so when I volunteered I was sent out and found I wasn't needed.  Suggest splitting the job - having a volunteer team leader (or several, in shifts) whose job it is to know who is where and also to make sure nobody gets stuck on a gate for 12 hours (eg. rotating people to more interesting places every couple of hours). ([[User:TonyHoyle|TonyHoyle]])&lt;br /&gt;
* Also similar to this, a register of 'on call' people - excess volunteers who can deal with sudden demands for people (esp. in the case of fire I can imagine this would be extremely useful - you'd potentially need to cordon off a largish area very quickly, and that takes people.  More mundane reasons would be a talk/workshop accumulating a large queue that needs managing). ([[User:TonyHoyle|TonyHoyle]])&lt;br /&gt;
&lt;br /&gt;
==Suggestions==&lt;br /&gt;
* Ask for an optional email address for each ticket to go on your announce only mailing list.  Only the person that bought the tickets got your emails and they were slow to forward them on meaning most messages were received too late.&lt;br /&gt;
* Ask for age of children when booking, to give better planning stats for workshops etc. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* A talk (a bit like lightning talks) where people are given 5-10 minutes to share what they did with the previous event's badge. (If someone sends me the competition winners/runners up, I'll co-ordinate it) [[User:MatS|MatS]] ([[User talk:MatS|talk]]) 07:54, 1 September 2014 (UTC)&lt;br /&gt;
* Pre-paid accounts for spending money on food/beer/whatever to negate need for cash ([[User:Markp]])&lt;br /&gt;
* Have a fleet of communal wheel-barrows to help people transport their stuff from car to campsite [+1]&lt;br /&gt;
** Stepney City Farm have a fleet of broken wheelbarrows – fix ’em, use ’em, everybody wins! ([[User:Andylolz]])&lt;br /&gt;
** Or purchase some sack trolleys&lt;br /&gt;
* contactless payment gear for food, beer, workshops&lt;br /&gt;
** We had contactless payment for beer! (And we also offered cashback.) We should have messaged that better. Contactless payment for other things is complex, as we don't really control them. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
* forewarn food vendors to expect all-day demand, not just mealtimes, so they can stock and staff appropriately [+1]&lt;br /&gt;
** food vendors were pretty much *events* caterers, used to feeding people snacks/lunch, we need *festival* caterers who are used to feeding people who are staying for a number of days. thethalicafe.co.uk? bedouin tent (shambala)? +late night options [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
*** It's really difficult to get caterers. Now we're a bit better known it's getting easier. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
* pinboard (offline) notice board everyone can contribute to (lost property, mini event notices eg rocket launches, would like to meet.., etc) [+1]&lt;br /&gt;
* Ask people who want to give workshops if they'd be happy to give more than one session - the blacksmiths' output was extreme, but even giving two or three sessions would greatly increase the % of attendees who could sign up.&lt;br /&gt;
* Sign-ups some kind of &amp;quot;express preference&amp;quot; systems, so most people (including those who don't check email regularly) can get at least one of their top choices, rather than first-come-first-served.&lt;br /&gt;
* Board games tent in the evenings [+4]&lt;br /&gt;
* Poker tent&lt;br /&gt;
* Be less ambitious with badge functionality [+3]&lt;br /&gt;
** And provide full documentation of features/functionality [+1]&lt;br /&gt;
** And sample code for each function&lt;br /&gt;
** Perhaps a back-to-basics through-hole design that comes with soldering iron, solder and instructions?&lt;br /&gt;
** I think we might build on this design for the next event. [[User:Russ|Russ]] ([[User talk:Russ|talk]])&lt;br /&gt;
** Software that doesn't involve an OS (but rather more conventional Arduinoery) might be more easily hackable by others during/after the event? Especially given libraries for people to do amusing things with the peer-to-peer radio...&lt;br /&gt;
* EMF is unlike other festivals - for a large number of people, carrying kit to/from car is impractical and security walking every car through site is time-consuming and volunteer-intensive (not to mention the fact that cars driving off site weren't walked off). Suggest that the parking area is directly next to and easily accessible from the camping area (e.g. just separated by hay bales to stop cars driving on to the camping area).&lt;br /&gt;
** As a village/car user you could generally provide your own security person walking in front of the car. This works 2 fold: 1) security doesn't need to walk for you 2) less waiting time for you since you already provide someone to walk.&lt;br /&gt;
** The plan for this was to allow people to drive onto site on the Thursday evening. It wasn't very well communicated and we had a *very* tight setup schedule so we needed to reduce this as much as possible. This is ultimately an issue with our setup schedule&lt;br /&gt;
** It wouldn't work on this site, but for some locations it might be possible to have a drop-off point close to camping (with a limited number of cars at one time), better idea than having cars (ignition source) close to tents. Some people were taking the mickey on Monday morning, many people driving onto site that could have carried things instead tying up volunteer resources to escort them.&lt;br /&gt;
* Provide job descriptions for traffic control, parking and entrance gatehouse. Instructions were handed from volunteer to volunteer by word of mouth and whilst common sense prevailed, it would have been useful to have instructions as to what to do under certain circumstances and a list of answers to FAQs, e.g.:&lt;br /&gt;
** What if somebody didn't have a parking ticket and wanted to park?&lt;br /&gt;
** What if somebody was just dropping off - where should they do this?&lt;br /&gt;
** What times were shuttle buses running?&lt;br /&gt;
** What times the gates were open/closed?&lt;br /&gt;
** Have a priority queue for people with machine readable tickets (ie paper!)&lt;br /&gt;
* Add suggested age ranges for all workshops, some of the &amp;quot;adult&amp;quot; workshops were also very suitable for children (e.g. electronic fashion, solar pv) or could have been run once in main workshop once in kid's area [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Bolt the fence from the right side, I know we didn't even want it at all but local authorities can be fussy, I've been at a festival before who did the same and they made them fix it during the event.. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Want the good coffee on Monday morning, especially for drivers :) Maybe in the car park to help persuade people off site. [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
* Would be good to have eggs, fresh milk, bacon at the shop (there was a comment like &amp;quot;we don't have eggs, they break too easily&amp;quot; - so charge extra to cover this, though it's probably not as bad as you think..) [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]])&lt;br /&gt;
** Morrisons did a tent with Milk, Bread, Burgers, BBQs etc @ http://www.festivalofcycling.org/expo/name/morrisons/, might be worth asking them? [[User:Jburgess777|Jburgess777]] ([[User talk:Jburgess777|talk]])&lt;br /&gt;
* Start ticket sales (a couple of months?) earlier, maybe with a slightly bigger difference between early ticket prices and full price to encourage attendees to get in early (which in turn would improve cashflow) [[User:Sthen|Sthen]] ([[User talk:Sthen|talk]]) [+1]&lt;br /&gt;
* Start ticket sales *now* whilst you have all the publicity or at least have a page up where people can register to be emailed once the next event has tickets for sale.  That way you get your current mailing list + everyone else who has only just learned about it as your audience. [[User:Alteralias|Alteralias]]&lt;br /&gt;
* Cluster the talks into related-topic sessions&lt;br /&gt;
* Volunteering stuff ([[User:HughePaul|HughePaul]])&lt;br /&gt;
** Whiteboard in info tent for current issues / tasks, handover&lt;br /&gt;
** Have info tent next to security tent so both can be available at the same time and all the time.&lt;br /&gt;
*** The info tent and the gatehouse/security tent could be two sides of the same erection.&lt;br /&gt;
** have predefined named people in shifts for head of / coordination of volunteering (could also double as an info/security tent staff)&lt;br /&gt;
** maybe stream some talks in info tent so they don't feel like they are missing things&lt;br /&gt;
** more formal defined (and communicated) lost-property form and procedure&lt;br /&gt;
** define volunteer job roles to make handovers easier and so we know what we are meant to be doing&lt;br /&gt;
* Have dedicated blog / tweet / website updating person/team&lt;br /&gt;
* big screen with latest official event update tweets&lt;br /&gt;
* info about getting DISconnected from DKs and leaving the site in vehicles&lt;/div&gt;</summary>
		<author><name>Jburgess777</name></author>
	</entry>
</feed>