I've torn my hair out over this BeagleBone problem for a week so now I
need to come to the list for help.
What I need to do:
read an SPI A/D converter at 1 megasample/second. This requires a 16Mhz
SPI clock. I need to read 512 byte sample.
Here's what I can do so far.
Read the converter at 16MHz for 128 bytes. At 256 bytes, the ioctl
never returns, the process is locked in the kernel and nothing but a
hard reset or power cycle will bring it back.
I think this may have something to do with DMA but TFRM has my head
spinning.
Thanks in advance for any help forthcoming.
John
If you don't want to try to read this line-wrapped crap below, it is in
a file here:
https://dl.dropbox.com/u/81715047/spi_help.txt
Here: my dmesg for a SUCCESSFUL run. I've added many debugging
statement to the driver code.
[ 102.622772] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 0, speed is 24000000
[ 102.622802] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 24000000, sample trailing edge, clk normal
[ 102.622802] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 102.622863] spidev spi1.0: spi.c: spi_setup: mode 1, 8 bits/w,
24000000 Hz max -- status 0
[ 102.622863] spidev spi1.0: spi mode 01
[ 102.622894] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 0, speed is 24000000
[ 102.622924] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 24000000, sample trailing edge, clk normal
[ 102.622955] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 102.622955] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
24000000 Hz max -- status 0
[ 102.622985] spidev spi1.0: 16 bits per word
[ 102.623016] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 102.623016] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 102.623046] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 102.623077] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 102.623077] spidev spi1.0: spidev.c: 16000000 Hz (max)
[ 102.625732] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 102.625762] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 102.625762] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 102.625823] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 102.625823] spidev spi1.0: spi mode 01
[ 102.625854] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 102.625885] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 102.625915] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 102.625915] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 102.625946] spidev spi1.0: 16 bits per word
[ 102.625976] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 102.625976] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 102.626007] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 102.626037] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 102.626037] spidev spi1.0: spidev.c: 16000000 Hz (max)
[ 102.626708] spidev spi1.0: spidev.c: _IOC_NR(cmd) = 0,
_IOC_NR(SPI_IOC_MESSAGE(0) = 0 , -IOC_DIR(cmd) = 1 _IOC_WRITE = 1
[ 102.626800] spidev spi1.0: spidev.c: tmp = 32 bytes, cmd = 1075866368
, n_ioc = 1 bytes
[ 102.626800] spidev spi1.0: spidev.c: calling spidev_message()
[ 102.626831] spidev spi1.0: spidev.c:spidev_msg(): xfer len 128 rx
16bits per word 0 usec delay 16000000Hz
[ 102.626861] spidev spi1.0: calling spidev_sync(), sizeof(msg) = 44
[ 102.626892] spidev spi1.0: spicev.c: spidev_sync(): return from
spi_async(), status is 0
[ 102.626953] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 102.626983] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 102.626983] spidev spi1.0: spi_omap2-mcspi.c: calling
mcspi_write_chconf0() in omap2_mcspi_force_cs
[ 102.627014] spidev spi1.0: spi_omap2-mcspi.c: calling
mcspi_write_chconf0() in omap2_mcspi_work()
[ 102.627105] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 102.627136] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 102.627136] spidev spi1.0: spi_omap2-mcspi.c: calling
mcspi_write_chconf0() in omap2_mcspi_force_cs
[ 102.627197] spidev spi1.0: spidev_sync() returned, status = 128
[ 102.627197] spidev spi1.0: spidev.c:spidev_msg(): starting to copy
received data to user space
[ 102.627227] spidev spi1.0: spidev.c:spidev_msg(): receive data copy
finished, status = 128
[ 102.627227] spidev spi1.0: spidev.c:spidev_msg(): returning from
function
[ 102.627258] spidev spi1.0: spidev.c: returned from spidev_message()
Here is the dmesg from a failed, 256 byte run. Everything is the same
until I get into spi_omap2-mcspie.c. This is just the last part of the
log where thing go south.
[ 429.267517] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 429.267517] spidev spi1.0: spi mode 01
[ 429.267547] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 429.267578] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 429.267608] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 429.267639] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 429.267639] spidev spi1.0: 16 bits per word
[ 429.267669] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 429.267700] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 429.267700] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcpi_setup_transfer returned 0
[ 429.267730] spidev spi1.0: spi.c: spi_setup: mode 1, 16 bits/w,
16000000 Hz max -- status 0
[ 429.267730] spidev spi1.0: spidev.c: 16000000 Hz (max)
[ 429.268402] spidev spi1.0: spidev.c: _IOC_NR(cmd) = 0,
_IOC_NR(SPI_IOC_MESSAGE(0) = 0 , -IOC_DIR(cmd) = 1 _IOC_WRITE = 1
[ 429.268493] spidev spi1.0: spidev.c: tmp = 32 bytes, cmd = 1075866368
, n_ioc = 1 bytes
[ 429.268524] spidev spi1.0: spidev.c: calling spidev_message()
[ 429.268554] spidev spi1.0: spidev.c:spidev_msg(): xfer len 256 rx
16bits per word 0 usec delay 16000000Hz
[ 429.268554] spidev spi1.0: calling spidev_sync(), sizeof(msg) = 44
[ 429.268585] spidev spi1.0: spicev.c: spidev_sync(): return from
spi_async(), status is 0
[ 429.268646] spidev spi1.0: spi_omap2-mcspi.c:
omap2_mcspi_setup_transfer(): dividor is 1, speed is 16000000
[ 429.268676] spidev spi1.0: spi_omap2-mcspi.c: after
mcspi_writ_chcon(): speed 12000000, sample trailing edge, clk normal
[ 429.268707] spidev spi1.0: spi_omap2-mcspi.c: calling
mcspi_write_chconf0() in omap2_mcspi_force_cs
[ 429.268707] spidev spi1.0: spi_omap2-mcspi.c: calling
mcspi_write_chconf0() in omap2_mcspi_work()
[ 429.268737] spidev spi1.0: spi_omap2-mcspi.c: calling
mcspi_write_chconf0() in omap2_mcspi_set_dma_req
A few minutes later the following is added to the log.
[ 600.338867] INFO: task kworker/u:1:39 blocked for more than 120 seconds.
[ 600.345886] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[ 600.354095] kworker/u:1 D c04cc854 0 39 2 0x00000000
[ 600.354095] Backtrace:
[ 600.354156] [<c04cc468>] (__schedule+0x0/0x43c) from [<c04cc9c0>]
(schedule+0x78/0x7c)
[ 600.354187] [<c04cc948>] (schedule+0x0/0x7c) from [<c04ccd00>]
(schedule_timeout+0x20/0x16c)
[ 600.354217] [<c04ccce0>] (schedule_timeout+0x0/0x16c) from
[<c04cc220>] (wait_for_common+0xc8/0x154)
[ 600.354217] r6:00000002 r5:cf8b8cdc r4:7fffffff
[ 600.354248] [<c04cc158>] (wait_for_common+0x0/0x154) from
[<c04cc2c4>] (wait_for_completion+0x18/0x1c)
[ 600.354278] [<c04cc2ac>] (wait_for_completion+0x0/0x1c) from
[<c0333cdc>] (omap2_mcspi_work+0x46c/0xa14)
[ 600.354309] [<c0333870>] (omap2_mcspi_work+0x0/0xa14) from
[<c004cdcc>] (process_one_work+0x1e0/0x334)
[ 600.354339] [<c004cbec>] (process_one_work+0x0/0x334) from
[<c004d748>] (worker_thread+0x1b4/0x2b8)
[ 600.354370] [<c004d594>] (worker_thread+0x0/0x2b8) from [<c0050f48>]
(kthread+0x90/0x98)
[ 600.354400] [<c0050eb8>] (kthread+0x0/0x98) from [<c003c228>]
(do_exit+0x0/0x624)
[ 600.354431] r6:c003c228 r5:c0050eb8 r4:cf83fed8
[ 600.354461] INFO: task adcspi:327 blocked for more than 120 seconds.
[ 600.361114] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[ 600.369293] adcspi D c04cc854 0 327 313 0x00000000
[ 600.369293] Backtrace:
[ 600.369323] [<c04cc468>] (__schedule+0x0/0x43c) from [<c04cc9c0>]
(schedule+0x78/0x7c)
[ 600.369354] [<c04cc948>] (schedule+0x0/0x7c) from [<c04ccd00>]
(schedule_timeout+0x20/0x16c)
[ 600.369384] [<c04ccce0>] (schedule_timeout+0x0/0x16c) from
[<c04cc220>] (wait_for_common+0xc8/0x154)
[ 600.369384] r6:00000002 r5:cf83de3c r4:7fffffff
[ 600.369415] [<c04cc158>] (wait_for_common+0x0/0x154) from
[<c04cc2c4>] (wait_for_completion+0x18/0x1c)
[ 600.369445] [<c04cc2ac>] (wait_for_completion+0x0/0x1c) from
[<bf04e204>] (spidev_sync+0xa0/0xc8 [spidev])
[ 600.369476] [<bf04e164>] (spidev_sync+0x0/0xc8 [spidev]) from
[<bf04e9bc>] (spidev_ioctl+0x58c/0x6e4 [spidev])
[ 600.369506] r6:cfaecce4 r5:cfa4c400 r4:cf801280
[ 600.369537] [<bf04e430>] (spidev_ioctl+0x0/0x6e4 [spidev]) from
[<c00cbc54>] (do_vfs_ioctl+0x4b0/0x524)
[ 600.369567] [<c00cb7a4>] (do_vfs_ioctl+0x0/0x524) from [<c00cbd20>]
(sys_ioctl+0x58/0x7c)
[ 600.369567] r9:cf83c000 r8:00000000 r7:00000003 r6:40206b00 r5:00012260
[ 600.369598] r4:cfb223c0
[ 600.369628] [<c00cbcc8>] (sys_ioctl+0x0/0x7c) from [<c000d5c0>]
(ret_fast_syscall+0x0/0x30)
[ 600.369628] r8:c000d744 r7:00000036 r6:00008491 r5:00000000 r4:00000000
Finally, the test code that is producing this stuff.
#undef FFT_SIZE
#define FFT_SIZE 256
static const char *device = "/dev/spidev1.0";
static uint8_t mode = SPI_CPHA;
static uint8_t bits = 16;
static uint32_t speed = 16000000L; // 16 MHz clock for 1.0 megasample/sec
static uint16_t delay=0;
//array is also 512 (FFT_SIZE) bytes
uint16_t rx[FFT_SIZE] = {0, };
struct spi_ioc_transfer tr; // the IOCTL struct
tr.tx_buf = NULL;
tr.rx_buf = (unsigned long)rx;
tr.len = ARRAY_SIZE(rx);
tr.delay_usecs = delay;
tr.speed_hz = speed;
tr.bits_per_word = bits;
// This call should return with 512 samples in tr.rx_buf
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 0)
pabort("can't send spi message, conversion failed ");
exit(0);
}