Skip to content

Commit ad7ffd4

Browse files
committed
sdcard testing results and resources
1 parent fb1cae0 commit ad7ffd4

File tree

4 files changed

+616
-0
lines changed

4 files changed

+616
-0
lines changed

fsl_host.c

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/*
2+
* Copyright (c) 2015 Freescale Semiconductor, Inc.
3+
* Copyright 2016-2018 NXP
4+
*
5+
* SPDX-License-Identifier: BSD-3-Clause
6+
*/
7+
8+
#include "board.h"
9+
#include "event.h"
10+
#include "fsl_gpio.h"
11+
#include "fsl_host.h"
12+
#ifdef BOARD_USDHC_CD_PORT_BASE
13+
#include "fsl_port.h"
14+
#endif
15+
16+
/*******************************************************************************
17+
* Definitions
18+
******************************************************************************/
19+
20+
/*******************************************************************************
21+
* Prototypes
22+
******************************************************************************/
23+
/*!
24+
* @brief host controller error recovery.
25+
* @param host base address.
26+
*/
27+
static void Host_ErrorRecovery(HOST_TYPE *hostBase);
28+
/*******************************************************************************
29+
* Variables
30+
******************************************************************************/
31+
/* DMA descriptor should allocate at non-cached memory */
32+
AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_usdhcAdma2Table[USDHC_ADMA_TABLE_WORDS], USDHC_ADMA2_ADDR_ALIGN);
33+
34+
static usdhc_handle_t g_usdhcHandle;
35+
static volatile bool g_usdhcTransferSuccessFlag = true;
36+
static volatile bool g_sdInsertedFlag;
37+
static volatile status_t g_reTuningFlag = false;
38+
/*******************************************************************************
39+
* Code
40+
******************************************************************************/
41+
42+
/* Delay some time united in milliseconds. */
43+
static void Delay(uint32_t milliseconds)
44+
{
45+
uint32_t i;
46+
uint32_t j;
47+
48+
for (i = 0; i < milliseconds; i++)
49+
{
50+
for (j = 0; j < 20000U; j++)
51+
{
52+
__asm("NOP");
53+
}
54+
}
55+
}
56+
57+
static void DetectCardByGpio(void)
58+
{
59+
if (HOST_CARD_DETECT_STATUS() != HOST_CARD_INSERT_CD_LEVEL)
60+
{
61+
g_sdInsertedFlag = false;
62+
}
63+
else
64+
{
65+
g_sdInsertedFlag = true;
66+
}
67+
}
68+
69+
/* Card detect. */
70+
status_t CardInsertDetect(HOST_TYPE *hostBase)
71+
{
72+
if (!EVENT_Create(kEVENT_CardDetect))
73+
{
74+
return kStatus_Fail;
75+
}
76+
77+
HOST_CARD_DETECT_INIT();
78+
/* only SD card need card detect*/
79+
HOST_ENABLE_SD_POWER(false);
80+
/* Open card detection pin NVIC. */
81+
EnableIRQ(HOST_CARD_DETECT_IRQ);
82+
/* set IRQ priority */
83+
#if defined(__CORTEX_M)
84+
NVIC_SetPriority(HOST_CARD_DETECT_IRQ, 6U);
85+
#else
86+
GIC_SetPriority(HOST_CARD_DETECT_IRQ, 26U);
87+
#endif
88+
/* detect card status */
89+
DetectCardByGpio();
90+
91+
if (!g_sdInsertedFlag)
92+
{
93+
/* Wait card inserted. */
94+
do
95+
{
96+
if (!EVENT_Wait(kEVENT_CardDetect, EVENT_TIMEOUT_CARD_DETECT))
97+
{
98+
return kStatus_Fail;
99+
}
100+
} while (!g_sdInsertedFlag);
101+
}
102+
103+
EVENT_Delete(kEVENT_CardDetect);
104+
/* Delat some time to make card stable. */
105+
Delay(500U);
106+
/* card power on */
107+
HOST_ENABLE_SD_POWER(true);
108+
/* Delat some time to make card stable. */
109+
Delay(500U);
110+
111+
return kStatus_Success;
112+
}
113+
114+
/* Card detect pin port interrupt handler. */
115+
void HOST_CARD_DETECT_INTERRUPT_HANDLER(void)
116+
{
117+
if (HOST_CARD_DETECT_INTERRUPT_STATUS() & (1U << BOARD_USDHC_CD_GPIO_PIN))
118+
{
119+
DetectCardByGpio();
120+
}
121+
/* Clear interrupt flag.*/
122+
HOST_CARD_DETECT_INTERRUPT_CLEAR(~0U);
123+
EVENT_Notify(kEVENT_CardDetect);
124+
}
125+
126+
/* USDHC transfer complete callback function. */
127+
static void USDHC_TransferCompleteCallback(USDHC_Type *base, usdhc_handle_t *handle, status_t status, void *userData)
128+
{
129+
/* wait the target status and then notify the transfer complete */
130+
if (status == kStatus_Success)
131+
{
132+
g_usdhcTransferSuccessFlag = true;
133+
}
134+
else
135+
{
136+
g_usdhcTransferSuccessFlag = false;
137+
}
138+
139+
EVENT_Notify(kEVENT_TransferComplete);
140+
}
141+
142+
/* USDHC transfer complete callback function. */
143+
static void USDHC_ReTuningCallback(void)
144+
{
145+
g_reTuningFlag = true;
146+
EVENT_Notify(kEVENT_TransferComplete);
147+
}
148+
149+
/* User defined transfer function. */
150+
static status_t USDHC_TransferFunction(USDHC_Type *base, usdhc_transfer_t *content)
151+
{
152+
status_t error = kStatus_Success;
153+
154+
usdhc_adma_config_t dmaConfig;
155+
156+
if (content->data != NULL)
157+
{
158+
memset(&dmaConfig, 0, sizeof(usdhc_adma_config_t));
159+
/* config adma */
160+
dmaConfig.dmaMode = USDHC_DMA_MODE;
161+
dmaConfig.burstLen = kUSDHC_EnBurstLenForINCR;
162+
dmaConfig.admaTable = g_usdhcAdma2Table;
163+
dmaConfig.admaTableWords = USDHC_ADMA_TABLE_WORDS;
164+
}
165+
166+
do
167+
{
168+
error = USDHC_TransferNonBlocking(base, &g_usdhcHandle, &dmaConfig, content);
169+
} while (error == kStatus_USDHC_BusyTransferring);
170+
171+
if ((error != kStatus_Success) || (false == EVENT_Wait(kEVENT_TransferComplete, EVENT_TIMEOUT_TRANSFER_COMPLETE)) ||
172+
(g_reTuningFlag) || (!g_usdhcTransferSuccessFlag))
173+
{
174+
if (g_reTuningFlag || (error == kStatus_USDHC_ReTuningRequest))
175+
{
176+
if (g_reTuningFlag)
177+
{
178+
g_reTuningFlag = false;
179+
error = kStatus_USDHC_TuningError;
180+
}
181+
}
182+
else
183+
{
184+
error = kStatus_Fail;
185+
/* host error recovery */
186+
Host_ErrorRecovery(base);
187+
}
188+
}
189+
190+
return error;
191+
}
192+
193+
static void Host_ErrorRecovery(HOST_TYPE *hostBase)
194+
{
195+
uint32_t status = 0U;
196+
/* get host present status */
197+
status = USDHC_GetPresentStatusFlags(hostBase);
198+
/* check command inhibit status flag */
199+
if ((status & kUSDHC_CommandInhibitFlag) != 0U)
200+
{
201+
/* reset command line */
202+
USDHC_Reset(hostBase, kUSDHC_ResetCommand, 100U);
203+
}
204+
/* check data inhibit status flag */
205+
if ((status & kUSDHC_DataInhibitFlag) != 0U)
206+
{
207+
/* reset data line */
208+
USDHC_Reset(hostBase, kUSDHC_ResetData, 100U);
209+
}
210+
}
211+
212+
status_t HOST_Init(void *host)
213+
{
214+
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
215+
usdhc_transfer_callback_t callback;
216+
/* init card power control */
217+
HOST_INIT_SD_POWER();
218+
HOST_INIT_MMC_POWER();
219+
220+
/* register callback function */
221+
callback.TransferComplete = USDHC_TransferCompleteCallback;
222+
callback.ReTuning = USDHC_ReTuningCallback;
223+
/* Initializes USDHC. */
224+
usdhcHost->config.dataTimeout = USDHC_DATA_TIMEOUT;
225+
usdhcHost->config.endianMode = USDHC_ENDIAN_MODE;
226+
usdhcHost->config.readWatermarkLevel = USDHC_READ_WATERMARK_LEVEL;
227+
usdhcHost->config.writeWatermarkLevel = USDHC_WRITE_WATERMARK_LEVEL;
228+
usdhcHost->config.readBurstLen = USDHC_READ_BURST_LEN;
229+
usdhcHost->config.writeBurstLen = USDHC_WRITE_BURST_LEN;
230+
231+
USDHC_Init(usdhcHost->base, &(usdhcHost->config));
232+
233+
/* disable the card insert/remove interrupt, due to use GPIO interrupt detect card */
234+
USDHC_DisableInterruptSignal(usdhcHost->base, kUSDHC_CardRemovalFlag | kUSDHC_CardInsertionFlag);
235+
/* create interrupt handler */
236+
USDHC_TransferCreateHandle(usdhcHost->base, &g_usdhcHandle, &callback, NULL);
237+
238+
if (false == EVENT_Create(kEVENT_TransferComplete))
239+
{
240+
return kStatus_Fail;
241+
}
242+
243+
/* Define transfer function. */
244+
usdhcHost->transfer = USDHC_TransferFunction;
245+
246+
return kStatus_Success;
247+
}
248+
249+
void HOST_Reset(HOST_TYPE *hostBase)
250+
{
251+
/* voltage switch to normal but not 1.8V */
252+
HOST_SWITCH_VOLTAGE180V(hostBase, false);
253+
/* Disable DDR mode */
254+
HOST_ENABLE_DDR_MODE(hostBase, false);
255+
/* disable tuning */
256+
HOST_EXECUTE_STANDARD_TUNING_ENABLE(hostBase, false);
257+
/* Disable HS400 mode */
258+
HOST_ENABLE_HS400_MODE(hostBase, false);
259+
/* Disable DLL */
260+
HOST_ENABLE_STROBE_DLL(hostBase, false);
261+
}
262+
263+
void HOST_Deinit(void *host)
264+
{
265+
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
266+
USDHC_Deinit(usdhcHost->base);
267+
EVENT_Delete(kEVENT_TransferComplete);
268+
}

0 commit comments

Comments
 (0)