As it is always the case, many products from Texas Instruments require a CC-Debugger to flash program memory. Bluegiga’s BLE112 module is not an exception. But when one compares BLE112 and CC-Debugger prices things don’t look bright anymore – there is a little sense (if any) to pay $50 US dollars for a CC-Debugger to program an $11 dollar module. Things become even more ridiculous when a hobbyst is simply willing to flash his/her module only once using the code that is already compiled and debugged by someone else. Would it be possible to find a replacement for a CC-Debugger? Yes, but as always, something is to be sacrificed.
There is a great project at Github called CCLib that uses an Arduino which acts almost like a CC-Debugger. Indeed, nowdays Arduinos are very popular piece of hardware and if you are that kind of person who needs to flash a BLE module, chances that you already have Arduino board in stock are pretty high. But even if it is not the case, buying a basic Arduino board still will be much cheaper than CC-Debugger, besides, immediately after flashing Arduino could be used for another project. The solution works just fine, the only downside of this is an enormously long flashing time, this is because Arduino script works literally as a proxy for business logic implemented in Python scripts on a PC side. The datapackets traveling between PC and Arduino are short resulting in tremendous round trips when it comes to uploading or downloading BLE112 memory snapshots. So, to flash 128Kb it takes 1.5 hours! For some people it could be acceptable but we decided to redesign the whole concept of CCLib focusing on highest possible performance.
First, the logic implemented in Python scripts has to be translated to C/C++ and relocated to Arduino side so the data packets would essentially contain packetised binary files including just a little bit of overhead – packet type, packet length, block number, checksum etc. Second, the size of a single packet would need to be as big as Arduino’s buffers are capable to accommodate, this would be achieved by making Arduino’s app to send the size of its RX buffer before actual data exchange takes place. So, the more advanced Arduino board is used, the bigger its RX buffer and the more effective data exchange would be. Third, standard Arduino’s library is extremely slow when it comes to digital in/out which is very critical for this particular application so faster equivalents of those functions would be used.
The PC application would need to have GUI interface, no nasty command lines with pathetic attempts to display a progress bar. CSharp is probably the most popular language now so the app would be designed for Visual Studio 2013 Community Edition which any hobbist can download for free and use without limitations. Of course, everything is going to be opensource, as usual.
The final result of development effort is given below. Additional total 2k lines of source code has been added to the CCLib project effectively replacing Python scripts. On a PC side an app called ‘Arduino CC-Debugger’ has three configuration parameters in CCLibFrontend.exe.config file which are SerialPort, Baudrate and LogPath. All of them must be set to appropriate values once as they pretty much remain unchanged on a given PC. SerialPort is set to a USB-to-Serial port name which appears in Device Manager list upone plugging in Arduino board to the PC. Baudrate is set to 115200 which matches the port speed on Arduino side. LogPath is set to a directory that would contain log file generated by the Arduino CC-Debugger.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="CCLibFrontend.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <userSettings> <CCLibFrontend.Properties.Settings> <setting name="SerialPort" serializeAs="String"> <value>COM3</value> </setting> <setting name="Baudrate" serializeAs="String"> <value>115200</value> </setting> <setting name="LogPath" serializeAs="String"> <value>C:\CCLib-Frontend\</value> </setting> </CCLibFrontend.Properties.Settings> </userSettings> </configuration>
GIU interface is intuitive and self-explanatory, there are only 3 buttons initiating either reading/writing or chip info retrieval sequence. There are fields for displaying the following information: chip ID, flash size, SRAM size, USB support flag, IEEE address, BT address, hardware version and license. Out of all these fields BT address, hardware version and license are kept at a special location in regular program memory so they could be wiped out or replaced, either accidentally or deliberately. That is why it is highly recommended to do a read operation on your module and keep the file as a backup before doing any writing. Also, for the sake of capturing screenshots and doing video presentations there is a ‘Hide values’ tick which, when enabled, shows only first two digits of your BT address and license preventing them from being stolen and at the same time allowing screenshot/video sharing. And finally, the screen form contains a progress bar which keeps an end user updated during lengthy operations. The total operation time is shown in seconds at the right bottom corner.
The Arduino CC-Debugger app accepts either binary (*.bin) or Intel HEX (*.hex) files. HEX files are parsed by another great third-party project, so-called LibGIS for .Net which is made part of the application. If a file is provided in HEX format, it will be converted to binary and written as image.bin. Then before flashing sequence BLE storage, BT address, hardware version and license will be read from the chip and merged with the content of ‘image.bin’ resulting in creation of ‘image_merged.bin’. Memory snapshots are generated by ‘Read’ command and written in binary format as ‘read.bin’. Each subsequent read operation overrides old file if it exists, same applies to ‘image.bin’ and ‘image_merge.bin’.
Physical connection between Arduino and BLE module comprises of three signal lines (DD, DC and RST) and in total requires 5 wires as Arduino uses two GPIOs for DD signal (one pin is configured as input for incoming data, one pin is configured as output for outgoing data ) plus one wire for ground. Mapping these four signals to Arduino’s GPIOs is done in ArduinoCCDebugger.ino in ‘Pinout configuration’ section and can be redefined to something else if needed. The BLE module’s inputs are not 5V tolerant so there must be resistor dividers as shown on the picture below.
Alternatively, a 3.3V Arduino could be used eliminating necessity of resistors. For example, Seeeduino V.3.0 board has 3.3V/5V selector and therefore it doesn’t require resistors when set to 3.3V mode. Another big plus of Seeeduino is two LEDs connected in parallel to RX/TX lines which conveniently provides with visual indication of data traffic over serial interface so no need in external LED which is used in CCLib project.
A BLE module is connected to Arduino via flat cable and 2.5mm-to-1.27mm adapter as shown on the picture below. The adapter could be the one which comes with CC-Debugger, it is also possible to buy it from ebay or simply build.
The full blown ‘ready-to-flash’ setup is provided on the picture below:
The comparison tables below highlight cost factors for all three solutions mentioned in this post:
Variant I – flashing with original CC-Debugger | ||
Item | Flashing time | Price, USD |
---|---|---|
CC-Debugger | few seconds | 49.00 |
Variant II – using Arduino + CCLib | |||
Item | Flashing time | Price | You save |
---|---|---|---|
CCLib project + Arduino Uno | 1.5 hours(!) | Starts from $3 USD at aliexpress | |
Total | 3.00* | 46.00 |
Variant III – using Arduino + Arduino CC-Debugger | |||
Item | Flashing time | Price | You save |
---|---|---|---|
Arduino CC-Debugger + Arduino Uno | 80 secs(!) | Starts from $3 USD at aliexpress | |
Total | 3.00* | 46.00 + a lot of time! |
*Note, that you may end up spending 0 if you already have Arduino.
This project also opens the following possibilities:
1) run the code on faster Arduinos and therefore achieve performance close to the original CC-Debugger or even run it on such boards as Particle (formerly Spark) and flash BLE modules from Apple/Android devices via Cloud;
2) in systems where BLE module works as a slave under control of a host microprocessor it becomes very easy to upgrade/update BLE firmware using host controller through its Serial/WiFi/USB/whatever capabilities.
Downloads:
1. Arduino CC-Debugger sketch & library Rev1.0
2. Arduino CC-Debugger Frontend Rev1.0
The video summarising development effort is given below:
Will it work on other BLE that is based on CC2540 or CC2541?
Such as HM-10 BLE? π
Well, there is an update which talks about minor fixes in order to support HM-10. In fact, Rev.1.1 was released after HM-10 support was added: http://magictale.com/2993/adding-hm-10-support-to-arduino-based-cc-debugger/
Will this work for the BLE112 dongle? I have one I’d like to recover. I’ve tried it with no success, no point in looking for a fault on my side if it is not an option for his device……
Thanks,
JMcC
Yes, it will work on BLE112 dongle as well – both modules use the same chip and it is the chip that you are trying to flash, never mind periphery. It sounds really funny – you have a bricked module and at the same time you are saying that there is no point in looking for a fault on your side. Well, don’t look then – it is not compulsory to use my library. π
And by the way, if you think that you spotted a problem in either frontend or Arduino sketch you are more than welcome to say about it or fix it yourself – after all, it is opensource.
Thank you,
Dmitry
No I meant a fault with the wiring/implementation of the interface by me. I’m unfortunately well aware that I have a bricked device :(. Of course the device could be more than bricked, though all I did was flash it with one of the BlueGiga examples. I since found out that apparently not all of these are safe for the dongle. Now I know the interface should work with the dongle, its worth me putting extra effort in. I’m probably missing something obvious.
Thanks,
JMcC
Please don’t get offended, I just joked. I understood you correctly, don’t worry. It is true, not all BlueGiga examples are safe for a dongle to flash because some of those examples may simply disable USB interface and then the only way is to use either CC-Debugger or this Arduino based CC-Debugger. Double check the wirings, make sure that the dongle is powered. Then try to do the test in the following sequence: connect Arduino board to your PC, then run the frontend, then push and release ‘Reset’ button on Arduino (if your board has such button), then hit ‘Info’ button on the frontend. If chip ID comes as zero, hit ‘Info’ button again – sometimes it doesn’t work from first time, same issue can be observed when using original CC-Debugger.
Good luck,
Dmitry
Good morning!
I actually tried this project over the weekend but have been unable to get it to work as of yet. I am using the following;
* Windows 10
* Visual Studio 2015
* The BLE112 breakout board by Jetney
* A homemade voltage divider made of 100k resistors (2 100k in series to make the required 200k resistors)
I was not familiar with the Arduino before this, so when the project didn’t work, I wrote some of my own code and square waves through my homemade voltage divider and saw exactly what I expected – peak-to-peak signals from 0V to 3.3V.
Anyway, what I’m seeing in the software is first a blank error box at startup (but not all the time). Then, when I execute an Info command, I basically get results back fully populated with zeros (Chip ID is 0x0000, Addresses are 00:00:00…, license, etc.) I can execute a Read and it creates a file for me which is filled with the same – all zeros!
I haven’t watched the serial traffic with a serial port sniffer, but that’s an option. I think the problem is more likely with the Arduino to BLE112 breakout side of things. I was a little concerned that I’ve got too much wire and too many connections between the two systems, so I dropped the baud rate to 9600 (both in the Arduino code and in the Visual Studio code) and got the exact same results.
Any thoughts on where I might go next with this? I’m receiving a new CC-debugger from Mouser today (my BLE112 development board port broke off last weekend which is why I went down this path), but I’d still really like to get this working!
Thanks so much,
Marshall
Hello again,
Well, I received my new CC Debugger from Mouser but couldn’t get over the fact that I never got this circuit working, so I went back to it today. It turns out that the voltage divider network I put together couldn’t really keep up with the digital logic signals between the Arduino and the BLE112 chip. I figured this out by creating a simple square wave generator in Sketch on the Arduino and then watching the resulting waveform on an oscilloscope as I increased the frequency. I can’t quite remember what speed the breakdown occurred, but break down it did!
So I used a TXB0104 bidirectional level shifter from Adafruit and substituted that in for the resistor network. Note that I also used a 10k resistor to pull up the DD_I line on the 5v (Arduino) side and I ran the DD_O line through a 1k resistor to combine the DD_I and DD_O lines into a single I/O line, but that was all that was necessary.
I then used the same Arduino code and Visual Studio code and was able to read the Info from the BLE112 along with the binary image of the code on the device! Success! Writing my own .hex image required one simple tweak to the C# code. The filter on the openFileDialog1 object on the form is set incorrectly. Instead of it being “*.hex|*.bin” it should be “Binary Files|*.hex;*.bin”. Once that change was in place, I was able to both successfully read and write binaries to the BLE112.
Finally, I am still getting the occasional blank error message when I run the Visual Studio front end software, but it doesn’t really get in my way. At some point, I’ll probably look into this, but I can’t say it’s high on my priority list.
Two things in conclusion; first, I don’t understand how Dmitry got all this working with a resistor voltage divider where I could not – maybe it’s just the environment I’m working in or possibly my soldering isn’t quite as good. Perhaps it’s somehow related to the fact that I used two 100k resistors in series to create my 200k resistors? Don’t know but wish I did. Second, I realize I only gave a verbal description of using the TXB0104 instead of the voltage divider network – if someone is interested in the details of exactly how I did this, I have no problem providing an actual schematic.
Dmitry, thanks so much for all the work on this – excellent project! Next, I really want to get this working on a Raspberry Pi 3!
Sincerely,
Marshall
Hi Marshall,
Thank you very much for your feedback. I must confess that I haven’t actually tried the resistor dividers as I always used my Arduino which can operate in 3.3V mode. Now you made me curious and I am willing to give it a try but it is going to be in 2-3 weeks as right now my time schedule is too tight.
Thank you for the great words Marshall – I am happy that my work could be considered useful by you guys and this is the main driving force for this blog.
You say Raspberry Pi? Well, have a look at this: http://logicalgenetics.com/raspberry-pi-and-mono-hello-world/
The guy was able to run Mono on Raspberry so you may even be able to compile the project under Mono without too much to change.
Thank you again,
Dmitry
Hello Dmitry,
I am quite surprised that the CCLib project takes about 1.5hours to flash a chip, and I am really, really curious to see your set-up! I agree that the library is optimised for agility and not performance, but thats ridiculous!
If for 128Kb it takes 90 minutes, it means that it sends 24 bytes per second? Did you accidentally switch your serial baud rate to 300 bps? In normal situations, you have at least 115,200 bps baud rate and the library can burst-write 2Kb at a time, resulting in about 1~2 minutes flashing time and about half a minute for validation afterwards.
Great work on the GUI version though! However, since I am constantly switching between Windows/Mac and Linux I would stick on the command-line version π
Hi wavesoft,
My setup is described in this article. π I totally agree that 1.5 hours is ridiculous this is why I started this project.
No, I didn’t accidentally switch to 300 bps. After all, if you read the article, the real bottleneck is not in bps, it is in data roundtrips. And it is not about burst-writes but rather the amount of time which is wasted while a 2kB block is transmitted through the serial interface with multiple transactions which used to be extremely inefficient. Sorry, I don’t see a way how you library can demonstrate the performance specified by you as 1~2 minutes.