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

📄 sd_cmd.c

📁 This fat 16 can be used for logging function. The user can use it for logger device.
💻 C
📖 第 1 页 / 共 4 页
字号:
    uint8 resp;
    int16 n;
    
    sd_addr <<= 9;
    
    if(blk_size == 0)
        return((int8) EOF);

    clear_sd_buff();
    resp = 0xFF;

    clear_sd_buff();
    resp = 0xFF;
    _SD_send_cmd(CMD25, sd_addr);        /* Send Write Multi-Block Command */
    for(n = 0; ((n < 30000) && (resp == 0xFF)); n++)
        resp = _FF_spi(0xFF);
    if(resp == 0)
    {
        #ifdef _DEBUG_MULTI_BLOCK_    
            _FF_printf(_FF_StartBlockWriteStr);
            _BLOCK_ADDRESS_ = sd_addr;
        #endif
        SDBlockWriteBlockCnt = 0;
        return(0);
    }
    SD_CS_OFF();
    _FF_spi(0xFF);
    #ifdef _DEBUG_MULTI_BLOCK_    
        _FF_printf(_FF_StartMultiErrStr, 4, resp);
    #endif
    return((uint8) EOF);
}

/****************************************************************************
**
** Function used to write 1 byte when block writing to the SD/MMC media.
**
** Parameters: sd_data, byte to write in block mode
**
** Returns:  0 - Byte written successfully
**          -1 - An error occurred
**
****************************************************************************/
int8 SD_write_block_byte(uint8 sd_data)
{
    uint8 resp, calc;
    int16 n, i;

    #ifdef _DEBUG_MULTIBLOCK_BYTE_
        _FF_putchar(sd_data);
    #endif
    i = SDBlockWriteBlockCnt % 512;
    if(i == 0)
    {
        _FF_spi(0xFF);
        _FF_spi(SD_MULTI_START);    /* Start Block Token */
        #ifdef _DEBUG_MULTI_BLOCK_    
            _FF_printf(_FF_MultiWriteStr, _BLOCK_ADDRESS_);
            _BLOCK_ADDRESS_ += 0x200;
        #endif
    }
    _FF_spi(sd_data);               /* Send the data */
    SDBlockWriteBlockCnt++;
    i++;
    if(i == 512)
    {
        _FF_spi(0xFF);              /* Send 2 blank CRC bytes */
        _FF_spi(0xFF);
        resp = _FF_spi(0xFF);       /* Response should be 0bXXX00101 */
        calc = resp | 0xE0;
        if(calc == 0xE5)
        {
            n = 0;
            do
            {
                /* Wait for not busy */
                resp = _FF_spi(0xFF);
                if(n++ > 30000)
                    resp = 0xFF;    /* Response not received for too long, ignore*/
            } while(resp == 0);
        }
        else
        {
            #ifdef _DEBUG_MULTI_BLOCK_    
                _FF_printf(_FF_Multi02Str, resp);
            #endif
            SD_CS_OFF();
            _FF_spi(0xFF);
            return((int8) EOF);
        }
    }
    return(0);
}


/****************************************************************************
**
** Function called when block writing to the SD/MMC media is done
**
** Parameters: None
**
** Returns:  0 - Block ended successfully
**          -1 - An error occurred
**
****************************************************************************/
int8 SD_write_block_end(void)
{
    uint8 resp, calc;
    int16 n, i;

    i = SDBlockWriteBlockCnt % 512;
    if(i)
    {
        while(i++ < 512)
            _FF_spi(0xFF);          /* Pad the rest of the block */
    
        _FF_spi(0xFF);              /* Send 2 blank CRC bytes */
        _FF_spi(0xFF);
        resp = _FF_spi(0xFF);       /* Response should be 0bXXX00101 */
        calc = resp | 0xE0;
        if(calc == 0xE5)
        {
            n = 0;
            do
            {
                /* Wait for not busy */
                resp = _FF_spi(0xFF);
                if(n++ > 30000)
                {
                    #ifdef _DEBUG_MULTI_BLOCK_
                        _FF_printf(_FF_MultiEndStr, 1);
                    #endif
                    resp = 0xFF;    /* Response not received for too long, ignore*/
                }
            } while(resp == 0);
        }
        else
        {
            SD_CS_OFF();
            _FF_spi(0xFF);
            #ifdef _DEBUG_MULTI_BLOCK_
                _FF_printf(_FF_MultiEndStr, 2);
            #endif
            return((int8) EOF);
        }
    }
    _FF_spi(0xFF);
    _FF_spi(SD_STOP_TRANS);         /* Stop Block Token */

    n = 0;
    do
    {
        /* Wait for not busy */
        resp = _FF_spi(0xFF);
        if(n++ > 30000)
            resp = 0xFF;            /* Response not received for too long, ignore*/
    } while(resp == 0);

    SD_CS_OFF();
    _FF_spi(0xFF);

    return(0);
}
#endif /*defined(_SD_BLOCK_WRITE_) && !defined(_READ_ONLY_)*/


/*****************************************************************************
**
** LOCAL FUNCTIONS 
**
*****************************************************************************/

