分享到plurk 分享到twitter 分享到facebook

版本 afd4b6ea6faab86c9f047db95a287de16d41e64d

embedded/SDIO

Changes from afd4b6ea6faab86c9f047db95a287de16d41e64d to 99a2a6c8889636ebbc0beac3acd555629cb8a33b

---
title: Secure digital input/output interface (SDIO)
categories: SDIO, STM32F4
...

Introduction
============

What is the SD/MMC?
--------------------------
- Secure Digital縮寫SD,全名Secure Digital Memory Card,中文翻譯為安全數位卡,為一種記憶卡,被廣泛地於攜帶型裝置上使用,例如數位相機、個人數位助理和多媒體播放器等。SD卡的技術是建基於MMC(MultiMedia)卡格式上。SD卡有比較高的資料傳送速度,而且不斷更新標準。

- SD 是一種 flash memory card 的標準,也就是一般常見的 SD 記憶卡,而 MMC 則是較早的一種記憶卡標準,目前已經被 SD 標準所取代.

.. image:: /sdio2.png

後來還出了SDHC(Secure Digital High Capacity),是由SD卡協會(SD Card Association)在2006年3月發表的Secure Digital高容量版本。SD卡協會有强制規定,所有符合SDHC規範的設備都必須標明“SDHC”的標誌.

SDHC與SD的主要差異在於,舊版本使用FAT16檔案系統,意思是管理檔案所在位置的表格用16位元表示,所以最多只能管理65536個範圍,再考慮每個範圍能儲存32KB的資料量,所以65536 × 32KB = 2GB,SD卡容量上限只能到達2GB。為解決FAT16格式可支援容量有限的問題,SDHC改用了FAT32格式;依規格定義,容量最大可達到32GB。

發佈SDHC的時候,制定了三種不同的級數(Class),分別是Class 2、Class 4及Class 6,表示該記憶卡穩定的最小存取速度。
後來,增加了Class 10及全新制定的UHS(Ultra High Speed)

.. image:: /class_speed.png

What is the SDIO?
-----------------

- SDIO 是目前我們比較關心的技術,SDIO 故名思義,就是 SD 的 I/O 介面(interface)的意思,不過這樣解釋可能還有點抽像。更具體的說明,SD 本來是記憶卡的標準,但是現在也可以把 SD 拿來插上一些週邊介面使用,這樣的技術便是 SDIO。

- 所以 SDIO 本身是一種相當單純的技術,透過 SD 的 I/O 接腳來連接外部週邊,並且透過 SD 上的 I/O 資料接位與這些週邊傳輸資料,而且 SD 協會會員也推出很完整的 SDIO stack 驅動程式,使得 SDIO 週邊(我們稱為 SDIO 卡)的開發與應用變得相當熱門。
- A SDIO (Secure Digital Input Output) card is an extension of the SD specification to cover I/O functions. 
- Host devices that support SDIO can use the SD slot to support: 
   1.  GPS receivers.
   2.  digital cameras. 
   3.  RFID readers. 
   4.  FM radio tuners.
   5.  TV tuners. 
   6.  Wi-Fi.
   7.  Bluetooth. 

 Many other SDIO devices have been proposed, but it is now more common for I/O devices to connect using the USB interface.
- SDIO cards support most of the memory commands of SD cards. SDIO cards can be structured as 8 logical cards, although currently, the typical way that an SDIO card uses this capability is to structure itself as one I/O card and one memory card.

.. image:: /sdio1.png
SDIO bus topology
=================

.. image:: /Selection_015.png
.. image:: /Selection_016.png
Note: The SDIO will not send any data as long as the Busy signal is asserted (SDIO_D0 pulled 
low).

.. image:: /Selection_017.png
.. image:: /Selection_018.png
.. image:: /Selection_019.png



SDIO functional description
============================
.. image:: /sdio_functional_description.png

圖說明:

  - SDIO_D0預設是用來當作資料傳輸 , 而在初始化時 , host端可以設定其資料寬度。
  - 當MMC連至bus時 , MMC可以支援只有1bit模式。
  - 當SD/SD I/O連至bus時,data transfer可以由host端來設定是SDIO_D0(1bit mode) 或者是 SDIO_D[3:0](4bit mode)
    而所有的data lines都是操作於push-pull mode.

SDIO_CMD has two operational modes:

  - Open-drain for initialization (only for MMCV3.31 or previous)

  - Push-pull for command transfer (SD/SD I/O card MMC4.2 use push-pull drivers also for 
    initialization)

