#include "def.h"
#include "val.h"
#include "dfu.h"
#include "usb.h"
#include "spk.h"


//-----MCU.C-----//
extern BYTE Wdt;                                 // Watch Dog Timer Default Value
extern void Delay_Xms( BYTE X );

//-----USB.C-----//
extern void USB_HID_Out( void );
extern EP0INFO Ep0;

//-----WM8987L.C-----//
extern void Initial_Wm8987l( void );


idata SPK Spk;


void SPK_VOL_Vol_Ctrl( BYTE L , BYTE R )
  { BYTE Cur;
    
    
    Cur = USB[GS_LCO];
    Cur &= 0x1F;
    
    if ( L > Cur )
      { while( L != Cur )
          { Cur++;
            USB[GS_LCO] = Cur;
            Delay_Xms( 1 );
          }
      }
    else if ( L < Cur )
      { while( L != Cur )
          { Cur--;
            USB[GS_LCO] = Cur;
            Delay_Xms( 1 );
          }
      }
    
    Cur = USB[GS_RCO];
    Cur &= 0x1F;
    
    if ( R > Cur )
      { while( R != Cur )
          { Cur++;
            USB[GS_RCO] = Cur;
            Delay_Xms( 1 );
          }
      }
    else if ( R < Cur )
      { while( R != Cur )
          { Cur--;
            USB[GS_RCO] = Cur;
            Delay_Xms( 1 );
          }
      }
  }


void SPK_VOL_Mix_Ctrl( BYTE M )
  { BYTE Cur;
    
    
    Cur = USB[GS_MIX];
    Cur &= 0x1F;
    
    if ( M > Cur )
      { while( M != Cur )
          { Cur++;
            USB[GS_MIX] = Cur;
            Delay_Xms( 1 );
          }
      }
    else if ( M < Cur )
      { while( M != Cur )
          { Cur--;
            USB[GS_MIX] = Cur;
            Delay_Xms( 1 );
          }
      }
  }


void SPK_VOL_Mic_Ctrl( BYTE M )
  { BYTE Cur;
    
    
    Cur = USB[GS_ADI];
    Cur &= 0x1F;
    
    if ( M > Cur )
      { while( M != Cur )
          { Cur++;
            USB[GS_ADI] = Cur;
            Delay_Xms( 1 );
          }
      }
    else if ( M < Cur )
      { while( M != Cur )
          { Cur--;
            USB[GS_ADI] = Cur;
            Delay_Xms( 1 );
          }
      }
  }


BIT SPK_Status( void )
  { WDTCR = Wdt;                                 // Reset Watch Dog Timer

    
    if (( Spk.Busy == SET )||( Ep0.EmuOk == CLR ))
      return SET;
    
    switch( Spk.Button )                         // Detect pin is "LOW" active ( AD8255 & BI2008 )
      { case VOLUMEUP:   if ( VOL_INC_IN == SET )
                           { Spk.Button = VOLUMENONE;
                             USB_HID_Out();
                           }
                         break;
        case VOLUMEDOWN: if ( VOL_DEC_IN == SET )
                           { Spk.Button = VOLUMENONE;
                             USB_HID_Out();
                           }
                         break;
        case VOLUMEMUTE: if ( VOL_MUTE_IN == SET )
                           { Spk.Button = VOLUMENONE;
                             USB_HID_Out();
                           }
                         break;        
        case KEYPLAYPAUSE: if ( KEY_PLAYPAUSE == SET )
                                { Spk.Button = VOLUMENONE;
                                  USB_HID_Out();
                                }
                              break;
        case KEYNEXT:      if ( KEY_NEXT == SET )
                                { Spk.Button = VOLUMENONE;
                                  USB_HID_Out();
                                }
                              break;
        case KEYPREVIOUS:  if ( KEY_PREVIOUS == SET )
                                { Spk.Button = VOLUMENONE;
                                  USB_HID_Out();
                                }
                              break;
        case KEYSTOP:      if ( KEY_STOP == SET )
                                { Spk.Button = VOLUMENONE;
                                  USB_HID_Out();
                                }
                              break;
        case KEYMEDIAPLAY: if ( KEY_MEDIAPLAY == SET )
                                { Spk.Button = VOLUMENONE;
                                  USB_HID_Out();
                                }
                              break;
        default:         if ( VOL_INC_IN == CLR )
                           { Spk.Button = VOLUMEUP;
                             USB_HID_Out();
                           }
                         else if ( VOL_DEC_IN == CLR )
                           { Spk.Button = VOLUMEDOWN;
                             USB_HID_Out();
                           }
                         else if ( VOL_MUTE_IN == CLR )
                           { Spk.Button = VOLUMEMUTE;
                             USB_HID_Out();
                           }
                         else if ( KEY_PLAYPAUSE == CLR )
                           { Spk.Button = KEYPLAYPAUSE;
                             USB_HID_Out();
                           }
                         else if ( KEY_NEXT == CLR )
                           { Spk.Button = KEYNEXT;
                             USB_HID_Out();
                           }
                         else if ( KEY_PREVIOUS == CLR )
                           { Spk.Button = KEYPREVIOUS;
                             USB_HID_Out();
                           }
                         else if ( KEY_STOP == CLR )
                           { Spk.Button = KEYSTOP;
                             USB_HID_Out();
                           }
                         else if ( KEY_MEDIAPLAY == CLR )
                           { Spk.Button = KEYMEDIAPLAY;
                             USB_HID_Out();
                           }
                         break;
      }
    
    if ( Spk.Vol_Mute )                          // Mute Mode
      { USBLED = CLR;                            // USB LED On
        MUTELED = CLR;                           // Mute LED On
      }
    else
      { MUTELED = SET;                           // Mute LED Off
        
      	if ( Ep0.Out_AltSet == SPKALTSET1 )
      	  { if ( Spk.Cnt == 0 )
              { if ( Spk.Tmp > 1 )
                  { USBLED = SET;// USB LED Off
                    Spk.Tmp = 0;
                  }
                else
                  { USBLED = CLR;// USB LED On
                    Spk.Tmp++;
                  }
              }
            Spk.Cnt++;
          }
        else
          USBLED = CLR;                          // USB LED On
      }
    return CLR;
  }


void SPK_PLL_Divider_Value( void )
  { if ( Spk.PfTl > 4 )
      { if ( Spk.PfTl == 5 )
          { if ( Spk.HfSeed == 4 )
              Spk.PfTl = 4;
            else
              Spk.PfTl = 6;
          }
        else if ( Spk.PfTl < 7 )
          Spk.PfTl = 6;
        else if ( Spk.PfTl == 7 )
          { if ( Spk.HfSeed == 6 )
              Spk.PfTl = 6;
            else
              Spk.PfTl = 8;
          }
        else if ( Spk.PfTl < 10 )
          Spk.PfTl = 8;
        else if ( Spk.PfTl == 10 )
          { if ( Spk.HfSeed == 8 )
              Spk.PfTl = 8;
            else
              Spk.PfTl = 12;
          }
        else if ( Spk.PfTl < 14 )
          Spk.PfTl = 12;
        else if ( Spk.PfTl == 14 )
          { if ( Spk.HfSeed == 12 )
              Spk.PfTl = 12;
            else
              Spk.PfTl = 16;
          }
        else if ( Spk.PfTl < 20 )
          Spk.PfTl = 16;
        else if ( Spk.PfTl == 20 )
          { if ( Spk.HfSeed == 16 )
              Spk.PfTl= 16;
            else
              Spk.PfTl = 24;
          }
        else if ( Spk.PfTl < 28 )
          Spk.PfTl = 24;
        else if ( Spk.PfTl == 28 )
          { if ( Spk.HfSeed == 24 )
              Spk.PfTl = 24;
            else
              Spk.PfTl = 32;
          }
        else if ( Spk.PfTl < 40 )
          Spk.PfTl = 32;
        else if ( Spk.PfTl == 40 )
          { if ( Spk.HfSeed == 32 )
              Spk.PfTl = 32;
            else
              Spk.PfTl = 48;
          }
        else if ( Spk.PfTl < 72 )
          Spk.PfTl = 48;
        else if ( Spk.PfTl == 72 )
          { if ( Spk.HfSeed == 48 )
              Spk.PfTl = 48;
            else
              Spk.PfTl = 96;
          }
        else
          Spk.PfTl = 96;
      }
  	
    if ( Spk.PfTl == Spk.HfSeed )
      Spk.HitErr = CLR;
    else if ( Spk.HitErr )
      { Spk.HfSeed = Spk.PfTl;
        Spk.HitErr = CLR;
      }
    else
     Spk.HitErr = SET;
  }


void SPK_PLL_Seed_Index( void )
  { switch( Spk.HfSeed )
      { case 1:  Spk.HfCon = 0;
                 break;
        case 2:  Spk.HfCon = 1;
                 break;
        case 3:  Spk.HfCon = 2;
                 break;
        case 4:  Spk.HfCon = 3;
                 break;
        case 6:  Spk.HfCon = 4;
                 break;
        case 8:  Spk.HfCon = 5;
                 break;
        case 12: Spk.HfCon = 6;
                 break;
        case 16: Spk.HfCon = 7;
                 break;
        case 24: Spk.HfCon = 8;
                 break;
        case 32: Spk.HfCon = 9;
                 break;
        case 48: Spk.HfCon = 10;
                 break;
        case 96: Spk.HfCon = 11;
                 break;
        default: Spk.HfCon = 11;
                 break;
      }
  }


void SPK_PLL_Divider( void )
  { BYTE Attr;
    
    
    Spk.PfTl = USB[PFTL];
    
    if ( Spk.PfTl & 0x80 )                       // Less then 0xF3
      { Spk.PfTl = 0xF3 - Spk.PfTl;
        Attr = DECEN;
      }
    else                                         // More then 0xF3
      { Spk.PfTl++;
        Attr = INCEN;
      }
    
    if ( Spk.PfTl > 1 )
      { SPK_PLL_Divider_Value();
 
        SPK_PLL_Seed_Index();                    // Change Spk.HfCon

        Spk.HfCon |= Attr;
      }
    else
      { Spk.HfCon = 0x05;                        // DECEN = 0 , Divider = 8;
        Spk.HfSeed = 0x08;
        Spk.HitErr = CLR;
      }
  }


void SPK_Reset( void )
  { Spk.Busy = CLR;
    Spk.Button = CLR;
    Spk.Vol_Mute = CLR;
    Spk.Mic_Mute = CLR;
    Spk.Mix_Mute = CLR;
    Spk.IdleRate = CLR;
    Spk.IdleRateCnt.W = CLR;
    
    Spk.HfCon = 11;                              // Same as register Default Value
    Spk.HfSeed = 96;                             // Same as register Default Value
    Spk.HitErr = SET;
  }


void Initial_SPK( void )
  { SPK_Reset();
    Initial_Wm8987l();
  }