a friendly hello to all lpc fans !!!
i am currently using the keil mcb2148 eval board with the keil tools
firmware description :
language C++
modified usb frontend from keil
modified msc, scsi, spi, sd/mmc backend from iar
it all works almost perfect without dma, except reading long files (larger than 32k) and
writing multiple blocks
the problem was, that the keil usb implementation handled all usb processing within the
isr which is not acceptabel for my app
the iar implementation processed the scsi commands in the main loop but the iar usb
frontend didn't seem as clean coded as the keil
also the iar implementation uses dma support, which appears to be a nice feature
therefore i combined both ends and wrapped it nicely into C++ classes
i am also using the keil hid interface (now in C++) in a composite device, msc and hid
first i got the memory disk to work and later the Sd/Mmc card
as i indicated, that the deferred processing (removing the scsi command processing from
the isr level to the main loop) is causing some problems with large files and especially
with write operations, the data flow coming from the out endpoint.
iar uses dma and the deferred processing approach, therefor i try the same
as indicated the non dma implementation works. has been tested by reading the directory of
a sd/mmc card and reading small files
now i substituted the endpoint read and write functions with the dma equivalent functions
at the correct spots in the code and according the iar sample software
i only implemented the bulk out operation in dma
the array of DDs as well as all DDs and the buffers they point to are located within the
USB-DMA memory (0x7fd00000)
the DmaDescr for fetching the cbw is setup with the following data
DD.pNextDd = 0 ;
DD.Ctrl.DmaMode = 0 ;
DD.Ctrl.NextDdValid = 0 ;
DD.Ctrl.Isochronous = 0 ;
DD.Ctrl.MaxPkgSize = 0x40 ;
DD.Ctrl.DmaBufLen = 0x1f ;
DD.pDmaBuf = 7fd004e0 ; // addr of buffer within USB-DMA memory
DD.Stat.DdRetired = 0 ;
DD.Stat.DdStatus = 0 ;
DD.Stat.PkgValid = 0 ;
DD.Stat.LsByteExtr = 0 ;
DD.Stat.MsByteExtr = 0 ;
DD.Stat.MsgLenPos = 0 ;
DD.Stat.PresDmaCnt = 0 ;
the code acts now the following way
the 1st dma operation (fetching the cbw) works correct and i respond to the inquiry
command with the inquiry data and the csw through the in endpoint in non-dma mode
now i issue a 2nd dma-setup to fetch the next cbw block by using the same function as for
the 1st (fetch a cbw), within the isr which sends the csw to the host on the in endpoint.
this dma setup happens after the csw has been sent to the host (in endpoint), but within
the in-endpoint isr
now the 2nd usb eot intr happens with the following DmaDescr error (data under-run)
DD.pNextDd --> 0
DD.Ctrl.DmaMode --> 0
DD.Ctrl.NextDdValid --> 0
DD.Ctrl.Isochronous --> 0
DD.Ctrl.MaxPkgSize --> 0x40
DD.Ctrl.DmaBufLen --> 0x1f
DD.pDmaBuf --> 7fd004e0 (un-altered addr of buffer within USB-DMA memory)
DD.Stat.DdRetired --> 1
DD.Stat.DdStatus --> 3 (data under-run)
DD.Stat.PkgValid --> 0
DD.Stat.LsByteExtr --> 0
DD.Stat.MsByteExtr --> 0
DD.Stat.MsgLenPos --> 0
DD.Stat.PresDmaCnt --> 0 (un-altered)
the 1st correct working cbw fetch shows the following diffs
DD.pDmaBuf --> 7fd004ff (advanced addr of buffer within USB-DMA memory)
DD.Stat.DdStatus --> 1
DD.Stat.DdStatus --> 2 (normal completion)
DD.Stat.PkgValid --> 1
DD.Stat.LsByteExtr --> 0
DD.Stat.MsByteExtr --> 0
DD.Stat.MsgLenPos --> 0
DD.Stat.PresDmaCnt --> 0x1f (updated)
i have absolutely no idea what could cause the data under run
any help is very highly appreciated, Klaus R Schambeck
sample code (called for 1st and 2nd cbw fetch)
bool TUsbHw::DmaSetup(UINT ep, void *pData, UINT size )
{
if (!(ep & 0x0f)) {
PRINT(".DMA-err %02x.", ep) ;
return eDmaParmErr ;
}
UINT epa = EPAdr(ep) ; // convert 0x8f ep format into 32bit ep addr
DmaDesc_t *pd = UDCA[epa] ; // get start addr of dma-descr
if (pd->DdStatus == eDmaBusy) {
PRINT(".DMA-busy-%02x.", ep) ;
return eDmaBusy ;
}
pd->pDmaBuf = pData ;
pd->MaxPkgSize = size ? 0x40 : 0 ; /* TMscUser::eMAX_PACKET */
pd->DmaBufLen = size ;
pd->Stat = 0 ;
USBEpDMAEn = 1 << epa ;
point of calling debug data print shown below
UINT epr = WrCmd(eCMD_SEL_EP | epa) ;
if (epa & 0x01 && !(epr & 0x60) || /* In EP empty */
!(epa & 0x01) && (epr & 0x60) == 0x60) { /* Out EP full */
if (pd->DdStatus != eDmaBusy) {
PRINT(".DMA-retrig-%02x.", ep) ;
USBDMARSet = 1 << epa ; /* Retrigger DMA Transfer */
}
}
return eDmaIdle ;
}
in fact i get the following debug info from within the DmaSetup function
all debug printing is into a tx-intr supported 1k que
IntSt 80000105
DevIntSt 035
EpIntSt 00000000
DMARSt 00000000
EpDMASt 00000010
DMAIntSt 1
EoTIntSt 00000010
NDDRIntSt 00000000
SysErrIntSt 00000000
Dma[04] 7fd00080
Dma.pNextDd 00000000
Dma.Ctrl 001f0800 0 0 0 040 001f
Dma.pDmaBuf 7fd004e0
Dma.Stat 00000007 1 3 0 0 0 00 0000
____________________________________________________________________________________
Never miss a thing. Make Yahoo your home page.
http://www.yahoo.com/r/hs
[Non-text portions of this message have been removed]