SDIO_CK is the clock to the card:

  - 在clock cycle 中 , 1 bit是用來切換command 或是 data lines.
  - clock的頻率依照規格不同有所不同:
       * between 0 and 20 MHz (for a MultiMediaCard V3.31).
       * between 0 and 48 MHz for a MultiMediaCard V4.0/4.2).
       * between 0 and 25 MHz (for an SD/SD I/O card).

  - The SDIO uses two clock signals:
       * SDIO adapter clock(SDIOCLK = 48MHz is coming from a specific output of PLL (PLL48CLK) ).
       * APB2 bus clock(PCLK2).
      NOTE: PCLK2 與 SDIO_CLK 之clock頻率必須遵循以下條件:
            Frequency PCLK2 ≥ (3/8) * Frequency SDIO_CK  ?????????????????


The signals shown in Table 149 are used on the MultiMediaCard/SD/SD I/O card bus

.. image:: /SDIO_IO_definitions.png


SDIO adapter
==============
============
block diagram of an SDIO adapter.

.. image:: /sdio_adapter.png

上圖中包含了五個子單元:

- Adapter register block
- Control unit
- Command path
- Data path
- Data FIFO

由圖中可以看出 , adapter registers 和 FIFO都是採用APB2 bus clock domain (PCLK2),
而control unit , command path , data path 則是採用SDIO adapter clock domain(SDIOCLK).

Q&A :  WHY??????????????????????????????????????????????????????

上圖中之左側部份(Adapter registers and FIFO):
Adapter registers 主要包含了所有SDIO的暫存器 , 而這些暫存器是用來配置一些參數,以用來實現SD協定中的時序,最終目的是用來實現SD卡的命令傳輸。
而FIFO則是為了實現與data path的傳輸 , 而這兩個分別代表著對SD卡的兩種操作模式 , 一個是命令的傳輸 , 一個是資料的傳輸。


上圖中之右側
主要分為三個子單元 , Control Unit , Command Path and Data Path , Control Unit主要用來控制電源以及時鐘的控制 , 而這些控制是根據Adapter registers當中的暫存器來做配置 , 而Command Path連結SDIO_CMD , 他用來控制命令的傳輸 , 最後Data Path則是連結SDIO_D[7:0],控制資料的傳輸。
主要分為三個子單元,Control Unit, Command Path and Data Path。Control Unit 主要用來控制電源以及時鐘的控制,而這些控制是根據 Adapter registers 當中的暫存器來做配置,而 Command Path 連結SDIO_CMD,他用來控制命令的傳輸,最後 Data Path 則是連結 SDIO_D[7:0],控制資料的傳輸。底下將分單元描述各部零件。

Adapter register block
----------------------
The adapter register block contains all system registers. This block also generates the 
signals that clear the static flags in the multimedia card. The clear signals are generated  
when 1 is written into the corresponding bit location in the SDIO Clear register.

底下分單元描述
   - Adapter register block:
Control Unit
------------

      The adapter register block contains all system registers. This block also generates the 
      signals that clear the static flags in the multimedia card. The clear signals are generated  
      when 1 is written into the corresponding bit location in the SDIO Clear register.
這部份又在其內部分為兩個子單元,一個是 Power management,另一個是 Clock management,這兩個子單元都受 Adapter registers 控制。詳見下圖:

.. image:: /control_unit.png

- Control Unit:
**Power management**

      這部份又在其內部分為兩個子單元 , 一個是Power management , 另一個是Clock management , 其兩個子單元都受控制於Adapter registers.
There are three power phases:
- power-off
- power-up
- power-on

      詳見下圖(Figure 328)
*NOTE!! The power management subunit disables the card bus output signals during the power-off and power-up phases.*

.. image:: /control_unit.png
**Clock management**

      Power management:
用來產生和控制SDIO_CK , 而其SDIO_CK又可選擇兩種模式: 

         There are three power phases:
- clock Divide (SDIO_CK = SDIO_CLK/div .)  
- clock Bypass (SDIO_CK = SDIO_CLK).

         * power-off
而在底下的情況下 , Clock是不輸出訊號的

         * power-up
- after reset
- during the power-off or power-up phases
- if the power saving mode is enabled and the card bus is in the Idle state (eight clock periods after both the command and data path subunits enter the Idle phase).

         * power-on
Command Path
------------
Command path 用來傳遞外來命令與接收卡片回應,是 SDIO 中負責處理外部裝置 command 的單位。

           NOTE!! The power management subunit disables the card bus output signals during the 
           power-off and power-up phases.
.. image:: /sdio-command_path.png

**Command Path State Machine**

      Clock management:
         用來產生和控制SDIO_CK , 而其SDIO_CK又可選擇兩種模式: 
我們可以用 state machine 表示 command path 的各狀態間的關係與運作方式:

         * clock Divide (SDIO_CK = SDIO_CLK/div .)  
.. image:: /SDIO_CPSM.png

         * clock Bypass (SDIO_CK = SDIO_CLK).
當 command register 被寫入且 enable bit 被設為真值,command 的傳送即告開始。Command 被傳送後,CPSM 會進入 *Idle* 狀態且自動設定 status flags 的值。若該命令需要回應,則等待回應。當回應產生後,command path 會比較回傳的 CRC 與內部產生的 code,然後對應的 status flag 會自動被設定。

         而在底下的情況下 , Clock是不輸出訊號的
*NOTE: The command timeout has a fixed value of 64 SDIO_CK clock periods.*

         * after reset
If the interrupt bit is set in the command register, the timer is disabled and the CPSM waits for an interrupt request from one of the cards. If a pending bit is set in the command register, the CPSM enters the Pend state, and waits for a CmdPend signal from the data path subunit. When CmdPend is detected, the CPSM moves to the Send state. This enables the data counter to trigger the stop command transmission.

         * during the power-off or power-up phases
Data Path
---------

         * if the power saving mode is enabled and the card bus is in the Idle state (eight clock 
           periods after both the command and data path subunits enter the Idle phase).
Data path 負責資料的傳輸,底下是該單元的 block diagram:

.. image:: /SDIO-data_path.png

Data path 與 command path 相同,可以用 state machine 表示 data path 的各狀態間的關係與運作方式:

.. image:: /SDIO-DPSM.png

Data FIFO
---------

The data FIFO (first-in-first-out) subunit is a data buffer with a transmit and receive unit.

SDIO APB2 interface
-------------------
===================
ARM 的 APB2 介面由 data path,register decoder 與 interrupt/DMA logic 組成,除了會產生 interrupt 與 DMA 的 request,也會存取 SDIO adapter registers 與 data FIFO。

SDIO interrupt:

- 當任何一個透過 mask register 預先選擇的特定 flags 之 status flag 為 high 時,interrupt logic 將會產生一個 interrupt request。又若某個 mask       
  flag 被 set 的話,其對應的 status flag 也會產生 interrupt request。



Sample Code
============
- https://github.com/JackABK/STM32F4-FreeRTOS/tree/master  (Switch master branch)

.. code-block:: prettyprint

  SD_Error SD_Init(void)
  {
    __IO SD_Error errorstatus = SD_OK;

    /* SDIO Peripheral Low Level Init */
    SD_LowLevel_Init();


    //SDIO_DeInit();

    errorstatus = SD_PowerON();



    if (errorstatus != SD_OK)
    {
      /*!< CMD Response TimeOut (wait for CMDSENT flag) */
      return(errorstatus);
    }

    errorstatus = SD_InitializeCards();

    if (errorstatus != SD_OK)
    {
      /*!< CMD Response TimeOut (wait for CMDSENT flag) */
      return(errorstatus);
    }

    /*!< Configure the SDIO peripheral */
    /*!< SDIO_CK = SDIOCLK / (SDIO_TRANSFER_CLK_DIV + 2) */
    /*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */
    SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV;
    SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
    SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
    SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
    SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
    SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
    SDIO_Init(&SDIO_InitStructure);

    /*----------------- Read CSD/CID MSD registers ------------------*/
    errorstatus = SD_GetCardInfo(&SDCardInfo);

    if (errorstatus == SD_OK)
    {

      /* Select Card*/
      errorstatus = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));

    }

    if (errorstatus == SD_OK)
    {

      errorstatus = SD_EnableWideBusOperation(SDIO_BusWide_4b);

    }

    return(errorstatus);
  }


Demo
============





Reference
==========
- `Secure Digital wiki<http://en.wikipedia.org/wiki/Secure_Digital#SDIO>`_
- `SDIO接口介绍<http://en.wikipedia.org/wiki/Secure_Digital#SDIO>`_
-  `Linux(open source)的 SD/MMC/SDIO 支援現況概要<http://www.jollen.org/blog/2007/01/open_source_sd_mmc_sdio.html>`_
-  `SD/MMC/SDIO概念區分<http://bbs.ednchina.com/BLOG_ARTICLE_198217.HTM>`_
- `Linux(open source)的 SD/MMC/SDIO 支援現況概要<http://www.jollen.org/blog/2007/01/open_source_sd_mmc_sdio.html>`_
- `SD/MMC/SDIO概念區分<http://bbs.ednchina.com/BLOG_ARTICLE_198217.HTM>`_
- `STM32 控制 SD 卡<http://www.360doc.com/content/12/0411/15/9707346_202767012.shtml>`_
- `STM32 + SDIO + FATFS 文件系统 直讀 SD 卡<http://ntn314.blog.163.com/blog/static/16174358420112263456948/>`_ 
- `零死角玩轉 stm32 - 高級篇之 SDIO(4bit + DMA、支持SDHC、帶協議分析)<http://www.eeboard.com/tutorials/%E9%9B%B6%E6%AD%BB%E8%A7%92%E7%8E%A9%E8%BD%ACstm32-%E9%AB%98%E7%BA%A7%E7%AF%87%E4%B9%8Bsdio%EF%BC%884bit-dma%E3%80%81%E6%94%AF%E6%8C%81sdhc%E3%80%81%E5%B8%A6%E5%8D%8F%E8%AE%AE%E5%88%86%E6%9E%90/>`_