There are already three different PIC32 families stacking on each other. Each new family introduced major changes in the SPI modules. The first family relied on unbuffered SPI similar to old 8-bit microcontrollers, the second family introduced buffering, while the third family introduced I2S compatibility (aka Audio Mode).
November 2007 Microchip introduced the PIC32 MX3-4 families of 32-bit microcontrollers. They were designed to be pin to pin compatible and share the same peripherals set with the PIC24FxxGA0xx family of devices allowing the use of common libraries, software and hardware tools.
July 2009 Microchip introduced the PIC32 MX4-5-6 families that provide up to 128 kbytes of RAM and extensive connectivity options, including 10/100 Mbps Ethernet, two CAN2.0b controllers, USB Host, Device and OTG, and 6 UART, 5 I2C and 4 SPI ports.
December 2011 Microchip introduced the PIC32 MX1-2 families featuring two I2S interfaces for audio processing. Does it mean all previous families were unable to deal with audio?
First and second PIC32 families allowed 32-bit SPI frames consisting on 16-bit left audio followed by 16-bit right audio. Say the audio Codec is SPI master, configured for departing from the genuine I2S standard. Once configured in the so-called DSP mode, the audio Codec generates a short one bit wide frame-sync pulse of positive polarity, instead of the 50% duty cycle I2S left-right sync spanning over the whole frame. Provided you configure PIC32 SPI to wake-up on a positive slave-select pulse, as soon as the pulse gets issued by the audio Codec, PIC32 SPI hardware automatically starts grabbing the 32-bit frame originating from the audio Codec. The SPI_RX flag gets automatically set when the receive is complete. In a trivial audio DSP application, the background task may continuously poll the SPI_RX flag, and start processing the two new audio samples (left and right) as soon as the flag gets detected as set. In a more refined audio DSP application, there may be a solid background task like managing an USB communication for changing parameters. In such case you would configure SPI for generating an interrupt. The whole DSP would execute as a quite long SPI interrupt. Such scheme generates no software overhead thanks to the MIPS shadow register set. Use the main register set in the background task. Use the shadow register set in the SPI interrupt. In that respect, PIC32 is clearly superior to ARM Cortex.
Thus, any PIC32 first or second family is able to deal with digital audio. The only drawback of the above scheme is the 16-bit audio resolution.
A 24-bit audio resolution is theoretically feasible using 32-bit SPI frames on an audio Codec delivering 64-bit audio frame consisting of two 32-bit words each having 24 significant bits. The issue with such setup, is that PIC32 will only receive a frame-sync (to be considered as positive slave-select pulse) every 64 bits now. You thus need synthesizing the missing frame-sync, in the middle. You can use a GPIO. You would connect a PIC32 timer to it, or a PWM with a short duty cycle corresponding to the wanted pulse duration. At first glance, you need to mix such synthetic pulse with the real frame-sync originating from the audio Codec. This is going to cause trouble, as there can be jitter and overlaps possibly inducing false or double triggers. Also, you don’t want to use an external AND gate as mixer. A better solution is to only use the synthetic pulse, provided you periodically check that it remains phased with the genuine frame-sync. A pulse width measurement using a gated input counter may serve as monitoring. Clock may be as high as Fcpu/8. Need to read the result every two samples. That’s quite a small software overhead. You may have not realized, but the real software overhead is SPI interrupt occurring at Fs*2. This would nearly kill an ARM Cortex, especially if Fs equals 96 kHz, but thanks to the shadow register set, the PIC32 suffers almost no penalty. It is just a matter of adding a simple 2-state machine for knowing which audio channel to process when comes the SPI interrupt. This been said, one must carefully read the SPI datasheet for knowing the maximum bit clock. PIC32 SPI operating in slave mode, the maximum bit clock could equal Fcpu/8. If we are dealing with 96 kHz audio, knowing the audio Codec frame is 64-bit long, the SPI bitrate equals 6.144 MHz. We thus need Fcpu = 49.152 MHz. A 40 MHz chip may not fit. Only 80 MHz chips would fit.
In the above scheme, selecting a second family chip like PIC32 MX5-6-7 featuring buffered SPI may provide a small advantage like configuring the buffer for generating a half-full buffer interruption. The buffer would be 128-bit long. This is exactly what section 23.3.2.2 ENHANCED BUFFER MODE says in the PIC32 MX5-6-7 family manual. This way, during each half-full buffer interruption, we get two audio words processed in a row, the left audio word and the right audio word. Thanks to the buffered SPI, the DSP interrupt occurs at Fs, not at Fs*2. This is in the context of grabbing 24-bit audio in stereo.
Worth noting are the 100-pin versions of second PIC32 family like PIC32 MX5-6-7 featuring four SPI. Would be interesting to hook such chip on a WM8580 multichannel Codec. There are three SPI needed in slave mode for the audio as there are 2 audio inputs and 6 audio outputs. There is one SPI needed in master mode for accessing the control registers. Obviously, the three SPI-audio need to remain in sync, bit-for-bit. Not a difficult requirement as all three PIC32 SPI-audio are slaves.
December 2011 Microchip introduced the PIC32 MX1-2 families featuring two I2S interfaces for audio processing, a Charge Time Measurement Unit (CTMU) peripheral for adding mTouch capacitive touch buttons or advanced sensors, and the 8-bit Parallel Master Port (PMP) interface for graphics or external memory. The new devices also feature an on-chip 10-bit,1 Msps, 13-channel Analog-to-Digital Converter, as well as USB 2.0, and serial-communications peripherals. Further easing the design effort is a Peripheral Pin Select (PPS) feature, which allows configuring the actual chip pin layout.
With such third family incorporating an I2S modality within SPI (this is the Audio Mode), stereo 24-bit audio gets natively supported. No tweaks, no software overheads. You can connect any I2S audio Codec you want.
As illustration, let’s review all three different SPI incarnations basing on the SPI register map published in all three family datasheets.
PIC32 MX 1-2 feature buffered SPI with I2S compatibility. There are two SPI modules. Those are the most recent chips introduced December 2011.
The SPI registers are
- SPIxCON
- SPIxSTAT
- SPIxBUF
- SPIxBRG
- SPIxCON2
SPIxCON and SPIxSTAT remain compatible with the buffered SPI variants, apart from bit FRZ that’s not showing anymore. SPIxCON2 disables or enables the audio mode, and defines the audio mode modalities.



The PIC32MX1/MX2 starter kit (DM320013) has a PIC32MX2 and a WM8731 Codec on-board. Microchip delivers it with a small audio application written in C. The PIC32 sends digital audio to the WM8731, delivered to the heaphones mini-jack. For some reason Microchip has not connected the I2S input of the WM8731. As a consequence, The PIC32 cannot read audio data from the WM8731.
Here is the corresponding SPI initialization code.
void I2SInit(void)
{
UINT32 ReadData
LRCLK_PPS_SETUP
LRCLK_TRIS_SETUP
DAC_DATA_PPS_SETUP
DAC_DATA_TRIS_SETUP
WM8731Codec_MusicOn(FALSE) // Disable playing of music until it’s turned on.
// Setup I2S on SPI1
I2SCON = I2SCON2 = 0 // Reset settings
I2SSTATBITS.SPIROV = 1 // Clear overflow, if set
I2SSTAT = 0
ReadData = I2SBUF // Read any data
WM8731DRV_TX_XFER_DONE_INT_FLAG = 0 // Clear prior interrupts
WM8731DRV_TX_XFER_DONE_INT_PRIORITY = 4
WM8731DRV_TX_XFER_DONE_INT_SUB_PRIORITY = 0
WM8731DRV_TX_XFER_DONE_INT_ENABLE = 1 // Enable interrupts
IFS0bits.CS0IF = 0 // Clear interrupt flag for software
IPC0bits.CS0IP = 3 // FileReadISR priority < I2S priority
IPC0bits.CS0IS = 0 // Secondary priority = 0
I2SBRG = 0x0D // Set baud rate, not needed for slave
I2SCON = SPI_CONFIG_CKP_HIGH // Invert input SCK polarity
SPI_CONFIG_ENHBUF // Enhanced buffer enabled
I2SCONBITS.STXISEL = 0×2 // Interrupt when half empty
I2SCON2 = SPI_CONFIG2_AUDMOD_I2S // I2S mode
SPI_CONFIG2_IGNROV // Ignore receive overflow
SPI_CONFIG2_IGNTUR // Ignore transmit underrun
SPI_CONFIG2_AUDEN // Enable Audio Codec Support
SPI1BUF = 0 // Fill xmit buffer
SPI1BUF = 0
SPI1BUF = 0
SPI1BUF = 0
SPI1BUF = 0
SPI1BUF = 0
SPI1BUF = 0
SPI1BUF = 0
SPI1BUF = 0
I2SCONBITS.ON = 1 // Turn SPI1 on
assert( SPI1STATbits.SPITUR == 0 )
assert( (SPI1STAT & 0×100) != 0×100 )
I may have missed something in the above example as I don’t see where, after having enabled the Audio Mode, the bits MODE16 and MODE32 get configured for defining if we are in mono (in mono, both are zero), or if we are in stereo 16-bit, stereo 24-bit or stereo 32-bit. Form the above table, it is clear that if we want stereo 24-bit audio, MODE32 must be set and MODE16 must be reset.
We are done with the third family PIC32 SPI register map.
Let’s now represent the second family PIC32 SPI register map.
PIC32 MX 5-6-7 feature buffered SPI without I2S compatibility. There can be three or four SPI modules depending on the package pin count. Only three SPI for 64-pin devices. Introduced June 2009.
The SPI registers are
- SPIxCON
- SPIxSTAT
- SPIxBUF
- SPIxBRG
SPIxCON and SPIxSTAT remain compatible with the unbuffered SPI variants, but of course for activating the buffer feature you need to manage a few bits that remained unused in the PIC32 MX 3-4 family.

We are done with the second family PIC32 SPI register map.
Let’s now represent the first family PIC32 SPI register map.
PIC32 MX 3-4 feature unbuffered SPI without I2S compatibility. There can be one or two SPI modules depending on the chip reference. Those are the oldest, very first PIC32 chips introduced November 2007. Back in those times PIC32 strategy was to tell “hello, I’m the less intimidating 32-bit µC just in case you consider jumping on the 32-bit bandwagon”.
The SPI registers are
- SPIxCON
- SPIxSTAT
- SPIxBUF
- SPIxBRG

Now you have a clear understanding of all three PIC32 families (2007, 2009, 2011).
Now you realize that as soon as 2007 Microchip delivered more MHz, a faster 32×32 multiplier, and the shadow register set compared to ARM Cortex-M0.
The 2009 family aimed at responding to ARM Cortex-M3 invasion. There are M3 chips with more sophisticated peripherals, possibly running faster, but they are significantly more expensive than PIC32 MX5-6-7 and still not featuring the shadow register set.
The 2011 family aimed at responding to the ARM Cortex-M4 invasion. Not a not a face-to-face competition as most M4 run faster, but a price-based competition on low-end M4. You can’t find M4 chips low priced like PIC32 MX1-2. And still PIC32 MX1-2 provides the shadow register set that’s not part of M4 design. And still PIC32 MX1-2 provides the twin I2S that no low-end M4 has.
What’s next PIC32 family ?
Would be nice to have PIC32 MX1-2 featuring four I2S, even in 28-pin and 44-pin packages.
- February 2010, Microchip acquired SST (Silicon Storage Technology), a company owning the intellectual rights concerning an inexpensive Flash memory process already in use in several 130 nanometer designs.
- October 2010, Microchip licenced the MIPS32 M14k family of cores from MIPS, which is a superset of the M4k family of cores from MIPS having enabled PIC32 in 2007.
- It may be necessary to decouple the CPU silicon process from the Flash memory silicon process. The example is coming from NXP LPC4330 Cortex-M4 featuring no internal Flash. You need to hook an external quad-lane Serial Flash. Upon booting, you need to copy the program code to RAM, then run it from RAM at full speed. As drawback, the executable code gets publicly exposed at boot unless the quad-lane Serial Flash content gets encrypted. Check the NGX Technologies LPC4330 Xplorer, a nice LPC4330 carrierboard priced $57.
- T.I. is already producing 65 nanometer LM4F ARM Cortex-M4 chips, not allowing the 200 MHz speed you would expect from such design rule, possibly because of a Flash speed bottleneck, possibly because of a particular area-optimized CPU and FPU implementation.
- It is said that Microchip gained access to a 65 nanometer fab.
- October 2010 Jiāngnán Computing Lab unveiled the SW1600 Microprocessor, a 65 nanometer 64-bit 16-core four-issue superscalar, 7-stage integer pipeline and 10-stage floating-point RISC designed and etched in China, running at 1.1 GHz. This is what you get, exploiting a said-to-be outdated 65 nanometer fab.
Those are the facts. Your brain may sketch the close future.




June 1st, 2012 on 2:16 PM
Hi,
Really interesting blog here, and great research and analysis of the PIC32 series for audio (and other options)!
There are 2 things that stick in my mind as being very interesting, in terms of quick prototyping setups for audio with the PIC32:
1) a PIC32MX2, even just in the DIP package on a breadboard for testing purposes, along with 1 or 2 of the mikroE CODEC boards ( http://www.mikroe.com/eng/products/view/484/audio-codec-board-proto/ ) would be pretty powerful for many applications. Natch, max channels = 4 in / 4 out, since the MX2 has 2 I2S peripherals…
2) any of the PIC32 series could probably function as a USB-host for a CM6206-based USB soundcard (which are available for around $20: http://www.dealextreme.com/p/usb-2-0-7-1-audio-8-channel-3d-external-sound-box-42470 ). I’m considering trying this approach with my CUI32Stem:
http://www.seeedstudio.com/depot/cui32stem-p-1100.html?cPath=132_208
Do you plan on trying either of these approaches yourself? If so, will you be posting code examples?
Cheers,
Dan
June 3rd, 2012 on 12:08 PM
For applications requiring more than 4 channels you can try the PIC32MX7 way using 16-bit audio in 32-bit SPI slave frames just like the DM320011 does for a single SPI. All four PIC32MX7 SPI would feed the WM8581 with 16-bit audio data. The PIC32MX7 I2C would feed the WM8581 with control data. This enables 8 channels and no software overhead. The corresponding PIC32 code just got exposed and commented in another post. Please search “DM320011″ on electrodesigns.net.
Is it worth issuing a PCB hosting a WM8580 (WM8581) superseding the mikroE WM8731 Audio Board-Proto? Is there a market currently? Would be nice that you tell us more about the applications.
The other approach consisting of a PIC32 USB-host talking to a CM6206 is elegant, in a 16-bit audio context. Currently I found no info like an USB log, grabbing the USB transactions occurring when a CM6206 gets hooked on a PC. The Linux-Android geeks have done it, I guess. We may investigate this shortly.
June 5th, 2012 on 1:54 AM
There are so many applications that it’s hard to pick a place to start!
One that comes to mind would be separating surround-sound speakers from ‘locked’ positioning around the room, for example using higher-order Ambisonics, sending the encoded signals around to all speakers and then having a way to setup each speaker so that it knows which part of the soundfield it should reproduce. This is a bit of a ‘chicken and the egg’ problem, though, since it’d ideally mean that Ambisonic-encoded source material would be available as recordings to purchase…
Another application that I’ve personally looked into a bit is for hybrid acoustic-electronic instruments, for example a violin that can have (through DSP) different ‘bodies’ depending on the processing. See this research for one example:
http://www.mt.haw-hamburg.de/home/mores/paper/ICMC_2010_NY_VirtVio.pdf
September 4th, 2012 on 8:48 PM
Thnx dude, that was useful
Keep it up
April 12th, 2013 on 5:45 PM
Small correction to the post: PIC32MX1/MX2 do not have shadow register sets. Also, due to architectural inefficiencies, even with SRS, the interrupt latency of current PIC32s is longer than Cortex-M3/M4. Future PIC32s that implement the MCU ASE should improve this, though it’s worth keeping in mind that the Cortex 12 cycle latency gives you nested interrupt handlers written in C at no extra cost, and the MIPS core will not be able to match this.