CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

RTTTL player and USB?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
acidice333



Joined: 14 Oct 2006
Posts: 33

View user's profile Send private message

RTTTL player and USB?
PostPosted: Wed Jan 11, 2012 2:03 pm     Reply with quote

I grabbed the RTTTL ringtone player src someone supplied on here and it works great Im having troubles getting it to work with USB.

It works until I uncomment the code for the usb_enumuerated() then it just plays the first 3 notes and repeats the 1st note forever.

Can I get this working like that?

Code:

#include <18F4550.h>
#device *=16
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR
#use delay(clock=48000000)

// CCS Library dynamic defines
#define USB_CONFIG_HID_TX_SIZE   20  // to pc
#define USB_CONFIG_HID_RX_SIZE   20  // from pc

// CCS USB Libraries
#include <pic18_usb.h>   //Microchip 18Fxx5x hardware layer for usb.c
#include "usb_desc_hid.h"
#include <usb.c>        //handles usb setup tokens and get descriptor reports


#include "tones.h"

#int_timer0
void rtcc_isr(void)
{
   //set_rtcc(RTCC_PRESET);
   //update_switch_status();   // Poll the switches
   
  // Preload a value for TMR0 so that we can control how long it takes to
  // trigger an interrupt
  TMR0 = Tempo;

  // Is a note playing?
  if (DurationCount)
  {
    DurationCount--;
    if (!DurationCount)
      setup_ccp2(CCP_OFF);
  }
  // Note is finished playing, do we have anymore in our buffer?
  else if (Notestat.Count)
  {
    DurationCount = NoteBuffer[Notestat.Head].duration;
    Note_Ticks = NoteBuffer[Notestat.Head].note;
    Notestat.Count--;
    Notestat.Head++;
    Notestat.Head &= NOTE_ROLLOVER_MASK;
    CCP_2 = TMR1 + Note_Ticks;
    if (Note_Ticks)
    {
      /* Setup the CCP module to toggle the output pin c2 */
      setup_ccp2(CCP_COMPARE_TOGGLE_MATCH);
    }
    // Nope, we are all through so disable the PWM
    else
    {
      setup_ccp2(CCP_OFF);
    }
  }   
}



#int_ccp2
void ccp2_isr (void)
{
  CCP_2 += Note_Ticks;
}


int8 in_data[20];

void main() {
   usb_init_cs();
   
   enable_interrupts(GLOBAL);
   TRISCbits.TRISC2 = 0; 
   inittimer();
   Melody_Pointer = JINGLEBELLS;
   while(true) {
      melody_task();
      usb_task();
      //if (usb_enumerated()) {
         //if (usb_kbhit(1)) {
         //   usb_get_packet(1, in_data, USB_CONFIG_HID_RX_SIZE);
         //}
      //}
     
     
     
   }
}



tones.h:
Code:

#define CLOCKSPEED     48000000
#define CCP_COMPARE_TOGGLE_MATCH        2

#define TMR1_PRESCALE  1
#define NOTE_C_SHARP   (((CLOCKSPEED/4)/277.18)/TMR1_PRESCALE)            // 277.18Hz
#define NOTE_D_SHARP   (((CLOCKSPEED/4)/311.13)/TMR1_PRESCALE)            // 311.13 Hz
#define NOTE_F_SHARP   (((CLOCKSPEED/4)/369.99)/TMR1_PRESCALE)            // 369.99 Hz
#define NOTE_G_SHARP   (((CLOCKSPEED/4)/415.30)/TMR1_PRESCALE)            // 415.30 Hz
#define NOTE_A_SHARP   (((CLOCKSPEED/4)/466.16)/TMR1_PRESCALE)            // 466.16 Hz

