Thursday, February 28, 2019

Dual-core development board

So a while ago, I discovered the dsPIC33CH family of dual core digital signal controllers (dsPIC33CH128MP505).  I did considerable tinkering with the proto board I was using, and it was becoming clear that this is a nice part. I took it being a 3V3 part as kind of a downside, but there are more and more 3V3 peripherals, which is one reason I kept hacking up that proto board to try yet another thing.

So my dsPIC-EL-GM solved that problem for the dsPIC33EVxxxGMy02 parts (and some PIC24 parts, too).  I've probably done hundreds of experiments with that board because the shield makes it so easy to start a new project. In spite of custom shields being a fraction of the price of commercial proto shields, I still tend to tack on project after project, and have found it necessary to label the shields so I don't get frustrated with the wrong connections.

Custom Proto Shield
So the idea of a experimenter's board for the dsPIC33CHxxxMPyzz was born.  Problem is, the 33CH isn't available in DIP. I'm not frightened by the prospect of soldering a TQFP, but laying out the PCB was another thing entirely.  My original thought was to design for the MP505 (48 pin) part. But I didn't have a TQFP48 footprint, and I wasn't real confident I could make one.  With the 64 pin part, I could populate all the Arduino headers without sharing pins with onboard peripherals.

But it isn't all sweetness and light. The dsPIC33CH512MP506-I/PT is in a 10 mm package, which means there are a whole lot of pins real close together. By itself that wouldn't be a real big deal, but you need to DO something with those pins. And that means you are going to need vias, and vias take space.

As I got the board laid out, I got lots of errors that the foils were too close, but in many cases, there didn't seem to be a lot I could do about it. Eventually, I got the first attempt at the board laid out.

PCB image from layout program
It had been a while since I had a PCB made, and in the interim, my favorite manufacturer quit making custom boards. And then another couple of surprises.  Many fabricators won't make boards with traces a tight as I had, and many of those that would charged a premium. Another surprise; it used to be that I could get a board made stateside for about twice what a Chinese board cost. I could have it in about a week, as opposed to three weeks for Chinese. Since then, Chinese prices dropped a little, Chinese fast shipping got more realistic, and U.S. prices exploded.  Stateside boards now cost more than ten times what a Chinese board cost.

I did find that JLCPCB would do my board without a premium, and I could get shipping for a sane price. I could get a board shipped from China in one day longer than it used to take for U.S. boards, and half the price that the U.S. boards used to cost. To add insult (to the U.S. fabricators) to injury, they have a nice web site that lets you watch the progress of your boards through the manufacturing process, and they have an apparently very thorough board checking before it goes to manufacture. It took me several cycles to get it right, and more than once they emailed me with questions; once I did something odd but meant to, another I had an error and was able to correct it before the board went to manufacturing.

Completed Dev Board (no shield installed)
Since much of the challenge was getting the traces routed, I actually laid out the board without a schematic. Yes, there were a couple places I shot myself in the foot, but all in all, it wasn't too bad.  I figured I should have a schematic too, and got to work on that. Turns out the schematic for something with all those legs is almost as fraught as the PCB.

I don't know if I'll think of other things that need to be done to this board.  A version of my Serial Graphics Terminal that avoids the use of I/O expanders has been on my radar for some time, but that requires the use of a TQFP100 part. This board may well give me the confidence to go ahead and attack that.

For now I have some playing with 3 volt gesture sensors I want to do.

As always, the gore is in gitlab.

Wednesday, November 28, 2018

An improved dsPIC-EL-GM

It was way back in 2012 when I first started thinking about a dsPIC-EL, but it was 2015 when I finally broke down and sent a PCB to production.  Since then the dsPIC-EL-GM has been the foundation for dozens, maybe hundreds of projects.

Recently I find I am dealing with many more 3 volt parts, and I often end up building a 3V3 supply on whatever shield I am making at the time.  The basic board has plenty of proto space which I never use, so why not sacrifice some of that for a 3 volt regulator?  The Arduino shield has a pin for 3 volts, so that wasn't a big deal.

