📄 dc550_audio.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 + -