Skip to main content

FORTHdsPIC goes Dual-Core: Part 3

Fig 1 dsPIC33CH Mailbox Communication

The dsPIC33CH Master-Slave Interface hardware set up to provide eight 16-bit ‘mailboxes’ in each direction. The red-outlined boxes have been configured as Protocol mailboxes. In automatic mode, writing data to one of them triggers the handshaking exchange between Master and Slave, and if it’s successful causes the receiving processor to read the data sent to the mailbox(es) by the transmitter.

Mailbox communication

Last time in Part 2, I described the software needed to get both Master and Slave processors of the Microchip dsPIC33CH up and running programs. A new word was added to the FORTHdsPIC vocabulary: LSLAVE which takes two parameters, the address in Master Flash memory where the Slave app is held, and an app ID code. The next item on the agenda is inter-processor communication via the MSI (Master-Slave Interface) ‘mailbox’ hardware. Most applications for multi-core processors will require those cores to exchange data: especially in real-time, embedded systems. Communication may only need to be one-way. For example, I’m working on a project which requires spectral analysis of a sampled analogue signal. It’s a good fit with the dsPIC33CH hardware because of Microchip’s decision to use a dual-processor format; each with its own (nearly) independent clock circuits, program/data memory and peripheral support modules (ADCs, Timers, etc.). My project will use the Slave processor to capture data via an ADC, process it with a Fast Fourier Transform algorithm (FFT), and then send the resulting frequency samples to the Master for display via the MSI mailboxes.

All processors are not equal

The processors in the dsPIC are definitely not ‘equal’, neither in speed nor distribution of peripherals. Microchip refers to them as Master and Slave, but that description is deceptive:

Master and Slave Differences

For a start, the Slave is faster, and it has independent control of a wider selection of peripheral modules. On the other hand, it depends on the Master to load its program RAM on power-up reset, and set it running. The Master software to do this was the subject of the Part 2 article. The latter introduced the Forth word LSLAVE which takes as a parameter the absolute address of a Slave program stored in the Master’s Flash memory. LSLAVE then loads the code located there into the Slave’s Program memory (PRAM) and enables it to run.

Configuring the Mailboxes: Registers FMBXM, FMBXHSx and FMBXHSEN

Each of the 16 mailboxes can be configured for Master to Slave (M2S) or Slave to Master (S2M) operation. All can be set for transmission in the same direction or any combination of either. For the purposes of this example, I decided to use MBX0 to 7 for M2S, and MBX8 to 15 for S2M. See Fig.1 above. All the bits (MBXM0 to 7) of configuration register FMBXM were set accordingly. Next, protocols for the reliable exchange of data between the Master and Slave processors were enabled. I should say at this point, that the words ‘transmitter’ and ‘receiver’ will usually be used instead of Master and Slave in the discussion of mailbox protocols, because the two processors can both operate in either mode. The purpose of a protocol is to ensure that data is only sent to mailboxes for transmission when a) there is no outstanding data in the mailboxes as yet unread by the receiver, and b) the receiver is ready to read new data from the transmitter.

Enabling a protocol involves ‘attaching’ it to a mailbox by setting the appropriate bit in configuration registers FMBXHS1 or FMBXHS2. Because there are just two groups of mailboxes in this example, only two protocols are required; Protocol A for the M2S group, and Protocol B for S2M. Only one mailbox in each group needs to have the protocol attached. Up to eight protocols (A – H) are available. The handshaking exchange for each protocol is enabled by setting the appropriate bits in configuration register FMBXHSEN.

Hardware or Software protocol?

A protocol involves an exchange of ‘handshaking’ signals which if successful, allows the receiver software to read new mailbox data deposited there by the transmitter. There are two ways of controlling this ‘conversation’: using on-chip hardware (automatic with interrupts) or user-software (polling).

Automatic data transfer

To activate automatic handshaking, all you need do is set the chosen protocol’s Interrupt Enable flag on the receiving processor. For protocol A, the line of assembler-code is: bset IEC8,#MSIAIE. The interrupt causes a jump to an interrupt service routine (ISR) which reads the protocol A mailboxes. The interrupt is generated by a successful handshaking exchange triggered when the transmitting processor writes data to the protocol A mailbox MSI1MBX7D, in the case of M2S, or protocol B mailbox SI1MBX15D, in the case of S2M. So, when sending data via a group of mailboxes, the protocol box, in this case MSI1MBX7D, must be written to last, as that action triggers the handshake process with the receiver. (Fig.2)

Fig 2 Master to Slave Transmission

One situation the automatic system can’t cope with is when the receiver hasn’t read its mailboxes by the time the transmitter sends more data. In other words, data can be lost. To prevent this, the processors have data transfer status registers, MSI1MBXS (Master) and SI1MBXS (Slave) with new mailbox data available flag bits for each protocol – DTRDYA to H. Physically, it’s a single read-only register, where a flag bit is set by a write to a protocol mailbox by the transmitter, and cleared by a read from the corresponding receiver mailbox. For the configuration shown in Fig.1, a write to mailbox MSI1MBX7D sets DTRDYA in MSI1MBXS and SI1MBXS as well as starting the handshake process. Now both transmitter and receiver software can read this flag. To the transmitter, it means that the receiver has not (yet) read the last data that was sent. The first two lines of both the Master and Slave’s transmit routines, MTRSND and SLVSND, pause operation if the previous flag has not been cleared by the receiver.


Code 1. MSI Master software subroutines: Auto-handshaking (interrupt) version. MTRSND is for transmission, MTRREC for reception. Slave subroutines SLVSND and SLVREC are identical except for the register names and swapped protocol references.

Software data transfer (Polling)

Automatic handshaking based on the use of interrupts works very well in applications without rigid timing requirements. Unfortunately, most embedded real-time systems operate with regular, accurately timed acquisition of data. The ‘advantage’ of unrestrained interrupt operation is that an urgent event can force a processor to run an interrupt service routine whenever it likes. That’s incompatible with a need for rigid timing. If you examine the flow chart (Fig.2) and corresponding code (Code 1), it should be obvious that I’ve ensured the MSI Interrupt Enable is only set in the receiver code itself – that is when the receiving processor’s app is ready to receive new data from the other processor. It means that the transmitter is stalled because its interrupt request is not acknowledged until the receiver subroutine executes. To some extent, this renders the use of an interrupt somewhat pointless, but it does eliminate the timing problem while allowing the fast on-chip hardware handshaking to be used. It is possible to drive the handshaking in full ‘manual’ mode however, and I’ve supplied example code in Code 2, together with an explanatory flowchart (Fig.3).

Fig 3 Master Slave - Polling

Code 2

Code 2. MSI Master software subroutines: Soft-handshaking (polling) version. MTRSND is for transmission, MTRREC for reception. Slave subroutines SLVSND and SLVREC are identical except for the register names and swapped protocol references.

New Words for FORTHdsPIC

I decided to use the limited interrupt system described above for my embedded FORTH system and created two new words MSND and MREC. The code for these differs from the Code 1 example in three ways:

  • MSND assumes that eight data items have been pushed onto the parameter stack.
  • MREC exits with eight received items on the stack.
  • The subroutine ‘return’ codes are replaced by the Forth link statement ‘bra NEXT’.

It must be remembered that Slave apps are written in dsPIC assembler code and will include the Slave equivalent of the subroutines shown in Code 1. This is not the end of the story though, because Microchip have included FIFO buffer operation and even DMA transfer on this chip for really efficient working. A project for the future, perhaps.

Master and Slave test programs for both handshaking versions are available in the Downloads section, as is the FORTHdsPIC code for MSND and MREC.

Essential Reading

Microchip dsPIC33CH MSI manual: Master Slave Interface (MSI) Module

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.

Engineer, PhD, lecturer, freelance technical writer, blogger & tweeter interested in robots, AI, planetary explorers and all things electronic. STEM ambassador. Designed, built and programmed my first microcomputer in 1976. Still learning, still building, still coding today.
DesignSpark Electrical Logolinkedin