diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-02-04 18:43:15 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-02-04 18:43:15 +0300 |
commit | ed3b2306a7df90ece49d6640bbf1aee3de7491f5 (patch) | |
tree | d460cb90bc44443315ef365ce14309f724bfeb29 | |
parent | 191f3e7d72a445e51a956805d2fc6fb1901327af (diff) | |
parent | 60ed67b33dff503fba35dd9e0979b0d2bc566471 (diff) |
Merge branch '3.3-dev' into wil-convert-same70-to-coren2g
-rw-r--r-- | BuildInstructions.md | 14 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 18 | ||||
-rw-r--r-- | src/Heating/Sensors/DhtSensor.cpp | 7 | ||||
-rw-r--r-- | src/Libraries/sd_mmc/sd_mmc.c | 310 | ||||
-rw-r--r-- | src/Libraries/sd_mmc/sd_mmc.h | 8 | ||||
-rw-r--r-- | src/Libraries/sd_mmc/sd_mmc_mem.c | 8 |
6 files changed, 210 insertions, 155 deletions
diff --git a/BuildInstructions.md b/BuildInstructions.md index 6e0c3e36..1297b3d9 100644 --- a/BuildInstructions.md +++ b/BuildInstructions.md @@ -19,7 +19,7 @@ To build RepRapFirmware v3.1.1, use the following tags: >**Note**: CoreNG, FreeRTOS, RRFLibraries do not have v3.1.1 tags because the 3.1.0 tagged releases are the base for v3.1.1 (no changes in the dependencies, only in RepRapFirmware) -To build RepRapFirmware from the latest development sources, use the following branches: +To build RepRapFirmware 3.2 from the latest development sources, use the following branches: | project | branch | notes | | :-- | --: | --- | @@ -31,6 +31,18 @@ To build RepRapFirmware from the latest development sources, use the following b |[RRFLibraries](https://github.com/Duet3D/RRFLibraries)| dev || |[DuetWiFiSocketServer](https://github.com/Duet3D/DuetWifiSocketServer)| dev || +To build RepRapFirmware 3.3 from the latest development sources, use the following branches: + +| project | branch | notes | +| :-- | --: | --- | +|[RepRapFirmware](https://github.com/Duet3D/RepRapFirmware)| v3.3-dev|| +|[CANlib](https://github.com/Duet3D/CANlib)| v3.3-dev | _only needed for Duet 3_ | +|[CoreNG](https://github.com/Duet3D/CoreNG)| dev | _not needed for Duet 3 Mini5+_ | +|[CoreN2G](https://github.com/Duet3D/CoreN2G)| v3.3-dev | _only needed for Duet 3 Mini5+_ | +|[FreeRTOS](https://github.com/Duet3D/FreeRTOS)| dev || +|[RRFLibraries](https://github.com/Duet3D/RRFLibraries)| v3.3-dev || +|[DuetWiFiSocketServer](https://github.com/Duet3D/DuetWifiSocketServer)| dev || + ## Additional Tools Building RepRapFirmware lately requires a tool called `crc32appender` to be in diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 19a06933..e4590c21 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -1423,13 +1423,21 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx break; case 109: // Deprecated in RRF, but widely generated by slicers - if ( !LockMovementAndWaitForStandstill(gb) // wait until movement has finished - || !IsCodeQueueIdle() // also wait until deferred command queue has caught up to avoid out-of-order execution - ) { - return false; + const bool movementWasLocked = gb.MachineState().lockedResources.IsBitSet(MoveResource); + if ( !LockMovementAndWaitForStandstill(gb) // wait until movement has finished + || !IsCodeQueueIdle() // also wait until deferred command queue has caught up to avoid out-of-order execution + ) + { + return false; + } + + // 2020-02-04 Don't unlock movement if it was already locked, e.g. because M109 was used in a macro + if (!movementWasLocked) + { + UnlockMovement(gb); // allow babystepping and pausing while heating + } } - UnlockMovement(gb); // allow babystepping and pausing while heating // no break case 104: diff --git a/src/Heating/Sensors/DhtSensor.cpp b/src/Heating/Sensors/DhtSensor.cpp index 001a2d83..5f52394c 100644 --- a/src/Heating/Sensors/DhtSensor.cpp +++ b/src/Heating/Sensors/DhtSensor.cpp @@ -147,7 +147,8 @@ void DhtTemperatureSensor::TakeReading() noexcept // End the start signal by setting data line high. the sensor will respond with the start bit in 20 to 40us. // We need only force the data line high long enough to charge the line capacitance, after that the pullup resistor keeps it high. - port.WriteDigital(true); // this will generate an interrupt, but we will ignore it + numPulses = ARRAY_SIZE(pulses); // tell the ISR not to collect data yet + port.WriteDigital(true); // this may generate an interrupt, but we will ignore it delayMicroseconds(3); // Now start reading the data line to get the value from the DHT sensor @@ -155,8 +156,8 @@ void DhtTemperatureSensor::TakeReading() noexcept // It appears that switching the pin to an output disables the interrupt, so we need to call attachInterrupt here // We are likely to get an immediate interrupt at this point corresponding to the low-to-high transition. We must ignore this. - numPulses = ARRAY_SIZE(pulses); // tell the ISR not to collect data yet - port.AttachInterrupt(DhtDataTransition, InterruptMode::change, this); + port.AttachInterrupt(DhtDataTransition, INTERRUPT_MODE_CHANGE, this); + delayMicroseconds(2); // give the interrupt time to occur lastPulseTime = 0; numPulses = 0; // tell the ISR to collect data } diff --git a/src/Libraries/sd_mmc/sd_mmc.c b/src/Libraries/sd_mmc/sd_mmc.c index 03033cf1..024b3a24 100644 --- a/src/Libraries/sd_mmc/sd_mmc.c +++ b/src/Libraries/sd_mmc/sd_mmc.c @@ -44,6 +44,9 @@ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> */ +// 2021-02-03: MC and DC converted this to be re-entrant, provided that only one task uses each interface. +// Currently all RRF configurations for Duets support at most one HSMCI and one SPI card, and there is a mutex for each volume, so this is the case. + #include <Core.h> // for digitalRead() and pinMode() #include <string.h> @@ -112,7 +115,7 @@ struct DriverInterface driverIdleFunc_t hsmci_set_idle_func(driverIdleFunc_t func) noexcept { - // This is not called when we use the SAME5x SDMMC driver + // This function is not used on the SAME5x because the low-level driver is FreeRTOS-aware return NULL; } @@ -232,14 +235,10 @@ struct sd_mmc_card { //DC added __nocache for SAME70 because 'csd' is read by DMA static __nocache struct sd_mmc_card sd_mmc_cards[SD_MMC_MEM_CNT]; -//! Index of current slot selected -static uint8_t sd_mmc_slot_sel; -//! Pointer on current slot selected -static struct sd_mmc_card *sd_mmc_card; //! Number of block to read or write on the current transfer -static uint16_t sd_mmc_nb_block_to_tranfer = 0; +static uint16_t sd_mmc_nb_block_to_tranfer[SD_MMC_MEM_CNT] = { 0 }; //! Number of block remaining to read or write on the current transfer -static uint16_t sd_mmc_nb_block_remaining = 0; +static uint16_t sd_mmc_nb_block_remaining[SD_MMC_MEM_CNT] = { 0 }; //! SD/MMC transfer rate unit codes (10K) list const uint32_t sd_mmc_trans_units[7] = { @@ -256,43 +255,43 @@ const uint32_t mmc_trans_multipliers[16] = { //! \name MMC, SD and SDIO commands process //! @{ -static bool mmc_spi_op_cond(void); -static bool mmc_mci_op_cond(void); -static bool sd_spi_op_cond(uint8_t v2); -static bool sd_mci_op_cond(uint8_t v2); +static bool mmc_spi_op_cond(uint8_t slot); +static bool mmc_mci_op_cond(uint8_t slot); +static bool sd_spi_op_cond(uint8_t v2, uint8_t slot); +static bool sd_mci_op_cond(uint8_t v2, uint8_t slot); static bool sdio_op_cond(void); static bool sdio_get_max_speed(void); static bool sdio_cmd52_set_bus_width(void); static bool sdio_cmd52_set_high_speed(void); -static bool sd_cm6_set_high_speed(void); -static bool mmc_cmd6_set_bus_width(uint8_t bus_width); -static bool mmc_cmd6_set_high_speed(void); -static bool sd_cmd8(uint8_t * v2); -static bool mmc_cmd8(uint8_t *b_authorize_high_speed); -static bool sd_mmc_cmd9_spi(void); -static bool sd_mmc_cmd9_mci(void); -static void mmc_decode_csd(void); -static void sd_decode_csd(void); -static bool sd_mmc_cmd13(void); +static bool sd_cm6_set_high_speed(uint8_t slot); +static bool mmc_cmd6_set_bus_width(uint8_t bus_width, uint8_t slot); +static bool mmc_cmd6_set_high_speed(uint8_t slot); +static bool sd_cmd8(uint8_t * v2, uint8_t slot); +static bool mmc_cmd8(uint8_t *b_authorize_high_speed, uint8_t slot); +static bool sd_mmc_cmd9_spi(uint8_t slot); +static bool sd_mmc_cmd9_mci(uint8_t slot); +static void mmc_decode_csd(uint8_t slot); +static void sd_decode_csd(uint8_t slot); +static bool sd_mmc_cmd13(uint8_t slot); #ifdef SDIO_SUPPORT_ENABLE static bool sdio_cmd52(uint8_t rw_flag, uint8_t func_nb, uint32_t reg_addr, uint8_t rd_after_wr, uint8_t *io_data); static bool sdio_cmd53(uint8_t rw_flag, uint8_t func_nb, uint32_t reg_addr, uint8_t inc_addr, uint32_t size, bool access_block); #endif // SDIO_SUPPORT_ENABLE -static bool sd_acmd6(void); -static bool sd_acmd51(void); +static bool sd_acmd6(uint8_t slot); +static bool sd_acmd51(uint8_t slot); //! @} //! \name Internal function to process the initialization and install //! @{ static sd_mmc_err_t sd_mmc_select_slot(uint8_t slot); -static bool sd_mmc_configure_slot(void); -static void sd_mmc_deselect_slot(void); -static bool sd_mmc_spi_card_init(void); -static bool sd_mmc_mci_card_init(void); -static bool sd_mmc_spi_install_mmc(void); -static bool sd_mmc_mci_install_mmc(void); +static bool sd_mmc_configure_slot(uint8_t slot); +static void sd_mmc_deselect_slot(uint8_t slot); +static bool sd_mmc_spi_card_init(uint8_t slot); +static bool sd_mmc_mci_card_init(uint8_t slot); +static bool sd_mmc_spi_install_mmc(uint8_t slot); +static bool sd_mmc_mci_install_mmc(uint8_t slot); //! @} @@ -308,9 +307,10 @@ static bool sd_mmc_mci_install_mmc(void); * * \return true if success, otherwise false */ -static bool mmc_spi_op_cond(void) +static bool mmc_spi_op_cond(uint8_t slot) { uint32_t retry, resp; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; /* * Timeout 1s = 400KHz / ((6+1)*8) cylces = 7150 retry @@ -355,9 +355,10 @@ static bool mmc_spi_op_cond(void) * * \return true if success, otherwise false */ -static bool mmc_mci_op_cond(void) +static bool mmc_mci_op_cond(uint8_t slot) { uint32_t retry, resp; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; /* * Timeout 1s = 400KHz / ((6+6)*8) cylces = 4200 retry @@ -399,9 +400,10 @@ static bool mmc_mci_op_cond(void) * * \return true if success, otherwise false */ -static bool sd_spi_op_cond(uint8_t v2) +static bool sd_spi_op_cond(uint8_t v2, uint8_t slot) { uint32_t arg, retry, resp; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; /* * Timeout 1s = 400KHz / ((6+1)*8) cylces = 7150 retry @@ -459,9 +461,10 @@ static bool sd_spi_op_cond(uint8_t v2) * * \return true if success, otherwise false */ -static bool sd_mci_op_cond(uint8_t v2) +static bool sd_mci_op_cond(uint8_t v2, uint8_t slot) { uint32_t arg, retry, resp; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; /* * Timeout 1s = 400KHz / ((6+6+6+6)*8) cylces = 2100 retry @@ -744,15 +747,17 @@ static bool sdio_cmd52_set_high_speed(void) * * \return true if success, otherwise false */ -static bool sd_cm6_set_high_speed(void) +static bool sd_cm6_set_high_speed(uint8_t slot) { #if SAME70 - static __nocache uint8_t switch_status[SD_SW_STATUS_BSIZE]; + static __nocache uint8_t switch_status_array[SD_MMC_MEM_CNT][SD_SW_STATUS_BSIZE]; + uint8_t * const switch_status = switch_status_array[slot]; #else uint8_t switch_status[SD_SW_STATUS_BSIZE]; #endif + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->adtc_start(SD_CMD6_SWITCH_FUNC, SD_CMD6_MODE_SWITCH | SD_CMD6_GRP6_NO_INFLUENCE @@ -802,7 +807,7 @@ static bool sd_cm6_set_high_speed(void) * * \return true if success, otherwise false */ -static bool mmc_cmd6_set_bus_width(uint8_t bus_width) +static bool mmc_cmd6_set_bus_width(uint8_t bus_width, uint8_t slot) { uint32_t arg; @@ -823,6 +828,7 @@ static bool mmc_cmd6_set_bus_width(uint8_t bus_width) | MMC_CMD6_VALUE_BUS_WIDTH_1BIT; break; } + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->send_cmd(MMC_CMD6_SWITCH, arg)) { return false; } @@ -845,8 +851,9 @@ static bool mmc_cmd6_set_bus_width(uint8_t bus_width) * * \return true if success, otherwise false */ -static bool mmc_cmd6_set_high_speed(void) +static bool mmc_cmd6_set_high_speed(uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->send_cmd(MMC_CMD6_SWITCH, MMC_CMD6_ACCESS_WRITE_BYTE | MMC_CMD6_INDEX_HS_TIMING @@ -876,9 +883,10 @@ static bool mmc_cmd6_set_high_speed(void) * \return true if success, otherwise false * with a update of \ref sd_mmc_err. */ -static bool sd_cmd8(uint8_t * v2) +static bool sd_cmd8(uint8_t * v2, uint8_t slot) { uint32_t resp; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; *v2 = 0; // Test for SD version 2 @@ -911,11 +919,12 @@ static bool sd_cmd8(uint8_t * v2) * * \return true if success, otherwise false */ -static bool mmc_cmd8(uint8_t *b_authorize_high_speed) +static bool mmc_cmd8(uint8_t *b_authorize_high_speed, uint8_t slot) { uint16_t i; uint32_t ext_csd; uint32_t sec_count; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->adtc_start(MMC_CMD8_SEND_EXT_CSD, 0, EXT_CSD_BSIZE, 1, false)) { return false; @@ -957,8 +966,9 @@ static bool mmc_cmd8(uint8_t *b_authorize_high_speed) * * \return true if success, otherwise false */ -static bool sd_mmc_cmd9_spi(void) +static bool sd_mmc_cmd9_spi(uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->adtc_start(SDMMC_SPI_CMD9_SEND_CSD, (uint32_t)sd_mmc_card->rca << 16, CSD_REG_BSIZE, 1, sd_mmc_card->csd)) { return false; } @@ -974,8 +984,9 @@ static bool sd_mmc_cmd9_spi(void) * * \return true if success, otherwise false */ -static bool sd_mmc_cmd9_mci(void) +static bool sd_mmc_cmd9_mci(uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->send_cmd(SDMMC_MCI_CMD9_SEND_CSD, (uint32_t)sd_mmc_card->rca << 16)) { return false; } @@ -986,11 +997,12 @@ static bool sd_mmc_cmd9_mci(void) /** * \brief Decodes MMC CSD register */ -static void mmc_decode_csd(void) +static void mmc_decode_csd(uint8_t slot) { uint32_t unit; uint32_t mul; uint32_t tran_speed; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // Get MMC System Specification version supported by the card switch (MMC_CSD_SPEC_VERS(sd_mmc_card->csd)) { @@ -1046,11 +1058,12 @@ static void mmc_decode_csd(void) /** * \brief Decodes SD CSD register */ -static void sd_decode_csd(void) +static void sd_decode_csd(uint8_t slot) { uint32_t unit; uint32_t mul; uint32_t tran_speed; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // Get SD memory maximum transfer speed in Hz. tran_speed = CSD_TRAN_SPEED(sd_mmc_card->csd); @@ -1090,9 +1103,10 @@ static void sd_decode_csd(void) * * \return true if success, otherwise false */ -static bool sd_mmc_cmd13(void) +static bool sd_mmc_cmd13(uint8_t slot) { uint32_t nec_timeout; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; /* Wait for data ready status. * Nec timing: 0 to unlimited @@ -1194,8 +1208,9 @@ static bool sdio_cmd53(uint8_t rw_flag, uint8_t func_nb, uint32_t reg_addr, * * \return true if success, otherwise false */ -static bool sd_acmd6(void) +static bool sd_acmd6(uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // CMD55 - Indicate to the card that the next command is an // application specific command rather than a standard command. if (!sd_mmc_card->iface->send_cmd(SDMMC_CMD55_APP_CMD, (uint32_t)sd_mmc_card->rca << 16)) { @@ -1221,13 +1236,15 @@ static bool sd_acmd6(void) * * \return true if success, otherwise false */ -static bool sd_acmd51(void) +static bool sd_acmd51(uint8_t slot) { #if SAME70 - static __nocache uint8_t scr[SD_SCR_REG_BSIZE]; + static __nocache uint8_t scr_array[SD_MMC_MEM_CNT][SD_SCR_REG_BSIZE]; + uint8_t * const scr = scr_array[slot]; #else uint8_t scr[SD_SCR_REG_BSIZE]; #endif + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // CMD55 - Indicate to the card that the next command is an // application specific command rather than a standard command. @@ -1339,9 +1356,9 @@ static sd_mmc_err_t sd_mmc_select_slot(uint8_t slot) } // Initialize interface - sd_mmc_slot_sel = slot; - sd_mmc_card = &sd_mmc_cards[slot]; - sd_mmc_configure_slot(); +// sd_mmc_slot_sel = slot; +// sd_mmc_card = &sd_mmc_cards[slot]; + sd_mmc_configure_slot(slot); return (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_INIT) ? SD_MMC_INIT_ONGOING : SD_MMC_OK; } @@ -1349,19 +1366,21 @@ static sd_mmc_err_t sd_mmc_select_slot(uint8_t slot) /** * \brief Configures the driver with the selected card configuration */ -static __attribute__((warn_unused_result)) bool sd_mmc_configure_slot(void) +static __attribute__((warn_unused_result)) bool sd_mmc_configure_slot(uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; return sd_mmc_card->iface->select_device(sd_mmc_card->slot, sd_mmc_card->clock, sd_mmc_card->bus_width, sd_mmc_card->high_speed); } /** * \brief Deselect the current card slot */ -static void sd_mmc_deselect_slot(void) +static void sd_mmc_deselect_slot(uint8_t slot) { - if (sd_mmc_slot_sel < SD_MMC_MEM_CNT) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; + if (slot < SD_MMC_MEM_CNT) { sd_mmc_card->iface->deselect_device(sd_mmc_card->slot); - sd_mmc_slot_sel = 0xFF; // No slot selected +// sd_mmc_slot_sel = 0xFF; // No slot selected FIXME } } @@ -1375,9 +1394,10 @@ static void sd_mmc_deselect_slot(void) * * \return true if success, otherwise false */ -static bool sd_mmc_spi_card_init(void) +static bool sd_mmc_spi_card_init(uint8_t slot) { uint8_t v2 = 0; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // In first, try to install SD/SDIO card sd_mmc_card->type = CARD_TYPE_SD; @@ -1392,7 +1412,7 @@ static bool sd_mmc_spi_card_init(void) if (!sd_mmc_card->iface->send_cmd(SDMMC_SPI_CMD0_GO_IDLE_STATE, 0)) { return false; } - if (!sd_cmd8(&v2)) { + if (!sd_cmd8(&v2, slot)) { return false; } // Try to get the SDIO card's operating condition @@ -1402,11 +1422,11 @@ static bool sd_mmc_spi_card_init(void) if (sd_mmc_card->type & CARD_TYPE_SD) { // Try to get the SD card's operating condition - if (!sd_spi_op_cond(v2)) { + if (!sd_spi_op_cond(v2, slot)) { // It is not a SD card sd_mmc_debug("Start MMC Install\n\r"); sd_mmc_card->type = CARD_TYPE_MMC; - return sd_mmc_spi_install_mmc(); + return sd_mmc_spi_install_mmc(slot); } /* The CRC on card is disabled by default. @@ -1422,12 +1442,12 @@ static bool sd_mmc_spi_card_init(void) // SD MEMORY if (sd_mmc_card->type & CARD_TYPE_SD) { // Get the Card-Specific Data - if (!sd_mmc_cmd9_spi()) { + if (!sd_mmc_cmd9_spi(slot)) { return false; } - sd_decode_csd(); + sd_decode_csd(slot); // Read the SCR to get card version - if (!sd_acmd51()) { + if (!sd_acmd51(slot)) { return false; } } @@ -1445,12 +1465,12 @@ static bool sd_mmc_spi_card_init(void) } // Check communication if (sd_mmc_card->type & CARD_TYPE_SD) { - if (!sd_mmc_cmd13()) { + if (!sd_mmc_cmd13(slot)) { return false; } } // Re-initialize the slot with the new speed - return sd_mmc_configure_slot(); + return sd_mmc_configure_slot(slot); } /** @@ -1463,9 +1483,10 @@ static bool sd_mmc_spi_card_init(void) * * \return true if success, otherwise false */ -static bool sd_mmc_mci_card_init(void) +static bool sd_mmc_mci_card_init(uint8_t slot) { uint8_t v2 = 0; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // In first, try to install SD/SDIO card sd_mmc_card->type = CARD_TYPE_SD; @@ -1481,7 +1502,7 @@ static bool sd_mmc_mci_card_init(void) { return false; } - if (!sd_cmd8(&v2)) + if (!sd_cmd8(&v2, slot)) { return false; } @@ -1494,12 +1515,12 @@ static bool sd_mmc_mci_card_init(void) if (sd_mmc_card->type & CARD_TYPE_SD) { // Try to get the SD card's operating condition - if (!sd_mci_op_cond(v2)) + if (!sd_mci_op_cond(v2, slot)) { // It is not a SD card sd_mmc_debug("Start MMC Install\n\r"); sd_mmc_card->type = CARD_TYPE_MMC; - return sd_mmc_mci_install_mmc(); + return sd_mmc_mci_install_mmc(slot); } } @@ -1522,11 +1543,11 @@ static bool sd_mmc_mci_card_init(void) // SD MEMORY, Get the Card-Specific Data if (sd_mmc_card->type & CARD_TYPE_SD) { - if (!sd_mmc_cmd9_mci()) + if (!sd_mmc_cmd9_mci(slot)) { return false; } - sd_decode_csd(); + sd_decode_csd(slot); } // Select the and put it into Transfer Mode if (!sd_mmc_card->iface->send_cmd(SDMMC_CMD7_SELECT_CARD_CMD, (uint32_t)sd_mmc_card->rca << 16)) @@ -1536,7 +1557,7 @@ static bool sd_mmc_mci_card_init(void) // SD MEMORY, Read the SCR to get card version if (sd_mmc_card->type & CARD_TYPE_SD) { - if (!sd_acmd51()) + if (!sd_acmd51(slot)) { return false; } @@ -1560,13 +1581,13 @@ static bool sd_mmc_mci_card_init(void) } if (sd_mmc_card->type & CARD_TYPE_SD) { - if (!sd_acmd6()) + if (!sd_acmd6(slot)) { return false; } } // Switch to selected bus mode - if (!sd_mmc_configure_slot()) + if (!sd_mmc_configure_slot(slot)) { return false; } @@ -1585,14 +1606,14 @@ static bool sd_mmc_mci_card_init(void) { if (sd_mmc_card->version > CARD_VER_SD_1_0) { - if (!sd_cm6_set_high_speed()) + if (!sd_cm6_set_high_speed(slot)) { return false; } } } // Valid new configuration - if (!sd_mmc_configure_slot()) + if (!sd_mmc_configure_slot(slot)) { return false; } @@ -1618,16 +1639,17 @@ static bool sd_mmc_mci_card_init(void) * * \return true if success, otherwise false */ -static bool sd_mmc_spi_install_mmc(void) +static bool sd_mmc_spi_install_mmc(uint8_t slot) { uint8_t b_authorize_high_speed; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // CMD0 - Reset all cards to idle state. if (!sd_mmc_card->iface->send_cmd(SDMMC_SPI_CMD0_GO_IDLE_STATE, 0)) { return false; } - if (!mmc_spi_op_cond()) { + if (!mmc_spi_op_cond(slot)) { return false; } @@ -1636,14 +1658,14 @@ static bool sd_mmc_spi_install_mmc(void) return false; } // Get the Card-Specific Data - if (!sd_mmc_cmd9_spi()) { + if (!sd_mmc_cmd9_spi(slot)) { return false; } - mmc_decode_csd(); + mmc_decode_csd(slot); // For MMC 4.0 Higher version if (sd_mmc_card->version >= CARD_VER_MMC_4) { // Get EXT_CSD - if (!mmc_cmd8(&b_authorize_high_speed)) { + if (!mmc_cmd8(&b_authorize_high_speed, slot)) { return false; } } @@ -1652,11 +1674,11 @@ static bool sd_mmc_spi_install_mmc(void) return false; } // Check communication - if (!sd_mmc_cmd13()) { + if (!sd_mmc_cmd13(slot)) { return false; } // Re-initialize the slot with the new speed - return sd_mmc_configure_slot(); + return sd_mmc_configure_slot(slot); } @@ -1670,9 +1692,10 @@ static bool sd_mmc_spi_install_mmc(void) * * \return true if success, otherwise false */ -static bool sd_mmc_mci_install_mmc(void) +static bool sd_mmc_mci_install_mmc(uint8_t slot) { uint8_t b_authorize_high_speed; + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; // CMD0 - Reset all cards to idle state. if (!sd_mmc_card->iface->send_cmd(SDMMC_MCI_CMD0_GO_IDLE_STATE, 0)) @@ -1680,7 +1703,7 @@ static bool sd_mmc_mci_install_mmc(void) return false; } - if (!mmc_mci_op_cond()) + if (!mmc_mci_op_cond(slot)) { return false; } @@ -1698,11 +1721,11 @@ static bool sd_mmc_mci_install_mmc(void) return false; } // Get the Card-Specific Data - if (!sd_mmc_cmd9_mci()) + if (!sd_mmc_cmd9_mci(slot)) { return false; } - mmc_decode_csd(); + mmc_decode_csd(slot); // Select the and put it into Transfer Mode if (!sd_mmc_card->iface->send_cmd(SDMMC_CMD7_SELECT_CARD_CMD, (uint32_t)sd_mmc_card->rca << 16)) { @@ -1712,19 +1735,19 @@ static bool sd_mmc_mci_install_mmc(void) { // For MMC 4.0 Higher version // Get EXT_CSD - if (!mmc_cmd8(&b_authorize_high_speed)) + if (!mmc_cmd8(&b_authorize_high_speed, slot)) { return false; } if (4 <= sd_mmc_card->iface->get_bus_width(sd_mmc_card->slot)) { // Enable more bus width - if (!mmc_cmd6_set_bus_width(sd_mmc_card->iface->get_bus_width(sd_mmc_card->slot))) + if (!mmc_cmd6_set_bus_width(sd_mmc_card->iface->get_bus_width(sd_mmc_card->slot), slot)) { return false; } // Re-initialize the slot with the bus width - if (!sd_mmc_configure_slot()) + if (!sd_mmc_configure_slot(slot)) { return false; } @@ -1732,12 +1755,12 @@ static bool sd_mmc_mci_install_mmc(void) if (sd_mmc_card->iface->is_high_speed_capable() && b_authorize_high_speed) { // Enable HS - if (!mmc_cmd6_set_high_speed()) + if (!mmc_cmd6_set_high_speed(slot)) { return false; } // Re-initialize the slot with the new speed - if (!sd_mmc_configure_slot()) + if (!sd_mmc_configure_slot(slot)) { return false; } @@ -1746,7 +1769,7 @@ static bool sd_mmc_mci_install_mmc(void) else { // Re-initialize the slot with the new speed - if (!sd_mmc_configure_slot()) + if (!sd_mmc_configure_slot(slot)) { return false; } @@ -1797,7 +1820,7 @@ void sd_mmc_init(const Pin wpPins[], const Pin spiCsPins[]) #endif } } - sd_mmc_slot_sel = 0xFF; // No slot selected +// sd_mmc_slot_sel = 0xFF; // No slot selected #if SD_MMC_HSMCI_MEM_CNT != 0 hsmci_init(); @@ -1820,22 +1843,23 @@ sd_mmc_err_t sd_mmc_check(uint8_t slot) sd_mmc_err_t sd_mmc_err = sd_mmc_select_slot(slot); if (sd_mmc_err != SD_MMC_INIT_ONGOING) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return sd_mmc_err; } // Initialization of the card requested - if (sd_mmc_card->iface->is_spi ? sd_mmc_spi_card_init() : sd_mmc_mci_card_init()) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; + if (sd_mmc_card->iface->is_spi ? sd_mmc_spi_card_init(slot) : sd_mmc_mci_card_init(slot)) { sd_mmc_debug("SD/MMC card ready\n\r"); sd_mmc_card->state = SD_MMC_CARD_STATE_READY; - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); // To notify that the card has been just initialized // It is necessary for USB Device MSC return SD_MMC_INIT_ONGOING; } sd_mmc_debug("SD/MMC card initialization failed\n\r"); sd_mmc_card->state = SD_MMC_CARD_STATE_UNUSABLE; - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_UNUSABLE; } @@ -1844,8 +1868,8 @@ card_type_t sd_mmc_get_type(uint8_t slot) if (SD_MMC_OK != sd_mmc_select_slot(slot)) { return CARD_TYPE_UNKNOWN; } - sd_mmc_deselect_slot(); - return sd_mmc_card->type; + sd_mmc_deselect_slot(slot); + return sd_mmc_cards[slot].type; } card_version_t sd_mmc_get_version(uint8_t slot) @@ -1853,8 +1877,8 @@ card_version_t sd_mmc_get_version(uint8_t slot) if (SD_MMC_OK != sd_mmc_select_slot(slot)) { return CARD_VER_UNKNOWN; } - sd_mmc_deselect_slot(); - return sd_mmc_card->version; + sd_mmc_deselect_slot(slot); + return sd_mmc_cards[slot].version; } uint32_t sd_mmc_get_capacity(uint8_t slot) @@ -1862,8 +1886,8 @@ uint32_t sd_mmc_get_capacity(uint8_t slot) if (SD_MMC_OK != sd_mmc_select_slot(slot)) { return 0; } - sd_mmc_deselect_slot(); - return sd_mmc_card->capacity; + sd_mmc_deselect_slot(slot); + return sd_mmc_cards[slot].capacity; } bool sd_mmc_is_write_protected(uint8_t slot) @@ -1901,8 +1925,8 @@ sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, uint16_t nb_b } // Wait for data ready status - if (!sd_mmc_cmd13()) { - sd_mmc_deselect_slot(); + if (!sd_mmc_cmd13(slot)) { + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } @@ -1911,6 +1935,9 @@ sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, uint16_t nb_b } else { cmd = SDMMC_CMD17_READ_SINGLE_BLOCK; } + + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; + /* * SDSC Card (CCS=0) uses byte unit address, * SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit). @@ -1922,7 +1949,7 @@ sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, uint16_t nb_b } if (!sd_mmc_card->iface->adtc_start(cmd, arg, SD_MMC_BLOCK_SIZE, nb_block, dmaAddr)) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } // Check response @@ -1931,51 +1958,53 @@ sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, uint16_t nb_b if (resp & CARD_STATUS_ERR_RD_WR) { sd_mmc_debug("%s: Read blocks %02d resp32 0x%08x CARD_STATUS_ERR_RD_WR\n\r", __func__, (int)SDMMC_CMD_GET_INDEX(cmd), resp); - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } } - sd_mmc_nb_block_remaining = nb_block; - sd_mmc_nb_block_to_tranfer = nb_block; + sd_mmc_nb_block_remaining[slot] = nb_block; + sd_mmc_nb_block_to_tranfer[slot] = nb_block; return SD_MMC_OK; } // Start reading blocks // On entry the card is selected // If SD_MMC_OK is returned then the card is selected, otherwise it is not selected -sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block) +sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block, uint8_t slot) { Assert(sd_mmc_nb_block_remaining >= nb_block); + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->start_read_blocks(dest, nb_block)) { - sd_mmc_nb_block_remaining = 0; - sd_mmc_deselect_slot(); + sd_mmc_nb_block_remaining[slot] = 0; + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } - sd_mmc_nb_block_remaining -= nb_block; + sd_mmc_nb_block_remaining[slot] -= nb_block; return SD_MMC_OK; } // Wait until all blocks have been read // On entry the device is selected // On return it is not selected -sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort) +sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort, uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->wait_end_of_read_blocks()) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } if (abort) { - sd_mmc_nb_block_remaining = 0; - } else if (sd_mmc_nb_block_remaining) { - sd_mmc_deselect_slot(); + sd_mmc_nb_block_remaining[slot] = 0; + } else if (sd_mmc_nb_block_remaining[slot]) { + sd_mmc_deselect_slot(slot); return SD_MMC_OK; } // All blocks are transfered then stop read operation - if (sd_mmc_nb_block_to_tranfer == 1) { + if (sd_mmc_nb_block_to_tranfer[slot] == 1) { // Single block transfer, then nothing to do - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_OK; } // WORKAROUND for no compliance card (Atmel Internal ref. !MMC7 !SD19): @@ -1984,7 +2013,7 @@ sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort) if (!sd_mmc_card->iface->adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0)) { sd_mmc_card->iface->adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0); } - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_OK; } @@ -2001,7 +2030,7 @@ sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, uint16_t nb_ return sd_mmc_err; } if (sd_mmc_is_write_protected(slot)) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_WP; } @@ -2010,6 +2039,9 @@ sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, uint16_t nb_ } else { cmd = SDMMC_CMD24_WRITE_BLOCK; } + + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; + /* * SDSC Card (CCS=0) uses byte unit address, * SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit). @@ -2020,7 +2052,7 @@ sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, uint16_t nb_ arg = (start * SD_MMC_BLOCK_SIZE); } if (!sd_mmc_card->iface->adtc_start(cmd, arg, SD_MMC_BLOCK_SIZE, nb_block, dmaAddr)) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } // Check response @@ -2029,50 +2061,52 @@ sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, uint16_t nb_ if (resp & CARD_STATUS_ERR_RD_WR) { sd_mmc_debug("%s: Write blocks %02d r1 0x%08x CARD_STATUS_ERR_RD_WR\n\r", __func__, (int)SDMMC_CMD_GET_INDEX(cmd), resp); - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } } - sd_mmc_nb_block_remaining = nb_block; - sd_mmc_nb_block_to_tranfer = nb_block; + sd_mmc_nb_block_remaining[slot] = nb_block; + sd_mmc_nb_block_to_tranfer[slot] = nb_block; return SD_MMC_OK; } // Start writing blocks // On entry the card is selected // If SD_MMC_OK is returned then the card is selected, otherwise it is not selected -sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block) +sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block, uint8_t slot) { Assert(sd_mmc_nb_block_remaining >= nb_block); + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->start_write_blocks(src, nb_block)) { - sd_mmc_nb_block_remaining = 0; - sd_mmc_deselect_slot(); + sd_mmc_nb_block_remaining[slot] = 0; + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } - sd_mmc_nb_block_remaining -= nb_block; + sd_mmc_nb_block_remaining[slot] -= nb_block; return SD_MMC_OK; } // Wait until all blocks have been written // On entry the device is selected // On return it is not selected -sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort) +sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort, uint8_t slot) { + struct sd_mmc_card * const sd_mmc_card = &sd_mmc_cards[slot]; if (!sd_mmc_card->iface->wait_end_of_write_blocks()) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } if (abort) { - sd_mmc_nb_block_remaining = 0; - } else if (sd_mmc_nb_block_remaining) { - sd_mmc_deselect_slot(); + sd_mmc_nb_block_remaining[slot] = 0; + } else if (sd_mmc_nb_block_remaining[slot]) { + sd_mmc_deselect_slot(slot); return SD_MMC_OK; } // All blocks are transfered then stop write operation - if (sd_mmc_nb_block_to_tranfer == 1) { + if (sd_mmc_nb_block_to_tranfer[slot] == 1) { // Single block transfer, then nothing to do - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_OK; } @@ -2080,11 +2114,11 @@ sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort) // Note: SPI multi block writes terminate using a special // token, not a STOP_TRANSMISSION request. if (!sd_mmc_card->iface->adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0)) { - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_ERR_COMM; } } - sd_mmc_deselect_slot(); + sd_mmc_deselect_slot(slot); return SD_MMC_OK; } diff --git a/src/Libraries/sd_mmc/sd_mmc.h b/src/Libraries/sd_mmc/sd_mmc.h index a9dbcb89..619bf3a1 100644 --- a/src/Libraries/sd_mmc/sd_mmc.h +++ b/src/Libraries/sd_mmc/sd_mmc.h @@ -200,7 +200,7 @@ sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, uint16_t nb_b * \return return SD_MMC_OK if started, * otherwise return an error code (\ref sd_mmc_err_t). */ -sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block) noexcept; +sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block, uint8_t slot) noexcept; /** * \brief Wait the end of read blocks of data from the card. @@ -212,7 +212,7 @@ sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block) noexcept; * \return return SD_MMC_OK if success, * otherwise return an error code (\ref sd_mmc_err_t). */ -sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort) noexcept; +sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort, uint8_t slot) noexcept; /** * \brief Initialize the write blocks of data @@ -235,7 +235,7 @@ sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, uint16_t nb_ * \return return SD_MMC_OK if started, * otherwise return an error code (\ref sd_mmc_err_t). */ -sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block) noexcept; +sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block, uint8_t slot) noexcept; /** * \brief Wait the end of write blocks of data @@ -247,7 +247,7 @@ sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block) noexc * \return return SD_MMC_OK if success, * otherwise return an error code (\ref sd_mmc_err_t). */ -sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort) noexcept; +sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort, uint8_t slot) noexcept; #ifdef SDIO_SUPPORT_ENABLE /** diff --git a/src/Libraries/sd_mmc/sd_mmc_mem.c b/src/Libraries/sd_mmc/sd_mmc_mem.c index 52ae9a36..94c5fb95 100644 --- a/src/Libraries/sd_mmc/sd_mmc_mem.c +++ b/src/Libraries/sd_mmc/sd_mmc_mem.c @@ -107,10 +107,10 @@ Ctrl_status sd_mmc_mem_2_ram(uint8_t slot, uint32_t addr, void *ram, uint32_t nu default: return CTRL_FAIL; } - if (SD_MMC_OK != sd_mmc_start_read_blocks(ram, numBlocks)) { + if (SD_MMC_OK != sd_mmc_start_read_blocks(ram, numBlocks, slot)) { return CTRL_FAIL; } - if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) { + if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false, slot)) { return CTRL_FAIL; } return CTRL_GOOD; @@ -126,10 +126,10 @@ Ctrl_status sd_mmc_ram_2_mem(uint8_t slot, uint32_t addr, const void *ram, uint3 default: return CTRL_FAIL; } - if (SD_MMC_OK != sd_mmc_start_write_blocks(ram, numBlocks)) { + if (SD_MMC_OK != sd_mmc_start_write_blocks(ram, numBlocks, slot)) { return CTRL_FAIL; } - if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) { + if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false, slot)) { return CTRL_FAIL; } return CTRL_GOOD; |