IR Toy. Помощь с прошивкой под NEC протокол

Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить
xxxSon1cxxx
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн июл 30, 2012 22:53:25

IR Toy. Помощь с прошивкой под NEC протокол

Сообщение xxxSon1cxxx »

Здравствуйте. Нужна помощь в переделке прошивки IR Toy для декодирования сигналов от пультов с протоколом NEC. На форуме проекта нашёл уже готовое решение, но возникли проблемы с переносом кода прошивки с поддержкой NEC протокола в последнюю доступную прошивку v22, которая работает с RC-5 протоколом. Внес изменения в файлы RCdecoder.c и HardwareProfile.h, но в итоге на ком-порт приходят сообщения ошибки NE... при нажатии любой кнопки на пульте.
Вот мой измененный RCdecoder.c
Спойлер

Код: Выделить всё

#include "globals.h"
#include "PICUSB.h"

extern BYTE cdc_In_buffer[64];
extern BDentry *Inbdp;

#pragma udata access uaccess
struct _rcStates
{
   enum _state{
      START=0,
      WAIT,
      IDLE,
      CAPTURE,
      DECODE,
      SEND
   }state;
}volatile near rcStates;

volatile near unsigned char count;

near char val;
near unsigned char byteno;
near unsigned char bitno;
near unsigned char i;
near unsigned char ticks;
near unsigned char signalLength;
near unsigned char irCode[6];


//disable timers, setup IR activity interrupt

void SetupRC5(void) {
    rcStates.state=START;

    //IRman protocol: respond to IR with OK...
}

//IR signals are first captured in the interrupt loop below
//when the capture is complete, the bits are decoded into bytes and sent to USB from this function

void ProcessIR(void) {
   //wait for line to be clear
   if(rcStates.state==START)
   {
      if (IRX == 1)
      {
         rcStates.state=WAIT;

          //start timer, wait for 5.5ms
         T2_5440us();
         T2IF=0;
         T2IE=1;
         T2ON=1;
         //arm interrupt
         IRRXIF=0;
         IRRX_EDGE=0;
         IRRXIE=1;   

         //signal to main loop that executing a sleep instruction
         // will not harm
         return(2);     
      }
   }
   else if(rcStates.state==DECODE)
   {
         // 1 tick = 61us
         if (count == 67)
         {
            //lead pulse
            if ((irToy.s[0] > 133) && (irToy.s[0] < 162) &&
                     (irToy.s[1] > 65) && (irToy.s[1] < 81))
            {
               for (i=0; i<6; i++)
               {
                  irCode[i] = 0;
               }
               irCode[0] = 'N';
               byteno = 1;
               bitno = 1;
               for (i=0; i<32; i++)
               {
                  //560 = 9ticks, 1680 = 27 ticks
                  val = irToy.s[2*i+3] + irToy.s[2*i+2];
   
                  // set bit "1"
                  if (val > 24)
                  {
                     irCode[byteno] |= bitno;
                  }
                  bitno <<= 1;
                  if (bitno == 0)
                  {
                     byteno++;
                     bitno = 1;
                  }
               } // end for
               // NEC format error check
               if (irCode[3] == ~(irCode[4]))
               {
                  irCode[4] = 0;
                  rcStates.state = SEND;
               }
               else
               {
                  irCode[0] = 'N';
                  irCode[1] = 'E';
                  irCode[2] = 1;
                  rcStates.state = SEND;
               }
            } // end if lead pulse
            else
            {
               irCode[0] = 'd';
               irCode[1] = 'a';
               irCode[2] = 2;
               irCode[3] = irToy.s[0];
               irCode[4] = irToy.s[1];
               irCode[5] = count;
               rcStates.state = SEND;
            }
         }// end if count
         // check for NEC repreat code
         else if (count == 3)
         {
            //lead pulse for repeat 9ms, 2.25, 0.55
            if ((irToy.s[0] > 133) && (irToy.s[0] < 162) &&
                     (irToy.s[1] > 30) && (irToy.s[1] < 45) &&
                        (irToy.s[2] > 4) && (irToy.s[2] <15))
            {
               // resend last code
               rcStates.state = SEND;
            }
            else
            {
               irCode[0] = 'N';
               irCode[1] = 'E';
               irCode[2] = 4;
               irCode[3] = count;
               rcStates.state = SEND;
            }
         }
         else
         {
            irCode[0] = 'N';
            irCode[1] = 'E';
            irCode[2] = 3;
            irCode[3] = count;
            //rcStates.events |= EV_ERROR;
            rcStates.state = SEND;
         }
   }// DECODE
   else if(rcStates.state==SEND)
   {
      if (getInReady())
      {

            for (i=0; i<6; i++)
            {
               cdc_In_buffer[i] = irCode[i];
            }
            putUnsignedCharArrayUsbUsart(cdc_In_buffer,6);
            rcStates.state = START;
      }
      else
      {
         rcStates.state = START;
      }
   }
   return(0);
}