3V3 supply
Turns out to have been a pretty simple change, and I was running out of boards and probably would need to order more anyway.  The one disappointment was that I paid extra for DHL shipping, and due to customs delays, Chinese holidays, etc. the board took almost as long as free shipping. Well, that and Maker Studio no longer makes custom boards so I had to search out other suppliers.

Things have changed over the past few years. The price of Chinese boards has come down a little, but the price for U.S. made boards has exploded. It used to cost less than three times as much for a U.S. board over a Chinese board. Now it is more than ten times. Plus, I can get Chinese boards just as quickly as U.S. boards, so even paying a premium for fast shipping, they are still a lot cheaper.

One minor annoyance in the old board was that the contrast pot for the LCD couldn't be adjusted when a shield was in place. I tried drilling a hole in the shield, and even laid out a new shield PCB (but never ordered it).  It occurred to me that I could fit a vertical pot under the LCD.

New contrast pot location
With that change, I could now adjust the LCD contrast without messing with the shield.  (Yes, I know, how often do you need to do that. Well, I play with various LCDs, kind of a fetish I have, so I probably twiddle that pot more than the average bear.)

While I was at it, I decided I would change the bypass caps out for SMT caps. Don't know why, I have hundreds of 0.1 and 0.01 monolithics in the parts drawer, but it seemed like the thing to do.  What I didn't do is change out the resistors, which I probably should have.

dsPIC-EL-GM full board
The other thing I really should have done is used SMT LEDs. The 5mm LEDs sometimes get in the way. On one instance I did tack SMT LEDs on to the through hole pads, and that worked quite well.

I'm pretty pleased with this board. Although there are a few things I would like to change, nothing is really pressing, so probably this will be the last change for a while.

As always, the PCB file, Gerbers, etc are all in gitlab. This version is in the Rev2 branch.

Saturday, July 28, 2018



So back in June, AB Pearce mentioned on the piclist that Microchip had introduced some dual-core PICs.  Apparently they had been out for some time, and talked about in the Microchip forums, but I hadn't been aware.

So I did a little exploration, they look reasonable, checked out the pricing on Newark and Digikey, and ordered a couple dsPIC33CH128MP505 and a dsPIC33CH128MP506. I didn't really have the time to play with them, but I figured might as well have them on hand for whenever I did find the time.

Of course, the bright, shiny things kept calling, so more important things got pushed out of the way to play with the dual-core dsPIC.


For my testing I selected the dsPIC33CH128MP505; with only a few LEDs and maybe later something else, there seemed to be no reason for the 64 pin dsPIC33CH128MP506.

The dsPIC33CH128MP505 is a 48 pin part, I ordered it in TQFP because I had some TQFP adapters that would work and there were no DIP parts.  The master core is more or less as expected, 128K of flash program memory, 80 MIPS so a tad faster than my favorite dsPIC33EV.  The slave core has 24K of program RAM, and at 100 MIPS is slightly faster still.  Obviously, since the slave program memory is RAM, the slave program has to be loaded by the master, so it needs to be stored in the master flash.

Each core has its own set of peripherals, slightly different from each other.  All input pins are accessible to both cores, but outputs must be assigned to one core or the other. Like other dsPIC33's, the peripheral complement is huge.

There is the typical set of PRI, FRC, LPRC oscillators, with or without PLL, shared by both cores. Each core can select the oscillator and has its own PLL chain. The PLL chain is slightly different from the dsPIC33E, but conceptually similar.

One interesting thing is that the datasheet indicated that the outputs can drive LEDs without the need for current limiting resistors. On my test board I used them anyway, because that's what I do.

Test board

In order to do something, I built up a simple test board. I generally power my PIC projects with a cell phone charger which provides 5 volts, so my board needed a 3.3 volt supply. A connector for programming, some assorted caps and resistors, and a few LEDs were all that I needed to hack together something to play on.

I am generally a little cavalier about bypass caps on prototyping boards, but in this case, the processor wouldn't run until I sprinkled a few around in obvious places. That is actually the first time I ran into that.

