Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
NuttX RTOS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
f4grx
NuttX RTOS
Commits
89385500
Commit
89385500
authored
7 years ago
by
Gregory Nutt
Browse files
Options
Downloads
Patches
Plain Diff
arch/arm/src/lpc54xx: In SDMMC driver, don't do DMA if the entire transfer will fit in the FIFO.
parent
96e68357
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
arch/arm/src/lpc54xx/chip/lpc54_sdmmc.h
+5
-0
5 additions, 0 deletions
arch/arm/src/lpc54xx/chip/lpc54_sdmmc.h
arch/arm/src/lpc54xx/lpc54_sdmmc.c
+97
-101
97 additions, 101 deletions
arch/arm/src/lpc54xx/lpc54_sdmmc.c
with
102 additions
and
101 deletions
arch/arm/src/lpc54xx/chip/lpc54_sdmmc.h
+
5
−
0
View file @
89385500
...
...
@@ -47,6 +47,11 @@
* Pre-processor Definitions
************************************************************************************************/
#define LPC54_TXFIFO_DEPTH 32
#define LPC54_TXFIFO_WIDTH 4
#define LPC54_RXFIFO_DEPTH 32
#define LPC54_RXFIFO_WIDTH 4
/* MCI register offsets (with respect to the MCI base) ******************************************/
#define LPC54_SDMMC_CTRL_OFFSET 0x0000
/* Control register */
...
...
This diff is collapsed.
Click to expand it.
arch/arm/src/lpc54xx/lpc54_sdmmc.c
+
97
−
101
View file @
89385500
...
...
@@ -135,6 +135,11 @@
#define SDCARD_BUS_D4 1
#define SDCARD_BUS_D8 0x100
/* FIFO size in bytes */
#define LPC54_TXFIFO_SIZE (LPC54_TXFIFO_DEPTH | LPC54_TXFIFO_WIDTH)
#define LPC54_RXFIFO_SIZE (LPC54_RXFIFO_DEPTH | LPC54_RXFIFO_WIDTH)
/* Data transfer interrupt mask bits */
#define SDCARD_RECV_MASK (SDMMC_INT_DCRC | SDMMC_INT_RCRC | SDMMC_INT_DRTO | \
...
...
@@ -187,7 +192,6 @@
#define SDCARD_DMADONE_FLAG (2)
#define SDCARD_ALLDONE (3)
/* Card debounce time. Number of host clocks (SD_CLK) used by debounce
* filter logic for card detect. typical debounce time is 5-25 ms.
*
...
...
@@ -1595,20 +1599,6 @@ static int lpc54_cancel(FAR struct sdio_dev_s *dev)
(
void
)
wd_cancel
(
priv
->
waitwdog
);
/* If this was a DMA transfer, make sure that DMA is stopped */
#ifdef CONFIG_LPC54_SDMMC_DMA
if
(
priv
->
dmamode
)
{
/* Make sure that the DMA is stopped (it will be stopped automatically
* on normal transfers, but not necessarily when the transfer terminates
* on an error condition.
*/
//lpc54_dmastop(priv->dma);
}
#endif
/* Mark no transfer in progress */
priv
->
remaining
=
0
;
...
...
@@ -2182,95 +2172,97 @@ static int lpc54_registercallback(FAR struct sdio_dev_s *dev,
static
int
lpc54_dmarecvsetup
(
FAR
struct
sdio_dev_s
*
dev
,
FAR
uint8_t
*
buffer
,
size_t
buflen
)
{
struct
lpc54_dev_s
*
priv
=
(
struct
lpc54_dev_s
*
)
dev
;
struct
lpc54_dev_s
*
priv
;
uint32_t
regval
;
uint32_t
ctrl
=
0
;
uint32_t
maxs
=
0
;
int
ret
=
OK
;
int
i
=
0
;
mcinfo
(
"DMA size: %d
\n
"
,
buflen
);
DEBUGASSERT
(
priv
!=
NULL
&&
buffer
!=
NULL
&&
buflen
>
0
);
DEBUGASSERT
(((
uint32_t
)
buffer
&
3
)
==
0
);
ctrl
=
MCI_DMADES0_OWN
|
MCI_DMADES0_CH
;
uint32_t
ctrl
;
uint32_t
maxs
;
int
ret
;
int
i
;
/* Wide bus operation is required for DMA */
/* Don't bother with DMA if the entire transfer will fit in the RX FIFO or
* if we do not have a 4-bit wide bus.
*/
if
(
priv
->
widebus
)
if
(
buflen
<=
LPC54_RXFIFO_SIZE
||
!
priv
->
widebus
)
{
/* Save the destination buffer information for use by the interrupt handler */
return
lpc54_recvsetup
(
dev
,
buffer
,
buflen
);
}
priv
->
buffer
=
(
uint32_t
*
)
buffer
;
priv
->
remaining
=
buflen
;
priv
->
dmamode
=
true
;
mcinfo
(
"buflen=%lu
\n
"
,
(
unsigned
long
)
buflen
);
/* Reset DMA */
priv
=
(
struct
lpc54_dev_s
*
)
dev
;
DEBUGASSERT
(
priv
!=
NULL
&&
buffer
!=
NULL
&&
buflen
>
0
);
DEBUGASSERT
(((
uint32_t
)
buffer
&
3
)
==
0
);
regval
=
lpc54_getreg
(
LPC54_SDMMC_CTRL
);
regval
|=
SDMMC_CTRL_FIFORESET
|
SDMMC_CTRL_DMARESET
;
lpc54_putreg
(
regval
,
LPC54_SDMMC_CTRL
);
/* Save the destination buffer information for use by the interrupt handler */
while
(
lpc54_getreg
(
LPC54_SDMMC_CTRL
)
&
SDMMC_CTRL_DMARESET
)
{
}
priv
->
buffer
=
(
uint32_t
*
)
buffer
;
priv
->
remaining
=
buflen
;
priv
->
dmamode
=
true
;
/*
Setup DMA list
*/
/*
Reset DMA
*/
while
(
buflen
>
0
)
{
/* Limit size of the transfer to maximum buffer size */
regval
=
lpc54_getreg
(
LPC54_SDMMC_CTRL
);
regval
|=
SDMMC_CTRL_FIFORESET
|
SDMMC_CTRL_DMARESET
;
lpc54_putreg
(
regval
,
LPC54_SDMMC_CTRL
);
maxs
=
buflen
;
while
(
lpc54_getreg
(
LPC54_SDMMC_CTRL
)
&
SDMMC_CTRL_DMARESET
)
{
}
if
(
maxs
>
MCI_DMADES1_MAXTR
)
{
maxs
=
MCI_DMADES1_MAXTR
;
}
/* Setup DMA list */
buflen
-=
maxs
;
i
=
0
;
while
(
buflen
>
0
)
{
/* Limit size of the transfer to maximum buffer size */
/* Set buffer size */
maxs
=
buflen
;
g_sdmmc_dmadd
[
i
].
des1
=
MCI_DMADES1_BS1
(
maxs
);
if
(
maxs
>
MCI_DMADES1_MAXTR
)
{
maxs
=
MCI_DMADES1_MAXTR
;
}
/* Setup buffer address (chained) */
buflen
-=
maxs
;
g_sdmmc_dmadd
[
i
].
des2
=
(
uint32_t
)
priv
->
buffer
+
(
i
*
MCI_DMADES1_MAXTR
);
/* Set buffer size */
/* Setup basic control */
g_sdmmc_dmadd
[
i
].
des1
=
MCI_DMADES1_BS1
(
maxs
);
ctrl
=
MCI_DMADES0_OWN
|
MCI_DMADES0_CH
;
/* Setup buffer address (chained) */
if
(
i
==
0
)
{
ctrl
|=
MCI_DMADES0_FS
;
/* First DMA buffer */
}
g_sdmmc_dmadd
[
i
].
des2
=
(
uint32_t
)
priv
->
buffer
+
(
i
*
MCI_DMADES1_MAXTR
);
/* No more data? Then this is the last descriptor
*/
/* Setup basic control
*/
if
(
!
buflen
)
{
ctrl
|=
MCI_DMADES0_LD
;
}
else
{
ctrl
|=
MCI_DMADES0_DIC
;
}
ctrl
=
MCI_DMADES0_OWN
|
MCI_DMADES0_CH
;
/* Another descriptor is needed */
if
(
i
==
0
)
{
ctrl
|=
MCI_DMADES0_FS
;
/* First DMA buffer */
}
g_sdmmc_dmadd
[
i
].
des0
=
ctrl
;
g_sdmmc_dmadd
[
i
].
des3
=
(
uint32_t
)
&
g_sdmmc_dmadd
[
i
+
1
];
/* No more data? Then this is the last descriptor */
i
++
;
if
(
!
buflen
)
{
ctrl
|=
MCI_DMADES0_LD
;
}
else
{
ctrl
|=
MCI_DMADES0_DIC
;
}
lpc54_putreg
((
uint32_t
)
&
g_sdmmc_dmadd
[
0
],
LPC54_SDMMC_DBADDR
);
/* Another descriptor is needed */
g_sdmmc_dmadd
[
i
].
des0
=
ctrl
;
g_sdmmc_dmadd
[
i
].
des3
=
(
uint32_t
)
&
g_sdmmc_dmadd
[
i
+
1
];
i
++
;
}
return
ret
;
lpc54_putreg
((
uint32_t
)
&
g_sdmmc_dmadd
[
0
],
LPC54_SDMMC_DBADDR
);
return
OK
;
}
#endif
...
...
@@ -2299,44 +2291,48 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
{
struct
lpc54_dev_s
*
priv
=
(
struct
lpc54_dev_s
*
)
dev
;
uint32_t
regval
;
int
ret
=
-
EPERM
;
/* Don't bother with DMA if the entire transfer will fit in the TX FIFO or
* if we do not have a 4-bit wide bus.
*/
if
(
buflen
<=
LPC54_TXFIFO_SIZE
||
!
priv
->
widebus
)
{
return
lpc54_sendsetup
(
dev
,
buffer
,
buflen
);
}
mcinfo
(
"buflen=%lu
\n
"
,
(
unsigned
long
)
buflen
);
priv
=
(
struct
lpc54_dev_s
*
)
dev
;
DEBUGASSERT
(
priv
!=
NULL
&&
buffer
!=
NULL
&&
buflen
>
0
);
DEBUGASSERT
(((
uint32_t
)
buffer
&
3
)
==
0
);
/* Wide bus operation is required for DMA */
if
(
priv
->
widebus
)
{
/* Save the destination buffer information for use by the interrupt
* handler.
*/
priv
->
buffer
=
(
uint32_t
*
)
buffer
;
priv
->
remaining
=
buflen
;
priv
->
dmamode
=
true
;
/* Save the destination buffer information for use by the interrupt
* handler.
*/
/* Reset DMA */
priv
->
buffer
=
(
uint32_t
*
)
buffer
;
priv
->
remaining
=
buflen
;
priv
->
dmamode
=
true
;
regval
=
lpc54_getreg
(
LPC54_SDMMC_CTRL
);
regval
|=
SDMMC_CTRL_FIFORESET
|
SDMMC_CTRL_DMARESET
;
lpc54_putreg
(
regval
,
LPC54_SDMMC_CTRL
);
while
(
lpc54_getreg
(
LPC54_SDMMC_CTRL
)
&
SDMMC_CTRL_DMARESET
);
/* Reset DMA */
/* Setup DMA descriptor list */
regval
=
lpc54_getreg
(
LPC54_SDMMC_CTRL
);
regval
|=
SDMMC_CTRL_FIFORESET
|
SDMMC_CTRL_DMARESET
;
lpc54_putreg
(
regval
,
LPC54_SDMMC_CTRL
);
while
(
lpc54_getreg
(
LPC54_SDMMC_CTRL
)
&
SDMMC_CTRL_DMARESET
)
{
}
g_sdmmc_dmadd
[
0
].
des0
=
MCI_DMADES0_OWN
|
MCI_DMADES0_CH
|
MCI_DMADES0_LD
;
g_sdmmc_dmadd
[
0
].
des1
=
512
;
g_sdmmc_dmadd
[
0
].
des2
=
(
uint32_t
)
priv
->
buffer
;
g_sdmmc_dmadd
[
0
].
des3
=
(
uint32_t
)
&
g_sdmmc_dmadd
[
1
];
/* Setup DMA descriptor list */
lpc54_putreg
((
uint32_t
)
&
g_sdmmc_dmadd
[
0
],
LPC54_SDMMC_DBADDR
);
ret
=
OK
;
}
g_sdmmc_dmadd
[
0
].
des0
=
MCI_DMADES0_OWN
|
MCI_DMADES0_CH
|
MCI_DMADES0_LD
;
g_sdmmc_dmadd
[
0
].
des1
=
512
;
g_sdmmc_dmadd
[
0
].
des2
=
(
uint32_t
)
priv
->
buffer
;
g_sdmmc_dmadd
[
0
].
des3
=
(
uint32_t
)
&
g_sdmmc_dmadd
[
1
];
return
ret
;
lpc54_putreg
((
uint32_t
)
&
g_sdmmc_dmadd
[
0
],
LPC54_SDMMC_DBADDR
);
return
OK
;
}
#endif
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment