Loving the Ever Versatile PSoC
Around the office I’m known for my adoration of Cypress’ Programmable System-on-Chip (PSoC) series of microcontrollers. I’ve used them in a few personal and client projects and each time I’m thrilled by the ease of setup and sheer adaptability they offer. In architecture brainstorms or during part selection I’m guaranteed to enthusiastically suggest “throwing a PSoC in there!” The rest of this post illustrates why.
A PSoC isn’t like a normal micro controller, it’s much more awesome.
Oh sure, it has a CPU core and you can get a C compiler for it, but instead of a particular set of pre-specified hardware peripherals it comes with a big bundle of reconfigurable logic. It’s like having an ARM Cortex-M0/M3 (depending on product line) and an FPGA in one package with no special programmer required and a free IDE.
In a personal project I’m working on I need to send data over infrared between devices. I decided to crib from the Philips-RC5 protocol and use Manchester Encoding to do so, which is a nifty method for blending clock and data pulses together into a single signal in a recoverable way. In my system the sender will generate an SPI-style clock and data stream, encode it, then blast it out through an IR LED (modulating each ‘high’ bit at 38kHz). The receiver will ‘see’ the pulse train, convert the 38kHz pulses back to stable logic levels, decode that, and do an SPI receive to read the data.
There are plenty of examples of doing this with traditional microcontrollers, but the PSoC offers a better way.
To allow the developer to describe the hardware configuration they want the PSoC to take, the IDE comes with a ’schematic editor’ which should look fairly familiar to anyone who’s, well, read a circuit schematic! This is the one I created to encode and decode data:
I’m not the first person to think of this (for example there is this Cypress Blog Post) but the technique is so convenient and illustrative it’s worth sharing.
To Transmit (Lower Right)
- Encoding the outgoing signal requires XORing together the data and clock edges of an SPI transmitter. In PSoC land this is accomplished by… wiring an XOR gate to those pins of an SPI peripheral!
- To reduce interference from ambient infrared light the receiver I’m using has a bandpass filter at about 38kHz, so I need to modulate my outgoing signal (IR light from the LEDs) at that frequency. Again, with a PSoC this is trivial. I direct the output I/O pin (IRLED1) to couple a clock (out_clk) to its output, then enable and disable it with the signal I want to send. So when I assert the output line it automatically clocks out clock pulses. This is directly attached to the driving circuitry for the IR LEDs.
That’s it! Encoding is pretty straightforward.
To Receive (Upper Left)
The data from the IR receiver (a Vishay TSOP6238TT) enters at IR_Receiver and is inverted with a NAND gate before being decoded. The receiver handles converting the incoming 38kHz pulses into a normal series of bits and spaces.
- To separate the clock from the data, on every rising edge of the recovered clock the CPU needs to wait 3/4 of a bit period then take a sample. This is illustrated in the figure below (again from the Cypress Blog Post). On the PSoC we can use a PWM block to generate the delay. It’s a little complex to describe so I recommend referring to the Cypress post for more detail.
- The rising edge of the PWM is used to clock a D Flip Flop in order to stash the value of the incoming data. It’s Q terminal produces the recovered data stream RX Data.
- To extract the clock from the incoming signal, it needs to be XORed with the data. Now that we have the RX Data this is trivially accomplished with another XOR gate.
There are a few other things going on on the receiving side.
- The Pix_rx_decoded_[clk/data] pins are lines that I added in order to attach a logic analyzer. Because the PSoC allows you to more or less arbitrarily reconfigure digital I/O pins, with a couple test points on a board the developer gains the ability to tap into any point in the logic of their design! At the time of this screenshot I was verifying my decoder worked properly.
- The IRDataIncomingInter in an interrupt which is part of an experiment in how to alert the CPU that there was incoming data.
Of course there are other ways to transmit and receive Manchester Encoded data. Most of the ones I found were designed for Arduinos and required the use of AVR assembly and very precise timing, making those systems difficult to use for much more than receiving the data itself! But doing it in hardware without CPU intervention highlights the unique convenience of the PSoC. To get started, try one of Cypress’ low cost development boards (links below).