Sunday, September 2, 2018

SPIdriver

I recently backed an interesting SPIdriver project on Crowd Supply. For as little as $27 you can have your very own SPI debugging tool!


First, it should be noted what this device is, and what it is not. As clearly stated by the name - it is a driver and not a monitor. There's an open issue on GitHub regarding monitoring, I'm interested in seeing what happens with that. But really, for monitoring, that would be the job of an oscilloscope - ideally a DSO, or even better: a logic analyzer.

There was a (slightly misleading) but otherwise interesting review by the folks over at linuxgizmos that mentions the word "monitor" several times when describing the SPIdriver.

Still, I had hoped to see how complex of an undertaking it might be to add the monitoring feature.  When I looked at the source for the firmware, I kinda just stared in bewilderment for a few moments: "What is this strange language?"- but then back in the README, I noticed in the first line: "It uses the MyForth compiler written by Charley Shattuck and Bob Nash". wow. Forth! And not just any Forth:
This version is intended for embedding in small 8051 based projects. They currently feel the product is not commercial worthy as it has too many personal enhancements, and is more an exploration of concepts than a real product.
Really - I'm impressed that not only someone could code something in this language, but as noted on the documentation page:
This version is intended for embedding in small 8051 based projects. 
So even more impressive is that this code is compiled and loaded into... (?) what specific chip: "Silicon Labs automotive-grade microcontroller"? I'm not really sure, but have requested the schematic be made available. The article mentioned above claims the controller is an EFM8 8051-based 8-bit MCU. The text on chip includes 8810 and 1743; not much luck when googling this. So I have not confirmed the exact processor being used. I've not coded for the 8051 in quite some time, and certainly never in Forth. It is good to know this chip is still around if that's what's here.

Not only do I have pretty much no Forth-programming skills; further, I have no idea how the binary, once compiled, would even get on the chip itself. Perhaps something like avrdude is used? I wonder if the code comes in via the serial port, or perhaps the bi-directional SPI port? (Hopefully not another vendor specific, proprietary IDE)

In any case, the code seems to work well for the intended purpose: The FTDI chip acts like a serial port talking the to SPIdriver controller. The device works some magic converting serial port text commands into SPI control signals - and displays them!

The initial out-of-box experience was quite good; I had the device working almost immediately thanks to the great documentation page. It would have been sooner, had my Ubuntu VM not been in the middle of an update. (thus preventing me from installing anything new). The Windows command-line does not work quite as documented, since the ports are not named /dev/ttyUSB[n]. Fortunately the parameters accept Windows-style port names:


>>> from spidriver import SPIDriver
>>> s = SPIDriver("com16")
>>> s.sel()
>>> s.write([0x9f])
>>> list(s.read(3))
[127, 255, 255]
>>> s.unsel()
>>> quit()

Very cool. Moving on from the initial test, I played a bit with the pre-compiled Windows executable. Minor stumble here, as my 64-bit Windows 10 installed the app into the x86 directory, thus the sample command-line was slightly different than the docs:


C:\workspace>"c:\Program Files\Excamera Labs\SPIDriver\spicl.exe" COM16 i
The system cannot find the path specified.

C:\workspace>"c:\Program Files (x86)\Excamera Labs\SPIDriver\spicl.exe" COM16 i
uptime 61  5.029 V  0 mA  29.0 C


The Windows GUI makes it ridiculously easy to send SPI commands. Up to two hex digits can be entered and sent with each "Transfer" button press:

SPIdriver Windows GUI

Resulting in the display on the SPIdriver to look like this:


SPIdriver sample SPI signal
Note that if you exit the SPIdriver Windows app, you may need to wait a few moments for the process to be completely killed; Otherwise when starting a new instance, I found that the data entry box would sometimes not accept any characters.

On to a more impressive and complex, sending an entire picture to another SPI display! Here too, I had a minor stumble, as the docs claim that  the command looks like this:


python -h /dev/ttyUSB0 st7735s.py grace.png


This brought up the python help for me, and ignored the rest of the parameters. On Windows the command was this one (also note different picture):


python st7735s.py -h COM16 spidriver.png


Resulting in this:

