/*
**********************************************************************
* 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 accessing MMC/SD
via port banging.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "fs_api.h"
#include "fs_conf.h"
#include "fs_port.h"
#include "44b.h"
#if FS_USE_MMC_DRIVER
/* CMD0: response R1 */
#define CMD_GO_IDLE_STATE 0x00
/* CMD1: response R1 */
#define CMD_SEND_OP_COND 0x01
/* CMD8: response R7 */
#define CMD_SEND_IF_COND 0x08
/* CMD9: response R1 */
#define CMD_SEND_CSD 0x09
/* CMD10: response R1 */
#define CMD_SEND_CID 0x0a
/* CMD12: response R1 */
#define CMD_STOP_TRANSMISSION 0x0c
/* CMD13: response R2 */
#define CMD_SEND_STATUS 0x0d
/* CMD16: arg0[31:0]: block length, response R1 */
#define CMD_SET_BLOCKLEN 0x10
/* CMD17: arg0[31:0]: data address, response R1 */
#define CMD_READ_SINGLE_BLOCK 0x11
/* CMD18: arg0[31:0]: data address, response R1 */
#define CMD_READ_MULTIPLE_BLOCK 0x12
/* CMD24: arg0[31:0]: data address, response R1 */
#define CMD_WRITE_SINGLE_BLOCK 0x18
/* CMD25: arg0[31:0]: data address, response R1 */
#define CMD_WRITE_MULTIPLE_BLOCK 0x19
/* CMD27: response R1 */
#define CMD_PROGRAM_CSD 0x1b
/* CMD28: arg0[31:0]: data address, response R1b */
#define CMD_SET_WRITE_PROT 0x1c
/* CMD29: arg0[31:0]: data address, response R1b */
#define CMD_CLR_WRITE_PROT 0x1d
/* CMD30: arg0[31:0]: write protect data address, response R1 */
#define CMD_SEND_WRITE_PROT 0x1e
/* CMD32: arg0[31:0]: data address, response R1 */
#define CMD_TAG_SECTOR_START 0x20
/* CMD33: arg0[31:0]: data address, response R1 */
#define CMD_TAG_SECTOR_END 0x21
/* CMD34: arg0[31:0]: data address, response R1 */
#define CMD_UNTAG_SECTOR 0x22
/* CMD35: arg0[31:0]: data address, response R1 */
#define CMD_TAG_ERASE_GROUP_START 0x23
/* CMD36: arg0[31:0]: data address, response R1 */
#define CMD_TAG_ERASE_GROUP_END 0x24
/* CMD37: arg0[31:0]: data address, response R1 */
#define CMD_UNTAG_ERASE_GROUP 0x25
/* CMD38: arg0[31:0]: stuff bits, response R1b */
#define CMD_ERASE 0x26
/* ACMD41: arg0[31:0]: OCR contents, response R1 */
#define CMD_SD_SEND_OP_COND 0x29
/* CMD42: arg0[31:0]: stuff bits, response R1b */
#define CMD_LOCK_UNLOCK 0x2a
/* CMD55: arg0[31:0]: stuff bits, response R1 */
#define CMD_APP 0x37
/* CMD58: arg0[31:0]: stuff bits, response R3 */
#define CMD_READ_OCR 0x3a
/* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */
#define CMD_CRC_ON_OFF 0x3b
/* command responses */
/* R1: size 1 byte */
#define R1_IDLE_STATE 0
#define R1_ERASE_RESET 1
#define R1_ILL_COMMAND 2
#define R1_COM_CRC_ERR 3
#define R1_ERASE_SEQ_ERR 4
#define R1_ADDR_ERR 5
#define R1_PARAM_ERR 6
/* R1b: equals R1, additional busy bytes */
/* R2: size 2 bytes */
#define R2_CARD_LOCKED 0
#define R2_WP_ERASE_SKIP 1
#define R2_ERR 2
#define R2_CARD_ERR 3
#define R2_CARD_ECC_FAIL 4
#define R2_WP_VIOLATION 5
#define R2_INVAL_ERASE 6
#define R2_OUT_OF_RANGE 7
#define R2_CSD_OVERWRITE 7
#define R2_IDLE_STATE (R1_IDLE_STATE + 8)
#define R2_ERASE_RESET (R1_ERASE_RESET + 8)
#define R2_ILL_COMMAND (R1_ILL_COMMAND + 8)
#define R2_COM_CRC_ERR (R1_COM_CRC_ERR + 8)
#define R2_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 8)
#define R2_ADDR_ERR (R1_ADDR_ERR + 8)
#define R2_PARAM_ERR (R1_PARAM_ERR + 8)
/* R3: size 5 bytes */
#define R3_OCR_MASK (0xffffffffUL)
#define R3_IDLE_STATE (R1_IDLE_STATE + 32)
#define R3_ERASE_RESET (R1_ERASE_RESET + 32)
#define R3_ILL_COMMAND (R1_ILL_COMMAND + 32)
#define R3_COM_CRC_ERR (R1_COM_CRC_ERR + 32)
#define R3_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 32)
#define R3_ADDR_ERR (R1_ADDR_ERR + 32)
#define R3_PARAM_ERR (R1_PARAM_ERR + 32)
/* Data Response: size 1 byte */
#define DR_STATUS_MASK 0x0e
#define DR_STATUS_ACCEPTED 0x05
#define DR_STATUS_CRC_ERR 0x0a
#define DR_STATUS_WRITE_ERR 0x0c
/* status bits for card types */
#define SD_RAW_SPEC_1 0
#define SD_RAW_SPEC_2 1
#define SD_RAW_SPEC_SDHC 2
/* card type state */
static FS_u8 sd_raw_card_type;
/*********************************************************************
*
* #define Macros
*
**********************************************************************
*/
/*********************************************************************
*
* Configurable macros
*
* Please setup these macros according your hardware
*
*/
#define SPI_CS_PORT rPDATD
#define SPI_CLK_PORT rPDATD
#define SPI_DATAOUT_PORT rPDATD
#define SPI_DATAIN_PORT rPDATD
#define SPI_CS_PIN 0
#define SPI_CLK_PIN 2
#define SPI_DATAOUT_PIN 1
#define SPI_DATAIN_PIN 3
/*********************************************************************
*
* #define Macros
*
*/
#define SPI_CLR_CS() SPI_CS_PORT &= ~(1 << SPI_CS_PIN)
#define SPI_SET_CS() SPI_CS_PORT |= (1 << SPI_CS_PIN)
#define SPI_CLR_CLK() SPI_CLK_PORT &= ~(1 << SPI_CLK_PIN)
#define SPI_SET_CLK() SPI_CLK_PORT |= (1 << SPI_CLK_PIN)
#define SPI_CLR_DATAOUT() SPI_DATAOUT_PORT &= ~(1 << SPI_DATAOUT_PIN)
#define SPI_SET_DATAOUT() SPI_DATAOUT_PORT |= (1 << SPI_DATAOUT_PIN)
#define SPI_DATAIN() (SPI_DATAIN_PORT & (1 << SPI_DATAIN_PIN))
#define SPI_SETUP_PINS()
#define MMC_DEFAULTSUPPLYVOLTAGE 3300 /* in mV, example means 3.3V */
#define MMC_MAXFREQUENCY 400 /* 400 KHz */
static SPI_Delay_Count=100;
void SPI_DELAY(void) {int i=SPI_Delay_Count; while(i-- != 0);}
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
static volatile int _MaxFreq;
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
static void _Init(void) {
_MaxFreq = MMC_MAXFREQUENCY;
SPI_SETUP_PINS();
}
/*********************************************************************
*
* FS_MMC_HW_X_BusyLedOff
*
* Description:
* FS low level function. Switches the busy LED off.
*
* Parameters:
* Unit - Device Index
*
* Return value:
* void
*/
void FS_MMC_HW_X_BusyLedOff (FS_u8 Unit) {
}
/*********************************************************************
*
* FS_MMC_HW_X_BusyLedOn
*
* Description:
* FS low level function. Switches the busy LED off.
*
* Parameters:
* Unit - Device Index
*
* Return value:
* void
*/
void FS_MMC_HW_X_BusyLedOn(FS_u8 Unit) {
}
/*********************************************************************
*
* FS_MMC_HW_X_EnableCS
*
* Description:
* FS low level function. Sets the card slot active using the
* chip select (CS) line.
*
* Parameters:
* Unit - Device Index
*
* Return value:
* void
*/
void FS_MMC_HW_X_EnableCS (FS_u8 Unit) {
SPI_CLR_CS();
}
/*********************************************************************
*
* FS_