
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).
336 lines
8.2 KiB
C
336 lines
8.2 KiB
C
/**
|
|
* \file
|
|
*
|
|
* \brief Implementation of low level disk I/O module skeleton for FatFS.
|
|
*
|
|
* Copyright (c) 2012 - 2013 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
|
|
*
|
|
*/
|
|
/// @cond 0
|
|
/**INDENT-OFF**/
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/**INDENT-ON**/
|
|
/// @endcond
|
|
|
|
#include "ctrl_access.h"
|
|
#include "compiler.h"
|
|
|
|
#include "diskio.h"
|
|
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
//void debugPrintf(const char*, ...);
|
|
|
|
//#if (SAM3S || SAM3U || SAM3N || SAM3XA_SERIES || SAM4S)
|
|
//# include "rtc.h"
|
|
//#endif
|
|
|
|
/**
|
|
* \defgroup thirdparty_fatfs_port_group Port of low level driver for FatFS
|
|
*
|
|
* Low level driver for FatFS. The driver is based on the ctrl access module
|
|
* of the specific MCU device.
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
/** Default sector size */
|
|
#define SECTOR_SIZE_DEFAULT 512
|
|
|
|
/** Supported sector size. These values are based on the LUN function:
|
|
* mem_sector_size(). */
|
|
#define SECTOR_SIZE_512 1
|
|
#define SECTOR_SIZE_1024 2
|
|
#define SECTOR_SIZE_2048 4
|
|
#define SECTOR_SIZE_4096 8
|
|
|
|
/**
|
|
* \brief Initialize a disk.
|
|
*
|
|
* \param drv Physical drive number (0..).
|
|
*
|
|
* \return 0 or disk status in combination of DSTATUS bits
|
|
* (STA_NOINIT, STA_PROTECT).
|
|
*/
|
|
DSTATUS disk_initialize(BYTE drv)
|
|
{
|
|
int i;
|
|
Ctrl_status mem_status;
|
|
|
|
#if (SAM3S || SAM3U || SAM3N || SAM3XA_SERIES || SAM4S)
|
|
/* Default RTC configuration, 24-hour mode */
|
|
/**@TODO FIX THIS - need an RTC*/
|
|
//rtc_set_hour_mode(RTC, 0);
|
|
#endif
|
|
|
|
#if LUN_USB
|
|
/* USB disk with multiple LUNs */
|
|
if (drv > LUN_ID_USB + Lun_usb_get_lun()) {
|
|
return STA_NOINIT;
|
|
}
|
|
#else
|
|
if (drv > MAX_LUN) {
|
|
/* At least one of the LUN should be defined */
|
|
return STA_NOINIT;
|
|
}
|
|
#endif
|
|
/* Check LUN ready (USB disk report CTRL_BUSY then CTRL_GOOD) */
|
|
for (i = 0; i < 2; i ++) {
|
|
mem_status = mem_test_unit_ready(drv);
|
|
if (CTRL_BUSY != mem_status) {
|
|
break;
|
|
}
|
|
}
|
|
if (mem_status != CTRL_GOOD) {
|
|
return STA_NOINIT;
|
|
}
|
|
|
|
/* Check Write Protection Status */
|
|
if (mem_wr_protect(drv)) {
|
|
return STA_PROTECT;
|
|
}
|
|
|
|
/* The memory should already be initialized */
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Return disk status.
|
|
*
|
|
* \param drv Physical drive number (0..).
|
|
*
|
|
* \return 0 or disk status in combination of DSTATUS bits
|
|
* (STA_NOINIT, STA_NODISK, STA_PROTECT).
|
|
*/
|
|
DSTATUS disk_status(BYTE drv)
|
|
{
|
|
switch (mem_test_unit_ready(drv)) {
|
|
case CTRL_GOOD:
|
|
return 0;
|
|
case CTRL_NO_PRESENT:
|
|
return STA_NOINIT | STA_NODISK;
|
|
default:
|
|
return STA_NOINIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read sector(s).
|
|
*
|
|
* \param drv Physical drive number (0..).
|
|
* \param buff Data buffer to store read data.
|
|
* \param sector Sector address (LBA).
|
|
* \param count Number of sectors to read (1..255).
|
|
*
|
|
* \return RES_OK for success, otherwise DRESULT error code.
|
|
*/
|
|
DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count)
|
|
{
|
|
// debugPrintf("R %u %u\n", sector, count);
|
|
#if ACCESS_MEM_TO_RAM
|
|
uint8_t uc_sector_size = mem_sector_size(drv);
|
|
uint32_t ul_last_sector_num;
|
|
|
|
if (uc_sector_size == 0) {
|
|
return RES_ERROR;
|
|
}
|
|
|
|
/* Check valid address */
|
|
mem_read_capacity(drv, &ul_last_sector_num);
|
|
if ((sector + count * uc_sector_size) > (ul_last_sector_num + 1) * uc_sector_size) {
|
|
return RES_PARERR;
|
|
}
|
|
|
|
/* Read the data */
|
|
if (memory_2_ram(drv, sector, buff, count) != CTRL_GOOD) {
|
|
return RES_ERROR;
|
|
}
|
|
|
|
return RES_OK;
|
|
|
|
#else
|
|
return RES_ERROR;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* \brief Write sector(s).
|
|
*
|
|
* The FatFs module will issue multiple sector transfer request (count > 1) to
|
|
* the disk I/O layer. The disk function should process the multiple sector
|
|
* transfer properly. Do not translate it into multiple sector transfers to the
|
|
* media, or the data read/write performance may be drastically decreased.
|
|
*
|
|
* \param drv Physical drive number (0..).
|
|
* \param buff Data buffer to store read data.
|
|
* \param sector Sector address (LBA).
|
|
* \param count Number of sectors to read (1..255).
|
|
*
|
|
* \return RES_OK for success, otherwise DRESULT error code.
|
|
*/
|
|
#if _READONLY == 0
|
|
DRESULT disk_write(BYTE drv, BYTE const *buff, DWORD sector, BYTE count)
|
|
{
|
|
// debugPrintf("W %u %u\n", sector, count);
|
|
#if ACCESS_MEM_TO_RAM
|
|
uint8_t uc_sector_size = mem_sector_size(drv);
|
|
uint32_t ul_last_sector_num;
|
|
|
|
if (uc_sector_size == 0) {
|
|
return RES_ERROR;
|
|
}
|
|
|
|
/* Check valid address */
|
|
mem_read_capacity(drv, &ul_last_sector_num);
|
|
if ((sector + count * uc_sector_size) >
|
|
(ul_last_sector_num + 1) * uc_sector_size) {
|
|
return RES_PARERR;
|
|
}
|
|
|
|
/* Write the data */
|
|
if (ram_2_memory(drv, sector, buff, count) != CTRL_GOOD) {
|
|
return RES_ERROR;
|
|
}
|
|
|
|
return RES_OK;
|
|
|
|
#else
|
|
return RES_ERROR;
|
|
#endif
|
|
}
|
|
|
|
#endif /* _READONLY */
|
|
|
|
/**
|
|
* \brief Miscellaneous functions, which support the following commands:
|
|
*
|
|
* CTRL_SYNC Make sure that the disk drive has finished pending write
|
|
* process. When the disk I/O module has a write back cache, flush the
|
|
* dirty sector immediately.
|
|
* In read-only configuration, this command is not needed.
|
|
*
|
|
* GET_SECTOR_COUNT Return total sectors on the drive into the DWORD variable
|
|
* pointed by buffer.
|
|
* This command is used only in f_mkfs function.
|
|
*
|
|
* GET_BLOCK_SIZE Return erase block size of the memory array in unit
|
|
* of sector into the DWORD variable pointed by Buffer.
|
|
* When the erase block size is unknown or magnetic disk device, return 1.
|
|
* This command is used only in f_mkfs function.
|
|
*
|
|
* GET_SECTOR_SIZE Return sector size of the memory array.
|
|
*
|
|
* \param drv Physical drive number (0..).
|
|
* \param ctrl Control code.
|
|
* \param buff Buffer to send/receive control data.
|
|
*
|
|
* \return RES_OK for success, otherwise DRESULT error code.
|
|
*/
|
|
DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
|
|
{
|
|
DRESULT res = RES_PARERR;
|
|
|
|
switch (ctrl) {
|
|
case GET_BLOCK_SIZE:
|
|
*(DWORD *)buff = 1;
|
|
res = RES_OK;
|
|
break;
|
|
|
|
/* Get the number of sectors on the disk (DWORD) */
|
|
case GET_SECTOR_COUNT:
|
|
{
|
|
uint32_t ul_last_sector_num;
|
|
|
|
/* Check valid address */
|
|
mem_read_capacity(drv, &ul_last_sector_num);
|
|
|
|
*(DWORD *)buff = ul_last_sector_num + 1;
|
|
|
|
res = RES_OK;
|
|
}
|
|
break;
|
|
|
|
/* Get sectors on the disk (WORD) */
|
|
case GET_SECTOR_SIZE:
|
|
{
|
|
uint8_t uc_sector_size = mem_sector_size(drv);
|
|
|
|
if ((uc_sector_size != SECTOR_SIZE_512) &&
|
|
(uc_sector_size != SECTOR_SIZE_1024) &&
|
|
(uc_sector_size != SECTOR_SIZE_2048) &&
|
|
(uc_sector_size != SECTOR_SIZE_4096)) {
|
|
/* The sector size is not supported by the FatFS */
|
|
return RES_ERROR;
|
|
}
|
|
|
|
*(U8 *)buff = uc_sector_size * SECTOR_SIZE_DEFAULT;
|
|
|
|
res = RES_OK;
|
|
}
|
|
break;
|
|
|
|
/* Make sure that data has been written */
|
|
case CTRL_SYNC:
|
|
if (mem_test_unit_ready(drv) == CTRL_GOOD) {
|
|
res = RES_OK;
|
|
} else {
|
|
res = RES_NOTRDY;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
res = RES_PARERR;
|
|
break;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
//@}
|
|
|
|
/// @cond 0
|
|
/**INDENT-OFF**/
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
/**INDENT-ON**/
|
|
/// @endcond
|