LPCOpen Platform for LPC18XX/43XX microcontrollers
18XX43XX
LPCOpen Platform for the NXP LPC18XX/43XX family of Microcontrollers
Main Page
Modules
Data Structures
Files
File List
Globals
software
lpc_core
lpc_chip
chip_18xx_43xx
sdif_18xx_43xx.c
Go to the documentation of this file.
1
/*
2
* @brief LPC18xx/43xx SD/SDIO driver
3
*
4
* @note
5
* Copyright(C) NXP Semiconductors, 2012
6
* All rights reserved.
7
*
8
* @par
9
* Software that is described herein is for illustrative purposes only
10
* which provides customers with programming information regarding the
11
* LPC products. This software is supplied "AS IS" without any warranties of
12
* any kind, and NXP Semiconductors and its licensor disclaim any and
13
* all warranties, express or implied, including all implied warranties of
14
* merchantability, fitness for a particular purpose and non-infringement of
15
* intellectual property rights. NXP Semiconductors assumes no responsibility
16
* or liability for the use of the software, conveys no license or rights under any
17
* patent, copyright, mask work right, or any other intellectual property rights in
18
* or to any products. NXP Semiconductors reserves the right to make changes
19
* in the software without notification. NXP Semiconductors also makes no
20
* representation or warranty that such application will be suitable for the
21
* specified use without further testing or modification.
22
*
23
* @par
24
* Permission to use, copy, modify, and distribute this software and its
25
* documentation is hereby granted, under NXP Semiconductors' and its
26
* licensor's relevant copyrights in the software, without fee, provided that it
27
* is used in conjunction with NXP Semiconductors microcontrollers. This
28
* copyright, permission, and disclaimer notice must appear in all copies of
29
* this code.
30
*/
31
32
#include "
chip.h
"
33
#include "string.h"
34
35
/*****************************************************************************
36
* Private types/enumerations/variables
37
****************************************************************************/
38
39
/*****************************************************************************
40
* Public types/enumerations/variables
41
****************************************************************************/
42
43
/*****************************************************************************
44
* Private functions
45
****************************************************************************/
46
47
/*****************************************************************************
48
* Public functions
49
****************************************************************************/
50
51
/* Initializes the SD/MMC controller */
52
void
Chip_SDIF_Init
(
LPC_SDMMC_T
*pSDMMC)
53
{
54
/* Enable SDIO module clock */
55
Chip_Clock_EnableOpts
(
CLK_MX_SDIO
,
true
,
true
, 1);
56
57
/* Software reset */
58
pSDMMC->
BMOD
=
MCI_BMOD_SWR
;
59
60
/* reset all blocks */
61
pSDMMC->
CTRL
=
MCI_CTRL_RESET
|
MCI_CTRL_FIFO_RESET
|
MCI_CTRL_DMA_RESET
;
62
while
(pSDMMC->
CTRL
& (
MCI_CTRL_RESET
|
MCI_CTRL_FIFO_RESET
|
MCI_CTRL_DMA_RESET
)) {}
63
64
/* Internal DMA setup for control register */
65
pSDMMC->
CTRL
=
MCI_CTRL_USE_INT_DMAC
|
MCI_CTRL_INT_ENABLE
;
66
pSDMMC->
INTMASK
= 0;
67
68
/* Clear the interrupts for the host controller */
69
pSDMMC->
RINTSTS
= 0xFFFFFFFF;
70
71
/* Put in max timeout */
72
pSDMMC->
TMOUT
= 0xFFFFFFFF;
73
74
/* FIFO threshold settings for DMA, DMA burst of 4, FIFO watermark at 16 */
75
pSDMMC->
FIFOTH
=
MCI_FIFOTH_DMA_MTS_4
|
MCI_FIFOTH_RX_WM
((
SD_FIFO_SZ
/ 2) - 1) |
MCI_FIFOTH_TX_WM
(
SD_FIFO_SZ
/ 2);
76
77
/* Enable internal DMA, burst size of 4, fixed burst */
78
pSDMMC->
BMOD
=
MCI_BMOD_DE
|
MCI_BMOD_PBL4
|
MCI_BMOD_DSL
(4);
79
80
/* disable clock to CIU (needs latch) */
81
pSDMMC->
CLKENA
= 0;
82
pSDMMC->
CLKSRC
= 0;
83
}
84
85
/* Shutdown the SD/MMC controller */
86
void
Chip_SDIF_DeInit
(
LPC_SDMMC_T
*pSDMMC)
87
{
88
/* Disable the clock */
89
Chip_Clock_Disable
(
CLK_MX_SDIO
);
90
}
91
92
/* Function to send command to Card interface unit (CIU) */
93
int32_t
Chip_SDIF_SendCmd
(
LPC_SDMMC_T
*pSDMMC, uint32_t cmd, uint32_t arg)
94
{
95
volatile
int32_t tmo = 50;
96
volatile
int
delay
;
97
98
/* set command arg reg*/
99
pSDMMC->
CMDARG
= arg;
100
pSDMMC->
CMD
=
MCI_CMD_START
| cmd;
101
102
/* poll untill command is accepted by the CIU */
103
while
(--tmo && (pSDMMC->
CMD
&
MCI_CMD_START
)) {
104
if
(tmo & 1) {
105
delay = 50;
106
}
107
else
{
108
delay = 18000;
109
}
110
111
while
(--delay > 1) {}
112
}
113
114
return
(tmo < 1) ? 1 : 0;
115
}
116
117
/* Read the response from the last command */
118
void
Chip_SDIF_GetResponse
(
LPC_SDMMC_T
*pSDMMC, uint32_t *resp)
119
{
120
/* on this chip response is not a fifo so read all 4 regs */
121
resp[0] = pSDMMC->
RESP0
;
122
resp[1] = pSDMMC->
RESP1
;
123
resp[2] = pSDMMC->
RESP2
;
124
resp[3] = pSDMMC->
RESP3
;
125
}
126
127
/* Sets the SD bus clock speed */
128
void
Chip_SDIF_SetClock
(
LPC_SDMMC_T
*pSDMMC, uint32_t clk_rate, uint32_t speed)
129
{
130
/* compute SD/MMC clock dividers */
131
uint32_t div;
132
133
div = ((clk_rate / speed) + 2) >> 1;
134
135
if
((div == pSDMMC->
CLKDIV
) && pSDMMC->
CLKENA
) {
136
return
;
/* Closest speed is already set */
137
138
}
139
/* disable clock */
140
pSDMMC->
CLKENA
= 0;
141
142
/* User divider 0 */
143
pSDMMC->
CLKSRC
=
MCI_CLKSRC_CLKDIV0
;
144
145
/* inform CIU */
146
Chip_SDIF_SendCmd
(pSDMMC,
MCI_CMD_UPD_CLK
|
MCI_CMD_PRV_DAT_WAIT
, 0);
147
148
/* set divider 0 to desired value */
149
pSDMMC->
CLKDIV
=
MCI_CLOCK_DIVIDER
(0, div);
150
151
/* inform CIU */
152
Chip_SDIF_SendCmd
(pSDMMC,
MCI_CMD_UPD_CLK
|
MCI_CMD_PRV_DAT_WAIT
, 0);
153
154
/* enable clock */
155
pSDMMC->
CLKENA
=
MCI_CLKEN_ENABLE
;
156
157
/* inform CIU */
158
Chip_SDIF_SendCmd
(pSDMMC,
MCI_CMD_UPD_CLK
|
MCI_CMD_PRV_DAT_WAIT
, 0);
159
}
160
161
/* Function to clear interrupt & FIFOs */
162
void
Chip_SDIF_SetClearIntFifo
(
LPC_SDMMC_T
*pSDMMC)
163
{
164
/* reset all blocks */
165
pSDMMC->
CTRL
|=
MCI_CTRL_FIFO_RESET
;
166
167
/* wait till resets clear */
168
while
(pSDMMC->
CTRL
&
MCI_CTRL_FIFO_RESET
) {}
169
170
/* Clear interrupt status */
171
pSDMMC->
RINTSTS
= 0xFFFFFFFF;
172
}
173
174
/* Setup DMA descriptors */
175
void
Chip_SDIF_DmaSetup
(
LPC_SDMMC_T
*pSDMMC,
sdif_device
*psdif_dev, uint32_t addr, uint32_t size)
176
{
177
int
i = 0;
178
uint32_t ctrl, maxs;
179
180
/* Reset DMA */
181
pSDMMC->
CTRL
|=
MCI_CTRL_DMA_RESET
|
MCI_CTRL_FIFO_RESET
;
182
while
(pSDMMC->
CTRL
&
MCI_CTRL_DMA_RESET
) {}
183
184
/* Build a descriptor list using the chained DMA method */
185
while
(size > 0) {
186
/* Limit size of the transfer to maximum buffer size */
187
maxs = size;
188
if
(maxs >
MCI_DMADES1_MAXTR
) {
189
maxs =
MCI_DMADES1_MAXTR
;
190
}
191
size -= maxs;
192
193
/* Set buffer size */
194
psdif_dev->
mci_dma_dd
[i].
des1
=
MCI_DMADES1_BS1
(maxs);
195
196
/* Setup buffer address (chained) */
197
psdif_dev->
mci_dma_dd
[i].
des2
= addr + (i *
MCI_DMADES1_MAXTR
);
198
199
/* Setup basic control */
200
ctrl =
MCI_DMADES0_OWN
|
MCI_DMADES0_CH
;
201
if
(i == 0) {
202
ctrl |=
MCI_DMADES0_FS
;
/* First DMA buffer */
203
204
}
205
/* No more data? Then this is the last descriptor */
206
if
(!size) {
207
ctrl |=
MCI_DMADES0_LD
;
208
}
209
else
{
210
ctrl |=
MCI_DMADES0_DIC
;
211
}
212
213
/* Another descriptor is needed */
214
psdif_dev->
mci_dma_dd
[i].
des3
= (uint32_t) &psdif_dev->
mci_dma_dd
[i + 1];
215
psdif_dev->
mci_dma_dd
[i].
des0
= ctrl;
216
217
i++;
218
}
219
220
/* Set DMA derscriptor base address */
221
pSDMMC->
DBADDR
= (uint32_t) &psdif_dev->
mci_dma_dd
[0];
222
}
223
Generated on Fri Feb 20 2015 21:29:44 for LPCOpen Platform for LPC18XX/43XX microcontrollers by
1.8.3.1