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

📄 mmc.c

📁 S64和VS1003的MP3播放实现的源代码/
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------------------------------------*/
/* MMC/SDC (in SPI mode) control module  (C)ChaN, 2006                   */
/*-----------------------------------------------------------------------*/
/* Only rcvr_spi(), xmit_spi(), disk_timerproc(), disk_initialize () and */
/* some macros are platform dependent.                                   */
/*-----------------------------------------------------------------------*/


#include "AT91SAM7S64.h"
#include "lib_AT91SAM7S64.h"
#include "SAMspi.h"

#include "diskio.h"

#define SPI_CSR_SD  1
#define SD_NPCS     PCS_1
#define SD_CS_PIN   AT91C_PA31_NPCS1

/* SPI CLK = (MCK / SPI_DIV) */
#define SPI_DIV     6
//#define USE_DMA

/* MMC/SD command (in SPI) */
#define CMD0	(0x40+0)	/* GO_IDLE_STATE */
#define CMD1	(0x40+1)	/* SEND_OP_COND */
#define CMD9	(0x40+9)	/* SEND_CSD */
#define CMD10	(0x40+10)	/* SEND_CID */
#define CMD12	(0x40+12)	/* STOP_TRANSMISSION */
#define CMD16	(0x40+16)	/* SET_BLOCKLEN */
#define CMD17	(0x40+17)	/* READ_SINGLE_BLOCK */
#define CMD18	(0x40+18)	/* READ_MULTIPLE_BLOCK */
#define CMD24	(0x40+24)	/* WRITE_BLOCK */
#define CMD25	(0x40+25)	/* WRITE_MULTIPLE_BLOCK */
#define CMD41	(0x40+41)	/* SEND_OP_COND (ACMD) */
#define CMD55	(0x40+55)	/* APP_CMD */
#define CMD58	(0x40+58)	/* READ_OCR */

static volatile DSTATUS Stat = STA_NOINIT;	/* Disk status */
static volatile BYTE Timer = 0;			/* 100Hz decrement timer */

/*-----------------------------------------------------------------------*/
/* Module Private Functions                                              */
/*-----------------------------------------------------------------------*/

/*-------------------------------------*/
/* HW Interface  config                */
/*-------------------------------------*/

/*------------------*/
/* SET SPI Baudrate */
static void if_spiSetSpeed(unsigned char speed)
{
    SAMspiSetSCBR(SPI_CSR_SD, speed);
}

/*------------------*/
/* Init AT91SAM SPI */
static void init_spi(void)
{
    //SAMspiInit();
    //SAMspiCfgCH(SPI_CSR_SD, (AT91C_SPI_NCPHA | AT91C_SPI_BITS_8));
}

/*-------------------------------------*/
/* Power & CS control                  */
/*-------------------------------------*/

/*--------------------- */
/* MMC disable : CS = 1 */
void DESELECT(void)
{
    //AT91C_BASE_SPI->SPI_MR |= ((0x0F << 16) & AT91C_SPI_PCS ); // disable all PCS
	AT91C_BASE_PIOA->PIO_PER  = SD_CS_PIN; // enable PIO of CS-pin
	AT91C_BASE_PIOA->PIO_SODR = SD_CS_PIN; // set
	AT91C_BASE_PIOA->PIO_OER  = SD_CS_PIN; // output
}

/*---------------------*/
/* MMC enable : CS = 0 */
void SELECT(void)
{
    //AT91C_BASE_SPI->SPI_MR &= ~(AT91C_SPI_PCS ); // CLEAR PCS
    //AT91C_BASE_SPI->SPI_MR |= ((SD_NPCS << 16) & AT91C_SPI_PCS ); // set PCS
	AT91C_BASE_PIOA->PIO_PER  = SD_CS_PIN; // enable PIO of CS-pin
	AT91C_BASE_PIOA->PIO_CODR = SD_CS_PIN; // set
	AT91C_BASE_PIOA->PIO_OER  = SD_CS_PIN; // output
}

/*--------------*/
/* MMC Power ON */
static void power_on(void)
{

}

/*---------------*/
/* MMC Power OFF */
static void power_off(void)
{

}

/*-------------------------------------*/
/* MMC  Operation                      */
/*-------------------------------------*/

/*--------------------------------*/
/* Transmit a byte to MMC via SPI */

static BYTE xmit_spi(BYTE dat)
{
    BYTE rcv = 0;
#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	
	while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
	pSPI->SPI_TDR = dat;

	while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
	rcv = (BYTE)( pSPI->SPI_RDR ); // it's important to read RDR here!
#else
    rcv = SAMspiSend(SD_NPCS, dat);
#endif
    return (BYTE)rcv;
}

/*---------------------------------*/
/* Receive a byte from MMC via SPI */
static BYTE rcvr_spi(void)
{
	BYTE rcv = 0;
#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	
	while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
	pSPI->SPI_TDR = 0xFF;

	while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
	rcv = (BYTE)( pSPI->SPI_RDR );

	//iprintf("r: %x\n", dat);
#else
    rcv = SAMspiSend(SD_NPCS, 0xff);
#endif
	return (BYTE)rcv;
}

/*---------------------------------*/
/* Receive a byte from MMC via SPI */
static void rcvr_spi_m(BYTE *dest)
{
	BYTE dat = 0;
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	
	while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
	pSPI->SPI_TDR = 0xFF;

	while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
	dat = (BYTE)( pSPI->SPI_RDR );

	*dest = dat;
}

/*---------------------*/
/* Wait for card ready */

static BYTE wait_ready ()
{
	BYTE res = 0;

	Timer = 50;			/* Wait for ready in timeout of 500ms */
	rcvr_spi();

	do
    {
		res = rcvr_spi();
    } while ((res != 0xFF) && Timer);

	return res;
}



/*--------------------------------*/
/* Receive a data packet from MMC */
static BOOL rcvr_datablock (
	BYTE *buff,			/* Data buffer to store received data */
	BYTE wc				/* Word count (0 means 256 words) */
)
{
	BYTE token;

#ifdef USE_DMA
	/* TODO: deuglyfy */
	static const BYTE dummy_ff_block[512] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
#endif

	Timer = 10;
	do 
    {							/* Wait for data packet in timeout of 100ms */
		token = rcvr_spi();
	} while ((token == 0xFF) && Timer);

	//iprintf("token: %x\n", token);
	if (token != 0xFE) return FALSE;	/* If not valid data token, retutn with error */

#ifdef USE_DMA
	// enable DMA transfer
	*AT91C_SPI_RPR = (unsigned long)buff;
	*AT91C_SPI_RCR = 2 * (wc == 0 ? 256 : wc);
	*AT91C_SPI_TPR = (unsigned long)dummy_ff_block;
	*AT91C_SPI_TCR = 2 * (wc == 0 ? 256 : wc);
	*AT91C_SPI_PTCR = AT91C_PDC_RXTEN;
	*AT91C_SPI_PTCR = AT91C_PDC_TXTEN;
	/*while(i++ < 512)
	*AT91C_SPI_TDR = 0xFF; // start transfer*/
	
	while(! (*AT91C_SPI_SR & AT91C_SPI_ENDRX));	
	*AT91C_SPI_PTCR = AT91C_PDC_RXTDIS;
	*AT91C_SPI_PTCR = AT91C_PDC_TXTDIS;
#else
	do 
    {							/* Receive the data block into buffer */
		rcvr_spi_m(buff++);
		rcvr_spi_m(buff++);
	} while (--wc);
#endif
	
	rcvr_spi();						/* Discard CRC */
	rcvr_spi();

	//puts("rcvr_datablock success");
	return TRUE;					/* Return with success */
}

/*---------------------------*/
/* Send a data packet to MMC */
#if _READONLY == 0
static BOOL xmit_datablock (
	const BYTE *buff,	/* 512 byte data block to be transmitted */
	BYTE token			/* Data/Stop token */
)
{
#ifdef USE_DMA
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
#else
    BYTE wc = 0;
#endif
	BYTE resp = 0;

	if (wait_ready() != 0xFF) return FALSE;

	xmit_spi(token);		/* Xmit data token */

	if (token != 0xFD) 
    {	/* Is data token */
		
#ifdef USE_DMA
		// enable DMA transfer
		*AT91C_SPI_TPR = (unsigned int)buff;
		*AT91C_SPI_TCR = 512;
		*AT91C_SPI_PTCR = AT91C_PDC_TXTEN;

		while(! (*AT91C_SPI_SR & AT91C_SPI_ENDTX));	
		*AT91C_SPI_PTCR = AT91C_PDC_TXTDIS;
		(BYTE)( pSPI->SPI_RDR ); // it's important to read RDR here!
#else
		do 
        {							/* Xmit the 512 byte data block to MMC */
			xmit_spi(*buff++);

⌨️ 快捷键说明

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