📄 ad1819_sport1tx_isr.asm
字号:
.segment /dm dm_codec;
/* AD1819a stereo-channel data holders - used for DSP processing of audio data recieved from codec */
.VAR Left_Channel_In;
.VAR Right_Channel_In;
.VAR Left_Channel_Out;
.VAR Right_Channel_Out;
.VAR Left_Channel;
.VAR Right_Channel;
.VAR RX_left_flag = 0x00000000; /* DSP algorithm only processed when these flags are set to 1 */
.VAR RX_right_flag = 0x00000000;
.VAR ADC_valid_bits;
/* AC'97 audio frame/ISR counter, for debug purposes */
.VAR audio_frame_timer = 0;
.endseg;
.segment /pm pm_code;
Process_AD1819_Audio_Samples:
/* Build Transmit Tag Phase Slot Information */
r0 = 0x8000; /* Set Valid Frame bit 15 in slot 0 tag phase */
dm(tx1a_buf + TAG_PHASE) = r0; /* Write tag to tx-buf ASAP before it's shifted out of SPORT! */
r0 = 0; /* Clear AC97 link Audio Output Frame slots for now */
dm(tx1a_buf + COMMAND_ADDRESS_SLOT) = r0;
dm(tx1a_buf + COMMAND_DATA_SLOT) = r0;
dm(tx1a_buf + LEFT) = r0;
dm(tx1a_buf + RIGHT) = r0;
check_ADCs_for_valid_data:
r0 = dm(rx1a_buf + TAG_PHASE); /* Get ADC valid bits from tag phase slot*/
r1 = 0x1800; /* Inspect for valid L/R ADC data */
r2 = r0 and r1; /* Mask other bits in tag */
dm(ADC_valid_bits) = r2;
set_tx_slot_valid_bits:
r1 = dm(tx1a_buf + TAG_PHASE); /* set tx valid bits based on ADC valid bits info */
r3 = r2 or r1; /* set left/right channel bits in tag, if required */
dm(tx1a_buf + TAG_PHASE) = r3; /* Write tag to tx-buf ASAP before it's shifted out of SPORT! */
check_AD1819_ADC_left:
BTST r2 by M_Left_ADC; /* Check Master left ADC valid bit */
IF sz JUMP check_AD1819_ADC_right; /* If valid data then save ADC sample */
r6 = dm(rx1a_buf + LEFT); /* get Master 1819 left channel input sample */
r6 = lshift r6 by 16; /* shift up to MSBs to preserve sign in 1.31 format */
dm(Left_Channel_In) = r6; /* save to data holder for processing */
r4 = 1;
dm(RX_left_flag) = r4; /* if we have a new left sample, let the DSP filter routine know */
check_AD1819_ADC_right:
BTST r2 by M_Right_ADC; /* Check Master right ADC valid bit */
If sz rti; /* If valid data then save ADC sample */
r6 = dm(rx1a_buf + RIGHT); /* get Master 1819 right channel input sample */
r6 = lshift r6 by 16; /* shift up to MSBs to preserve sign in 1.31 format */
dm(Right_Channel_In) = r6; /* save to data holder for processing */
r4 = 1;
dm(RX_right_flag) = r4; /* if we have a new right sample, let the DSP filter routine know */
/* -------------------------------------------------------------------------------------------- */
/* user_applic( ) - User Applications Routines */
/* *** Insert DSP Algorithms Here *** */
/* */
/* Input L/R Data Streams - DM(Left_Channel_In) DM(Right_Channel_In) */
/* Output L/R Results - DM(Left_Channel_Out) DM(Right_Channel_Out) */
/* */
/* These left/right data holders are used to pipeline data through multiple modules, and */
/* can be removed if the dsp programmer needs to save instruction cycles */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* Coding TIP: */
/* The samples from the AD1819A are 16-bit and are in the lower 16 bits of the the 32-bit */
/* word. They are shifted to the most significant bit positions in order to preserve the */
/* sign of the samples when they are converted to floating point numbers. The values are */
/* also scaled to the range +/-1.0 with the integer to float conversion */
/* (f0 = float r0 by r1). */
/* */
/* To convert between our assumed 1.31 fractional number and IEEE floating point math, */
/* here are some example assembly instructions ... */
/* */
/* r1 = -31 <-- scale the sample to the range of +/-1.0 */
/* r0 = DM(Left_Channel); */
/* f0 = float r0 by r1; */
/* [Call Floating_Point_Algorithm] */
/* r1 = 31; <-- scale the result back up to MSBs */
/* r8 = fix f8 by r1; */
/* DM(Left_Channel) = r8; */
/* -------------------------------------------------------------------------------------------- */
user_applic:
/* do audio processing on input samples */
/* these flags are used for sample rates < 48 kHz */
/* at 48 kHz, these instructions are not required and can be removed */
r4 = 0x0; /* since we are not using the right flag, always clear */
dm(RX_right_flag) = r4; /* since left & right come in pairs at same fs rate, we
only need one flag (because we powered down ADCs for L/R sync).
Thus, the user can optionally remove the right flag set/clear
instructions to save cycles */
r4 = dm(RX_left_flag);
r4 = pass r4;
if eq jump playback_audio_data; /* if RX_left_flag = 1, then do audio processing */
/* delay routine will clear RX_left_flag */
do_audio_processing:
r0 = DM(effects_counter);
r0 = pass r0; /* get preset mode */
if eq call (pc, Slapback_Echo); /* check for count == 0 */
r0 = DM(effects_counter); /* check again */
r0 = pass r0; /* still the same ? */
if eq jump playback_audio_data; /* bypass if not stereo */
r0 = r0 - 1; /* decrement, must be stereo effect */
if eq call (pc, Stereo_Double_Tracking);/* check for count == 1 */
/* ---- DSP processing is finished, now the newly processed input audio sample is sent to SPORT0 I2S
channel A tx, and we now playback previous SPORT0 I2S channel A rx data to AD1819A ---- */
playback_audio_data:
/* Transmit Left and Right Valid Data every time there the ADCs have valid data */
r2 = dm(ADC_valid_bits);
tx_AD1819_DAC_left:
BTST r2 by M_Left_ADC; /* Check to see if we need to send DAC right sample */
IF sz JUMP tx_AD1819_DAC_right; /* If valid data then transmit DAC sample */
r15 = dm(Left_Channel_Out); /* get channel 1 output result */
r15 = lshift r15 by -16; /* put back in bits 0..15 for SPORT tx */
dm(tx1a_buf + LEFT) = r15; /* output right result to AD1819a Slot 3 */
tx_AD1819_DAC_right:
BTST r2 by M_Right_ADC; /* Check to see if we need to send DAC right sample */
If sz jump tx_done; /* If valid data then transmit DAC sample */
r15 = dm(Right_Channel_Out); /* get channel 2 output result */
r15 = lshift r15 by -16; /* put back in bits 0..15 for SPORT tx */
dm(tx1a_buf + RIGHT) = r15; /* output right result to AD1819a Slot 4 */
tx_done:
r0=dm(audio_frame_timer); /* get last count */
rti(db); /* return from interrupt, delayed branch */
r0=r0+1; /* increment count */
dm(audio_frame_timer)=r0; /* save updated count */
/* ----------------------------------------------------------------------------------------- */
.endseg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -