Exemplo n.º 1
0
uint8_t mmc_init(void)
{
    unsigned int i,retval;
	digitalWrite(SDSS,HIGH)	;
    for(i=0;i<10;i++)           // send 80 clocks while card power stabilizes
        (void)spixfer(0xff);

    mmc_send_command(0,0,0);    // send CMD0 - reset card
  	retval=mmc_get();

    if (retval != 1)         // if no valid response code
    {
		printf("\nmmc init cmd 0 failed with code %d (should have been 1)\n");
       	mmc_clock_and_release();
       	return 1;                // card cannot be detected
    }

    //
    // send CMD1 until we get a 0 back, indicating card is done initializing
    //
    i = 0xff;                     // max timeout
    while ((spixfer(0xff) != 0) && (--i))  // wait for it
    {
         mmc_send_command(1,0,0);   // send CMD1 - activate card init
    }

    mmc_clock_and_release();        // clean up

    if (i == 0){                     // if we timed out above
    	printf("\nmmc cmd 1 failed\n");
       	return 2;                    // return failure code
	}

    return 0;
}
Exemplo n.º 2
0
Arquivo: mmc.c Projeto: freecores/igor
/** Init MMC/SD card.
	Initialize I/O ports for the MMC/SD interface and 
	send init commands to the MMC/SD card
	\return 0 on success, other values on error 
*/
uint8_t mmc_init(void)
{
//Run configure_spi() to setup the SPI port before initializing MMC.
	
	int i;

	for(i=0;i<10;i++)	// send 8 clocks while card power stabilizes
		spi_byte(0xff);

	mmc_send_command(0,0,0);	// send CMD0 - reset card

	if (mmc_get() != 1)			// if no valid response code
	{
		mmc_clock_and_release();
		return 1;  			// card cannot be detected
	}

	//
	// send CMD1 until we get a 0 back, indicating card is done initializing 
	//
	i = 0xffff;				// max timeout
	while ((spi_byte(0xff) != 0) && (--i))	// wait for it
	{
		mmc_send_command(1,0,0);	// send CMD1 - activate card init
	}

	mmc_clock_and_release();		// clean up

	if (i == 0)				// if we timed out above
		return 2;			// return failure code

	return 0;
}
Exemplo n.º 3
0
void mmc_playerStop(){
	if(mmc_player_status==MMC_PLAYER_STARTED){
		mmc_send_command(12,0,0); //stop transfers
		mmc_clock_and_release();
	}	
	mmc_player_status = MMC_PLAYER_STOPPED;
}
Exemplo n.º 4
0
static int mmc_get_card_status(uint32_t* result)
{
    return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_STATUS)
                          | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
                          | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                            MMC_CMD_SEND_STATUS_RCA(CEATA_MMC_RCA), result, CEATA_COMMAND_TIMEOUT);
}
Exemplo n.º 5
0
static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size)
{
    uint32_t i;
    if (size > 0x10) RET_ERR(0);
    mmc_discard_irq();
    SDCI_DMASIZE = size;
    SDCI_DMACOUNT = 0;
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
                           | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR
                           | SDCI_CMD_RES_BUSY | SDCI_CMD_RES_TYPE_R1
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_WRITE
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
                             NULL, CEATA_COMMAND_TIMEOUT), 3, 1);
    SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
    for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i];
    long startusec = USEC_TIMER;
    if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
        == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
    while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE)
    {
        if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3);
        yield();
    }
    PASS_RC(mmc_dsta_check_data_success(), 3, 4);
    return 0;
}
Exemplo n.º 6
0
/* write a single 512 byte sector to the SD card */
unsigned int mmc_writesector(uint32_t lba, uint8_t *buffer)
{
	uint16_t i;
	uint8_t r;
	
	CS_ASSERT;

	// send command and sector
	mmc_send_command(WRITE_SINGLE_BLOCK, lba<<9);
	
	mmc_datatoken();	// get response

	spi_byte(0xfe);	// send start block token

	for (i=0;i<512;i++)	// write sector data
    	spi_byte(*buffer++);

	spi_byte(0xff);	// ignore checksum
	spi_byte(0xff);	// ignore checksum

	r = spi_byte(0xff);
    
	// check for error
	if ((r & 0x1f) != 0x05) return r;
    
	// wait for SD card to complete writing and become idle
	i = 0xffff;
	while (!spi_byte(0xff) && --i) ;	// wait for card to finish writing
    
	mmc_release();	// cleanup

	if (!i) return -1;	// timeout error

	return 0;
}
Exemplo n.º 7
0
static int mmc_fastio_read(uint32_t addr, uint32_t* data)
{
    return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_FAST_IO)
                          | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R4
                          | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                            MMC_CMD_FAST_IO_RCA(CEATA_MMC_RCA) | MMC_CMD_FAST_IO_DIRECTION_READ
                          | MMC_CMD_FAST_IO_ADDRESS(addr), data, CEATA_COMMAND_TIMEOUT);
}
Exemplo n.º 8
0
/* Initialize a mmc/sd card */
uint8_t mmc_init(void)
{
	int i;

	// setup I/O ports 
	PORTB &= ~((1 << MMC_SCK) | (1 << MMC_MOSI));
	PORTB |= (1 << MMC_MISO);
	DDRB  |= (1<<MMC_SCK) | (1<<MMC_MOSI);


	PORTB |= (1 << MMC_CS);	
	DDRB  |= (1 << MMC_CS);

	SPCR = (1<<MSTR)|(1<<SPE)|2;	// enable SPI interface
	SPSR = 0;			// set/disable double speed

	for(i=0;i<10;i++)			// send 80 clocks
		spi_byte(0xff);

	mmc_send_command(GO_IDLE_STATE,0);	// reset card

	if (mmc_get() != 1)			// error if bad/no response code
	{
	   mmc_release();
	   return 1;
	}

	// wait for initialization to finish (gets a 0 back)
	i = 0xffff;
	while ((spi_byte(0xff) != 0) && (--i))
	{
	     mmc_send_command(SEND_OP_COND,0);	// init card
	}
	
	if (!i)	return 2; // timed out above
	
	mmc_send_command(SET_BLOCK_LEN, 512);	//set block size to 512
	
	mmc_release();
	
	// increase SPI clock to (Fosc/2)
	SPCR &= ~3;
	SPSR = 1;

	return 0;
}
Exemplo n.º 9
0
static int mmc_fastio_write(uint32_t addr, uint32_t data)
{
    return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_FAST_IO)
                          | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R4
                          | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                            MMC_CMD_FAST_IO_RCA(CEATA_MMC_RCA) | MMC_CMD_FAST_IO_DIRECTION_WRITE
                          | MMC_CMD_FAST_IO_ADDRESS(addr) | MMC_CMD_FAST_IO_DATA(data),
                            NULL, CEATA_COMMAND_TIMEOUT);
}
Exemplo n.º 10
0
static int mmc_init(void)
{
    sleep(HZ / 10);
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_GO_IDLE_STATE)
                           | SDCI_CMD_CMD_TYPE_BC | SDCI_CMD_RES_TYPE_NONE
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NID,
                             0, NULL, CEATA_COMMAND_TIMEOUT), 3, 0);
    long startusec = USEC_TIMER;
    uint32_t result;
    do
    {
        if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(1);
        sleep(HZ / 100);
        PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND)
                               | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3
                               | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NID,
                                 MMC_CMD_SEND_OP_COND_OCR(MMC_OCR_270_360),
                                 NULL, CEATA_COMMAND_TIMEOUT), 3, 2);
        result = SDCI_RESP0;
    }
    while (!(result & MMC_OCR_POWER_UP_DONE));
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_ALL_SEND_CID)
                           | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R2
                           | SDCI_CMD_RES_SIZE_136 | SDCI_CMD_NCR_NID_NID,
                             0, NULL, CEATA_COMMAND_TIMEOUT), 3, 3);
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SET_RELATIVE_ADDR)
                           | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R1
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             MMC_CMD_SET_RELATIVE_ADDR_RCA(CEATA_MMC_RCA),
                             NULL, CEATA_COMMAND_TIMEOUT), 3, 4);
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SELECT_CARD)
                           | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA),
                             NULL, CEATA_COMMAND_TIMEOUT), 3, 5);
    PASS_RC(mmc_get_card_status(&result), 3, 6);
    if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) RET_ERR(7);
    return 0;
}
Exemplo n.º 11
0
static int ceata_cancel_command(void)
{
    *((uint32_t volatile*)0x3cf00200) = 0x9000e;
    udelay(1);
    *((uint32_t volatile*)0x3cf00200) = 0x9000f;
    udelay(1);
    *((uint32_t volatile*)0x3cf00200) = 0x90003;
    udelay(1);
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_STOP_TRANSMISSION)
                           | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             0, NULL, CEATA_COMMAND_TIMEOUT), 1, 0);
    PASS_RC(ceata_wait_idle(), 1, 1);
    return 0;
}
Exemplo n.º 12
0
static int ceata_init(int buswidth)
{
    uint32_t result;
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
                           | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             MMC_CMD_SWITCH_ACCESS_WRITE_BYTE
                           | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING)
                           | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED),
                             &result, CEATA_COMMAND_TIMEOUT), 3, 0);
    if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(1);
    if (buswidth > 1)
    {
        int setting;
        if (buswidth == 4) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT;
        else if (buswidth == 8) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT;
        else setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT;
        PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
                               | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
                               | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                                 MMC_CMD_SWITCH_ACCESS_WRITE_BYTE
                               | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH)
                               | MMC_CMD_SWITCH_VALUE(setting),
                                 &result, CEATA_COMMAND_TIMEOUT), 3, 2);
        if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(3);
        if (buswidth == 4)
            SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT;
        else if (buswidth == 8)
            SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_8BIT;
    }
    PASS_RC(ceata_soft_reset(), 3, 4);
    PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5);
    if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) RET_ERR(6);
    PASS_RC(mmc_fastio_write(6, 0), 3, 7);
    return 0;
}
Exemplo n.º 13
0
//starts playing wav file pointed at by lba
void mmc_playerStart(mmc_File file){

	if(mmc_player_status==MMC_PLAYER_STARTED)
	{
		mmc_player_status = MMC_PLAYER_STOPPED;
		mmc_send_command(12,0,0); //stop current transfer
		mmc_clock_and_release();
	}

	// send the multiple block read command and logical sector address
	mmc_player_sector=file.firstSector;
	mmc_send_command(18,(mmc_player_sector>>7) & 0xffff, (mmc_player_sector<<9) & 0xffff);	
	playerRead=0;
	sectorRead=0;
	samplesToPlay.value=-1;
	mmc_player_status = MMC_PLAYER_STARTED;
}
Exemplo n.º 14
0
static int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long timeout)
{
    mmc_discard_irq();
    uint32_t responsetype;
    uint32_t cmdtype;
    uint32_t direction;
    if (write)
    {
        cmdtype = SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR;
        responsetype = SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY;
        direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_WRITE;
    }
    else
    {
        cmdtype = SDCI_CMD_CMD_TYPE_ADTC;
        responsetype = SDCI_CMD_RES_TYPE_R1;
        direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_READ;
    }
    SDCI_DMASIZE = 0x200;
    SDCI_DMAADDR = buf;
    SDCI_DMACOUNT = count;
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
    commit_discard_dcache();
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_BLOCK)
                           | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
                             NULL, CEATA_COMMAND_TIMEOUT), 4, 0);
    if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
    if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
    {
        PASS_RC(ceata_cancel_command(), 4, 1);
        RET_ERR(2);
    }
    PASS_RC(mmc_dsta_check_data_success(), 4, 3);
    if (semaphore_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
    {
        PASS_RC(ceata_cancel_command(), 4, 4);
        RET_ERR(4);
    }
    PASS_RC(ceata_check_error(), 4, 5);
    return 0;
}
Exemplo n.º 15
0
static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
{
    if (size > 0x10) RET_ERR(0);
    mmc_discard_irq();
    SDCI_DMASIZE = size;
    SDCI_DMACOUNT = 1;
    SDCI_DMAADDR = dest;
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
    commit_discard_dcache();
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
                           | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_RES_TYPE_R1
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
                             MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_READ
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
                             NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
    if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
        == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
    PASS_RC(mmc_dsta_check_data_success(), 2, 3);
    return 0;
}
Exemplo n.º 16
0
/* reads a single 512 bytes sector from the SD card */
int mmc_readsector(uint32_t lba, uint8_t *buffer)
{
	uint16_t i;

	// send command and sector
	mmc_send_command(READ_SINGLE_BLOCK, lba<<9);

	if (mmc_datatoken() != 0xfe)	// wait for start of block token
	{
		 mmc_release();	// error
   		return -1;
	}

	for (i=0;i<512;i++)
		*buffer++ = spi_byte(0xff); // read data

	spi_byte(0xff);					// ignore checksum
	spi_byte(0xff);					// ignore checksum

	mmc_release();

	return 0;
}