(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )
hello
have you found any good working DMA code for LPC2148 USB?
> i am currently using the keil mcb2148 eval board with the keil tools
>
> firmware description :
> language C++
> modified usb frontend from keil
> modified msc, scsi, spi, sd/mmc backend from iar
>
> it all works almost perfect without dma, except reading long files (larger than 32k) and
writing multiple blocks
>
> the problem was, that the keil usb implementation handled all usb processing within the
isr which is not acceptabel for my app
> the iar implementation processed the scsi commands in the main loop but the iar usb
frontend didn't seem as clean coded as the keil
> also the iar implementation uses dma support, which appears to be a nice feature
> therefore i combined both ends and wrapped it nicely into C++ classes
> i am also using the keil hid interface (now in C++) in a composite device, msc and
hid
>
> first i got the memory disk to work and later the Sd/Mmc card
>
> as i indicated, that the deferred processing (removing the scsi command processing from
the isr level to the main loop) is causing some problems with large files and especially
with write operations, the data flow coming from the out endpoint.
>
> iar uses dma and the deferred processing approach, therefor i try the same
>
> as indicated the non dma implementation works. has been tested by reading the directory
of a sd/mmc card and reading small files
>
> now i substituted the endpoint read and write functions with the dma equivalent
functions at the correct spots in the code and according the iar sample software
>
> i only implemented the bulk out operation in dma
>
> the array of DDs as well as all DDs and the buffers they point to are located within the
USB-DMA memory (0x7fd00000)
>
> the DmaDescr for fetching the cbw is setup with the following data
>
> DD.pNextDd = 0 ;
>
> DD.Ctrl.DmaMode = 0 ;
> DD.Ctrl.NextDdValid = 0 ;
> DD.Ctrl.Isochronous = 0 ;
> DD.Ctrl.MaxPkgSize = 0x40 ;
> DD.Ctrl.DmaBufLen = 0x1f ;
>
> DD.pDmaBuf = 7fd004e0 ; // addr of buffer within USB-DMA memory
>
> DD.Stat.DdRetired = 0 ;
> DD.Stat.DdStatus = 0 ;
> DD.Stat.PkgValid = 0 ;
> DD.Stat.LsByteExtr = 0 ;
> DD.Stat.MsByteExtr = 0 ;
> DD.Stat.MsgLenPos = 0 ;
> DD.Stat.PresDmaCnt = 0 ;
> the code acts now the following way
>
> the 1st dma operation (fetching the cbw) works correct and i respond to the inquiry
command with the inquiry data and the csw through the in endpoint in non-dma mode
>
> now i issue a 2nd dma-setup to fetch the next cbw block by using the same function as
for the 1st (fetch a cbw), within the isr which sends the csw to the host on the in
endpoint. this dma setup happens after the csw has been sent to the host (in endpoint),
but within the in-endpoint isr
> now the 2nd usb eot intr happens with the following DmaDescr error (data under-run)
>
> DD.pNextDd --> 0
>
> DD.Ctrl.DmaMode --> 0
> DD.Ctrl.NextDdValid --> 0
> DD.Ctrl.Isochronous --> 0
> DD.Ctrl.MaxPkgSize --> 0x40
> DD.Ctrl.DmaBufLen --> 0x1f
>
why you're limiting data to 0x1f?
> DD.pDmaBuf --> 7fd004e0 (un-altered addr of buffer within USB-DMA memory)
>
> DD.Stat.DdRetired --> 1
> DD.Stat.DdStatus --> 3 (data under-run)
> DD.Stat.PkgValid --> 0
> DD.Stat.LsByteExtr --> 0
> DD.Stat.MsByteExtr --> 0
> DD.Stat.MsgLenPos --> 0
> DD.Stat.PresDmaCnt --> 0 (un-altered)
>
> the 1st correct working cbw fetch shows the following diffs
>
> DD.pDmaBuf --> 7fd004ff (advanced addr of buffer within USB-DMA memory)
>
> DD.Stat.DdStatus --> 1
> DD.Stat.DdStatus --> 2 (normal completion)
> DD.Stat.PkgValid --> 1
> DD.Stat.LsByteExtr --> 0
> DD.Stat.MsByteExtr --> 0
> DD.Stat.MsgLenPos --> 0
> DD.Stat.PresDmaCnt --> 0x1f (updated)
>
> i have absolutely no idea what could cause the data under run
>
data underrun is set whenever packet is shorter that Max_packet_size
(see 14.10.5)
but there should be Present_DMA_count set to correct value
------------------------------------

(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )