This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2433: Issues outputting signal with IR module

Part Number: MSP430FR2433

Hi, I'm having issues getting a steady output from the IR module on the MSP430fr2433.

I have confirmed on an oscilloscope on P1.2 that I'm generating a 38 kHz signal with Timer_A0.

I have also confirmed on P1.4 that I'm generating a 500 Hz signal with Timer_A1.

Page 53 of the user manual (slau445g) seems to indicate that I need to set the following registers

IRDATA = 0
IRDSSEL = 1
IRMSEL = 0
IREN = 1

When I put all this on the oscilloscope, all I get is a high output on P2.6

My code is below. Does anyone have any suggestions where I've gone wrong?

// IR transmitter test

#include "driverlib.h"
#include "msp430.h"

//******************************************************************************
//
//          PINOUTS
//
//******************************************************************************
// PIN 1.0 = onboard red LED for MSP430FR2433 dev board - Set to basic output
// PIN 2.6 = IR LED. Pin set to output in IR transmit mode IREN
// PIN 2.7 = onboard switch for MSP430FR2433 dev board. Set to trigger on high to low

//******************************************************************************
//
//          Function Prototypes
//
//******************************************************************************
void Init_Clock(void);
void Init_GPIO(void);
void Start_38k_Timer(void);
void Start_Envelope_Timer(void);
void BlinkLED ();

//******************************************************************************
//
//          Global Variables
//
//******************************************************************************
volatile uint32_t buttonDebounce;

/************ Lighting Related Global Variables ************/
// Blank for now


/************ IR TX Related Global Variables ************/
//unsigned char   IR_code = 0;
//unsigned char   IR_flag = 0;
unsigned char   IR_stop = 0;
unsigned char   byte_cnt = 0;
unsigned int    bit_sel = 0;
unsigned char   *send_addr;
unsigned char   send_data[4]={0x55, 0xaa, 0x00, 0xff}; // default values. every other byte is inverse

/************ Timer Related Global Variables ************/
uint32_t MclockValue = 0;           //Variable to store current MClock value
uint32_t SMclockValue = 0;          //Variable to store current SMClock value
uint32_t AclockValue = 0;           //Variable to store current AClock value

/************ Clock Frequencies ************/
//Target frequency for MCLK in kHz
#define CS_MCLK_DESIRED_FREQUENCY_IN_KHZ 8000

//MCLK/FLLRef Ratio
// Set this to MCLK value divided by 32000. This sets a countdown timer to allow the FLL to settle into the desired MCLK value
#define CS_MCLK_FLLREF_RATIO 250

void main (void)
{
    //Stop watchdog timer
    WDT_A_hold(WDT_A_BASE);

    // Initialize everything
    Init_GPIO();                                //Initialize GPIO
    Init_Clock();                               //Initialize Clock

    //Verify if the Clock settings are as expected
    MclockValue = CS_getMCLK();
    SMclockValue = CS_getSMCLK();
    AclockValue = CS_getACLK();

    IR_stop = 0;   //enable IR emitter

    while(1)
        {

            // clear the flag and counter
            //IR_flag  = 0;
            byte_cnt = 0;
            bit_sel = 0;

            if(IR_stop == 0)
            {
                // disable Port1 & Port2 interrupt during IR emitting
                P1IE = 0;
                P2IE = 0;

                // Start generating a 38khz signal
                Start_38k_Timer();
                Start_Envelope_Timer();
                // Stop and sit here just putting out a constant 38khz signal
                while(1);

            }
            __bis_SR_register(LPM3_bits + GIE);     //enter LPM3 with global interrupts enabled

            IR_stop = 0;                            // enable IR code emitting
        }

    //Enter LPM3 w/interrupt
    //__bis_SR_register(LPM3_bits + GIE);

    //For debugger
    __no_operation();
}

//******************************************************************************
//
//          Functions
//
//******************************************************************************

//Initialize Clock
void Init_Clock(void)
{
    // This function uses driverlib to set the clock values for the board
    // See driverlib documentation for more information about these functions

    // Set DCO FLL reference = REFO
    CS_initClockSignal(CS_FLLREF,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);

    // Set Ratio and Desired MCLK Frequency and initialize DCO
    CS_initFLLSettle(CS_MCLK_DESIRED_FREQUENCY_IN_KHZ,CS_MCLK_FLLREF_RATIO);

    // Set ACLK = REFO
    CS_initClockSignal(CS_ACLK,CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);

                                            // DCOCLK = MCLK and SMCLK source
    CSCTL5 |= DIVM_0 | DIVS_1;              // MCLK = DCOCLK = 8MHZ,
                                            // SMCLK = MCLK/2 = 4MHz
}

//Initialize GPIO
void Init_GPIO(void)
{
    //************  IR CONFIGURATION  ************//
    // Configure IR output pin
    // Set P 2.6 to output the signal from IR module
    GPIO_setAsPeripheralModuleFunctionOutputPin(
      GPIO_PORT_P2,
      GPIO_PIN6,
      GPIO_PRIMARY_MODULE_FUNCTION
      );


    // DEBUG - Set P 1.2 to output the signal from Timer_A0
    // See slau445g page 328 for instruction on how to set manually
    GPIO_setAsPeripheralModuleFunctionOutputPin(
      GPIO_PORT_P1,
      GPIO_PIN2,
      GPIO_SECONDARY_MODULE_FUNCTION
      );

    // DEBUG - Set P 1.4 to output the signal from Timer_A1
    GPIO_setAsPeripheralModuleFunctionOutputPin(
      GPIO_PORT_P1,
      GPIO_PIN4,
      GPIO_SECONDARY_MODULE_FUNCTION
      );

    // Currently set for FSK modulation with output set to high
    // Configure IR modulation - see slau445g page 78
    // BIT 4 = IRDATA
    // BIT 3 = IRDSSEL  - IR Data Source Select 0 = hardware | 1 = IRDATA bit
    // BIT 2 = IRMSEL   - IR Mode Select    0 = ASK | 1 = FSK
    // BIT 1 = IRPSEL   - Polarity (don't touch)
    // BIT 0 = IREN     - IR Enable 0 = off | 1 = on
    SYSCFG1 = IRDSSEL + IREN;       // Datasource = IRDATA bit, ASK mode

    PMM_unlockLPM5();
}

void Start_38k_Timer(void){
    // This setup configures and starts a constant 38khz signal using timer_A0
    // Timer configuration step order from slau445g page 363

    // Step 1 - Clear everything    slau445g page 377
    TA0CTL = TACLR;

    // Step 2 - Initialize Timer_A0 Capture/Compare Register    slau445g page 381
    // 38kHz 1/4 duty-cycle carrier waveform length setting     slaa644b page 10
    // Configured based on 4 MHz clock!!
    TA0CCR0 = 104;          // (4000 / 38 = 105) (timer counts from 0)
    TA0CCR2 = 25;           // (105 / 4 = 26) (1/4 duty cycle for power conservation)

    // Step 3 - Configure Timer_A0 Capture/Compare Control Register     slau445g page 379
    TA0CCTL2 = OUTMOD_7;                // output mode: reset/set

    // Step 4 - Configure Timer_A0 Control Register     slau445g page 377
    // timer operation mode settings
    // TACLR    = Timer A counter clear
    // TASSEL_2 = Timer A clock source select: 2 - SMCLK
    // MC_1     = Timer A mode control: 1 - Up to CCR0
    TA0CTL = TASSEL_2 + MC_1;
}

void Start_Envelope_Timer(void){
    // This setup configures an envelope timing signal using timer_A0
    // Timer configuration step order from slau445g page 363

    // Currently configured to output a constant high signal

    // Step 1 - Clear everything    slau445g page 377
    TA1CTL = TACLR;

    // Step 2 - Initialize Timer_A1 Capture/Compare Register    slau445g page 381
    // 9 ms
    // Configured based on 4 MHz clock!!
    TA1CCR0 = 8000 - 1;          // (4000000 x 0.001 = 4000 + TA1CCR2 = 8000) (1ms low)
    TA1CCR2 = 4000 - 1;          // (4000000 x 0.001 = 4000) (1ms high)

    // Step 3 - Configure Timer_A1 Capture/Compare Control Register     slau445g page 379
    TA1CCTL2 = OUTMOD_7;                // output mode: reset/set

    // Step 4 - Configure Timer_A1 Control Register     slau445g page 377
    // timer operation mode settings
    // TACLR    = Timer A counter clear
    // TASSEL_2 = Timer A clock source select: 2 - SMCLK
    // MC_1     = Timer A mode control: 1 - Up to CCR0
    TA1CTL = TASSEL_2 + MC_1;
}

  • Hi Sandy,

    We have some resources on our site that could be helpful to you.

    The link below is an Application Report that explains IR Remote Control implementation with our MSP devices.
    www.ti.com/.../slaa644b.pdf

    This link is another Application Report that also explains IR Remote Control implementation. This one is older, but I’ll include it just for reference.
    www.ti.com/.../slla175.pdf

    Here is a link to a TI IR Remote Control Design. You can find example code there that shows how to implement IR functionality.
    www.ti.com/.../TIDM-BOOST-IR-REMOTE

    Please let me know if you continue to have questions.

    Thanks!

    -Mitch Ridgeway
  • Thanks for the suggestions Mitch. I've actually been using those resources plus a few others to design my code. The part I can't figure out is the functionality of the built in IR module as described on page 53 of the slau445g user manual.

    My question is based on the diagram below. I have a 38 kHz carrier signal being output from TA0.2A (P1.2) and a 500 Hz envelope signal output from TA1.2A (P1.4). Both verified using an oscilloscope.

    I set:

    IREN = 1
    IRMSEL = 0
    IRDSSEL = 1

    Pin 2.6 is set as output and SEL bit is set to 1 to function as UCA1TXD/'UCA1SIMO  (from page57 of the MSP430fr2433 data sheet)

    Why would there be no output on P2.6? Shouldn't this generate a 38 kHz signal with a period of 1ms transmit and 1ms off?

  • Hi Sandy,

    I am looking further into this. Thanks for the information.

    -Mitch
  • Thanks! Using the hardware module looks like it should be a lot more efficient than using software PWM to send the signal.

  • Hi Sandy,

    There is a typo in the user's guide. As you shown in the figure, the IR output pin is P2.6/UCA1TXD, it is not correct. For all MSP430FR2x4x devices, the IR output pin is on UCA0TXD but not UCA1TXD. I changed the IR pin to P1.4/UCA0TXD in your code as attached, then it works as expected. I have given feedback to user's guide owner and the typo will be updated.

    #include <msp430.h> 
    
    // IR transmitter test
    
    #include "driverlib.h"
    
    //******************************************************************************
    //
    //          PINOUTS
    //
    //******************************************************************************
    // PIN 1.0 = onboard red LED for MSP430FR2433 dev board - Set to basic output
    // PIN 2.6 = IR LED. Pin set to output in IR transmit mode IREN
    // PIN 2.7 = onboard switch for MSP430FR2433 dev board. Set to trigger on high to low
    
    //******************************************************************************
    //
    //          Function Prototypes
    //
    //******************************************************************************
    void Init_Clock(void);
    void Init_GPIO(void);
    void Start_38k_Timer(void);
    void Start_Envelope_Timer(void);
    void BlinkLED ();
    
    //******************************************************************************
    //
    //          Global Variables
    //
    //******************************************************************************
    volatile uint32_t buttonDebounce;
    
    /************ Lighting Related Global Variables ************/
    // Blank for now
    
    
    /************ IR TX Related Global Variables ************/
    //unsigned char   IR_code = 0;
    //unsigned char   IR_flag = 0;
    unsigned char   IR_stop = 0;
    unsigned char   byte_cnt = 0;
    unsigned int    bit_sel = 0;
    unsigned char   *send_addr;
    unsigned char   send_data[4]={0x55, 0xaa, 0x00, 0xff}; // default values. every other byte is inverse
    
    /************ Timer Related Global Variables ************/
    uint32_t MclockValue = 0;           //Variable to store current MClock value
    uint32_t SMclockValue = 0;          //Variable to store current SMClock value
    uint32_t AclockValue = 0;           //Variable to store current AClock value
    
    /************ Clock Frequencies ************/
    //Target frequency for MCLK in kHz
    #define CS_MCLK_DESIRED_FREQUENCY_IN_KHZ 8000
    
    //MCLK/FLLRef Ratio
    // Set this to MCLK value divided by 32000. This sets a countdown timer to allow the FLL to settle into the desired MCLK value
    #define CS_MCLK_FLLREF_RATIO 250
    
    void main (void)
    {
        //Stop watchdog timer
        WDT_A_hold(WDT_A_BASE);
    
        // Initialize everything
        Init_GPIO();                                //Initialize GPIO
        Init_Clock();                               //Initialize Clock
    
        //Verify if the Clock settings are as expected
        MclockValue = CS_getMCLK();
        SMclockValue = CS_getSMCLK();
        AclockValue = CS_getACLK();
    
        IR_stop = 0;   //enable IR emitter
    
        while(1)
            {
    
                // clear the flag and counter
                //IR_flag  = 0;
                byte_cnt = 0;
                bit_sel = 0;
    
                if(IR_stop == 0)
                {
                    // disable Port1 & Port2 interrupt during IR emitting
                    P1IE = 0;
                    P2IE = 0;
    
                    // Start generating a 38khz signal
                    Start_38k_Timer();
                    Start_Envelope_Timer();
                    // Stop and sit here just putting out a constant 38khz signal
                    while(1);
    
                }
                __bis_SR_register(LPM3_bits + GIE);     //enter LPM3 with global interrupts enabled
    
                IR_stop = 0;                            // enable IR code emitting
            }
    
        //Enter LPM3 w/interrupt
        //__bis_SR_register(LPM3_bits + GIE);
    
        //For debugger
        __no_operation();
    }
    
    //******************************************************************************
    //
    //          Functions
    //
    //******************************************************************************
    
    //Initialize Clock
    void Init_Clock(void)
    {
        // This function uses driverlib to set the clock values for the board
        // See driverlib documentation for more information about these functions
    
        // Set DCO FLL reference = REFO
        CS_initClockSignal(CS_FLLREF,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);
    
        // Set Ratio and Desired MCLK Frequency and initialize DCO
        CS_initFLLSettle(CS_MCLK_DESIRED_FREQUENCY_IN_KHZ,CS_MCLK_FLLREF_RATIO);
    
        // Set ACLK = REFO
        CS_initClockSignal(CS_ACLK,CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
                                                // DCOCLK = MCLK and SMCLK source
        CSCTL5 |= DIVM_0 | DIVS_1;              // MCLK = DCOCLK = 8MHZ,
                                                // SMCLK = MCLK/2 = 4MHz
    }
    
    //Initialize GPIO
    void Init_GPIO(void)
    {
        //************  IR CONFIGURATION  ************//
        // Configure IR output pin
        // Set P 2.6 to output the signal from IR module
    //    GPIO_setAsPeripheralModuleFunctionOutputPin(
    //      GPIO_PORT_P2,
    //      GPIO_PIN6,
    //      GPIO_PRIMARY_MODULE_FUNCTION
    //      );
    
        GPIO_setAsPeripheralModuleFunctionOutputPin(
          GPIO_PORT_P1,
          GPIO_PIN4,
          GPIO_PRIMARY_MODULE_FUNCTION
          );
    
        // DEBUG - Set P 1.2 to output the signal from Timer_A0
        // See slau445g page 328 for instruction on how to set manually
    //    GPIO_setAsPeripheralModuleFunctionOutputPin(
    //      GPIO_PORT_P1,
    //      GPIO_PIN2,
    //      GPIO_SECONDARY_MODULE_FUNCTION
    //      );
    //
    //    // DEBUG - Set P 1.4 to output the signal from Timer_A1
    //    GPIO_setAsPeripheralModuleFunctionOutputPin(
    //      GPIO_PORT_P1,
    //      GPIO_PIN4,
    //      GPIO_SECONDARY_MODULE_FUNCTION
    //      );
    
        // Currently set for FSK modulation with output set to high
        // Configure IR modulation - see slau445g page 78
        // BIT 4 = IRDATA
        // BIT 3 = IRDSSEL  - IR Data Source Select 0 = hardware | 1 = IRDATA bit
        // BIT 2 = IRMSEL   - IR Mode Select    0 = ASK | 1 = FSK
        // BIT 1 = IRPSEL   - Polarity (don't touch)
        // BIT 0 = IREN     - IR Enable 0 = off | 1 = on
        SYSCFG1 = IRDSSEL + IREN;       // Datasource = IRDATA bit, ASK mode
    
        PMM_unlockLPM5();
    }
    
    void Start_38k_Timer(void){
        // This setup configures and starts a constant 38khz signal using timer_A0
        // Timer configuration step order from slau445g page 363
    
        // Step 1 - Clear everything    slau445g page 377
        TA0CTL = TACLR;
    
        // Step 2 - Initialize Timer_A0 Capture/Compare Register    slau445g page 381
        // 38kHz 1/4 duty-cycle carrier waveform length setting     slaa644b page 10
        // Configured based on 4 MHz clock!!
        TA0CCR0 = 104;          // (4000 / 38 = 105) (timer counts from 0)
        TA0CCR2 = 25;           // (105 / 4 = 26) (1/4 duty cycle for power conservation)
    
        // Step 3 - Configure Timer_A0 Capture/Compare Control Register     slau445g page 379
        TA0CCTL2 = OUTMOD_7;                // output mode: reset/set
    
        // Step 4 - Configure Timer_A0 Control Register     slau445g page 377
        // timer operation mode settings
        // TACLR    = Timer A counter clear
        // TASSEL_2 = Timer A clock source select: 2 - SMCLK
        // MC_1     = Timer A mode control: 1 - Up to CCR0
        TA0CTL = TASSEL_2 + MC_1;
    }
    
    void Start_Envelope_Timer(void){
        // This setup configures an envelope timing signal using timer_A0
        // Timer configuration step order from slau445g page 363
    
        // Currently configured to output a constant high signal
    
        // Step 1 - Clear everything    slau445g page 377
        TA1CTL = TACLR;
    
        // Step 2 - Initialize Timer_A1 Capture/Compare Register    slau445g page 381
        // 9 ms
        // Configured based on 4 MHz clock!!
        TA1CCR0 = 8000 - 1;          // (4000000 x 0.001 = 4000 + TA1CCR2 = 8000) (1ms low)
        TA1CCR2 = 4000 - 1;          // (4000000 x 0.001 = 4000) (1ms high)
    
        // Step 3 - Configure Timer_A1 Capture/Compare Control Register     slau445g page 379
        TA1CCTL2 = OUTMOD_7;                // output mode: reset/set
    
        // Step 4 - Configure Timer_A1 Control Register     slau445g page 377
        // timer operation mode settings
        // TACLR    = Timer A counter clear
        // TASSEL_2 = Timer A clock source select: 2 - SMCLK
        // MC_1     = Timer A mode control: 1 - Up to CCR0
        TA1CTL = TASSEL_2 + MC_1;
    }
    

    Best Regards,

    Darren

  • Thanks! At least now I know I'm not crazy.

**Attention** This is a public forum