Bad things happen when programmer finds a soldering iron

Detecting Watchdog Reset in XC8

Illustration

Watchdog is probably one of the best PIC microcontroller features. Yes, it would be great if you would write perfect code and program would not get stuck in the first place, but let’s face it: mistakes are going to be made. And really, are you going to write timeout code around every communication routine just so you can detect one in million error?

In 99% of cases, you will just turn on WDT timer in your config bits and count on it to reset microcontroller if something goes wrong. If watchdog times out, program will start from scratch and all is good. For all practical purposes, watchdog-initiated restart is same as normal start. Or is it?

Most PIC microcontrollers clear their ~TO bit in STATUS register as a way to detect watchdog restart. However, if you try to read that from your XC8 compiled C program it will seem that every microcontroller start is normal. It will report any timeout. Cause? Because your compiler is clearing STATUS register before your program starts running.

If you are interested in watchdog timeouts, first you need to tell your compiler to preserve startup status for you. This can be done by going into project properties, selecting XC8 linker category and checking Backup reset condition flags item. Now your compiler will give you access to two special variables: __timeout and __powerdown. These variables will be copy of ~TO and ~PD states respectively.

If you read datasheet carefully you will notice that ~TO will be 0 if timeout has occurred. Thus code to check for it would look something as:

void main() {
    ...

    if (^^__timeout == 0^^) { //value 0 means there was a timeout
        //this restart is due to the watchdog timeout - do something here
    }

    ...
}

PS: Procedure described here is specific to XC8 compiler. But same principle applies with most other compilers too.

Jelly Bean PICs

It used to be easier years ago when I started playing with Microchip microcontrollers. You pretty much had only PIC16F84 readily available and that was the PIC you used for anything. Today situation is very different. There is probably a different microcontroller for any purpose you can imagine. However, with time, I more-less standardized on a few of them.

Theme is common. I work mostly with 5 V power supply so anything that can work directly of that is highly desirable. Pretty mandatory is at least one UART port because that is something I use more often than not. I2C and SPI are also high on the list but they sort of go hand-in-hand with aforementioned USART so I rarely specifically search for them.

For most of things I do speed is rarely of concern and any PIC with internal oscillator (keeping component count low) will usually do. Exception is when it comes to USB and CAN bus that are really finicky in that respect.

Quite often my PIC of choice has multiple family members so I can easily go between memory sizes and/or pin counts. Also high on the list are old and proven designs everybody else uses. Why do development around a new and/or unknown PIC if you cannot buy it 90% of the time.

Since most of my soldering is done by hand any PIC that cannot be obtained in SSOP or similar package is automatically out of picture. Having it in DIP format is a small plus but I personally don’t really care about it.

Without a further ado, here is my list of PIC chips I always have available:

PIC16F1826

If I don’t have any special needs I will most probably end up using this little gem. It is rather small in size with only 20 pins SSOP (18-pin DIP), 16 of which can be used for I/O (not all models are this pin-efficient). Alongside 256 bytes of RAM, it also has 256 bytes of data EEPROM available. Basic model has only 2K of programming space but upgrade to 4K model (PIC16F1827) is completely painless.

Features include 10-bit ADC (12 channels), specialized capacitive touch module (12 channels), good UART, and support for both I2C and SPI. It goes up to 32 MHz, all that on internal oscillator module. Only thing you need to connect one of these is 1.8-5.5 V power supply and a small decoupling capacitor.

Price (in quantities of 1) is always less than $2.

PIC16F1934

If I need to connect PIC to LCD, I keep going back to this one 40-pin beast. With total of 36 I/O lines controlling 3 digit LCDs is trivial and that is not even maximum it can support. This basic model has similar (to PIC16F1826) memory configuration. However, next two models (PIC16F1937 and PIC16F1939) double the RAM and program memory each, all the while keeping full hardware and software compatibility.

Due to its bigger size, it has 14-channel 10-bit ADC and 16-channel capacitive touch module. It goes without saying that UART, I2C, and SPI are all supported. Internal oscillator is same respectable 32 MHz as is the need for 1.8-5.5 V power supply. A bit more careful decoupling is going to require three capacitors.

This family has also a smaller PIC16F1933, PIC16F1936, and PIC16F1938 members I sometime use. From software perspective they are the same as their bigger brothers but, since they have lower pin count, you cannot just drop them instead of larger device.

Price for one is $2.50.

PIC18F25K80

This microcontroller is a beast. In its small package (28-pin) it has whooping (for a microcontroller) 32K of a programming memory acompanied with 1K of a data EEPROM and 3.5K of RAM. Its hardware-compatible upgrade (PIC18F26K80) improves program memory to 64K. This family also has bigger members in 40 and 64-pin configuration but they are not drop-in replacements.

ADC is 12-bit (8 channels) which is pretty much the best you can find in any microcontroller and there is a support for two UART devices at the same time. Of course that it also supports I2C and SPI but my main reason for using it lies in its CAN bus support. Just add a CAN bus driver and you are good to go.

This is still 1.8-5.5 V device but one has to take a bit bigger care with decoupling since Vddcore needs a bit larger capacitor than standard 100 nF we’ve come to expect. Also notice that CAN bus functionality pretty much requires you to have external oscillator so getting everything setup is a bit more work.

For one you’ll pay about $3.50 but it is worth it.

PIC18F26J50

Whenever I need to play with USB, this is my go-to chip. This 28-pin device has 64K of program memory, 3.5K of RAM and unfortunately no data EEPROM. But fear not, you can use program memory for settings. If you don’t need a lot of program memory, you can use smaller PIC18F25J50 and PIC18F24J50 but I’ve found that anything USB related usually wants 64K as a minimum. Of couse, you can also go to higher pin count with PIC18F46J50 if that is what you need.

You also get standard 10-bit ADC (10 channels), 2 UART modules and, of course, I2C and SPI support. Internal oscillator goes up to 48 MHz and it is precise enough to allow for USB interaction. This device also has a really configurable pinout so it’s great for a size-constrained designs. Unfortunately its power supply has to be 2.0-3.6 V, it needs pull-up resistor for reset control, and multiple decoupling capacitor sizes require you to have quite a few supporting components. It gets expensive and crowded pretty fast.

There is a promising PIC16F1459 which does offer a bit more modern architecture and a simpler 1.8-5.5 V life but I find 8K programming memory really restrictive when dealing with anything USB.

One PIC will cost you slightly less than $4.50.

No Drilling, Please

Illustration

As I managed to do create a holly grail of electronics - double sided PCB without any vias, only remaining step was to get it made.

Usually this would consists of uploading board gerbers to OSH Park and getting payment sorted out. However, this time I was greeted with error: “I can’t find a drills file”. Mind you, this was expected since I really didn’t have a drill file, but unfortunately this wasn’t a warning I could skip. So I contacted support.

I really didn’t expect any quick answer since I raised ticket on December 31st after 16h PST. Surprisingly I got the solution almost immediately. It wasn’t possible to upload design without drills but Dan (yep, Laen doesn’t handle support any more) suggested a file with drill locations all falling outside of board. Their filtering process would then remove those as invalid and my drill-less board would be ready for manufacturing.

While this solution was acceptable for one-off job, it got me thinking whether there was something a bit more elegant and less error-prone if I create some bigger board in the future. To solve it properly I had to have a drill file without any drills. To the Excellon specification!

With a bit of testing, I got to the minimum of content that OSH Park parser would still consider a valid drill file. It is essentially just defining one drill tool, selecting it for work and then finishing script without ever drilling a hole:

M48
INCH
T01C0.0394
%
T01
T00
M30

Empty drill file is available for download.

Rectangular NFC Antenna Calculator

NFC coil example

For a project I had to calculate parameters needed to make nice rectangular PCB inductor for a NFC antenna. Since my search didn’t bear desired results, I decided to make my own.

Enjoy.

mm
mm
oz
mil
mil
 
mm
mm
mm
 
μH

Calculation is done per NXP’s AN1445.

FTDI - Best to Avoid?

Serial port ruled the hobby market when connecting custom electronics to a computer was needed. As USB became prevalent, instead of serial interface we got USB-to-UART chips. Most common ones were manufactured by Prolific and FTDI and they became defacto standard. I personally chose FTDI’s FT232RL for huge majority of my designs. Partly it was due to driver availability for almost any platform and partly due to my bad experience with Prolific’s PL-2303.

Mid October FTDI pushed new WHQL certified driver via Windows Update. For quite a few customers that meant death of their serial devices. And it wasn’t just a compatibility issue. Once some devices saw new driver they became unusable on other operating systems (yes, including Linux). For more information, there is a huge thread at EEVblog forum along with some other sources.

Story started when the FTDI engineering found a way to detect some (if not all) non-genuine chips reprogramming them in process. For all practical purposes any device containing fake, cloned or compatible chip became dead. You could boot into Linux and previously working device would refuse to cooperate. You could even move it to another computer (without driver update) and it still wouldn’t work. While change is reversible by the expert user, normal user would just assume device is dead.

