2

我正在运行 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()似乎已经解决了这个问题 - 我希望它保持这种状态!

4

0 回答 0