Programming the master

Getting the master to blink an LED was no big deal. The only surprise was that there are an incredible number of configuration bits. The bits are shared between master and slave. Many apply to both, but there are some that are specific to the core. All are provided in the master core's program.

Besides the fuses you might expect, every pin has a fuse to assign it to either the master or slave. There is a data direction fuse for each of the mailbox registers. There are also bits to enable each of the mailbox protocol blocks and to assign them to a mailbox register. Each of the four sets of alternate registers can be assigned to an interrupt level. The master and slave can each have independent ICD communications pins.  All in all, an intimidating set of configuration fuses.

Once you get past the shock of the configuration bits, programming the master is unexciting, as long as you are only programming the master.

I did set up the master and slave program projects as subdirectories of a sort of master directory, and placed both projects in the same git repository. Although small repos are generally better, in this case the master and slave are closely linked, so it seemed to make sense.

Programming the slave

Getting the slave to run is quite another can of worms. There is, of course, the datasheet, the Family Reference Manual, and an application note, AN2721, which has some associated sample code.  Even with this documentation, there are a number of secrets that aren't obvious.

The documentation seems to indicate that the slave program must have the same name as the master's, followed by S1. This doesn't seem to be a requirement, although I haven't tested that supposition. What you do need to do, though, is select a processor name followed by S1 when creating the slave project.  So the project for dsPIC33CH128MP505 is the master program, and the slave program uses dsPIC33CH128MP505S1 as the processor type.

Since xc.h takes care of the processor, it isn't 100% obvious that there are also two header files, p33CH128MP205.h and p33CH128MP205S1.h, which becomes important because often the headers need to be explored to understand what the documentation means, or more often, to fill in the blanks.

Everything is slave 1 this and slave 1 that, so it appears Microchip is leaving the door open for parts with more than one slave core. Since the slave program has to be stored in the master's flash, it would seem that multiple slave versions are going to need an awful lot of flash.

The slave core's program is loaded with a call to _program_slave(), obvious enough, and the slave started with a call to _start_slave(). Also seems fairly obvious. However, the _program_slave() call takes three arguments. The first is the number of the slave. The second is whether the program is to be "verified", whatever that means. The final is the address of the slave program.

And that's where it gets interesting. When creating the master project, a new folder, "Slaves", is created. The slave project must be added to this folder in master. So far, makes sense. If the slave program is going to be stored in the master flash, the master needs to know that it needs to be linked in.

The address in the master flash can be specified in the slave project properties in the Slaves folder. But, referencing that address in the _program_slave call doesn't work!

The examples from Microchip all use the slave project name in the _program_slave() call. However, simply stuffing that in doesn't work. The examples always included the slave's include file in the master's mainline, which I assumed somehow declared the symbol. But I could find no combination of attributes that worked. Worse, in the example code, I could never find that particular include file.

It turns out that referencing the slave's include file, even though it is in another project, does the trick. The include file can even be empty.  I suspect it might not even need to exist, although I haven't tried that yet. Also note that _program_slave() and _start_slave() are defined in libpic30.h.

Once that was in place, I was able to flash an LED from the slave. But to understand that the master and slave were both working, I thought it would be helpful to start and stop the slave.  While libpic30.h defines a _start_slave() function, there is no function to stop the slave.

The slave is started by setting the SLVEN bit in the MSI1CON register. This register, like the EEPROM in the 8 bit parts, requires an unlock sequence. Since I may want to do this in the future, I wrote a stop_slave() function.

I did find it rather curious that the assembler played like a compiler a bit, and modified my code. Where I cleared the SLVEN bit (bit 15) in the MSI1CON register, the generated object code cleared bit 7 in the MSI1CONH register, apparently saving a little time.

I was now able to start and stop the slave as needed.  In theory, one could have multiple slave programs and switch between them under master control. In this case it would be important to be able to stop the slave. Lacking a stop_slave() function in libpic30 seems like a significant oversight.

Mailbox Communications

Now that I could program, start and stop the slave, the next step is communicating between the two. So on to sending data from the master to the slave. There are two ways to do this, through mailboxes or through a FIFO. I decided to try the mailbox first.

Slave Output

Being able to understand that I was successful in sending data from master to slave was going to take more than an LED as a way to let me know I was successful. Previously, I had built a PIC32 based Serial Graphics Terminal  for just this problem.  So I added a connector for this terminal and a litttle code to communicate.

Unfortunately, I had some hassle with this. I'm not sure whether I forgot some initialization or didn't have the baud rate quite right, but the objective was to try out the mailbox communications, not debug the terminal, so I fell back to my
Simple Terminal which only does text. Since this application is really dumb and has no cursor control, it is fairly slow, but adequate for this purpose.

Mailbox Communications

The 33CH provides 16 mailbox registers which are visible to both master and slave. They are unidirectional; each must be assigned as master to slave or slave to master.

There are up to eight protocol blocks. A protocol block is a sequential group of mailboxes going in one direction. The final mailbox in the group triggers the transfer. Again, more configuration bits to enable a group and assign the register.

You can see how we come up with over 100 configuration settings.

Once the configuration bits are set, the exchange is fairly easy.  The master enters the data into the mailbox registers, taking care to load the last register in the handshake block last. Writing the last mailbox sets the data ready bit for the slave.

Master then waits for the data ready bit to clear, indicating that the slave has retrieved the data.

On the slave side, it waits for the data ready bit, then reads the data. When the final mailbox is read, the data ready bit is automatically cleared.

Note that the registers have different names on the master and slave side.

Graphics Terminal Output

FIFO Communications

FIFO communications, if anythig, is even simpler than mailbox, assuming no handshaking anyway.

The master and slave each  have a control register for the FIFO,  MSI1FIFOCS for the master and SI1FIFOCS for the slave. The receiver sets a read FIFO enable bit, while the sender sets a write FIFO enable bit.  The sender then stores data into the FIFO which the receiver can retrieve.

As an example:


So the dual-core PIC is pretty manageable. There is still plenty to explore.

But I am thinking wouldn't it be nice to have the master run a DDS while the slave runs the keyer.  I may need to try that.

The code for this is in gitlab as always.

73 de WB8RCR

Monday, July 24, 2017

A GPS adjusted clock

We recently got a new cable box.  The new box has a clock that is a little smaller than the old one, and my wife has a hard time seeing it. We had an LCD clock with huge letters but there just isn't enough light in the place we want it.

So, NE06 GPS modules are getting pretty cheap. Why not get some huge seven segment LEDs and build up a clock based on a GPS?  Turns out large LED displays are fairly hard to come by, and pretty expensive. Plus, all that wiring to all those pins is a pain.

Then it hit me: I have some TFT displays, not huge, but plenty adequate for inch or inch and a half high digits.  If I used the TFT, I wouldn't even have to build the board; I could use my serial graphics terminal board.

First step was to see if I could make huge letters without too much hassle (the largest font I have is only about 3/8" high).  The first whack isn't too bad. It will work, although I might yet do some prettying up of the font.

So, on to the GPS.

I started with my serial terminal code, which may have added more complexity than I needed, but it works.  This code fills a circular buffer with serial interrupts from the GPS and the mainline has to process the contents of the buffer. This makes missing characters less likely but it does mean the mainline is futzing with trying to understand whether there are characters in the buffer and identify the start and end of the GPS data.

Parsing the GPS data is tedious, but not especially difficult.  With the PIC32MX150F128B there is plenty of memory, so I can be pretty aggressive with my code.  Most of the code is the TFT library so the stuff I'm working on is pretty small anyway.

At this point I can get the time and coordinates (which I don't need).  I am displaying all sorts of values which eventually won't be used.

Next up is to get the date, and go through the tedious business of determining whether it is daylight savings or standard time. The correction is trivial but knowing when to apply it is a pain.

Following that I'll get after the PIC's real time clock calendar.  Supposedly the PIC can maintain the time to within a third of a second per month.  I'm not convinced can actually accomplish that, but adjusting it from time to time through the GPS should keep the time always correct.

Since even in the basement with overcast skies I can still see 8 to 11 satellites that might be overkill.  If I have too much trouble with the RTCC I might just skip that, but the next priority is the daylight savings time thing.

The code is currently partial, and pretty rough, but as always I keep everything in git and the current code is in gitlab:

The board hardware is at

And the TFT library code at

They will be updated as time goes on.

OK, so some code cleanup, and slightly larger digits, but still significant work to do:

The digits are actually a tan color, but it doesn't show in the picture.

And yet another little tweak.  After seeing the clock it occurred to me it would be a nice addition to the shack, too, providing it showed UTC as well as local.


 Time to get on to making cases, perhaps.

Sunday, July 16, 2017


It has been a long time since I wrote about the dsPIC-EL-GM. This thing has turned out to be a very successful tool for me.

Over the past couple of years, this has been the platform for dozens of projects.  In some cases the entire project was done on the board plus a shield. In others, it became the prototype for a purpose built board.

The choice of the dsPIC33EV was a good one.  Besides being 5 volts, meaning inexpensive displays work with it, it is fast, available in a variety of memory sizes (32-cheap, up to 256-huge), has a huge range of peripherals, and PPS.

The decision to put connectors for shields on the board turns out to be critical. Most projects need an LCD.  Hand wiring all those pins from the PIC to the display, plus power and programming (which I seemed to always get wrong) tended to present a barrier to starting new projects. With the shields I can just grab a shield and get started, and all the tedious stuff is behind me.

Plus, by having a standard part, standard display/LED/button pinouts, I have built up a number of libraries that make getting a project started easier and faster.

There are a couple of features that turn out not to have been so useful.  The jumper allowing me to use PIC24EV parts hasn't gotten used very much. I was attracted by the low price of some of those parts, but the 33EV32 isn't all that much more expensive, and it has more memory and way more speed.

Also, I had added a connector offset slightly from the shield connectors to allow me to plug in standard perfboards. But the extremely low cost of custom prototyping boards made that less useful. The demise of Radio Shack also shoved that feature into obscurity.  It was a significant advantage to be able to run down to the corner to get a perfboard. Now that it has to be mail order, I just keep an adequate supply of prototyping shields on hand.

I have been tempted to build another PIC-EL for one of the PIC32s. The PIC32MZ series offers blinding speed, crazy big memory, and even floating point. By having a flexible platform, the need for a DIP package is mitigated, and the price of the MZ, while not cheap, isn't really crazy. I had a lot of fun doing a graphics card with the PIC32MX250F128B, so I feel like the PIC32 isn't that alien of an animal.  But that is a project for another day.

I am not trying to sell dsPIC-ELs. However, needed information for building your own is available on gitlab:
  • Gerbers for the dsPIC-EL-GM are available here.
  • And for the proto shields here.
We did kit a few for the high school electronics club, which necessitated creating detailed construction instructions:
  • Build instructions here.
Should you build your own, let me know how you did in the comments below.

Saturday, January 14, 2017

Really ancient history

A long, long time ago, roughly around the time of the invention of the wheel, I did a series of lessons on 8-bit PICs. These lessons were very well received, downloaded thousands of times, and although aimed at hobbyists, many professionals also used them as an introduction to microcontrollers.

Craig Johnson made an experimenter's board to help with these lessons, which was originally kitted by the American QRP Club and later by Kanga U.S. Over the years this board underwent a couple of revisions, and is still available from Craig directly.

I have continued to get questions about these lessons, even though it is over a decade, and the target micro, the PIC16F84A, pretty long in the tooth.   Most of the more recent questions have to do with the development environment, which has changed pretty dramatically since MPLAB 6.

I finally broke down and decided to update a couple of the lessons, those that go into great detail about manipulating MPLAB.
Of course, I based them on MPLAB-X, rather than MPLAB 8.  MPLAB-X was pretty rough during the beta testing, but has evolved into quite a nice IDE. Reviewing these old MPLAB documents reminded me of just how much the environment has improved. I also updated the screenshots and some of the prose for Windows 10.  I don't use Windows much myself, but these days most people do, so it seemed to make sense.

The lessons are both available on gitlab in pdf; Lesson 3 which does some initial exploration of MPLAB-X which is available here, and Lesson 4 which explores the MPLAB-X simulator in some detail here.

 The only other lesson that is tempting is Lesson 11.  It goes into a lot of detail about manipulating a program called FPP, which is no longer available. The replacement, tho, hardly seems worth it.  On MPLAB-X with the PIC-EL III it reduces to "click this button".

So perhaps that will reduce the emails in the future.  In any event, it should make things easier for those who are finally getting around to doing Elmer 160.

Wednesday, December 7, 2016

Serial Graphics Terminal

It has been a while since I last posted here, and there have been a number of fun projects under the bridge.

One of the more fun, with more work still planned, is the development of a serial graphics terminal.

Most PIC projects use an LCD for a display. It is cheap and easy, but it has pretty limited real estate, and it uses a bunch of pins.  For quick little test projects, you often spend more time hooking up the LCD than you do on the rest of the project. Serial LCDs are expensive, and don't solve the problem.

More recently there have been some relatively inexpensive TFTs available. Fairly small 320x480 displays have tended to be among the least expensive, but they take even more pins than the LCDs, and quite a bit more code.

Suppose we could connect one of those things up to the serial interface.  That would allow a competent display with only one or two pins.  If we put a lot of smarts into the terminal, the performance might be decent, and we might even end up with a small software footprint on the host project.

Unfortunately, there are relatively few PICs available in 40 pin DIP, and those that are tend to be pretty slow or have limited memory.  I wanted a fast PIC with gobs of memory in a DIP package that I could prototype easily.

By using the MCP23S17 I/O expander, I could get enough I/O to handle a TFT, and selected the PIC32MX250F128B.  Turns out that the PIC32MX150F128B is the same for this purpose, and cheaper, but at the time I could get the 250 quicker.

So I breadboarded up the thing, mounted on my breadboard dsPIC-EL as a test host, and the thing worked.

I developed first text terminal code, then graphics terminal code, and decided that a custom PCB would be worthwhile.

The serial performance, even though limited by the I/O expanders, is quite good.  I developed a graphics library for the PIC32 that the terminal code builds on. The board is capable of the things you would hope such a terminal would do.

One of the things that is a real pain is drawing decent graphs.  All the piddling around in getting the axes and legends straight is a major hassle, so I decided to put a graphing feature into the PIC32 so that a small host application could draw decent graphs.

The TFT library makes it tempting to do projects directly on the TFT board. Unfortunately, there are only a few pins left (which are brought out to a connector), but a simple logic analyzer was irresistible:

Although the performance is quite good, and for most things, even with a serial connection, speed is not an issue, there is one place where the performance falls down, and it is a common one: drawing a continuously varying graph like a strip chart recorder.

A strange thing about this particular TFT controller is that it takes as many commands (and as much time) to fill a rectangle as it does to draw a pixel. When drawing lines at odd angles, like a graph, each pixel must be drawn individually. In this case, the MCP23S17, even though SPI is running at 10 MHz, simply can't keep up.

A large buffer in the PIC32 mitigates this problem for finite lines, if you want to continuously monitor a variable at some point you overflow the buffer.  Even with a huge buffer, at some point it fills.  I have done some experimenting with XON/XOFF, but this requires more complex code in the host.

The next step will be to prototype something with the PIC32MZ1024EFH100 (the 100 pin part is necessary to get all the pins in a single register). If the prototype can substantially improve performance, then I will look at a PCB for that part.

Again, I have no plans in marketing this, but everything needed is in GitLab. PCBs can be cheaply made and all parts, except the TFT, are available from DigiKey. The TFT is a SainSmart 20-011-918.

Project Components (all gitlab projects except document):

The following is a little video to give an idea of the performance of the serial terminal: