source: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/sdmmc.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 38.7 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
11 * によって公表されている GNU General Public License の Version 2 に記
12 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
13 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 *
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
34 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
35 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 *
37 * @(#) $Id$
38 */
39/*
40 * STM32F746用 SDMMCドライバ
41 */
42#include "kernel_impl.h"
43#include <t_syslog.h>
44#include <t_stdlib.h>
45#include <sil.h>
46#include <target_syssvc.h>
47#include "kernel_cfg.h"
48#include "device.h"
49#include "sdmmc.h"
50
51#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
52#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
53#define sil_modw_mem(a, b, c) sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
54
55#ifdef TOPPERS_STM32F769_DISCOVERY
56#define TADR_SDMMC_BASE TADR_SDMMC2_BASE
57#define GPIO_AF10_SDMMC2 0x0A /* SDMMC2 Alternate Function mapping */
58#define GPIO_AF11_SDMMC2 0x0B /* SDMMC2 Alternate Function mapping */
59#define RCC_APB2ENR_SDMMCEN RCC_APB2ENR_SDMMC2EN
60#define SD_DETECT_CLOCK RCC_AHB1ENR_GPIOIEN
61#define SD_DETECT_PORT TADR_GPIOI_BASE
62#define SD_DETECT_PIN 15
63#define TADR_DMA_RX TADR_DMA2_STM0_BASE
64#define TADR_DMA_TX TADR_DMA2_STM5_BASE
65#define DMA_RX_CHANNEL DMA_CHANNEL_11
66#define DMA_TX_CHANNEL DMA_CHANNEL_11
67
68#else
69#define TADR_SDMMC_BASE TADR_SDMMC1_BASE
70#define GPIO_AF12_SDMMC1 0x0C /* SDMMC1 Alternate Function mapping */
71#define RCC_APB2ENR_SDMMCEN RCC_APB2ENR_SDIOEN
72#define SD_DETECT_CLOCK RCC_AHB1ENR_GPIOCEN
73#define SD_DETECT_PORT TADR_GPIOC_BASE
74#define SD_DETECT_PIN 13
75#define TADR_DMA_RX TADR_DMA2_STM3_BASE
76#define TADR_DMA_TX TADR_DMA2_STM6_BASE
77#define DMA_RX_CHANNEL DMA_CHANNEL_4
78#define DMA_TX_CHANNEL DMA_CHANNEL_4
79
80#endif
81
82
83#define CLKCR_CLEAR_MASK ((SDMMC_CLKCR_CLKDIV | SDMMC_CLKCR_PWRSAV |\
84 SDMMC_CLKCR_BYPASS | SDMMC_CLKCR_WIDBUS |\
85 SDMMC_CLKCR_NEGEDGE | SDMMC_CLKCR_HWFC_EN))
86/* --- DCTRL Register ---*/
87/* SDMMC DCTRL Clear Mask */
88#define DCTRL_CLEAR_MASK ((SDMMC_DCTRL_DTEN | SDMMC_DCTRL_DTDIR |\
89 SDMMC_DCTRL_DTMODE | SDMMC_DCTRL_DBLOCKSIZE))
90
91/* --- CMD Register ---*/
92/* CMD Register clear mask */
93#define CMD_CLEAR_MASK ((SDMMC_CMD_CMDINDEX | SDMMC_CMD_WAITRESP |\
94 SDMMC_CMD_WAITINT | SDMMC_CMD_WAITPEND |\
95 SDMMC_CMD_CPSMEN | SDMMC_CMD_SDIOSUSPEND))
96
97/*
98 * SDMMCデータブロック長
99 */
100#define DATA_BLOCK_SIZE (9 << 4)
101
102/*
103 * SDMMCでスタックに使用するフラグ
104 */
105#define SDMMC_STATIC_FLAGS (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | SDMMC_STA_CTIMEOUT |\
106 SDMMC_STA_DTIMEOUT | SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR |\
107 SDMMC_STA_CMDREND | SDMMC_STA_CMDSENT | SDMMC_STA_DATAEND |\
108 SDMMC_STA_DBCKEND)
109
110/*
111 * RESPONSE1エラー値
112 */
113#define SD_OCR_ERROR 0xFDFFE008
114
115/*
116 * RESPONSE6エラー値
117 */
118#define SD_R6_GENERAL_UNKNOWN_ERROR 0x00002000
119#define SD_R6_ILLEGAL_CMD 0x00004000
120#define SD_R6_COM_CRC_FAILED 0x00008000
121
122#define SDMMC_WAIT_STATUS (SDMMC_STA_CCRCFAIL | SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT)
123#define SDMMC_INT1_ERROR (SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT | SDMMC_STA_RXOVERR)
124#define SDMMC_INT2_ERROR (SDMMC_INT1_ERROR | SDMMC_STA_TXUNDERR)
125#define SDMMC_INT_MASK (SDMMC_INT2_ERROR | SDMMC_STA_DATAEND | SDMMC_STA_TXFIFOHE | SDMMC_STA_RXFIFOHF)
126
127/*
128 * カードタイプ定義
129 */
130#define SD_HIGH_CAPACITY 0x40000000
131#define SD_STD_CAPACITY 0x00000000
132
133/*
134 * SCRのビット定義
135 */
136#define SD_WIDE_BUS_SUPPORT 0x00040000
137#define SD_SINGLE_BUS_SUPPORT 0x00010000
138#define SD_CARD_LOCKED 0x02000000
139
140/*
141 * CSDのクラスサポート定義
142 */
143#define SD_CCCC_LOCK_UNLOCK 0x00000080
144#define SD_CCCC_WRITE_PROT 0x00000040
145#define SD_CCCC_ERASE 0x00000020
146
147#define SD_MAX_VOLT_TRIAL 0x0000FFFF
148#define SDMMC_CMD0TIMEOUT (5000*1000)
149
150
151static ER sdmmc_sendcommand(SDMMC_Handle_t *hsd, uint32_t cmd, uint32_t arg, ER (*func)(SDMMC_Handle_t *, uint32_t));
152
153static ER sdmmc_checkrep1(SDMMC_Handle_t *hsd, uint32_t Cmd);
154static ER sdmmc_checkrep2(SDMMC_Handle_t *hsd, uint32_t Cmd);
155static ER sdmmc_checkrep3(SDMMC_Handle_t *hsd, uint32_t Cmd);
156static ER sdmmc_checkrep6(SDMMC_Handle_t *hsd, uint32_t Cmd);
157static ER sdmmc_command_wait(SDMMC_Handle_t *hsd);
158
159static ER sdmmc_enable_widebus(SDMMC_Handle_t *hsd);
160static ER sdmmc_disable_widebus(SDMMC_Handle_t *hsd);
161static ER sdmmc_getSCR(SDMMC_Handle_t *hsd, uint32_t *pSCR);
162static ER sdmmc_getpstate(SDMMC_Handle_t *hsd, uint8_t *pStatus);
163
164static SDMMC_Handle_t SdHandle;
165
166/*
167 * SDMMC 受信DMAコールバック関数
168 */
169static void
170sdmmc_rxdma_callback(DMA_Handle_t *hdma)
171{
172 isig_sem(SDMMC_SEM);
173}
174
175/*
176 * SDMMC 送信DMAコールバック関数
177 */
178static void
179sdmmc_txdma_callback(DMA_Handle_t *hdma)
180{
181 isig_sem(SDMMC_SEM);
182}
183
184
185/*
186 * SDMMC初期化
187 * parameter1 addr: Pointer to SDMMC register base
188 */
189void
190sdmmc_init(intptr_t exinf)
191{
192 GPIO_Init_t GPIO_Init_Data;
193 volatile unsigned long tmp;
194
195 /* AHB1ENRクロックイネーブル */
196 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), SD_DETECT_CLOCK);
197#ifdef TOPPERS_STM32F769_DISCOVERY
198 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOGEN);
199#else
200 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN);
201#endif
202 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
203 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN);
204 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
205
206 GPIO_Init_Data.mode = GPIO_MODE_INPUT;
207 GPIO_Init_Data.pull = GPIO_PULLUP;
208 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
209 gpio_setup(SD_DETECT_PORT, &GPIO_Init_Data, SD_DETECT_PIN);
210
211 /* SDIOクロックイネーブル */
212 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SDMMCEN);
213 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR));
214 (void)(tmp);
215
216 GPIO_Init_Data.mode = GPIO_MODE_AF;
217 GPIO_Init_Data.pull = GPIO_PULLUP;
218 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
219 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
220#ifdef TOPPERS_STM32F769_DISCOVERY
221 GPIO_Init_Data.alternate = GPIO_AF10_SDMMC2;
222 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 3);
223 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 4);
224 GPIO_Init_Data.alternate = GPIO_AF11_SDMMC2;
225 gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, 6);
226 gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, 7);
227 gpio_setup(TADR_GPIOG_BASE, &GPIO_Init_Data, 9);
228 gpio_setup(TADR_GPIOG_BASE, &GPIO_Init_Data, 10);
229#else
230 GPIO_Init_Data.alternate = GPIO_AF12_SDMMC1;
231 gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 8);
232 gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 9);
233 gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 10);
234 gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 11);
235 gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 12);
236 gpio_setup(TADR_GPIOD_BASE, &GPIO_Init_Data, 2);
237#endif
238}
239
240/*
241 * SDカード有無チェック
242 */
243bool_t
244sdmmc_sense(int id)
245{
246 if((sil_rew_mem((uint32_t *)(SD_DETECT_PORT+TOFF_GPIO_IDR)) & (1<<SD_DETECT_PIN)) != 0)
247 return false;
248 else
249 return true;
250}
251
252/*
253 * SDMMCオープン
254 */
255SDMMC_Handle_t*
256sdmmc_open(int id)
257{
258 static DMA_Handle_t dma_rx_handle;
259 static DMA_Handle_t dma_tx_handle;
260 ER ercd = E_OK;
261 SDMMC_Handle_t *hsd = &SdHandle;
262 uint32_t response = 0, count = 0, validvoltage = 0;
263 uint32_t sdtype = SD_STD_CAPACITY;
264 int timeout;
265
266 hsd->base = TADR_SDMMC_BASE;
267 hsd->ClockMode = SDMMC_TRANSFER_CLK_DIV;
268 hsd->BusWide = SDMMC_BUS_WIDE_4B;
269 hsd->RetryCount = 32;
270 /*
271 * 初期設定、BUS WIDEは1ビット
272 */
273 sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), CLKCR_CLEAR_MASK, (SDMMC_INIT_CLK_DIV | SDMMC_BUS_WIDE_1B));
274
275 /*
276 * SDMMCクロック停止後、電源オンし、1秒後クロック再開
277 */
278 sil_andw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), SDMMC_CLKCR_CLKEN);
279 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_POWER), SDMMC_POWER_PWRCTRL);
280
281 /* 1MSの待ち */
282 dly_tsk(1);
283 sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), SDMMC_CLKCR_CLKEN);
284
285 /*
286 * CMD0: GO IDLE STATE
287 */
288 sdmmc_sendcommand(hsd, MCI_CMD0, 0, NULL);
289
290 /* コマンドステート終了待ち */
291 timeout = 5000;
292 while((timeout > 0) && ((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CMDSENT) == 0)){
293 dly_tsk(1);
294 timeout--;
295 }
296 if(timeout == 0){
297 return NULL;
298 }
299
300 /* ステートフラグをクリア */
301 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
302
303 /*
304 * CMD8: SEND IF COND
305 */
306 sdmmc_sendcommand(hsd, MCI_CMD8, 0x000001AA, NULL);
307 ercd = sdmmc_command_wait(hsd);
308 if(ercd != E_OK || ((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CTIMEOUT) != 0)){
309 /*
310 * タイムアウトならタイムアウトをクリア
311 */
312 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CTIMEOUT);
313 }
314 else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CMDREND) != 0){
315 /*
316 * レスポンスエンドならSDCARDV2.0確定
317 */
318 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CMDREND);
319 hsd->cardtype = SD_CARD_V20;
320 sdtype = SD_HIGH_CAPACITY;
321 }
322
323 /*
324 * CMD55を送信
325 */
326 ercd = sdmmc_sendcommand(hsd, MCI_CMD55, 0, sdmmc_checkrep1);
327 if(ercd == E_OK){
328 /*
329 * SDCARD確定:VOLTAGEの確認
330 */
331 while(validvoltage == 0 && count < SD_MAX_VOLT_TRIAL){
332 /* SEND CMD55 APP_CMD with RCA as 0 */
333 ercd = sdmmc_sendcommand(hsd, MCI_CMD55, 0, sdmmc_checkrep1);
334 if(ercd != E_OK){
335 return NULL;
336 }
337 /*
338 * 引数0x8010000でCMD41を送信
339 */
340 ercd = sdmmc_sendcommand(hsd, MCI_ACMD41, (0x80100000 | sdtype), sdmmc_checkrep3);
341 if(ercd != E_OK){
342 return NULL;
343 }
344 /*
345 * レスポンスから制御ボルテージを取得
346 */
347 response = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
348 validvoltage = (((response >> 31) == 1) ? 1 : 0);
349 count++;
350 }
351 if(count >= SD_MAX_VOLT_TRIAL){
352 return NULL;
353 }
354
355 if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY){
356 /*
357 * HC-SDCARD確定
358 */
359 hsd->cardtype = SD_CARD_HC;
360 }
361 }
362
363 /*
364 * 受信DMAのコンフィギュレーション
365 */
366 dma_rx_handle.Init.Channel = DMA_RX_CHANNEL;
367 dma_rx_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
368 dma_rx_handle.Init.PeriphInc = DMA_PINC_DISABLE;
369 dma_rx_handle.Init.MemInc = DMA_MINC_ENABLE;
370 dma_rx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
371 dma_rx_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
372 dma_rx_handle.Init.Mode = DMA_PFCTRL;
373 dma_rx_handle.Init.Priority = DMA_PRIORITY_VERY_HIGH;
374 dma_rx_handle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
375 dma_rx_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
376 dma_rx_handle.Init.MemBurst = DMA_MBURST_INC4;
377 dma_rx_handle.Init.PeriphBurst = DMA_PBURST_INC4;
378 dma_rx_handle.base = TADR_DMA_RX;
379
380 /*
381 * 受信DMAハンドルの設定
382 */
383 hsd->hdmarx = &dma_rx_handle;
384 dma_deinit(&dma_rx_handle);
385 dma_init(&dma_rx_handle);
386
387 /*
388 * 送信DMAのコンフィギュレーション
389 */
390 dma_tx_handle.Init.Channel = DMA_TX_CHANNEL;
391 dma_tx_handle.Init.Direction = DMA_MEMORY_TO_PERIPH;
392 dma_tx_handle.Init.PeriphInc = DMA_PINC_DISABLE;
393 dma_tx_handle.Init.MemInc = DMA_MINC_ENABLE;
394 dma_tx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
395 dma_tx_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
396 dma_tx_handle.Init.Mode = DMA_PFCTRL;
397 dma_tx_handle.Init.Priority = DMA_PRIORITY_VERY_HIGH;
398 dma_tx_handle.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
399 dma_tx_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
400 dma_tx_handle.Init.MemBurst = DMA_MBURST_INC4;
401 dma_tx_handle.Init.PeriphBurst = DMA_PBURST_INC4;
402 dma_tx_handle.base = TADR_DMA_TX;
403
404 /*
405 * 送信DMAハンドルの設定
406 */
407 hsd->hdmatx = &dma_tx_handle;
408 dma_deinit(&dma_tx_handle);
409 dma_init(&dma_tx_handle);
410 return hsd;
411}
412
413/*
414 * SDMMCクローズ
415 */
416ER
417sdmmc_close(SDMMC_Handle_t *hsd)
418{
419 if(hsd == NULL)
420 return E_PAR;
421
422 /* SDの電源オフ */
423 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_POWER), 0x00000000);
424 hsd->status = 3;
425 return E_OK;
426}
427
428/*
429 * SDMMCカードイレーズ
430 * parameter1 hsd: SDMMCハンドラ
431 * parameter2 startaddr: スタートバイト位置
432 * parameter3 endaddr: エンドバイト位置
433 * return :ERコード
434 */
435ER
436sdmmc_erase(SDMMC_Handle_t *hsd, uint64_t startaddr, uint64_t endaddr)
437{
438 ER ercd = E_OK;
439 uint32_t delay = 0;
440 volatile uint32_t maxdelay = 0;
441 uint8_t cardstate = 0;
442
443 if(hsd == NULL)
444 return E_PAR;
445
446 /*
447 * イレーズコマンド有り無し判定
448 */
449 if(((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0){
450 return E_OBJ;
451 }
452
453 /*
454 * コマンド受付待ちカウント取得
455 */
456 maxdelay = 120000 / (((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR))) & 0xFF) + 2);
457
458 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP)) & SD_CARD_LOCKED) == SD_CARD_LOCKED){
459 return E_OBJ;
460 }
461
462 /*
463 * HC SDCARDの設定アドレス補正
464 */
465 if(hsd->cardtype == SD_CARD_HC){
466 startaddr /= 512;
467 endaddr /= 512;
468 }
469
470 /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
471 if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20 || hsd->cardtype == SD_CARD_HC){
472 /* Send CMD32 SD_ERASE_GRP_START with argument as addr */
473 ercd = sdmmc_sendcommand(hsd, MCI_CMD32, (uint32_t)startaddr, sdmmc_checkrep1);
474 if (ercd != E_OK){
475 return ercd;
476 }
477
478 /* Send CMD33 SD_ERASE_GRP_END with argument as addr */
479 ercd = sdmmc_sendcommand(hsd, MCI_CMD33, (uint32_t)endaddr, sdmmc_checkrep1);
480 if(ercd != E_OK){
481 return ercd;
482 }
483 }
484
485 /*
486 * CMD38 ERASE送信
487 */
488 ercd = sdmmc_sendcommand(hsd, MCI_CMD38, 0, sdmmc_checkrep1);
489 if(ercd != E_OK){
490 return ercd;
491 }
492
493 for (; delay < maxdelay; delay++){
494 }
495
496 /*
497 * プログラミング終了待ち
498 */
499 ercd = sdmmc_getpstate(hsd, &cardstate);
500 delay = 120*1000;
501 while(delay > 0 && ercd == E_OK && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))){
502 ercd = sdmmc_getpstate(hsd, &cardstate);
503 dly_tsk(1);
504 delay--;
505 }
506 return ercd;
507}
508
509/*
510 * SDMMCブロックREAD
511 * parameter1 hsd: SDMMCハンドラ
512 * parameter2 pbuf: 読み出しデータ格納領域のポインタ(uint32_t型)
513 * parameter3 ReadAddr: カード上の読み出し位置
514 * parameter4 blocksize: ブロックサイズ
515 * parameter5 num: 読み出しブロック数
516 * return ERコード
517 */
518ER
519sdmmc_blockread(SDMMC_Handle_t *hsd, uint32_t *pbuf, uint64_t ReadAddr, uint32_t blocksize, uint32_t num)
520{
521 ER ercd = E_OK;
522
523 if(hsd == NULL)
524 return E_PAR;
525
526 /*
527 * データコントロールレジスタをクリア
528 */
529 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), 0);
530
531 /*
532 * ステートをクリア
533 */
534 hsd->status = 0;
535
536 /*
537 * リードコマンド選択
538 */
539 if(num > 1)
540 hsd->SdCmd = MCI_CMD18;
541 else
542 hsd->SdCmd = MCI_CMD17;
543
544 /*
545 * 転送割込み設定
546 */
547 sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_MASK), (SDMMC_INT1_ERROR | SDMMC_STA_DATAEND));
548
549 /*
550 * DMA転送設定
551 */
552 sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), SDMMC_DCTRL_DMAEN);
553
554 /*
555 * コールバック関数設定
556 */
557 hsd->hdmarx->xfercallback = sdmmc_rxdma_callback;
558 hsd->hdmarx->errorcallback = NULL;
559
560 /*
561 * 受信DMAスタート
562 */
563 if(((uint32_t)pbuf) < 0x40000000)
564 flushinvalidatedcache_by_addr((uint8_t *)pbuf, (blocksize * num));
565 dma_start(hsd->hdmarx, hsd->base+TOFF_SDIO_FIFO, (uint32_t)pbuf, (uint32_t)(blocksize * num)/4);
566 if(hsd->cardtype == SD_CARD_HC){
567 blocksize = 512;
568 ReadAddr /= 512;
569 }
570
571 /*
572 * CMD16:ブロックサイズ設定
573 */
574 ercd = sdmmc_sendcommand(hsd, MCI_CMD16, (uint32_t)blocksize, sdmmc_checkrep1);
575 if(ercd != E_OK){
576 return ercd;
577 }
578
579 /*
580 * SD-DPSMを設定
581 */
582 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DTIMER), 0xFFFFFFFF);
583 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DLEN), blocksize * num);
584 sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), DCTRL_CLEAR_MASK,
585 (SDMMC_DBSIZE_512B | SDMMC_DCTRL_DTDIR | SDMMC_DCTRL_DTEN));
586
587 /*
588 * READコマンド送信
589 */
590 ercd = sdmmc_sendcommand(hsd, hsd->SdCmd, (uint32_t)ReadAddr, sdmmc_checkrep1);
591
592 /*
593 * 送信エラーならエラー設定をする
594 */
595 if (ercd != E_OK){
596 hsd->status = 2;
597 }
598 return ercd;
599}
600
601/*
602 * SDMMCブロックWRITE
603 * parameter1 hsd: SDMMCハンドラ
604 * parameter2 pbuf: 書込みデータ格納領域のポインタ(uint32_t型)
605 * parameter3 WritedAddr: カード上の書き込み位置
606 * parameter4 blocksize: ブロックサイズ
607 * parameter5 num: 書込みブロック数
608 * return ERコード
609 */
610ER
611sdmmc_blockwrite(SDMMC_Handle_t *hsd, uint32_t *pbuf, uint64_t WriteAddr, uint32_t blocksize, uint32_t num)
612{
613 ER ercd = E_OK;
614
615 if(hsd == NULL)
616 return E_PAR;
617
618 /*
619 * データコントロールレジスタをクリア
620 */
621 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), 0);
622
623 /*
624 * ステートをクリア
625 */
626 hsd->status = 0;
627
628 /*
629 * ライトコマンド選択
630 */
631 if(num > 1)
632 hsd->SdCmd = MCI_CMD25;
633 else
634 hsd->SdCmd = MCI_CMD24;
635
636 /*
637 * 転送割込み設定
638 */
639 sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_MASK), (SDMMC_INT2_ERROR | SDMMC_STA_DATAEND));
640
641 /*
642 * コールバック関数設定
643 */
644 hsd->hdmatx->xfercallback = sdmmc_txdma_callback;
645 hsd->hdmatx->errorcallback = NULL;
646
647 /*
648 * 送信DMAスタート
649 */
650 if(((uint32_t)pbuf) < 0x40000000)
651 flushinvalidatedcache_by_addr((uint8_t *)pbuf, (blocksize * num));
652 dma_start(hsd->hdmatx, (uint32_t)pbuf, hsd->base+TOFF_SDIO_FIFO, (uint32_t)(blocksize * num)/4);
653 if(hsd->cardtype == SD_CARD_HC){
654 blocksize = 512;
655 WriteAddr /= 512;
656 }
657
658 /*
659 * DMA転送設定
660 */
661 sil_orw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), SDMMC_DCTRL_DMAEN);
662
663 /*
664 * CMD16:ブロックサイズ設定
665 */
666 ercd = sdmmc_sendcommand(hsd, MCI_CMD16, (uint32_t)blocksize, sdmmc_checkrep1);
667 if(ercd != E_OK){
668 return ercd;
669 }
670
671 /*
672 * WRITEコマンド送信
673 */
674 ercd = sdmmc_sendcommand(hsd, hsd->SdCmd, (uint32_t)WriteAddr, sdmmc_checkrep1);
675 if(ercd != E_OK){
676 return ercd;
677 }
678
679 /*
680 * SD-DPSMを設定
681 */
682 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DTIMER), 0xFFFFFFFF);
683 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DLEN), blocksize * num);
684 sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), DCTRL_CLEAR_MASK,
685 (SDMMC_DBSIZE_512B | SDMMC_DCTRL_DTEN));
686
687 /*
688 * 送信エラーならエラー設定をする
689 */
690 if(ercd != E_OK){
691 hsd->status = 2;
692 }
693 return ercd;
694}
695
696/*
697 * SDMMCブロック転送終了待ち
698 * parameter1 hsd: SDMMCハンドラ
699 * parameter2 Timeout: タイムアウト値(1msec)
700 * return ERコード
701 */
702ER
703sdmmc_wait_transfar(SDMMC_Handle_t *hsd, uint32_t Timeout)
704{
705 DMA_Handle_t *hdma = hsd->hdmarx;
706 ER tercd = E_OK, ercd = E_OK;
707 int timeout;
708 uint32_t tmp1, tmp2;
709
710 if(hsd == NULL)
711 return E_PAR;
712
713 if(Timeout > 60*1000);
714 Timeout = 60*1000;
715 timeout = Timeout;
716 /*
717 * DMA/SD転送の終了割込み待ち
718 */
719 tmp1 = hdma->status;
720 tmp2 = hsd->status;
721
722 while((tmp1 == DMA_STATUS_BUSY || tmp2 == 0) && timeout > 0){
723 tmp1 = hdma->status;
724 tmp2 = hsd->status;
725 twai_sem(SDMMC_SEM, 10);
726 timeout -= 10;
727 }
728
729 timeout = Timeout;
730 if(hsd->status != 1){
731 ercd = hsd->status;
732 }
733
734 if(hsd->SdCmd == MCI_CMD18 || hsd->SdCmd == MCI_CMD17){ /* 読み出し処理待ち */
735 dma_end(hsd->hdmarx);
736 /*
737 * 受信ACTオフ待ち
738 */
739 while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_RXACT) != 0 && timeout > 0){
740 dly_tsk(1);
741 timeout--;
742 }
743
744 /*
745 * マルチブロック転送ならCMD12を送信
746 */
747 if(hsd->SdCmd == MCI_CMD18){
748 tercd = sdmmc_sendcommand(hsd, MCI_CMD12, 0, sdmmc_checkrep1);
749 }
750 if(ercd == E_OK)
751 ercd = tercd;
752 if(timeout == 0 && ercd == E_OK)
753 ercd = E_TMOUT;
754
755 /*
756 * 転送フラグをクリア
757 */
758 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
759 }
760 else{ /* 書き込み待ち処理 */
761 dma_end(hsd->hdmatx);
762 /*
763 * 送信ACTオフ待ち
764 */
765 while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_TXACT) != 0 && timeout > 0){
766 dly_tsk(1);
767 timeout--;
768 }
769
770 /*
771 * マルチブロック転送ならCMD12を送信
772 */
773 if(hsd->SdCmd == MCI_CMD25){
774 tercd = sdmmc_sendcommand(hsd, MCI_CMD12, 0, sdmmc_checkrep1);
775 }
776 if(ercd == E_OK)
777 ercd = tercd;
778 if(timeout == 0 && ercd == E_OK)
779 ercd = E_TMOUT;
780
781 /*
782 * 転送フラグをクリア
783 */
784 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
785
786 /*
787 * 送信終了待ち
788 */
789 while(sdmmc_getstatus(hsd) != SD_TRANSFER_OK){
790 dly_tsk(1);
791 }
792 }
793 return ercd;
794}
795
796/*
797 * SDカード割込みテストルーチン
798 * parameter1 hsd: SDMMCハンドラ
799 */
800void
801sdmmc_checkint(SDMMC_Handle_t *hsd)
802{
803 uint32_t status = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA));
804
805 /* データエンドを検証 */
806 if((status & SDMMC_STA_DATAEND) != 0){
807 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_DATAEND);
808 hsd->status = 1; /* 終了番号をセット */
809 }
810 else if((status & SDMMC_INT2_ERROR) != 0){
811 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), (status & SDMMC_INT2_ERROR));
812 hsd->status = E_SDTRS;
813 }
814
815 /* 割込みをマスク */
816 sil_andw_mem((uint32_t *)(hsd->base+TOFF_SDIO_MASK), SDMMC_INT_MASK);
817}
818
819
820/*
821 * SDカードの情報を取り込む
822 * parameter1 hsd: SDMMCハンドラ
823 * parameter2 pCardInfo: カードインフォ構造体へのポインタ
824 * return ERコード
825 */
826ER
827sdmmc_getcardinfo(SDMMC_Handle_t *hsd, SDMMC_CardInfo_t *pCardInfo)
828{
829 ER ercd = E_OK;
830 uint32_t devicesize;
831 uint8_t blocklen, mul;
832
833 pCardInfo->cardtype = (uint8_t)(hsd->cardtype);
834 pCardInfo->RCA = (uint16_t)(hsd->RCA);
835
836 if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20){
837 /* ブロック長を取り込む */
838 blocklen = (uint8_t)((hsd->CSD[1] & 0x000F0000) >> 16);
839 devicesize = (hsd->CSD[1] & 0x000003FF) << 2;
840 devicesize |= (hsd->CSD[2] & 0xC0000000) >> 30;
841 mul = (hsd->CSD[2] & 0x00038000) >> 15;
842 pCardInfo->capacity = (devicesize + 1) ;
843 pCardInfo->capacity *= (1 << (mul + 2));
844 pCardInfo->blocksize = 1 << (blocklen);
845 pCardInfo->capacity *= pCardInfo->blocksize;
846 }
847 else if(hsd->cardtype == SD_CARD_HC){
848 devicesize = (hsd->CSD[1] & 0x0000003F) << 16;
849 devicesize |= (hsd->CSD[2] & 0xFFFF0000) >> 16;
850 pCardInfo->capacity = (uint64_t)(devicesize + 1) << 19 /* 512 * 1024*/;
851 pCardInfo->blocksize = 512;
852 }
853 else{
854 pCardInfo->capacity = 0;
855 pCardInfo->blocksize = 512;
856 ercd = E_OBJ;
857 }
858 pCardInfo->maxsector = pCardInfo->capacity / 512;
859 pCardInfo->status = (uint8_t)((hsd->CSD[3] >> 8) & 0xff);
860#if 1 /* ROI DEBUG */
861 syslog_1(LOG_NOTICE, "## status[%02x] ##", pCardInfo->status);
862 syslog_5(LOG_NOTICE, "## cardtype(%d) capacity[%08x%08x] blocksize(%d) maxsector(%u) ##", pCardInfo->cardtype, (uint32_t)(pCardInfo->capacity>>32), (uint32_t)(pCardInfo->capacity & 0xffffffff), pCardInfo->blocksize, pCardInfo->maxsector);
863#endif /* ROI DEBUG */
864 return ercd;
865}
866
867/*
868 * WIDE BUS設定
869 * parameter1 hsd: SDMMCハンドラ
870 * return ERコード
871 */
872ER
873sdmmc_set_widebus(SDMMC_Handle_t *hsd)
874{
875 ER ercd = E_OK;
876
877 /* MMC Card does not support this feature */
878 if(hsd->cardtype == MMC_CARD){
879 return E_PAR;
880 }
881 else if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20 || hsd->cardtype == SD_CARD_HC){
882 if(hsd->BusWide == SDMMC_BUS_WIDE_8B)
883 ercd = E_NOSPT;
884 else if(hsd->BusWide == SDMMC_BUS_WIDE_4B)
885 ercd = sdmmc_enable_widebus(hsd);
886 else if(hsd->BusWide == SDMMC_BUS_WIDE_1B)
887 ercd = sdmmc_disable_widebus(hsd);
888 else
889 ercd = E_PAR;
890 if(ercd == E_OK){
891 /*
892 * 最終ペリフェラル設定
893 */
894 sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), CLKCR_CLEAR_MASK, ((hsd->ClockMode | hsd->BusWide)));
895 }
896 }
897 return ercd;
898}
899
900/*
901 * CIDの取得
902 * SDカードCMD2,MMCカードCMD1送信後のレスポンス受信
903 * parameter1 hsd: SDMMCハンドラ
904 * return ERコード
905 */
906ER
907sdmmc_checkCID(SDMMC_Handle_t *hsd)
908{
909 ER ercd = E_OK;
910 int i;
911
912 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_POWER)) & SDMMC_POWER_PWRCTRL) == 0){
913 return E_OBJ;
914 }
915
916 if(hsd->cardtype == SD_IO_CARD)
917 return E_OK;
918 for(i = 0 ; i < hsd->RetryCount ; i++){
919 /*
920 * CMD2送信
921 */
922 ercd = sdmmc_sendcommand(hsd, MCI_CMD2, 0, sdmmc_checkrep2);
923 if(ercd == E_OK){
924 /*
925 * CID取り込み
926 */
927 hsd->CID[0] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
928 hsd->CID[1] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP2));
929 hsd->CID[2] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP3));
930 hsd->CID[3] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP4));
931 return E_OK;
932 }
933 sil_dly_nse(2000);
934 }
935 return ercd;
936}
937
938/*
939 * 相対アドレス(RCA)の取得
940 * parameter1 hsd: SDMMCハンドラ
941 * return ERコード
942 */
943ER
944sdmmc_setaddress(SDMMC_Handle_t *hsd)
945{
946 ER ercd = E_OK;
947 int i;
948
949 if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20 ||
950 hsd->cardtype == SD_IO_COMBO_CARD || hsd->cardtype == SD_CARD_HC){
951
952 for(i = 0 ; i < hsd->RetryCount ; i++){
953 /*
954 * CMD3送信、RCA受信
955 */
956 ercd = sdmmc_sendcommand(hsd, MCI_CMD3, 0, sdmmc_checkrep6);
957 if(ercd == E_OK)
958 return E_OK;
959 sil_dly_nse(2000);
960 }
961 return E_TMOUT;
962 }
963 hsd->RCA = 1;
964 return ercd;
965}
966
967/*
968 * CSD(Card Specific DATA)の取得
969 * parameter1 hsd: SDMMCハンドラ
970 * return ERコード
971 */
972ER
973sdmmc_sendCSD(SDMMC_Handle_t *hsd)
974{
975 ER ercd = E_OK;
976 int i;
977
978 if(hsd->cardtype == SD_IO_CARD)
979 return E_OK;
980 for(i = 0 ; i < hsd->RetryCount ; i++){
981 /*
982 * CMD9送信、CSD要求
983 */
984 ercd = sdmmc_sendcommand(hsd, MCI_CMD9, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep2);
985 if(ercd == E_OK){
986 /*
987 * CSD取得
988 */
989 hsd->CSD[0] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
990 hsd->CSD[1] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP2));
991 hsd->CSD[2] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP3));
992 hsd->CSD[3] = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP4));
993 return E_OK;
994 }
995 sil_dly_nse(2000);
996 }
997 return ercd;
998}
999
1000/*
1001 * SELECT_CARDコマンドの送信
1002 * parameter1 hsd: SDMMCハンドラ
1003 * return ERコード
1004 */
1005ER
1006sdmmc_select_card(SDMMC_Handle_t *hsd, uint64_t addr)
1007{
1008 ER ercd = E_OK;
1009 int i;
1010
1011 for(i = 0 ; i < hsd->RetryCount ; i++){
1012 /*
1013 * CMD7送信 カードセレクト
1014 */
1015 ercd = sdmmc_sendcommand(hsd, MCI_CMD7, (uint32_t)addr, sdmmc_checkrep1);
1016 if(ercd == E_OK)
1017 return E_OK;
1018 sil_dly_nse(2000);
1019 }
1020 return ercd;
1021}
1022
1023/*
1024 * SDMMCコンフィギュレーション
1025 * parameter1 hsd: SDMMCハンドラ
1026 * return ERコード
1027 */
1028ER
1029sdmmc_configuration(SDMMC_Handle_t *hsd)
1030{
1031 /*
1032 * 最終コンフィギュレーション
1033 */
1034 sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_CLKCR), CLKCR_CLEAR_MASK, ((hsd->ClockMode | SDMMC_BUS_WIDE_1B)));
1035 return E_OK;
1036}
1037
1038/*
1039 * SDカードステートを取得
1040 * parameter1 hsd: SDMMCハンドラ
1041 * return カードステート
1042 */
1043uint32_t
1044sdmmc_getstatus(SDMMC_Handle_t *hsd)
1045{
1046 ER ercd = E_OK;
1047 uint32_t resp1 = 0;
1048 uint32_t cardstate = SD_CARD_TRANSFER;
1049
1050 /*
1051 * CMD13送信
1052 */
1053 ercd = sdmmc_sendcommand(hsd, MCI_CMD13, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep1);
1054 if(ercd != E_OK){
1055 return ercd;
1056 }
1057
1058 /*
1059 * SDカードステータス取り込み
1060 */
1061 resp1 = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
1062 cardstate = ((resp1 >> 9) & 0x0F);
1063
1064 /*
1065 * カードステータスをカードステートに変換
1066 */
1067 if(cardstate == SD_CARD_TRANSFER){
1068 return SD_TRANSFER_OK;
1069 }
1070 else if(cardstate == SD_CARD_ERROR){
1071 return SD_TRANSFER_ERROR;
1072 }
1073 else{
1074 return SD_TRANSFER_BUSY;
1075 }
1076}
1077
1078/*
1079 * WIDE BUSモード設定
1080 */
1081static ER
1082sdmmc_enable_widebus(SDMMC_Handle_t *hsd)
1083{
1084 ER ercd = E_OK;
1085 uint32_t scr[2];
1086
1087 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP)) & SD_CARD_LOCKED) == SD_CARD_LOCKED){
1088 return E_OBJ;
1089 }
1090 dly_tsk(1);
1091
1092 /* Get SCR Register */
1093 ercd = sdmmc_getSCR(hsd, scr);
1094 if(ercd != E_OK){
1095 return ercd;
1096 }
1097
1098 /*
1099 * WIDE BUS設定処理
1100 */
1101 if((scr[1] & SD_WIDE_BUS_SUPPORT) != 0){
1102 /*
1103 * CMD55送信(APPEDコマンド要求
1104 */
1105 ercd = sdmmc_sendcommand(hsd, MCI_CMD55, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep1);
1106 if(ercd != E_OK){
1107 return ercd;
1108 }
1109
1110 /*
1111 * WIDE BUS設定でACMD6コマンド送信
1112 */
1113 ercd = sdmmc_sendcommand(hsd, MCI_ACMD6, 2, sdmmc_checkrep1);
1114 return ercd;
1115 }
1116 return E_OBJ;
1117}
1118
1119/*
1120 * WIDE BUSモード停止
1121 */
1122static ER
1123sdmmc_disable_widebus(SDMMC_Handle_t *hsd)
1124{
1125 ER ercd = E_OK;
1126 uint32_t scr[2];
1127
1128 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP)) & SD_CARD_LOCKED) == SD_CARD_LOCKED){
1129 return E_SYS;
1130 }
1131 dly_tsk(1);
1132
1133 /* Get SCR Register */
1134 ercd = sdmmc_getSCR(hsd, scr);
1135 if(ercd != E_OK){
1136 return ercd;
1137 }
1138
1139 /*
1140 * 1ビットバス設定処理
1141 */
1142 if((scr[1] & SD_SINGLE_BUS_SUPPORT) != 0){
1143 /*
1144 * CMD55送信(APPEDコマンド要求
1145 */
1146 ercd = sdmmc_sendcommand(hsd, MCI_CMD55, (uint32_t)(hsd->RCA << 16), sdmmc_checkrep1);
1147 if(ercd != E_OK){
1148 return ercd;
1149 }
1150
1151 /*
1152 * 1 BIT BUS設定でACMD6コマンド送信
1153 */
1154 ercd = sdmmc_sendcommand(hsd, MCI_ACMD6, 0, sdmmc_checkrep1);
1155 return ercd;
1156 }
1157 return E_OBJ;
1158}
1159
1160/*
1161 * SCRの取得
1162 */
1163static ER
1164sdmmc_getSCR(SDMMC_Handle_t *hsd, uint32_t *pSCR)
1165{
1166 ER ercd = E_OK;
1167 uint32_t index = 0;
1168 uint32_t recvdata[2];
1169
1170 /*
1171 * 8バイトブロックサイズ設定
1172 */
1173 ercd = sdmmc_sendcommand(hsd, MCI_CMD16, 8, sdmmc_checkrep1);
1174 if(ercd != E_OK){
1175 return ercd;
1176 }
1177
1178 /*
1179 * CMD55送信(APPEDコマンド要求
1180 */
1181 ercd = sdmmc_sendcommand(hsd, MCI_CMD55, (uint32_t)((hsd->RCA) << 16), sdmmc_checkrep1);
1182 if(ercd != E_OK){
1183 return ercd;
1184 }
1185 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DTIMER),0xFFFFFFFF);
1186 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DLEN), 8);
1187 sil_modw_mem((uint32_t *)(hsd->base+TOFF_SDIO_DCTRL), DCTRL_CLEAR_MASK,
1188 (SDMMC_DBSIZE_8B | SDMMC_DCTRL_DTDIR | SDMMC_DCTRL_DTEN));
1189
1190 /*
1191 * ACMD51送信、SCR要求
1192 */
1193 ercd = sdmmc_sendcommand(hsd, MCI_ACMD51, 0, sdmmc_checkrep1);
1194 if(ercd != E_OK){
1195 return ercd;
1196 }
1197
1198 while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & (SDMMC_INT1_ERROR | SDMMC_STA_DBCKEND)) == 0){
1199 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_RXDAVL) != 0){
1200 *(recvdata + index) = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_FIFO));
1201 index++;
1202 }
1203 }
1204
1205 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_DTIMEOUT) != 0){
1206 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_DTIMEOUT);
1207 return E_TMOUT;
1208 }
1209 else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_DCRCFAIL) != 0){
1210 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_DCRCFAIL);
1211 return E_SDCRC;
1212 }
1213 else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_RXOVERR) != 0){
1214 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_RXOVERR);
1215 return E_SDTRS;
1216 }
1217 /*
1218 * スタティック・フラグをクリア
1219 */
1220 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
1221
1222 *(pSCR + 1) = ((recvdata[0] & 0x000000FF) << 24) | ((recvdata[0] & 0x0000FF00) << 8) |
1223 ((recvdata[0] & 0x00FF0000) >> 8) | ((recvdata[0] & 0xFF000000) >> 24);
1224
1225 *(pSCR) = ((recvdata[1] & 0x000000FF) << 24) | ((recvdata[1] & 0x0000FF00) << 8) |
1226 ((recvdata[1] & 0x00FF0000) >> 8) | ((recvdata[1] & 0xFF000000) >> 24);
1227 return E_OK;
1228}
1229
1230/*
1231 * プログラミングステートを取り出す
1232 */
1233static
1234ER sdmmc_getpstate(SDMMC_Handle_t *hsd, uint8_t *pStatus)
1235{
1236 volatile uint32_t respValue = 0;
1237 ER ercd;
1238
1239 sdmmc_sendcommand(hsd, MCI_CMD13, (uint32_t)(hsd->RCA << 16), NULL);
1240 ercd = sdmmc_command_wait(hsd);
1241 if(ercd != E_OK){
1242 return ercd;
1243 }
1244 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CTIMEOUT) != 0){
1245 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CTIMEOUT);
1246 return E_TMOUT;
1247 }
1248 else if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
1249 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
1250 return E_SDCRC;
1251 }
1252 else{ /* エラーなし */
1253 /*
1254 * レスポンス・コマンド・インデックスの確認
1255 */
1256 if((uint8_t)sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESPCMD)) != (MCI_CMD13 & CMD_INDEX)){
1257 return E_SDECMD;
1258 }
1259
1260 /*
1261 * スタティック・フラグをクリア
1262 */
1263 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
1264
1265 /*
1266 * レスポンス1を取得
1267 */
1268 respValue = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
1269
1270 /*
1271 * カードステータスを取り出す
1272 */
1273 *pStatus = (uint8_t)((respValue >> 9) & 0x0000000F);
1274
1275 /*
1276 * レスポンス1のエラーチェック
1277 */
1278 if((respValue & SD_OCR_ERROR) == 0)
1279 return E_OK;
1280 else
1281 return E_SYS;
1282 }
1283}
1284
1285/*
1286 * SDMMC割込みハンドラ
1287 */
1288void sdmmc_handler(void)
1289{
1290 sdmmc_checkint(&SdHandle);
1291 isig_sem(SDMMC_SEM);
1292}
1293
1294
1295/*
1296 * SDMMCコマンド送信
1297 */
1298static ER
1299sdmmc_sendcommand(SDMMC_Handle_t *hsd, uint32_t cmd, uint32_t arg, ER (*func)(SDMMC_Handle_t *, uint32_t))
1300{
1301 uint32_t addr = hsd->base;
1302
1303 sil_wrw_mem((uint32_t *)(addr+TOFF_SDIO_ARG), arg);
1304 sil_modw_mem((uint32_t *)(addr+TOFF_SDIO_CMD), CMD_CLEAR_MASK, ((cmd & CMD_MASK) | SDMMC_CMD_CPSMEN));
1305 if(func != NULL){
1306 ER ercd = sdmmc_command_wait(hsd);
1307 if(ercd != E_OK){
1308 return ercd;
1309 }
1310 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CTIMEOUT) != 0){
1311 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CTIMEOUT);
1312 return E_TMOUT;
1313 }
1314 return func(hsd, cmd);
1315 }
1316 else
1317 return E_OK;
1318}
1319
1320/*
1321 * R1レスポンス
1322 */
1323static ER
1324sdmmc_checkrep1(SDMMC_Handle_t *hsd, uint32_t Cmd)
1325{
1326 uint32_t respValue;
1327
1328 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
1329 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
1330 return E_SDCRC;
1331 }
1332
1333 /*
1334 * レスポンス・コマンド・インデックス確認
1335 */
1336 if((uint8_t)sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESPCMD)) != (Cmd & CMD_INDEX) && (Cmd & CMD_IGNOREIRES) == 0){
1337 return E_SDECMD;
1338 }
1339
1340 /*
1341 * スタティック・フラグをクリア
1342 */
1343 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
1344
1345 /*
1346 * レスポンス1のエラーチェック
1347 */
1348 respValue = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
1349 if((respValue & SD_OCR_ERROR) == 0)
1350 return E_OK;
1351 else
1352 return E_SDCOM;
1353}
1354
1355/*
1356 * R2レスポンス
1357 */
1358static ER
1359sdmmc_checkrep2(SDMMC_Handle_t *hsd, uint32_t Cmd)
1360{
1361 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
1362 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
1363 return E_SDCRC;
1364 }
1365 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
1366 return E_OK;
1367}
1368
1369/*
1370 * R3レスポンス
1371 */
1372static ER
1373sdmmc_checkrep3(SDMMC_Handle_t *hsd, uint32_t Cmd)
1374{
1375 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
1376 return E_OK;
1377}
1378
1379/*
1380 * R6レスポンス
1381 */
1382static ER
1383sdmmc_checkrep6(SDMMC_Handle_t *hsd, uint32_t Cmd)
1384{
1385 uint32_t respValue;
1386
1387 if((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_STA_CCRCFAIL) != 0){
1388 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STA_CCRCFAIL);
1389 return E_SDCRC;
1390 }
1391
1392 /*
1393 * レスポンス・コマンド・インデックス確認
1394 */
1395 if((uint8_t)sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESPCMD)) != (Cmd & CMD_INDEX)){
1396 return E_SDECMD;
1397 }
1398 sil_wrw_mem((uint32_t *)(hsd->base+TOFF_SDIO_ICR), SDMMC_STATIC_FLAGS);
1399
1400 /*
1401 * レスポンス1の確認
1402 */
1403 respValue = sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_RESP));
1404 if((respValue & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR){
1405 return E_OBJ;
1406 }
1407 if((respValue & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD){
1408 return E_SDECMD;
1409 }
1410 if((respValue & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED){
1411 return E_SDCRC;
1412 }
1413 hsd->RCA = (uint16_t) (respValue >> 16);
1414 return E_OK;
1415}
1416
1417/*
1418 * コマンド転送待ち
1419 */
1420static ER
1421sdmmc_command_wait(SDMMC_Handle_t *hsd)
1422{
1423 int timeout = SDMMC_CMD0TIMEOUT;
1424
1425 while((sil_rew_mem((uint32_t *)(hsd->base+TOFF_SDIO_STA)) & SDMMC_WAIT_STATUS) == 0){
1426 if(timeout == 0)
1427 return E_TMOUT;
1428 sil_dly_nse(1000);
1429 timeout--;
1430 }
1431 return E_OK;
1432}
1433
1434
Note: See TracBrowser for help on using the repository browser.