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 Answer 1

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;
        }

    }
}
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.