📄 i2s_jz4740.c
字号:
left =((unsigned short) save_last_samples[out_busy_queue.oldid].left)+0x8000; right = (( unsigned short)save_last_samples[out_busy_queue.oldid].right)+0x8000; if(left >= 0x8000) { tmp1 = left - 0x8000; } else{ tmp1 = 0x8000 - left; } if(right >= 0x8000) { tmp2 = right - 0x8000; } else{ tmp2 = 0x8000 - right; } step_len = jz_audio_rate / 10 * 4; step_len /= 2; step_len = 0x7fff / step_len + 1;// step_len = 4; if(tmp1>=tmp2) { step_cnt=tmp1/step_len; } else { step_cnt=tmp2/step_len; } for(i=0;i<step_cnt;) { tx_con = (REG_AIC_SR & 0x00003f00) >> 8; if(tx_con < 30) { if(left - 0x8000 > step_len){ left = left - step_len; } else if(left - 0x8000 < -step_len){ left = left + step_len; }else if(left - 0x8000 >= -step_len && left - 0x8000 <= step_len) { left = 0x8000; } if(right - 0x8000 > step_len){ right = right - step_len; } else if(right - 0x8000 < -step_len){ right = right + step_len; }else if(right - 0x8000 >= -step_len && right - 0x8000 <= step_len) { right = 0x8000; } if(i%2==0){ REG_AIC_DR = left ; REG_AIC_DR = right; } else{ REG_AIC_DR = 0xffff-left; REG_AIC_DR = 0xffff-right; } i++; } } }void anti_pop_2(void){ unsigned char err; int dma = AUDIO_WRITE_DMA; int id; int i,j,tx_con=0,step_cnt,step_len; int d; unsigned short left,right,tmp1,tmp2; left =((unsigned short) save_last_samples[out_busy_queue.oldid].left)+0x8000; right = (( unsigned short)save_last_samples[out_busy_queue.oldid].right)+0x8000; if(left >= 0x8000) { tmp1 = left - 0x8000; } else{ tmp1 = 0x8000 - left; } if(right >= 0x8000) { tmp2 = right - 0x8000; } else { tmp2 = 0x8000 - right; } step_len = 4; if(tmp1>=tmp2) { step_cnt=tmp1/step_len; } else { step_cnt=tmp2/step_len; } for(i=0;i<step_cnt;) { tx_con = (REG_AIC_SR & 0x00003f00) >> 8; if(tx_con < 30) { if(left - 0x8000 > step_len){ left = left - step_len; } else if(left - 0x8000 < -step_len){ left = left + step_len; }else if(left - 0x8000 >= -step_len && left - 0x8000 <= step_len) { left = 0x8000; } if(right - 0x8000 > step_len){ right = right - step_len; } else if(right - 0x8000 < -step_len){ right = right + step_len; }else if(right - 0x8000 >= -step_len && right - 0x8000 <= step_len) { right = 0x8000; } if(i%2==0){ REG_AIC_DR = left ; REG_AIC_DR = right; } else{ REG_AIC_DR = 0xffff-left; REG_AIC_DR = 0xffff-right; } i++; } } }void anti_pop(void){ unsigned char err; int dma = AUDIO_WRITE_DMA; int id; int i,j,tx_con=0,step_cnt,step_len; int d; unsigned short left,right,tmp1,tmp2; left =((unsigned short) save_last_samples[out_busy_queue.oldid].left)+0x8000; right = (( unsigned short)save_last_samples[out_busy_queue.oldid].right)+0x8000; if(left >= 0x8000) { tmp1 = left - 0x8000; } else{ tmp1 = 0x8000 - left; } if(right >= 0x8000) { tmp2 = right - 0x8000; } else { tmp2 = 0x8000 - right; } step_len = 4; if(tmp1>=tmp2) { step_cnt=tmp1/step_len; left=left; step_len=left/2; } else { step_cnt=tmp2/step_len; left=right; step_len=left/2; } for(i=0;i<step_cnt;) { tx_con = (REG_AIC_SR & 0x00003f00) >> 8; if(tx_con < 30) { if(left - 0x8000 > step_len){ left = left - step_len; } else if(left - 0x8000 < -step_len){ left = left + step_len; }else if(left - 0x8000 >= -step_len && left - 0x8000 <= step_len) { left = 0x8000; } if(i%2==0){ REG_AIC_DR = left ; REG_AIC_DR = left; } else{ REG_AIC_DR = 0xffff-left; REG_AIC_DR = 0xffff-left; } i++; } } }static void jz_i2s_replay_dma_irq (unsigned int arg){ unsigned char err; int dma = AUDIO_WRITE_DMA; int id; int i,j,tx_con=0,step_cnt,step_len; int d; unsigned short left,right,tmp1,tmp2; dma_stop(dma); if (__dmac_channel_address_error_detected(dma)) { printf("%s: DMAC address error.\n", __FUNCTION__); __dmac_channel_clear_address_error(dma); } if (__dmac_channel_transmit_end_detected(dma)) { __dmac_channel_clear_transmit_end(dma); if(pause_flag) { __intc_mask_irq(20); anti_pop(); #if 0 //insert data to DMA id = out_busy_queue.oldid;// printf("[ id:%d ; left:%d ; right:%d ]",id,save_last_samples[id].left,save_last_samples[id].right); out_dma_buf_data_count[id] = insert_pcm(out_dma_buf_data_count[id],out_dma_buf[id]);// printf("count:%d\n",out_dma_buf_data_count[id]); if(out_dma_buf_data_count[id] != 0) { dma_start(dma, out_dma_pbuf[id], PHYADDR(AIC_DR), out_dma_buf_data_count[id]); }#endif dma_stop(dma); } else { if ((id = get_buffer_id(&out_busy_queue)) < 0) printf("Strange DMA finish interrupt for AIC module\n"); put_buffer_id(&out_empty_queue, id); if ((id = get_buffer_id(&out_full_queue)) >= 0) { put_buffer_id(&out_busy_queue, id); dma_start(dma, out_dma_pbuf[id], PHYADDR(AIC_DR), out_dma_buf_data_count[id]); } else out_busy_queue.count = 0; } // if (elements_in_queue(&out_empty_queue) > 0)// OSSemPost(tx_sem); } }#endif/* * Initialize the onchip I2S controller */static void jz_i2s_initHw(void){ unsigned int aic_cr_val; //__i2s_reset(); i2s_clk = __cpm_get_i2sclk(); __i2s_disable(); __i2s_as_slave(); __i2s_set_oss_sample_size(16); __i2s_set_iss_sample_size(16); //__i2s_enable(); __i2s_disable_record(); __i2s_disable_replay(); __i2s_disable_loopback(); __i2s_set_transmit_trigger(8); __i2s_set_receive_trigger(1);}static int jz_audio_set_speed(int rate){/* 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 ? */ if (rate > 48000) rate = 48000; if (rate < 8000) rate = 8000; jz_audio_rate = rate; i2s_codec_set_samplerate(rate); return rate;}static int record_fill_1x8_u(unsigned long dst_start, int count, int id){ int cnt = 0; unsigned short data; unsigned long *s = (unsigned long*)(in_dma_buf[id]); unsigned char *dp = (unsigned char*)dst_start; while (count > 0) { count -= 4; /* count in dword */ cnt += 1; data =(unsigned short) *s++; *(dp ++) =(data+0x8080) >> 8; } return cnt;}static int record_fill_2x8_u(unsigned long dst_start, int count, int id){ int cnt = 0; unsigned short d1, d2;// unsigned long d1, d2; volatile unsigned long *s = (unsigned long*)(in_dma_buf[id]); volatile unsigned char *dp = (unsigned char*)dst_start; while (count > 0) { count -= 4; cnt += 2; s++; d1 = (unsigned short)*s; *(dp ++) = (d1+0x8000) >> 8; d2 = (unsigned short)(*s >> 16); *(dp ++) = (d2+0x8000) >> 8; } return cnt;}static int record_fill_1x16_s(unsigned long dst_start, int count, int id){ int cnt = 0; unsigned long *s = (unsigned long * )(in_dma_buf[id]); unsigned short *dp = (unsigned short *)dst_start; while (count > 0) { count -= 4; /* count in dword */ cnt += 2; /* count in byte */ *(dp ++) = (*(s++) & 0xffff); } return cnt;}static int record_fill_2x16_s(unsigned long dst_start, int count, int id){ int cnt = 0; unsigned long d1, d2; unsigned long *s = (unsigned long*)(in_dma_buf[id]); unsigned short *dp = (unsigned short *)dst_start; while (count > 0) { count -= 2; /* count in dword */ cnt += 4; /* count in byte */ d1 = *(s++); *(dp ++) = (d1 + 0x80) >> 8; d2 = *(s++); *(dp ++) = (d2 + 0x80)>> 8; } return cnt;}static inline int record_fill_all(unsigned long dst_start, int count, int id){ memcpy((void *)dst_start,(void *)in_dma_buf[id],count); return count;}static void replay_fill_1x8_u(unsigned long src_start, int count, int id){ int cnt = 0; unsigned char data; unsigned short ddata; unsigned char *s = (unsigned char *)src_start; unsigned short *dp = (unsigned short*)(out_dma_buf[id]); while (count > 0) { count -= 1; cnt += 2; data = *s++;//see ak4642en page 29// data = (unsigned char)get_new_sample((int)data); ddata = ((unsigned short) data << 8) - 0x8000; *(dp ++) = ddata; } out_dma_buf_data_count[id] = cnt;}static void replay_fill_2x8_u(unsigned long src_start, int count, int id){ int cnt = 0; unsigned char d1; unsigned long dd1; volatile unsigned char *s = (unsigned char *)src_start; volatile unsigned short *dp = (unsigned short*)(out_dma_buf[id]); while (count > 0) { count -= 2; cnt += 4 ; d1 = *s++;// d1 = (unsigned char)get_new_sample((int)d1); dd1 = ((unsigned short) d1 << 8)- 0x8000; *(dp ++) = dd1; d1 = *s++; dd1 = ((unsigned short) d1 << 8)- 0x8000; *(dp ++) = dd1; } out_dma_buf_data_count[id] = cnt;}static void replay_fill_1x16_s(unsigned long src_start, int count, int id){ int cnt = 0; unsigned short d1; unsigned long l1; volatile unsigned short *s = (unsigned short *)src_start; volatile unsigned long *dp = (unsigned long*)(out_dma_buf[id]); while (count > 0) { count -= 2; cnt += 2 ; d1 = *(s++);// d1 = (signed short)get_new_sample(d1); l1 = (unsigned long)d1; *(dp ++) = l1; *(dp ++) = l1; } cnt = cnt * 2 * jz_audio_b; out_dma_buf_data_count[id] = cnt;}static void replay_fill_2x16_s(unsigned long src_start, int count, int id){ int cnt = 0; unsigned short d1; signed short d2; unsigned long l1; unsigned short *s = (unsigned short *)src_start; unsigned long *dp = (unsigned long*)(out_dma_buf[id]);// printf("replay_fill_2x16_s dp:%x s:%x\r\n",dp,s); while (count > 0) { count -= 1; cnt += 1; d1 = *s++;// d2=(signed short)d1;// d2 = (signed short)get_new_sample(d2);// d1=(unsigned short)d2; l1 = (unsigned long)d1; *dp ++ = l1;// *dp ++ = l1; } out_dma_buf_data_count[id] = cnt; }#if 0int pcm_close(void){ int id; printf("replay some mute\n"); id = out_busy_queue.oldid; //printf("[ id:%d ; left:%d ; right:%d ]",id,save_last_samples[id].left,save_last_samples[id].right); out_dma_buf_data_count[id] = insert_pcm(out_dma_buf_data_count[id], (unsigned char *)out_dma_buf[id]); /*if(out_dma_buf_data_count[id] != 0) { dma_start(dma, out_dma_pbuf[id], PHYADDR(AIC_DR), out_dma_buf_data_count[id]); } }*/#endifstatic void (*get_volume)(void *block,int count,void *out_dma_buf, int jz_audio_factor,int shift) = NULL;static void set_audio_volume(void *p){ get_volume=p;}static inline void replay_fill_all(unsigned long src_start, int count, int id){ #if 1 int i; if(get_volume) { //printf("get_volume11111111111:%d\n",get_volume); // volatile signed short *s = (signed short*)src_start; unsigned int *p = (unsigned int *)((unsigned int)out_dma_buf[id] & (~0x20000000)); get_volume((void *)src_start,count,(void *)p,jz_audio_factor,8); dma_cache_wback_inv((unsigned long)p, count); out_dma_buf_data_count[id] = count; } else { if (jz_audio_format==AFMT_S16_LE) { short *s = (signed short*)src_start; volatile signed short value; int i; short *p = (short *)((unsigned int)out_dma_buf[id] & (~0x20000000)); for(i = 0;i < (count / 2);i++) { p[i] = ((*(s++)) * jz_audio_factor) >> 8; } dma_cache_wback_inv((unsigned long)p, count); out_dma_buf_data_count[id] = count; } else { unsigned int *p = (unsigned int *)((unsigned int)out_dma_buf[id] & (~0x20000000)); memcpy((void *)p,(void *)src_start,count); dma_cache_wback_inv((unsigned long)p, count); out_dma_buf_data_count[id] = count; } }#else unsigned int *p = (unsigned int *)((unsigned int)out_dma_buf[id] & (~0x20000000)); memcpy((void *)p,(void *)src_start,count); dma_cache_wback_inv((unsigned long)p, count); out_dma_buf_data_count[id] = count;#endif //printf("id %d count = %d src_start = %x\n",id,count,src_start);#if 0 //save the last left and right sample data volatile signed short *s = (signed short*)src_start; volatile signed short value;// printf("\nsrc %d %d ",*(s + (count/2) -2) , *(s + (count/2) -1) );/* for(i= (count/2) - 4;i < (count/2) ; i++) { value = (signed short) ( *(s + i) ); printf("\n( i:%d ; val:%d )",i,value); }*/ save_last_samples[id].left = (signed short) ( *(s + (count/2) -2) ); save_last_samples[id].right = (signed short) ( *(s + (count/2) -1) );#endif// printf("\n{{ id:%d ; L:%d ; R:%d }}",id,save_last_samples[id].left,save_last_samples[id].right);}static unsigned int jz_audio_set_format(unsigned int fmt){ switch (fmt) { case AFMT_U8: jz_audio_format = fmt; jz_update_filler(fmt, jz_audio_channels); break; case AFMT_S16_LE: jz_audio_format = fmt; jz_update_filler(fmt, jz_audio_channels); break; } return jz_audio_format;}static short jz_audio_set_channels(short channels){ switch (channels) { case 1: //i2s_codec_set_channel(1); //jz_audio_channels = channels; //jz_update_filler(jz_audio_format, jz_audio_channels); //break; case 2: jz_audio_channels = channels; jz_update_filler(jz_audio_format, jz_audio_channels); break; case 0: break; } return jz_audio_channels;}static void jz_audio_reset_buffer(void){ int i; in_empty_queue.count = QUEUE_MAX; out_empty_queue.count = QUEUE_MAX; for (i=0;i<QUEUE_MAX;i++) { in_empty_queue.id[i] = i; out_empty_queue.id[i] = i; } in_busy_queue.count = 0; in_full_queue.count = 0; out_busy_queue.count = 0; out_full_queue.count = 0;}static void jz_audio_reset(void){ __i2s_disable_replay(); __i2s_disable_receive_dma(); __i2s_disable_record(); __i2s_disable_transmit_dma(); /* if(HP_on_off_flag == 1) { HP_on_off_flag = 0; HP_turn_off(); } */ jz_audio_reset_buffer(); }/* I2S codec initialisation. */static int jz_i2s_codec_init(void){ i2s_codec_init(); return 0;}static void jz_update_filler(int format, int channels){#define TYPE(fmt,ch) (((fmt)<<3) | ((ch)&7)) /* up to 8 chans supported. */ switch (TYPE(format, channels)) { case TYPE(AFMT_U8, 1): jz_audio_b = 8; replay_filler = replay_fill_all;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -