📄 aud_atom.c
字号:
// YYD, added for PCM supportint aud_atom_set_pcm_fmt(AUD_PCM_FORMAT_CONFIG *pcmcfg){ unsigned long val=0; PDEBUG("PCM_FMT: sign = %d, channel = %d, bits = %d, freq = %d, endian=%d\n", pcmcfg->sign, pcmcfg->channel, pcmcfg->bits, pcmcfg->freq, pcmcfg->endian); // set parameteres val = MF_DCR(AUD_DSP_CTRL); val &= ~AUD_DSP_PCM_MASK; // clear current switch(pcmcfg->sign) { case AUD_PCM_SIGNED: val |= AUD_DSP_PCM_SIGNED; break; case AUD_PCM_UNSIGNED: val |= AUD_DSP_PCM_UNSIGNED; break; } switch(pcmcfg->channel) { case AUD_PCM_MONO: val |= AUD_DSP_PCM_MONO; break; case AUD_PCM_STEREO: val |= AUD_DSP_PCM_STEREO; break; } switch(pcmcfg->bits) { case AUD_PCM_20BIT: val |= AUD_DSP_PCM_20BIT; break; case AUD_PCM_18BIT: val |= AUD_DSP_PCM_18BIT; break; case AUD_PCM_8BIT: val |= AUD_DSP_PCM_8BIT; break; case AUD_PCM_16BIT: default: val |= AUD_DSP_PCM_16BIT; break; } switch(pcmcfg->freq) { case AUD_PCM_16KHZ: val |= AUD_DSP_PCM_16KHZ; break; case AUD_PCM_32KHZ: val |= AUD_DSP_PCM_32KHZ; break; case AUD_PCM_22_05KHZ: val |= AUD_DSP_PCM_22_05KHZ; break; case AUD_PCM_44_1KHZ: val |= AUD_DSP_PCM_44_1KHZ; break; case AUD_PCM_24KHZ: val |= AUD_DSP_PCM_24KHZ; break; case AUD_PCM_48KHZ: val |= AUD_DSP_PCM_48KHZ; break; // untested modes case AUD_PCM_8KHZ: val |= AUD_DSP_PCM_8KHZ; break; case AUD_PCM_11_025KHZ: val |= AUD_DSP_PCM_11_025KHZ; break; case AUD_PCM_12KHZ: val |= AUD_DSP_PCM_12KHZ; break; case AUD_PCM_64KHZ: val |= AUD_DSP_PCM_64KHZ; break; case AUD_PCM_88_2KHZ: val |= AUD_DSP_PCM_88_2KHZ; break; case AUD_PCM_96KHZ: val |= AUD_DSP_PCM_96KHZ; break; default: val |= AUD_DSP_PCM_44_1KHZ; break; } MT_DCR(AUD_DSP_CTRL, val); // set the endian of audio#if 1 val = MF_DCR(AUD_CTRL2); val &= ~DECOD_AUD_CTRL2_ENDIAN_MASK; // clear current switch(pcmcfg->endian) { case AUD_PCM_BIG_ENDIAN: val |= DECOD_AUD_CTRL2_BIG_ENDIAN; break; case AUD_PCM_LITTLE_ENDIAN: val |= DECOD_AUD_CTRL2_LITTLE_ENDIAN; break; } MT_DCR(AUD_CTRL2, val); #endif aud_atom_reset_rb(); // YYD, as required by uc 3.01 after set stream format return 0;}// end of YYD addedvoid aud_atom_init_tv(){ unsigned long reg; reg = MF_DCR(AUD_CTRL0) & (~DECOD_AUD_CTRL0_CLIP_EN); MT_DCR(AUD_CTRL0, reg);}void aud_atom_init_clip(){ unsigned long reg; reg = MF_DCR(AUD_CTRL0); MT_DCR(AUD_CTRL0, reg | DECOD_AUD_CTRL0_CLIP_EN);}void aud_atom_close_clip(){ unsigned long reg; unsigned long ctrl0; unsigned long t1; ctrl0 = MF_DCR(AUD_CTRL0) & ~DECOD_AUD_CTRL0_CLIP_EN; /*-------------------------------------------------------------------------+ | Reset the clip regs. Turning clip mode from on to off will reset the | working clip length reg but not the queued clip length reg so we turn the | clip mode from off to on twice. The first time to clear the working length | reg. Turning clip mode back on will transfer the queued clip regs to the | working clip regs and reset block valid. Then turning clip mode off again | will reset the working length again. | | Note: DECOD_AUD_CTRL0_START_PARSING mus be turned on to allow the stream | busy status to be cleared. +-------------------------------------------------------------------------*/ reg=ctrl0 | DECOD_AUD_CTRL0_START_PARSING; MT_DCR(AUD_CTRL0, reg); /*-------------------------------------------------------------------------+ | Reset the rate buffer. If the rate bufer is full, stream busy will not | reset. +-------------------------------------------------------------------------*/ aud_atom_reset_rb(); /*-------------------------------------------------------------------------+ | Must wait for stream busy to clear before re-enabling clip mode or the | decoder state machine will get confused +-------------------------------------------------------------------------*/ for(t1=MF_SPR(SPR_TBL);MF_DCR(AUD_QLR) & DECOD_AUD_QLR_SB;) { if(MF_SPR(SPR_TBL) - t1 >= (__TMRCLK/1000)*5) { break; } } MT_DCR(AUD_CTRL0, reg | DECOD_AUD_CTRL0_CLIP_EN); MT_DCR(AUD_CTRL0,reg); aud_atom_reset_rb(); for(t1=MF_SPR(SPR_TBL);MF_DCR(AUD_QLR) & DECOD_AUD_QLR_SB;) { if(MF_SPR(SPR_TBL) - t1 >= (__TMRCLK/1000)*5) { break; } } MT_DCR(AUD_CTRL0,ctrl0); }int aud_atom_buf_ready(){ return (MF_DCR(AUD_QLR) & DECOD_AUD_QLR_BV) ? 0 : 1;}int aud_atom_buf_ready2(){ return (MF_DCR(AUD_QLR2) & DECOD_AUD_QLR_BV) ? 0 : 1;}void aud_atom_write_clip(CLIPINFO *pInfo){ unsigned long reg; PDEBUG("write clip start = 0x%8.8lx, len = 0x%8.8lx \n", pInfo->uClipAdrOff, pInfo->uClipLen); reg = pInfo->uClipLen & 0x1fffff; //write to audio decoder MT_DCR(AUD_QAR, pInfo->uClipAdrOff); //at most 2M MT_DCR(AUD_QLR, reg | DECOD_AUD_QLR_BV);}void aud_atom_write_clip2(CLIPINFO *pInfo){ unsigned long reg; PDEBUG("write clip start = 0x%8.8lx, len = 0x%8.8lx \n", pInfo->uClipAdrOff, pInfo->uClipLen); reg = pInfo->uClipLen & 0x1fffff; //write to audio decoder MT_DCR(AUD_QAR2, pInfo->uClipAdrOff); //at most 2M MT_DCR(AUD_QLR2, reg | DECOD_AUD_QLR_BV);}void aud_atom_set_irq_mask(UINT32 mask){ MT_DCR(AUD_IMR, mask);}UINT32 aud_get_irq_status(){ return MF_DCR(AUD_ISR);}void aud_atom_irq_handler(UINT uIrq, void *pData){ unsigned int reg; TASK_MSG msg; PDEBUG("\n[IRQ = %d\n", uIrq); reg = MF_DCR(AUD_ISR); if ((reg & DECOD_AUD_INT_CCC) != 0) { /*data = MF_DCR(AUD_CTRL0) & (~DECOD_AUD_CTRL0_ENABLE_SYNC); MT_DCR(AUD_CTRL0, data); DEMUX_CHAN_CHAN_DONE(AUD_CHAN_CHAN_DONE); DEMUX_PCR_CALLBACK(XP_CALLBACK_RUN); if ((__audio_mute == 0) && (__audio_playing != 0)) { mpeg_a_hw_aud_unmute(); }*/ aud_cc_done(); if(_mute == 0) aud_atom_unmute(); PDEBUG("channel change done\n"); } if ((reg & DECOD_AUD_INT_RTBC) != 0) { //DEMUX_PCR_CALLBACK(XP_CALLBACK_RUN); ; } if ((reg & DECOD_AUD_INT_AMSI) != 0) { STC_T stc; //audio master if(MF_DCR(AUD_DSR) & DECOD_AUD_DSR_SYNC_MASTER) { aud_atom_get_pts(&stc); vid_atom_set_stc(&stc); } } if ((reg & DECOD_AUD_INT_CM) != 0) { //schedule a task for this interrupt PDEBUG("main block ready\n"); msg.uMsgType = AUD_MSG_BLOCK_READ; //message type msg.ulPara1 = reg; //interrupt status msg.ulPara2 = 0; os_call_irq_task(uIrq, &msg); } if ((reg & DECOD_AUD_INT_CM2) != 0) { //schedule a task for this interrupt PDEBUG("mixer block ready\n"); msg.uMsgType = AUD_MSG_BLOCK_READ2; //message type msg.ulPara1 = reg; //interrupt status msg.ulPara2 = 0; os_call_irq_task(uIrq, &msg); } PDEBUG("\n]\n"); return;}INT aud_atom_load_microcode(const unsigned short *code, int count){ int i; /*-------------------------------------------------------------------------+ | Enable microcode download. +-------------------------------------------------------------------------*/ i = (MF_DCR(AUD_CTRL0) & ~(DECOD_AUD_CTRL0_DOWNLOAD_EN | DECOD_AUD_CTRL0_DOWNLOAD_END)); MT_DCR(AUD_CTRL0, i); MT_DCR(AUD_CTRL0, i | DECOD_AUD_CTRL0_DOWNLOAD_EN); /*-------------------------------------------------------------------------+ | Load microcode. +-------------------------------------------------------------------------*/ for (i = 0; i < (count / 2); i++) { MT_DCR(AUD_IMFD, ((unsigned long *) code)[i]); } /*-------------------------------------------------------------------------+ | Signal end of microcode load. +-------------------------------------------------------------------------*/ i = (MF_DCR(AUD_CTRL0) & ~(DECOD_AUD_CTRL0_DOWNLOAD_EN | DECOD_AUD_CTRL0_DOWNLOAD_END)); MT_DCR(AUD_CTRL0, i); // turn off download enable MT_DCR(AUD_CTRL0, i | DECOD_AUD_CTRL0_DOWNLOAD_END);// turn on valid microcode return (0);}INT aud_atom_load_dfile(void *base, const unsigned char *dfile, int df_len, unsigned long rb_off){ unsigned char *des; /*-------------------------------------------------------------------------+ | Compute where data file should be stored in Audio Offsets Temp Area +-------------------------------------------------------------------------*/ des = (unsigned char *) ((base + ( rb_off & DECOD_AUD_OFFSETS_TEMP_MASK) * 4096) + DECOD_AUD_OFFSETS_TEMP_HDR_SIZE); PDEBUG("dfile des = 0x%8.8x, dfile len = 0x%8.8x\n", des, df_len); /*-------------------------------------------------------------------------+ | Copy Data file into Audio Segment 1 Temp Data Area +-------------------------------------------------------------------------*/ memcpy(des, dfile, df_len); return(0);}void aud_atom_init_irq_mask(){ UINT32 flags; flags = os_enter_critical_section(); MT_DCR(AUD_IMR, DEF_AUD_IRQ_MASK); os_leave_critical_section(flags);}void aud_atom_reg_dump(){ PDEBUG("CTRL 0 = 0x%8x\n", MF_DCR(AUD_CTRL0)); PDEBUG("CTRL 1 = 0x%8.8x\n", MF_DCR(AUD_CTRL1)); PDEBUG("CTRL 2 = 0x%8.8x\n", MF_DCR(AUD_CTRL2)); PDEBUG("MEM SEG 1 = 0x%8.8x\n", MF_DCR(AUD_SEG1)); PDEBUG("MEM SEG 2 = 0x%8.8x\n", MF_DCR(AUD_SEG2)); PDEBUG("MEM SEG 3 = 0x%8.8x\n", MF_DCR(AUD_SEG3)); PDEBUG("INT MASK = 0x%8.8x\n", MF_DCR(AUD_IMR)); /*PDEBUG("FRAME BUF = 0x%8.8x\n", MF_DCR(VID_FRAME_BUF)); PDEBUG("RB BUF = 0x%8.8x\n", MF_DCR(VID_RB_BASE)); PDEBUG("RB SIZE = 0x%8.8x\n", MF_DCR(VID_RB_SIZE));*/}inline void aud_atom_reset_rb(){ MT_DCR(AUD_CMD, DECOD_AUD_CMD_DSP_RESET);}inline INT aud_atom_dsp_ready(){ return !(MF_DCR(AUD_DSR) & DECOD_AUD_DSR_COMMAND_COM); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -