This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/Libraries/SD_HSMCI/utility/sd_mmc_mem.c
David Crocker 611620d689 Version 1.09o-dc42
Implemented F, H and R parameters to M106 command. The second fan output
on a Duet 0.8.5 now defaults to being a thermostatic fan at power up.
Improved speed of file upload to SD card
G32 is now allowed if the printer has not been homed, if there is a
bed.g file
G30 commands are no longer allowed on a delta that has not been homed
M572 parameter P (drive number) replaced by parameter D (extruder
number)
File info requests are now processed in stages to reduce impact on
printing (thanks chrishamm)
Use latest network stack and webserver modules from chrishamm (thanks
chrishamm)
Added Roland mill support (thanks RRP/chrishamm)
Added S parameter (idle timeout) to M18 ans M84 commands (thanks
chrishamm)
Moved I/O pin assignments to separate Pins.h file to more easily support
alternative hardware (thanks dnewman)
Bug fix: filament usage and % print complete figures were incorrect when
absolute extruder coordinates were used
Bug fix: file-based print estimate was occasionally returned as 'inf'
which caused the web interface to disconnect
Bug fix: M666 now flags all towers as not homed
Bug fixes to extruder pressure compensation (M572 command).
2015-12-27 21:04:02 +00:00

369 lines
8.3 KiB
C