Were they in the right to detect fake devices and not work with them? For fakes chips answer is most definitive yes. It is a bit of a gray area when it comes to the compatible chips that have no FTDI markings. But actually killing the end-user devices is taking “pirate” fight a step too far. I am not necessarily talking about legality of “bricking” devices; I am sure that we will see at least legal analysis if not a legal action due to this.

As it works currently, in hobby market, you almost never contact manufacturer directly. You typically go via third-party. Whether you get legitimate or counterfeited chips is mostly a function of price. But you can get a real chip for cheap (e.g. somebody selling unused stock) and you can get a fake for a full price. Yes, you are more likely to get a original if you deal with a big/official suppliers (e.g. DigiKey, RS, Farnell/Newark/Element 14/whatever-is-their-name-now) but they are pain to deal if you are from in “unsupported” country. And a dollar difference here or there might make a difference to a hobby user.

As you sell a few devices with everything looking peachy they all suddenly stop working. Devices start coming back and you need to issue refunds or give a new device with a genuine chip. In an ideal world, you would sue your supplier and recover your damages. In reality you just swallow the loss because having a day in court would cost much more (in both time and money) than what you can hope to win. Only thing you can do is to avoid troublesome chip in the future. Once burned twice shy.

Similar problem exists if you bought a hardware device with the purest intentions. Price was right, not too high, not too low, functionality was just right and device used a FTDI chip internally (e.g. quite a few Arduinos, some BusPirate versions, humble chip breakout, or even some boards I made). But device manufacturer either used fake part knowingly or they just got screwed. In former case device was happily working until suddenly unrelated driver update killed it. If device is new you might get a refund. But chances are that you’ll get nothing.

If you are doing more than a few devices chances are you’re probably outsourcing assembly to somebody else. Dealing with assembly is handful on the best of days and now suddenly you might have on your hands a bunch of devices that pass all possible tests on the assembly bench only to be bricked by the end-user’s computer. To anybody other than the biggest manufacturers this is a scenario from hell. You will need to replace quite a few devices with assembler claiming devices work on their end and that it is not their issue. Court may be your friend but money/time equation usually does not work out.

And it is not as this fixes issue of fake devices. Those making fakes will just adjust their firmware to behave as a real FTDI chip for this case and Whac-A-Mole starts anew. I personally see a much higher chance that some later driver update will accidentally kill some genuine chips rather than preventing cloning. Recognizing that problem, FTDI CEO did say “sorry” but with a side dish of “we’ll do something else less drastic next time”.

I will personally vote with my wallet until I see what next few months will bring in this FTDI saga.

PS: If you want to get away from the FTDI but you don’t want to rework your board, there is a Cypress CY7C65213-28PVXI. It is pretty much exact pinout (albeit without possibility of an external oscillator), supporting anything from Windows 98 onward, and at a lower cost.

PPS: Those prepared to change board can look at MCP2221.

PPPS: Yes, I am aware my actions are purely cosmetic since I only buy 20ish FTDI chips a year.

[2016-02-05: They’re at it again. This time not bricking, just messing with data output.]

How Much for the Shipping?

Illustration

One of the most common ways to interface a computer and custom electronics is still a serial port. Since 9-pin connectors are mostly thing of the past usual choice these days is an USB to serial bridge chip.

While I am usually relying on excellent FTDI’s FT232R, I am always open for a something new. Therefore I was click-happy when I saw Silicon Labs tweet about $5 evaluation kit of their CP2104.

I went forward only to be surprised at the shipping cost for a device that cannot be heavier than a few dekagrams. Cheapest shipping within United States was $26 - a way too much for this device especially when anyone, as a private person, can get a better deal from UPS. How come that company such as Silicon Labs cannot ship it cheaper? Answer is - they can.

Over-inflating shipping cost became popular on ebay as a way to seem really cheap. You decrease item cost and increase the shipping. Total amount you get is still the same but your offer stands out as the cheapest one. With time this way of pricing has spread to Amazon and essentially any site that allows you to set shipping cost.

Somebody from Silicon Labs wanted to be able to say they do cheap kits but without all the hurdle of actually being cheap. I call that lying, they call it marketing. :)

CAN Bus Setup

Note: If you are only interested in bit-rate calculator, skip to the bottom.

Illustration

As you start designing CAN bus node around Microchip’s PIC microcontroller everything seems deceptively simple on the paper. Like with good old UART you only set for a node frequency and everything is fine and dandy. And then reality hits with various bit times and their “fuzzyness”. At times it might seem that there are a gazillion different ways it can be configured. How to decide?

There are four main parameters that determine all others. Obvious one is microcontroller’s frequency. You are pretty much required to use crystal because CAN bus tolerances and stability needs don’t allow for internal oscillator. My personal preference is using 12 MHz crystal as an oscillator source. 12 MHz allows quite high frequency (48 MHz with PLL) and it is quite commonly used for USB so you can share it (via REFO pin) with other devices on board (e.g. serial to USB converter).

Since all CAN nodes have to share the same baud rate, decision is made for you if the new node has to be integrated in the existing network. If you are designing your bus from scratch there is a whole slew of speeds you can select. I personally like to stick with CiA DS-102 defined speeds (10, 20, 50, 125, 250, 500, 800 and 1000 kbps). Higher baud rate allows for more messages/second but it works only at shorter distances and demands for better frequency stability. Lower baud rates allows for more distributed nodes and you might even get away with R/C oscillator source (at very low speeds). I use 125 kbps (500 meters max) as a starting point and deviate only if I really have to.

Maximum bus length is function of allowed signal delay. Higher the bitrate lower the distance and vice-versa. This parameter is basically our sanity checking mechanism and one of inputs when we calculate propagation segment duration.

Time quanta (TQ for friends) is smallest time unit in CAN bus and it controls duration of a single bit. To represent a single bit, you need between 8 and 25 TQ. Those TQ units are further subdivided into synchronization segment (always 1 TQ), propagation segment (1-8 TQ), phase segment 1 (1-8 TQ) and phase segment 2 (1-8 TQ). Bigger the TQ, more control you have over fine bit tuning but at the cost of higher frequency need (i.e. 16 TQ subdivision will need double the frequency compared to 8 TQ to maintain same bit rate).

Synchronization segment always last for single quanta and CAN bus uses it internally to adjust bit edge. This ensures that various nodes don’t drift in time because of slight frequency differences. This is only segment with fixed duration.

Propagation segment that follows is there to compensate for a physical delay of the signal going over wire and its receival in driver. Rule of the thumb is that its value gets bigger with physical distance.

Phase segment 1 tells us duration (in TQ) before bit is actually sampled from line. Higher value you have, later sampling will occur. Actual sampling happens after sync + propagation + phase 1 quanta. More often than not, you want this time to be as close to the full quanta as possible.

Phase segment 2 is last segment and its duration concludes full bit time. It is very useful to keep this at at least 2 TQ because otherwise your sample point might get too close to edge of next bit.

First programming parameter that PIC will actually use is the baud rate prescaler (BRP). Based on it we determine bit rate according to following formula BRP = FREQUENCY / (2 * TQ * BITRATE). This value than gives you actual TQ time (TQTIME = 2 * (BRP + 1) / FREQUENCY). From that you can get duration of a single bit (TBITTIME = TQ * TQTIME). Since BRP value can only be integer, to get nominal bit rate PIC we use another calculation BITRATE = 1 / TBITTIME. If everything goes alright actual bit rate will match desired bit rate. If such thing does not happen, a bit of input parameter tweaking might be beneficial.

I prefer to calculate phase 1 duration next. General rule is to have it last as long as possible. Half of total bit duration is as good approximation as any. Of course, maximum of 8 TQ.

Propagation segment length gets calculated based on desired physical bus. I use standard 5 ns/m figure for bus delay and I add 250 ns as worst case processing delay in transceiver and use that as a minimum value. If TQ is higher propagation delay must be increased regardless of actual physical distance because of phase 1 and phase 2 having maximum of 8 TQ.

Phase 2 gets calculated from whatever is left after sync, propagation and phase 1 segment get their share.

Synchronization jump width is fuzziest of them all. In theory it would help you if clock drifts between nodes. However, make it too big and PIC starts detecting sync bits where there are none. I usually go with half of propagation length as a starting point and then I adjust it not to be longer than either phase 1 or phase 2. This gives a bit of wiggling space for clocks to drift but it is not overly aggressive.

Below is a small form which actually does these calculations. Might come in handy.

MHz
kbps
m
 
kbps
m
%
 
(- TQ)
(- TQ)
(- TQ)
(- TQ)

PS: Some additional information that might be useful:

Forcing Rebuild in MPLAB X.

Illustration

For a project of mine I needed a random serial number. I got it in Intel hex file not by memory address as you would commonly have, but by search & replace of a string. While I prefer this approach in most cases, it also meant that once code has been replaced, next replace would fail. I needed a rebuild.

Unfortunately MPLAB is too smart and it avoids rebuilding if no file has been changed. Of course there is no option to force rebuild either. Only thing left is to actually change a file or at least its time.

Under Linux there is a touch command. Under Windows there is an almighty copy. To update file time we need to simply execute:

COPY /B **source**+,,

To use this in MPLAB X go to project Properties, Building and check Execute this line before build. In text box underneath just apply newly found command on project’s main file (App.c in my case):

COPY /B **${ProjectDir}\App.c**+,,

Serial Number in Intel Hex

While doing an electronic project in MPLAB, I found it necessary to create an unique serial number for each device I program in order to have a proper USB functionality. Something as simple and often needed as this has to be already solved. Or so I thought.

Oh, I found solutions and solutions for this particular issue. Most of them were only useful with their device programmers - and I wanted something to work inside of MPLAB. Some other worked by modifying source code - a big no-no when you do source control. Some required serial number placed at an exact location - annoying (and volatile) to calculate in my case because USB serial number is a part of a bigger structure. Commercial solutions were also out of question… With each visited link I grew more firm in decision to roll out my own (“me hammer, problem nail” approach).

However, simple replacement is not necessarily an easy thing to do. You see, in world of microcontrollers Intel Hex format is the ruler. Without getting into details, format has two characteristics that make it suitable for firmwares. It splits data into fixed length blocks which is really nice when you have to do chip programming in blocks. Additionally every row is checksumed so data corruption can be avoided. Both those characteristics conspire against us to do simple file change. Not only that we cannot just simply change data because of checksum but we often cannot even simply find it because it can span across the rows.

So, it was a scripting time. Because of annoyingly difficult parsing, simple CMD was out of question. Only other choices were PowerShell or a completely custom program. While custom program would probably offer easiest development, I didn’t want to embed only executable. And embedding sources would mean that I would need Visual Studio on each machine I want to compile this at - to high cost in practicality. Only other choice really was PowerShell - environment that exists on every Windows 7 and higher machine.

Requirements were straightforward. I wanted something that would be a single call (Microchip’s MPLAB can call only single external build command). It had to replace file in-place (so that I could continue using PICkit 3 programming procedure). It had to change file as little as possible (e.g. by not removing extra headers). It had to support ASCII random (USB MSD specifications). And, lastly, it had to be capable of producing a valid output hex without checksum shenanigans.

I won’t dwelve into boring details and explain each part of code but it suffices to say that it loads whole file in memory, searches for placeholder and then replaces that placeholder with random value, adjusting the checksum as it goes. End result is the file that gets pushed onto the device.

Here is an example command (Project Properties, Conf, Building, Execute this line after build):

PowerShell.exe -ExecutionPolicy RemoteSigned -File ${ProjectDir}\..\Setup\HexReplace.ps1 **${ProjectDir}\dist\default\production\Source.production.hex** **197901281815** -**AsciiHexRandom** -Destination2 **${ProjectDir}\..\Binaries\TmpUsb.hex**

First part we might as well ignore because it is only preparing terrain for script by calling PowerShell. First meaningful argument is a location of an intermediate Intel hex file followed by a placeholder value. Since my device is USB based, I opted to have a valid serial number (197901281815) as a placeholder - makes live easier if script fails. Most common approach is to use something that won’t appear by accident (various number of X characters seem to be popular choice). Anything unique will do.

Switch AsciiHexRandom ensures that our randomness will be limited to numbers 0 to 9 and letters A to F, as required by MSD Bulk Only Transport 1.0 specification. If that parameter gets omitted random binary (0 to 255) will be used. Which one is better actually depends on your use case.

Last pièce de résistance is -Destination2 argument. That ensures script will not only change file but additionally copy it to a different place. It is not strictly necessary but I find it useful for archiving purposes. You can omit it without any consequence.

And that is my way of generating random serial number from within MPLAB project. Try it out and see whether it fits your needs.


PS: Script itself was not designed but grown. As such it is full of unoptimized code (just check function that does replacement) and it treats memory as kids treat candy. But realistically we are speaking about file that won’t be bigger than couple hundreds KB in the worse case scenario. I could not justify spending time I would need to make it “proper” when it already runs (unoptimized) within a fraction of a second.

PPS: Yes, I have cheated by embedding C# code inside of PowerShell.

PPPS: If something goes wrong, add -debug argument. That will give you a bit more information to go with.

OSH Park Just Got Bigger

Illustration

Last few years it got really easy to have your PCB manufactured in small quantities. All manufacturers shared similar price but each had its own peculiarities.

I find it very sad that one such manufacturer, BatchPCB, is closing its doors. It is not that I used them often. It is not that they were anything special. It is not even that they were cheap(er). It is just that I liked the choice.

Good news is that they were taken over by OSH Park. BatchPCB users can expect lower prices on smaller than 20 cm2 boards, they can expect ENIG finish (aka “gold”), and they can expect free shipping within USA.

Dream purple.