SPIdriver talking to an SPI display
Sadly, I could not find a convenient SPI memory device laying around (at least not one I was willing to possibly fry), so I could not continue with the sample SPI flash. But while digging through my parts, I found an ENC28J60 SPI Ethernet board like this one that I've been meaning to play with. Coming soon...

Other notes:





Sunday, July 15, 2018

Pushing a button. From afar. With LoRa.

This blog entry is about pushing a button. Seems simple enough, eh? Except when the button you want to press is very far from where you are physically located... say, when there's a remote gate control well out of sight and out of range for the remote. Oh, and it is also too far to have any network connectivity. What to do?

My plan is to use LoRa to communicate from an M5Stack console to a distant LoRa32u4, each equipped with a LoRa module; essentially push the button of the remote from afar! The actual pysical button push on the M5Stack will essentially be "sent" (via LoRa message) to the remote 32u4 which will then trigger the actual remote control transmitter. The working prototype is shown here:



How to get there: The first thing needed is to disassemble the remote and determine how it normally works. The remote I am using is a Somfy TR2 similar to this one that can control two different devices. Upon disassembly, the first thing we see is those two buttons each with 4 pins. The buttons appear to be very similar to this Grayhill Gull Wing 95C06C3RAT at Mouser as documented here. Note that although there are 4 pins, it is simply a SPST switch:

Photo credit: Grayhill spec sheet

I confirmed both visually and with an ohmmeter that indeed I have a similar switch and proceeded to connect some external wires to it:

Somfy remote switch wiring

If you look closely, I took the time to wrap the wire around the pin of the switch to make a good mechanical connections, while being careful not to touch any other circuit. It would probably be a good idea to use some hot melt glue and affix the wires to the pc board.

Here, Green is a ground (all 4 pins, 2 from each switch); Orange is BP1 and Yellow is BP2. The top of the battery is labeled as being the positive side. The entire metal surface here is at 3.3V:



This turned out to be an extremely handy arrangement for me: the entire device could essentially be the "load" for an NPN transistor circuit!

Putting an ammeter between either the orange or yellow pins to ground, I found about 0.3mA that would otherwise flow though the button (or a transistor).

Looking at the specs for the 2N3904, the max collector current is a whopping 200mA  max, well over a couple orders of magnitude for what we'll need:


And for a collector current of (we'll round up) to 0.5 mA, we'll have a minimum gain of around 60 to 80 (let's pick a gain of 70 for discussion-sake):




We'll need a base current of around  (0.005A / 70) =  0.0714 mA;  For the current-limiting base resistor, we'll thus need: 3.3v / (0.0000714) ~= 40K ohms. I didn't have a 40K handy, but I did have a bunch of 20K ohm resistors laying around, so I'll use that. It is still well within spec, and will certainly account for any gain drift or degradation.

Our button-pressing supplement thus looks like this (shown for BP1, but the same for BP2):
Note that this circuit will allow our 32u4 to control the remote via a GPIO pin. Fortunately the remote is also smart enough to turn itself off - if for some reason the button remains pressed so that the battery does not drain (such as being poked by your keys in your pocket). In our case: regardless of the state of the pin during power up (or application crash) the battery will be preserved.
The manual prototype looks like this:



Note the red wire to drive the base of the transistor is stuffed into the battery holder for the picture. Once in operation this red wire will instead be the GPIO output from the 32u4.

Next, we need to make sure the remote is actually working! As mentioned in my previous blogs on M5Stack LoRa Range Issues as well as this fun project using OpenWRT on EA3500 with RTL-SDR Stream, I have an inexpensive NooElec SDR, that is simply amazing - particularly given the price! With this hardware, and the some software, we'll be able to "see" the remote signal.

The last time I used Cubic SDR, it was working fine. Today? Nothing. Erg. Gotta love Windows. App starts, no complaints, but no signal. A little bit of googling, and there's the Quick Start Guide. First thing I noticed was mention of my old friend, zadig. Sure enough: during one of the the Windows updates, the default driver was changed for some bizarre reason. Here's the screen just before correcting it:



And tada! Exit Cubic SDR (no need, at least for me, to reboot computer)... relaunch Cubic SDR app... then pressing Start for my RTL2832U device:


The waterfall immediately starts! Press the button on the remote a few times, and we can see the pulse at about 433.5 MHz. Notice the messy side-band noise, as well as someone else continuously transmitting at about 432 MHz:



I have the source code for all this on GitHub here: https://github.com/gojimmypi/LoRa-GPIO (note there are also Development and M5-RadioHead branches, but after a bunch of GitHub fussing, I think the master branch is now up to date). The projects are VisualMicro extensions to Visual Studio, but I suspect the Arduino code would work just fine in the Arduino IDE.

More to come...

Saturday, June 30, 2018

AD9280 AD9708 AD / DA Module for AX series FPGA Development Board


I keep seeing these AD/DA modules on ebay, (such as this one) but I've not been able to find much  documentation. There's of course the Analog Devices AD9708 and AD9280 spec sheets, but not much else for the board itself.

"The AD9280 is a monolithic, single supply, 8-bit, 32 MSPS analog-to-digital converter with an on-chip sample-and-hold amplifier and voltage reference" ... "The AD9708 (digital-to-analog converter) can support update rates up to 125 MSPS"

When considering a board, the AD9764  14-bit also looks interesting, but it appears to be obsolete. There's a newer AD9246, but I could not find a site that listed the eval board for sale: (e.g. mouser, digikey, etc). In fact, there are a LOT of options: Here's a list of Analog Devices Eval Boards at Mouser. There's also this Precision ADC selector Guide. I'm pretty sure I'm just interested in the ones on page 5: Analog Devices’ single channel successive approximation register. There's kinda no limit to the options, such as this impressive AD9172 Dual, 16-Bit, 12.6 GSPS RF DAC with Channelizers  (spec sheet); yes that's over TWELVE BILLION, 16-bit samples per second. ZOOM!

So many choices... I ended up exhausted trying to find something with a high sampling rate, and a large bit width, and a low cost for simply experimenting. So in the end the 8 bit dual AD and DA on one board for about $20 bucks was hard to beat.

For this board, I've found two different pin numbering schemes: one that uses the traditional left-right, 1-2 number used in most ribbon cables, (so that the ribbon cable wires are sequentially numbered)... and I would think that this is the correct pin numbering:



However I also found this somewhat "DIP-style" numbering used on integrated circuits, running sequentially down one side, then the other (although the numbering is reversed on the second column). I'm hoping this is not the correct wiring, but I will not know for sure until my board arrives.:


See video clip here.

They seem to be in agreement with pin number (e.g. Pin 5 is DA CLK)... but the point is: where exactly is that pin on the header?

I did eventually find this interesting article from Hackaday regarding using this board to build a software defined radio for the Raspberry Pi using the Icoboard plug-in with a Lattice iCE FPGA  (this may tie in well with my recent iCE40UP5K-B-EVN purchase!) The the icoboard is for sale here, for about 80 euro. Note for that price you also get 8 mbit of RAM on the back of the board!

Info starting here in the video.



Sunday, May 6, 2018

Programming the Lattice Semiconductor FPGA iCE40 Ultra Plus Breakout Board iCE40UP5K-B-EVN

FPGA programming the Lattice Semiconductor iCE40 Ultra Plus Breakout Board.

(work in progress, come back soon)

TL;DR
Lattice Semiconductor tweeted a "new low price" for their iCE40UP5k-SG48 breakout that I simply could not resist. I've been wanting to learn FPGA programming for some time, and had recently taken the Altera Cyclone IV for a test drive. I was not super impressed with the Quartus software, so I was interested in seeing how well the Lattice Diamond software worked in comparison.

Lattice iCE40UP board diagram from the User Guide


I initially tried to order the board from DigiKey. I gave up fussing with their dreadful ordering UI/UX and instead I ordered it from Mouser. (specifically this iCE40UP5K-B-EVN item on the Mouser web site). The device arrived about a week later.

There was a (clearly hand-cut) quarter sheet of paper with instructions included with the board:


Mainly of interest are the links:

  http://www.latticesemi.com/ice40ultraplusbreakout

      and

  http://www.latticesemi.com/software

.. and the reminder to put the jumpers on J6 in the "vertical position" (perpendicular to the jumper at J7)

Despite the seemingly simply instructions, my initial out of the box experience was dreadful. Not only was the computer completely unable to connect to the board for the demo, but later once I was able to connect without the error, the demo didn't even work. I don't think my board shipped with the demo program installed, nor was I able to find the source code anywhere to try it.

The first problem seems to have been the fact that I already had installed FTDI drivers for my ESP32 development some time ago (specifically the rather rare JESP32). This was apparent when *both* FTDI devices were listed at the bottom of device manager, and when looking at properties - both were configured as JTAG devices:


Looking back, I suppose this makes sense, as the JESP32 that was previously installed has the normal order of the devices reversed:
"Yeah. I used FT2232H interface 0 for UART and interface 1 for JTAG. This is different from many other debuggers. Advantages being you get same /dev/ttyUSB0 UART like many other dev boards. Also (which I heard) you don’t need to modify kext under OSX" - @ba0sh1
Sadly when the Lattice iCEcube2 software installs, it does not configure the ports properly. I ended up manually removing the drivers, then manually installing them. I'm pretty sure when I revisit my JESP32, it will not work.

I was unable to find any useful sample code for the iCE40UP5K. I eventually found this:

https://github.com/cliffordwolf/icestorm/tree/master/examples/up5k_rgb

I was unable to program from the Lattice iCEcube2 software, as there was no "Tool - Program" on my menu!


I needed to download the "Standalone Diamond Programmer" from here:

http://www.latticesemi.com/Products/DesignSoftwareAndIP/ProgrammingAndConfigurationSw/Programmer

Don't bother using the site search to find this! Seemingly every software item *except* the one you want will be listed in the hundreds of results. (yes, I mistakenly tried installing an older version, and the iCE40UP is not listed as a device). The version that worked for me was 3.10.0.111.2 (I manually installed this one, different than the one that came with Lattice Diamond install) Specifically this link:

Programmer Standalone 3.10 64-bit for Windows

From the iCECube2 output, once a project is successfully compiled, the resulting file can be found in the log output near the end (see above). In my case, the bin file was found here:

C:/lscc/iCEcube2.2017.08/sbt_backend/Projects/blink/blink_Implmnt\sbt\outputs\bitmap

Note the annoying, sloppy use of forward and back slashes. They will need to be edited in Windows, otherwise an error occurs when pasting in the path.


Windows only likes back-slashes, so each will need to be individually changed. In my case, the default project ended up in:

C:\lscc\iCEcube2.2017.08\sbt_backend\Projects\blink\blink_Implmnt\sbt\outputs\bitmap

And the file needed (mysteriously) is prefixed with "top_". Select that bin file in the Diamond Programmer by clicking on the little 3 dot ellipsis button:


It should pop up a dialog box like this:


Note the device family is set to iCE40 Ultra Plus and the Device is iCE40UP5K.

Double-click on the "Operation" column (or click the "Device Properties" button) and ensure these settings are in place:


I saved my working project to GitHub here: https://github.com/gojimmypi/iCE40UP5k-blink

Once working, when viewing with Zadig, this is what I see (note Interface 0 and Interface 1):



However programming is not always successful, even if the software finds the device:

INFO - Check XCF Project: The current XCF Project is valid.
INFO - Check XCF Project: The current XCF Project is valid.
INFO - Check configuration setup: Start.

INFO - Check configuration setup: Successful (Ignored JTAG Connection Checking).

INFO - Device1 iCE40UP5K: Fast Program


 "Device detection failed. Cannot continue."

ERROR - Process Operation Failed.

INFO - Elapsed time: 00 min : 00 sec

ERROR - Operation: unsuccessful.

ERROR - Programming failed.

If the programming fails like this, try switching ports. One one computer (one that I had not installed JESP32 FTDI drivers)... I was able to program on the default "Port 0" (FTUSB-0) - on another computer (the one I previously had configured FTDI drivers, I had to change to "Port 1" (FTUSB-1) in order to program.


In the end I was eventually successful, but I don't think the iCE40UP5K is for everyone.






Sunday, April 29, 2018

NXP freescale FRDM-KL25Z first impressions

I found an inexpensive C/TCP-IP, the Embedded Protocol Stack for the Kinetis Arm Cortex-M4 book on amazon, somehow listed for sale at 90% off! ... along with a used used NXP freescale FRDM-KL25Z on ebay similar to this one. The initial Getting Started at freescale.com/FRDM-KL25Z was initially pretty impressive. But then I encountered the hassle of "you need to register and give up a bunch of PII just so you can download our software to see if you even want to use our product".

So ok, after a bit of anti-climactic download adventures, the download completed. Apparently the software have not been updated in the last couple of years. Either it is really good and stable, but free with no security issues... or is is not a high priority.


So another underwhelming "feature" of the software... once install is complete, there's a disappointment when there's no "new items" in Windows 10, nor under "F" for freescale, nor "K" for Kinetis, nor "N" for NXP. You'll need to remember that it was installed in C:\Freescale. Nothing obvious to get going on your own. No executable, no README. Well, that's apparently because there's yet ANOTHER download for the development environment. Why don't they just bundle all this into a single download?


So I next installed the "Kinetis SDK 1.3.0 Mainline - Windows.exe" - another 300MB compressed file that went... I don't know where. But no IDE icon, and no new apps immediately visible. The real install is kinetis-design-studio_3.2.0.exe - it really should simply have check boxes to install the other options, and the executable should be simply called something like kinetis-setup.exe There are install options for other things, why not for the SDK and "mainline" things?


This initial user experience makes me wonder if their software is also similarly, needlessly arduous.

Even after install of the new software is complete, the walk-through instructions note that "Help - Check for Updates" is needed. Sure enough, even more downloads an more manual steps. In fact, it is even several steps needed to actually accept the (new?) terms and conditions, next, next, next to install.

Go away and come back after install is complete? No, of course not:


There's a warning about "unsigned content". Super. The funny thing is that in the online video, no sooner did my updates complete, but the video instructs to ONLY select the processor updates. Oops. too late.


OMG - but we're not done! Seriously? There's Help - Install New Software


The "Update" for me is from 2015.



The for importing a new project, you just need to know project import:

C:\Freescale\KSDK_1.3.0\lib\ksdk_platform_lib\kds\KL25Z4

and

C:\Freescale\KSDK_1.3.0\examples\frdmkl25z\demo_apps\hello_world

I gave up at this point..






Sunday, April 15, 2018

Single Step JTAG debugging an ESP32 Arduino Sketch with VisualGDB

In my last post, I took the latest Preview 1 version of VisualGDB for a test drive. This time around, I am looking at the next increment: Preview 2. Spoiler from the the blog title: it is pretty cool.

TLDR; This is for JTAG debug ESP32 VisualGDB 5.4 Preview 2. This will not work with Preview 1. Preview 3 is now available.

Key is to BOTH: (1) add directories as "Additional Include Directories" and (2) right-click on solution "Add existing files" for these directories:

C:\Users\gojimmypi\Documents\Arduino\libraries\RadioHead
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\cores\esp32
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\libraries\SPI
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\variants\esp32

This Visual Studio / VisualGDB Arduino project can be downloaded here:

https://github.com/gojimmypi/MyArduinoConversion

(Update 4/28: some final editing still in progress)

First, the Arduino "sketch" is an odd critter, so close to being C/C++ but just enough different that some people have even called Arduino a language of its own. In the Ardunio IDE, File-New creates something like this (note no "main"):

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

The big drawback in the Arduino IDE is there's no debug. (besides - it is really just a text editor, not really an Integrated Development Environment, in my opinion).

Debugging a sketch in Visual Studio takes a few steps. The first part here is based on the Switching Advanced ESP-IDF Projects Between Different IDF Versions and Creating Advanced ESP32 Projects with ESP-IDF tutorials. I should also add that Arduino debugging is not yet officially by VisualGDB.

Note that I am using the PREVIEW 2 version of VisualGDB 5.4 with Visual Studio 2017..

First, we'll need to create a project in Visual Studio with VisualGDB. This example is called myArduinoConversion:


Leave default at "Create a new project based on a sample project". (hopefully the sysprogs folks will fix the black-on-dark-gray color scheme for those of of that choose the dark theme in Visual Studio):


If you don't have the ESP-IDF installed, there will be a prompt:


In my case, there was a version error. (despite the version warning, my C:\SysGCC\esp32\esp-idf\master-VisualGDB didn't even exist!

Click Clone an ESP-IDF from GitHub link to download:


VisualGDB may give an error:


So I manually downloaded the toolchain. Unfortunately the error message does now show the actual command being attempted:



mkdir C:\SysGCC\esp32\esp-idf\master
cd C:\SysGCC\esp32\esp-idf\master
git clone --recursive https://github.com/espressif/esp-idf.git
If you had to download your own manually, VisualGDB will not find it, even if in the specified directory. Choose the option on the right "Locate and existing ESP-IDF checkout. I purposely keep the VisualGDB stuff in this directory, as I have another ESP-IDF in my:
Documents\Arduino\hardware\espressif\esp32
... that is used for other Arduino / VisualMicro projects. Visual GDB will me looking for the README.md file in the root of the clone project. with the above command, I would need to use the ESP-IDF checkout here:

C:\SysGCC\esp32\esp-idf\master\esp-idf


Next, ensure the proper ESP32 toolchain is selected:



Next, choose a sample project. Here we use the get-started / blink template:


Next is the JTAG driver. In my case, I am using the ESP32-WROVER-KIT V3, and I chose the interface/ftdi/esp32-devkitj_v1,cfg file:


Here we can optionally press the "test" button, for a result like this if everything is working properly:



Although there's a "next" button there, it does not do anything; click "finish".

WAIT. (yes, it takes a surprisingly long time) It appears nothing is happening. I think most of the time is spent setting up the project ESP-IDF container.  Eventually a new "blink.c" file shows up:



/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h&gt
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"

/* Can run 'make menuconfig' to choose the GPIO to blink,
   or you can edit the following line and set a number here.
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO

void blink_task(void *pvParameter)
{
    /* Configure the IOMUX register for pad BLINK_GPIO (some pads are
       muxed to GPIO on reset already, but some default to other
       functions and need to be switched to GPIO. Consult the
       Technical Reference for a list of pads and their default
       functions.)
    */
    gpio_pad_select_gpio(BLINK_GPIO);
    /* Set the GPIO as a push/pull output */
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
    while(1) {
        /* Blink off (output low) */
        gpio_set_level(BLINK_GPIO, 0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        /* Blink on (output high) */
        gpio_set_level(BLINK_GPIO, 1);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main()
{
    xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
}


The first thing we'll need to do is take that sketch_mmmdd.ino file and rename it to something like main.cpp and make a few other changes.  (hopefully in a future release, sysprogs will give the option of using C or C++ sample templates).

In the case of this blink app, BLINK_GPIO is simply defined as "2" with no type. The gpio_set_level expects a gpio_num_t like this:
  gpio_set_level(static_cast<gpio_num_t>(BLINK_GPIO), 0);

The blink.c will also need to be renamed blink.cpp (apparently to ensure the compiler knows we are doing C++ and not just C). Preview 2 does not support right-click to rename, but you can click on the file in Solution Explorer and press F2 to enable the rename.

Only other minor tweak is needed; add extern "C" before the void main() like this:
extern "C" void app_main()

The revised code now looks like this:

/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"

/* Can run 'make menuconfig' to choose the GPIO to blink,
   or you can edit the following line and set a number here.
*/
#define BLINK_GPIO 2

void blink_task(void *pvParameter)
{
    /* Configure the IOMUX register for pad BLINK_GPIO (some pads are
       muxed to GPIO on reset already, but some default to other
       functions and need to be switched to GPIO. Consult the
       Technical Reference for a list of pads and their default
       functions.)
    */
    gpio_pad_select_gpio(BLINK_GPIO);
    /* Set the GPIO as a push/pull output */
 gpio_set_direction(static_cast<gpio_num_t>(BLINK_GPIO), GPIO_MODE_OUTPUT);
    while(1) {
        /* Blink off (output low) */
     gpio_set_level(static_cast<gpio_num_t>(BLINK_GPIO), 0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        /* Blink on (output high) */
     gpio_set_level(static_cast<gpio_num_t>(BLINK_GPIO), 1);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

extern "C" void app_main()
{
    xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
}


So that all is your basic VisualGDB project. Not a whole lot new. Yet.

I've been tinkering with LoRa stuff, and being able to single-step debug the code will be helpful. I'm using the RadioHead library and my local copy is git-cloned into \Documents\libraries\RadioHead. The interesting thing here is that the library is what I call "Arduino-style". I've never been able to get VisualGDB to play well with them, so I do a lot of development with VisualMicro instead. It is less expensive and fully supports the Arduino libraries. Alas I have a tons of "if debugging serial print" statements, as the JTAGsupport is weak. (there is however a VisualMicro GDB tutorial I've been meaning to check out). The reality is the sysprogs VisualGDB is simply a more extensive and robust implementation with JTAG support (with a price to show for it). The problem with the sysprogs folks however, is they never had much of an interest in Arduino.  (Yes, I want my cake and JTAG it too!)

So a single include statement turns out project into something considerably more interesting.

#include "RH_RF95.h"

Actually we'll do a few more things to instantiate the RadioHead drivers:


#include "RH_RF95.h"

#define RFM95_CS 5   // LORA_CS_PIN
#define RFM95_RST 36 // LORA_RST_PIN is 36, TODO but it is read-only! so we'll need to short to another pin
#define RFM95_INT 26 // M5 LORA_IRQ_PIN 36 (jumper to 16)
RH_RF95 rf95(RFM95_CS, RFM95_INT);

Ok, so the code is actually from my M5Stack project, and I don't yet have LoRa hooked up to my lastest ESP32-WROVER, but that's beside the point...

After adding the code, the IDE will complain:


So simply go into Project-Properties and add the path the the "Additional Include Directories". In my case that's:

C:\Users\gojimmypi\Documents\Arduino\libraries\RadioHead

NOTE: If your cursor is in the source code panel when you click Project-Properties, you'll get this modal dialog box. It is NOT the one to use to enter paths for include files (it didn't work for me):


Be sure to click on the project name in the solution explorer, and THEN click Project - Properties:


...for this dialog box to enter the Additional Include File Directory paths:


(note I like to make a habit of always pressing "Apply" before pressing ok, anytime that option is available)

That will take care of finding the code, but trying to compile will give an error about platform not defined:


The first compile will take some time. There's a shockingly large amount of code that gets compiled for such a tiny target. If when building/cleaning/rebuilding, nothing happens, simply exit Visual Studio and relaunch (see below).

This is another one of those Arduino-style nuances. You'll notice this code in RadioHead.h header and shown here:

#ifndef RH_PLATFORM
 #if (MPIDE>=150 && defined(ARDUINO))
  // Using ChipKIT Core on Arduino IDE
  #define RH_PLATFORM RH_PLATFORM_CHIPKIT_CORE
 #elif defined(MPIDE)
  // Uno32 under old MPIDE, which has been discontinued:
  #define RH_PLATFORM RH_PLATFORM_UNO32
#elif defined(NRF51)
  #define RH_PLATFORM RH_PLATFORM_NRF51
#elif defined(NRF52)
  #define RH_PLATFORM RH_PLATFORM_NRF52
 #elif defined(ESP8266)
  #define RH_PLATFORM RH_PLATFORM_ESP8266
 #elif defined(ESP32)
  #define RH_PLATFORM RH_PLATFORM_ESP32
 #elif defined(ARDUINO)
  #define RH_PLATFORM RH_PLATFORM_ARDUINO
 #elif defined(__MSP430G2452__) || defined(__MSP430G2553__)
  #define RH_PLATFORM RH_PLATFORM_MSP430
 #elif defined(MCU_STM32F103RE)
  #define RH_PLATFORM RH_PLATFORM_STM32
 #elif defined(STM32F2XX)
  #define RH_PLATFORM RH_PLATFORM_STM32F2
 #elif defined(USE_STDPERIPH_DRIVER)
  #define RH_PLATFORM RH_PLATFORM_STM32STD
 #elif defined(RASPBERRY_PI)
  #define RH_PLATFORM RH_PLATFORM_RASPI
#elif defined(__unix__) // Linux
  #define RH_PLATFORM RH_PLATFORM_UNIX
#elif defined(__APPLE__) // OSX
  #define RH_PLATFORM RH_PLATFORM_UNIX
 #else
  #error Platform not defined!  
 #endif
#endif

#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtinyX313__)
 #define RH_PLATFORM_ATTINY
#endif

To fix, simply add "ESP32" as a Preprocessor definition:


Rebuild again. There's a subtle change in the error message:


So this starts looking a bit more intimidating: Arduino.h missing for our ESP32 project. I took the brute-force approach and searched from the root of my C:\ drive:



C:
cd\
dir Arduino.h /s

I had a 32 matches in various locations. Some are obviously not of interest if found in an .\Arduino\ directory. In my case, I have the Espressif Arduino Core git-cloned in my .\Documents\Hardware\Espressif directory. It can be installed like this:


cd %USERPROFILE%\documents
mkdir hardware
git clone --recursive https://github.com/espressif/arduino-esp32.git
cd arduino-esp32
dir Arduino.h /s
dir SPI.h /s
dir pins_arduino.h /s




Put that directory in the include file list. Compile again and find another missing header file. Repeat. Note the pins_arduino.h is found in multiple directories. I chose the generic ESP32 one. After doing this a few times, VisualGDB often will complain the the settings are corrupt:


I simply exited Visual Studio and restarted. Upon restart, it complained out "line endings not being consistent". VisualGDB probably did this to itself; simple answer yes to fix:


Upon doing a rebuild, I found more files missing. Repeat the procedure for finding files.

Mine were found in:

C:\Users\gojimmypi\Documents\Arduino\libraries\RadioHead
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\cores\esp32
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\libraries\SPI\src
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\variants\esp32


May also need:
C:\Users\gojimmypi\Documents\Arduino\hardware\espressif\esp32\variants\doitESP32devkitV1

Note that the include file locations is not the only place for this fix; The intellisense will be happy, however the compiler does not seem to "find" there files. There is where things get a little wonky. Those same include files paths need to be added to the project. Right-click on the project, add, existing item (for each of the directories listed above).


Paste one of those include file paths into the File Name box. I choose to select header files (some directories have only headers!). Pick one of them. VisualGDB will recognize that there are others and prompt you to add them all. Click ok.

If multiple files are found, there will be a prompt asking if they all should be added (yes, they should):



Rebuild the project. (sometimes it can help to clean, and then do a full rebuild).

Tada! A fully compiled Arduino-style library with VisualGDB. For me - this was really quite cool: something I've been wanting to do for a long time.



There are still a few weird things. The include files are presented in the Solution Explorer in a pretty bizarre fashion. As these same include directories are found in the Project Properties, I really think it would be best of the directory scanning and file additions happened transparently to the developer.



Also, It seems that breakpoint cannot be placed directly on those included files. However you can step-into them. Unfortunately the only option is step into. Step-over does not seem to work. Nor does step out. Alas this is only Preview 2, and still in development.

The Solution Explorer also looks a bit odd:



There's also some wonkiness with OpenOCD when code is paused too long. I think there's some sort of panic watchdog that is not fed while single-step debug is paused:



And no sooner do I polish this Preview 2 blog... the sysprogs folks have already released Preview 3! (And yes, it DOES appear to work in Preview 3 as well!)

* July 2018 edit:

Over the course of time, my Windows 10 drivers were changed, resulting in the dreaded message:

Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
Error: no device found
Error: unable to open ftdi device with vid 0403, pid 6010, description '*', serial '*' at bus location '*'


Zadig to the rescue once again! Change both drivers on Interface 0 and Interface 1 to libusbk.


I am using the config file found in:

C:\sysgcc\esp32\esp32-bsp\OpenOCD\share\openocd\scripts\interface\ftdi\esp32_devkitj_v1.cfg

That specifically looks like this:


#
# Driver for the FT2232H JTAG chip on the Espressif DevkitJ board
#
 

interface ftdi
ftdi_vid_pid 0x0403 0x6010

# interface 1 is the uart
ftdi_channel 0
# just TCK TDI TDO TMS, no reset
ftdi_layout_init 0x0008 0x000b
reset_config none



SPIdriver

I recently backed an interesting SPIdriver project on Crowd Supply . For as little as $27 you can have your very own SPI debugging tool! ...