#define NOTE_C         (((CLOCKSPEED/4)/261.63)/TMR1_PRESCALE)            // 261.63 Hz
#define NOTE_D         (((CLOCKSPEED/4)/293.66)/TMR1_PRESCALE)            // 293.66 Hz
#define NOTE_E         (((CLOCKSPEED/4)/329.63)/TMR1_PRESCALE)            // 329.63 Hz
#define NOTE_F         (((CLOCKSPEED/4)/349.23)/TMR1_PRESCALE)            // 349.23 Hz
#define NOTE_G         (((CLOCKSPEED/4)/392.00)/TMR1_PRESCALE)            // 392.00 Hz
#define NOTE_A         (((CLOCKSPEED/4)/440.00)/TMR1_PRESCALE)            // 440.00 Hz
#define NOTE_B         (((CLOCKSPEED/4)/493.88)/TMR1_PRESCALE)            // 493.88 Hz
#define NOTE_SILENCE   0         

#define DURATION_32   5    // Duration = 2^x
#define DURATION_16   4    // Duration = 2^x
#define DURATION_8    3    // Duration = 2^x
#define DURATION_4    2    // Duration = 2^x
#define DURATION_2    1    // Duration = 2^x
#define DURATION_1    0    // Duration = 2^x

typedef enum
{
  JINGLEBELLS,
  LAST_MELODY
}MELODIES;

typedef struct
{
  int Head;
  int Tail;
  int Count;
} NOTESTATR;

typedef struct
{
  long note;
  long duration;
}NOTE_DEF;


struct
{
  int TRISC0:1;
  int TRISC1:1;
  int TRISC2:1;
  int TRISC3:1;
  int TRISC4:1;
  int TRISC5:1;
  int TRISC6:1;
  int TRISC7:1;
}TRISCbits;
#locate TRISCbits = 0xF94

long TMR1;
#locate TMR1 = 0xFCE

int TMR1L;
#locate TMR1L = 0xFCE

int TMR1H;
#locate TMR1H = 0xFCF

int TMR0;
#locate TMR0 = 0xFD6


#define   MAX_NOTE_BUFFER_SIZE  4
#define   NOTE_ROLLOVER_MASK     0b00000011
NOTE_DEF  NoteBuffer[MAX_NOTE_BUFFER_SIZE];
NOTESTATR  Notestat = {0,0,0};

long      DurationCount=0;
int       Tempo=0;
long      Note_Ticks=0;
MELODIES  Melody_Pointer;
long      Note_Index = 0xFFFF;
BOOLEAN   PlayMelodyFlag = TRUE;
int       Read_Button_Count = 0;

const struct
{
  char tune[202];
  int  defaultoctave;
  int  defaultduration;
  int  tempo;
}JingleBellsss = {
                 {"8e.,8e.,e.,8e.,8e.,e.,8e.,8g.,c,16d.,2e,p,8f.,8f.,f,16f.,8f.,8e.,8e.,16e.,16e.,8e.,8d.,8d.,8e.,d.,g.,8e.,8e.,e.,8e.,8e.,e.,8e.,8g.,c,16d.,2e,p,8f.,8f.,f,16f.,8f.,8e.,8e.,16e.,16e.,8g.,8g.,8f.,8d.,c.,1p"},
                 5,
                 DURATION_4,
                 180
               };

const struct
{
  char tune[192];
  int16  defaultoctave;
  int16  defaultduration;
  int16  tempo;
}JingleBellss = {
                 {"f#.,8g#,f#,d#.,p.,f#.,8g#,f#,d#.,p.,2c#6,c#6,a#.,p.,2b,b,f#.,p.,2g#,g#,b.,8a#,g#,f#.,8g#,f#,d#.,p.,2g#,g#,b.,8a#,g#,f#.,8g#,f#,d#.,p.,2c#6,c#6,e.6,8c#6,a#,2b.,2d#6,p.,b,f#,d#,f#.,8e,c#,b.4,1p"},
                 5,
                 DURATION_4,
                 140
               };

