Sunday, May 13, 2012

How to implement hardware-only SIR (Slow IrDA) on a Microchip PIC16 MCU using Data Signal Modulator (DSM)

In one of my projects (actually, in HDD POV clock v.2) I had to transfer data wirelessly over a distance about 7cm (~3"). After some research I was pointed to IrDA protocol and I was told this is the best option and I shouldn't be inventing a bicycle. Indeed if I had an IrDA transceiver, I would be totally OK. But I didn't and I couldn't find any available within easy reach. reasonable time and for a reasonable price. Those things are pretty obsolete by now you know.
While searching I also figured out that STM8 MCUs have SIR built into UART, but I had to stick to PIC16F1827... So, what do I do?


After reading a bit about how SIR signal looks like I immediately noticed a few things:

  • SIR is inverted in respect to UART. Means when UART is high, SIR is low
  • SIR pulse has different timing - it's about 3/16 of the UART pulse length
  • Worst of all - SIR is an RTZ (return-to-zero) signal. Means that if UART sends for example three consecutive zeroes by just staying low for three pulse lengths, SIR emits three short impulses. No good, this means I can't just play with an inverter and capacitor and few resistors. Or, let's it put this way, I don't know how to deal with it. I guess if one is smart enough he could build a SIR encoder with one NE555, but I'm simply not.
Ok, let's have a look at the signal:

UART and SIR timing diagram
Yes, I forgot one more thing - SIR output is time-shifted in respect to UART input - it's delayed by about 13/32 of the UART bit length. I just kept looking at it and asking myself - WHY? WHY there's a delay? What's the point in it? And I just didn't find any answer. So, probably, being totally wrong, I discarded the delay. Simply because I don't like it. Here's what I've got:
Getting rid of delay when converting UART to SIR

OK, better.
Now, the signal really looks like:

  • periodic pulses with period of 1 UART bit and a duty cycle of 3/16 when UART signal is low (1)
  • low, when UART signal is high (2)
Luckily, that was the first time I was using pic16f1827 and for this reason was paying a closer than ever attention to datasheet. DSM (data signal modulator) took my attention and when I understood what is that, I knew I can play with registers and have the satisfy the above conditions.
What DSM does, it simply modulates your signal by another signal. And it can take quite a few signal as modulation source:
MDMS<3:0> Modulation Source Selection bits
1111 = Reserved. No channel connected.
1110 = Reserved. No channel connected.
1101 = Reserved. No channel connected.
1100 = Reserved. No channel connected.
1011 = Reserved. No channel connected.
1010 = EUSART TX output
1001 = MSSP2 SDOx output
1000 = MSSP1 SDOx output
0111 = Comparator2 output
0110 = Comparator1 output
0101 = CCP4 output (PWM Output mode only)
0100 = CCP3 output (PWM Output mode only)
0011 = CCP2 output (PWM Output mode only)
0010 = CCP1 output (PWM Output mode only)
0001 = MDMIN port pin
0000 = MDBIT bit of MDCON register is modulation source
And also a few (less of course) signals as modulators:
MDCH<3:0> Modulator Data High Carrier Selection bits (1)
1111 = Reserved. No channel connected.
•
•
•
1000 = Reserved. No channel connected.
0111 = CCP4 output (PWM Output mode only)
0110 = CCP3 output (PWM Output mode only)
0101 = CCP2 output (PWM Output mode only)
0100 = CCP1 output (PWM Output mode only)
0011 = Reference Clock module signal
0010 = MDCIN2 port pin
0001 = MDCIN1 port pin
0000 = VSS
Notice that EUSART pin can be selected as modulation source. What I'm going to do, I will take EUSART signal and modulate it with PWM:
UART, Modulation, Modulators and SIR
And that's almost exactly what we need. The only thing left is to make sure we've got beautiful uncut 3/16 pulses when UART goes low. That's simple after you spend an hour looking at the following graph from the datasheet:
Green waveform is what we want - so full synchronization is the way to go!
We need exact number of uncut pulses, so we fully synchronize our carriers and modulation. And there you have it - SIR output on MDOUT pin of MCU. Just a few picture from a real device:
Here blue is our PWM and purple is UART with inverted polarity (which is absolutely not necessary as polarity can be changed in DSM for every signal both input and output).
And the result:
Purple is the same inverted UART and blue is our SIR signal on MDOUT. 
Great, problem solved. Let's just play a bit more with this to have the complete HW and SW solution. Imaging you need to use the same HW and firmware with either SIR or UART - in different installations. If you switch on UART - it will show up on TX pin. If you switch on DSM - it will show on MDOUT pin. What if you need to bring the signal out on the same pin of your PCB without using jumpers or stuff like this?
Ok, let's define a macros in firmware SIR_OPERATION. If we have this macros defined we will bring MDOUT to the PCB signal_out pin, if else - we'll bring TX signal there. We'll design PCB with TX and MD out connected. If we go for SIR, we'll configure TX pin as high-impedance input and forward SIR output to MDOUT. Else, we'll configure TX as UART output and MDOUT as high-impedance input.

//setting up serial
SPBRG = 16;
BRGH = 1;
BRG16 = 1;
SYNC = 0;
SPEN = 1;
TXEN = 1;

#ifdef SIR_OPERATION

#else

TRISB2 = 1; //TX as input
TRISB3 = 0; //MDOUT as output

T6CON = 0b00000100; /*setting PWM as Carrier LOW*/
PR6 = 16;

CCPTMRSbits.C3TSEL = 0b10; //TMR6 for CCP3
CCPR3L = 3;
CCP3CON = 0b00011100;

MDCON = 0b11001000; //setting up DSM module
MDSRC = 0b10001010;
MDCARH = 0xFF;
MDCARL = 0b10100110;

TRISB2 = 0; //TX as output
TRISB3 = 1; //MDOUT as input
Lastly: I almost managed to get HW SIR decoder running on the same principle. However by design this seems to be not possible. I will not go into details, but here's an illustration from the real system:

DSM-encoded, DSM-decoded SIR signal sent over wire. Notice the blue spike.
Purple is what we were sending from UART, blue is the result of signal encoding, sending it over WIRE (not IR - for test purposes) and decoding with DSM. you can see the blue spike - it is not possible to get rid of it as falling edge of the signal is used as synchronization. Take it away and you will have no signal at all. 

No comments: