⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc550_audio.c

📁 一款经典的数字电话设计资料
💻 C
字号:
/*****************************************************************************/
/*  CONFIDENTIAL                                                             */
/*  Sigpro Copyright 2003, All rights reserved                               */
/*****************************************************************************/
/*  CLIENT:  Telematrix                                                      */
/*  PROJECT: DC550 Digital Centrex Phone                                     */
/*  FILE:    dc550_audio.c                                                   */
/*****************************************************************************/
/*  The Audio Controller will interpret and execute audio commands issued by */
/*  the Software Controller.                                                 */
/*****************************************************************************/

#define DC550_AUDIO_EXTERN
// #include "dc550_usartdriver.h"
#include "dc550_audio.h"
#include "dc550_i2cdriver.h"
#include "dc550_interrupt.h"


/******************************************************************************
 *  LOCAL/STATIC VARIABLES
 *****************************************************************************/
/*
030321 Modification:
enum enum_RING_STATE { RINGER_OFF=0, RINGER_LOW_TONE, RINGER_HIGH_TONE };
typedef enum enum_RING_STATE RING_STATE;
*/
// Keeps track of current audio state
struct str_audioState {
    BOOL          allAudioOff;
    AUDIO_CHANNEL hearChannel;
    AUDIO_CHANNEL talkChannel;
    BOOL          muteOn;
    BOOL          buzzing;
    BOOL          ringing;
    /*
    030321 Modification:
    RING_STATE    ringState;
    unsigned int  quietTimer;
    unsigned int  warbleTimer;
    unsigned int  ringTimer;
    */
    int           handsetVolume;
    int           headsetVolume;
    int           speakerVolume;
    int           ringingVolume;
};
static struct str_audioState audioState;


/******************************************************************************
 *  FUNCTION: void audio_init(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called during the initialization phase to initialize all
 *  of the audio controller variables.
 *****************************************************************************/
void audio_init(void)
{
  // Make sure the port pins are set up properly
  AUDIO_RX_SEL_DIR |= AUDIO_RX_SEL_MSK;
  AUDIO_TX_SEL_DIR |= AUDIO_TX_SEL_MSK;
  AUDIO_MIC_SEL_DIR |= AUDIO_MIC_SEL_MSK;
  AUDIO_HEAD_EN_DIR |= AUDIO_HEAD_EN_MSK;
  AUDIO_SPKR_EN_DIR |= AUDIO_SPKR_EN_MSK;
  AUDIO_EAR_EN_DIR |= AUDIO_EAR_EN_MSK;

  // Set the power good pin to input
  POWERGOOD_DIR &= ~POWERGOOD_PIN;

  // Set buzzer pin to digital output
  BUZZER_SEL &= ~(BUZZER_PIN);
  BUZZER_DIR |= BUZZER_PIN;

  audioState.allAudioOff = TRUE;
  audioState.hearChannel = AUDIO_HANDSET;
  audioState.talkChannel = AUDIO_HANDSET;
  audioState.muteOn = FALSE;
  audio_ringer(FALSE);
  audio_buzzer(FALSE);

}

/*
030321 Modification:
int audio_ringerStateMachine(void)
{
    if (!audioState.ringing)
        return 0;

    // Execute Ringer State Machine
    switch (audioState.ringState) {
    case (RINGER_OFF):
        if ((interrupt_counter-audioState.quietTimer) >= QUIET_TICKS) {
            audioState.ringState = RINGER_LOW_TONE;
            audioState.warbleTimer = interrupt_counter;
            audioState.ringTimer = interrupt_counter;

            // Start playing low tone
            dtmf_PlayTone(0x30);
            return 1;
        }
        break;
 
    case (RINGER_LOW_TONE):
        if ((interrupt_counter-audioState.warbleTimer) >= WARBLE_TICKS) {
            if ((interrupt_counter-audioState.ringTimer) >= RING_TICKS) {
                audioState.ringState = RINGER_OFF;
                audioState.quietTimer = interrupt_counter;

                // Turn tones off
                dtmf_PlayTone(DTMF_OFF);
                return 1;
            }
            else {
                audioState.ringState = RINGER_HIGH_TONE;
                audioState.warbleTimer = interrupt_counter;

                // Turn on high tone
                dtmf_PlayTone(0x33);
                return 1;
            }
        }
        break;

    case (RINGER_HIGH_TONE):
        if ((interrupt_counter-audioState.warbleTimer) >= WARBLE_TICKS) {
            if ((interrupt_counter-audioState.ringTimer) >= RING_TICKS) {
                audioState.ringState = RINGER_OFF;
                audioState.quietTimer = interrupt_counter;

                // Turn tones off
                dtmf_PlayTone(DTMF_OFF);
                return 1;
            }
            else {
                audioState.ringState = RINGER_LOW_TONE;
                audioState.warbleTimer = interrupt_counter;

                // Turn on low tone
                dtmf_PlayTone(0x30); 
                return 1;
            }
        }
        break;
    }
    return 0;
}
*/

/******************************************************************************
 *  FUNCTION: void audio_exec(void)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called to execute the audio controller task.
 *****************************************************************************/
#define AUDIO_NUL_SEL_MSK AUDIO_MIC_SEL_MSK

void audio_exec(void)
{
    /*
    030321 Modification:
    // First Check for Ring Processing since it's Time Sensitive
    if (audioState.ringing) {
        // Make sure audio is being sourced by the DTMF chip
        AUDIO_RX_SEL_OUT &= ~AUDIO_RX_SEL_MSK;

        // Make sure the audio output is going to the speaker
        digpot_Volume(audioState.ringingVolume);
        AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
        AUDIO_EAR_EN_OUT &= ~AUDIO_EAR_EN_MSK;
        AUDIO_SPKR_EN_OUT |= AUDIO_SPKR_EN_MSK;

        // Send the "NULL" muc to the line
        AUDIO_MIC_SEL_OUT |= AUDIO_NUL_SEL_MSK;
        AUDIO_TX_SEL_OUT |= AUDIO_TX_SEL_MSK;

        return;
    }
    */
    if(audioState.ringing) {
    
        // When ringing, the speaker is used for audio output
        if( (POWERGOOD_IN & POWERGOOD_PIN) && 
            (audioState.ringingVolume > AUDIO_NOPOWER_RINGVOL) )
          digpot_Volume(AUDIO_NOPOWER_RINGVOL);
        else
          digpot_Volume(audioState.ringingVolume);
        #if PREPRODUCTION
          AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
          AUDIO_EAR_EN_OUT &= ~AUDIO_EAR_EN_MSK;
          AUDIO_SPKR_EN_OUT |= AUDIO_SPKR_EN_MSK;
        #else
          AUDIO_HEAD_EN_OUT |= AUDIO_HEAD_EN_MSK;
          AUDIO_EAR_EN_OUT |= AUDIO_EAR_EN_MSK;
          AUDIO_SPKR_EN_OUT &= ~AUDIO_SPKR_EN_MSK;
        #endif
        
        if(audioState.buzzing)
            // If also buzzing, select the buzzer input
            AUDIO_RX_SEL_OUT &= ~AUDIO_RX_SEL_MSK;
        else
            // Otherwise, make sure audio is being sourced by the line
            AUDIO_RX_SEL_OUT |= AUDIO_RX_SEL_MSK;

        // Send the "NULL" muc to the line
        AUDIO_TX_SEL_OUT &= ~AUDIO_TX_SEL_MSK;

        // Make sure the speaker microphone is not selected so
        //   that the TEA1099 phone chip will not go beserk
        AUDIO_MIC_SEL_OUT |= AUDIO_MIC_SEL_MSK;
        return;
    }

    if (audioState.allAudioOff) {
        // Make sure audio tx and rx channels are connected to
        //  the DTMF chip
        AUDIO_RX_SEL_OUT &= ~AUDIO_RX_SEL_MSK;
        AUDIO_TX_SEL_OUT &= ~AUDIO_TX_SEL_MSK;
        
        // If we're also buzzing, turn on the buzzer at the ringer volume
        if(audioState.buzzing) {
          if( (POWERGOOD_IN & POWERGOOD_PIN) && 
              (audioState.ringingVolume > AUDIO_NOPOWER_RINGVOL) )
            digpot_Volume(AUDIO_NOPOWER_RINGVOL);
          else
            digpot_Volume(audioState.ringingVolume);
        }
        else
          digpot_Volume(0);

        // Make the speaker the audio output
        #if PREPRODUCTION
          AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
          AUDIO_EAR_EN_OUT &= ~AUDIO_EAR_EN_MSK;
          AUDIO_SPKR_EN_OUT |= AUDIO_SPKR_EN_MSK;
        #else
          AUDIO_HEAD_EN_OUT |= AUDIO_HEAD_EN_MSK;
          AUDIO_EAR_EN_OUT |= AUDIO_EAR_EN_MSK;
          AUDIO_SPKR_EN_OUT &= ~AUDIO_SPKR_EN_MSK;
        #endif

        // Make sure the speaker microphone is not selected so
        //   that the TEA1099 phone chip will not go beserk
        AUDIO_MIC_SEL_OUT |= AUDIO_MIC_SEL_MSK;
        return;
    }

    // Process Incoming Audio Channel
    switch (audioState.hearChannel) {
      case (AUDIO_HANDSET):
        digpot_Volume(audioState.handsetVolume);
        #if PREPRODUCTION
          AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
          AUDIO_SPKR_EN_OUT &= ~AUDIO_SPKR_EN_MSK;
          AUDIO_EAR_EN_OUT |= AUDIO_EAR_EN_MSK;
        #else
          AUDIO_HEAD_EN_OUT |= AUDIO_HEAD_EN_MSK;
          AUDIO_SPKR_EN_OUT |= AUDIO_SPKR_EN_MSK;
          AUDIO_EAR_EN_OUT &= ~AUDIO_EAR_EN_MSK;
        #endif
        break;
      case (AUDIO_SPEAKER):
        if( (POWERGOOD_IN & POWERGOOD_PIN) && 
            (audioState.speakerVolume > AUDIO_NOPOWER_SPEAKERVOL) )
          digpot_Volume(AUDIO_NOPOWER_SPEAKERVOL);
        else
          digpot_Volume(audioState.speakerVolume);
        #if PREPRODUCTION
          AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
          AUDIO_EAR_EN_OUT &= ~AUDIO_EAR_EN_MSK;
          AUDIO_SPKR_EN_OUT |= AUDIO_SPKR_EN_MSK;
        #else
          AUDIO_HEAD_EN_OUT |= AUDIO_HEAD_EN_MSK;
          AUDIO_EAR_EN_OUT |= AUDIO_EAR_EN_MSK;
          AUDIO_SPKR_EN_OUT &= ~AUDIO_SPKR_EN_MSK;
        #endif
        break;
      case (AUDIO_HEADSET):
        digpot_Volume(audioState.headsetVolume);
        #if PREPRODUCTION
          AUDIO_SPKR_EN_OUT &= ~AUDIO_SPKR_EN_MSK;
          AUDIO_EAR_EN_OUT |= AUDIO_EAR_EN_MSK;
          AUDIO_HEAD_EN_OUT |= AUDIO_HEAD_EN_MSK;
        #else
          AUDIO_SPKR_EN_OUT |= AUDIO_SPKR_EN_MSK;
          AUDIO_EAR_EN_OUT |= AUDIO_EAR_EN_MSK;
          AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
        #endif
        break;
    }
    if(audioState.buzzing) {
        // If also buzzing, select the buzzer input
        AUDIO_RX_SEL_OUT &= ~AUDIO_RX_SEL_MSK;
    }
    else {
        // Make sure audio is being sourced by the line
        AUDIO_RX_SEL_OUT |= AUDIO_RX_SEL_MSK;
    }

    // Process outgoing audio channel
    if (audioState.muteOn || audioState.buzzing) {
        // Make sure the outgoing audio channel is connected
        //   to the DTMF chip.
        AUDIO_TX_SEL_OUT &= ~AUDIO_TX_SEL_MSK;
        
        // Make sure the speaker microphone is not selected so
        //   that the TEA1099 phone chip will not go beserk
        AUDIO_MIC_SEL_OUT |= AUDIO_MIC_SEL_MSK;
    }
    else {
        // Connect the specified microphone to the line
        switch (audioState.talkChannel) {
        case (AUDIO_HANDSET):
            #if PREPRODUCTION
              AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
            #endif
            AUDIO_MIC_SEL_OUT |= AUDIO_MIC_SEL_MSK;
            break;
	case (AUDIO_SPEAKER):
            #if PREPRODUCTION
              AUDIO_HEAD_EN_OUT &= ~AUDIO_HEAD_EN_MSK;
            #endif
            AUDIO_MIC_SEL_OUT &= ~AUDIO_MIC_SEL_MSK;
            break;
	case (AUDIO_HEADSET):
            #if PREPRODUCTION
              AUDIO_HEAD_EN_OUT |= AUDIO_HEAD_EN_MSK;
            #endif
            AUDIO_MIC_SEL_OUT |= AUDIO_MIC_SEL_MSK;
            break;
	}
        AUDIO_TX_SEL_OUT |= AUDIO_TX_SEL_MSK;
    }

}

/******************************************************************************
 *  FUNCTION: void audio_select(AUDIO_CHANNEL channel)
 ******************************************************************************
 *  DESCRIPTION:
 *  This function is called to select an audio channel for the telephone.
 *  The channel specified will be used for both audio reception and
 *  transmission over the line.  If the channel specified is AUDIO_OFF,
 *  the line signal will be diverted from the audio reception pathway.
 *****************************************************************************/
int audio_select(AUDIO_CHANNEL channel)
{
    switch (channel) {
    case AUDIO_OFF:
        // Turn audio off and revert to defaults
        audioState.allAudioOff = TRUE;
        if (audioState.ringing)
            audio_ringer(FALSE);
        audioState.muteOn = FALSE;
        audioState.hearChannel = AUDIO_HANDSET;
        audioState.talkChannel = AUDIO_HANDSET;
        return 0;
    case AUDIO_HANDSET:
    case AUDIO_HEADSET:
    case AUDIO_SPEAKER:
        audioState.hearChannel = channel;
        audioState.talkChannel = channel;
        if (audioState.ringing)
            audio_ringer(FALSE);
        audioState.allAudioOff = FALSE;
        return 0;
    }

    // No other values for channel are legal
    return -1;
}


int audio_volume(AUDIO_CHANNEL channel, int volume)
{
    switch (channel) {
    case AUDIO_HEADSET:
        // dc550_printf("\r\nSet headset volume to %d", volume);
        audioState.headsetVolume = volume;
        break;
    case AUDIO_HANDSET:
        // dc550_printf("\r\nSet handset volume to %d", volume);
        audioState.handsetVolume = volume;
        break;
    case AUDIO_SPEAKER:
        // dc550_printf("\r\nSet speaker volume to %d", volume);
        audioState.speakerVolume = volume;
        break;
    case AUDIO_RINGER:
        // dc550_printf("\r\nSet ringer volume to %d", volume);
        audioState.ringingVolume = volume;
        break;
    }
    return 0;
}

int audio_mute(BOOL muteOn)
{
    audioState.muteOn = muteOn;
    // 030321: dtmf_PlayTone(DTMF_OFF);
    return 0;
}

int audio_ringer(BOOL ringerOn)
{
    if (ringerOn) {
        // 030321: dtmf_PlayTone(DTMF_OFF);
        // 030321: digpot_Volume(audioState.ringingVolume);
        // 030321: audioState.hearChannel = AUDIO_SPEAKER;
        audioState.ringing = TRUE;
        // 030321: audioState.ringState = RINGER_OFF;
        // 030321: audioState.quietTimer = interrupt_counter;
        // 030321: audioState.warbleTimer = 0;
        // 030321: audioState.ringTimer = interrupt_counter;
    }
    else {
        // 030321: dtmf_PlayTone(DTMF_OFF);
        audioState.ringing = FALSE;
    }
    return 0;
}

int audio_buzzer(BOOL buzzerOn)
{
  if (buzzerOn) {
    audioState.buzzing = TRUE;
    // 030321: dtmf_PlayTone(DTMF_BUZZER);
    BUZZER_OUT &= ~(BUZZER_PIN);       // Set buzzer pin output at 0
    interrupt_buzzercounter =
      INTERRUPT_BUZZERFREQUENCY;       // Turn on buzzer counter
  }
  else {
    audioState.buzzing = FALSE;
    // 030321: dtmf_PlayTone(DTMF_OFF);
    interrupt_buzzercounter = 0;       // Turn off buzzer counter
    BUZZER_OUT &= ~(BUZZER_PIN);       // Set buzzer pin output at 0
  }
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -