UDA1341不能录音的解决方法
来源:互联网 发布:空知英秋讨厌中国 知乎 编辑:程序博客网 时间:2024/05/17 05:57
原文地址:http://www.hhcn.com/cgi-bin/topic.cgi?forum=3&topic=613&show=125
===================================================================
static ssize_t smdk2410_audio_read(struct file *file, char *buffer,
size_t count, loff_t * ppos)
{
const char *buffer0 = buffer;
audio_stream_t *s = &input_stream;
int chunksize, ret = 0;
DPRINTK("audio_read: count=%d\n", count);
/*
if (ppos != &file->f_pos)
return -ESPIPE;
*/
if (!s->buffers) {
int i;
if (audio_setup_buf(s))
return -ENOMEM;
for (i = 0; i < s->nbfrags; i++) {
audio_buf_t *b = s->buf;
down(&b->sem);
s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, s->fragsize);
NEXT_BUF(s, buf);
}
}
while (count > 0) {
audio_buf_t *b = s->buf;
/* Wait for a buffer to become full */
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
if (down_trylock(&b->sem))
break;
} else {
ret = -ERESTARTSYS;
if (down_interruptible(&b->sem))
break;
}
chunksize = b->size;
if (chunksize > count)
chunksize = count;
DPRINTK("read %d from %d\n", chunksize, s->buf_idx);
if (copy_to_user(buffer, b->start + s->fragsize - b->size,
chunksize)) {
up(&b->sem);
return -EFAULT;
}
b->size -= chunksize;
buffer += chunksize;
count -= chunksize;
if (b->size > 0) {
up(&b->sem);
break;
}
/* Make current buffer available for DMA again */
s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, s->fragsize);
NEXT_BUF(s, buf);
}
if ((buffer - buffer0))
ret = buffer - buffer0;
// DPRINTK("audio_read: return=%d\n", ret);
return ret;
}
static int __init audio_init_dma(audio_stream_t * s, char *desc)
{
int ret ;
s3c2410_dmasrc_t source;
int hwcfg;
unsigned long devaddr;
dmach_t channel;
int dcon;
unsigned int flags = 0;
if(s->dma_ch == DMA_CH2){
channel = 2;
source = S3C2410_DMASRC_MEM;
hwcfg = 3;
devaddr = 0x55000010;
dcon = 0xa0800000;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);
s3c2410_dma_config(channel, 2, dcon);
s3c2410_dma_set_buffdone_fn(channel, audio_dmaout_done_callback);
s3c2410_dma_setflags(channel, flags);
s->dma_ok = 1;
return ret;
}
else if(s->dma_ch == DMA_CH1){
channel =1;
source =S3C2410_DMASRC_HW;
hwcfg =3;
devaddr = 0x55000010;
dcon = 0xa2900000;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_in, NULL);
s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);
s3c2410_dma_config(channel, 2, dcon);
s3c2410_dma_set_buffdone_fn(channel, audio_dmain_done_callback);
s3c2410_dma_setflags(channel, flags);
s->dma_ok =1;
return ret ;
}
else
return 1;
}
小弟搞uda1341的录音部分已多时,现在终于可以正常播音、录音了,现把驱程公开,希望对正在为此问题烦恼的朋友有所帮助^_^
首先说明一下:
1、 驱程源于中国linux公社->嵌入式linux2.6内核专题:
http://www.linuxfans.org/nuke/modules.php?name=Forums&file=viewtopic&t=112750&postdays=0&postorder=asc&start=30
上的牛貼,稍加修改就可以使用madplay正常播放mp3,但它提供的源码录音部分没做好。
2、 小弟参考网上其它大虾的讨论和三星、uda1341的datasheet修改了驱动程序(见红色部分),其中smdk2410_audio_read函数中注释了:
if (ppos != &file->f_pos)
return -ESPIPE;
部分是因为此处会造成死锁的现象,也就是经常在网上看到的:
cat: Read error: Illegal seek
3、 按照第2步修改了驱动程序后还是不行,出现:
dma1: loadbuffer:timeout loading buffer
的错误,一直没搞清楚为什么。
最后,参考华恒提供的uda13800驱程,修改了dcon寄存器的配置(如蓝色部分),困扰了我一个月的问题终于解决了^_^
借此机会,想向各位刚入门的朋友提点建议:
1、不要一味的找现在(最好是什么都不用修改)的驱动程序,世界上没有免费的午餐。好好的研究一下驱程并大胆的去修改驱程才会学到更多东西。我在找工的时候总被问到的一个问题是:你在移植哪一部分的时候收获最大,你都移植了些什么,为什么要这样移植?
2、在发贴之前先看一下论坛上的精华贴。我经常看到同一个问题有不少的人重重复复的去问题,其实问题的答案早在以前的精华贴里。
3、要学会提问的技巧,不要问“详细移植过程”之类的问题,这应该是最令人讨厌的问题,相信没有几个人愿意回答。问问题的时候把问题写清楚,把出错的提示信息也贴出来,不然的话人家想帮你都难。
4、不要什么问题都发贴问人,或者已经发贴问人但没人回复的话也不要再发无谓的贴了,自己有能力解决的问题最好留给自己来解决。不要指望别人像老师一样帮你,别人只能提点一下,其它的就要靠你自己了,这是我的切身体会。
5、饮水要思源,大家把问题解决后希望都写一下总结或把方法往论坛上贴一贴,这样可以帮到更多的人。应该有不少人从论坛上得到帮助的吧,但为何没几个人把解决方法给贴一贴呢,中国人应该互相帮助嘛^_^
顺便提一下,请不要把问题发到我邮箱了,我一般是不回的。直接把它发到论坛上去吧,或许你遇到的问题别人也可能会遇到,然后你们可以互相讨论、互相帮忙。
回想我找工的期间,每天打开邮箱都有新邮箱,打开一看都是提问,还以为是哪间公司叫我笔试、面试了,那心情真是失望透顶了~_~
===================================================================
static ssize_t smdk2410_audio_read(struct file *file, char *buffer,
size_t count, loff_t * ppos)
{
const char *buffer0 = buffer;
audio_stream_t *s = &input_stream;
int chunksize, ret = 0;
DPRINTK("audio_read: count=%d\n", count);
/*
if (ppos != &file->f_pos)
return -ESPIPE;
*/
if (!s->buffers) {
int i;
if (audio_setup_buf(s))
return -ENOMEM;
for (i = 0; i < s->nbfrags; i++) {
audio_buf_t *b = s->buf;
down(&b->sem);
s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, s->fragsize);
NEXT_BUF(s, buf);
}
}
while (count > 0) {
audio_buf_t *b = s->buf;
/* Wait for a buffer to become full */
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
if (down_trylock(&b->sem))
break;
} else {
ret = -ERESTARTSYS;
if (down_interruptible(&b->sem))
break;
}
chunksize = b->size;
if (chunksize > count)
chunksize = count;
DPRINTK("read %d from %d\n", chunksize, s->buf_idx);
if (copy_to_user(buffer, b->start + s->fragsize - b->size,
chunksize)) {
up(&b->sem);
return -EFAULT;
}
b->size -= chunksize;
buffer += chunksize;
count -= chunksize;
if (b->size > 0) {
up(&b->sem);
break;
}
/* Make current buffer available for DMA again */
s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, s->fragsize);
NEXT_BUF(s, buf);
}
if ((buffer - buffer0))
ret = buffer - buffer0;
// DPRINTK("audio_read: return=%d\n", ret);
return ret;
}
static int __init audio_init_dma(audio_stream_t * s, char *desc)
{
int ret ;
s3c2410_dmasrc_t source;
int hwcfg;
unsigned long devaddr;
dmach_t channel;
int dcon;
unsigned int flags = 0;
if(s->dma_ch == DMA_CH2){
channel = 2;
source = S3C2410_DMASRC_MEM;
hwcfg = 3;
devaddr = 0x55000010;
dcon = 0xa0800000;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);
s3c2410_dma_config(channel, 2, dcon);
s3c2410_dma_set_buffdone_fn(channel, audio_dmaout_done_callback);
s3c2410_dma_setflags(channel, flags);
s->dma_ok = 1;
return ret;
}
else if(s->dma_ch == DMA_CH1){
channel =1;
source =S3C2410_DMASRC_HW;
hwcfg =3;
devaddr = 0x55000010;
dcon = 0xa2900000;
flags = S3C2410_DMAF_AUTOSTART;
ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_in, NULL);
s3c2410_dma_devconfig(channel, source, hwcfg, devaddr);
s3c2410_dma_config(channel, 2, dcon);
s3c2410_dma_set_buffdone_fn(channel, audio_dmain_done_callback);
s3c2410_dma_setflags(channel, flags);
s->dma_ok =1;
return ret ;
}
else
return 1;
}
小弟搞uda1341的录音部分已多时,现在终于可以正常播音、录音了,现把驱程公开,希望对正在为此问题烦恼的朋友有所帮助^_^
首先说明一下:
1、 驱程源于中国linux公社->嵌入式linux2.6内核专题:
http://www.linuxfans.org/nuke/modules.php?name=Forums&file=viewtopic&t=112750&postdays=0&postorder=asc&start=30
上的牛貼,稍加修改就可以使用madplay正常播放mp3,但它提供的源码录音部分没做好。
2、 小弟参考网上其它大虾的讨论和三星、uda1341的datasheet修改了驱动程序(见红色部分),其中smdk2410_audio_read函数中注释了:
if (ppos != &file->f_pos)
return -ESPIPE;
部分是因为此处会造成死锁的现象,也就是经常在网上看到的:
cat: Read error: Illegal seek
3、 按照第2步修改了驱动程序后还是不行,出现:
dma1: loadbuffer:timeout loading buffer
的错误,一直没搞清楚为什么。
最后,参考华恒提供的uda13800驱程,修改了dcon寄存器的配置(如蓝色部分),困扰了我一个月的问题终于解决了^_^
借此机会,想向各位刚入门的朋友提点建议:
1、不要一味的找现在(最好是什么都不用修改)的驱动程序,世界上没有免费的午餐。好好的研究一下驱程并大胆的去修改驱程才会学到更多东西。我在找工的时候总被问到的一个问题是:你在移植哪一部分的时候收获最大,你都移植了些什么,为什么要这样移植?
2、在发贴之前先看一下论坛上的精华贴。我经常看到同一个问题有不少的人重重复复的去问题,其实问题的答案早在以前的精华贴里。
3、要学会提问的技巧,不要问“详细移植过程”之类的问题,这应该是最令人讨厌的问题,相信没有几个人愿意回答。问问题的时候把问题写清楚,把出错的提示信息也贴出来,不然的话人家想帮你都难。
4、不要什么问题都发贴问人,或者已经发贴问人但没人回复的话也不要再发无谓的贴了,自己有能力解决的问题最好留给自己来解决。不要指望别人像老师一样帮你,别人只能提点一下,其它的就要靠你自己了,这是我的切身体会。
5、饮水要思源,大家把问题解决后希望都写一下总结或把方法往论坛上贴一贴,这样可以帮到更多的人。应该有不少人从论坛上得到帮助的吧,但为何没几个人把解决方法给贴一贴呢,中国人应该互相帮助嘛^_^
顺便提一下,请不要把问题发到我邮箱了,我一般是不回的。直接把它发到论坛上去吧,或许你遇到的问题别人也可能会遇到,然后你们可以互相讨论、互相帮忙。
回想我找工的期间,每天打开邮箱都有新邮箱,打开一看都是提问,还以为是哪间公司叫我笔试、面试了,那心情真是失望透顶了~_~
- UDA1341不能录音的解决方法
- IOS7 AVAudioRecorder 不能录音的解决方法
- Win7电脑不能录音怎么办?Win7电脑无法录音的解决方法
- 放音后不能再录音的问题
- 电脑不能录音问题解决
- iOS7 AVAudioRecorder不能录音
- bugfix:录音的时候,webview不能播放视频
- arm开发板上arecord 录音出现噪声的解决方法
- 录音的
- 麦克风不能录音解决方案汇总
- ios7下不能录音问题解决
- 电脑不能开机的解决方法
- 电脑不能开机的解决方法
- javascript不能运行的解决方法
- ppstream不能全屏的解决方法
- 可执行文件不能运行的解决方法
- QQ不能安装的解决方法
- apache不能启动的解决方法
- maven+snoatype nexus+jrebel+eclipse+tomcat整合的小例子
- 以数据库字段分组显示数据的sql语句
- 黑马程序员_java基础(1)
- 黑马程序眼_Java基础(2)面向对象(一)
- 说说java
- UDA1341不能录音的解决方法
- tip 1
- qt获取输入中的中文
- Linux——UDA1341驱动
- Delphi中数组分析
- 2112.8.25
- delpi中的RTTI初试
- ARM汇编语言(7) ARM处理器异常处理
- php display_error设置