Merge pull request #1939 from bthebaudeau/re-mote-sd-fat
Add global SD/MMC and FAT support, with RE-Mote as an example
This commit is contained in:
commit
bd3f8fa3c5
|
@ -100,6 +100,20 @@ typedef void (* gpio_callback_t)(uint8_t port, uint8_t pin);
|
|||
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK) \
|
||||
do { REG((PORT_BASE) + GPIO_DIR) |= (PIN_MASK); } while(0)
|
||||
|
||||
/** \brief Return whether pins with PIN_MASK of port with PORT_BASE are set to
|
||||
* output.
|
||||
* \param PORT_BASE GPIO Port register offset
|
||||
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
||||
* \return The direction of the pins specified by PIN_MASK
|
||||
*
|
||||
* This macro will \e not return 0 or 1. Instead, it will return the directions
|
||||
* of the pins specified by PIN_MASK ORed together. Thus, if 0xC3
|
||||
* (0x80 | 0x40 | 0x02 | 0x01) is passed as the PIN_MASK and pins 7 and 0 are
|
||||
* set to output, the macro will return 0x81.
|
||||
*/
|
||||
#define GPIO_IS_OUTPUT(PORT_BASE, PIN_MASK) \
|
||||
(REG((PORT_BASE) + GPIO_DIR) & (PIN_MASK))
|
||||
|
||||
/** \brief Set pins with PIN_MASK of port with PORT_BASE high.
|
||||
* \param PORT_BASE GPIO Port register offset
|
||||
* \param PIN_MASK Pin number mask. Pin 0: 0x01, Pin 1: 0x02 ... Pin 7: 0x80
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "contiki.h"
|
||||
#include "reg.h"
|
||||
#include "spi-arch.h"
|
||||
#include "sys/cc.h"
|
||||
#include "dev/ioc.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/spi.h"
|
||||
|
@ -155,7 +156,12 @@
|
|||
#if (SPI1_CPRS_CPSDVSR & 1) == 1 || SPI1_CPRS_CPSDVSR < 2 || SPI1_CPRS_CPSDVSR > 254
|
||||
#error SPI1_CPRS_CPSDVSR must be an even number between 2 and 254
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Clock source from which the baud clock is determined for the SSI, according
|
||||
* to SSI_CC.CS.
|
||||
*/
|
||||
#define SSI_SYS_CLOCK SYS_CTRL_SYS_CLOCK
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
int8_t port;
|
||||
|
@ -314,6 +320,37 @@ spix_set_mode(uint8_t spi,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spix_set_clock_freq(uint8_t spi, uint32_t freq)
|
||||
{
|
||||
const spi_regs_t *regs;
|
||||
uint64_t div;
|
||||
uint32_t scr;
|
||||
|
||||
if(spi >= SSI_INSTANCE_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
regs = &spi_regs[spi];
|
||||
|
||||
/* Disable the SSI peripheral to configure it */
|
||||
REG(regs->base + SSI_CR1) = 0;
|
||||
|
||||
/* Configure the SSI serial clock rate */
|
||||
if(!freq) {
|
||||
scr = 255;
|
||||
} else {
|
||||
div = (uint64_t)regs->ssi_cprs_cpsdvsr * freq;
|
||||
scr = (SSI_SYS_CLOCK + div - 1) / div;
|
||||
scr = MIN(MAX(scr, 1), 256) - 1;
|
||||
}
|
||||
REG(regs->base + SSI_CR0) = (REG(regs->base + SSI_CR0) & ~SSI_CR0_SCR_M) |
|
||||
scr << SSI_CR0_SCR_S;
|
||||
|
||||
/* Re-enable the SSI */
|
||||
REG(regs->base + SSI_CR1) |= SSI_CR1_SSE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
spix_cs_init(uint8_t port, uint8_t pin)
|
||||
{
|
||||
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port),
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
*/
|
||||
#define SSI0_BASE 0x40008000 /**< Base address for SSI0 */
|
||||
#define SSI1_BASE 0x40009000 /**< Base address for SSI1 */
|
||||
/** Base address of the \c dev instance of the SSI */
|
||||
#define SSI_BASE(dev) (SSI0_BASE + (dev) * (SSI1_BASE - SSI0_BASE))
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name SSI register offsets
|
||||
|
|
|
@ -109,17 +109,17 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* New API macros */
|
||||
#define SPIX_WAITFORTxREADY(spi) do { \
|
||||
while(!(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_TNF)) ; \
|
||||
while(!(REG(SSI_BASE(spi) + SSI_SR) & SSI_SR_TNF)) ; \
|
||||
} while(0)
|
||||
#define SPIX_BUF(spi) REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_DR)
|
||||
#define SPIX_BUF(spi) REG(SSI_BASE(spi) + SSI_DR)
|
||||
#define SPIX_WAITFOREOTx(spi) do { \
|
||||
while(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_BSY) ; \
|
||||
while(REG(SSI_BASE(spi) + SSI_SR) & SSI_SR_BSY) ; \
|
||||
} while(0)
|
||||
#define SPIX_WAITFOREORx(spi) do { \
|
||||
while(!(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_RNE)) ; \
|
||||
while(!(REG(SSI_BASE(spi) + SSI_SR) & SSI_SR_RNE)) ; \
|
||||
} while(0)
|
||||
#define SPIX_FLUSH(spi) do { \
|
||||
while(REG(CC_CONCAT3(SSI, spi, _BASE) + SSI_SR) & SSI_SR_RNE) { \
|
||||
while(REG(SSI_BASE(spi) + SSI_SR) & SSI_SR_RNE) { \
|
||||
SPIX_BUF(spi); \
|
||||
} \
|
||||
} while(0)
|
||||
|
@ -197,6 +197,14 @@ void spix_set_mode(uint8_t spi, uint32_t frame_format,
|
|||
uint32_t clock_polarity, uint32_t clock_phase,
|
||||
uint32_t data_size);
|
||||
|
||||
/**
|
||||
* \brief Sets the SPI clock frequency of the given SSI instance.
|
||||
*
|
||||
* \param spi SSI instance
|
||||
* \param freq Frequency (Hz)
|
||||
*/
|
||||
void spix_set_clock_freq(uint8_t spi, uint32_t freq);
|
||||
|
||||
/**
|
||||
* \brief Configure a GPIO to be the chip select pin.
|
||||
*
|
||||
|
|
98
dev/disk/disk.h
Normal file
98
dev/disk/disk.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup dev
|
||||
* @{
|
||||
*
|
||||
* \defgroup disk Disk device drivers
|
||||
*
|
||||
* Documentation for all the disk device drivers.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file defining the disk device driver API.
|
||||
*/
|
||||
#ifndef DISK_H_
|
||||
#define DISK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Disk status flags. */
|
||||
typedef enum {
|
||||
DISK_STATUS_INIT = 0x01, /**< Device initialized and ready to work */
|
||||
DISK_STATUS_DISK = 0x02, /**< Medium present in the drive */
|
||||
DISK_STATUS_WRITABLE = 0x04 /**< Writable medium */
|
||||
} disk_status_t;
|
||||
|
||||
/** Generic disk I/O control commands. */
|
||||
typedef enum {
|
||||
DISK_IOCTL_CTRL_SYNC, /**< Synchronize the cached writes to persistent storage */
|
||||
DISK_IOCTL_GET_SECTOR_COUNT, /**< Get the sector count through the \c uint32_t pointed to by \c buff */
|
||||
DISK_IOCTL_GET_SECTOR_SIZE, /**< Get the sector size through the \c uint16_t pointed to by \c buff */
|
||||
DISK_IOCTL_GET_BLOCK_SIZE, /**< Get the erase block size (in sectors) through the \c uint32_t pointed to by \c buff */
|
||||
DISK_IOCTL_CTRL_TRIM /**< Trim the sector range within the \c uint32_t boundaries pointed to by \c buff */
|
||||
} disk_ioctl_t;
|
||||
|
||||
/** Disk access result codes. */
|
||||
typedef enum {
|
||||
DISK_RESULT_OK, /**< Success */
|
||||
DISK_RESULT_IO_ERROR, /**< Unrecoverable I/O error */
|
||||
DISK_RESULT_WR_PROTECTED, /**< Write-protected medium */
|
||||
DISK_RESULT_NO_INIT, /**< Device not initialized */
|
||||
DISK_RESULT_INVALID_ARG /**< Invalid argument */
|
||||
} disk_result_t;
|
||||
|
||||
/** Disk driver API structure. */
|
||||
struct disk_driver {
|
||||
/** Get device status. */
|
||||
disk_status_t (*status)(uint8_t dev);
|
||||
|
||||
/** Initialize device. */
|
||||
disk_status_t (*initialize)(uint8_t dev);
|
||||
|
||||
/** Read sector(s). */
|
||||
disk_result_t (*read)(uint8_t dev, void *buff, uint32_t sector,
|
||||
uint32_t count);
|
||||
|
||||
/** Write sector(s). */
|
||||
disk_result_t (*write)(uint8_t dev, const void *buff, uint32_t sector,
|
||||
uint32_t count);
|
||||
|
||||
/** Control device-specific features. */
|
||||
disk_result_t (*ioctl)(uint8_t dev, uint8_t cmd, void *buff);
|
||||
};
|
||||
|
||||
#endif /* DISK_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
98
dev/disk/mmc/mmc-arch.h
Normal file
98
dev/disk/mmc/mmc-arch.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup mmc
|
||||
* @{
|
||||
*
|
||||
* \defgroup mmc-arch SD/MMC architecture-specific definitions
|
||||
*
|
||||
* SD/MMC device driver architecture-specific definitions.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the SD/MMC device driver architecture-specific definitions.
|
||||
*/
|
||||
#ifndef MMC_ARCH_H_
|
||||
#define MMC_ARCH_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** \brief Callback of the SD/MMC driver to call when the card-detection signal
|
||||
* changes.
|
||||
* \param dev Device
|
||||
* \param cd Whether a card is detected
|
||||
* \note Using this function is not mandatory. This only allows to detect a card
|
||||
* replacement between two successive calls to the SD/MMC driver API.
|
||||
*/
|
||||
void mmc_arch_cd_changed_callback(uint8_t dev, bool cd);
|
||||
|
||||
/** \brief Gets the state of the card-detection signal.
|
||||
* \param dev Device
|
||||
* \return Whether a card is detected
|
||||
*/
|
||||
bool mmc_arch_get_cd(uint8_t dev);
|
||||
|
||||
/** \brief Gets the state of the write-protection signal.
|
||||
* \param dev Device
|
||||
* \return Whether the card is write-protected
|
||||
*/
|
||||
bool mmc_arch_get_wp(uint8_t dev);
|
||||
|
||||
/** \brief Sets the SPI /CS signal as indicated.
|
||||
* \param dev Device
|
||||
* \param sel Whether to assert /CS
|
||||
*/
|
||||
void mmc_arch_spi_select(uint8_t dev, bool sel);
|
||||
|
||||
/** \brief Sets the SPI clock frequency.
|
||||
* \param dev Device
|
||||
* \param freq Frequency (Hz)
|
||||
*/
|
||||
void mmc_arch_spi_set_clock_freq(uint8_t dev, uint32_t freq);
|
||||
|
||||
/** \brief Performs an SPI transfer.
|
||||
* \param dev Device
|
||||
* \param tx_buf Pointer to the transmission buffer, or \c NULL
|
||||
* \param tx_cnt Number of bytes to transmit, or \c 0
|
||||
* \param rx_buf Pointer to the reception buffer, or \c NULL
|
||||
* \param rx_cnt Number of bytes to receive, or \c 0
|
||||
*/
|
||||
void mmc_arch_spi_xfer(uint8_t dev, const void *tx_buf, size_t tx_cnt,
|
||||
void *rx_buf, size_t rx_cnt);
|
||||
|
||||
#endif /* MMC_ARCH_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
608
dev/disk/mmc/mmc.c
Normal file
608
dev/disk/mmc/mmc.c
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on the FatFs Module STM32 Sample Project,
|
||||
* Copyright (c) 2014, ChaN
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup mmc
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the SD/MMC device driver.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "contiki.h"
|
||||
#include "sys/clock.h"
|
||||
#include "sys/rtimer.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "mmc-arch.h"
|
||||
#include "mmc.h"
|
||||
|
||||
/* Data read/write block length */
|
||||
#define BLOCK_LEN 512
|
||||
/*
|
||||
* Logical sector size exposed to the disk API, not to be confused with the SDSC
|
||||
* sector size, which is the size of an erasable sector
|
||||
*/
|
||||
#define SECTOR_SIZE BLOCK_LEN
|
||||
|
||||
/* Clock frequency in card identification mode: fOD <= 400 kHz */
|
||||
#define CLOCK_FREQ_CARD_ID_MODE 400000
|
||||
/*
|
||||
* Clock frequency in data transfer mode: fPP <= 20 MHz, limited by the
|
||||
* backward-compatible MMC interface timings
|
||||
*/
|
||||
#define CLOCK_FREQ_DATA_XFER_MODE 20000000
|
||||
|
||||
/* SPI-mode command list */
|
||||
#define CMD0 0 /* GO_IDLE_STATE */
|
||||
#define CMD1 1 /* SEND_OP_COND */
|
||||
#define CMD8 8 /* SEND_IF_COND */
|
||||
#define CMD8_VHS_2_7_3_6 0x1
|
||||
#define CMD8_ARG(vhs, check_pattern) ((vhs) << 8 | (check_pattern))
|
||||
#define CMD8_ECHO_MASK 0x00000fff
|
||||
#define CMD9 9 /* SEND_CSD */
|
||||
#define CMD10 10 /* SEND_CID */
|
||||
#define CMD12 12 /* STOP_TRANSMISSION */
|
||||
#define CMD13 13 /* SEND_STATUS */
|
||||
#define CMD16 16 /* SET_BLOCKLEN */
|
||||
#define CMD17 17 /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 18 /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 23 /* SET_BLOCK_COUNT */
|
||||
#define CMD24 24 /* WRITE_BLOCK */
|
||||
#define CMD25 25 /* WRITE_MULTIPLE_BLOCK */
|
||||
#define CMD32 32 /* ERASE_WR_BLK_START */
|
||||
#define CMD33 33 /* ERASE_WR_BLK_END */
|
||||
#define CMD38 38 /* ERASE */
|
||||
#define CMD55 55 /* APP_CMD */
|
||||
#define CMD58 58 /* READ_OCR */
|
||||
#define ACMD 0x80 /* Application-specific command */
|
||||
#define ACMD13 (ACMD | 13) /* SD_STATUS */
|
||||
#define ACMD23 (ACMD | 23) /* SET_WR_BLK_ERASE_COUNT */
|
||||
#define ACMD41 (ACMD | 41) /* SD_APP_OP_COND */
|
||||
#define ACMD41_HCS (1 << 30)
|
||||
|
||||
#define CMD_TX 0x40 /* Command transmission bit */
|
||||
|
||||
#define R1_MSB 0x00
|
||||
#define R1_SUCCESS 0x00
|
||||
#define R1_IDLE_STATE (1 << 0)
|
||||
#define R1_ERASE_RESET (1 << 1)
|
||||
#define R1_ILLEGAL_COMMAND (1 << 2)
|
||||
#define R1_COM_CRC_ERROR (1 << 3)
|
||||
#define R1_ERASE_SEQUENCE_ERROR (1 << 4)
|
||||
#define R1_ADDRESS_ERROR (1 << 5)
|
||||
#define R1_PARAMETER_ERROR (1 << 6)
|
||||
|
||||
#define TOK_DATA_RESP_MASK 0x1f
|
||||
#define TOK_DATA_RESP_ACCEPTED 0x05
|
||||
#define TOK_DATA_RESP_CRC_ERROR 0x0b
|
||||
#define TOK_DATA_RESP_WR_ERROR 0x0d
|
||||
#define TOK_RD_SINGLE_WR_START_BLOCK 0xfe
|
||||
#define TOK_MULTI_WR_START_BLOCK 0xfc
|
||||
#define TOK_MULTI_WR_STOP_TRAN 0xfd
|
||||
|
||||
/* The SD Status is one data block of 512 bits. */
|
||||
#define SD_STATUS_SIZE (512 / 8)
|
||||
#define SD_STATUS_AU_SIZE(sd_status) ((sd_status)[10] >> 4)
|
||||
|
||||
#define OCR_CCS (1 << 30)
|
||||
|
||||
#define CSD_SIZE 16
|
||||
#define CSD_STRUCTURE(csd) ((csd)[0] >> 6)
|
||||
#define CSD_STRUCTURE_SD_V1_0 0
|
||||
#define CSD_STRUCTURE_SD_V2_0 1
|
||||
#define CSD_SD_V1_0_READ_BL_LEN(csd) ((csd)[5] & 0x0f)
|
||||
#define CSD_SD_V1_0_BLOCK_LEN(csd) (1ull << CSD_SD_V1_0_READ_BL_LEN(csd))
|
||||
#define CSD_SD_V1_0_C_SIZE(csd) \
|
||||
(((csd)[6] & 0x03) << 10 | (csd)[7] << 2 | (csd)[8] >> 6)
|
||||
#define CSD_SD_V1_0_C_SIZE_MULT(csd) \
|
||||
(((csd)[9] & 0x03) << 1 | (csd)[10] >> 7)
|
||||
#define CSD_SD_V1_0_MULT(csd) \
|
||||
(1 << (CSD_SD_V1_0_C_SIZE_MULT(csd) + 2))
|
||||
#define CSD_SD_V1_0_BLOCKNR(csd) \
|
||||
(((uint32_t)CSD_SD_V1_0_C_SIZE(csd) + 1) * CSD_SD_V1_0_MULT(csd))
|
||||
#define CSD_SD_V1_0_CAPACITY(csd) \
|
||||
(CSD_SD_V1_0_BLOCKNR(csd) * CSD_SD_V1_0_BLOCK_LEN(csd))
|
||||
#define CSD_SD_V1_0_SECTOR_SIZE(csd) \
|
||||
(((csd)[10] & 0x3f) << 1 | (csd)[11] >> 7)
|
||||
#define CSD_SD_V1_0_WRITE_BL_LEN(csd) \
|
||||
(((csd)[12] & 0x03) << 2 | (csd)[13] >> 6)
|
||||
#define CSD_SD_V2_0_C_SIZE(csd) \
|
||||
(((csd)[7] & 0x3f) << 16 | (csd)[8] << 8 | (csd)[9])
|
||||
#define CSD_SD_V2_0_CAPACITY(csd) \
|
||||
(((uint64_t)CSD_SD_V2_0_C_SIZE(csd) + 1) << 19)
|
||||
#define CSD_MMC_ERASE_GRP_SIZE(csd) (((csd)[10] & 0x7c) >> 2)
|
||||
#define CSD_MMC_ERASE_GRP_MULT(csd) \
|
||||
(((csd)[10] & 0x03) << 3 | (csd)[11] >> 5)
|
||||
#define CSD_MMC_WRITE_BL_LEN(csd) \
|
||||
(((csd)[12] & 0x03) << 2 | (csd)[13] >> 6)
|
||||
|
||||
typedef enum {
|
||||
CARD_TYPE_MMC = 0x01, /* MMC v3 */
|
||||
CARD_TYPE_SD1 = 0x02, /* SD v1 */
|
||||
CARD_TYPE_SD2 = 0x04, /* SD v2 */
|
||||
CARD_TYPE_SD = CARD_TYPE_SD1 | CARD_TYPE_SD2, /* SD */
|
||||
CARD_TYPE_BLOCK = 0x08 /* Block addressing */
|
||||
} card_type_t;
|
||||
|
||||
static struct mmc_priv {
|
||||
uint8_t status;
|
||||
uint8_t card_type;
|
||||
} mmc_priv[MMC_CONF_DEV_COUNT];
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
mmc_spi_xchg(uint8_t dev, uint8_t tx_byte)
|
||||
{
|
||||
uint8_t rx_byte;
|
||||
|
||||
mmc_arch_spi_xfer(dev, &tx_byte, 1, &rx_byte, 1);
|
||||
return rx_byte;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
mmc_spi_tx(uint8_t dev, const void *buf, size_t cnt)
|
||||
{
|
||||
mmc_arch_spi_xfer(dev, buf, cnt, NULL, 0);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
mmc_spi_rx(uint8_t dev, void *buf, size_t cnt)
|
||||
{
|
||||
mmc_arch_spi_xfer(dev, NULL, 0, buf, cnt);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static bool
|
||||
mmc_wait_ready(uint8_t dev, uint16_t timeout_ms)
|
||||
{
|
||||
rtimer_clock_t timeout_end =
|
||||
RTIMER_NOW() + ((uint32_t)timeout_ms * RTIMER_SECOND + 999) / 1000;
|
||||
uint8_t rx_byte;
|
||||
|
||||
do {
|
||||
rx_byte = mmc_spi_xchg(dev, 0xff);
|
||||
watchdog_periodic();
|
||||
} while(rx_byte != 0xff && RTIMER_CLOCK_LT(RTIMER_NOW(), timeout_end));
|
||||
return rx_byte == 0xff;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static bool
|
||||
mmc_select(uint8_t dev, bool sel)
|
||||
{
|
||||
mmc_arch_spi_select(dev, sel);
|
||||
mmc_spi_xchg(dev, 0xff); /* Dummy clock (force D0) */
|
||||
if(sel && !mmc_wait_ready(dev, 500)) {
|
||||
mmc_select(dev, false);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
mmc_send_cmd(uint8_t dev, uint8_t cmd, uint32_t arg)
|
||||
{
|
||||
uint8_t resp, n;
|
||||
|
||||
/* Send a CMD55 prior to a ACMD<n>. */
|
||||
if(cmd & ACMD) {
|
||||
cmd &= ~ACMD;
|
||||
resp = mmc_send_cmd(dev, CMD55, 0);
|
||||
if(resp != R1_SUCCESS && resp != R1_IDLE_STATE) {
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Select the card and wait for ready, except to stop a multiple-block read.
|
||||
*/
|
||||
if(cmd != CMD12) {
|
||||
mmc_select(dev, false);
|
||||
if(!mmc_select(dev, true)) {
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the command packet. */
|
||||
mmc_spi_xchg(dev, CMD_TX | cmd); /* Start & tx bits, cmd index */
|
||||
mmc_spi_xchg(dev, arg >> 24); /* Argument[31..24] */
|
||||
mmc_spi_xchg(dev, arg >> 16); /* Argument[23..16] */
|
||||
mmc_spi_xchg(dev, arg >> 8); /* Argument[15..8] */
|
||||
mmc_spi_xchg(dev, arg); /* Argument[7..0] */
|
||||
switch(cmd) {
|
||||
case CMD0:
|
||||
n = 0x95; /* CMD0(0) CRC7, end bit */
|
||||
break;
|
||||
case CMD8:
|
||||
n = 0x87; /* CMD8(0x1aa) CRC7, end bit */
|
||||
break;
|
||||
default:
|
||||
n = 0x01; /* Dummy CRC7, end bit */
|
||||
break;
|
||||
}
|
||||
mmc_spi_xchg(dev, n);
|
||||
|
||||
/* Receive the command response. */
|
||||
if(cmd == CMD12) {
|
||||
mmc_spi_xchg(dev, 0xff); /* Discard following byte if CMD12. */
|
||||
}
|
||||
/* Wait for the response (max. 10 bytes). */
|
||||
n = 10;
|
||||
do {
|
||||
resp = mmc_spi_xchg(dev, 0xff);
|
||||
} while((resp & 0x80) != R1_MSB && --n);
|
||||
return resp;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static bool
|
||||
mmc_tx_block(uint8_t dev, const void *buf, uint8_t token)
|
||||
{
|
||||
uint8_t resp;
|
||||
|
||||
if(!mmc_wait_ready(dev, 500)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mmc_spi_xchg(dev, token);
|
||||
if(token != TOK_MULTI_WR_STOP_TRAN) {
|
||||
mmc_spi_tx(dev, buf, BLOCK_LEN);
|
||||
mmc_spi_xchg(dev, 0xff); /* Dummy CRC */
|
||||
mmc_spi_xchg(dev, 0xff);
|
||||
|
||||
resp = mmc_spi_xchg(dev, 0xff);
|
||||
if((resp & TOK_DATA_RESP_MASK) != TOK_DATA_RESP_ACCEPTED) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static bool
|
||||
mmc_rx(uint8_t dev, void *buf, size_t cnt)
|
||||
{
|
||||
rtimer_clock_t timeout_end =
|
||||
RTIMER_NOW() + (200ul * RTIMER_SECOND + 999) / 1000;
|
||||
uint8_t token;
|
||||
|
||||
do {
|
||||
token = mmc_spi_xchg(dev, 0xff);
|
||||
watchdog_periodic();
|
||||
} while(token == 0xff && RTIMER_CLOCK_LT(RTIMER_NOW(), timeout_end));
|
||||
if(token != TOK_RD_SINGLE_WR_START_BLOCK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mmc_spi_rx(dev, buf, cnt);
|
||||
mmc_spi_xchg(dev, 0xff); /* Discard CRC. */
|
||||
mmc_spi_xchg(dev, 0xff);
|
||||
return true;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mmc_arch_cd_changed_callback(uint8_t dev, bool cd)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
if(dev >= MMC_CONF_DEV_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(cd) {
|
||||
status = DISK_STATUS_DISK;
|
||||
if(!mmc_arch_get_wp(dev)) {
|
||||
status |= DISK_STATUS_WRITABLE;
|
||||
}
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
mmc_priv[dev].status = status;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static disk_status_t
|
||||
mmc_status(uint8_t dev)
|
||||
{
|
||||
bool cd;
|
||||
struct mmc_priv *priv;
|
||||
|
||||
if(dev >= MMC_CONF_DEV_COUNT) {
|
||||
return DISK_RESULT_INVALID_ARG;
|
||||
}
|
||||
|
||||
cd = mmc_arch_get_cd(dev);
|
||||
priv = &mmc_priv[dev];
|
||||
if(cd == !(priv->status & DISK_STATUS_DISK)) {
|
||||
mmc_arch_cd_changed_callback(dev, cd);
|
||||
}
|
||||
return priv->status;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static disk_status_t
|
||||
mmc_initialize(uint8_t dev)
|
||||
{
|
||||
disk_status_t status;
|
||||
uint8_t n, cmd;
|
||||
card_type_t card_type;
|
||||
rtimer_clock_t timeout_end;
|
||||
uint32_t arg, resp, ocr;
|
||||
struct mmc_priv *priv;
|
||||
|
||||
if(dev >= MMC_CONF_DEV_COUNT) {
|
||||
return DISK_RESULT_INVALID_ARG;
|
||||
}
|
||||
status = mmc_status(dev);
|
||||
if(!(status & DISK_STATUS_DISK)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
mmc_arch_spi_select(dev, false);
|
||||
clock_delay_usec(10000);
|
||||
|
||||
mmc_arch_spi_set_clock_freq(dev, CLOCK_FREQ_CARD_ID_MODE);
|
||||
for(n = 10; n; n--) {
|
||||
mmc_spi_xchg(dev, 0xff); /* Generate 80 dummy clock cycles. */
|
||||
}
|
||||
|
||||
card_type = 0;
|
||||
if(mmc_send_cmd(dev, CMD0, 0) == R1_IDLE_STATE) {
|
||||
timeout_end = RTIMER_NOW() + RTIMER_SECOND;
|
||||
arg = CMD8_ARG(CMD8_VHS_2_7_3_6, 0xaa); /* Arbitrary check pattern */
|
||||
if(mmc_send_cmd(dev, CMD8, arg) == R1_IDLE_STATE) { /* SD v2? */
|
||||
resp = 0;
|
||||
for(n = 4; n; n--) {
|
||||
resp = resp << 8 | mmc_spi_xchg(dev, 0xff);
|
||||
}
|
||||
/* Does the card support 2.7 V - 3.6 V? */
|
||||
if((arg & CMD8_ECHO_MASK) == (resp & CMD8_ECHO_MASK)) {
|
||||
/* Wait for end of initialization. */
|
||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), timeout_end) &&
|
||||
mmc_send_cmd(dev, ACMD41, ACMD41_HCS) != R1_SUCCESS) {
|
||||
watchdog_periodic();
|
||||
}
|
||||
if(RTIMER_CLOCK_LT(RTIMER_NOW(), timeout_end) &&
|
||||
mmc_send_cmd(dev, CMD58, 0) == R1_SUCCESS) { /* Read OCR. */
|
||||
ocr = 0;
|
||||
for(n = 4; n; n--) {
|
||||
ocr = ocr << 8 | mmc_spi_xchg(dev, 0xff);
|
||||
}
|
||||
card_type = CARD_TYPE_SD2;
|
||||
if(ocr & OCR_CCS) {
|
||||
card_type |= CARD_TYPE_BLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* Not SD v2 */
|
||||
resp = mmc_send_cmd(dev, ACMD41, 0);
|
||||
if(resp == R1_SUCCESS || resp == R1_IDLE_STATE) { /* SD v1 or MMC? */
|
||||
card_type = CARD_TYPE_SD1;
|
||||
cmd = ACMD41;
|
||||
} else {
|
||||
card_type = CARD_TYPE_MMC;
|
||||
cmd = CMD1;
|
||||
}
|
||||
/* Wait for end of initialization. */
|
||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), timeout_end) &&
|
||||
mmc_send_cmd(dev, cmd, 0) != R1_SUCCESS) {
|
||||
watchdog_periodic();
|
||||
}
|
||||
/* Set block length. */
|
||||
if(!RTIMER_CLOCK_LT(RTIMER_NOW(), timeout_end) ||
|
||||
mmc_send_cmd(dev, CMD16, BLOCK_LEN) != R1_SUCCESS) {
|
||||
card_type = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
priv = &mmc_priv[dev];
|
||||
priv->card_type = card_type;
|
||||
mmc_select(dev, false);
|
||||
|
||||
status = priv->status;
|
||||
if(status & DISK_STATUS_DISK && card_type) { /* OK */
|
||||
mmc_arch_spi_set_clock_freq(dev, CLOCK_FREQ_DATA_XFER_MODE);
|
||||
status |= DISK_STATUS_INIT;
|
||||
} else { /* Failed */
|
||||
status &= ~DISK_STATUS_INIT;
|
||||
}
|
||||
priv->status = status;
|
||||
return status;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static disk_result_t
|
||||
mmc_read(uint8_t dev, void *buff, uint32_t sector, uint32_t count)
|
||||
{
|
||||
if(dev >= MMC_CONF_DEV_COUNT || !count) {
|
||||
return DISK_RESULT_INVALID_ARG;
|
||||
}
|
||||
if(!(mmc_status(dev) & DISK_STATUS_INIT)) {
|
||||
return DISK_RESULT_NO_INIT;
|
||||
}
|
||||
|
||||
if(!(mmc_priv[dev].card_type & CARD_TYPE_BLOCK)) {
|
||||
sector *= SECTOR_SIZE;
|
||||
}
|
||||
|
||||
if(count == 1) {
|
||||
if(mmc_send_cmd(dev, CMD17, sector) == R1_SUCCESS &&
|
||||
mmc_rx(dev, buff, SECTOR_SIZE)) {
|
||||
count = 0;
|
||||
}
|
||||
} else if(mmc_send_cmd(dev, CMD18, sector) == R1_SUCCESS) {
|
||||
do {
|
||||
if(!mmc_rx(dev, buff, SECTOR_SIZE)) {
|
||||
break;
|
||||
}
|
||||
buff = (uint8_t *)buff + SECTOR_SIZE;
|
||||
watchdog_periodic();
|
||||
} while(--count);
|
||||
mmc_send_cmd(dev, CMD12, 0); /* Stop transmission. */
|
||||
}
|
||||
mmc_select(dev, false);
|
||||
return count ? DISK_RESULT_IO_ERROR : DISK_RESULT_OK;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static disk_result_t
|
||||
mmc_write(uint8_t dev, const void *buff, uint32_t sector, uint32_t count)
|
||||
{
|
||||
disk_status_t status;
|
||||
card_type_t card_type;
|
||||
|
||||
if(dev >= MMC_CONF_DEV_COUNT || !count) {
|
||||
return DISK_RESULT_INVALID_ARG;
|
||||
}
|
||||
status = mmc_status(dev);
|
||||
if(!(status & DISK_STATUS_INIT)) {
|
||||
return DISK_RESULT_NO_INIT;
|
||||
}
|
||||
if(!(status & DISK_STATUS_WRITABLE)) {
|
||||
return DISK_RESULT_WR_PROTECTED;
|
||||
}
|
||||
|
||||
card_type = mmc_priv[dev].card_type;
|
||||
if(!(card_type & CARD_TYPE_BLOCK)) {
|
||||
sector *= SECTOR_SIZE;
|
||||
}
|
||||
|
||||
if(count == 1) {
|
||||
if(mmc_send_cmd(dev, CMD24, sector) == R1_SUCCESS &&
|
||||
mmc_tx_block(dev, buff, TOK_RD_SINGLE_WR_START_BLOCK)) {
|
||||
count = 0;
|
||||
}
|
||||
} else {
|
||||
if(card_type & CARD_TYPE_SD) {
|
||||
mmc_send_cmd(dev, ACMD23, count);
|
||||
}
|
||||
if(mmc_send_cmd(dev, CMD25, sector) == R1_SUCCESS) {
|
||||
do {
|
||||
if(!mmc_tx_block(dev, buff, TOK_MULTI_WR_START_BLOCK)) {
|
||||
break;
|
||||
}
|
||||
buff = (uint8_t *)buff + BLOCK_LEN;
|
||||
watchdog_periodic();
|
||||
} while(--count);
|
||||
if(!mmc_tx_block(dev, NULL, TOK_MULTI_WR_STOP_TRAN)) {
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
mmc_select(dev, false);
|
||||
return count ? DISK_RESULT_IO_ERROR : DISK_RESULT_OK;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static disk_result_t
|
||||
mmc_ioctl(uint8_t dev, uint8_t cmd, void *buff)
|
||||
{
|
||||
card_type_t card_type;
|
||||
disk_result_t res;
|
||||
uint8_t csd[CSD_SIZE], sd_status[SD_STATUS_SIZE], au_size;
|
||||
uint64_t capacity;
|
||||
uint32_t block_size;
|
||||
|
||||
static const uint8_t AU_TO_BLOCK_SIZE[] = {12, 16, 24, 32, 64};
|
||||
|
||||
if(dev >= MMC_CONF_DEV_COUNT) {
|
||||
return DISK_RESULT_INVALID_ARG;
|
||||
}
|
||||
if(!(mmc_status(dev) & DISK_STATUS_INIT)) {
|
||||
return DISK_RESULT_NO_INIT;
|
||||
}
|
||||
|
||||
card_type = mmc_priv[dev].card_type;
|
||||
res = DISK_RESULT_IO_ERROR;
|
||||
|
||||
switch(cmd) {
|
||||
case DISK_IOCTL_CTRL_SYNC:
|
||||
if(mmc_select(dev, true)) {
|
||||
res = DISK_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISK_IOCTL_GET_SECTOR_COUNT:
|
||||
if(mmc_send_cmd(dev, CMD9, 0) == R1_SUCCESS && mmc_rx(dev, csd, CSD_SIZE)) {
|
||||
capacity = CSD_STRUCTURE(csd) == CSD_STRUCTURE_SD_V2_0 ?
|
||||
CSD_SD_V2_0_CAPACITY(csd) : CSD_SD_V1_0_CAPACITY(csd);
|
||||
*(uint32_t *)buff = capacity / SECTOR_SIZE;
|
||||
res = DISK_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISK_IOCTL_GET_SECTOR_SIZE:
|
||||
*(uint16_t *)buff = SECTOR_SIZE;
|
||||
res = DISK_RESULT_OK;
|
||||
break;
|
||||
|
||||
case DISK_IOCTL_GET_BLOCK_SIZE:
|
||||
if(card_type & CARD_TYPE_SD2) {
|
||||
if(mmc_send_cmd(dev, ACMD13, 0) == R1_SUCCESS) { /* Read SD status. */
|
||||
mmc_spi_xchg(dev, 0xff);
|
||||
if(mmc_rx(dev, sd_status, SD_STATUS_SIZE)) {
|
||||
au_size = SD_STATUS_AU_SIZE(sd_status);
|
||||
if(au_size) {
|
||||
block_size = au_size <= 0xa ? 8192ull << au_size :
|
||||
(uint32_t)AU_TO_BLOCK_SIZE[au_size - 0xb] << 20;
|
||||
*(uint32_t *)buff = block_size / SECTOR_SIZE;
|
||||
res = DISK_RESULT_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(mmc_send_cmd(dev, CMD9, 0) == R1_SUCCESS &&
|
||||
mmc_rx(dev, csd, CSD_SIZE)) {
|
||||
if(card_type & CARD_TYPE_SD1) {
|
||||
block_size = (uint32_t)(CSD_SD_V1_0_SECTOR_SIZE(csd) + 1) <<
|
||||
CSD_SD_V1_0_WRITE_BL_LEN(csd);
|
||||
} else { /* MMC */
|
||||
block_size = (uint32_t)(CSD_MMC_ERASE_GRP_SIZE(csd) + 1) *
|
||||
(CSD_MMC_ERASE_GRP_MULT(csd) + 1) <<
|
||||
CSD_MMC_WRITE_BL_LEN(csd);
|
||||
}
|
||||
*(uint32_t *)buff = block_size / SECTOR_SIZE;
|
||||
res = DISK_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
res = DISK_RESULT_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
mmc_select(dev, false);
|
||||
return res;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
const struct disk_driver mmc_driver = {
|
||||
.status = mmc_status,
|
||||
.initialize = mmc_initialize,
|
||||
.read = mmc_read,
|
||||
.write = mmc_write,
|
||||
.ioctl = mmc_ioctl
|
||||
};
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
61
dev/disk/mmc/mmc.h
Normal file
61
dev/disk/mmc/mmc.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup disk
|
||||
* @{
|
||||
*
|
||||
* \defgroup mmc SD/MMC
|
||||
*
|
||||
* SD/MMC device driver.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file for the SD/MMC device driver.
|
||||
*/
|
||||
#ifndef MMC_H_
|
||||
#define MMC_H_
|
||||
|
||||
#include "contiki-conf.h"
|
||||
#include "../disk.h"
|
||||
|
||||
#ifndef MMC_CONF_DEV_COUNT
|
||||
/** Number of SD/MMC devices. */
|
||||
#define MMC_CONF_DEV_COUNT 1
|
||||
#endif
|
||||
|
||||
extern const struct disk_driver mmc_driver;
|
||||
|
||||
#endif /* MMC_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
12
examples/fat/Makefile
Normal file
12
examples/fat/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
|
||||
CONTIKI = ../..
|
||||
|
||||
all: example-fat
|
||||
|
||||
CONTIKI_WITH_RIME = 1
|
||||
|
||||
ifeq ($(TARGET), zoul)
|
||||
BOARD ?= remote-revb
|
||||
endif
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
2
examples/fat/Makefile.target
Normal file
2
examples/fat/Makefile.target
Normal file
|
@ -0,0 +1,2 @@
|
|||
TARGET = zoul
|
||||
BOARD ?= remote-revb
|
6
examples/fat/README.md
Normal file
6
examples/fat/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
FAT File System Example
|
||||
=======================
|
||||
|
||||
Supported Hardware (tested or known to work)
|
||||
--------------------------------------------
|
||||
* Zoul: RE-Mote revision B
|
96
examples/fat/example-fat.c
Normal file
96
examples/fat/example-fat.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \file
|
||||
* Example demonstrating how to use the FAT file system.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include "contiki.h"
|
||||
#include "ff.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(example_fat_process, "FAT example");
|
||||
AUTOSTART_PROCESSES(&example_fat_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define TEST_FILENAME "test.txt"
|
||||
#define TEST_LINE "Hello world!"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(example_fat_process, ev, data)
|
||||
{
|
||||
static FATFS FatFs; /* Work area (file system object) for logical drive */
|
||||
FIL fil; /* File object */
|
||||
char line[82]; /* Line buffer */
|
||||
FRESULT fr; /* FatFs return code */
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("FAT example\n");
|
||||
|
||||
/* Register work area to the default drive */
|
||||
f_mount(&FatFs, "", 0);
|
||||
|
||||
printf("Writing \"%s\" to \"%s\"\n", TEST_LINE, TEST_FILENAME);
|
||||
|
||||
/* Create the test file */
|
||||
fr = f_open(&fil, TEST_FILENAME, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if(fr) {
|
||||
printf("f_open() error: %d\n", fr);
|
||||
PROCESS_EXIT();
|
||||
}
|
||||
|
||||
/* Write the test line */
|
||||
f_printf(&fil, "%s\n", TEST_LINE);
|
||||
|
||||
/* Close the file */
|
||||
f_close(&fil);
|
||||
|
||||
printf("Reading back \"%s\":\n\n", TEST_FILENAME);
|
||||
|
||||
/* Open the test file */
|
||||
fr = f_open(&fil, TEST_FILENAME, FA_READ);
|
||||
if(fr) {
|
||||
printf("f_open() error: %d\n", fr);
|
||||
PROCESS_EXIT();
|
||||
}
|
||||
|
||||
/* Read all the lines and display them */
|
||||
while(f_gets(line, sizeof(line), &fil)) {
|
||||
printf(line);
|
||||
}
|
||||
|
||||
/* Close the file */
|
||||
f_close(&fil);
|
||||
|
||||
printf("\nDone\n");
|
||||
|
||||
PROCESS_END();
|
||||
}
|
41
examples/fat/project-conf.h
Normal file
41
examples/fat/project-conf.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef PROJECT_CONF_H_
|
||||
#define PROJECT_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if CONTIKI_TARGET_ZOUL
|
||||
#define RTC_CONF_INIT 1
|
||||
#define RTC_CONF_SET_FROM_SYS 1
|
||||
#endif
|
||||
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -4,9 +4,6 @@ CONTIKI_PROJECT = test-power-mgmt
|
|||
|
||||
BOARD ?= remote-revb
|
||||
|
||||
# Works in Linux and probably on OSX too (RTCC example)
|
||||
CFLAGS = -DDATE="\"`date +"%02u %02d %02m %02y %02H %02M %02S"`\""
|
||||
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI = ../../../..
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
#define BROADCAST_CHANNEL 129
|
||||
#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
|
||||
#define RTC_CONF_INIT 1
|
||||
#define RTC_CONF_SET_FROM_SYS 1
|
||||
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,10 +59,6 @@ static struct etimer et;
|
|||
/* RE-Mote revision B, low-power PIC version */
|
||||
#define PM_EXPECTED_VERSION 0x20
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef DATE
|
||||
#define DATE "Unknown"
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define TEST_LEDS_FAIL leds_off(LEDS_ALL); \
|
||||
leds_on(LEDS_RED); \
|
||||
PROCESS_EXIT();
|
||||
|
@ -80,7 +76,6 @@ PROCESS_THREAD(test_remote_pm, ev, data)
|
|||
static uint8_t aux;
|
||||
static uint16_t voltage;
|
||||
static uint32_t cycles;
|
||||
static char *next;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
@ -162,37 +157,12 @@ PROCESS_THREAD(test_remote_pm, ev, data)
|
|||
/* Configure the RTCC to schedule a "hard" restart of the shutdown mode,
|
||||
* waking up from a RTCC interrupt to the low-power PIC
|
||||
*/
|
||||
printf("PM: System date: %s\n", DATE);
|
||||
if(strcmp("Unknown", DATE) == 0) {
|
||||
printf("PM: could not retrieve date from system\n");
|
||||
TEST_LEDS_FAIL;
|
||||
}
|
||||
printf("PM\n");
|
||||
|
||||
/* Configure RTC and return structure with all parameters */
|
||||
rtcc_init();
|
||||
|
||||
/* Configure the RTC with the current values */
|
||||
simple_td->weekdays = (uint8_t)strtol(DATE, &next, 10);
|
||||
simple_td->day = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->months = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->years = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->hours = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->minutes = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->seconds = (uint8_t)strtol(next, NULL, 10);
|
||||
|
||||
simple_td->miliseconds = 0;
|
||||
simple_td->mode = RTCC_24H_MODE;
|
||||
simple_td->century = RTCC_CENTURY_20XX;
|
||||
|
||||
if(rtcc_set_time_date(simple_td) == AB08_ERROR) {
|
||||
printf("PM: Time and date configuration failed\n");
|
||||
TEST_LEDS_FAIL;
|
||||
} else {
|
||||
if(rtcc_get_time_date(simple_td) == AB08_ERROR) {
|
||||
printf("PM: Couldn't read time and date\n");
|
||||
TEST_LEDS_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
printf("PM: Configured time: ");
|
||||
rtcc_print(RTCC_PRINT_DATE_DEC);
|
||||
|
|
|
@ -3,9 +3,6 @@ CONTIKI_PROJECT = test-rtcc
|
|||
|
||||
TARGET = zoul
|
||||
|
||||
# Works in Linux and probably on OSX too (RTCC example)
|
||||
CFLAGS = -DDATE="\"`date +"%02u %02d %02m %02y %02H %02M %02S"`\""
|
||||
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI = ../../../..
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
|
||||
#define NETSTACK_CONF_RDC nullrdc_driver
|
||||
|
||||
#define RTC_CONF_INIT 1
|
||||
#define RTC_CONF_SET_FROM_SYS 1
|
||||
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -55,10 +55,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifndef DATE
|
||||
#define DATE "Unknown"
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define LOOP_PERIOD 60L
|
||||
#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD)
|
||||
#define TEST_ALARM_SECOND 15
|
||||
|
@ -109,58 +105,13 @@ rtcc_interrupt_callback(uint8_t value)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(test_remote_rtcc_process, ev, data)
|
||||
{
|
||||
static char *next;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/* Alternatively for test only, undefine DATE and define on your own as
|
||||
* #define DATE "07 06 12 15 16 00 00"
|
||||
* Also note that if you restart the node at a given time, it will use the
|
||||
* already defined DATE, so if you want to update the device date/time you
|
||||
* need to reflash the node
|
||||
*/
|
||||
|
||||
/* Get the system date in the following format: wd dd mm yy hh mm ss */
|
||||
printf("RE-Mote RTC test, system date: %s\n", DATE);
|
||||
|
||||
/* Sanity check */
|
||||
if(strcmp("Unknown", DATE) == 0) {
|
||||
printf("Fail: could not retrieve date from system\n");
|
||||
PROCESS_EXIT();
|
||||
}
|
||||
|
||||
/* Configure RTC and return structure with all parameters */
|
||||
rtcc_init();
|
||||
printf("RE-Mote RTC test\n");
|
||||
|
||||
/* Map interrupt callback handler */
|
||||
RTCC_REGISTER_INT1(rtcc_interrupt_callback);
|
||||
|
||||
/* Configure the RTC with the current values */
|
||||
simple_td->weekdays = (uint8_t)strtol(DATE, &next, 10);
|
||||
simple_td->day = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->months = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->years = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->hours = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->minutes = (uint8_t)strtol(next, &next, 10);
|
||||
simple_td->seconds = (uint8_t)strtol(next, NULL, 10);
|
||||
|
||||
/* Don't care about the milliseconds... */
|
||||
simple_td->miliseconds = 0;
|
||||
|
||||
/* This example relies on 24h mode */
|
||||
simple_td->mode = RTCC_24H_MODE;
|
||||
|
||||
/* And to simplify the configuration, it relies it will be executed in the
|
||||
* present century
|
||||
*/
|
||||
simple_td->century = RTCC_CENTURY_20XX;
|
||||
|
||||
/* Set the time and date */
|
||||
if(rtcc_set_time_date(simple_td) == AB08_ERROR) {
|
||||
printf("Fail: Time and date not configured\n");
|
||||
PROCESS_EXIT();
|
||||
}
|
||||
|
||||
/* Wait a bit */
|
||||
etimer_set(&et, (CLOCK_SECOND * 2));
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
|
||||
|
|
279
lib/fs/fat/00history.txt
Normal file
279
lib/fs/fat/00history.txt
Normal file
|
@ -0,0 +1,279 @@
|
|||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Improved f_rename() to be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
4
lib/fs/fat/README.md
Normal file
4
lib/fs/fat/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
FatFs - Generic FAT File System Module
|
||||
======================================
|
||||
|
||||
See the documentation on the [official FatFs Module website](http://elm-chan.org/fsw/ff/00index_e.html).
|
80
lib/fs/fat/diskio.h
Normal file
80
lib/fs/fat/diskio.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
6042
lib/fs/fat/ff.c
Normal file
6042
lib/fs/fat/ff.c
Normal file
File diff suppressed because it is too large
Load diff
366
lib/fs/fat/ff.h
Normal file
366
lib/fs/fat/ff.h
Normal file
|
@ -0,0 +1,366 @@
|
|||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT file system module R0.12b /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2016, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 68020 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
|
||||
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode (UTF-16) string */
|
||||
#if _USE_LFN == 0
|
||||
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if _FS_EXFAT
|
||||
#if _USE_LFN == 0
|
||||
#error LFN must be enabled when enable exFAT
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* File system type (0:N/A) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if _MAX_SS != _MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _USE_LFN != 0
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if _FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if _FS_RPATH != 0
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if _FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (_FDID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if _FS_EXFAT
|
||||
DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */
|
||||
#endif
|
||||
#if _FS_LOCK != 0
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} _FDID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if _USE_LFN != 0
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if _USE_LFN != 0
|
||||
TCHAR altname[13]; /* Altenative file name */
|
||||
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[13]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
38
lib/fs/fat/integer.h
Normal file
38
lib/fs/fat/integer.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _FF_INTEGER
|
||||
#define _FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
152
lib/fs/fat/option/syscall.c
Normal file
152
lib/fs/fat/option/syscall.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs */
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../ff.h"
|
||||
|
||||
|
||||
#if _FS_REENTRANT
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
||||
ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static sync object) */
|
||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
||||
|
||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
|
||||
// ret = (int)(*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */
|
||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
ret = CloseHandle(sobj); /* Win32 */
|
||||
|
||||
// ret = 1; /* uITRON (nothing to do) */
|
||||
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
// vSemaphoreDelete(sobj); /* FreeRTOS */
|
||||
// ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
||||
|
||||
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
||||
|
||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
// ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
ReleaseMutex(sobj); /* Win32 */
|
||||
|
||||
// sig_sem(sobj); /* uITRON */
|
||||
|
||||
// OSMutexPost(sobj); /* uC/OS-II */
|
||||
|
||||
// xSemaphoreGive(sobj); /* FreeRTOS */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||
*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
17
lib/fs/fat/option/unicode.c
Normal file
17
lib/fs/fat/option/unicode.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "../ff.h"
|
||||
|
||||
#if _USE_LFN != 0
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift_JIS */
|
||||
#include "unicode/cc932.c"
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#include "unicode/cc936.c"
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#include "unicode/cc949.c"
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#include "unicode/cc950.c"
|
||||
#else /* Single Byte Character-Set */
|
||||
#include "unicode/ccsbcs.c"
|
||||
#endif
|
||||
|
||||
#endif
|
3870
lib/fs/fat/option/unicode/cc932.c
Normal file
3870
lib/fs/fat/option/unicode/cc932.c
Normal file
File diff suppressed because it is too large
Load diff
11045
lib/fs/fat/option/unicode/cc936.c
Normal file
11045
lib/fs/fat/option/unicode/cc936.c
Normal file
File diff suppressed because it is too large
Load diff
8674
lib/fs/fat/option/unicode/cc949.c
Normal file
8674
lib/fs/fat/option/unicode/cc949.c
Normal file
File diff suppressed because it is too large
Load diff
6900
lib/fs/fat/option/unicode/cc950.c
Normal file
6900
lib/fs/fat/option/unicode/cc950.c
Normal file
File diff suppressed because it is too large
Load diff
388
lib/fs/fat/option/unicode/ccsbcs.c
Normal file
388
lib/fs/fat/option/unicode/ccsbcs.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */
|
||||
/* (SBCS code pages) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S.
|
||||
/ 720 Arabic
|
||||
/ 737 Greek
|
||||
/ 771 KBL
|
||||
/ 775 Baltic
|
||||
/ 850 Latin 1
|
||||
/ 852 Latin 2
|
||||
/ 855 Cyrillic
|
||||
/ 857 Turkish
|
||||
/ 860 Portuguese
|
||||
/ 861 Icelandic
|
||||
/ 862 Hebrew
|
||||
/ 863 Canadian French
|
||||
/ 864 Arabic
|
||||
/ 865 Nordic
|
||||
/ 866 Russian
|
||||
/ 869 Greek 2
|
||||
*/
|
||||
|
||||
#include "../../ff.h"
|
||||
|
||||
|
||||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 771
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 860
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
||||
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 861
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 863
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
||||
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
||||
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 864
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
|
||||
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
||||
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
||||
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
||||
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
|
||||
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
|
||||
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
|
||||
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
|
||||
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 865
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 869
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
|
||||
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
||||
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
|
||||
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
|
||||
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
|
||||
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !_TBLDEF || !_USE_LFN
|
||||
#error This file is not needed at current configuration. Remove from the project.
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR chr, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
|
||||
)
|
||||
{
|
||||
WCHAR c;
|
||||
|
||||
|
||||
if (chr < 0x80) { /* ASCII */
|
||||
c = chr;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEM code to Unicode */
|
||||
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
||||
|
||||
} else { /* Unicode to OEM code */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (chr == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WCHAR ff_wtoupper ( /* Returns upper converted character */
|
||||
WCHAR chr /* Unicode character to be upper converted (BMP only) */
|
||||
)
|
||||
{
|
||||
/* Compressed upper conversion table */
|
||||
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
|
||||
/* Basic Latin */
|
||||
0x0061,0x031A,
|
||||
/* Latin-1 Supplement */
|
||||
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
||||
/* Latin Extended-A */
|
||||
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
||||
/* Latin Extended-B */
|
||||
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
||||
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
|
||||
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
|
||||
/* IPA Extensions */
|
||||
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
||||
/* Greek, Coptic */
|
||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
|
||||
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
|
||||
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
||||
/* Cyrillic */
|
||||
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
|
||||
/* Armenian */
|
||||
0x0561,0x0426,
|
||||
|
||||
0x0000
|
||||
};
|
||||
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
|
||||
/* Phonetic Extensions */
|
||||
0x1D7D,0x0001,0x2C63,
|
||||
/* Latin Extended Additional */
|
||||
0x1E00,0x0196, 0x1EA0,0x015A,
|
||||
/* Greek Extended */
|
||||
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
|
||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
|
||||
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
||||
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
|
||||
/* Letterlike Symbols */
|
||||
0x214E,0x0001,0x2132,
|
||||
/* Number forms */
|
||||
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
||||
/* Enclosed Alphanumerics */
|
||||
0x24D0,0x051A, 0x2C30,0x042F,
|
||||
/* Latin Extended-C */
|
||||
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
||||
/* Coptic */
|
||||
0x2C80,0x0164,
|
||||
/* Georgian Supplement */
|
||||
0x2D00,0x0826,
|
||||
/* Full-width */
|
||||
0xFF41,0x031A,
|
||||
|
||||
0x0000
|
||||
};
|
||||
const WCHAR *p;
|
||||
WCHAR bc, nc, cmd;
|
||||
|
||||
|
||||
p = chr < 0x1000 ? cvt1 : cvt2;
|
||||
for (;;) {
|
||||
bc = *p++; /* Get block base */
|
||||
if (!bc || chr < bc) break;
|
||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||
if (chr < bc + nc) { /* In the block? */
|
||||
switch (cmd) {
|
||||
case 0: chr = p[chr - bc]; break; /* Table conversion */
|
||||
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
|
||||
case 2: chr -= 16; break; /* Shift -16 */
|
||||
case 3: chr -= 32; break; /* Shift -32 */
|
||||
case 4: chr -= 48; break; /* Shift -48 */
|
||||
case 5: chr -= 26; break; /* Shift -26 */
|
||||
case 6: chr += 8; break; /* Shift +8 */
|
||||
case 7: chr -= 80; break; /* Shift -80 */
|
||||
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!cmd) p += nc;
|
||||
}
|
||||
|
||||
return chr;
|
||||
}
|
||||
|
|
@ -18,6 +18,9 @@ endif
|
|||
PYTHON = python
|
||||
BSL_FLAGS += -e -w -v
|
||||
|
||||
# Works in Linux and probably on OSX too (RTCC example)
|
||||
CFLAGS += -DDATE="\"`date +"%02u %02d %02m %02y %02H %02M %02S"`\""
|
||||
|
||||
### Configure the build for the board and pull in board-specific sources
|
||||
CONTIKI_TARGET_DIRS += . dev
|
||||
CONTIKI_TARGET_DIRS += . $(BOARD)
|
||||
|
|
|
@ -60,6 +60,7 @@ In terms of hardware support, the following drivers have been implemented for th
|
|||
* Built-in core temperature and battery sensor.
|
||||
* CC1200 sub-1GHz radio interface.
|
||||
* Real Time Clock Calendar (on the RE-Mote platform).
|
||||
* SD
|
||||
|
||||
There is a Zoul powering the RE-Mote and Firefly platforms, check out its specific README files for more information about on-board features.
|
||||
|
||||
|
|
|
@ -573,6 +573,27 @@ typedef uint32_t rtimer_clock_t;
|
|||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name RTC
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifdef PLATFORM_HAS_RTC
|
||||
|
||||
#ifndef RTC_CONF_INIT
|
||||
#define RTC_CONF_INIT 0 /**< Whether to initialize the RTC */
|
||||
#endif
|
||||
|
||||
#ifndef RTC_CONF_SET_FROM_SYS
|
||||
#define RTC_CONF_SET_FROM_SYS 0 /**< Whether to set the RTC from the build system */
|
||||
#endif
|
||||
|
||||
#else
|
||||
#undef RTC_CONF_INIT
|
||||
#define RTC_CONF_INIT 0
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* CONTIKI_CONF_H_ */
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "dev/cc2538-rf.h"
|
||||
#include "dev/udma.h"
|
||||
#include "dev/crypto.h"
|
||||
#include "dev/rtcc.h"
|
||||
#include "usb/usb-serial.h"
|
||||
#include "lib/random.h"
|
||||
#include "net/netstack.h"
|
||||
|
@ -72,6 +73,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if STARTUP_CONF_VERBOSE
|
||||
|
@ -109,6 +111,62 @@ fade(unsigned char l)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
rtc_init(void)
|
||||
{
|
||||
#if RTC_CONF_INIT
|
||||
#if RTC_CONF_SET_FROM_SYS
|
||||
char *next;
|
||||
simple_td_map td;
|
||||
#endif
|
||||
|
||||
/* Configure RTC and return structure with all parameters */
|
||||
rtcc_init();
|
||||
|
||||
#if RTC_CONF_SET_FROM_SYS
|
||||
#ifndef DATE
|
||||
#error Could not retrieve date from system
|
||||
#endif
|
||||
|
||||
/* Alternatively, for test only, undefine DATE and define it on your own as:
|
||||
* #define DATE "07 06 12 15 16 00 00"
|
||||
* Also note that if you restart the node at a given time, it will use the
|
||||
* already defined DATE, so if you want to update the device date/time you
|
||||
* need to reflash the node.
|
||||
*/
|
||||
|
||||
/* Get the system date in the following format: wd dd mm yy hh mm ss */
|
||||
PRINTF("Setting RTC from system date: %s\n", DATE);
|
||||
|
||||
/* Configure the RTC with the current values */
|
||||
td.weekdays = (uint8_t)strtol(DATE, &next, 10);
|
||||
td.day = (uint8_t)strtol(next, &next, 10);
|
||||
td.months = (uint8_t)strtol(next, &next, 10);
|
||||
td.years = (uint8_t)strtol(next, &next, 10);
|
||||
td.hours = (uint8_t)strtol(next, &next, 10);
|
||||
td.minutes = (uint8_t)strtol(next, &next, 10);
|
||||
td.seconds = (uint8_t)strtol(next, NULL, 10);
|
||||
|
||||
/* Don't care about the milliseconds... */
|
||||
td.miliseconds = 0;
|
||||
|
||||
/* This example relies on 24h mode */
|
||||
td.mode = RTCC_24H_MODE;
|
||||
|
||||
/*
|
||||
* And to simplify the configuration, it relies on the fact that it will be
|
||||
* executed in the present century
|
||||
*/
|
||||
td.century = RTCC_CENTURY_20XX;
|
||||
|
||||
/* Set the time and date */
|
||||
if(rtcc_set_time_date(&td) == AB08_ERROR) {
|
||||
PRINTF("Failed to set time and date\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
set_rf_params(void)
|
||||
{
|
||||
uint16_t short_addr;
|
||||
|
@ -204,6 +262,8 @@ main(void)
|
|||
crypto_disable();
|
||||
#endif
|
||||
|
||||
rtc_init();
|
||||
|
||||
netstack_init();
|
||||
set_rf_params();
|
||||
|
||||
|
|
139
platform/zoul/dev/mmc-arch.c
Normal file
139
platform/zoul/dev/mmc-arch.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup mmc-arch
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the SD/MMC device driver RE-Mote-specific definitions.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "spi-arch.h"
|
||||
#include "dev/ioc.h"
|
||||
#include "dev/gpio.h"
|
||||
#include "dev/spi.h"
|
||||
#include "mmc-arch.h"
|
||||
|
||||
#define USD_SEL_PORT_BASE GPIO_PORT_TO_BASE(USD_SEL_PORT)
|
||||
#define USD_SEL_PIN_MASK GPIO_PIN_MASK(USD_SEL_PIN)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void
|
||||
mmc_arch_init(void)
|
||||
{
|
||||
static uint8_t init_done;
|
||||
|
||||
if(init_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPIO_SET_INPUT(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
|
||||
GPIO_SOFTWARE_CONTROL(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
|
||||
ioc_set_over(USD_SEL_PORT, USD_SEL_PIN, IOC_OVERRIDE_DIS);
|
||||
|
||||
spix_cs_init(USD_CSN_PORT, USD_CSN_PIN);
|
||||
spix_init(USD_SPI_INSTANCE);
|
||||
spix_set_mode(USD_SPI_INSTANCE, SSI_CR0_FRF_MOTOROLA, 0, 0, 8);
|
||||
|
||||
init_done = 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
bool
|
||||
mmc_arch_get_cd(uint8_t dev)
|
||||
{
|
||||
mmc_arch_init();
|
||||
|
||||
if(GPIO_IS_OUTPUT(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK)) {
|
||||
/* Card previously detected and powered */
|
||||
return true;
|
||||
} else if(GPIO_READ_PIN(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK)) {
|
||||
/* Card inserted -> power it */
|
||||
GPIO_SET_OUTPUT(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
|
||||
GPIO_CLR_PIN(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
|
||||
return true;
|
||||
} else {
|
||||
/* No card detected */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
bool
|
||||
mmc_arch_get_wp(uint8_t dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mmc_arch_spi_select(uint8_t dev, bool sel)
|
||||
{
|
||||
if(sel) {
|
||||
SPIX_CS_CLR(USD_CSN_PORT, USD_CSN_PIN);
|
||||
} else {
|
||||
SPIX_CS_SET(USD_CSN_PORT, USD_CSN_PIN);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mmc_arch_spi_set_clock_freq(uint8_t dev, uint32_t freq)
|
||||
{
|
||||
spix_set_clock_freq(USD_SPI_INSTANCE, freq);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
mmc_arch_spi_xfer(uint8_t dev, const void *tx_buf, size_t tx_cnt,
|
||||
void *rx_buf, size_t rx_cnt)
|
||||
{
|
||||
const uint8_t *tx_buf_u8 = tx_buf;
|
||||
uint8_t *rx_buf_u8 = rx_buf;
|
||||
|
||||
while(tx_cnt || rx_cnt) {
|
||||
SPIX_WAITFORTxREADY(USD_SPI_INSTANCE);
|
||||
if(tx_cnt) {
|
||||
SPIX_BUF(USD_SPI_INSTANCE) = *tx_buf_u8++;
|
||||
tx_cnt--;
|
||||
} else {
|
||||
SPIX_BUF(USD_SPI_INSTANCE) = 0;
|
||||
}
|
||||
SPIX_WAITFOREOTx(USD_SPI_INSTANCE);
|
||||
SPIX_WAITFOREORx(USD_SPI_INSTANCE);
|
||||
if(rx_cnt) {
|
||||
*rx_buf_u8++ = SPIX_BUF(USD_SPI_INSTANCE);
|
||||
rx_cnt--;
|
||||
} else {
|
||||
SPIX_BUF(USD_SPI_INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
84
platform/zoul/fs/fat/diskio.c
Normal file
84
platform/zoul/fs/fat/diskio.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup remote-fat
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Implementation of the default port of FatFs on RE-Mote.
|
||||
*/
|
||||
#include "diskio.h"
|
||||
#include "mmc.h"
|
||||
#include "rtcc.h"
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
DSTATUS __attribute__((__weak__))
|
||||
disk_status(BYTE pdrv)
|
||||
{
|
||||
return ~mmc_driver.status(pdrv);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
DSTATUS __attribute__((__weak__))
|
||||
disk_initialize(BYTE pdrv)
|
||||
{
|
||||
return ~mmc_driver.initialize(pdrv);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
DRESULT __attribute__((__weak__))
|
||||
disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
|
||||
{
|
||||
return mmc_driver.read(pdrv, buff, sector, count);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
DRESULT __attribute__((__weak__))
|
||||
disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
|
||||
{
|
||||
return mmc_driver.write(pdrv, buff, sector, count);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
DRESULT __attribute__((__weak__))
|
||||
disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
|
||||
{
|
||||
return mmc_driver.ioctl(pdrv, cmd, buff);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
DWORD __attribute__((__weak__))
|
||||
get_fattime(void)
|
||||
{
|
||||
simple_td_map td;
|
||||
|
||||
return rtcc_get_time_date(&td) == AB08_SUCCESS ?
|
||||
(2000 + td.years - 1980) << 25 | td.months << 21 | td.day << 16 |
|
||||
td.hours << 11 | td.minutes << 5 | td.seconds : 0;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
418
platform/zoul/fs/fat/ffconf.h
Normal file
418
platform/zoul/fs/fat/ffconf.h
Normal file
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on the FatFs Module,
|
||||
* Copyright (c) 2016, ChaN
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/**
|
||||
* \addtogroup remote
|
||||
* @{
|
||||
*
|
||||
* \defgroup remote-fat RE-Mote FatFs
|
||||
*
|
||||
* Default port of FatFs on RE-Mote.
|
||||
* @{
|
||||
*
|
||||
* \file
|
||||
* Header file configuring FatFs for RE-Mote.
|
||||
*/
|
||||
#ifndef FFCONF_H_
|
||||
#define FFCONF_H_
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#define _FFCONF 68020 /**< Revision ID */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/** \name Function Configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _FS_READONLY
|
||||
/** This option switches the read-only configuration
|
||||
* (\c 0: read/write or \c 1: read-only).
|
||||
*
|
||||
* The read-only configuration removes the writing functions from the API:
|
||||
* \c f_write(), \c f_sync(), \c f_unlink(), \c f_mkdir(), \c f_chmod(),
|
||||
* \c f_rename(), \c f_truncate(), \c f_getfree(), and optional writing
|
||||
* functions as well.
|
||||
*/
|
||||
#define _FS_READONLY 0
|
||||
#endif
|
||||
|
||||
#ifndef _FS_MINIMIZE
|
||||
/** This option defines the minimization level to remove some basic API
|
||||
* functions.
|
||||
*
|
||||
* \c 0: All the basic functions are enabled.
|
||||
* \c 1: \c f_stat(), \c f_getfree(), \c f_unlink(), \c f_mkdir(),
|
||||
* \c f_truncate(), and \c f_rename() are removed.
|
||||
* \c 2: \c f_opendir(), \c f_readdir(), and \c f_closedir() are removed in
|
||||
* addition to \c 1.
|
||||
* \c 3: \c f_lseek() is removed in addition to \c 2.
|
||||
*/
|
||||
#define _FS_MINIMIZE 0
|
||||
#endif
|
||||
|
||||
#ifndef _USE_STRFUNC
|
||||
/** This option switches the string functions: \c f_gets(), \c f_putc(),
|
||||
* \c f_puts(), and \c f_printf().
|
||||
*
|
||||
* \c 0: Disable string functions.
|
||||
* \c 1: Enable without LF-CRLF conversion.
|
||||
* \c 2: Enable with LF-CRLF conversion.
|
||||
*/
|
||||
#define _USE_STRFUNC 1
|
||||
#endif
|
||||
|
||||
#ifndef _USE_FIND
|
||||
/** This option switches the filtered directory read functions: \c f_findfirst()
|
||||
* and \c f_findnext() (\c 0: disable, \c 1: enable, \c 2: enable with matching
|
||||
* \c altname[] too).
|
||||
*/
|
||||
#define _USE_FIND 1
|
||||
#endif
|
||||
|
||||
#ifndef _USE_MKFS
|
||||
/** This option switches the \c f_mkfs() function
|
||||
* (\c 0: disable or \c 1: enable).
|
||||
*/
|
||||
#define _USE_MKFS 1
|
||||
#endif
|
||||
|
||||
#ifndef _USE_FASTSEEK
|
||||
/** This option switches the fast seek function
|
||||
* (\c 0: disable or \c 1: enable).
|
||||
*/
|
||||
#define _USE_FASTSEEK 0
|
||||
#endif
|
||||
|
||||
#ifndef _USE_EXPAND
|
||||
/** This option switches the \c f_expand() function
|
||||
* (\c 0: disable or \c 1: enable).
|
||||
*/
|
||||
#define _USE_EXPAND 0
|
||||
#endif
|
||||
|
||||
#ifndef _USE_CHMOD
|
||||
/** This option switches the attribute manipulation functions: \c f_chmod() and
|
||||
* \c f_utime() (\c 0: disable or \c 1: enable). Also, \c _FS_READONLY needs to
|
||||
* be \c 0 to enable this option.
|
||||
*/
|
||||
#define _USE_CHMOD 1
|
||||
#endif
|
||||
|
||||
#ifndef _USE_LABEL
|
||||
/** This option switches the volume label functions: \c f_getlabel() and
|
||||
* \c f_setlabel() (\c 0: disable or \c 1: enable).
|
||||
*/
|
||||
#define _USE_LABEL 1
|
||||
#endif
|
||||
|
||||
#ifndef _USE_FORWARD
|
||||
/** This option switches the \c f_forward() function
|
||||
* (\c 0: disable or \c 1: enable).
|
||||
*/
|
||||
#define _USE_FORWARD 0
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/** \name Locale and Namespace Configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CODE_PAGE
|
||||
/** This option specifies the OEM code page to be used on the target system.
|
||||
* Incorrect setting of the code page can cause a file open failure.
|
||||
*
|
||||
* \c 1 - ASCII (no extended character, non-LFN cfg. only)
|
||||
* \c 437 - U.S.
|
||||
* \c 720 - Arabic
|
||||
* \c 737 - Greek
|
||||
* \c 771 - KBL
|
||||
* \c 775 - Baltic
|
||||
* \c 850 - Latin 1
|
||||
* \c 852 - Latin 2
|
||||
* \c 855 - Cyrillic
|
||||
* \c 857 - Turkish
|
||||
* \c 860 - Portuguese
|
||||
* \c 861 - Icelandic
|
||||
* \c 862 - Hebrew
|
||||
* \c 863 - Canadian French
|
||||
* \c 864 - Arabic
|
||||
* \c 865 - Nordic
|
||||
* \c 866 - Russian
|
||||
* \c 869 - Greek 2
|
||||
* \c 932 - Japanese (DBCS)
|
||||
* \c 936 - Simplified Chinese (DBCS)
|
||||
* \c 949 - Korean (DBCS)
|
||||
* \c 950 - Traditional Chinese (DBCS)
|
||||
*/
|
||||
#define _CODE_PAGE 437
|
||||
#endif
|
||||
|
||||
#ifndef _USE_LFN
|
||||
/** \c _USE_LFN switches the support of long file name (LFN).
|
||||
*
|
||||
* \c 0: Disable LFN support. \c _MAX_LFN has no effect.
|
||||
* \c 1: Enable LFN with static working buffer on the BSS. Always thread-unsafe.
|
||||
* \c 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
* \c 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
*
|
||||
* To enable LFN, the Unicode handling functions (<tt>option/unicode.c</tt>)
|
||||
* must be added to the project. The working buffer occupies
|
||||
* <tt>(_MAX_LFN + 1) * 2</tt> bytes, and 608 more bytes with exFAT enabled.
|
||||
* \c _MAX_LFN can be in the range from 12 to 255. It should be set to 255 to
|
||||
* support the full-featured LFN operations. When using the stack for the
|
||||
* working buffer, take care of stack overflow. When using the heap memory for
|
||||
* the working buffer, the memory management functions, \c ff_memalloc() and
|
||||
* \c ff_memfree(), must be added to the project.
|
||||
*/
|
||||
#define _USE_LFN 3
|
||||
#endif
|
||||
#ifndef _MAX_LFN
|
||||
#define _MAX_LFN 255
|
||||
#endif
|
||||
|
||||
#ifndef _LFN_UNICODE
|
||||
/** This option switches the character encoding in the API
|
||||
* (\c 0: ANSI/OEM or \c 1: UTF-16).
|
||||
*
|
||||
* To use a Unicode string for the path name, enable LFN and set \c _LFN_UNICODE
|
||||
* to \c 1.
|
||||
* This option also affects the behavior of the string I/O functions.
|
||||
*/
|
||||
#define _LFN_UNICODE 0
|
||||
#endif
|
||||
|
||||
#ifndef _STRF_ENCODE
|
||||
/** If \c _LFN_UNICODE is set to \c 1, this option selects the character
|
||||
* encoding OF THE FILE to be read/written via the string I/O functions:
|
||||
* \c f_gets(), \c f_putc(), \c f_puts(), and \c f_printf().
|
||||
*
|
||||
* \c 0: ANSI/OEM
|
||||
* \c 1: UTF-16LE
|
||||
* \c 2: UTF-16BE
|
||||
* \c 3: UTF-8
|
||||
*
|
||||
* This option has no effect if \c _LFN_UNICODE is set to \c 0.
|
||||
*/
|
||||
#define _STRF_ENCODE 0
|
||||
#endif
|
||||
|
||||
#ifndef _FS_RPATH
|
||||
/** This option configures the support of relative path.
|
||||
*
|
||||
* \c 0: Disable relative path and remove related functions.
|
||||
* \c 1: Enable relative path. \c f_chdir() and \c f_chdrive() are available.
|
||||
* \c 2: \c f_getcwd() is available in addition to \c 1.
|
||||
*/
|
||||
#define _FS_RPATH 2
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/** \name Drive/Volume Configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _VOLUMES
|
||||
/** Number of volumes (logical drives) to be used. */
|
||||
#define _VOLUMES 1
|
||||
#endif
|
||||
|
||||
#ifndef _STR_VOLUME_ID
|
||||
/** \c _STR_VOLUME_ID switches the string support of volume ID.
|
||||
* If \c _STR_VOLUME_ID is set to \c 1, pre-defined strings can also be used as
|
||||
* drive number in the path name. \c _VOLUME_STRS defines the drive ID strings
|
||||
* for each logical drive. The number of items must be equal to \c _VOLUMES.
|
||||
* The valid characters for the drive ID strings are: A-Z and 0-9.
|
||||
*/
|
||||
#define _STR_VOLUME_ID 0
|
||||
#endif
|
||||
#ifndef _VOLUME_STRS
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
#endif
|
||||
|
||||
#ifndef _MULTI_PARTITION
|
||||
/** This option switches support of multi-partition on a physical drive.
|
||||
* By default (0), each logical drive number is bound to the same physical drive
|
||||
* number and only an FAT volume found on the physical drive will be mounted.
|
||||
* When multi-partition is enabled (1), each logical drive number can be bound to
|
||||
* arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
* funciton will be available.
|
||||
*/
|
||||
#define _MULTI_PARTITION 0
|
||||
#endif
|
||||
|
||||
#ifndef _MIN_SS
|
||||
/** These options configure the range of sector size to be supported (512, 1024,
|
||||
* 2048, or 4096). Always set both to 512 for most systems, all types of memory
|
||||
* cards and harddisk. But a larger value may be required for on-board flash
|
||||
* memory and some types of optical media. When \c _MAX_SS is larger than
|
||||
* \c _MIN_SS, FatFs is configured to variable sector size and the
|
||||
* \c GET_SECTOR_SIZE command must be implemented in \c disk_ioctl().
|
||||
*/
|
||||
#define _MIN_SS 512
|
||||
#endif
|
||||
#ifndef _MAX_SS
|
||||
#define _MAX_SS 512
|
||||
#endif
|
||||
|
||||
#ifndef _USE_TRIM
|
||||
/** This option switches the support of ATA-TRIM
|
||||
* (\c 0: disable or \c 1: enable).
|
||||
*
|
||||
* To enable the Trim function, the \c CTRL_TRIM command should also be
|
||||
* implemented in \c disk_ioctl().
|
||||
*/
|
||||
#define _USE_TRIM 0
|
||||
#endif
|
||||
|
||||
#ifndef _FS_NOFSINFO
|
||||
/** If you need to know the correct free space on the FAT32 volume, set the bit
|
||||
* 0 of this option, and the \c f_getfree() function will force a full FAT scan
|
||||
* on the first time after a volume mount. The bit 1 controls the use of the
|
||||
* last allocated cluster number.
|
||||
*
|
||||
* bit 0=0: Use the free cluster count in FSINFO if available.
|
||||
* bit 0=1: Do not trust the free cluster count in FSINFO.
|
||||
* bit 1=0: Use the last allocated cluster number in FSINFO if available.
|
||||
* bit 1=1: Do not trust the last allocated cluster number in FSINFO.
|
||||
*/
|
||||
#define _FS_NOFSINFO 3
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/** \name System Configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _FS_TINY
|
||||
/** This option switches the tiny buffer configuration
|
||||
* (\c 0: normal or \c 1: tiny).
|
||||
*
|
||||
* With the tiny configuration, the size of a file object (FIL) is reduced to
|
||||
* \c _MAX_SS bytes. Instead of the private sector buffer eliminated from the
|
||||
* file object, a common sector buffer in the file system object (FATFS) is used
|
||||
* for the file data transfer.
|
||||
*/
|
||||
#define _FS_TINY 0
|
||||
#endif
|
||||
|
||||
#ifndef _FS_EXFAT
|
||||
/** This option switches the support of the exFAT file system
|
||||
* (\c 0: disable or \c 1: enable).
|
||||
*
|
||||
* With exFAT enabled, LFN also needs to be enabled (\c _USE_LFN >= 1).
|
||||
* Note that enabling exFAT discards C89 compatibility.
|
||||
*/
|
||||
#define _FS_EXFAT 1
|
||||
#endif
|
||||
|
||||
#ifndef _FS_NORTC
|
||||
/** The option \c _FS_NORTC switches the timestamp function. If the system does
|
||||
* not have any RTC function or if a valid timestamp is not needed, set
|
||||
* \c _FS_NORTC to \c 1 to disable the timestamp function. All the objects
|
||||
* modified by FatFs will have a fixed timestamp defined by \c _NORTC_MON,
|
||||
* \c _NORTC_MDAY, and \c _NORTC_YEAR in local time.
|
||||
* To enable the timestamp function (\c _FS_NORTC set to \c 0), \c get_fattime()
|
||||
* needs to be added to the project to get the current time from a real-time
|
||||
* clock. \c _NORTC_MON, \c _NORTC_MDAY, and \c _NORTC_YEAR have no effect.
|
||||
* These options have no effect with a read-only configuration (\c _FS_READONLY
|
||||
* set to \c 1).
|
||||
*/
|
||||
#define _FS_NORTC (!RTC_CONF_INIT)
|
||||
#endif
|
||||
#ifndef _NORTC_MON
|
||||
#define _NORTC_MON 1
|
||||
#endif
|
||||
#ifndef _NORTC_MDAY
|
||||
#define _NORTC_MDAY 1
|
||||
#endif
|
||||
#ifndef _NORTC_YEAR
|
||||
#define _NORTC_YEAR 2016
|
||||
#endif
|
||||
|
||||
#ifndef _FS_LOCK
|
||||
/** The option \c _FS_LOCK switches the file lock function controlling duplicate
|
||||
* file open and illegal operations on the open objects. This option must be set
|
||||
* to \c 0 if \c _FS_READONLY is \c 1.
|
||||
*
|
||||
* \c 0: Disable the file lock function. To avoid volume corruption, the
|
||||
* application program should avoid illegal open, remove, and rename on
|
||||
* the open objects.
|
||||
* \c >0: Enable the file lock function. The value defines how many
|
||||
* files/sub-directories can be opened simultaneously under file lock
|
||||
* control. Note that the file lock control is independent of
|
||||
* re-entrancy.
|
||||
*/
|
||||
#define _FS_LOCK 0
|
||||
#endif
|
||||
|
||||
#ifndef _FS_REENTRANT
|
||||
/** The option \c _FS_REENTRANT switches the re-entrancy (thread-safe) of the
|
||||
* FatFs module itself. Note that, regardless of this option, file access to
|
||||
* different volumes is always re-entrant, and the volume control functions,
|
||||
* \c f_mount(), \c f_mkfs(), and \c f_fdisk(), are always non-re-entrant. Only
|
||||
* file/directory access to the same volume is under control of this function.
|
||||
*
|
||||
* \c 0: Disable re-entrancy. \c _FS_TIMEOUT and \c _SYNC_t have no effect.
|
||||
* \c 1: Enable re-entrancy. The user-provided synchronization handlers,
|
||||
* \c ff_req_grant(), \c ff_rel_grant(), \c ff_del_syncobj(), and
|
||||
* \c ff_cre_syncobj(), must also be added to the project. Samples are
|
||||
* available in <tt>option/syscall.c</tt>.
|
||||
*
|
||||
* \c _FS_TIMEOUT defines the timeout period in unit of time tick.
|
||||
* \c _SYNC_t defines the OS-dependent sync object type, e.g. \c HANDLE, \c ID,
|
||||
* \c OS_EVENT*, \c SemaphoreHandle_t, etc. A header file for the OS definitions
|
||||
* needs to be included somewhere in the scope of <tt>ff.h</tt>.
|
||||
*/
|
||||
#define _FS_REENTRANT 0
|
||||
#endif
|
||||
#ifndef _FS_TIMEOUT
|
||||
#define _FS_TIMEOUT 1000
|
||||
#endif
|
||||
#ifndef _SYNC_t
|
||||
#define _SYNC_t HANDLE
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* FFCONF_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
|
@ -1,2 +1,4 @@
|
|||
MOTELIST_ZOLERTIA = remote
|
||||
BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c power-mgmt.c leds-arch.c
|
||||
BOARD_SOURCEFILES += board.c antenna-sw.c mmc-arch.c rtcc.c power-mgmt.c leds-arch.c
|
||||
|
||||
MODULES += lib/fs/fat lib/fs/fat/option platform/zoul/fs/fat dev/disk/mmc
|
||||
|
|
|
@ -405,6 +405,7 @@
|
|||
* external module, to be used with SSI1
|
||||
* @{
|
||||
*/
|
||||
#define USD_SPI_INSTANCE 1
|
||||
#define USD_CLK_PORT SPI1_CLK_PORT
|
||||
#define USD_CLK_PIN SPI1_CLK_PIN
|
||||
#define USD_MOSI_PORT SPI1_TX_PORT
|
||||
|
@ -454,6 +455,7 @@
|
|||
* requiring to put the PIC into deep-sleep and waking up at a certain time.
|
||||
* @{
|
||||
*/
|
||||
#define PLATFORM_HAS_RTC 1
|
||||
#define RTC_SDA_PORT I2C_SDA_PORT
|
||||
#define RTC_SDA_PIN I2C_SDA_PIN
|
||||
#define RTC_SCL_PORT I2C_SCL_PORT
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
MOTELIST_ZOLERTIA = remote
|
||||
BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c leds-res-arch.c power-mgmt.c
|
||||
BOARD_SOURCEFILES += board.c antenna-sw.c mmc-arch.c rtcc.c leds-res-arch.c power-mgmt.c
|
||||
|
||||
MODULES += lib/fs/fat lib/fs/fat/option platform/zoul/fs/fat dev/disk/mmc
|
||||
|
|
|
@ -433,6 +433,7 @@
|
|||
* a microSD in the slot, or when connected to disable the microSD to save power
|
||||
* @{
|
||||
*/
|
||||
#define USD_SPI_INSTANCE 1
|
||||
#define USD_CLK_PORT SPI1_CLK_PORT
|
||||
#define USD_CLK_PIN SPI1_CLK_PIN
|
||||
#define USD_MOSI_PORT SPI1_TX_PORT
|
||||
|
@ -481,6 +482,7 @@
|
|||
*
|
||||
* @{
|
||||
*/
|
||||
#define PLATFORM_HAS_RTC 1
|
||||
#define RTC_SDA_PORT I2C_SDA_PORT
|
||||
#define RTC_SDA_PIN I2C_SDA_PIN
|
||||
#define RTC_SCL_PORT I2C_SCL_PORT
|
||||
|
|
|
@ -54,6 +54,7 @@ sensniff/ev-aducrf101mkxz \
|
|||
cfs-coffee/cc2538dk \
|
||||
cfs-coffee/openmote-cc2538 \
|
||||
cfs-coffee/zoul \
|
||||
fat/zoul:BOARD=remote-revb \
|
||||
ipv6/rpl-tsch/zoul \
|
||||
ipv6/rpl-tsch/zoul:MAKE_WITH_ORCHESTRA=1 \
|
||||
ipv6/rpl-tsch/zoul:MAKE_WITH_SECURITY=1
|
||||
|
|
Loading…
Reference in a new issue