/* Function Prototypes */
void InitTimer(void);
int PlayMelody();
void PlayNote(long note, int octave, int duration);
char get_char_from_tune(long index);
int get_tempo(void);
int get_defaultoctave(void);
int get_defaultduration(void);
void display_melody_name(void);
void Melody_Task(void);
void Button_Task(void);
void Check_Button_Press(void);




/* *************************************************************************
  DESCRIPTION:  This function handles the playing of a melody
  RETURN:       True if the melody is still active or False if its complete
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int PlayMelody(void)
{

  int octave = 0;
  int duration = 0;
  long note = 0;

  // Check for a valid Melody
  if (Melody_Pointer >= LAST_MELODY)
  {
    // Reset the Melody to the start
    Melody_Pointer = 0;
    Note_Index = 0xFFFF;
  }
   
  // Load notes while we have enough room
  while (Notestat.Count < MAX_NOTE_BUFFER_SIZE)
  {

    // Is this the first note?
    if (Note_Index == 0xFFFF)
    {
      display_melody_name();
      Tempo = get_tempo();
      Note_Index = 0;
    }

    // Set Default duration
    duration = get_defaultduration();
    // Set Default Octave
    octave = get_defaultoctave();     
 
    // Play a bit of slience between notes
    if (get_char_from_tune(Note_Index) == ',')
    {
      PlayNote(0, 4, DURATION_32);
      Note_Index++;
      return(TRUE);
    }

    // We are checking the duration
    else if ((get_char_from_tune(Note_Index) == '3') && (get_char_from_tune(Note_Index+1) == '2'))
    {
      duration = DURATION_32;
      Note_Index += 2;
    }
    else if ((get_char_from_tune(Note_Index) == '1') && (get_char_from_tune(Note_Index+1) == '6'))
    {
      duration = DURATION_16;
      Note_Index += 2;
    }
    else if (get_char_from_tune(Note_Index) == '8')
    {
      duration = DURATION_8;
      Note_Index++;
    }
    else if (get_char_from_tune(Note_Index) == '4')
    {
      duration = DURATION_4;
      Note_Index++;
    }
    else if (get_char_from_tune(Note_Index) == '2')
    {
      duration = DURATION_2;
      Note_Index++;
    }
    else if (get_char_from_tune(Note_Index) == '1')
    {
      duration = DURATION_1;
      Note_Index++;
    }

    // Now we get the note
    switch (get_char_from_tune(Note_Index++))
    {
      case 'c':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_C_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_C;
        break;
      case 'd':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_D_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_D;
        break;
      case 'e':
        note = NOTE_E;
        break;
      case 'f':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_F_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_F;
        break;
      case 'g':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_G_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_G;
        break;
      case 'a':
        if (get_char_from_tune(Note_Index) == '#')
        {
          note = NOTE_A_SHARP;
          Note_Index++;
        }
        else
          note = NOTE_A;
        break;
      case 'b':
        note = NOTE_B;
        break;
      case 'p': // slience
        note = NOTE_SILENCE;
        break;
    }
 
    // See if this note is 1.5x the duration
    if (get_char_from_tune(Note_Index) == '.')
    {
      // Use the MSB to signify 1.5x
      duration |= 0x80;
      Note_Index++;
    }

    // Get the octave
    switch (get_char_from_tune(Note_Index))
    { 
      case '4':
        octave = 4;
        Note_Index++;
        break;
      case '5':
        octave = 5;
        Note_Index++;
        break;
      case '6':
        octave = 6;
        Note_Index++;
        break;
      case '7':
        octave = 7;
        Note_Index++;
        break;
      default:
        break;
    }   

    // Sometimes the duration multiplier comes after the octave
    if (get_char_from_tune(Note_Index) == '.')
    {
      /* Duration 1.5x */
      duration |= 0x80;
      Note_Index++;
    } 
 
    // Play the note (we actually just load it in a buffer
    PlayNote(note, octave, duration);

    // Is this the end?
    if (get_char_from_tune(Note_Index) == 0)
    {
      Note_Index = 0xFFFF;
      return(FALSE);
    }
    return(TRUE);
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void PlayNote(long note, int octave, int duration)
{
  long duration_count;

  // Process octave
  switch (octave)
  {
    case 4 :
      break;
    case 5 :
      note = note >> 1;
      break;
    case 6 :
      note = note >> 2;
      break;
    case 7 :
      note = note >> 4;
      break;
  }

  // Process Note Duration
  duration_count = 256;
  duration_count >>= (duration & 0x7F);

  // If duration is 1.5x add .5 to duration
  if (duration & 0x80)
    duration_count += (duration_count >> 1);   

  // Add the note to our buffer
  NoteBuffer[Notestat.Tail].note = note;
  NoteBuffer[Notestat.Tail].duration = duration_count;
  Notestat.Tail++;
  Notestat.Tail &= NOTE_ROLLOVER_MASK;
  Notestat.Count++;


/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void InitTimer(void)
{
  setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //8 ;

  enable_interrupts(INT_CCP2);
  enable_interrupts(INT_TIMER0);
  //enable_interrupts(INT_TIMER2);
}


/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
char get_char_from_tune(long index)
{
  switch (Melody_Pointer)
  { 
    case JINGLEBELLS:
      return (JingleBellss.tune[index]);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int get_tempo(void)
{
  switch (Melody_Pointer)
  {
    case JINGLEBELLS:
      return (JingleBellss.tempo);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int get_defaultoctave(void)
{
  switch (Melody_Pointer)
  {
    case JINGLEBELLS:
      return (JingleBellss.defaultoctave);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
int get_defaultduration(void)
{
  switch (Melody_Pointer)
  {
    case JINGLEBELLS:
      return (JingleBellss.defaultduration);
      break;
    default:
      break;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void Melody_Task(void)
{
  if (PlayMelodyFlag)
  {
    if (!PlayMelody())
      Melody_Pointer++;
  }
}

/* *************************************************************************
  DESCRIPTION:  This function displays the title of the melody on the LCD
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void display_melody_name(void)
{
  // Clear the screen and make sure that we are at the top
  //lcd_putc("\f");
  //lcd_gotoxy(0,1);

  // Use our global Melody_Pointer to determine the title of the current tune
  switch (Melody_Pointer)
  {
    case JINGLEBELLS:
      //lcd_putc("JingleBells");
      break;
     default:
       break;
  }
}

/* *************************************************************************
  DESCRIPTION:  Button Tasks
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void Button_Task(void)
{
  if (!Read_Button_Count)
  {
    Read_Button_Count = 30;
    Check_Button_Press();
  }
}

/* *************************************************************************
  DESCRIPTION:  This function handles checking for button presses
  RETURN:       none
  ALGORITHM:    none
  NOTES:        none
 *************************************************************************** */
void Check_Button_Press(void)
{
  static int debounce_count = 4;
  static int stable = 0xFF;
  static int last = 0xFF;
  int trans_low;
  int current = 0xFF;
  BOOLEAN change = FALSE;

  // Read the current state of the buttons
  if (!input(PIN_B7))
    bit_clear(current,2);

  if (!input(PIN_B6))
    bit_clear(current,3);

  // See if they have changed
  if (current != last)
  {
    last = current;
    change = TRUE;
  }

  // If they have changed then reset our counter
  if (change)
  {
    debounce_count = 4;
  }
  // Each time they are stable, then decrement our count
  else if (debounce_count)
  {
    debounce_count--;
  }
  // They have been stable long enough so act on them
  else if (current != stable)
  {
    // Get the high transitions
    trans_low = ((stable ^ current) & stable);

    if (bit_test(trans_low,2))
      PlayMelodyFlag = ! PlayMelodyFlag;
    if (bit_test(trans_low,3))
    {
      Melody_Pointer++;
      if (Melody_Pointer >= LAST_MELODY)
        Melody_Pointer = 0;
      Note_Index = 0xFFFF;
      display_melody_name();
    }
    stable = current;
  }
}





Code:
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group