I've got an M32C/87 project that uses Uart4 in synchronous mode to talk to an SPI device (microsd card). To speed it up, I used DMA0 to handle the block read transfers. However, I'm noticing an approximately 3 uS delay between bytes transferred (about 60 clocks at 20 MHz), reducing the overall bit rate from 10 Mb/s to about 2 Mb/s. The delay is approximately constant, regardless of the uart's speed. The app is just doing a busy loop waiting for the DMA interrupt. I tried a WAIT but that caused an even bigger delay between bytes.
Now, I can understand some overhead due to the fact that you have to send a byte to read a byte, but 60 clocks? I did try writing two bytes to u4tb to try to "fill the pipeline" which works for a few bytes but then it reverts to the original timing; I assume it misses a byte and loses sync.
Anyone have any ideas why the fixed delay, and/or how to reduce or eliminate it?
No, I'm using an internal clock with RRM
uart init:
/* We're on UART 4 */
u4brg = 199;
u4mr.smd = 1; /* Synchronous serial */
u4mr.ckdir = 0; /* internal clock */
u4mr.iopol = 0; /* not inverted */
u4c0.clk = 0; /* 0=f1, 1=f8 */
u4c0.crd = 1; /* disable CTS/RTS */
u4c0.nch = 0; /* CMOS output */
u4c0.ckpol = 0; /* data changes on falling edge */
u4c0.uform = 1; /* MSB first */
u4c1.te = 1; /* enable transmitter */
u4c1.re = 1; /* enable reciever */
/* If you enable continuous receive, the chip will clock out extra
bytes just because you're reading the receive buffer. */
u4c1.uirrm = 0; /* continuous recieve mode */
u4c1.uilch = 0; /* not inverted */
u4smr.b = 0; /* no special modes */
u4smr2.b = 0; /* no special modes */
u4smr3.b = 0; /* clock format */
u4smr4.b = 0; /* no I2C */
prcr.prc2 = 1;
ps3.b = 0x60;
psl3.b = 0;
psc3.b = 0;
DMA stuff:
void __attribute__((interrupt))
dma0_handler()
{
p10.b = 0x80;
dma0_done = 1;
u4c1.uirrm = 0; /* continuous recieve mode */
/* Read the last byte */
while (!u4c1.ri)
;
*dma_bufend = u4rb;
}
static void
dma_init ()
{
set_dmd0 (0); /* disable DMA */
s4tic = 0; /* disable serial interrupts */
s4ric = 0; /* disable serial interrupts */
dm0ic = 5;
}
static void
dma_start_read (char *buffer, int count)
{
/* DMA does N reads, but we started the first, so this starts N+1
writes. Decrement here and do the last one manually. */
count --;
dma_bufend = buffer + count;
cprintf("buffer %X count %d\n", buffer, count);
dma0_done = 0;
set_dma0(buffer);
set_dra0(buffer);
set_dsa0(&u4rb);
set_dct0(count);
set_drc0(count);
dm0sl = 0x97; /* requested, s4rx */
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
u4c1.uirrm = 1; /* continuous recieve mode */
u4c1.te = 1; /* enable transmitter */
u4c1.re = 1; /* enable reciever */
set_dmd0(0x01); /* single transfer, 8 bits, fixed to memory */
p10.b5 = 1;
u4tb = 0xff; /* start transfer */
}
My manual didn't have a "note 3"... so I downloaded a new one, which is much more helpful. Thanks! It is kinda annoying that the hardware seems determined to not want to be used in SPI+DMA mode, though. The existing app notes weren't helpful as they were either for synchronous transmit, or asynchronous receive.
Odd that it does what I want, though, just with an unexplained delay.
©2003–2009 Renesas Technology Corp. All rights reserved. Using Our Website | Privacy
Contact us