Ejemplo n.º 1
0
void FatFS_class::begin(SPIClass &spi, int csline)
{
    s_spi=&spi;
    s_csline=csline;
    digitalWrite(csline,HIGH);
    pinMode(csline,OUTPUT);
    spi.setDataMode(SPI_MODE3);
    spi.setClockDivider(SPI_CLOCK_DIV4);
    register_sd();
}
Ejemplo n.º 2
0
/**
    Set the SPI clock rate.

    \param[in] sckRateID A value in the range [0, 6].

    The SPI clock will be set to F_CPU/pow(2, 1 + sckRateID). The maximum
    SPI rate is F_CPU/2 for \a sckRateID = 0 and the minimum rate is F_CPU/128
    for \a scsRateID = 6.

    \return The value one, true, is returned for success and the value zero,
    false, is returned for an invalid value of \a sckRateID.
*/
uint8_t Sd2Card::setSckRate(uint8_t sckRateID)
{
    if (sckRateID > 6)
    {
        error(SD_CARD_ERROR_SCK_RATE);
        return false;
    }
#ifndef USE_SPI_LIB
    // see avr processor datasheet for SPI register bit definitions
    if ((sckRateID & 1) || sckRateID == 6)
    {
        SPSR &= ~(1 << SPI2X);
    }
    else
    {
        SPSR |= (1 << SPI2X);
    }
    SPCR &= ~((1 << SPR1) | (1 << SPR0));
    SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
            | (sckRateID & 2 ? (1 << SPR0) : 0);
#else // USE_SPI_LIB
    int v;
#ifdef SPI_CLOCK_DIV128
    switch (sckRateID)
    {
        case 0: v = SPI_CLOCK_DIV2; break;
        case 1: v = SPI_CLOCK_DIV4; break;
        case 2: v = SPI_CLOCK_DIV8; break;
        case 3: v = SPI_CLOCK_DIV16; break;
        case 4: v = SPI_CLOCK_DIV32; break;
        case 5: v = SPI_CLOCK_DIV64; break;
        case 6: v = SPI_CLOCK_DIV128; break;
    }
#else // SPI_CLOCK_DIV128
    v = 2 << sckRateID;
#endif // SPI_CLOCK_DIV128
    SPI_for_SD.setClockDivider(v);
#endif // USE_SPI_LIB
    return true;
}
Ejemplo n.º 3
0
/**
    Initialize an SD flash memory card.

    \param[in] sckRateID SPI clock rate selector. See setSckRate().
    \param[in] chipSelectPin SD chip select pin number.

    \return The value one, true, is returned for success and
    the value zero, false, is returned for failure.  The reason for failure
    can be determined by calling errorCode() and errorData().
*/
uint8_t Sd2Card::init(uint8_t chipSelectPin, uint8_t sckRateID, int8_t SPI_Port, int8_t cardDetectionPin, int8_t level)
{
    // Serial.println("> Sd2Card::init");

    errorCode_ = inBlock_ = partialBlockRead_ = type_ = 0;
    chipSelectPin_ = chipSelectPin;
    SPI_Port_ = SPI_Port;
    cardDetectionPin_ = cardDetectionPin;
    level_ = level;

    // 16-bit init start time allows over a minute
    uint16_t t0 = (uint16_t)millis();
    uint32_t arg;

    // set pin modes
    pinMode(chipSelectPin_, OUTPUT);
    chipSelectHigh();

    if (cardDetectionPin_ >= 0)
    {
        pinMode(cardDetectionPin_, INPUT_PULLUP);
    }
    //#ifndef USE_SPI_LIB
    //  pinMode(SPI_MISO_PIN, INPUT);
    //  pinMode(SPI_MOSI_PIN, OUTPUT);
    //  pinMode(SPI_SCK_PIN, OUTPUT);
    //#endif

    //#ifndef SOFTWARE_SPI
    //#ifndef USE_SPI_LIB
    //  // SS must be in output mode even it is not chip select
    //  pinMode(SS_PIN, OUTPUT);
    //  digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
    //  // Enable SPI, Master, clock rate f_osc/128
    //  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
    //  // clear double speed
    //  SPSR &= ~(1 << SPI2X);
    //#else // USE_SPI_LIB

    /// @todo Add SPI port selection for LM4F and TM4C

    SPI_for_SD.begin();

#if defined(__LM4F120H5QR__) || defined(__TM4C1230C3PM__) || defined(__TM4C123GH6PM__) || defined(__TM4C129XNCZAD__) || defined(__TM4C1294NCPDT__)
    // LM4F and TM4C specific
    if (SPI_Port >= 0)
    {
        SPI_for_SD.setModule(SPI_Port);
    }
#endif

#ifdef SPI_CLOCK_DIV128
    // Serial.println("> SPI_Port 128");
    SPI_for_SD.setClockDivider(SPI_CLOCK_DIV128);
#else
    // Serial.println("> SPI_Port 255");
    SPI_for_SD.setClockDivider(255);
#endif

    //#endif // USE_SPI_LIB
    //#endif // SOFTWARE_SPI


    // Hardware card detection
    if (cardDetectionPin_ >= 0)
    {
        //        debugln("hardware card detection %i should be %i", digitalRead(cardDetectionPin_), level);
        if (digitalRead(cardDetectionPin_) != level_)
        {
            // Serial.println("*** hardware failure");
            error(SD_CARD_ERROR_CMD0);
            // I don't like goto but this is how it is implemented
            goto fail;
        }
    }

    // Software card detection

    // must supply min of 74 clock cycles with CS high.
    for (uint8_t i = 0; i < 10; i++)
    {
        spiSend(0xff);
    }

    chipSelectLow();

    // Serial.print("software card detection ");


    // command to go idle in SPI mode
    while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE)
    {
        if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT)
        {
            error(SD_CARD_ERROR_CMD0);
            // Serial.println("*** software failure");
            goto fail;
        }
    }
    // check SD version
    if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND))
    {
        type(SD_CARD_TYPE_SD1);
    }
    else
    {
        // only need last byte of r7 response
        for (uint8_t i = 0; i < 4; i++)
        {
            status_ = spiRec();
        }
        if (status_ != 0xaa)
        {
            error(SD_CARD_ERROR_CMD8);
            goto fail;
        }
        type(SD_CARD_TYPE_SD2);
    }
    // initialize card and send host supports SDHC if SD2
    arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0;

    while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE)
    {
        // check for timeout
        if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT)
        {
            error(SD_CARD_ERROR_ACMD41);
            goto fail;
        }
    }
    // if SD2 read OCR register to check for SDHC card
    if (type() == SD_CARD_TYPE_SD2)
    {
        if (cardCommand(CMD58, 0))
        {
            error(SD_CARD_ERROR_CMD58);
            goto fail;
        }
        if ((spiRec() & 0xc0) == 0xc0)
        {
            type(SD_CARD_TYPE_SDHC);
        }
        // discard rest of ocr - contains allowed voltage range
        for (uint8_t i = 0; i < 3; i++)
        {
            spiRec();
        }
    }
    chipSelectHigh();

#ifndef SOFTWARE_SPI
    return setSckRate(sckRateID);
#else  // SOFTWARE_SPI
    return true;
#endif  // SOFTWARE_SPI

fail:
    chipSelectHigh();
    return false;
}