我正在运行 uClinux 的 AD Blackfin BF537 DSP 上进行开发。我总共有 32MB 的 SD-RAM 可用。我连接了一个 ADC,我可以使用对read()
.
我的代码中最有趣的部分如下。运行程序似乎工作得很好,我得到了一个很好的数据包,我可以从 SD 卡中获取并绘图。但是,如果我注释掉浮点计算部分(如代码中所述),我在 ft_all.raw 文件中只得到零。如果我将优化级别从 -O3 更改为 -O0,也会发生同样的情况。
我已经尝试过无数种各种事物的组合,有时它可以工作,有时它不能 - 早些时候(对下面的小修改),代码只有在禁用优化时才能工作。如果我在文件中进一步添加其他内容,它也可能会中断。
我的怀疑是read()
-function 传输的数据可能没有完全传输(这可能吗,即使它返回正确的字节数?)。这也是我第一次使用直接内存地址初始化指针,我不知道编译器对此有何反应——也许我错过了什么,在这里?
我现在已经在这个问题上花了几天时间,而且我越来越绝望 - 我真的很感谢在这个问题上提供一些帮助!提前致谢。
// Clear the top 16M memory for data processing
memset((int *)0x01000000,0x0000,(size_t)SIZE_16M);
/* Prep some pointers for data processing */
int16_t *buffer;
int16_t *buf16I, *buf16Q;
buffer = (int16_t *)(0x1000000);
buf16I = (int16_t *)(0x1600000);
buf16Q = (int16_t *)(0x1680000);
/* Read data from ADC */
int rbytes = read(Sportfd, (int16_t*)buffer, 0x200000);
if (rbytes != 0x200000) {
printf("could not sample data! %X\n",rbytes);
goto end;
} else {
printf("Read %X bytes\n",rbytes);
}
FILE *outfd;
int wbytes;
/* Commenting this region results in all zeroes in ft_all.raw */
float a,b;
int c;
b = 0;
for (c = 0; c < 1000; c++) {
a = c;
b = b+pow(a,3);
}
printf("b is %.2f\n",b);
/* Only 12 LSBs of each 32-bit word is actual data.
* First 20 bits of nothing, then 12 bits I, then 20 bits
* nothing, then 12 bits Q, etc...
* Below, the I and Q parts are scaled with a factor of 16
* and extracted to buf16I and buf16Q.
* */
int32_t *buf32;
buf32 = (int32_t *)buffer;
uint32_t i = 0;
uint32_t n = 0;
while (n < 0x80000) {
buf16I[i] = buf32[n] << 4;
n++;
buf16Q[i] = buf32[n] << 4;
i++;
n++;
}
printf("Saving to /mnt/sd/d/ft_all.raw...");
outfd = fopen("/mnt/sd/d/ft_all.raw", "w+");
if (outfd == NULL) {
printf("Could not open file.\n");
}
wbytes = fwrite((int*)0x1600000, 1, 0x100000, outfd);
fclose(outfd);
if (wbytes < 0x100000) {
printf("wbytes not correct (= %d) \n", (int)wbytes);
}
printf(" done.\n");
编辑:如果我使用 read() 从简单文件而不是 ADC 读取数据,代码似乎工作得很好。这让我相信,在提取输入的 I 和 Q 部分时,看起来相当 hacky 的代码正在按预期工作。检查编译器生成的程序集证实了这一点。
我正在尝试与 ADC 驱动程序的开发人员取得联系,看看他是否对此行为有解释。
ADC 通过 SPORT 连接,并按如下方式打开:
sportfd = open("/dev/sport1", O_RDWR);
ioctl(sportfd, SPORT_IOC_CONFIG, spconf);
以下是配置 SPORT 时使用的选项:
spconf->int_clk = 1;
spconf->word_len = 32;
spconf->serial_clk = SPORT_CLK;
spconf->fsync_clk = SPORT_CLK/34;
spconf->fsync = 1;
spconf->late_fsync = 1;
spconf->act_low = 1;
spconf->dma_enabled = 1;
spconf->tckfe = 0;
spconf->rckfe = 1;
spconf->txse = 0;
spconf->rxse = 1;
还包括来自 Analog Devices 的 bfin_sport.h 文件:https ://gist.github.com/tausen/5516954
更新 在与项目的前任开发人员进行了一夜的调试后,结果发现问题与上面显示的代码完全无关。正如 Chris 所建议的,这确实是 SPORT 驱动程序和 ADC 配置的问题。
调试时,只要数据“损坏”,就会出现此错误消息:bfin_sport: sport ffc00900 status error: TUVF
。虽然这在应用程序中没有多大意义,但从打印数据中可以清楚地看出,有些东西是不同步的:缓冲区中的数据在表单上,0x12000000,0x34000000,...
而不是0x00000012,0x00000034,...
在显示状态错误时。那么似乎很清楚,为什么 buf16I 和 buf16Q 只包含零(因为我正在提取 12 个 LSB)。
在 ADC 初始化和配置阶段之间进行几次调用usleep()
似乎已经解决了这个问题 - 我希望它保持这种状态!