2010-06-24 09:59:37 BF518F SPORT DMA, first word transfered is always 0
Andrew Kohlsmith (CANADA)
Message: 90594
I'm using 2009R1-1.1 with the provided bfin_sport.c kernel module. I'm transmitting 32-bit words using DMA, and I've noticed that the first transfered word is always 0x00000000, THEN my data. Of course my data is always short by 4 bytes as well since the 0x0000000 was inserted before my data.
I've added some debugging code to the driver and enabled the pr_debug() calls. Here is what I see:
tcr1:0x602, tcr2:0x1f, rcr1:0x602, rcr2:0x1f
mcmc1:0x0, mcmc2:0x0
sport_write count:21 dma_tx_chan:4
DMA mode
dump_dma_regs config:0x00a9, x_count:0x0005, x_modify:0x0004
sport_write(21 bytes):
cfg->word_len=32, word_bytes=4, xcount=5, ycount=0
00 01 02 03 04 05 06 07
08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 00 00 00
wait for transfer finished
dma_tx_irq_handler enter (stat=0008)
waiting over
As you can see, my first 32-bit word should be 00010203, but it is always 0x00000000, THEN 0x00010203. I am verifying this with a logic analyzer hooked up to the TFS0/TSCLK0/DT0PRI pins.
Thinking it might be some goofy bug where the TX shift register is shifted out before the first DMA transfer completes, I tried to manually load dev->regs->tx with a known value, but that just crashes the kernel with a NULL pointer dereference, which is also confusing. The line I use to load the tx reg before enabling TXEN is
*(volatile unsigned long *)dev->regs->tx = 0xaa5500ff;
This is identical to the method used by the driver when using PIO mode. I have verified that dev->regs->tx is not NULL (it is 0xffc00810).
I've also poked around this site and the rest of the internet looking for errata or something which might explain this first transferred word of 0, but nothing's come up.
Has anyone seen this before? What's the workaround?
-A.
QuoteReplyEditDelete
2010-06-24 15:41:26 Re: BF518F SPORT DMA, first word transfered is always 0
Andrew Kohlsmith (CANADA)
Message: 90607
*(volatile unsigned long *)dev->regs->tx = 0xaa5500ff;
I was missing an '&' in that, should have been
*(volatile unsigned long *)(&dev->regs->tx) = 0xaa5500ff;
However that does not fix the original problem. Writing to TX_REG when using DMA results in an aborted transfer. I didn't think it would work, but I tried just to see.
Using PIO mode leads to similar results; the first (32-bit) word appearing on the SPORT output is 0. If I use the above line there before the sport_tx_write() call, then the first word coming out of the sport appears to be the MSB of the word I send.
e.g. if I write 0xff00aa55, before calling the first entire 32-bit word coming out of the SPORT is 0xffffffff. If I write 0x7f00aa55, the first 32-bit word is 0x00000000. It is like only the MSB is making it out in the first word.
QuoteReplyEditDelete
2010-06-25 00:08:50 Re: BF518F SPORT DMA, first word transfered is always 0
Sonic Zhang (CHINA)
Message: 90619
Please try to set DITFS in TCR1 register before you start output.
Data-Independent transmit frame sync select. (DITFS). This bit
selects whether the SPORT generates a data-independent TFS (sync
at selected interval) or a data-dependent TFS (sync when data is
present in SPORTx_TX) for the case of internal frame sync select
(ITFS = 1). The DITFS bit is ignored when external frame syncs are
selected.
QuoteReplyEditDelete
2010-07-06 09:29:39 Re: BF518F SPORT DMA, first word transfered is always 0
Andrew Kohlsmith (CANADA)
Message: 90959
I set DITFS to 0 by default (I do not want frame sync if I don't have data to send), but on your suggestion I tried setting it to 1.
The DITFS setting makes no difference whatsoever with respect to the first word. It is always invalid (all bits set to the MSB of the first word of data I want to send), but it does make a difference at the end of the transfer.
To repeat what is occuring:
DMA transfer of (example) 21 bytes. SPORT is set up for 32-bit words, internal clock.
My data (verified with printk() from bfin_sport's write() routine: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
Data appearing on SPORT (verified with logic analyzer on physical SPORT TFS0/TSCLK0/DT0PRI pins): 0x00000000 0x03020100 0x07060504 0x0b0a0908 0x0f0e0d0c 0x13121110 (note missing final word)
If my data would have the MSB set, then the first word out of the SPORT would be 0xffffffff. e.g. If I were to send 00 01 02 83, the data would come out 0xffffffff 0x83020100 ...
-A.