Hi,
I am trying to record modulated infrared signals using the TMS320F28335 and a TSOP98200 IR receiver. The reason for this is that I want to implement the code learning functionality of universal remote controls. Thus, I am trying to use the Enhanced Capture Module to record the signal and the Enhanced Pulse Width Modulation Module to output the signal. Nevertheless, so far I have only been able to detect the modulation carrier of the signal but not the whole signal, that is, the carrier along with the envelope of the signal. In other words, when I probe the output using an oscilloscope I get a pulse train that looks exactly like the modulation carrier but the envelope is just constant. I have posted the code I am using below. I expect, since the IR sensor I am using outputs a pulse train, that the eCap module should acquire the exact signal but for some reason it is not working. Any help in figuring how to acquire the whole signal would be very much appreciated.
Thanks,
Jorge
//##########################################################################
//
// FILE: Infrared Transceiver
//
// TITLE: DSP28335ControlCARD; IR - remote receiver, measurement with eCAP1
//###########################################################################
#include "DSP2833x_Device.h"
#define SAMPLES 4000
// external function prototypes
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void InitCpuTimers(void);
extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);
// Global variables
Uint16 signal[SAMPLES];
Uint16 index1;
Uint16 index2;
// Prototype statements for functions found within this file.
void Gpio_select(void);
void Setup_eCap1(void);
void Setup_ePWM1A(void);
interrupt void eCap1_isr(void);
interrupt void ePWM1A_isr(void);
interrupt void cpu_timer0_isr(void);
//###########################################################################
// main code
//###########################################################################
void main(void)
{
int i;
index1 = index2 = i = 0;
InitSysCtrl(); // Basic Core Init from DSP2833x_SysCtrl.c
DINT; // Disable all interrupts
Gpio_select(); // GPIO31 and GPIO34 as output to 2 LEDs at Development Board
Setup_eCap1(); // init eCap1
Setup_ePWM1A();
InitPieCtrl(); // basic setup of PIE table; from DSP2833x_PieCtrl.c
InitPieVectTable(); // default ISR's in PIE
EALLOW;
PieVectTable.TINT0 = &cpu_timer0_isr;
PieVectTable.ECAP1_INT = &eCap1_isr;
PieVectTable.EPWM1_INT = &ePWM1A_isr;
EDIS;
InitCpuTimers();
for(i=0; i<SAMPLES; i++) signal[i] = 0;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
IER |= 0xD;
EINT;
ERTM;
while(ECap1Regs.TSCTR < 2000000000)
{
asm(" NOP");
}
ECap1Regs.ECEINT.bit.CEVT4 = 0;
ConfigCpuTimer(&CpuTimer0, 150, 10000);
while(1)
{
GpioDataRegs.GPASET.bit.GPIO4 = 1;
CpuTimer0.InterruptCount = 0;
CpuTimer0Regs.TCR.bit.TSS = 0;
while(CpuTimer0.InterruptCount == 0)
{
asm(" NOP");
}
CpuTimer0Regs.TCR.bit.TSS = 1;
CpuTimer0Regs.TCR.bit.TRB = 1;
index2 = 0;
EPwm1Regs.ETSEL.bit.INTEN = 1;
while(index2 < index1)
{
asm(" NOP");
}
EPwm1Regs.ETSEL.bit.INTEN = 0;
}
}
/*****************************************************************************/
/* Interrupt Service Function for eCap1 */
/* triggered after 4 consecutive edges falling - rising - falling - rising */
/* Code calculates the time between edges and */
/* stores the values in global variable signal */
/*****************************************************************************/
interrupt void eCap1_isr(void)
{
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;
// read four captures falling-rising-falling-rising
if(index1 < SAMPLES) {
signal[index1++] = ECap1Regs.CAP1;
signal[index1++] = ECap1Regs.CAP2;
signal[index1++] = ECap1Regs.CAP3;
signal[index1++] = ECap1Regs.CAP4;
}
ECap1Regs.ECCLR.bit.CEVT4 = 1; // Clear the CEVT4 flag
ECap1Regs.ECCLR.bit.INT = 1; // Clear the ECap1 main interrupt flag
PieCtrlRegs.PIEACK.bit.ACK4 = 1; // Must acknowledge the PIE group 4
}
/*****************************************************************************/
/* Interrupt Service Function for Timer0 */
/*****************************************************************************/
void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
/*****************************************************************************/
/* Interrupt Service Function for Enhanced Pulse Width Modulation 1 A */
/*****************************************************************************/
interrupt void ePWM1A_isr(void)
{
GpioDataRegs.GPATOGGLE.bit.GPIO4 = 1;
if(index2 < index1) EPwm1Regs.TBPRD = signal[index2++]/4-1;
EPwm1Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.bit.ACK3 = 1;
}
void Gpio_select(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX1.all = 0; // GPIO15 ... GPIO0 = General Puropse I/O
GpioCtrlRegs.GPAMUX2.all = 0; // GPIO31 ... GPIO16 = General Purpose I/O
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1;// eCap1 active
GpioCtrlRegs.GPBMUX1.all = 0; // GPIO47 ... GPIO32 = General Purpose I/O
GpioCtrlRegs.GPBMUX2.all = 0; // GPIO63 ... GPIO48 = General Purpose I/O
GpioCtrlRegs.GPCMUX1.all = 0; // GPIO79 ... GPIO64 = General Purpose I/O
GpioCtrlRegs.GPCMUX2.all = 0; // GPIO87 ... GPIO80 = General Purpose I/O
GpioCtrlRegs.GPADIR.all = 0;
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // development board: LED LD2 at GPIO31
GpioCtrlRegs.GPBDIR.all = 0; // GPIO63-32 as inputs
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // development board: LED LD3 at GPIO34
GpioCtrlRegs.GPCDIR.all = 0; // GPIO87-64 as inputs
EDIS;
}
/*****************************************************************************/
/* Setup Function for eCap1 */
/*****************************************************************************/
void Setup_eCap1(void)
{
ECap1Regs.ECEINT.all = 0; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // clear all interrupt flags
ECap1Regs.ECCTL1.all = 0;
ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Capture on falling edge
ECap1Regs.ECCTL1.bit.CAP2POL = 0; // Capture on rising edge
ECap1Regs.ECCTL1.bit.CAP3POL = 1; // Capture on falling edge
ECap1Regs.ECCTL1.bit.CAP4POL = 0; // Capture on rising edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // Delta Mode
ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Delta Mode
ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Delta Mode
ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // Delta Mode
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enables loading of CAP registers at capture
ECap1Regs.ECCTL1.bit.PRESCALE = 0; // No prescaling
ECap1Regs.ECCTL1.bit.FREE_SOFT = 2; // Run free
ECap1Regs.ECCTL2.all = 0;
ECap1Regs.ECCTL2.bit.CAP_APWM = 0; // Capture mode
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 2; // Disable sync signal
ECap1Regs.ECCTL2.bit.SYNCI_EN = 0; // Disable sync in option
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Free running
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // Continuous Mode
ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // Wrap after Capture Event 4
ECap1Regs.ECEINT.all = 0;
ECap1Regs.ECEINT.bit.CEVT4 = 1; // Enable event 1 interrupt
}
/*****************************************************************************/
/* Setup Function for ePWM1 */
/*****************************************************************************/
void Setup_ePWM1A(void)
{
EPwm1Regs.TBCTL.bit.FREE_SOFT = 2; // Emulation Mode Bits
EPwm1Regs.TBCTL.bit.CLKDIV = 1; // Time-base Clock Prescale Bits
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // High Speed Time-base Clock Prescale Bits
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // Up-count mode
EPwm1Regs.TBCTL.bit.SYNCOSEL = 3; // Disable EPWM1SYNCO signal
EPwm1Regs.TBCTL.bit.PRDLD = 0; // Load the TBPRD register using a shadow register
EPwm1Regs.TBCTL.bit.PHSEN = 0; // Do not load the time-base counter from the time-base phase register
EPwm1Regs.TBPRD = 60000; // This sets the PWM frequency.
EPwm1Regs.AQCTLA.all = 0x1; // Action when the counter equals zero
EPwm1Regs.ETSEL.all = 0;
EPwm1Regs.ETSEL.bit.INTEN = 0; // Disable ePWM1_INT Generation
EPwm1Regs.ETSEL.bit.INTSEL = 1; // Enable event time-base counter equal to zero
EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate an interrupt on the first event
}