/****************************************************************************
**
** Initializes the SPI bus in the correct mode to use with the SD/MMC media.
**
** Parameters: None
**
** Returns: None
**
****************************************************************************/
void _FF_spi_init(void)
{
    /* SPI BUS SETUP */
    /* SPI initialization */
    /* SPI Type: Master */
    /* SPI Clock Rate: 921.600 kHz */
    /* SPI Clock Phase: Cycle Half */
    /* SPI Clock Polarity: Low */
    /* SPI Data Order: MSB First */
    #ifdef _MEGAAVRDEV_
        DDRB  = 0xB0 | DEMO_LED;
    #else
        DDRB |= 0x07;       /* Set SS, SCK, and MOSI to Output (If not output, processor will be a slave) */
        DDRB &= 0xF7;       /* Set MISO to Input */
    #endif
    CS_DDR_SET();           /* Set CS to Output */
    SPSR = 0x01;
    SPCR = _FF_SPCR_SET;    /* Initialize the SPI bus as a master */
}


/****************************************************************************
**
** Initializes all timers in the system. This call must be made before any 
** time-dependent functions can be called. The application should not enable 
** interrupts before TimeInit is called.
**
** Parameters:  command, the command to send to the card
**              argument, any data needed associated with the command
**
** Returns: None
**
****************************************************************************/
void _SD_send_cmd(uint8 command, uint32 argument)
{
    HiLo32Union arg_temp;

    SD_CS_ON();            /* select SD Card */

    /* send the command */
    _FF_spi(command);

    arg_temp.uval32 = argument;
    _FF_spi(arg_temp.uval8.hi);
    _FF_spi(arg_temp.uval8.mh);
    _FF_spi(arg_temp.uval8.ml);
    _FF_spi(arg_temp.uval8.lo);

    /* Send the CRC byte */
    if(command == CMD0)
        _FF_spi(0x95);        /* CRC byte, don't care except for CMD0 = 0x95 */
    else
        _FF_spi(0xFF);

    return;
}


/****************************************************************************
**
** Clears the SD/MMC's SPI bus so commands can be sent cleanly.
**
** Parameters: None
**
** Returns: None
**
****************************************************************************/
void clear_sd_buff(void)
{
    int8 n;

    SD_CS_OFF();
    for(n = 0; n < 10; n++)
        _FF_spi(0xFF);
}


/****************************************************************************
**
** Sends the "RESET" command to the SD/MMC media, the first command that has 
** to be sent to the card when initally powered.
**
** Parameters: None
**
** Returns:  0 - Reset command successful 
**          -1 - Failed to reset the card
**
****************************************************************************/
int8 reset_sd(void)
{
    int8 resp, c;
    int16 n;
    //**********************************************************************
    #ifdef _DEBUG_INIT_SD_
        _FF_printf(_FF_ResetCMDStr);
    #endif
    //**********************************************************************
    for(c = 0; c < 10; c++)        /* try reset command 3 times if needed */
    {
        clear_sd_buff();          /*dummy SPI */
        _SD_send_cmd(CMD0, 0);   /* idle COMMAND */
        for(n = 0; n < 1000; n++)
        {
            resp = _FF_spi(0xFF);
            if(resp == 0x1)
            {
                SD_CS_OFF();        // CS = 1  
                //***********************************************************
                #ifdef _DEBUG_INIT_SD_
                    _FF_printf(_FF_OkStr);
                #endif      
                //***********************************************************
                _FF_spi(0xFF);
                return(0);
            }
        }       
        //*******************************************************************
        #ifdef _DEBUG_INIT_SD_
            _FF_printf(_FF_Err02Str, resp);
        #endif
        //*******************************************************************
    }
    return((int8) EOF);
}


/****************************************************************************
**
** Sends the "RESET" command to the SD/MMC media, the first command that has 
** to be sent to the card when initally powered.
**
** Parameters: None
**
** Returns:  0 - Reset command successful 
**          -1 - Failed to reset the card
**
****************************************************************************/
int8 init_sd(void)
{
    uint8 resp;
    int16 i, n;

    clear_sd_buff();   
    //***********************************************************************
    #ifdef _DEBUG_INIT_SD_
        _FF_printf(_FF_InitStr);
    #endif
    //***********************************************************************
    resp = 0xFF;
    for(i = 0; ((i < 10000) && (resp != 0)); i++)
    {
        _SD_send_cmd(CMD1, 0);
        for(n = 0; ((n < 200) && (resp != 0)); n++)
            resp = _FF_spi(0xFF);
    }

    _FF_spi(0xFF);
    SD_CS_OFF();

    if(resp == 0)
    {   //*********************************************************************
        #ifdef _DEBUG_INIT_SD_
           _FF_printf(_FF_OkStr);
        #endif
        //*********************************************************************
        return(0);
    }
    else
    {   //*********************************************************************
        #ifdef _DEBUG_INIT_SD_
           _FF_printf(_FF_Err02Str, resp);
        #endif         
        //*********************************************************************
        return((int8) EOF);
     }
}


/*****************************************************************************
**
** EOF 
**
*****************************************************************************/

⌨️ 快捷键说明

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