⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_x_hw_imx21ads.c

📁 ucosII在DRAGONBALL MX21上的移植 开发环境为IAR
💻 C
字号:
/*
**********************************************************************
*                          Micrium, Inc.
*                      949 Crestview Circle
*                     Weston,  FL 33327-1848
*
*                            uC/FS
*
*             (c) Copyright 2001 - 2003, Micrium, Inc.
*                      All rights reserved.
*
***********************************************************************

----------------------------------------------------------------------
File        : mmc_x_hw.c
Purpose     : Sample MMC hardware layer for i.MX21ADS
Author      : ES
---------------------------END-OF-HEADER------------------------------
*/

/*********************************************************************
*
*             #include Section
*
**********************************************************************
*/

#include "fs_api.h"
#include "fs_conf.h"

#if FS_USE_MMC_DRIVER

#include "mmc.h"
#include "mmc_x_hw.h"
#include <includes.h>

/*********************************************************************
*
*             #define constants
*
**********************************************************************
*/

#define  MMC_INIT_FREQUENCY             400        /* MMC/SD frequency = 400 KHZ on startup  */

#define  FS__MMC_DEFAULTSUPPLYVOLTAGE  3300        /* MMC/SD Operating voltage in millivolts */

/*********************************************************************
*
*             Constant Checking
*
**********************************************************************
*/

#if ((FS_USE_MMC_DRIVER == 1) && (OSView_Uses_Own_Timer != 1))
#error "The MMC/SD hardware driver shares a general purpose timer with uC/OS-View" \n
        Set BSP_TickMode to 0 and OSView_Uses_Own_Timer to 1 in bsp.h"
#endif

/*********************************************************************
*
*             #define Macros
*
* Notes : The Following macros are used when bit-banging the MMC/SD
*       : card IO lines via software. When HW_USE_SPI is defined as 0
**********************************************************************
*/

#define  SPI_SET_CLK()      PTE_DR  |=  (1 << 23)  /* Raise SCLK                             */
#define  SPI_CLR_CLK()      PTE_DR  &= ~(1 << 23)  /* Lower SCLK                             */
#define  SPI_SET_DATAOUT()  PTE_DR  |=  (1 << 22)  /* Raise MISO                             */
#define  SPI_CLR_DATAOUT()  PTE_DR  &= ~(1 << 22)  /* Lower MISO                             */
#define  SPI_SET_CS()       PTE_DR  |=  (1 << 21)  /* Raise CardSelect                       */
#define  SPI_CLR_CS()       PTE_DR  &= ~(1 << 21)  /* Lower CardSelect                       */

#define  SPI_DATAIN()      (PTE_SSR &   (1 << 18)) /* 0 if input bit is clr else > 0 if set  */

/*********************************************************************
*
*             Local Globals
*
**********************************************************************
*/

static  FS_U32  SPI_DlyNbrCnts;

/*********************************************************************
*
*             Local functions
*
**********************************************************************
*/

static void SPI_DELAY(void);

/*********************************************************************
*
*             _Init
*
*  Description:
*    FS low level Generap Purpose IO Port Init for SPI software emulation
*
*  Parameters:
*    void
*
*  Return value:
*    void
*/

void _Init(void) {
                                                   /* Use GPIO and bit bang                  */
    PCCR0         |=  GPIO_EN;                     /* Enable GPIO module clock               */
    PTE_GIUS      |=  0x00FC0000;                  /* Port E pins / CSPI3 not GPIO           */
    PTE_DDIR      |=  0x00E00000;                  /* [23:21] = output, 19 = input           */
    PTE_ICONFA2   &= ~0x000000C0;                  /* Pin 19, GPIO_In -> A_Out               */
    PTE_0CR2      |=  0x0000FC00;                  /* Data Reg. -> Pins [23:21]              */
}

/*********************************************************************
*
*             FS_MMC_HW_X_BusyLedOff
*
*  Description:
*    FS low level function. Switches the busy LED off.
*
*  Parameters:
*    Unit      - Unit number
*
*  Return value:
*    void
*/

void FS_MMC_HW_X_BusyLedOff (FS_U8 Unit) {
    LED_Off(2);
}

