How do you feel about this article? Help us to provide better content for you.
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
What do you think of this article?
The Microchip Curiosity demo board for the dsPIC33CH dual-core microcontroller shown running a test program from the Microchip Developer website. It’s not very exciting; just turning on the two red LEDs to signal a successful exchange of data words between the two cores using the mailbox system.
It was inevitable that someday I’d seek to port my embedded FORTH platform, FORTHdsPIC, to the latest version of the Microchip dsPIC microcontroller range. It would also provide the opportunity to explore dual-core operation with the dsPIC33CH part.
Curiosity development board
It’s a shame MikroElektronika haven’t yet produced a dsPIC33CH version of their Clicker 2 series of development boards. With a compact size, multiplicity of power supply options and mikroBUS expansion sockets it’s ideal for prototyping embedded projects. The full-blown Explorer kitwith interchangeable processor PIM modules is recommended on the Microchip developer website. But the cheapest option is the Curiosity board featuring the 512KB Flash part. Like a Clicker 2, it features two MikroBUS connectors for Click expansion boards. Unfortunately, the power supply options don’t include a Li-Ion battery interface and charger. It does have a UART-USB bridge circuit though, eliminating the need for a separate Click module to provide FORTHdsPIC’s console connection to a PC. Another plus is the on-board programming/debug tool PKOB (PICkit On-Board).
I’ve done this sort of upgrade before when I moved FORTHdsPIC from an ‘F’ part to the dsPIC33E version: two blog posts here and here covered that transition. It should have been easy, on the assumption that the new chip would be backward compatible with the current version of my firmware. Some of the irritating incompatibilities encountered are documented in those two posts along with the revelation that increasing the clock rate from 40 to 70MHz did not yield a corresponding improvement in Forth code execution speed! So, I approached the ‘upgrade’ from ‘E’ to ‘C’ with some trepidation.
The PKOB eliminated the need for an external programmer/debug module and with a short USB cable plugged into my laptop running Microchip’s MPLAB X IDE, I was ready to go. Icing on the cake was the on-board UART-USB bridge hardware; so, with the addition of a further USB cable linking to Tera Term terminal emulation software, FORTHdsPIC would have its operator console. But before its power-up message could appear, the source code for the firmware required to be modified and re-compiled starting with the processor clock initialisation.
Moving the clocks forward
Years ago, developers working on a design for an embedded system didn’t have to waste much time on the MCU’s clock. An old 8-bit Intel 8051, for example, needed a 6.144MHz* crystal and a couple of picofarad capacitors to be attached on two pins, and that was the processor clock sorted. The external crystal defined the maximum frequency present, with instructions taking 12 or 24 cycles to execute. Nowadays, frequencies are much higher and there are multiple internal, external and backup options to be considered. The Slave core in the dsPIC is capable of executing 100million instructions per second (100MIPS) and even though most instructions only need two clock cycles that still leaves a clock frequency of 200MHz. A crystal oscillator trying to run at that rate is going to be pretty unstable – if it works at all. The Curiosity’s chip is provided with a much more reasonable 8MHz crystal. To get to a stable 200MHz we use a frequency multiplying circuit known as a Phase-Lock Loop (PLL). This is set up by programming the device’s configuration and oscillator control registers to yield a system clock of 800MHz which is then divided back down to 200MHz. Incidentally, the datasheets of most modern processor chips, including the dsPIC, boast about their ‘single-cycle instructions’. Clearly, that doesn’t refer, in this case, to the crystal frequency (8MHz), or the internal system oscillator (800MHz), or even the system clock (200MHz). The 100MIPS figure implies a clock frequency of only 100MHz, so when they say ‘single-cycle’, it refers to this Machine cycle time as the time it takes to fetch and execute a single instruction.
For the previous ‘F’ and ‘E’ versions of the FORTHdsPIC firmware, I just configured the clock circuit so that when the processor came out of Reset, the external crystal clock (XT) was started with the PLL. The code monitored a LOCK bit in the OSCCON register until it indicated that the PLL was stable and ‘locked’ before continuing with the rest of the initialising routine. This arrangement was fine for the F part but a little flaky on the E; failing occasionally to restart after a software reset. Things became a whole lot worse with the C version and I decided to look more closely at the clock initialisation code. The solution was to do what I should have done all along:
- Power-up with an internal oscillator (FRC).
- Select XT as the new clock source by setting bits in OSCCON.
- Trigger a switch to XT by setting OSWEN in the OSCCON.
- Wait for OSWEN to go low indicating switch complete.
- Wait for LOCK in OSCCON to go high indicating clock frequency stable.
What a rigmarole, particularly as steps 2 and 3 required sending security unlock codes to OSCCON before bits could be changed. But it was worth it – smooth reliable restarts from power-up reset, software reset and manual button reset. Before the above could be tested, the console UART code had to be modified to suit the new pin configuration and clock frequency. Once that was done, I could power-up the board, get the familiar ‘hello’ message and run Forth code: except that is for those words requiring yet-to-be-reconfigured hardware such as Timers.
*In case you’re wondering why we used such an odd frequency as 6.144MHz for an MCU clock, it’s because it divides down nicely to the ‘standard’ UART baud rates of 300, 600, 1200, …..19200!
Is the C a lot faster than the E?
At this point, I decided to get the User Timer working so that I could run benchmark timing tests and see if they fully reflected the increase in clock speed from the 70MHz E part. The ‘new’ clock speed relevant here is 90MHz because this is the rate for the Master core which activates on power-up. The results (Table 1.) indicate an across-the-board improvement in speed of about 29% which corresponds exactly to the clock speed change from 70 to 90MHz. The Slave running at 100MHz should be even better – nearly 43% faster. For more info on Forth benchmarking see the FORTHdsPIC project page.
While perusing the instruction set summary, something caught my eye: the divide instruction DIV now only requires 6 cycles to execute, reduced from the previous 18. That means a total improvement of over 60% for maths benchmarks BM15 and BM16. Now that’s more like it!
Software development for a two-processor device
It is possible to ignore the Slave processor in the CH device because, from power-up reset, only the Master can boot-up from code in Flash program memory. That code includes a boot-loader to transfer a program from Master Flash into Slave PRAM and starting it running. All device pin functions also default to the Master. Code development in this situation is obviously rather more complicated than usual. Fortunately, Microchip do provide development tools to make programming and debugging of a twin-core chip easier.
- MPLAB X IDE
- MPLAB Code Configurator
- XC16 C compiler and assembler
All of these can be downloaded free-of-charge from their website. Once installed, the Code Configurator is accessed from a button on the IDE main page. The basic development sequence is as follows:
- Using MPLAB IDE create a project called ‘Master’. Set it up to use, in this case, the device dsPIC33CH512MP508.
- Using MPLAB IDE create a project called ‘Slave’. Set it up to use device dsPIC33CH512MP508S1.
- Launch Code Configurator (MCC) which will create the initialisation program in C source code using parameters typed in by the user. In theory, all the user has to do is paste their application C code into the Master and Slave main.c files, then hit the Make and Program device button while the Master project is selected. MCC builds a Master executable file that contains both the Master and Slave code, including configuration settings and the routines to transfer the Slave code to the PRAM and set the whole lot running.
The Microchip Developer site has a step-by-step guide to programming a very simple application which demonstrates the use of the ‘Mailbox’ inter-processor link system.
If the two processors ran their respective programs completely independently, with no exchange of data between them, then coding this device is fairly straightforward. But if they were that unconnected then it might be better to use two separate single-core chips in the first place. The real challenge with multi-core communication lies with the fact the cores are not perfectly synchronised with each other, This leads to communication channels with very complex handshaking controls to ensure no data is corrupted or ‘lost in transmission’. Look at the code in the step-by-step example for exchanging a single 16-bit word of data back and forth between Master and Slave with each side turning on an LED to indicate that reception was successful (See heading photo). The manual for programming the Master Slave Interface alone is 50 pages long…. And I’ll be using assembler code not C (gulp).
The all-important bootloader code that transfers Slave code from the Master Flash memory to the Slave PRAM and starts both processors running. An added feature allows for on-the-fly selection from sixteen alternative Slave programs stored in Flash while under Master program control.
If you're stuck for something to do, follow my posts on Twitter. I link to interesting articles on new electronics and related technologies, retweeting posts I spot about robots, space exploration and other issues. To see my back catalogue of recent DesignSpark blog posts type “billsblog” into the Search box above.