/**
* \file
*
* \brief CTRL_ACCESS interface for common SD/MMC stack
*
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "conf_access.h"
#if (SD_MMC_0_MEM == ENABLE) || (SD_MMC_1_MEM == ENABLE)
#include "../SD_HSMCI.h"
#include "sd_mmc.h"
#include "sd_mmc_mem.h"
/**
* \ingroup sd_mmc_stack_mem
* \defgroup sd_mmc_stack_mem_internal Implementation of SD/MMC Memory
* @{
*/
/**
* \name Control Interface
* @{
*/
static bool sd_mmc_ejected[2] = {false, false};
Ctrl_status sd_mmc_test_unit_ready(uint8_t slot)
{
switch (sd_mmc_check(slot))
{
case SD_MMC_OK:
if (sd_mmc_ejected[slot]) {
return CTRL_NO_PRESENT;
}
if (sd_mmc_get_type(slot) & (CARD_TYPE_SD | CARD_TYPE_MMC)) {
return CTRL_GOOD;
}
// It is not a memory card
return CTRL_NO_PRESENT;
case SD_MMC_INIT_ONGOING:
return CTRL_BUSY;
case SD_MMC_ERR_NO_CARD:
sd_mmc_ejected[slot] = false;
return CTRL_NO_PRESENT;
default:
return CTRL_FAIL;
}
}
Ctrl_status sd_mmc_test_unit_ready_0(void)
{
return sd_mmc_test_unit_ready(0);
}
Ctrl_status sd_mmc_test_unit_ready_1(void)
{
return sd_mmc_test_unit_ready(1);
}
Ctrl_status sd_mmc_read_capacity(uint8_t slot, uint32_t *nb_sector)
{
// Return last sector address (-1)
*nb_sector = (sd_mmc_get_capacity(slot) * 2) - 1;
return sd_mmc_test_unit_ready(slot);
}
Ctrl_status sd_mmc_read_capacity_0(uint32_t *nb_sector)
{
return sd_mmc_read_capacity(0, nb_sector);
}
Ctrl_status sd_mmc_read_capacity_1(uint32_t *nb_sector)
{
return sd_mmc_read_capacity(1, nb_sector);
}
bool sd_mmc_unload(uint8_t slot, bool unload)
{
sd_mmc_ejected[slot] = unload;
return true;
}
bool sd_mmc_unload_0(bool unload)
{
return sd_mmc_unload(0, unload);
}
bool sd_mmc_unload_1(bool unload)
{
return sd_mmc_unload(1, unload);
}
bool sd_mmc_wr_protect(uint8_t slot)
{
return sd_mmc_is_write_protected(slot);
}
bool sd_mmc_wr_protect_0(void)
{
return sd_mmc_wr_protect(0);
}
bool sd_mmc_wr_protect_1(void)
{
return sd_mmc_wr_protect(1);
}
bool sd_mmc_removal(uint8_t slot)
{
UNUSED(slot);
return true;
}
bool sd_mmc_removal_0(void)
{
return sd_mmc_removal(0);
}
bool sd_mmc_removal_1(void)
{
return sd_mmc_removal(1);
}
//! @}
#if ACCESS_USB == true
/**
* \name MEM <-> USB Interface
* @{
*/
#include "udi_msc.h"
COMPILER_WORD_ALIGNED
uint8_t sector_buf_0[SD_MMC_BLOCK_SIZE];
COMPILER_WORD_ALIGNED
uint8_t sector_buf_1[SD_MMC_BLOCK_SIZE];
Ctrl_status sd_mmc_usb_read_10(uint8_t slot, uint32_t addr, uint16_t nb_sector)
{
bool b_first_step = true;
uint16_t nb_step;
switch (sd_mmc_init_read_blocks(slot, addr, nb_sector)) {
case SD_MMC_OK:
break;
case SD_MMC_ERR_NO_CARD:
return CTRL_NO_PRESENT;
default:
return CTRL_FAIL;
}
// Pipeline the 2 transfer in order to speed-up the performances
nb_step = nb_sector + 1;
while (nb_step--) {
if (nb_step) { // Skip last step
// MCI -> RAM
if (SD_MMC_OK != sd_mmc_start_read_blocks(((nb_step % 2) == 0) ?
sector_buf_0 : sector_buf_1, 1)) {
return CTRL_FAIL;
}
}
if (!b_first_step) { // Skip first step
// RAM -> USB
if (!udi_msc_trans_block(true,
((nb_step % 2) == 0) ?
sector_buf_1 : sector_buf_0,
SD_MMC_BLOCK_SIZE,
NULL)) {
if (!b_first_step) {
sd_mmc_wait_end_of_read_blocks(true);
}
return CTRL_FAIL;
}
} else {
b_first_step = false;
}
if (nb_step) { // Skip last step
if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) {
return CTRL_FAIL;
}
}
b_first_step = false;
}
return CTRL_GOOD;
}
Ctrl_status sd_mmc_usb_read_10_0(uint32_t addr, uint16_t nb_sector)
{
return sd_mmc_usb_read_10(0, addr, nb_sector);
}
Ctrl_status sd_mmc_usb_read_10_1(uint32_t addr, uint16_t nb_sector)
{
return sd_mmc_usb_read_10(1, addr, nb_sector);
}
Ctrl_status sd_mmc_usb_write_10(uint8_t slot, uint32_t addr, uint16_t nb_sector)
{
bool b_first_step = true;
uint16_t nb_step;
switch (sd_mmc_init_write_blocks(slot, addr, nb_sector)) {
case SD_MMC_OK:
break;
case SD_MMC_ERR_NO_CARD:
return CTRL_NO_PRESENT;
default:
return CTRL_FAIL;
}
// Pipeline the 2 transfer in order to speed-up the performances
nb_step = nb_sector + 1;
while (nb_step--) {
if (!b_first_step) { // Skip first step
// RAM -> MCI
if (SD_MMC_OK != sd_mmc_start_write_blocks(((nb_step % 2) == 0) ?
sector_buf_0 : sector_buf_1, 1)) {
return CTRL_FAIL;
}
}
if (nb_step) { // Skip last step
// USB -> RAM
if (!udi_msc_trans_block(false,
((nb_step % 2) == 0) ?
sector_buf_1 : sector_buf_0,
SD_MMC_BLOCK_SIZE,
NULL)) {
if (!b_first_step) {
sd_mmc_wait_end_of_write_blocks(true);
}
return CTRL_FAIL;
}
}
if (!b_first_step) { // Skip first step
if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) {
return CTRL_FAIL;
}
} else {
b_first_step = false;
}
}
return CTRL_GOOD;
}
Ctrl_status sd_mmc_usb_write_10_0(uint32_t addr, uint16_t nb_sector)
{
return sd_mmc_usb_write_10(0, addr, nb_sector);
}
Ctrl_status sd_mmc_usb_write_10_1(uint32_t addr, uint16_t nb_sector)
{
return sd_mmc_usb_write_10(1, addr, nb_sector);
}
//! @}
#endif // ACCESS_USB == true
#if ACCESS_MEM_TO_RAM == true
/**
* \name MEM <-> RAM Interface
* @{
*/
Ctrl_status sd_mmc_mem_2_ram(uint8_t slot, uint32_t addr, void *ram, uint32_t numBlocks)
{
switch (sd_mmc_init_read_blocks(slot, addr, numBlocks)) {
case SD_MMC_OK:
break;
case SD_MMC_ERR_NO_CARD:
return CTRL_NO_PRESENT;
default:
return CTRL_FAIL;
}
if (SD_MMC_OK != sd_mmc_start_read_blocks(ram, numBlocks)) {
return CTRL_FAIL;
}
if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) {
return CTRL_FAIL;
}
return CTRL_GOOD;
}
Ctrl_status sd_mmc_mem_2_ram_0(uint32_t addr, void *ram, uint32_t numBlocks)
{
return sd_mmc_mem_2_ram(0, addr, ram, numBlocks);
}
Ctrl_status sd_mmc_mem_2_ram_1(uint32_t addr, void *ram, uint32_t numBlocks)
{
return sd_mmc_mem_2_ram(1, addr, ram, numBlocks);
}
Ctrl_status sd_mmc_ram_2_mem(uint8_t slot, uint32_t addr, const void *ram, uint32_t numBlocks)
{
switch (sd_mmc_init_write_blocks(slot, addr, numBlocks)) {
case SD_MMC_OK:
break;
case SD_MMC_ERR_NO_CARD:
return CTRL_NO_PRESENT;
default:
return CTRL_FAIL;
}
if (SD_MMC_OK != sd_mmc_start_write_blocks(ram, numBlocks)) {
return CTRL_FAIL;
}
if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) {
return CTRL_FAIL;
}
return CTRL_GOOD;
}
Ctrl_status sd_mmc_ram_2_mem_0(uint32_t addr, const void *ram, uint32_t numBlocks)
{
return sd_mmc_ram_2_mem(0, addr, ram, numBlocks);
}
Ctrl_status sd_mmc_ram_2_mem_1(uint32_t addr, const void *ram, uint32_t numBlocks)
{
return sd_mmc_ram_2_mem(1, addr, ram, numBlocks);
}
//! @}
//! @}
#endif // ACCESS_MEM_TO_RAM == true
#endif // SD_MMC_0_MEM == ENABLE || SD_MMC_1_MEM == ENABLE