/*********************************************************************
*
*             FS_MMC_HW_X_BusyLedOn
*
*  Description:
*    FS low level function. Switches the busy LED off.
*
*  Parameters:
*    Unit      - Unit number
*
*  Return value:
*    void
*/

void FS_MMC_HW_X_BusyLedOn  (FS_U8 Unit) {
    LED_On(2);
}

/*********************************************************************
*
*       FS_MMC_HW_X_EnableCS
*
*  Description:
*    FS low level function. Sets the card slot active using the
*    chip select (CS) line.
*
*  Parameters:
*    Unit      - Unit number
*
*  Return value:
*    void
*/

void FS_MMC_HW_X_EnableCS   (FS_U8 Unit) {
    SPI_CLR_CS();
}

/*********************************************************************
*
*       FS_MMC_HW_X_EnableCS
*
*  Description:
*    FS low level function. Sets the card slot inactive using the
*    chip select (CS) line.
*
*  Parameters:
*    Unit      - Unit number
*
*  Return value:
*    void
*/

void FS_MMC_HW_X_DisableCS(FS_U8 Unit) {
    SPI_SET_CS();
}

/*********************************************************************
*
*       FS_MMC_HW_X_IsWriteProtected
*
*  Description:
*    FS low level function. Returns the state of the physical write
*    protection of the SD cards.
*
*  Parameters:
*    Unit      - Unit number
*
*  Return value:
*    1                - the card is write protected
*    ==0              - the card is not write protected
*/

FS_U8 FS_MMC_HW_X_IsWriteProtected(FS_U8 Unit) {
  /* If the card slot has no write switch detector, return 0 */
  return 0;
}

/*********************************************************************
*
*       FS_MMC_HW_X_SetMaxSpeed
*
*  Description:
*    FS low level function. Sets the SPI interface to one of three
*    possible frequencies. Either the MMC/SD recommended startup
*    frequency, which is 400 KHZ, or the specified MaxFrequency
*    which is read from the MMC/SD card's CSD, or lastly, the
*    maximum possible speed based on the minimum delay that can
*    be created with the general purpose timer (GPT). If the
*    specified frequency, MaxFreq, is too fast and can not be
*    set as a result of the GPT not being fast enough, then the
*    actual frequency based on the speed of the GPT under its fastest
*    operation is returned.
*
*  Note: This function is called twice during startup. Once to
*        initialize the port with a frequency of 400 KHZ and
*        read the cards CSD information, then a second time
*        with the MaxFreq = to the maximum medium frequency
*        read from the cards CSD.
*
*  Parameters:
*    Unit       - Unit number
*    MaxFreq    - SPI clock frequency in kHz
*
*  Return value:
*    max. frequency    - the maximum frequency set in kHz
*    ==0               - the frequency could not be set
*/

FS_U16 FS_MMC_HW_X_SetMaxSpeed(FS_U8 Unit, FS_U16 MaxFreq) {

  FS_U16 actual_freq;


  if (MaxFreq == MMC_INIT_FREQUENCY) {             /* If we are setting the initialization frequency                        */
      _Init();                                     /* Initialize the IO pins for bit banging the SPI                        */
      return MMC_INIT_FREQUENCY;                   /* Return the Init frequency, 400 KHZ.                                   */
  } else {                                         /* Attempt to set a frequency other than the initialization frequency    */
      SPI_DlyNbrCnts  = ((GPT2CLK / (MaxFreq * 1000)) / 2); /* Calculate the number of SPI_DELAY() counts necessary         */
      if (SPI_DlyNbrCnts == 0) {                            /* If the delay counts is zero, then the delay is faster        */
          actual_freq = ((MCLK / PERDIV1) / 1000);          /*  then the timer can run. So return the maximum frequency     */
          return actual_freq;                               /*  possible bassed on the speed of the GTP input clock         */
      } else {
          return MaxFreq;                          /* If the specified MaxFrequency can be set, then return that value      */
      }
  }
}

/*********************************************************************
*
*             FS_MMC_HW_X_SetVoltage
*
*  Description:
*    FS low level function. Be sure that your card slot si within the given
*    voltage range. Return 1 if your slot can support the required voltage,
*    and if not, return 0;
*
*  Parameters:
*    Unit      - Unit number
*    MaxFreq          - SPI clock frequency in kHz
*
*  Return value:
*    1                - the card slot supports the voltage range
*    ==0              - the card slot does not support the voltage range
*/

FS_U8 FS_MMC_HW_X_SetVoltage(FS_U8 Unit, FS_U16 Vmin, FS_U16 Vmax) {
    FS_U8 r;


                                                   /* voltage range check                    */
    if ((Vmin <= FS__MMC_DEFAULTSUPPLYVOLTAGE) && (Vmax >= FS__MMC_DEFAULTSUPPLYVOLTAGE)) {
        r = 1;
    } else {
        r = 0;
    }

    return r;
}

/*********************************************************************
*
*       FS_MMC_HW_X_IsPresent
*
*  Description:
*    Returns the state of the media. If you do not know the state, return
*    FS_MEDIA_STATEUNKNOWN and the higher layer will try to figure out if
*    a media is present.
*
*  Parameters:
*    Unit                 - Unit number
*
*  Return value:
*    FS_MEDIA_STATEUNKNOWN       - the state of the media is unkown
*    FS_MEDIA_ISNOTPRESENT       - no card is present
*    FS_MEDIA_ISPRESENT          - a card is present
*/

FS_U8 FS_MMC_HW_X_IsPresent(FS_U8 Unit) {
    return FS_MEDIA_STATEUNKNOWN;
}

/*********************************************************************
*
*       FS_MMC_HW_X_Read
*
*  Description:
*    FS low level function. Reads a specified number of bytes from MMC
*    card to buffer.
*
*  Parameters:
*    Unit        - Unit number
*    pData       - Pointer to a data buffer
*    NumBytes    - Number of bytes
*
*  Return value:
*    void
*/

void FS_MMC_HW_X_Read (FS_U8 Unit, FS_U8 * pData, int NumBytes) {
    FS_U8 c;
    FS_U8 bpos;


    do {
        c = 0;
        bpos = 8;                                  /* get 8 bits                             */
        do { SPI_CLR_CLK();
            c <<= 1;
            if (SPI_DATAIN() > 0) {
                c |= 1;
            }
            SPI_SET_CLK();
        } while (--bpos);
        *pData++ = c;
    } while (--NumBytes);
}

/*********************************************************************
*
*       FS_MMC_HW_X_Write
*
*  Description:
*    FS low level function. Writes a specified number of bytes from
*    data buffer to the MMC/SD card.
*
*  Parameters:
*    Unit        - Unit number
*    pData       - Pointer to a data buffer
*    NumBytes    - Number of bytes
*
*  Return value:
*    void
*/

void FS_MMC_HW_X_Write(FS_U8 Unit, const unsigned char * pData, int NumBytes) {
    int i;
    FS_U8  mask;
    FS_U8  data;


    for (i = 0; i < NumBytes; i++) {
        data = pData[i];
        mask = 0x80;
        while (mask > 0) {
            if ((data & mask) > 0) {
                SPI_SET_DATAOUT();
            } else {
                SPI_CLR_DATAOUT();
            }
            SPI_CLR_CLK();
            SPI_DELAY();
            SPI_SET_CLK();
            SPI_DELAY();
            mask >>= 1;
        }
    }

    SPI_SET_DATAOUT(); /* default state of data line is high */
}

/*********************************************************************
*
*       SPI_DELAY
*
*  Description:
*    FS low level function which regulates the rate of the MMCCLK
*    pin toggle for software emulation, aka bit banging of the
*    MMC/SD card slot.
*
*  Parameters:
*    void
*
*  Return value:
*    void
*
*  Notes : 1) Shares a generap purpose timer with uC/OS-View!
*/

static void SPI_DELAY(void) {
    FS_U32 tmr_start_val;

    tmr_start_val = GPT2_TCN1;
    while ((GPT2_TCN1 - tmr_start_val) < SPI_DlyNbrCnts) {
        ;
    }
}

#endif /* FS_USE_MMC_DRIVER */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -