1

I am trying to replicate an LTC Audio Decoder code from Arduino Uno into AVR ATmega8 which I got from here.

My Arduino Uno code is working great. Here is my Arduino Uno code:

#define one_time_max          588 // these values are setup for NTSC video
#define one_time_min          422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max          1080 // 80bits times 29.97 frames per sec
#define zero_time_min          922 // equals 833 (divide by 8 clock pulses)


#define icpPin 8        // ICP input pin on arduino
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile boolean valid_tc_word;
volatile boolean ones_bit_count;
volatile boolean tc_sync;
volatile boolean write_tc_out;
volatile boolean drop_frame_flag;

volatile byte total_bits;
volatile byte current_bit;
volatile byte sync_count;

volatile byte tc[8];
volatile char timeCode[11];

/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect)
{
 //toggleCaptureEdge
 TCCR1B ^= _BV(ICES1);
  //Serial.println("Inter");
 bit_time = ICR1;

 //resetTimer1
 TCNT1 = 0;

if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
 {
   //Serial.println(bit_time, DEC);
   total_bits = 0;
 }
 else
 {
   if (ones_bit_count == true) // only count the second ones pluse
     ones_bit_count = false;
   else
   {    
     if (bit_time > zero_time_min)
     {
       current_bit = 0;
       sync_count = 0;
     }
     else //if (bit_time < one_time_max)
     {
       ones_bit_count = true;
       current_bit = 1;
       sync_count++;
       if (sync_count == 12) // part of the last two bytes of a timecode word
       {
         sync_count = 0;
         tc_sync = true;
         total_bits = end_sync_position;
       }
     }

     if (total_bits <= end_data_position) // timecode runs least to most so we need
     {                                    // to shift things around
       tc[0] = tc[0] >> 1;

       for(int n=1;n<8;n++)
       {
         if(tc[n] & 1)
           tc[n-1] |= 0x80;

         tc[n] = tc[n] >> 1;
       }

       if(current_bit == 1)
         tc[7] |= 0x80;
     }
     total_bits++;
   }

   if (total_bits == end_smpte_position) // we have the 80th bit
   {
     total_bits = 0;
     if (tc_sync)
     {
       tc_sync = false;
       valid_tc_word = true;
     }
   }

   if (valid_tc_word)
   {
     valid_tc_word = false;

     timeCode[11]= '\0';
     timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
     timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
     timeCode[8] =  '-';
     timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
     timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
     timeCode[5] =  '-';
     timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
     timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
     timeCode[2] = '-';
     timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
     timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours

       drop_frame_flag = bit_is_set(tc[1], 2);

     write_tc_out = true;
   }
 }
}


void setup()
{
 Serial.begin(9600);
 pinMode(8, INPUT);                  // ICP pin (digital pin 8 on arduino) as input

 bit_time = 0;
 valid_tc_word = false;
 ones_bit_count = false;
 tc_sync = false;
 write_tc_out = false;
 drop_frame_flag = false;
 total_bits =  0;
 current_bit =  0;
 sync_count =  0;

 Serial.println("Finished setup ");
 delay (1000);

 TCCR1A = B00000000; // clear all
 TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
 TCCR1C = B00000000; // clear all
 TIMSK1 = B00100000; // ICIE1 enable the icp

 TCNT1 = 0; // clear timer1
}

void loop()
{
  if (write_tc_out)
   {
     write_tc_out = false;
     //if (drop_frame_flag)
       //Serial.print("TC-[df] ");
     //else
       //Serial.print("TC-[nd] ");
     Serial.println((char*)timeCode);
   //  Serial.print("  ");
     //Serial.print("\r");
   }
}

Now to replicate this code for AVR ATmega8, I just copy this code in AVR studio and make small changes like initializing UART, initializing Input Capture Mode etc. Here is my AVR ATmega8 code:

#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>


#define one_time_max          588 // these values are setup for NTSC video
#define one_time_min          422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max          1080 // 80bits times 29.97 frames per sec
#define zero_time_min          922 // equals 833 (divide by 8 clock pulses)


#define icpPin 8        // ICP input pin on arduino
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile char valid_tc_word;
volatile char ones_bit_count;
volatile char tc_sync;
volatile char write_tc_out;
volatile char drop_frame_flag;

volatile unsigned char total_bits;
volatile unsigned char current_bit;
volatile unsigned char sync_count;

volatile unsigned char tc[8];
volatile char timeCode[11];


void USARTInit(uint16_t ubrr_value)
{

    UBRRL = ubrr_value;
    UBRRH = (ubrr_value>>8);
    UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);


}

unsigned char USARTReadChar()
{

    while(!(UCSRA & (1<<RXC)));
    return UDR;
}

void USARTWriteChar(char data)
{

    while(!(UCSRA & (1<<UDRE)));
    UDR=data;
}

void send_string(char s[])
{
    int i =0;

    while (s[i] != 0x00)
    {
        USARTWriteChar(s[i]);
        i++;
    }
}



int main(void)
{

    USARTInit(103);
    DDRB=0;
     bit_time = 0;
     valid_tc_word = 0;
     ones_bit_count = 0;
     tc_sync = 0;
     write_tc_out = 0;
     drop_frame_flag = 0;
     total_bits =  0;
     current_bit =  0;
     sync_count =  0;

    send_string("FINISHED SETUP");
    _delay_ms(1000);     


    TCCR1A = 0;
    TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
    TIMSK = (1<<TICIE1);
    TCNT1 = 0;
    sei();
    while(1)
    {

        if (write_tc_out==1)
        {
            write_tc_out = 0;
            send_string((char*)timeCode);       
        }
}

}

ISR(TIMER1_CAPT_vect)
{

 //toggleCaptureEdge
 TCCR1B ^= _BV(ICES1);
  //Serial.println("Inter");
 bit_time = ICR1;

 //resetTimer1
 TCNT1 = 0;

if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
 {
   //Serial.println(bit_time, DEC);
   total_bits = 0;
 }
 else
 {
   if (ones_bit_count == 1) // only count the second ones pluse
     ones_bit_count = 0;
   else
   {    
     if (bit_time > zero_time_min)
     {
       current_bit = 0;
       sync_count = 0;
     }
     else //if (bit_time < one_time_max)
     {
       ones_bit_count = 1;
       current_bit = 1;
       sync_count++;
       if (sync_count == 12) // part of the last two bytes of a timecode word
       {
         sync_count = 0;
         tc_sync = 1;
         total_bits = end_sync_position;
       }
     }

     if (total_bits <= end_data_position) // timecode runs least to most so we need
     {       
               // to shift things around
       tc[0] = tc[0] >> 1;

       for(int n=1;n<8;n++)
       {
         if(tc[n] & 1)
           tc[n-1] |= 0x80;

         tc[n] = tc[n] >> 1;
       }

       if(current_bit == 1)
         tc[7] |= 0x80;
     }
     total_bits++;
   }

   if (total_bits == end_smpte_position) // we have the 80th bit
   {
     total_bits = 0;
     if (tc_sync)
     {
       tc_sync = 0;
       valid_tc_word = 1;
     }
   }

  if (valid_tc_word==1)
   {

     valid_tc_word = 0;

     timeCode[11]= '\0';
     timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
     timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
     timeCode[8] =  '-';
     timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
     timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
     timeCode[5] =  '-';
     timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
     timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
     timeCode[2] = '-';
     timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
     timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours

       drop_frame_flag = bit_is_set(tc[1], 2);

     write_tc_out = 1;
   }

 }
}

Now when I run this code, I don't get any time stamps. I have gone through this code many times but I am unable to figure out the mistake in my code. Can any one help me figure out the issue?

1

I figure out the issue , I just add a small delay in ISR and my code is running fine now. I don't know reason behind it but anyway my code is running now. Here is my new code:-

#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>


#define one_time_max          588 // these values are setup for NTSC video
#define one_time_min          422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max          1080 // 80bits times 29.97 frames per sec
#define zero_time_min          922 // equals 833 (divide by 8 clock pulses)


#define icpPin 8        // ICP input pin on arduino
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile char valid_tc_word;
volatile char ones_bit_count;
volatile char tc_sync;
volatile char write_tc_out;
volatile char drop_frame_flag;

volatile unsigned char total_bits;
volatile unsigned char current_bit;
volatile unsigned char sync_count;

volatile unsigned char tc[8];
volatile char timeCode[11];


void USARTInit(uint16_t ubrr_value)
{

    UBRRL = ubrr_value;
    UBRRH = (ubrr_value>>8);
    UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);


}

unsigned char USARTReadChar()
{

    while(!(UCSRA & (1<<RXC)));
    return UDR;
}

void USARTWriteChar(char data)
{

    while(!(UCSRA & (1<<UDRE)));
    UDR=data;
}

void send_string(char s[])
{
    int i =0;

    while (s[i] != 0x00)
    {
        USARTWriteChar(s[i]);
        i++;
    }
    USARTWriteChar('\n');
}



int main(void)
{

    USARTInit(103);
    DDRB=0;
    bit_time = 0;
    valid_tc_word = 0;
    ones_bit_count = 0;
    tc_sync = 0;
    write_tc_out = 0;
    drop_frame_flag = 0;
    total_bits =  0;
    current_bit =  0;
    sync_count =  0;

    send_string("FINISHED SETUP");
    _delay_ms(1000);


    TCCR1A = 0;
    TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
    TIMSK = (1<<TICIE1);
    TCNT1 = 0;
    sei();
    while(1)
    {

        if (write_tc_out==1)
        {
            write_tc_out = 0;
            send_string((char*)timeCode);
        }
    }

}

ISR(TIMER1_CAPT_vect)
{

    //toggleCaptureEdge
    TCCR1B ^= _BV(ICES1);
    //Serial.println("Inter");
    bit_time = ICR1;

    //resetTimer1
    TCNT1 = 0;
_delay_us(13);

    if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
    {
        //Serial.println(bit_time, DEC);
        total_bits = 0;
    }
    else
    {
        if (ones_bit_count == 1) // only count the second ones pluse
        ones_bit_count = 0;
        else
        {
            if (bit_time > zero_time_min)
            {
                current_bit = 0;
                sync_count = 0;
            }
            else //if (bit_time < one_time_max)
            {
                ones_bit_count = 1;
                current_bit = 1;
                sync_count++;
                if (sync_count == 12) // part of the last two bytes of a timecode word
                {
                    sync_count = 0;
                    tc_sync = 1;
                    total_bits = end_sync_position;
                }
            }

            if (total_bits <= end_data_position) // timecode runs least to most so we need
            {
                // to shift things around
                tc[0] = tc[0] >> 1;

                for(int n=1;n<8;n++)
                {
                    if(tc[n] & 1)
                    tc[n-1] |= 0x80;

                    tc[n] = tc[n] >> 1;
                }

                if(current_bit == 1)
                tc[7] |= 0x80;
            }
            total_bits++;
        }

        if (total_bits == end_smpte_position) // we have the 80th bit
        {
            total_bits = 0;
            if (tc_sync)
            {
                tc_sync = 0;
                valid_tc_word = 1;
            }
        }

        if (valid_tc_word==1)
        {

            valid_tc_word = 0;

            timeCode[11]= '\0';
            timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
            timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
            timeCode[8] =  '-';
            timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
            timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
            timeCode[5] =  '-';
            timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
            timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
            timeCode[2] = '-';
            timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
            timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours

            drop_frame_flag = bit_is_set(tc[1], 2); 

            write_tc_out = 1;
        }

    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.