00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "pic24_all.h"
00030
00037 #define IR_FIFO_SIZE 32
00038 volatile uint8 au8_irFIFO[32];
00039 volatile uint16 u16_irFifoHead = 0;
00040 volatile uint16 u16_irFifoTail = 0;
00041
00042 void irFifoWrite(uint8 u8_x) {
00043 u16_irFifoHead++;
00044 if (u16_irFifoHead == IR_FIFO_SIZE) u16_irFifoHead = 0;
00045 au8_irFIFO[u16_irFifoHead] = u8_x;
00046 }
00047 uint8 irFifoRead(void) {
00048 while (u16_irFifoHead == u16_irFifoTail) {
00049 doHeartbeat();
00050 }
00051 u16_irFifoTail++;
00052 if (u16_irFifoTail == IR_FIFO_SIZE) u16_irFifoTail = 0;
00053 return au8_irFIFO[u16_irFifoTail];
00054 }
00055
00056 uint8 irFifoDataRdy(void) {
00057 return(u16_irFifoHead != u16_irFifoTail);
00058 }
00059
00060
00061
00062 #define PWM_PERIOD 20000 //in microseconds
00063
00064
00065
00066
00067
00068 void configTimer2(void) {
00069 T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
00070 | T2_32BIT_MODE_OFF
00071 | T2_SOURCE_INT
00072 | T2_PS_1_64 ;
00073 PR2 = usToU16Ticks(PWM_PERIOD, getTimerPrescale(T2CONbits)) - 1;
00074 TMR2 = 0;
00075 _T2IF = 0;
00076 T2CONbits.TON = 1;
00077 }
00078
00079 #define TWOTHIRDS_PERIOD_US 1100 //two thirds expected bit period, in microseconds
00080 #define COMMAND_LENGTH 13 //number of bits expected in IR command
00081 #define IR_INPUT _RB7 //using RB9 for IR input
00082
00083 volatile uint16 u16_lastCapture, u16_thisCapture,u16_delta, u16_twoThirdsPeriodTicks;
00084 volatile uint8 u8_bitCount,u8_bitCountTotal,u8_currentByte;
00085
00086 typedef struct tagFLAGBITS {
00087 unsigned u1_bitEdge:
00088 1;
00089 unsigned u1_bitValue:
00090 1;
00091 }FLAGBITS;
00092 static volatile FLAGBITS flags;
00093
00094 typedef enum {
00095 STATE_START_PULSE_FALL = 0,
00096 STATE_START_PULSE_RISE,
00097 STATE_BIT_CAPTURE,
00098 STATE_LAST_EDGE,
00099 } ICSTATE;
00100
00101 ICSTATE e_isrICState;
00102
00103 void _ISRFAST _IC1Interrupt() {
00104 _IC1IF = 0;
00105 u16_thisCapture = IC1BUF ;
00106 u16_delta = computeDeltaTicks(u16_lastCapture,u16_thisCapture,PR2);
00107 u16_lastCapture = u16_thisCapture;
00108 switch (e_isrICState) {
00109 case STATE_START_PULSE_FALL:
00110 e_isrICState = STATE_START_PULSE_RISE;
00111 break;
00112 case STATE_START_PULSE_RISE:
00113 if (u16_delta > u16_twoThirdsPeriodTicks) {
00114
00115 e_isrICState = STATE_START_PULSE_FALL;
00116 } else {
00117
00118 flags.u1_bitEdge = 1;
00119 u8_bitCount = 0;
00120 u8_currentByte = 0;
00121 flags.u1_bitValue = 1;
00122 u8_bitCountTotal = 0;
00123 e_isrICState = STATE_BIT_CAPTURE;
00124 }
00125 break;
00126 case STATE_BIT_CAPTURE:
00127 if ((u16_delta > u16_twoThirdsPeriodTicks) || flags.u1_bitEdge) {
00128
00129 if ((u16_delta > u16_twoThirdsPeriodTicks)) {
00130
00131 flags.u1_bitValue = !flags.u1_bitValue;
00132 }
00133 if (u8_bitCount != 0)u8_currentByte = u8_currentByte << 1;;
00134 if (flags.u1_bitValue) u8_currentByte = u8_currentByte | 0x01;
00135 u8_bitCount++;
00136 u8_bitCountTotal++;
00137 flags.u1_bitEdge = 1;
00138 if (u8_bitCount == 7) {
00139 irFifoWrite(u8_currentByte);
00140 u8_currentByte = 0;
00141 u8_bitCount = 0;
00142 }
00143 }
00144 flags.u1_bitEdge = !flags.u1_bitEdge;
00145 if (u8_bitCountTotal == COMMAND_LENGTH) {
00146 if (u8_bitCount != 0) irFifoWrite(u8_currentByte);
00147 if (IR_INPUT) e_isrICState = STATE_START_PULSE_FALL;
00148 else e_isrICState = STATE_LAST_EDGE;
00149 }
00150 break;
00151 case STATE_LAST_EDGE:
00152 e_isrICState = STATE_START_PULSE_FALL;
00153 break;
00154
00155 default:
00156 e_isrICState = STATE_START_PULSE_FALL;
00157 }
00158 }
00159
00160
00161
00162 void configInputCapture1(void) {
00163 CONFIG_RB7_AS_DIG_INPUT();
00164 CONFIG_IC1_TO_RP(7);
00165 e_isrICState = STATE_START_PULSE_FALL;
00166 u16_irFifoHead = 0;
00167 u16_irFifoTail = 0;
00168 u16_twoThirdsPeriodTicks = usToU16Ticks(TWOTHIRDS_PERIOD_US, getTimerPrescale(T2CONbits));
00169 IC1CON = IC_TIMER2_SRC |
00170 IC_INT_1CAPTURE |
00171 IC_EVERY_EDGE;
00172 _IC1IF = 0;
00173 _IC1IP = 1;
00174 _IC1IE = 1;
00175 }
00176