//high priority interrupt routine
#pragma code INTERRUPTS
//#pragma interrupt IRdecoderInterruptHandlerHigh
void IRdecoderInterruptHandlerHigh(void) {
   // signal change detected
   if(IRRXIF == 1)
   {
      //busy, try again
      if(rcStates.state==WAIT)
      {
         T2IE=0;
         IRRXIE=0;
         rcStates.state=START;
      }
      // first falling edge
      else if(rcStates.state==IDLE)
      {
         // store length of signals in array
         // 1 tick approx 61 us
         T3_sample();
         TMR3L=0;
         T3ON=1;
         count = 0;
         
         rcStates.state=CAPTURE;

         IRRX_EDGE ^= 1;
      }
      else if(rcStates.state==CAPTURE)
      {
         irToy.s[count] = TMR3L;
         TMR3L=0;
         
         // set timer to detect end of signal
         //start timer 5ms
         if (count==0)
         {
            T2_5440us();
            T2IF=0;
            T2IE=1;
            T2ON=1;
         }

         count++;
         if (count>=SAMPLE_ARRAY_SIZE)
         {
            rcStates.state=DECODE;
            T2ON=0;
            T3ON=0;
            IRRXIE=0;
            T2IE=0;         
         }

         TMR2=0;
         IRRX_EDGE ^= 1;
      }
      IRRXIF=0;
   }
   if (T2IF == 1)
   {
      //ready for receive
      if(rcStates.state==WAIT)
      {
         T2ON=0;
         T2IE=0;
         rcStates.state=IDLE;

         //arm interrupt
         IRRXIF=0;
         IRRX_EDGE=0;
         IRRXIE=1;   
      }
      //end of signal
      else if (rcStates.state==CAPTURE)
      {
         rcStates.state=DECODE;
         T2ON=0;
         T3ON=0;
         IRRXIE=0;
         T2IE=0;
      }
      T2IF=0;
   }
}
//#endif //RC_DECODER

и HardwareProfile.h
Спойлер

Код: Выделить всё

#ifndef HARDWARE_PROFILE_H
#define HARDWARE_PROFILE_H

#define FIRMWARE_VERSION_H '2'
#define FIRMWARE_VERSION_L '2'

#define SAMPLE_ARRAY_SIZE 0x0080 //0x0010 JTR3 these are not used for SUMP mode. See sump.h and sump.c
#define SAMPLE_SIZE 0x0400 //0x0080 //(SAMPLE_ARRAY_SIZE*0x0008)

struct _irtoy {
    unsigned char s[SAMPLE_ARRAY_SIZE];
    //JTR2 this appears not to be used:
    //unsigned char usbIn[30];
    //unsigned char usbOut[64];
    unsigned char HardwareVersion;
    //  unsigned char CrtlByte;
};
//hardware platform?
#define USBIRTOY //Dangerous Prototypes IR Toy, RX on RB4 and RB2,TX on RC2, 2550
#define IRRX_ONRB4 //force RB4 interrupt instead of INT2 on USBIRTOY
//#define HAD_USBIRC //hackaday RX on B4 only, PIC 2455

//select the correct interrupt pin depending on hardware and settings
#if defined (HAD_USBIRC) || defined (IRRX_ONRB4)// irRX B4 (25)
#define IRRX_LAT  LATB
#define IRRX_TRIS TRISB
#define IRRX_PORT PORTB
#define IRX PORTBbits.RB4
#define IRRX_PIN  0b10000
#define IRRAW_PIN  0b10 //JTR3
#define IRRAW PORTBbits.RB1 // JTR3
#define IRRXIE INTCONbits.RBIE
#define IRRXIF INTCONbits.RBIF
#define IRRX_EDGE INTCON2bits.INTEDG2
#define T0_IP INTCON2bits.TMR0IP
#define T1_IP IPR1bits.TMR1IP
#define T2_IP IPR1bits.TMR2IP
#define T3_IP IPR2bits.TMR3IP
#define IRRX_IP INTCON2bits.RBIP
#define IRRAWINT1_IP INTCON3bits.INT1IP
#define CCP1_IP IPR1bits.CCP1IP
#else //use INT2 with edge trigger, schmidt buffer
#define IRRX_ONINT2 //tells other functions we're using INT2 interrupt
#define IRRX_LAT  LATB
#define IRRX_TRIS TRISB
#define IRRX_PORT PORTB
#define IRX PORTBbits.RB2
#define IRRX_PIN  0b100
#define IRRXIE INTCON3bits.INT2IE
#define IRRXIF INTCON3bits.INT2IF
#define IRRX_IP INTCON3bits.INT2IP
#define IRRX_EDGE INTCON2bits.INTEDG2
#define IRRAWINT1_IP INTCON3bits.INT1IP
#define CCP1_IP IPR1bits.CCP1IP
#define T0_IP INTCON2bits.TMR0IP
#define T1_IP IPR1bits.TMR1IP
#define T2_IP IPR1bits.TMR2IP
#define T3_IP IPR2bits.TMR3IP
#endif
#define IRRX_PULLUP INTCON2bits.RBPU //one pullup bit for all PORTB pins
#define EnableIRTOY_HI_IP() RCONbits.IPEN = 1

#if defined (HAD_USBIRC)
// LED C2 (13)
#define LED_LAT LATC
#define LED_TRIS TRISC
#define LED_PIN  0b100
#elif defined (USBIRTOY)
// LED A0 (2)
#define LED_LAT  LATA
#define LED_TRIS TRISA
#define LED_PIN  0b1
#endif
// irTX C2 (13) CCP1
#define IRTX_LAT  LATC
#define IRTX_TRIS TRISC
#define IRTX_PIN  0b100

//
//V2 extra hardware
//
//raw receiver
//CCP pin (12/RC1)
#define IRFREQ_CAP_LAT  LATC
#define IRFREQ_CAP_TRIS TRISC
#define IRFREQ_CAP_PORT PORTC
#define IRFREQ_CAP_PIN  0b10
#define IRFREQ_CAP              PORTCbits.RC1
#define IRFREQ_CAP_SETUP() PIE2bits.CCP2IE=0; T3CON=0; CCP2CON=0b00000101 //capture every rising edge (0100 = falling edge) //select timer1 for CPP2 in T3CON   
#define IRFREQ_CAPIE   PIE2bits.CCP2IE
#define IRFREQ_CAPIF   PIR2bits.CCP2IF         
#define IRFREQ_CAP_L    CCPR2L
#define IRFREQ_CAP_H    CCPR2H 
#define IRFREQ_CCPxCON  CCP2CON

//Interrupt pin (22/RB1)
#define IRFREQ_INT_LAT  LATB
#define IRFREQ_INT_TRIS TRISB
#define IRFREQ_INT_PORT PORTB
#define IRFREQ_INT_PIN  0b10
#define IRFREQ_INT              PORTBbits.RB1

//T1/3 external clock (11/RC0)
#define IRFREQ_EC_LAT   LATC
#define IRFREQ_EC_TRIS  TRISC
#define IRFREQ_EC_PORT  PORTC
#define IRFREQ_EC_PIN   0b1
#define IRFREQ_EC               PORTCbits.RC0

//all connected IR FREQ pin to input
#define IRFREQ_PIN_SETUP() IRFREQ_CAP_TRIS|=IRFREQ_CAP_PIN; IRFREQ_INT_TRIS|=IRFREQ_INT_PIN; IRFREQ_EC_TRIS|=IRFREQ_EC_PIN

// RX C7 (18)
// TX C6 (17)

#if 0
#define dLedOff()  LED_LAT&=(~LED_PIN)  // JTR redefine led for debugging
#define dLedOn() LED_LAT|=LED_PIN
#define dbLedToggle() LedOut(); LED_LAT ^=LED_PIN

#define LedOff() 
#define LedOn()
#define LedToggle()

#else
#define dLedOff()
#define dLedOn()
#define dbLedToggle()

#define LedOff()  LED_LAT &=(~LED_PIN)  //JTR TODO uncomment
#define LedOn() LED_LAT|=LED_PIN //JTR TODO uncomment
#define LedToggle() LED_LAT ^=LED_PIN
#endif

#define LedOut() LED_TRIS&=(~LED_PIN)
#define LedIn() LED_TRIS|=LED_PIN
#define T0_IF INTCONbits.T0IF
#define T0_IE INTCONbits.T0IE
#define T0ON T0CONbits.TMR0ON

#define T1IF    PIR1bits.TMR1IF
#define T1IE    PIE1bits.TMR1IE
#define T1ON    T1CONbits.TMR1ON

#define T2IF    PIR1bits.TMR2IF
#define T2IE    PIE1bits.TMR2IE
#define T2ON    T2CONbits.TMR2ON

#define T3ON    T3CONbits.TMR3ON

#define IRRAWINTIF INTCON3bits.INT1IF
#define IRRAWINTIE INTCON3bits.INT1IE

//10us timer for TVBGONE on TIMER1 (65415)
#define T1_10usOffset() TMR1H=0xFF; TMR1L=0x9A //87

//10khz default sampling clock for IRIO on TIMER1
#define T1_OFFSET 0xFB4B //64331 preload = 10006.8kHz
#define T1_OFFSETH 0xFB //(T1_OFFSET>>8)
#define T1_OFFSETL 0x4B //(T1_OFFSET &= (~0xff00))
#define T1_10kHzOffset()  TMR1H=T1_OFFSETH; TMR1L=T1_OFFSETL

//SUMP sample period with TIMER2
#define T2_RXsampleperiod() PR2 = 150; T2CON = PRE_x4 + POST_x2 //10040.1Hz

//RC5 bit and half bit period with TIMER2
#define T2_RC5halfbitperiod() PR2=222; T2CON=PRE_x4+POST_x6 //setup to hit in the middle of next bit period
#define T2_RC5bitperiod() PR2=222; T2CON=PRE_x4+POST_x12 //full bit values from now on

#define T2_5440us() PR2=254; TMR2=0; T2CON=PRE_x16+POST_x16
#define T3_sample() T3CON=0b00010110

#define PWMon() TMR2=0;CCP1CON |=0b1100
#define PWMoff() CCP1CON &=(~0b1100)


//we don't use these, disable
#define self_power          1
#define USB_BUS_SENSE       1

#define BootloaderJump() _asm goto 0x16 _endasm

//TMR2 Pre- and post- scalers
#define PRE_x4 0b01
#define PRE_x16 0b11
#define POST_x2 0b1000
#define POST_x3 0b10000
#define POST_x4 0b11000
#define POST_x5 0b100000
#define POST_x6 0b101000
#define POST_x7 0b110000
#define POST_x8 0b111000
#define POST_x9 0b1000000
#define POST_x10 0b1001000
#define POST_x11 0b1010000
#define POST_x12 0b1011000
#define POST_x13 0b1100000
#define POST_x14 0b1101000
#define POST_x15 0b1110000
#define POST_x16 0b1111000

#endif


Прошивки прикрепил ниже.
Вложения
firmware-with-NEC.rar
(31.73 КБ) 193 скачивания
Firmware-v22.zip
(85.64 КБ) 165 скачиваний
Реклама
Ответить

Вернуться в «PIC»