/******************************************************************************
*                       Software License Agreement                            *
*                                                                             *
*   The software supplied herewith by Microchip Technology Incorporated       *
*   (the "Company") for its dsPIC controller is intended and supplied to      *
*   you, the Company's customer, for use solely and exclusively on            *
*   Microchip dsPIC products. The software is owned by the Company and/or     *
*   its supplier, and is protected under applicable copyright laws. All       *
*   rights are reserved. Any use in violation of the foregoing                *
*   restrictions may subject the user to criminal sanctions under             *
*   applicable laws, as well as to civil liability for the breach of the      *
*   terms and conditions of this license.                                     *
*                                                                             *
*   THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION.  NO WARRANTIES,        *
*   WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO,     *
*   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        *
*   PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, IN ANY             *
*   CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR CONSEQUENTIAL         *
*   DAMAGES, FOR ANY REASON WHATSOEVER.                                       *
*                                                                             *
*******************************************************************************
*                                                                             *
*   Decode manchester coded data from an Input Capture interrupt routine      *
*   and output the decoded text to the UART.                                  *
*                                                                             *
******************************************************************************/

#include "p30F6014.h"
#include "stdio.h"

unsigned int DataBuffer[32];
unsigned int *InBufferPointer,*OutBufferPointer;
unsigned int PreviousCapture,NewCapture,TimeDifference;
unsigned int BitTimeThreshold = 75;
unsigned int BitValue = 0, HalfBit = 1;
unsigned int DataWord,DataMask;

int main (void)
{
    InBufferPointer = &DataBuffer[0];        //Initialize buffer pointers
    OutBufferPointer = &DataBuffer[0];

    IC1CON = 0x0081;                         //Set up Input Capture 1
    T2CON = 0x8000;                          //Set up Timer 2

    IFS0bits.IC1IF = 0;                      //Clear IC1 interrupt flag
    IEC0bits.IC1IE = 1;                      //Enable IC1 interrupt

    U1BRG = 0;
    U1MODE = 0x8000;                         //Enable UART and disable auto baud detection
    U1STA = 0x0400;                          //Enable transmission

    while(InBufferPointer == OutBufferPointer){} //Wait for first data byte
    PreviousCapture = *(OutBufferPointer++); //Save data to have previous data to subtract for difference
    DataMask = 0x0100;                       //Initialize mask to shift in data bits

    while(1)                                 //Loop forever receiving and decoding data
    {    
        while(InBufferPointer != OutBufferPointer) //Keep decoding as long as there is incoming data
        {
            NewCapture = *(OutBufferPointer++);    //Get new data
            TimeDifference = NewCapture - PreviousCapture; //Subtract previous time to get difference
            PreviousCapture = NewCapture;          //Save data as next previous value
            if(OutBufferPointer > &DataBuffer[31]) //Check if reached end of buffer
                OutBufferPointer = &DataBuffer[0]; //If so then wrap to beginning
            if(TimeDifference > BitTimeThreshold)  //Check if time is more than 1.5 bit periods
            {                                      //If time more than 1.5 bit periods:
                BitValue ^= 1;                     //Toggle bit value because 2 bit periods indicates a change
                BitTimeThreshold = (TimeDifference * 3) >> 2; //Calculate new 1.5 bit time threshold
                if(BitValue)                       //Save incoming bit that was decoded
                    DataWord |= DataMask;
                if(DataMask == 0)                  //Check if reached end of byte
                {
                    U1TXREG = DataWord;            //Transmit new byte out USART
                    DataMask = 0x0200;             //Reinitialize mask to shift in new byte
                    DataWord = 0;                  //Reset data word to get new bits
                }
                DataMask = DataMask >> 1;          //Shift mask for next bit
            }
            else                                   //If time is less than 1.5 bit periods
            {
                if(HalfBit == 0)                   //Check if first of second bit time
                    HalfBit = 1;                   //If first then indicate next will be second
                else                               
                {
                    HalfBit = 0;                   //If second bit time then indicate next will be first
                    if(BitValue)                   //Save incoming bit that was decoded
                        DataWord |= DataMask;
                    if(DataMask == 0)              //Check if reached end of byte
                    {
                        U1TXREG = DataWord;        //Transmit new byte out USART
                        DataMask = 0x0200;         //Reinitialize mask to shift in new byte
                        DataWord = 0;              //Reset data word to get new bits
                    }
                    DataMask = DataMask >> 1;      //Shift mask for next bit
                }
            }

        }
    }
}

//---------------------------------------------------------------------------

