Simblee Watchdog Timer & OTA Updates

We fell in love with RF Digital's RFDuino product when it hit the market a few years back, and their newest module, Simblee, is an impressive improvement. 

During hardware beta testing the last thing that we ever want is a device that locks up due to a software bug and becomes unusable. Most micro controllers include functionality to protect against this, a watchdog timer. The watchdog is configured with a certain time interval, say 10 seconds. If the watchdog is not 'petted' within that 10 second window the device is reset. This way any infinite loops or unintended lock ups can be mitigated. 

Configuring the Simblee's watchdog is fairly straight forward : 

NRF_WDT->CRV = kWATCHDOG_INTERVAL_1S * 5;
NRF_WDT->TASKS_START = 1;

'Petting' the watchdog is done with:

NRF_WDT->RR[0] = WDT_RR_RR_Reload;

So far so good, but, we were very interested in Simblee's new over-the-air firmware update functionality (OTA). This allows the device to accept new code, without being physically connected to a programmer. Very convenient for patching bugs and introducing new functionality when users already have devices in hand. However! Upon implementing OTA functionality in our firmware it consistently failed! After a bit of investigation we noticed that it was failing after exactly the amount of time that our watchdog timer was set to. It turns out that once the watchdog timer has been enabled, it can not be disabled until either the device has been power cycled, or a watchdog reset has been performed.

If you're looking to get OTA updates working with a watchdog timer here are the steps that you'll need to take:

  1. Send a custom command to initiate your OTA update method.
  2. Write a flag to persistent storage as a way of signaling to your program that you'd like to not enable the watchdog on startup, and move directly to the built-in Simblee OTA update. 
  3. Enter an infinite loop, and do not pet the watchdog inside this loop
  4. The device will be reset by the watchdog timer
  5. Read the flag you previously wrote to persistent storage. If it exists, go ahead and clear it, then start the OTA update without enabling the watchdog. Otherwise, enable the watchdog and move forward!

Hope this helps others on the same path move forward. 

As an additional tidbit, if you're interested in knowing why your Simblee reset, here's a bit of code that the RF Digital team shared with us:

void resetReason(){
if (NRF_POWER->RESETREAS & 0x00000001)
log(F("Reset from pin"));
if (NRF_POWER->RESETREAS & 0x00000002)
log(F("Reset from WDT"));
if (NRF_POWER->RESETREAS & 0x00000004)
log(F("Reset from software"));
if (NRF_POWER->RESETREAS & 0x00000008)
log(F("Reset from lockup"));
if (NRF_POWER->RESETREAS & 0x00010000)
log(F("Reset from Powerup"));
//Serial.println(NRF_POWER->RESETREAS,BIN); //Print binary value of Reset Reason
NRF_POWER->RESETREAS = 0xFFFFFFFF;//Clear reset reason register
}

Raspberry Pi + Adafruit PiTFT Display

Recently we had the chance to work on an interesting standalone Raspberry Pi project for a client. For user interaction we decided on good ol' Lady Ada's 2.8" PiTFT display with capacitive touch. 

At first glance everything looked remarkably easy, as things often do. Adafruit's team was kind enough to offer an easy way to download a new kernel for the display, along with a few prebuilt Raspbian Jessie images for quickly testing out the product. We ordered a few up and quickly ran into an issue : the display worked great, but touch input was not working. If you're seeing something similar, you can verify that you're not going insane by checking the values using 'evtest' :

  1. sudo nano /etc/udev/rules.d/95-ft6206.rules
  2. sudo rmmod ft6x06_ts
  3. sudo modprobe ft6x06_ts
  4. ls -l /dev/input/touchscreen
  5. sudo evtest /dev/input/touchscreen

At the end, you should be able to move your fingers across the touch screen and watch the raw values on screen change. If not, you're in the same boat we were. Adafruit's support team mentioned that they were seeing similar issues with the touchscreen that were not being supplied enough voltage. Check your 3.3V and 5V rails and make sure that they're not dipping too low. If so, you more than likely need a beefier power supply. This fixed up our first round of issues.

While Adafruit's Jessie images are great for a general purpose Pi, our Pi would only be doing one thing : running a custom python app with Kivy. As usual the internet had beat us to this idea, and a prebuilt Kivy installation running on top of PipaOS had already been built out. Perfect! PipaOS is very lightweight, boots up in about 4 seconds, and has a power fault tolerant file system. Our customer would get a very fast device, that wouldn't mind having the power rug pulled out from underneath its feet. 

If you're looking to get the KivyPie image up and running with a PiTFT here's what we needed to do.

  1. Write the KivyPie Image to our Pi's SD card
  2. After booting up, run 'sudo pipaos-config' and go ahead and expand the file system.

  3. After rebooting, open up /usr/bin/raspi-config' in your favorite editor, and change out any references to 'pi' in the autologin section to 'sysop' (the default KivyPie username). 
  4. Rerun 'sudo pipaos-config' and tell the Pi to automatically login to the console, but don't start the GUI.
  5. Walk through Adafruit's helper installation (raspberrypi-bootloader, and adafruit-pitft-helper)
  6. Be sure to specify the home directory when running the PiTFT Helper, 'adafruit-pitft-helper -t 28c -u /home/sysop'
  7. Run 'sudo apt-get install xserver-xord-video-fbdev'
  8. Run 'export FRAMEBUFFER=/dev/fb1'
  9. Install rpi-fbcp : https://github.com/tasanakorn/rpi-fbcp
  10. Edit '/home/sysop/.kivy/config.ini' and change the resolution to 320 x 240, change the [input] section to match : 
    [input]
    
    mouse = mouse
    
    %(name)s = probesysfs,provider=hidinput
    
    pitft = mtdev,/dev/input/touchscreen,max_position_x=240,max_position_y=320,invert_y=0,invert_x=1,rotation=90
  11. Now open '/boot/config.txt' in your favorite editor and add : 

    hdmi_force_hotplug=1
    
    hdmi_group=2
    
    hdmi_mode=87
    
    hdmi_cvt=320 240 60 1 0 0 0
  12. Reboot!

  13. Run 'fbcp &'

  14. You should now see the console text on the Pi display, you can run your Kivy app now and it should show up beautifully!