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.

problems with logical operators on C6713b

Hi,

I'm using the C6713 DSK from Spectrum Digital and I'm having some problems with logical operators in my code.

I am receiving input from the LINE IN jack, being commanded by my PC's audio output port. I am filtering (time domain, FIR) the audio signal on the DSP. The results of filtering appear fine because I send the results via the DSK's HEADPHONE jack back to my PC's mic port and I plot the results on my PC. I can see the FIR filter works properly.

I have some logic in the DSP code that should turn on the LED, signifying an amplitude achieved by the filtered result. Simply testing that the amplitude after filtering is above a threshold seems to correctly turn the LED on (and off). I do not want to see the LED flicker rapidly (I filter during each sample, and the rate is 8000 Hz), so I need to implement some logic that will hold the LED on for X samples. To do this, I have a nested-if structure. My problem is that the if-test on my boolean seems to do the opposite of what I need.

interrupt void c_int11()
{
  filteredResult = filter( getInput() );

  if( b_trigger > 0 ) // boolean is ON already
  {
    DSK6713_LED_on(1); // turn ON LED #1

    if( trigger_counter < X )
    {
      trigger_counter = trigger_counter + 1;
    }
    else
    {
      b_trigger = 0; // turn OFF boolean
    }
  }
  else // boolean is OFF
  {
    DSK6713_LED_off(1); // turn OFF LED #2

    // test if we need to turn ON boolean
    if( filteredResult > ampThreshold )
    {
      b_trigger = 1;  // turn ON boolean
      trigger_counter = 0; // reset
  }
}

I am brainstorming about what could be the cause of my problem. I doubt these are truly the cause of the problem, but here are some thoughts:

  1. It is not allowed to use nested-if structure. The compiler cannot handle it properly.
  2. Right now the FIR filter operates on a buffer of 'short' (16 bit integers) and convolves the buffer with the array of filter coefficients. Since the filter coefficients are stored using the 'double' precision floating point type, can this be causing some exception causing logical operators to misbehave? Remember, the output signal looks fine.
  3. Is it wrong to command an LED from within a hardware interrupt function?

System:
OS: Windows 7 64 bit
IDE: CCS 5.1
compiler: TI v7.3.4

  • My experience is with the C6747 and C6748. I think it is same compiler as C6713. I've had no problems with nested ifs.

    I assume that the LED is driven by a GPIO. Changing a GPIO is okay from an ISR. It's the preferred over printing to a serial port to avoid taking too much time inside an ISR. I'm assuming the DSK6713_LED_off() function takes care of any possible inversion in logic that might occur from a pull-up vs pull-down setup of the LED.

    I would think the filter() function has a greater risk of taking too much time. I assume that the entire ISR completes before another IRQ comes in. Maybe your filter() function is overwriting your counter and flag by accident.

    Your code should work but the LED will be one interrupt behind. You should not need to repeatedly set the LED state.

    static volatile int          b_trigger       = 0;
    static volatile unsigned int trigger_counter = 0;
    interrupt void c_int11()
    {
      filteredResult = filter( getInput() );

      if( b_trigger )
      { // LED is currently ON
        trigger_counter++;
        if( trigger_counter >= X )
        {
          b_trigger = 0;      // turn OFF boolean
          DSK6713_LED_off(1); // turn OFF LED
        }
      }
      else
      { // LED is currently OFF
        // test if we need to turn ON boolean
        if( filteredResult > ampThreshold )
        {
          b_trigger       = 1; // turn ON boolean
          trigger_counter = 0; // reset
          DSK6713_LED_on(1);   // turn ON LED
      }
    }

    Example code using count-down:

    static volatile unsigned int trigger_counter = 0;
    interrupt void c_int11()
    {
      filteredResult = filter( getInput() );

      if( trigger_counter )
      { // Counter is active
        if( --trigger_counter == 0 )
          DSK6713_LED_off(1); // turn OFF LED
      }
      else
      { // Counter is inactive
        // test if we need to start counter
        if( filteredResult > ampThreshold )
        {
          trigger_counter = X; // start counter
          DSK6713_LED_on(1);   // turn ON LED
        }
      }
    }

  • Hi John,

    Thanks for your post.

    I don't think, there should be probem with nested-if structure on C6713 compiler. I doubt, there should be issues with your second point mentioned on your thoughts above. Like, FIR filter convolving buffer with the array of filter coefficients which is in double precision floating point type and there are chances to cause exception on the same.

    Please refer TMS320C6000 Optimizing Compiler v7.4 User's Guide as given below for more information

    http://www.ti.com/lit/ug/spru187u/spru187u.pdf

    Thanks & regards,

    Sivaraj K

    ----------------------------------------------------------------------------------------------------------
    Please click the Verify Answer button on this post if it answers your question.
    ----------------------------------------------------------------------------------------------------------

     

  • John,

    The nested-if statements are fine. The compiler meets the ANSI spec as mentioned in the Compiler User Guide.

    You are missing a closing brace for your last if-statement that tests the filteredResult variable. Norman fixed this in his count-down example.

    If your filteredResult exceeds the ampThreashold soon after the LED is turned off, the LED will go back on very quickly. To fix this, add a copy of the counter code to the boolean OFF part of the code before testing the filteredResult again.

    If you use a value like 4000 for X, the LED should go on for 1/2 second. If you add the OFF-time counter, you can guarantee that it stays off for another 1/2 second and get rid of the flicker.

    What value are you using for X?

    A good way to test your logic and prove to yourself that the compiler implemented the code correctly is to take off the interrupt keyword and call c_int11() from an infinite loop with a breakpoint in the c_int11() function at the b_trigger test line. Then you can step through the code to see how it works. In CCS, you can set the trigger_counter to X-1 so you do not have to go through too many iterations before seeing the logic change.

    Regards,
    RandyP