diff --git a/content/technical/2019/01/linux-conf-au-rust-epaper-badge.md b/content/technical/2019/01/linux-conf-au-rust-epaper-badge.md
index 79712b1..6ae4b35 100644
--- a/content/technical/2019/01/linux-conf-au-rust-epaper-badge.md
+++ b/content/technical/2019/01/linux-conf-au-rust-epaper-badge.md
@@ -296,6 +296,10 @@ them something at the same time.
All in all it was a fun project and excellent conference. If you're interested,
[the Rust source for the badge is on GitHub][source].
+
✦
+
+Next Post: [Rebuilding My Personal Infrastructure With Alpine Linux and Docker](/technical/2019/02/alpine-linux-docker-infrastructure/)
+
[BADGEr]: https://wyolum.com/projects/badger/
[edunham-talk]: https://youtu.be/uCnnhMleoKA?t=530
[edunham]: http://edunham.net/
diff --git a/content/technical/2019/01/linux-conf-au-rust-epaper-badge.yaml b/content/technical/2019/01/linux-conf-au-rust-epaper-badge.yaml
index 70cc82e..83d6705 100644
--- a/content/technical/2019/01/linux-conf-au-rust-epaper-badge.yaml
+++ b/content/technical/2019/01/linux-conf-au-rust-epaper-badge.yaml
@@ -4,7 +4,7 @@ extra: For linux.conf.au 2019 I built a digital conference badge using a Raspber
kind: article
section: technical
created_at: 2019-01-27 11:00:00.000000000 +11:00
-updated_at: 2019-01-28T20:08:26+11:00
+updated_at: 2019-03-13T20:39:51+11:00
keywords:
- rust
- linux
diff --git a/content/technical/2019/02/alpine-linux-docker-infrastructure.md b/content/technical/2019/02/alpine-linux-docker-infrastructure.md
index a8fa7e3..87fbe97 100644
--- a/content/technical/2019/02/alpine-linux-docker-infrastructure.md
+++ b/content/technical/2019/02/alpine-linux-docker-infrastructure.md
@@ -124,7 +124,7 @@ decided early on that these weren't really for me:
- A lot of them build the package from source instead of just installing the
Alpine package.
-- The Docker build was more complicated that I needed as it was trying to be
+- The Docker build was more complicated than I needed as it was trying to be
a generic image that anyone could pull and use.
- I wasn't a huge fan of pulling random Docker images from the Internet, even
if they were official images.
@@ -384,6 +384,11 @@ TLS negotiations to one.
Thanks for reading, I hope the bits didn't take too long to get from Australia
to wherever you are. Happy computing!
+
✦
+
+Previous Post: [My Rust Powered linux.conf.au e-Paper Badge](/technical/2019/01/linux-conf-au-rust-epaper-badge/)
+Next Post: [A Coding Retreat and Getting Embedded Rust Running on a SensorTag](/technical/2019/03/sensortag-embedded-rust-coding-retreat/)
+
[acme.sh]: https://github.com/Neilpang/acme.sh
[Alpine Linux]: https://alpinelinux.org/
[alpine-3.9.1]: https://alpinelinux.org/posts/Alpine-3.9.1-released.html
diff --git a/content/technical/2019/02/alpine-linux-docker-infrastructure.yaml b/content/technical/2019/02/alpine-linux-docker-infrastructure.yaml
index 32add5b..c66af16 100644
--- a/content/technical/2019/02/alpine-linux-docker-infrastructure.yaml
+++ b/content/technical/2019/02/alpine-linux-docker-infrastructure.yaml
@@ -4,7 +4,7 @@ extra: My story of replacing three servers, across two countries, running two op
kind: article
section: technical
created_at: 2019-02-28 09:45:00.000000000 +11:00
-updated_at: 2019-03-02T14:09:11+11:00
+updated_at: 2019-03-13T20:37:45+11:00
keywords:
- docker
- linux
diff --git a/content/technical/2019/03/sensortag-embedded-rust-coding-retreat.md b/content/technical/2019/03/sensortag-embedded-rust-coding-retreat.md
new file mode 100644
index 0000000..2e1d977
--- /dev/null
+++ b/content/technical/2019/03/sensortag-embedded-rust-coding-retreat.md
@@ -0,0 +1,241 @@
+This past long weekend some friends on I went on a coding retreat inspired by
+John Carmack doing similar in 2018. During the weekend I worked on adding
+support for the Texas Instruments SensorTag to the embedded Rust ecosystem.
+This post is a summary of the weekend and what I was able to achieve code wise.
+
+Back in March 2018 [John Carmack posted about a week long coding
+retreat][carmack] he went on to work on neural networks and [OpenBSD]. After
+reading the post I quoted it to some friends and commented:
+
+> > I finally took another week-long programming retreat, where I could work in
+> > hermit mode, away from the normal press of work.
+
+> > In the spirit of my retro theme, I had printed out several of Yann LeCun’s
+> > old papers and was considering doing everything completely off line, as if
+> > I was actually in a mountain cabin somewhere
+
+> I kind of love the idea of a week long code retreat in a cabin somewhere.
+
+One of my friends also liked the idea and actually made it happen! There was an
+initial attempt in June 2018 but life got in the way so it was postponed. At
+the start of the year he picked it up again and organised it for the Labour day
+long weekend, which just passed.
+
+We rented an Airbnb in the Dandenong Ranges, 45 minutes from Melbourne. Six
+people attended, two of which were from interstate. The setting was cozy, quiet
+and picturesque. Our days involved coding and collaborating, shared meals,
+and a walk or two around the surrounds.
+
+
+
+After [linux.conf.au] I got inspired to set up some self-hosted home sensors
+and automation. I did some research and picked up two [Texas Instruments
+SensorTags][SensorTag] and a debugger add-on. It uses a [CC2650]
+microcontroller with an ARM Cortex-M3 core and has support a number for low
+power wireless standards, such as Bluetooth, ZigBee, and 6LoWPAN. The CC2650
+also has a low power 16-bit sensor controller that can be used to help achieve
+years long battery life from a single CR2032 button cell. In addition to the
+microcontroller the SensorTag also add a bunch of sensors, including:
+temperature, humidity, barometer, accelerometer, gyroscope, and light.
+
+
+
+My project for the weekend was to try to get some [Rust] code running on the
+SensorTag. Rust has good support out of the box for targeting ARM Cortex
+microcontrollers but there were no crates to make interacting with this
+particular chip or board easy, so I set about building some.
+
+The first step was generating a basic crate to allow interacting with the chip
+without needing to wrap everything in an `unsafe` block and poke at random
+memory addresses. Fortunately [svd2rust] can automate this by converting System
+View Description XML files (SVD) into a Rust crate. Unfortunately TI don't
+publish SVD files for their devices. As luck would have it though, [M-Labs]
+have found that TI do publish XML descriptions in format of their own called
+DSLite. They have written a tool, [dslite2svd], that converts this to SVD, so
+you can then use `svd2rust`. It took a while to get `dslite2svd` working and I
+had to tweak to the tool to handle differences in the files I was processing,
+but eventually I was able to generate a crate that compiled.
+
+Now that I had an API for the chip I turned to working out how to program and
+debug the SensorTag with a very basic Rust program. I used the excellent
+[embedded Rust Discovery guide][discovery] as a basis for the configuration,
+tools, and process for getting code onto the SensorTag. Since this was a
+different chip from a different manufacturer it took a long time to work out
+which tools worked, how to configure them, what format binaries they wanted,
+create a linker script, etc. A lot of trial and error was performed, along with
+lots of searching online with less than perfect internet. However, by Sunday I
+could program the device, debug code, and verify that my very basic program,
+shown below, was running.
+
+```language-rust
+fn main() -> ! {
+ let _y;
+ let x = 42;
+ _y = x;
+
+ // infinite loop; just so we don't leave this stack frame
+ loop {}
+}
+```
+
+The combination that worked for programming was:
+
+* `cargo build --target thumbv7m-none-eabi`
+* Convert ELF to BIN using `cargo objcopy`, which is part of [cargo-binutils]:
+ `cargo objcopy --bin sensortag --target thumbv7m-none-eabi -- -O binary sensortag.bin`
+* Program with [UniFlash]:
+ * Choose CC2650F128 and XDS1100 on the first screen
+ * Do a full erase the first time to reset CCFG, etc
+ * Load image (select the `.bin` file produced above)
+
+For debugging:
+
+* Build OpenOCD from git to get support for the chip and debugger (I used the
+ existing [AUR package][openocd-git])
+* Run OpenOCD: `openocd -f jtag/openocd.cfg`
+* Use GDB to debug: `arm-none-eabi-gdb -x jtag/gdbinit -q target/thumbv7m-none-eabi/debug/sensortag`
+* The usual `mon reset halt` in GDB upsets the debugger connection. I found
+ that `soft_reset_halt` was able to reset the target (although it complains
+ about being deprecated).
+
+_**Note:** Files in the `jtag` path above are in my
+[sensortag repo](https://git.sr.ht/~wezm/sensortag/tree/master/jtag).
+Trying to program through `openocd` failed with an error that the `vEraseFlash`
+command failed. I'd be curious to know if anyone has got this working as I'd
+very much like to ditch the huge 526.5 MiB UniFlash desktop-web-app dependency
+in my workflow._
+
+Now that I could get code to run on the SensorTag I set about trying to use the
+generated chip support crate to flash one of the on board LEDs. I didn't
+succeed in getting this working by the time the retreat came to an end, but
+after I arrived home I was able to find the source of the hard faults I was
+encountering and get the LED blinking! The key was that I needed to power up
+the peripheral power domain and enable the GPIO clocks to be able to enable an
+output GPIO.
+
+
+
+Below is the code that flashes the LED. It should be noted this code is
+operating with very little abstraction and is using register and field names
+that match the data sheet. Future work to implement the [embedded-hal] traits
+for this controller would make it less verbose and less cryptic.
+
+```language-rust
+#![deny(unsafe_code)]
+#![no_main]
+#![no_std]
+
+#[allow(unused_extern_crates)] // NOTE(allow) bug rust-lang/rust#53964
+extern crate panic_halt; // panic handler
+
+// SensorTag is using RGZ package. VQFN (RGZ) | 48 pins, 7×7 QFN
+
+use cc2650_hal as hal;
+use cc2650f128;
+use cortex_m_rt::entry;
+
+use hal::{ddi, delay::Delay, prelude::*};
+
+pub fn init() -> (Delay, cc2650f128::Peripherals) {
+ let core_peripherals = cortex_m::Peripherals::take().unwrap();
+ let device_peripherals = cc2650f128::Peripherals::take().unwrap();
+
+ let clocks = ddi::CFGR {
+ sysclk: Some(24_000_000),
+ }
+ .freeze();
+
+ let delay = Delay::new(core_peripherals.SYST, clocks);
+
+ // LEDs are connected to DIO10 and DIO15
+ // Configure GPIO pins for output, maximum strength
+ device_peripherals.IOC
+ .iocfg10
+ .modify(|_r, w| w.port_id().gpio().ie().clear_bit().iostr().max());
+ device_peripherals.IOC
+ .iocfg15
+ .modify(|_r, w| w.port_id().gpio().ie().clear_bit().iostr().max());
+
+ // Enable the PERIPH power domain and wait for it to be powered up
+ device_peripherals.PRCM.pdctl0.modify(|_r, w| w.periph_on().set_bit());
+ loop {
+ if device_peripherals.PRCM.pdstat0.read().periph_on().bit_is_set() {
+ break;
+ }
+ }
+
+ // Enable the GPIO clock
+ device_peripherals.PRCM.gpioclkgr.write(|w| w.clk_en().set_bit());
+
+ // Load settings into CLKCTRL and wait for LOAD_DONE
+ device_peripherals.PRCM.clkloadctl.modify(|_r, w| w.load().set_bit());
+ loop {
+ if device_peripherals.PRCM.clkloadctl.read().load_done().bit_is_set() {
+ break;
+ }
+ }
+
+ // Enable outputs
+ device_peripherals.GPIO
+ .doe31_0
+ .modify(|_r, w| w.dio10().set_bit().dio15().set_bit());
+
+ (delay, device_peripherals)
+}
+
+#[entry]
+fn entry() -> ! {
+ let (mut delay, periphs) = init();
+ let half_period = 500_u16;
+
+ loop {
+ // Turn LED on and wait half a second
+ periphs.GPIO.dout11_8.modify(|_r, w| w.dio10().set_bit());
+ delay.delay_ms(half_period);
+
+ // Turn LED off and wait half a second
+ periphs.GPIO.dout11_8.modify(|_r, w| w.dio10().clear_bit());
+ delay.delay_ms(half_period);
+ }
+}
+```
+
+The rest of the code is up on [Sourcehut]. It's all in a pretty rough state at
+the moment. I plan to tidy it up over the coming weeks and eventually publish
+the crates. If you're curious to see it now though, the repos are:
+
+* [cc2650f128](https://git.sr.ht/~wezm/cc2650f128) -- chip support crate
+ generated by `dslite2svd` and `svd2rust`.
+* [cc26x0-hal](https://git.sr.ht/~wezm/cc26x0-hal) (see `wip` branch, currently
+ very rough).
+* [sensortag](https://git.sr.ht/~wezm/sensortag) -- LED flashing code. I hope
+ to turn this into a board support crate eventually.
+
+Overall the coding retreat was a great success and we hope to do another one
+next year.
+
+[cargo-binutils]: https://crates.io/crates/cargo-binutils
+[carmack]: https://www.facebook.com/permalink.php?story_fbid=2110408722526967&id=100006735798590
+[CC2650]: http://www.ti.com/product/CC2650
+[discovery]: https://rust-embedded.github.io/discovery/
+[dslite2svd]: https://github.com/m-labs/dslite2svd
+[embedded-hal]: https://crates.io/crates/embedded-hal
+[linux.conf.au]: /technical/2019/01/linux-conf-au-rust-epaper-badge/
+[M-Labs]: https://github.com/m-labs
+[OpenBSD]: https://www.openbsd.org/
+[openocd-git]: https://aur.archlinux.org/packages/openocd-git/
+[Rust]: https://www.rust-lang.org/
+[SensorTag]: http://www.ti.com/tool/cc2650stk
+[Sourcehut]: https://sourcehut.org/
+[svd2rust]: https://github.com/rust-embedded/svd2rust
+[UniFlash]: http://www.ti.com/tool/uniflash
diff --git a/content/technical/2019/03/sensortag-embedded-rust-coding-retreat.yaml b/content/technical/2019/03/sensortag-embedded-rust-coding-retreat.yaml
new file mode 100644
index 0000000..177fe61
--- /dev/null
+++ b/content/technical/2019/03/sensortag-embedded-rust-coding-retreat.yaml
@@ -0,0 +1,14 @@
+---
+title: A Coding Retreat and Getting Embedded Rust Running on a SensorTag
+extra: I attended a small coding retreat with some friends and worked on running Rust code on a CC2650 based TI SensorTag.
+kind: article
+section: technical
+created_at: 2019-03-12 19:45:00.000000000 +11:00
+#updated_at: 2019-03-02T14:09:11+11:00
+keywords:
+ - rust
+ - embedded
+ - sensortag
+ - arm
+ - microcontroller
+short_url:
diff --git a/output/images/2019/coding-retreat-sunrise.jpg b/output/images/2019/coding-retreat-sunrise.jpg
new file mode 100644
index 0000000..c009392
Binary files /dev/null and b/output/images/2019/coding-retreat-sunrise.jpg differ
diff --git a/output/images/2019/sensortag-flashing-led.m4v b/output/images/2019/sensortag-flashing-led.m4v
new file mode 100644
index 0000000..291f533
Binary files /dev/null and b/output/images/2019/sensortag-flashing-led.m4v differ
diff --git a/output/images/2019/sensortag.jpg b/output/images/2019/sensortag.jpg
new file mode 100644
index 0000000..6c0f90a
Binary files /dev/null and b/output/images/2019/sensortag.jpg differ