mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 06:49:24 -05:00
Merge remote-tracking branch 'upstream/master'
Base class for text entry
This commit is contained in:
commit
abd154b3c7
@ -72,8 +72,11 @@ set(USE_FPU no)
|
||||
# Project, sources and paths
|
||||
#
|
||||
|
||||
set(CPLD_SVF_PATH ${HARDWARE_PATH}/portapack_h1/cpld/output_files/portapack_h1_cpld.svf)
|
||||
set(CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/portapack_cpld_data.cpp)
|
||||
set(CPLD_20150901_SVF_PATH ${HARDWARE_PATH}/portapack_h1/cpld/20150901/output_files/portapack_h1_cpld.svf)
|
||||
set(CPLD_20150901_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/portapack_cpld_20150901_data.cpp)
|
||||
|
||||
set(CPLD_20170522_SVF_PATH ${HARDWARE_PATH}/portapack_h1/cpld/20170522/output_files/portapack_h1_cpld.svf)
|
||||
set(CPLD_20170522_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/portapack_cpld_20170522_data.cpp)
|
||||
|
||||
set(HACKRF_CPLD_DATA_HPP ${CMAKE_CURRENT_BINARY_DIR}/hackrf_cpld_data.hpp)
|
||||
set(HACKRF_CPLD_DATA_CPP ${CMAKE_CURRENT_BINARY_DIR}/hackrf_cpld_data.cpp)
|
||||
@ -123,8 +126,9 @@ set(CPPSRC
|
||||
clock_manager.cpp
|
||||
si5351.cpp
|
||||
${COMMON}/wm8731.cpp
|
||||
${COMMON}/ak4951.cpp
|
||||
radio.cpp
|
||||
baseband_cpld.cpp
|
||||
${COMMON}/baseband_cpld.cpp
|
||||
tuning.cpp
|
||||
rf_path.cpp
|
||||
rffc507x.cpp
|
||||
@ -242,8 +246,9 @@ set(CPPSRC
|
||||
${COMMON}/cpld_xilinx.cpp
|
||||
${COMMON}/jtag.cpp
|
||||
${COMMON}/jtag_tap.cpp
|
||||
cpld_update.cpp
|
||||
${CPLD_DATA_CPP}
|
||||
${COMMON}/cpld_update.cpp
|
||||
${CPLD_20150901_DATA_CPP}
|
||||
${CPLD_20170522_DATA_CPP}
|
||||
${HACKRF_CPLD_DATA_CPP}
|
||||
)
|
||||
|
||||
@ -362,14 +367,20 @@ include(${RULESPATH}/rules.cmake)
|
||||
##############################################################################
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CPLD_DATA_CPP}
|
||||
COMMAND ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH} >${CPLD_DATA_CPP}
|
||||
DEPENDS ${EXTRACT_CPLD_DATA} ${CPLD_SVF_PATH}
|
||||
OUTPUT ${CPLD_20150901_DATA_CPP}
|
||||
COMMAND ${EXTRACT_CPLD_DATA} ${CPLD_20150901_SVF_PATH} rev_20150901 >${CPLD_20150901_DATA_CPP}
|
||||
DEPENDS ${EXTRACT_CPLD_DATA} ${CPLD_20150901_SVF_PATH}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CPLD_20170522_DATA_CPP}
|
||||
COMMAND ${EXTRACT_CPLD_DATA} ${CPLD_20170522_SVF_PATH} rev_20170522 >${CPLD_20170522_DATA_CPP}
|
||||
DEPENDS ${EXTRACT_CPLD_DATA} ${CPLD_20170522_SVF_PATH}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP}
|
||||
COMMAND ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH} hackrf::one::cpld::verify_blocks ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP}
|
||||
COMMAND ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH} hackrf::one::cpld::verify_blocks ${HACKRF_CPLD_DATA_CPP}
|
||||
DEPENDS ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH}
|
||||
)
|
||||
|
||||
|
@ -23,11 +23,9 @@
|
||||
#include "audio.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
using portapack::i2c0;
|
||||
using portapack::clock_manager;
|
||||
|
||||
#include "wm8731.hpp"
|
||||
using wolfson::wm8731::WM8731;
|
||||
#include "portapack_hal.hpp"
|
||||
|
||||
#include "i2s.hpp"
|
||||
using namespace lpc43xx;
|
||||
@ -98,24 +96,10 @@ constexpr i2s::ConfigDMA i2s0_config_dma {
|
||||
},
|
||||
};
|
||||
|
||||
constexpr uint8_t wm8731_i2c_address = 0x1a;
|
||||
|
||||
WM8731 audio_codec { i2c0, wm8731_i2c_address };
|
||||
static audio::Codec* audio_codec = nullptr;
|
||||
|
||||
} /* namespace */
|
||||
|
||||
namespace input {
|
||||
|
||||
void start() {
|
||||
i2s::i2s0::rx_start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
i2s::i2s0::rx_stop();
|
||||
}
|
||||
|
||||
} /* namespace input */
|
||||
|
||||
namespace output {
|
||||
|
||||
void start() {
|
||||
@ -130,53 +114,80 @@ void stop() {
|
||||
|
||||
void mute() {
|
||||
i2s::i2s0::tx_mute();
|
||||
|
||||
audio_codec.headphone_mute();
|
||||
audio_codec->headphone_disable();
|
||||
}
|
||||
|
||||
void unmute() {
|
||||
i2s::i2s0::tx_unmute();
|
||||
audio_codec->headphone_enable();
|
||||
}
|
||||
|
||||
} /* namespace output */
|
||||
|
||||
namespace input {
|
||||
|
||||
void start() {
|
||||
audio_codec->microphone_enable();
|
||||
i2s::i2s0::rx_start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
i2s::i2s0::rx_stop();
|
||||
audio_codec->microphone_disable();
|
||||
}
|
||||
|
||||
} /* namespace input */
|
||||
|
||||
namespace headphone {
|
||||
|
||||
volume_range_t volume_range() {
|
||||
return wolfson::wm8731::headphone_gain_range;
|
||||
return audio_codec->headphone_gain_range();
|
||||
}
|
||||
|
||||
void set_volume(const volume_t volume) {
|
||||
audio_codec.set_headphone_volume(volume);
|
||||
audio_codec->set_headphone_volume(volume);
|
||||
}
|
||||
|
||||
} /* namespace headphone */
|
||||
|
||||
namespace debug {
|
||||
|
||||
int reg_count() {
|
||||
return wolfson::wm8731::reg_count;
|
||||
size_t reg_count() {
|
||||
return audio_codec->reg_count();
|
||||
}
|
||||
|
||||
uint16_t reg_read(const int register_number) {
|
||||
return audio_codec.read(register_number);
|
||||
uint32_t reg_read(const size_t register_number) {
|
||||
return audio_codec->reg_read(register_number);
|
||||
}
|
||||
|
||||
std::string codec_name() {
|
||||
return audio_codec->name();
|
||||
}
|
||||
|
||||
size_t reg_bits() {
|
||||
return audio_codec->reg_bits();
|
||||
}
|
||||
|
||||
} /* namespace debug */
|
||||
|
||||
void init() {
|
||||
void init(audio::Codec* const codec) {
|
||||
audio_codec = codec;
|
||||
|
||||
clock_manager.start_audio_pll();
|
||||
audio_codec.init();
|
||||
audio_codec->init();
|
||||
|
||||
i2s::i2s0::configure(
|
||||
i2s0_config_tx,
|
||||
i2s0_config_rx,
|
||||
i2s0_config_dma
|
||||
);
|
||||
|
||||
// Set pin mode, since it's likely GPIO (as left after CPLD JTAG interactions).
|
||||
portapack::pin_i2s0_rx_sda.mode(3);
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
audio_codec.reset();
|
||||
audio_codec->reset();
|
||||
output::stop();
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,34 @@
|
||||
#include "volume.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace audio {
|
||||
|
||||
class Codec {
|
||||
public:
|
||||
virtual ~Codec() { }
|
||||
|
||||
virtual std::string name() const = 0;
|
||||
|
||||
virtual bool reset() = 0;
|
||||
virtual void init() = 0;
|
||||
|
||||
virtual void headphone_enable() = 0;
|
||||
virtual void headphone_disable() = 0;
|
||||
virtual volume_range_t headphone_gain_range() const = 0;
|
||||
virtual void set_headphone_volume(const volume_t volume) = 0;
|
||||
|
||||
virtual void microphone_enable() = 0;
|
||||
virtual void microphone_disable() = 0;
|
||||
|
||||
virtual size_t reg_count() const = 0;
|
||||
virtual size_t reg_bits() const = 0;
|
||||
virtual uint32_t reg_read(const size_t register_number) = 0;
|
||||
};
|
||||
|
||||
namespace output {
|
||||
|
||||
void start();
|
||||
@ -56,12 +81,14 @@ void set_volume(const volume_t volume);
|
||||
|
||||
namespace debug {
|
||||
|
||||
int reg_count();
|
||||
uint16_t reg_read(const int register_number);
|
||||
size_t reg_count();
|
||||
uint32_t reg_read(const size_t register_number);
|
||||
std::string codec_name();
|
||||
size_t reg_bits();
|
||||
|
||||
} /* namespace debug */
|
||||
|
||||
void init();
|
||||
void init(audio::Codec* const codec);
|
||||
void shutdown();
|
||||
|
||||
enum class Rate {
|
||||
|
@ -5,7 +5,7 @@
|
||||
/ FatFs - FAT file system module configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FFCONF 80186 /* Revision ID */
|
||||
#define _FFCONF 68300 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
@ -76,7 +76,7 @@
|
||||
/* 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.
|
||||
/
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 1 - ASCII (No support of extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
@ -151,7 +151,7 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
@ -175,11 +175,11 @@
|
||||
#define _MIN_SS 512
|
||||
#define _MAX_SS 512
|
||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||
/ 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
/ to variable sector size and GET_SECTOR_SIZE command needs to be implemented to
|
||||
/ the disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _USE_TRIM 0
|
||||
@ -207,15 +207,15 @@
|
||||
|
||||
#define _FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS bytes.
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked _MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define _FS_EXFAT 0
|
||||
/* This option switches support of exFAT file system in addition to the traditional
|
||||
/ FAT file system. (0:Disable or 1:Enable) To enable exFAT, also LFN must be enabled.
|
||||
/ Note that enabling exFAT discards C89 compatibility. */
|
||||
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define _FS_NORTC 0
|
||||
@ -228,7 +228,7 @@
|
||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
|
||||
|
||||
|
||||
@ -261,8 +261,11 @@
|
||||
/
|
||||
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.c. */
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
@ -130,23 +130,23 @@ static void event_loop() {
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
portapack::init();
|
||||
if( portapack::init() ) {
|
||||
portapack::display.init();
|
||||
|
||||
portapack::io.init();
|
||||
portapack::display.init();
|
||||
sdcStart(&SDCD1, nullptr);
|
||||
|
||||
sdcStart(&SDCD1, nullptr);
|
||||
controls_init();
|
||||
lcd_frame_sync_configure();
|
||||
rtc_interrupt_enable();
|
||||
|
||||
controls_init();
|
||||
lcd_frame_sync_configure();
|
||||
rtc_interrupt_enable();
|
||||
event_loop();
|
||||
|
||||
event_loop();
|
||||
sdcDisconnect(&SDCD1);
|
||||
sdcStop(&SDCD1);
|
||||
|
||||
sdcDisconnect(&SDCD1);
|
||||
sdcStop(&SDCD1);
|
||||
portapack::shutdown();
|
||||
}
|
||||
|
||||
portapack::shutdown();
|
||||
m4_init(portapack::spi_flash::image_tag_hackrf, portapack::memory::map::m4_code_hackrf);
|
||||
m0_halt();
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_hal.hpp"
|
||||
#include "portapack_dma.hpp"
|
||||
#include "portapack_cpld_data.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include "hackrf_hal.hpp"
|
||||
@ -32,8 +34,16 @@ using namespace hackrf::one;
|
||||
#include "touch_adc.hpp"
|
||||
#include "audio.hpp"
|
||||
|
||||
#include "wm8731.hpp"
|
||||
using wolfson::wm8731::WM8731;
|
||||
|
||||
#include "ak4951.hpp"
|
||||
using asahi_kasei::ak4951::AK4951;
|
||||
|
||||
#include "cpld_update.hpp"
|
||||
|
||||
#include "optional.hpp"
|
||||
|
||||
namespace portapack {
|
||||
|
||||
portapack::IO io {
|
||||
@ -60,6 +70,9 @@ ClockManager clock_manager {
|
||||
i2c0, clock_generator
|
||||
};
|
||||
|
||||
WM8731 audio_codec_wm8731 { i2c0, 0x1a };
|
||||
AK4951 audio_codec_ak4951 { i2c0, 0x12 };
|
||||
|
||||
ReceiverModel receiver_model;
|
||||
|
||||
TemperatureLogger temperature_logger;
|
||||
@ -106,7 +119,53 @@ private:
|
||||
|
||||
static Power power;
|
||||
|
||||
void init() {
|
||||
enum class PortaPackModel {
|
||||
R1_20150901,
|
||||
R2_20170522,
|
||||
};
|
||||
|
||||
static PortaPackModel portapack_model() {
|
||||
static Optional<PortaPackModel> model;
|
||||
|
||||
if( !model.is_valid() ) {
|
||||
if( audio_codec_wm8731.detected() ) {
|
||||
model = PortaPackModel::R1_20150901;
|
||||
} else {
|
||||
model = PortaPackModel::R2_20170522;
|
||||
}
|
||||
}
|
||||
|
||||
return model.value();
|
||||
}
|
||||
|
||||
static audio::Codec* portapack_audio_codec() {
|
||||
return (portapack_model() == PortaPackModel::R2_20170522)
|
||||
? static_cast<audio::Codec*>(&audio_codec_ak4951)
|
||||
: static_cast<audio::Codec*>(&audio_codec_wm8731)
|
||||
;
|
||||
}
|
||||
|
||||
static const portapack::cpld::Config& portapack_cpld_config() {
|
||||
return (portapack_model() == PortaPackModel::R2_20170522)
|
||||
? portapack::cpld::rev_20170522::config
|
||||
: portapack::cpld::rev_20150901::config
|
||||
;
|
||||
}
|
||||
|
||||
static void shutdown_base() {
|
||||
clock_manager.shutdown();
|
||||
|
||||
power.shutdown();
|
||||
// TODO: Wait a bit for supplies to discharge?
|
||||
|
||||
chSysDisable();
|
||||
|
||||
systick_stop();
|
||||
|
||||
hackrf::one::reset();
|
||||
}
|
||||
|
||||
bool init() {
|
||||
for(const auto& pin : pins) {
|
||||
pin.init();
|
||||
}
|
||||
@ -147,7 +206,18 @@ void init() {
|
||||
clock_manager.set_reference_ppb(persistent_memory::correction_ppb());
|
||||
clock_manager.run_at_full_speed();
|
||||
|
||||
audio::init();
|
||||
if( !portapack::cpld::update_if_necessary(portapack_cpld_config()) ) {
|
||||
shutdown_base();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !hackrf::cpld::load_sram() ) {
|
||||
chSysHalt();
|
||||
}
|
||||
|
||||
portapack::io.init();
|
||||
|
||||
audio::init(portapack_audio_codec());
|
||||
|
||||
clock_manager.enable_first_if_clock();
|
||||
clock_manager.enable_second_if_clock();
|
||||
@ -156,33 +226,23 @@ void init() {
|
||||
|
||||
touch::adc::init();
|
||||
|
||||
if( !cpld_update_if_necessary() ) {
|
||||
chSysHalt();
|
||||
}
|
||||
LPC_CREG->DMAMUX = portapack::gpdma_mux;
|
||||
gpdma::controller.enable();
|
||||
|
||||
if( !cpld_hackrf_load_sram() ) {
|
||||
chSysHalt();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
gpdma::controller.disable();
|
||||
|
||||
display.shutdown();
|
||||
|
||||
radio::disable();
|
||||
audio::shutdown();
|
||||
|
||||
cpld_hackrf_init_from_eeprom();
|
||||
hackrf::cpld::init_from_eeprom();
|
||||
|
||||
clock_manager.shutdown();
|
||||
|
||||
power.shutdown();
|
||||
// TODO: Wait a bit for supplies to discharge?
|
||||
|
||||
chSysDisable();
|
||||
|
||||
systick_stop();
|
||||
|
||||
hackrf::one::reset();
|
||||
shutdown_base();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
@ -53,7 +53,7 @@ extern uint8_t bl_tick_counter;
|
||||
|
||||
extern TemperatureLogger temperature_logger;
|
||||
|
||||
void init();
|
||||
bool init();
|
||||
void shutdown();
|
||||
|
||||
} /* namespace portapack */
|
||||
|
@ -132,8 +132,6 @@ AboutView::AboutView(
|
||||
NavigationView& nav
|
||||
)
|
||||
{
|
||||
//uint8_t p, c;
|
||||
|
||||
add_children({
|
||||
&text_cpld_hackrf,
|
||||
&text_cpld_hackrf_status,
|
||||
@ -150,13 +148,13 @@ AboutView::AboutView(
|
||||
add_child(&text);
|
||||
}
|
||||
|
||||
if( cpld_hackrf_verify_eeprom() ) {
|
||||
if( hackrf::cpld::verify_eeprom() ) {
|
||||
text_cpld_hackrf_status.set(" OK");
|
||||
} else {
|
||||
text_cpld_hackrf_status.set("BAD");
|
||||
}
|
||||
|
||||
button_ok.on_select = [this,&nav](Button&){
|
||||
button_ok.on_select = [&nav](Button&){
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ ADSBTxView::ADSBTxView(NavigationView& nav) {
|
||||
generate_frame();
|
||||
};
|
||||
button_callsign.on_select = [this, &nav](Button&) {
|
||||
text_entry(nav, &callsign, 9);
|
||||
text_prompt(nav, &callsign, 9);
|
||||
};
|
||||
|
||||
field_altitude.set_value(11000);
|
||||
|
@ -26,11 +26,8 @@
|
||||
#include "hackrf_hal.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace hackrf::one;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void AlphanumView::paint(Painter&) {
|
||||
@ -41,23 +38,14 @@ AlphanumView::AlphanumView(
|
||||
NavigationView& nav,
|
||||
std::string * str,
|
||||
size_t max_length
|
||||
) : _max_length(max_length),
|
||||
_str(str)
|
||||
) : TextEntryView(nav, str, max_length)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
// Trim from right
|
||||
_str->erase(std::find_if(_str->rbegin(), _str->rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _str->end());
|
||||
cursor_pos = _str->length();
|
||||
|
||||
_str->resize(_max_length, 0);
|
||||
|
||||
add_children({
|
||||
&text_input,
|
||||
&button_mode,
|
||||
&text_raw,
|
||||
&field_raw,
|
||||
&button_ok
|
||||
&field_raw
|
||||
});
|
||||
|
||||
const auto button_fn = [this](Button& button) {
|
||||
@ -97,22 +85,6 @@ AlphanumView::AlphanumView(
|
||||
update_text();
|
||||
}
|
||||
|
||||
void AlphanumView::draw_cursor() {
|
||||
Point draw_pos;
|
||||
|
||||
draw_pos = {text_input.screen_rect().location().x() + 8 + std::min((Coord)cursor_pos, (Coord)28) * 8,
|
||||
text_input.screen_rect().location().y() + 16};
|
||||
|
||||
portapack::display.fill_rectangle(
|
||||
{{text_input.screen_rect().location().x(), draw_pos.y()}, {text_input.screen_rect().size().width(), 4}},
|
||||
Color::black()
|
||||
);
|
||||
portapack::display.fill_rectangle(
|
||||
{draw_pos, {8, 4}},
|
||||
Color::white()
|
||||
);
|
||||
}
|
||||
|
||||
void AlphanumView::set_mode(const uint32_t new_mode) {
|
||||
size_t n = 0;
|
||||
|
||||
@ -137,10 +109,6 @@ void AlphanumView::set_mode(const uint32_t new_mode) {
|
||||
button_mode.set_text(key_sets[0].first);
|
||||
}
|
||||
|
||||
void AlphanumView::focus() {
|
||||
button_ok.focus();
|
||||
}
|
||||
|
||||
void AlphanumView::on_button(Button& button) {
|
||||
const auto c = button.text()[0];
|
||||
|
||||
@ -152,27 +120,4 @@ void AlphanumView::on_button(Button& button) {
|
||||
update_text();
|
||||
}
|
||||
|
||||
void AlphanumView::char_add(const char c) {
|
||||
if (cursor_pos >= _max_length) return;
|
||||
|
||||
_str->replace(cursor_pos, 1, 1, c);
|
||||
cursor_pos++;
|
||||
}
|
||||
|
||||
void AlphanumView::char_delete() {
|
||||
if (!cursor_pos) return;
|
||||
|
||||
cursor_pos--;
|
||||
_str->replace(cursor_pos, 1, 1, 0);
|
||||
}
|
||||
|
||||
void AlphanumView::update_text() {
|
||||
if (cursor_pos <= 28)
|
||||
text_input.set(' ' + *_str + std::string(_max_length - _str->length(), ' '));
|
||||
else
|
||||
text_input.set('<' + _str->substr(cursor_pos - 28, 28));
|
||||
|
||||
draw_cursor();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,16 +26,13 @@
|
||||
#include "ui.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_painter.hpp"
|
||||
#include "ui_textentry.hpp"
|
||||
#include "ui_menu.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_font_fixed_8x16.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class AlphanumView : public View {
|
||||
class AlphanumView : public TextEntryView {
|
||||
public:
|
||||
std::function<void(std::string*)> on_changed { };
|
||||
|
||||
AlphanumView(NavigationView& nav, std::string * str, size_t max_length);
|
||||
|
||||
AlphanumView(const AlphanumView&) = delete;
|
||||
@ -44,9 +41,6 @@ public:
|
||||
AlphanumView& operator=(AlphanumView&&) = delete;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Text entry"; };
|
||||
|
||||
private:
|
||||
const char * const keys_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ' .<";
|
||||
@ -59,21 +53,10 @@ private:
|
||||
{ "Digit", keys_digit }
|
||||
};
|
||||
|
||||
size_t _max_length { };
|
||||
uint32_t cursor_pos { 0 };
|
||||
uint32_t mode = 0; // Uppercase
|
||||
std::string * _str { };
|
||||
uint32_t mode = 0; // Uppercase
|
||||
|
||||
void char_add(const char c);
|
||||
void char_delete();
|
||||
void set_mode(const uint32_t new_mode);
|
||||
void draw_cursor();
|
||||
void on_button(Button& button);
|
||||
void update_text();
|
||||
|
||||
Text text_input {
|
||||
{ 0, 0, 240, 16 }
|
||||
};
|
||||
|
||||
std::array<Button, 30> buttons { };
|
||||
|
||||
|
@ -173,12 +173,12 @@ void RegistersWidget::paint(Painter& painter) {
|
||||
void RegistersWidget::draw_legend(const Coord left, Painter& painter) {
|
||||
const auto pos = screen_pos();
|
||||
|
||||
for(int i=0; i<config.registers_count; i+=config.registers_per_row) {
|
||||
for(int i=0; i<config.registers_count; i+=config.registers_per_row()) {
|
||||
const Point offset {
|
||||
left, (i / config.registers_per_row) * row_height
|
||||
left, (i / config.registers_per_row()) * row_height
|
||||
};
|
||||
|
||||
const auto text = to_string_hex(i, config.legend_length);
|
||||
const auto text = to_string_hex(i, config.legend_length());
|
||||
painter.draw_string(
|
||||
pos + offset,
|
||||
style().invert(),
|
||||
@ -195,13 +195,13 @@ void RegistersWidget::draw_values(
|
||||
|
||||
for(int i=0; i<config.registers_count; i++) {
|
||||
const Point offset = {
|
||||
left + config.legend_width() + 8 + (i % config.registers_per_row) * (config.value_width() + 8),
|
||||
(i / config.registers_per_row) * row_height
|
||||
left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8),
|
||||
(i / config.registers_per_row()) * row_height
|
||||
};
|
||||
|
||||
const auto value = reader(i);
|
||||
|
||||
const auto text = to_string_hex(value, config.value_length);
|
||||
const auto text = to_string_hex(value, config.value_length());
|
||||
painter.draw_string(
|
||||
pos + offset,
|
||||
style(),
|
||||
@ -247,37 +247,37 @@ void RegistersView::focus() {
|
||||
/* DebugPeripheralsMenuView **********************************************/
|
||||
|
||||
DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) {
|
||||
add_items<4>({ {
|
||||
{ "RFFC5072", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"RFFC5072", RegistersWidgetConfig { 31, 2, 4, 4 },
|
||||
add_items({
|
||||
{ "RFFC5072", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"RFFC5072", RegistersWidgetConfig { 31, 16 },
|
||||
[](const size_t register_number) { return radio::debug::first_if::register_read(register_number); }
|
||||
); } },
|
||||
{ "MAX2837", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"MAX2837", RegistersWidgetConfig { 32, 2, 3, 4 },
|
||||
{ "MAX2837", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"MAX2837", RegistersWidgetConfig { 32, 10 },
|
||||
[](const size_t register_number) { return radio::debug::second_if::register_read(register_number); }
|
||||
); } },
|
||||
{ "Si5351C", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"Si5351C", RegistersWidgetConfig { 96, 2, 2, 8 },
|
||||
{ "Si5351C", ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"Si5351C", RegistersWidgetConfig { 96, 8 },
|
||||
[](const size_t register_number) { return portapack::clock_generator.read_register(register_number); }
|
||||
); } },
|
||||
{ "WM8731",ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
"WM8731", RegistersWidgetConfig { audio::debug::reg_count(), 1, 3, 4 },
|
||||
{ audio::debug::codec_name(), ui::Color::white(), nullptr, [&nav](){ nav.push<RegistersView>(
|
||||
audio::debug::codec_name(), RegistersWidgetConfig { audio::debug::reg_count(), audio::debug::reg_bits() },
|
||||
[](const size_t register_number) { return audio::debug::reg_read(register_number); }
|
||||
); } },
|
||||
} });
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
||||
/* DebugMenuView *********************************************************/
|
||||
|
||||
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
add_items<4>({ {
|
||||
add_items({
|
||||
{ "Memory", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugMemoryView>(); } },
|
||||
{ "Radio State", ui::Color::white(), nullptr, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
//{ "SD Card", ui::Color::white(), nullptr, [&nav](){ nav.push<SDCardDebugView>(); } },
|
||||
{ "Peripherals", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugPeripheralsMenuView>(); } },
|
||||
{ "Temperature", ui::Color::white(), nullptr, [&nav](){ nav.push<TemperatureView>(); } },
|
||||
} });
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
||||
|
@ -131,20 +131,30 @@ private:
|
||||
|
||||
struct RegistersWidgetConfig {
|
||||
int registers_count;
|
||||
int legend_length;
|
||||
int value_length;
|
||||
int registers_per_row;
|
||||
int register_bits;
|
||||
|
||||
constexpr int legend_length() const {
|
||||
return (registers_count >= 0x10) ? 2 : 1;
|
||||
}
|
||||
|
||||
constexpr int legend_width() const {
|
||||
return legend_length * 8;
|
||||
return legend_length() * 8;
|
||||
}
|
||||
|
||||
constexpr int value_length() const {
|
||||
return (register_bits + 3) / 4;
|
||||
}
|
||||
|
||||
constexpr int value_width() const {
|
||||
return value_length * 8;
|
||||
return value_length() * 8;
|
||||
}
|
||||
|
||||
constexpr int registers_per_row() const {
|
||||
return (value_length() >= 3) ? 4 : 8;
|
||||
}
|
||||
|
||||
constexpr int registers_row_length() const {
|
||||
return (registers_per_row * (value_length + 1)) - 1;
|
||||
return (registers_per_row() * (value_length() + 1)) - 1;
|
||||
}
|
||||
|
||||
constexpr int registers_row_width() const {
|
||||
@ -156,7 +166,7 @@ struct RegistersWidgetConfig {
|
||||
}
|
||||
|
||||
constexpr int rows() const {
|
||||
return registers_count / registers_per_row;
|
||||
return registers_count / registers_per_row();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -25,14 +25,12 @@
|
||||
#include "portapack.hpp"
|
||||
#include "event_m0.hpp"
|
||||
|
||||
//#include <cstring>
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void FrequencySaveView::on_save_name() {
|
||||
text_entry(nav_, &desc_buffer, 7, [this](std::string * buffer) {
|
||||
text_prompt(nav_, &desc_buffer, 7, [this](std::string * buffer) {
|
||||
database.entries.push_back({ value_, "", *buffer, (int32_t)options_category.selected_index_value() });
|
||||
nav_.pop();
|
||||
});
|
||||
@ -209,7 +207,7 @@ void FreqManView::on_edit_freq(rf::Frequency f) {
|
||||
}
|
||||
|
||||
void FreqManView::on_edit_desc(NavigationView& nav) {
|
||||
text_entry(nav, &desc_buffer, 28, [this](std::string * buffer) {
|
||||
text_prompt(nav, &desc_buffer, 28, [this](std::string * buffer) {
|
||||
database.entries[menu_view.highlighted()].description = *buffer;
|
||||
//setup_list();
|
||||
});
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "hackrf_hal.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
@ -40,24 +40,15 @@ HandWriteView::HandWriteView(
|
||||
NavigationView& nav,
|
||||
std::string * str,
|
||||
size_t max_length
|
||||
) : _max_length(max_length),
|
||||
_str(str)
|
||||
) : TextEntryView(nav, str, max_length)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
// Trim from right
|
||||
_str->erase(std::find_if(_str->rbegin(), _str->rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _str->end());
|
||||
cursor_pos = _str->length();
|
||||
|
||||
_str->resize(_max_length, 0);
|
||||
|
||||
// Handwriting alphabet definition here
|
||||
handwriting = &handwriting_unistroke;
|
||||
|
||||
add_children({
|
||||
&text_input,
|
||||
&button_case,
|
||||
&button_ok
|
||||
&button_case
|
||||
});
|
||||
|
||||
const auto button_fn = [this](Button& button) {
|
||||
@ -224,9 +215,8 @@ void HandWriteView::guess_letter() {
|
||||
char_add('A' + symbol - 1);
|
||||
clear_zone(Color::green(), true); // Green flash
|
||||
} else {
|
||||
if (cursor_pos) {
|
||||
cursor_pos--;
|
||||
_str->replace(cursor_pos, 1, 1, 0);
|
||||
if (_cursor_pos) {
|
||||
char_delete();
|
||||
clear_zone(Color::yellow(), true); // Yellow flash
|
||||
} else {
|
||||
clear_zone(Color::red(), true); // Red flash
|
||||
@ -257,26 +247,7 @@ void HandWriteView::sample_pen() {
|
||||
int16_t diff_x, diff_y;
|
||||
uint8_t dir, dir_ud, dir_lr, stroke_prev;
|
||||
|
||||
// Blink cursor
|
||||
if (!(sample_skip & 15)) {
|
||||
Point draw_pos;
|
||||
|
||||
draw_pos = {text_input.screen_rect().location().x() + 8 + std::min((Coord)cursor_pos, (Coord)28) * 8,
|
||||
text_input.screen_rect().location().y() + 16 - 4};
|
||||
|
||||
if (cursor) {
|
||||
display.fill_rectangle(
|
||||
{draw_pos, {text_input.screen_rect().size().width() - draw_pos.x(), 4}},
|
||||
Color::black()
|
||||
);
|
||||
} else {
|
||||
display.fill_rectangle(
|
||||
{draw_pos, {8, 4}},
|
||||
Color::white()
|
||||
);
|
||||
}
|
||||
cursor = !cursor;
|
||||
}
|
||||
draw_cursor();
|
||||
|
||||
if (flash_timer) {
|
||||
if (flash_timer == 1) clear_zone(Color::black(), false);
|
||||
@ -385,18 +356,4 @@ void HandWriteView::on_button(Button& button) {
|
||||
update_text();
|
||||
}
|
||||
|
||||
void HandWriteView::char_add(const char c) {
|
||||
if (cursor_pos >= _max_length) return;
|
||||
|
||||
_str->replace(cursor_pos, 1, 1, c);
|
||||
cursor_pos++;
|
||||
}
|
||||
|
||||
void HandWriteView::update_text() {
|
||||
if (cursor_pos <= 28)
|
||||
text_input.set(' ' + *_str + std::string(_max_length - _str->length(), ' '));
|
||||
else
|
||||
text_input.set('<' + _str->substr(cursor_pos - 28, 28));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,58 +26,44 @@
|
||||
#include "ui.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_painter.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_textentry.hpp"
|
||||
#include "unistroke.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class HandWriteView : public View {
|
||||
class HandWriteView : public TextEntryView {
|
||||
public:
|
||||
std::function<void(std::string*)> on_changed { };
|
||||
|
||||
HandWriteView(NavigationView& nav, std::string * str, size_t max_length);
|
||||
|
||||
|
||||
HandWriteView(const HandWriteView&) = delete;
|
||||
HandWriteView(HandWriteView&&) = delete;
|
||||
HandWriteView& operator=(const HandWriteView&) = delete;
|
||||
HandWriteView& operator=(HandWriteView&&) = delete;
|
||||
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
void on_show() override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
|
||||
std::string title() const override { return "Text entry"; };
|
||||
|
||||
private:
|
||||
const char special_chars[5] = {'\'', '.', '?', '!', '='};
|
||||
const char special_chars[5] = { '\'', '.', '?', '!', '=' };
|
||||
|
||||
const HandWriting * handwriting { };
|
||||
Painter * _painter { };
|
||||
size_t _max_length;
|
||||
uint8_t dir_cnt { 0 };
|
||||
uint8_t dir_prev { 0 };
|
||||
uint8_t flash_timer { 0 };
|
||||
uint32_t cursor_pos { 0 };
|
||||
bool cursor { false };
|
||||
bool tracing { false };
|
||||
uint8_t stroke_index { 0 };
|
||||
uint8_t sample_skip { 0 }, move_wait { 0 };
|
||||
uint8_t stroke_list[8];
|
||||
Point start_pos { }, current_pos { }, last_pos { };
|
||||
bool _lowercase = false;
|
||||
std::string * _str { };
|
||||
|
||||
void sample_pen();
|
||||
void add_stroke(uint8_t dir);
|
||||
void guess_letter();
|
||||
void clear_zone(const Color color, const bool flash);
|
||||
void char_add(const char c);
|
||||
void on_button(Button& button);
|
||||
void update_text();
|
||||
|
||||
Text text_input {
|
||||
{ 8, 0, 232, 16 }
|
||||
};
|
||||
|
||||
std::array<Button, 10> num_buttons { };
|
||||
std::array<Button, 5> special_buttons { };
|
||||
|
@ -186,7 +186,7 @@ void LCRView::start_tx(const bool scan) {
|
||||
}
|
||||
|
||||
void LCRView::on_button_setam(NavigationView& nav, Button& button) {
|
||||
text_entry(nav, &litteral[button.id], 7);
|
||||
text_prompt(nav, &litteral[button.id], 7);
|
||||
}
|
||||
|
||||
LCRView::LCRView(NavigationView& nav) {
|
||||
@ -263,7 +263,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
button_scan.set_style(&style_val);
|
||||
|
||||
button_setrgsb.on_select = [this,&nav](Button&) {
|
||||
text_entry(nav, &rgsb, 4);
|
||||
text_prompt(nav, &rgsb, 4);
|
||||
};
|
||||
|
||||
button_txsetup.on_select = [&nav](Button&) {
|
||||
|
@ -138,11 +138,17 @@ void MenuView::clear() {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuView::add_item(const MenuItem item) {
|
||||
void MenuView::add_item(MenuItem item) {
|
||||
add_child(new MenuItemView { item, keep_highlight_ });
|
||||
update_items();
|
||||
}
|
||||
|
||||
void MenuView::add_items(std::initializer_list<MenuItem> items) {
|
||||
for(auto item : items) {
|
||||
add_item(item);
|
||||
}
|
||||
}
|
||||
|
||||
void MenuView::update_items() {
|
||||
size_t i = 0;
|
||||
int32_t y_pos;
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
MenuItemView(
|
||||
MenuItem item,
|
||||
bool keep_highlight
|
||||
) : item(item),
|
||||
) : item { item },
|
||||
keep_highlight_ { keep_highlight }
|
||||
{
|
||||
}
|
||||
@ -75,15 +75,9 @@ public:
|
||||
|
||||
~MenuView();
|
||||
|
||||
void add_item(const MenuItem item);
|
||||
void add_item(MenuItem item);
|
||||
void add_items(std::initializer_list<MenuItem> items);
|
||||
void clear();
|
||||
|
||||
template<size_t N>
|
||||
void add_items(const std::array<MenuItem, N>& items) {
|
||||
for (const auto& item : items) {
|
||||
add_item(item);
|
||||
}
|
||||
}
|
||||
|
||||
MenuItemView* item_view(size_t index) const;
|
||||
|
||||
|
@ -71,7 +71,7 @@ static msg_t ookthread_fn(void * arg) {
|
||||
}
|
||||
|
||||
void MorseView::on_set_text(NavigationView& nav) {
|
||||
text_entry(nav, &buffer, 28);
|
||||
text_prompt(nav, &buffer, 28);
|
||||
}
|
||||
|
||||
void MorseView::focus() {
|
||||
|
@ -281,7 +281,7 @@ void NavigationView::focus() {
|
||||
/* ReceiversMenuView *****************************************************/
|
||||
|
||||
ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
|
||||
add_items<9>({ {
|
||||
add_items({
|
||||
{ "ADS-B: Planes", ui::Color::grey(), &bitmap_icon_adsb, [&nav](){ nav.push<NotImplementedView>(); }, },
|
||||
{ "AIS: Boats", ui::Color::green(), &bitmap_icon_ais, [&nav](){ nav.push<AISAppView>(); } },
|
||||
{ "APRS", ui::Color::grey(), &bitmap_icon_aprs, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
@ -291,14 +291,14 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
|
||||
{ "SIGFOX", ui::Color::grey(), &bitmap_icon_fox, [&nav](){ nav.push<NotImplementedView>(); } }, // SIGFRXView
|
||||
{ "SSTV", ui::Color::grey(), &bitmap_icon_sstv, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "TPMS: Cars", ui::Color::green(), &bitmap_icon_tpms, [&nav](){ nav.push<TPMSAppView>(); } },
|
||||
} });
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
||||
/* TransmittersMenuView **************************************************/
|
||||
|
||||
TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
|
||||
add_items<16>({ {
|
||||
add_items({
|
||||
{ "ADS-B Mode S", ui::Color::orange(), &bitmap_icon_adsb, [&nav](){ nav.push<ADSBTxView>(); } },
|
||||
{ "APRS", ui::Color::grey(), &bitmap_icon_aprs, [&nav](){ nav.push<APRSTXView>(); } },
|
||||
{ "BHT Xy/EP", ui::Color::green(), &bitmap_icon_bht, [&nav](){ nav.push<BHTView>(); } },
|
||||
@ -315,20 +315,20 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
|
||||
{ "SSTV", ui::Color::green(), &bitmap_icon_sstv, [&nav](){ nav.push<SSTVTXView>(); } },
|
||||
{ "TEDI/LCR AFSK", ui::Color::yellow(), &bitmap_icon_lcr, [&nav](){ nav.push<LCRView>(); } },
|
||||
{ "Whistle", ui::Color::green(), &bitmap_icon_whistle, [&nav](){ nav.push<WhistleView>(); } },
|
||||
} });
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
||||
/* UtilitiesMenuView *****************************************************/
|
||||
|
||||
UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) {
|
||||
add_items<5>({ {
|
||||
add_items({
|
||||
{ "Frequency manager", ui::Color::green(), &bitmap_icon_freqman, [&nav](){ nav.push<FreqManView>(); } },
|
||||
{ "CW generator", ui::Color::green(), &bitmap_icon_cwgen, [&nav](){ nav.push<CWTXView>(); } },
|
||||
{ "Whip antenna length", ui::Color::yellow(),nullptr, [&nav](){ nav.push<WhipCalcView>(); } },
|
||||
{ "Notepad", ui::Color::grey(), &bitmap_icon_notepad, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "Wipe SD card", ui::Color::red(), nullptr, [&nav](){ nav.push<WipeSDView>(); } },
|
||||
} });
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
||||
@ -345,7 +345,7 @@ void SystemMenuView::hackrf_mode(NavigationView& nav) {
|
||||
}
|
||||
|
||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items<10>({ {
|
||||
add_items({
|
||||
{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<PlayDeadView>(); } },
|
||||
{ "Receivers", ui::Color::cyan(), &bitmap_icon_receivers, [&nav](){ nav.push<ReceiversMenuView>(); } },
|
||||
{ "Transmitters", ui::Color::green(), nullptr, [&nav](){ nav.push<TransmittersMenuView>(); } },
|
||||
@ -357,7 +357,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
//{ "Debug", ui::Color::white(), nullptr, [&nav](){ nav.push<DebugMenuView>(); } },
|
||||
{ "HackRF mode", ui::Color::white(), &bitmap_icon_hackrf, [this, &nav](){ hackrf_mode(nav); } },
|
||||
{ "About", ui::Color::white(), nullptr, [&nav](){ nav.push<AboutView>(); } }
|
||||
} });
|
||||
});
|
||||
|
||||
set_highlighted(1); // Startup selection is "Receivers"
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ void POCSAGTXView::paint(Painter&) {
|
||||
}
|
||||
|
||||
void POCSAGTXView::on_set_text(NavigationView& nav) {
|
||||
text_entry(nav, &buffer, 16);
|
||||
text_prompt(nav, &buffer, 16);
|
||||
}
|
||||
|
||||
POCSAGTXView::POCSAGTXView(
|
||||
|
@ -136,11 +136,11 @@ RDSView::RDSView(NavigationView& nav) {
|
||||
options_coverage.set_selected_index(0); // Local
|
||||
|
||||
button_editpsn.on_select = [this, &nav](Button&) {
|
||||
text_entry(nav, &PSN, 8);
|
||||
text_prompt(nav, &PSN, 8);
|
||||
};
|
||||
|
||||
button_editradiotext.on_select = [this, &nav](Button&){
|
||||
text_entry(nav, &RadioText, 24);
|
||||
text_prompt(nav, &RadioText, 24);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ void ModInfoView::focus() {
|
||||
}*/
|
||||
|
||||
SetupMenuView::SetupMenuView(NavigationView& nav) {
|
||||
add_items<6>({ {
|
||||
add_items({
|
||||
{ "UI", ui::Color::white(), nullptr, [&nav](){ nav.push<SetUIView>(); } },
|
||||
//{ "SD card modules", ui::Color::white(), [&nav](){ nav.push<ModInfoView>(); } },
|
||||
{ "Date/Time", ui::Color::white(), nullptr, [&nav](){ nav.push<SetDateTimeView>(); } },
|
||||
@ -453,7 +453,7 @@ SetupMenuView::SetupMenuView(NavigationView& nav) {
|
||||
{ "Antenna Bias Voltage", ui::Color::white(), nullptr, [&nav](){ nav.push<AntennaBiasSetupView>(); } },
|
||||
{ "Touch screen", ui::Color::white(), nullptr, [&nav](){ nav.push<TouchCalibrationView>(); } },
|
||||
{ "Play dead", ui::Color::red(), &bitmap_icon_playdead, [&nav](){ nav.push<SetPlayDeadView>(); } }
|
||||
} });
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,15 @@
|
||||
|
||||
#include "ui_textentry.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "ui_handwrite.hpp"
|
||||
#include "ui_alphanum.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void text_entry(NavigationView& nav, std::string * str, const size_t max_length, const std::function<void(std::string *)> on_done) {
|
||||
if (portapack::persistent_memory::ui_config_textentry() == 0) {
|
||||
void text_prompt(NavigationView& nav, std::string * str, const size_t max_length, const std::function<void(std::string *)> on_done) {
|
||||
if (persistent_memory::ui_config_textentry() == 0) {
|
||||
auto te_view = nav.push<AlphanumView>(str, max_length);
|
||||
te_view->on_changed = [on_done](std::string * value) {
|
||||
if (on_done)
|
||||
@ -41,4 +45,73 @@ void text_entry(NavigationView& nav, std::string * str, const size_t max_length,
|
||||
}
|
||||
}
|
||||
|
||||
void TextEntryView::update_text() {
|
||||
if (_cursor_pos <= 28)
|
||||
text_input.set(' ' + *_str + std::string(_max_length - _str->length(), ' '));
|
||||
else
|
||||
text_input.set('<' + _str->substr(_cursor_pos - 28, 28));
|
||||
|
||||
draw_cursor();
|
||||
}
|
||||
|
||||
void TextEntryView::char_delete() {
|
||||
if (!_cursor_pos) return;
|
||||
|
||||
_cursor_pos--;
|
||||
_str->replace(_cursor_pos, 1, 1, 0);
|
||||
}
|
||||
|
||||
void TextEntryView::char_add(const char c) {
|
||||
if (_cursor_pos >= _max_length) return;
|
||||
|
||||
_str->replace(_cursor_pos, 1, 1, c);
|
||||
_cursor_pos++;
|
||||
}
|
||||
|
||||
void TextEntryView::draw_cursor() {
|
||||
Point draw_pos;
|
||||
|
||||
draw_pos = { text_input.screen_rect().location().x() + 8 + std::min((Coord)_cursor_pos, (Coord)28) * 8,
|
||||
text_input.screen_rect().location().y() + 16 };
|
||||
|
||||
display.fill_rectangle(
|
||||
{ { text_input.screen_rect().location().x(), draw_pos.y() }, { text_input.screen_rect().size().width(), 4 } },
|
||||
Color::black()
|
||||
);
|
||||
display.fill_rectangle(
|
||||
{ draw_pos, { 8, 4 } },
|
||||
Color::white()
|
||||
);
|
||||
}
|
||||
|
||||
void TextEntryView::focus() {
|
||||
button_ok.focus();
|
||||
}
|
||||
|
||||
TextEntryView::TextEntryView(
|
||||
NavigationView& nav,
|
||||
std::string * str,
|
||||
size_t max_length
|
||||
) : _str(str),
|
||||
_max_length(max_length)
|
||||
{
|
||||
|
||||
// Trim from right
|
||||
_str->erase(std::find_if(_str->rbegin(), _str->rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _str->end());
|
||||
_cursor_pos = _str->length();
|
||||
|
||||
_str->resize(_max_length, 0);
|
||||
|
||||
add_children({
|
||||
&text_input,
|
||||
&button_ok
|
||||
});
|
||||
|
||||
button_ok.on_select = [this, &nav](Button&) {
|
||||
if (on_changed)
|
||||
on_changed(_str);
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
|
@ -25,12 +25,44 @@
|
||||
|
||||
#include "ui.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_handwrite.hpp"
|
||||
#include "ui_alphanum.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
void text_entry(NavigationView& nav, std::string * str, size_t max_length, const std::function<void(std::string*)> on_done = nullptr);
|
||||
class TextEntryView : public View {
|
||||
public:
|
||||
std::function<void(std::string*)> on_changed { };
|
||||
|
||||
void focus() override;
|
||||
std::string title() const override { return "Text entry"; };
|
||||
|
||||
protected:
|
||||
TextEntryView(NavigationView& nav, std::string * str, size_t max_length);
|
||||
|
||||
TextEntryView(const TextEntryView&) = delete;
|
||||
TextEntryView(TextEntryView&&) = delete;
|
||||
TextEntryView& operator=(const TextEntryView&) = delete;
|
||||
TextEntryView& operator=(TextEntryView&&) = delete;
|
||||
|
||||
void char_add(const char c);
|
||||
void char_delete();
|
||||
void draw_cursor();
|
||||
void update_text();
|
||||
|
||||
std::string * _str;
|
||||
size_t _max_length;
|
||||
uint32_t _cursor_pos { 0 };
|
||||
|
||||
Text text_input {
|
||||
{ 0, 0, 240, 16 }
|
||||
};
|
||||
|
||||
Button button_ok {
|
||||
{ 10 * 8, 33 * 8, 9 * 8, 32 },
|
||||
"OK"
|
||||
};
|
||||
};
|
||||
|
||||
void text_prompt(NavigationView& nav, std::string * str, size_t max_length, const std::function<void(std::string*)> on_done = nullptr);
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
|
@ -35,8 +35,6 @@ static void init() {
|
||||
audio::dma::configure();
|
||||
audio::dma::enable();
|
||||
|
||||
LPC_CREG->DMAMUX = portapack::gpdma_mux;
|
||||
gpdma::controller.enable();
|
||||
nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC_DMA_IRQ_PRIORITY));
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#define __CHANNEL_STATS_COLLECTOR_H__
|
||||
|
||||
#include "dsp_types.hpp"
|
||||
#include "simd.hpp"
|
||||
#include "message.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
@ -36,15 +35,7 @@ class ChannelStatsCollector {
|
||||
public:
|
||||
template<typename Callback>
|
||||
void feed(const buffer_c16_t& src, Callback callback) {
|
||||
auto src_p = simd32_ptr(src.p);
|
||||
const auto end_p = simd32_ptr(&src.p[src.count]);
|
||||
while(src_p < end_p) {
|
||||
const uint32_t sample = *(src_p++);
|
||||
const uint32_t mag_sq = __SMUAD(sample, sample);
|
||||
if( mag_sq > max_squared ) {
|
||||
max_squared = mag_sq;
|
||||
}
|
||||
}
|
||||
max_squared = compute_max_squared(src, max_squared);
|
||||
count += src.count;
|
||||
|
||||
const size_t samples_per_update = src.sampling_rate * update_interval;
|
||||
@ -63,6 +54,22 @@ private:
|
||||
static constexpr float update_interval { 0.1f };
|
||||
uint32_t max_squared { 0 };
|
||||
size_t count { 0 };
|
||||
|
||||
static uint32_t compute_max_squared(
|
||||
const buffer_c16_t& src,
|
||||
uint32_t max_squared
|
||||
) {
|
||||
auto src_p = src.p;
|
||||
while(src_p < &src.p[src.count]) {
|
||||
const uint32_t sample = *__SIMD32(src_p)++;
|
||||
const uint32_t mag_sq = __SMUAD(sample, sample);
|
||||
if( mag_sq > max_squared ) {
|
||||
max_squared = mag_sq;
|
||||
}
|
||||
}
|
||||
|
||||
return max_squared;
|
||||
}
|
||||
};
|
||||
|
||||
#endif/*__CHANNEL_STATS_COLLECTOR_H__*/
|
||||
|
@ -10,11 +10,11 @@
|
||||
<link rel="alternate" hreflang="en" title="Original" href="http://elm-chan.org/fsw/ff/00index_e.html">
|
||||
<link rel="alternate" hreflang="ja" title="Japanese version" href="00index_j.html">
|
||||
<link rel="stylesheet" href="css_e.css" type="text/css" media="screen" title="ELM Default">
|
||||
<title>FatFs - Generic FAT File System Module</title>
|
||||
<title>FatFs - Generic FAT File System Module (R0.12c)</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>FatFs - Generic FAT File System Module</h1>
|
||||
<h1>FatFs - Generic FAT File System Module (R0.12c)</h1>
|
||||
<hr>
|
||||
|
||||
<div class="abst">
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
<h4>Features</h4>
|
||||
<ul>
|
||||
<li>Windows compatible FAT/exFAT file system.</li>
|
||||
<li>DOS/Windows compatible FAT/exFAT file system.</li>
|
||||
<li>Platform independent. Easy to port.</li>
|
||||
<li>Very small footprint for program code and work area.</li>
|
||||
<li>Various <a href="en/config.html">configuration options</a> to support for:
|
||||
@ -44,6 +44,7 @@
|
||||
<div class="para">
|
||||
<h3>Application Interface</h3>
|
||||
<img src="res/layers1.png" class="rset" width="245" height="220" alt="layer">
|
||||
<p>FatFs provides various file control functions for the applications as shown below.</p>
|
||||
<ul>
|
||||
<li>File Access
|
||||
<ul>
|
||||
@ -103,9 +104,9 @@
|
||||
|
||||
|
||||
<div class="para">
|
||||
<h3>Device Control Interface</h3>
|
||||
<h3>Media Access Interface</h3>
|
||||
<img src="res/layers2.png" class="rset" width="245" height="220" alt="layer">
|
||||
<p>Since the FatFs module is a file system layer, it is completely separated from the physical devices, such as memory card, harddisk and any type of storage device. FatFs accesses the storage devices via a simple interface shown below. The low level device control module is <em>not a part of FatFs module</em>. It is provided by implementer. Also sample implementations for some platforms are available in the downloads.</p>
|
||||
<p>Since the FatFs module is just a file system layer independent of platform and storage device. It is completely separated from the physical devices, such as memory card, harddisk and any type of storage device. The low level device control module is <em>not a part of FatFs module</em> and it needs to be provided by implementer. FatFs accesses the storage devices via a simple media access interface shown below. Also sample implementations for some platforms are available in the downloads.</p>
|
||||
<ul>
|
||||
<li><a href="en/dstat.html">disk_status</a> - Get device status</li>
|
||||
<li><a href="en/dinit.html">disk_initialize</a> - Initialize device</li>
|
||||
@ -136,6 +137,6 @@
|
||||
|
||||
|
||||
<hr>
|
||||
<p class="foot"><a href="http://elm-chan.org/fsw/ff/00index_e.html">Latest Information</a></p>
|
||||
<p class="foot"><a href="http://elm-chan.org/fsw/ff/00index_e.html">FatFs Homepage</a></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -10,11 +10,11 @@
|
||||
<link rel="alternate" hreflang="ja" title="オリジナル版" href="http://elm-chan.org/fsw/ff/00index_j.html">
|
||||
<link rel="alternate" hreflang="en" title="英文版" href="00index_e.html">
|
||||
<link rel="stylesheet" href="css_j.css" type="text/css" media="screen" title="ELM Default">
|
||||
<title>FatFs 汎用FATファイルシステム モジュール</title>
|
||||
<title>FatFs 汎用FATファイルシステム モジュール (R0.12c)</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>FatFs 汎用FATファイルシステム モジュール</h1>
|
||||
<h1>FatFs 汎用FATファイルシステム モジュール (R0.12c)</h1>
|
||||
<hr>
|
||||
|
||||
<div class="abst">
|
||||
@ -22,7 +22,7 @@
|
||||
<p>FatFsは小規模な組み込みシステム向けの汎用FAT/exFATファイルシステム モジュールです。ANSI C(C89)準拠でハードウェア アーキテクチャには依存しないので、必要なワーク エリアが確保できれば、8051, PIC, AVR, SH, Z80, 68k, H8, ARMなど安価なマイコンでも使用可能です。このほか、FatFsを極小マイコン向けにシュリンクした<a href="http://elm-chan.org/fsw/ff/00index_p.html">ぷちFatFs</a>もあります。</p>
|
||||
<h4>FatFsモジュールの特徴</h4>
|
||||
<ul>
|
||||
<li>Windows互換 FAT/exFATファイルシステム</li>
|
||||
<li>DOS/Windows互換 FAT/exFATファイルシステム</li>
|
||||
<li>プラットフォーム非依存</li>
|
||||
<li>コンパクトなコードとRAM使用量</li>
|
||||
<li>多くの<a href="ja/config.html">構成オプション</a>:
|
||||
@ -41,8 +41,9 @@
|
||||
|
||||
|
||||
<div class="para">
|
||||
<h3>上位レイヤ インターフェース</h3>
|
||||
<h3>アプリケーション インターフェース</h3>
|
||||
<img src="res/layers1.png" class="rset" width="245" height="220" alt="layer">
|
||||
<p>FatFsモジュールは、上位レイヤに対して次に示すファイルAPIを提供します。</p>
|
||||
<ul>
|
||||
<li>ファイル アクセス
|
||||
<ul>
|
||||
@ -102,9 +103,9 @@
|
||||
|
||||
|
||||
<div class="para">
|
||||
<h3>下位レイヤ インターフェース</h3>
|
||||
<h3>デバイス制御インターフェース</h3>
|
||||
<img src="res/layers2.png" class="rset" width="245" height="220" alt="layer">
|
||||
<p>FatFsモジュールは、単なるファイルシステム レイヤなので、その下位のストレージ デバイス制御レイヤはそれに含まれません。それぞれのプラットフォームやストレージ デバイスに対応した制御レイヤは、インプリメンタによって提供される必要があります。FatFsモジュールは、下位レイヤに対し標準的には次のインターフェースを要求します。一部の拡張機能、たとえばOS関連機能を有効にしたときは、加えてプロセス/メモリ操作関数なども必要になります。サンプル プロジェクトに下位レイヤの実装例を示します。</p>
|
||||
<p>FatFsモジュールは、プラットフォームから独立した単なるファイルシステム レイヤです。ストレージ デバイス(例えばメモリ カード)の制御機能はFatFsの構成部分ではないので、インプリメンタによって提供される必要があります。FatFsモジュールは、下位レイヤに対し標準的には次のインターフェースを要求します。一部の拡張機能(たとえばOS関連機能)を利用するときは、これらに加えてプロセス/メモリ操作関数なども必要になります。サンプル プロジェクトに下位レイヤの実装例を示します。</p>
|
||||
<ul>
|
||||
<li><a href="ja/dstat.html">disk_status</a> - デバイスの状態取得</li>
|
||||
<li><a href="ja/dinit.html">disk_initialize</a> - デバイスの初期化</li>
|
||||
@ -136,6 +137,6 @@
|
||||
|
||||
|
||||
<hr>
|
||||
<p class="foot"><a href="http://elm-chan.org/fsw/ff/00index_j.html">FatFs Home Page</a></p>
|
||||
<p class="foot"><a href="http://elm-chan.org/fsw/ff/00index_j.html">FatFsホームページ</a></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -14,6 +14,7 @@ strong {}
|
||||
pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; font-size: 85%; font-family: "Consolas", "Courier New", monospace; background-color: white;}
|
||||
pre span.c {color: green;}
|
||||
pre span.k {color: blue;}
|
||||
pre span.b {font-weight: bold;}
|
||||
pre span.arg {font-style: italic;}
|
||||
tt {margin: 0 0.2em; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; }
|
||||
tt.arg {font-style: italic;}
|
||||
@ -24,7 +25,7 @@ dl {margin: 0.5em 1em;}
|
||||
dd {margin: 0 2em;}
|
||||
dt {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace;}
|
||||
dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; }
|
||||
dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace;}
|
||||
dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; font-weight: bold; }
|
||||
hr {border-width: 1px; margin: 1em;}
|
||||
div.abst {font-family: sans-serif;}
|
||||
div.para {clear: both; font-family: serif;}
|
||||
|
@ -17,6 +17,7 @@ strong {}
|
||||
pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; letter-spacing: 0; font-size: 0.85em; font-family: "Consolas", "Courier New", "MS ゴシック", monospace; background-color: white;}
|
||||
pre span.c {color: green;}
|
||||
pre span.k {color: blue;}
|
||||
pre span.b {font-weight: bold;}
|
||||
pre span.arg {font-style: italic;}
|
||||
tt {margin: 0 0.2em; letter-spacing: 0; font-size: 0.85em; font-family: "Consolas", "Courier New", "MS ゴシック", monospace;}
|
||||
tt.arg {font-style: italic;}
|
||||
@ -27,7 +28,7 @@ dl {margin: 0.5em 1em;}
|
||||
dd {margin: 0em 2em;}
|
||||
dt {font-size: 0.85em; font-family: "Consolas", "Courier New", "MS ゴシック", monospace;}
|
||||
dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; letter-spacing: 0;}
|
||||
dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", "MS ゴシック", monospace; letter-spacing: 0; }
|
||||
dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", "MS ゴシック", monospace; letter-spacing: 0; font-weight: bold; }
|
||||
hr {border-width: 1px; margin: 1em;}
|
||||
div.abst {font-family: "MS Pゴシック",sans-serif;}
|
||||
div.para {clear: both; font-family: "MS P明朝",serif;}
|
||||
|
@ -37,17 +37,17 @@
|
||||
<li>ANSI C<br>
|
||||
The FatFs module is a middleware written in ANSI C (C89). There is no platform dependence, so long as the compiler is in compliance with ANSI C.</li>
|
||||
<li>Size of integer types<br>
|
||||
The FatFs module assumes that size of <tt>char</tt>/<tt>short</tt>/<tt>long</tt> are 8/16/32 bit and <tt>int</tt> is 16 or 32 bit. These correspondence are defined in <tt>integer.h</tt>. This will not be a problem on most compilers. When any conflict with existing definitions is occured, you must resolve it with care.</li>
|
||||
The FatFs module assumes that size of <tt>char</tt>/<tt>short</tt>/<tt>long</tt> are 8/16/32 bit and <tt>int</tt> is 16 or 32 bit. These correspondence are defined in <tt>integer.h</tt>. This will not be a problem on most compilers. When a conflict with existing definitions is occured, you must resolve it with care.</li>
|
||||
</ul>
|
||||
|
||||
<h4>System organizations</h4>
|
||||
<p>The dependency diagram shown below is a typical but not specific configuration of the embedded system with FatFs module.</p>
|
||||
<p><img src="../res/modules.png" width="580" height="280" alt="dependency diagram"></p>
|
||||
<p>(a) If a working disk module with FatFs API is provided, no additional function is needed. (b) To attach existing disk drivers with different API, glue functions are needed to translate the APIs between FatFs and the drivers.</p>
|
||||
<p>(a) If a working disk module with FatFs disk interface is provided, nothing else will be needed. (b) To attach existing disk drivers with different interface, glue functions are needed to translate the interfaces between FatFs and the drivers.</p>
|
||||
<p><img src="../res/funcs.png" width="750" height="420" alt="functional diagram"></p>
|
||||
|
||||
<h4>Which function is required?</h4>
|
||||
<p>You need to provide only low level disk I/O functions that required by FatFs module and nothing else. If a working disk module for the target system is already existing, you need to write only glue functions to attach it to the FatFs module. If not, you need to port any other disk module or write it from scratch. Most of defined functions are not that always required. For example, disk write function is not required at read-only configuration. Following table shows which function is required depends on the configuration options.</p>
|
||||
<h4>Required functions</h4>
|
||||
<p>You need to provide only low level disk I/O functions required by FatFs module and nothing else. If a working disk module for the target system is already existing, you need to write only glue functions to attach it to the FatFs module. If not, you need to port another disk module or write it from scratch. Most of defined functions are not that always required. For example, disk write function is not required at read-only configuration. Following table shows which function is required depends on the configuration options.</p>
|
||||
<table class="lst2">
|
||||
<tr><th>Function</th><th>Required when</th><th>Note</th></tr>
|
||||
<tr><td>disk_status<br>disk_initialize<br>disk_read</td><td>Always</td><td rowspan="5">Disk I/O functions.<br>Samples available in ffsample.zip.<br>There are many implementations on the web.</td></tr>
|
||||
@ -64,7 +64,7 @@ The FatFs module assumes that size of <tt>char</tt>/<tt>short</tt>/<tt>long</tt>
|
||||
<div class="para doc" id="limits">
|
||||
<h3>Limits</h3>
|
||||
<ul>
|
||||
<li>File system type: FAT12, FAT16, FAT32(r0.0) and exFAT(r1.0).</li>
|
||||
<li>File system type: FAT, FAT32(r0.0) and exFAT(r1.0).</li>
|
||||
<li>Number of open files: Unlimited. (depends on available memory)</li>
|
||||
<li>Number of volumes: Upto 10.</li>
|
||||
<li>Volume size: Upto 2 TiB at 512 bytes/sector.</li>
|
||||
@ -81,21 +81,21 @@ The FatFs module assumes that size of <tt>char</tt>/<tt>short</tt>/<tt>long</tt>
|
||||
<tr><th></th><th>ARM7<small><br>32bit</small></th><th>ARM7<small><br>Thumb</small></th><th>CM3<small><br>Thumb-2</small></th><th>AVR</th><th>H8/300H</th><th>PIC24</th><th>RL78</th><th>V850ES</th><th>SH-2A</th><th>RX600</th><th>IA-32</th></tr>
|
||||
<tr class="cal"> <td>Compiler</td><td>GCC</td><td>GCC</td><td>GCC</td><td>GCC</td><td>CH38</td><td>C30</td><td>CC78K0R</td><td>CA850</td><td>SHC</td><td>RXC</td><td>MSC</td></tr>
|
||||
<!-- ARM Thumb CM3 AVR H8 PIC24 RL78 V850ES SH-2A RX600 IA-32 -->
|
||||
<tr class="ral"><td class="cal">text (Full, R/W)</td><td>10.1k</td><td>6.6k</td><td>6.2k</td><td>12.1k</td><td>10.5k</td><td>11.2k</td><td>12.6k</td><td>8.5k</td><td>8.7k</td><td>6.3k</td><td>8.4k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/W)</td> <td>6.6k</td><td>4.5k</td><td>4.2k</td> <td>7.9k</td> <td>7.0k</td> <td>7.6k</td> <td>8.8k</td><td>5.9k</td><td>5.8k</td><td>4.3k</td><td>5.8k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Full, R/O)</td> <td>4.8k</td><td>3.1k</td><td>2.9k</td> <td>5.8k</td> <td>5.1k</td> <td>5.5k</td> <td>6.4k</td><td>4.1k</td><td>4.0k</td><td>3.1k</td><td>4.0k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/O)</td> <td>3.5k</td><td>2.4k</td><td>2.3k</td> <td>4.4k</td> <td>3.9k</td> <td>4.2k</td> <td>5.0k</td><td>3.3k</td><td>3.1k</td><td>2.4k</td><td>3.1k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Full, R/W)</td><td>10.4k</td><td>6.8k</td><td>6.3k</td><td>12.4k</td> <td>9.8k</td><td>11.1k</td><td>12.8k</td><td>8.6k</td><td>8.9k</td><td>6.4k</td><td>8.5k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/W)</td> <td>6.8k</td><td>4.6k</td><td>4.3k</td> <td>8.2k</td> <td>6.7k</td> <td>7.6k</td> <td>9.1k</td><td>6.0k</td><td>5.9k</td><td>4.5k</td><td>5.9k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Full, R/O)</td> <td>4.8k</td><td>3.1k</td><td>2.8k</td> <td>5.6k</td> <td>4.6k</td> <td>5.3k</td> <td>6.3k</td><td>4.0k</td><td>3.9k</td><td>3.0k</td><td>3.9k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/O)</td> <td>3.6k</td><td>2.4k</td><td>2.3k</td> <td>4.4k</td> <td>3.5k</td> <td>4.0k</td> <td>4.9k</td><td>3.3k</td><td>3.0k</td><td>2.4k</td><td>3.1k</td></tr>
|
||||
<tr class="ral"><td class="cal">bss</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*2 + 2</td><td>V*4 + 2</td><td>V*2 + 2</td><td>V*2 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td></tr>
|
||||
<tr class="ral"><td class="cal">Work area<br><small>(_FS_TINY == 0)</small></td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*560<br>+ F*546</td><td>V*560<br>+ F*546</td><td>V*560<br>+ F*546</td><td>V*560<br>+ F*546</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td></tr>
|
||||
<tr class="ral"><td class="cal">Work area<br><small>(_FS_TINY == 1)</small></td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*560<br>+ F*34</td><td>V*560<br>+ F*34</td><td>V*560<br>+ F*34</td><td>V*560<br>+ F*34</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td></tr>
|
||||
</table>
|
||||
<p>These are the memory usage on some target systems with following condition. The memory sizes are in unit of byte, <em>V</em> denotes option <tt>_VOLUMES</tt> and <em>F</em> denotes number of open files. All samples here are optimezed in code size.</p>
|
||||
<pre>
|
||||
FatFs R0.12 options:
|
||||
FatFs R0.12b options:
|
||||
_FS_READONLY 0 (R/W) or 1 (R/O)
|
||||
_FS_MINIMIZE 0 (Full, with all basic functions) or 3 (Min, with fully minimized)
|
||||
_FS_TINY 0 (Default) or 1 (Tiny file object)
|
||||
And any other options are left unchanged from original setting.
|
||||
And other options are left unchanged from original setting.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -144,7 +144,7 @@ And any other options are left unchanged from original setting.
|
||||
|
||||
<div class="para doc" id="lfn">
|
||||
<h3>Long File Name</h3>
|
||||
<p>FatFs module supports long file name (LFN). The two different file names, short file name (SFN) and LFN, of a file is transparent on the API except for <tt>f_readdir</tt> function. The support for LFN is disabled by default. To enable the LFN, set <tt><a href="config.html#use_lfn">_USE_LFN</a></tt> to 1, 2 or 3, and add <tt>option/unicode.c</tt> to the project. The LFN requiers a certain working buffer in addition. The buffer size can be configured by <tt><a href="config.html#max_lfn">_MAX_LFN</a></tt> according to the available memory. The length of an LFN will be up to 255 characters, so that the <tt>_MAX_LFN</tt> should be set to 255 for all file names. If the size of working buffer is insufficient for the input file name, the file function fails with <tt>FR_INVALID_NAME</tt>. When use any re-entry to the API with LFN is enabled, <tt>_USE_LFN</tt> must be set to 2 or 3. In this case, the file function allocates the working buffer on the stack or heap. The working buffer occupies <tt>(_MAX_LFN + 1) * 2</tt> bytes and additional 608 bytes when exFAT enabled.</p>
|
||||
<p>FatFs module supports long file name (LFN). The two different file names, short file name (SFN) and LFN, of a file is transparent on the API except for <tt>f_readdir</tt> function. The support for LFN is disabled by default. To enable the LFN, set <tt><a href="config.html#use_lfn">_USE_LFN</a></tt> to 1, 2 or 3, and add <tt>option/unicode.c</tt> to the project. The LFN requiers a certain working buffer in addition. The buffer size can be configured by <tt><a href="config.html#max_lfn">_MAX_LFN</a></tt> according to the available memory. The length of an LFN will be up to 255 characters, so that the <tt>_MAX_LFN</tt> should be set to 255 for all file names. If the size of working buffer is insufficient for the input file name, the file function fails with <tt>FR_INVALID_NAME</tt>. When use any re-entry to the API with LFN is enabled, <tt>_USE_LFN</tt> must be set to 2 or 3. In this case, the file function allocates the working buffer on the stack or heap. The working buffer occupies <tt>(_MAX_LFN + 1) * 2</tt> bytes and additional <tt>(_MAX_LFN + 44) / 15 * 32</tt> bytes when exFAT is enabled.</p>
|
||||
<table class="lst2 rset">
|
||||
<caption>With LFN at CM3+gcc</caption>
|
||||
<tr><th><tt>_CODE_PAGE</tt></th><th>Code size</th></tr>
|
||||
@ -160,27 +160,27 @@ And any other options are left unchanged from original setting.
|
||||
|
||||
<div class="para doc" id="unicode">
|
||||
<h3>Unicode API</h3>
|
||||
<p>By default, FatFs uses ANSI/OEM code set on the API even at LFN configuration. FatFs can also switch the character encoding on the API to Unicode by configuration option <tt><a href="config.html#lfn_unicode">_LFN_UNICODE</a></tt>. This means that FatFs supports the full featured LFN specification. The data type <tt>TCHAR</tt> specifies any string on the API is an alias of <tt>char</tt>(ANSI) or <tt>WCHAR</tt>(UTF-16). For more information, refer to the description in the <a href="filename.html#uni">file name</a>.</p>
|
||||
<p>By default, FatFs uses ANSI/OEM code set on the API even at LFN configuration. FatFs can also switch the character encoding on the API to Unicode by configuration option <tt><a href="config.html#lfn_unicode">_LFN_UNICODE</a></tt>. This means that FatFs supports the full featured LFN specification. The data type <tt>TCHAR</tt> specifies strings on the API is an alias of <tt>char</tt>(ANSI/OEM) or <tt>WCHAR</tt>(UTF-16). For more information, refer to the description in the <a href="filename.html#uni">file name</a>.</p>
|
||||
</div>
|
||||
|
||||
<div class="para doc" id="exfat">
|
||||
<h3>exFAT File System</h3>
|
||||
<p>The exFAT (Microsoft's Extended File Allocation Table) file system is a replacement of the FAT file system which has been widely used in the embedded systems and consumer devices. It is adopted by SDA (SD Association) as a recommended file system for high capacity SD cards (>32GB) and they are being shipped with this format, so that the exFAT will soon become one of the standard file systems for removable media.</p>
|
||||
<p>The exFAT file system allows the file size larger than 4 GiB limit what FAT file system allows upto and some file system overhead, especially file allocation delay, are reduced as well. This feature improves the write throughput to the file. However a problem on the current implementation of FatFs is that write throughput at writing to the growing edge of the fragmented file gets less than the throughput on the FAT volume. Pre-allocating a contiguous block with <tt>f_expand</tt> function may be a workaround of this problem.</p>
|
||||
<p>Note that the exFAT is a patent of Microsoft Corporation. The exFAT function of FatFs is an implementation based on US. Pat. App. Pub. No. 2009/0164440 A1. FatFs module can swich the exFAT on or off by configuration option. When enable the exFAT on the commercial products, you will need to be licensed by Microsoft depends on the final destination of the products.</p></div>
|
||||
<p><em>Remark: Enabling exFAT discards C89 compatibility because of need for 64-bit integer type.</em></p>
|
||||
<p>The exFAT (Microsoft's Extended File Allocation Table) file system is a replacement of the FAT file system which has been widely used in the embedded systems and consumer devices. It is adopted by SDA (SD Association) as a recommended file system for high capacity SD cards (>32GB) and they are being shipped with this format, so that the exFAT become one of the standard file systems for removable media as well as FAT. The exFAT file system allows the file size larger than 4 GiB limit what FAT file system allows upto and some file system overhead, especially cluster allocation delay, are reduced as well. This feature improves the write throughput to the file.</p>
|
||||
<p>Note that the exFAT is a patent of Microsoft Corporation. The exFAT function of FatFs is an implementation based on <cite>US. Pat. App. Pub. No. 2009/0164440 A1</cite>. FatFs module can swich the exFAT on/off by configuration option. When enable the exFAT on the commercial products, you will need to be licensed by Microsoft depends on the final destination of the products.</p>
|
||||
<p><em>Remark: Enabling exFAT discards ANSI C (C89) compatibility because of need for 64-bit integer type.</em></p>
|
||||
</div>
|
||||
|
||||
<div class="para doc" id="reentrant">
|
||||
<h3>Re-entrancy</h3>
|
||||
<p>The file operations to the different volume is always re-entrant regardless of configurations except when LFN enabled with static working buffer. It can work simultaneously without any mutual exclusion.</p>
|
||||
<p>The file operations to the same volume is not re-entrant but it can also be configured thread-safe by option <tt><a href="config.html#fs_reentrant">_FS_REENTRANT</a></tt>. It enables to control exclusive use of each file system object. In this case, also the OS dependent synchronization object control functions, <tt>ff_cre_syncobj/ff_del_syncobj/ff_req_grant/ff_rel_grant</tt>, needed to be added to the project. There are some examples in the <tt>option/syscall.c</tt>.</p>
|
||||
<p>When a file function is called while the volume is being accessed by any other task, the file function to the volume will be suspended until that task leaves the file function. If the wait time exceeded a period defined by <tt>_TIMEOUT</tt>, the file function will abort with <tt>FR_TIMEOUT</tt>. The timeout function might not be supported on the some RTOSs.</p>
|
||||
<p>There is an exception on the re-entrancy for <tt>f_mount/f_mkfs/f_fdisk</tt> function. These volume management functions are not re-entrant to the same volume and corresponding physical drive. When use these functions, any other tasks need to avoid to access the volume.</p>
|
||||
<p>Note that this section describes on the re-entrancy of the FatFs module itself. The <tt>_FS_REENTRANT</tt> controls only exclusive use of each file system object and it does not that prevent to re-enter the low level disk functions. For example, only <tt>disk_status</tt> function can be re-entered at single volume system and any disk function can be re-entered at multiple volume system. Thus the low level disk I/O layer must be always thread-safe when any FatFs API is re-entered by two or more tasks.</p>
|
||||
<p>The file operations to the <em>different volume</em> each other is always re-entrant regardless of configurations except when LFN enabled with static working buffer. It can work simultaneously without any mutual exclusion.</p>
|
||||
<p>The file operations to the <em>same volume</em> is not re-entrant. It can also be configured thread-safe by option <tt><a href="config.html#fs_reentrant">_FS_REENTRANT</a></tt>. It enables to control exclusive use of each file system object. In this case, also the OS dependent synchronization object control functions, <tt>ff_cre_syncobj/ff_del_syncobj/ff_req_grant/ff_rel_grant</tt>, needed to be added to the project. There are some examples in the <tt>option/syscall.c</tt>.</p>
|
||||
<p>When a file function is called while the volume is being accessed by other task, the file function to the volume will be suspended until that task leaves the file function. If the wait time exceeded a period defined by <tt>_TIMEOUT</tt>, the file function will abort with <tt>FR_TIMEOUT</tt>. The timeout function might not be supported on the some RTOSs.</p>
|
||||
<p>There is an exception on the re-entrancy for <tt>f_mount/f_mkfs/f_fdisk</tt> function. These volume management functions are not re-entrant on the same volume and corresponding physical drive. When use these functions, other tasks need to avoid to access the volume.</p>
|
||||
<p>Note that this section describes on the re-entrancy of the FatFs module itself. The <tt>_FS_REENTRANT</tt> controls only exclusive use of each file system object and it does not that prevent re-entering the low level disk functions. For example, only <tt>disk_status</tt> function is re-entered at single volume system and every disk function is re-entered at multiple volume system. Thus the low level disk I/O layer must be always thread-safe when FatFs API is re-entered by two or more tasks.</p>
|
||||
</div>
|
||||
|
||||
<div class="para doc" id="dup">
|
||||
<h3>Duplicated File Access</h3>
|
||||
<h3>Duplicated File Open</h3>
|
||||
<p>FatFs module does not support the read/write collision control of duplicated open to a file. The duplicated open is permitted only when each of open method to a file is read mode. The duplicated open with one or more write mode to a file is always prohibited, and also open file must not be renamed or deleted. A violation of these rules can cause data colluption.</p>
|
||||
<p>The file lock control can be enabled by <tt><a href="config.html#fs_lock">_FS_LOCK</a></tt> option. The value of option defines the number of open objects to manage simultaneously. In this case, if any open, rename or remove that violating the file shareing rule that described above is attempted, the file function will rejected with <tt>FR_LOCKED</tt>. If number of open objects, files and sub-directories, is equal to <tt>_FS_LOCK</tt>, an extra <tt>f_open/f_opendir</tt> function will fail with <tt>FR_TOO_MANY_OPEN_FILES</tt>.</p>
|
||||
</div>
|
||||
@ -218,7 +218,7 @@ Figure 6. Comparison between Multiple/Single Sector Write<br>
|
||||
|
||||
<div class="para doc" id="critical">
|
||||
<h3>Critical Section</h3>
|
||||
<p>If a write operation to the FAT volume is interrupted due to any accidental failure, such as sudden blackout, incorrect media removal and unrecoverable disk error, the FAT structure on the volume can be broken. Following images shows the critical section of the FatFs module.</p>
|
||||
<p>If a write operation to the FAT volume is interrupted due to an accidental failure, such as sudden blackout, incorrect media removal and unrecoverable disk error, the FAT structure on the volume can be broken. Following images shows the critical section of the FatFs module.</p>
|
||||
<div class="lset">
|
||||
Figure 4. Long critical section<br>
|
||||
<img src="../res/f4.png" width="320" height="436" alt="fig.4">
|
||||
@ -236,17 +236,17 @@ Figure 5. Minimized critical section<br>
|
||||
<li>The file created as new or overwritten remains but no content.</li>
|
||||
<li>Efficiency of disk use gets worse due to lost clusters.</li>
|
||||
</ul>
|
||||
<p>Each case does not affect the files that not opened in write mode. To minimize risk of data loss, the critical section can be minimized by minimizing the time that file is opened in write mode or using <tt>f_sync</tt> function as shown in Figure 5.</p>
|
||||
<p>Each case does not affect any file not opened in write mode. To minimize risk of data loss, the critical section can be minimized by minimizing the time that file is opened in write mode or using <tt>f_sync</tt> function as shown in Figure 5.</p>
|
||||
</div>
|
||||
|
||||
<div class="para doc" id="fs3">
|
||||
<h3>Extended Use of FatFs API</h3>
|
||||
<p>These are examples of extended use of FatFs APIs. New item will be added whenever a useful code is found.</p>
|
||||
<ol>
|
||||
<li><a href="../res/app1.c">Open or create a file for append</a> (for R0.12 and older)</li>
|
||||
<li><a href="../res/app1.c">Open or create a file for append</a> (for only R0.12 and earlier)</li>
|
||||
<li><a href="../res/app2.c">Empty a directory</a></li>
|
||||
<li><a href="../res/app3.c">Allocate contiguous area to the file</a> (for R0.11a and older)</li>
|
||||
<li><a href="../res/app4.c">Function/compatibility checker for low level disk I/O module</a></li>
|
||||
<li><a href="../res/app3.c">Allocate contiguous area to the file</a> (for only R0.11a and earlier)</li>
|
||||
<li><a href="../res/app4.c">Compatibility checker for low level disk I/O module</a></li>
|
||||
<li><a href="../res/mkfatimg.zip">FAT image creator</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
@ -256,15 +256,15 @@ Figure 5. Minimized critical section<br>
|
||||
<p>FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that included in the source files.</p>
|
||||
<pre>
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT file system module R0.12a /
|
||||
/ FatFs - Generic FAT file system module Rx.xx /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2016, ChaN, all right reserved.
|
||||
/ Copyright (C) 20xx, 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.
|
||||
/
|
||||
@ -274,7 +274,7 @@ Figure 5. Minimized critical section<br>
|
||||
/ by use of this software.
|
||||
/----------------------------------------------------------------------------*/
|
||||
</pre>
|
||||
<p>Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software licenses that not conflict with FatFs license.</p>
|
||||
<p>Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license.</p>
|
||||
</div>
|
||||
|
||||
<p class="foot"><a href="../00index_e.html">Return Home</a></p>
|
||||
|
@ -25,7 +25,7 @@ FRESULT f_chdir (
|
||||
<h4>Parameters</h4>
|
||||
<dl class="par">
|
||||
<dt>path</dt>
|
||||
<dd>Pointer to the null-terminated string that specifies a <a href="filename.html">directory</a> to go.</dd>
|
||||
<dd>Pointer to the null-terminated string that specifies the <a href="filename.html">directory</a> to go.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -50,7 +50,7 @@ FRESULT f_chdir (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>The <tt>f_chdir</tt> function changes the current directory of the logical drive. The current directory of a drive is initialized to the root directory when the drive is auto-mounted. Note that the current directory is retained in the each file system object so that it also affects other tasks that using the volume.</p>
|
||||
<p>The <tt>f_chdir</tt> function changes the current directory of the logical drive. The current directory of a drive is set to the root directory when the drive is mounted. Note that the current directory is retained in the each file system object, so that it also affects other tasks that use the volume.</p>
|
||||
</div>
|
||||
|
||||
|
||||
@ -63,10 +63,10 @@ FRESULT f_chdir (
|
||||
<div class="para use">
|
||||
<h4>Example</h4>
|
||||
<pre>
|
||||
<span class="c">/* Change current direcoty of the current drive (dir1 under root dir) */</span>
|
||||
<span class="c">/* Change current direcoty of the current drive ('dir1' under root directory) */</span>
|
||||
f_chdir("/dir1");
|
||||
|
||||
<span class="c">/* Change current direcoty of drive 2 (parent dir) */</span>
|
||||
<span class="c">/* Change current direcoty of drive 2 (parent directory) */</span>
|
||||
f_chdir("2:..");
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -45,16 +45,16 @@
|
||||
<p>Disable (0) or Enable (1) <tt>f_mkfs</tt> function.</p>
|
||||
|
||||
<h4 id="use_fastseek">_USE_FASTSEEK</h4>
|
||||
<p>Disable (0) or Enable (1) fast seek function to enable accelerated mode of <tt>f_lseek</tt>, <tt>f_read</tt> and <tt>f_write</tt> function. For more information, read <a href="lseek.html">here</a>.</p>
|
||||
<p>Disable (0) or Enable (1) fast seek function to enable accelerated mode for <tt>f_lseek</tt>, <tt>f_read</tt> and <tt>f_write</tt> function. For more information, read <a href="lseek.html">here</a>.</p>
|
||||
|
||||
<h4 id="use_expand">_USE_EXPAND</h4>
|
||||
<p>Disable (0) or Enable (1) , <tt>f_enpand</tt> function. Also <tt>_FS_READONLY</tt> needs to be 0.</p>
|
||||
|
||||
<h4 id="use_chmod">_USE_CHMOD</h4>
|
||||
<p>Disable (0) or Enable (1) metadata manipulation functions, <tt>f_chmod</tt> and <tt>f_utime</tt>. Also <tt>_FS_READONLY</tt> needs to be 0.</p>
|
||||
<p>Disable (0) or Enable (1) metadata control functions, <tt>f_chmod</tt> and <tt>f_utime</tt>. Also <tt>_FS_READONLY</tt> needs to be 0.</p>
|
||||
|
||||
<h4 id="use_label">_USE_LABEL</h4>
|
||||
<p>Disable (0) or Enable (1) volume label functions, <tt>f_getlabel</tt> and <tt>f_setlabel</tt>.</p>
|
||||
<p>Disable (0) or Enable (1) API functions for volume label, <tt>f_getlabel</tt> and <tt>f_setlabel</tt>.</p>
|
||||
|
||||
<h4 id="use_forward">_USE_FORWARD</h4>
|
||||
<p>Disable (0) or Enable (1) <tt>f_forward</tt> function.</p>
|
||||
@ -147,7 +147,7 @@
|
||||
<p>Disable (0) or Enable (1). This option switches multi-partition function. By default (0), each logical drive number is bound to the same physical drive number and only an FAT volume in the physical drive is mounted. When enabled, each logical drive is bound to the partition on the physical drive listed in the user defined partition resolution table <tt>VolToPart[]</tt>. Also <tt>f_fdisk</tt> funciton will be available. For more information, read <a href="filename.html#vol">here</a>.</p>
|
||||
|
||||
<h4 id="max_ss">_MIN_SS, _MAX_SS</h4>
|
||||
<p>This set of options defines the size of sector on low level disk I/O interface, <tt>disk_read</tt> and <tt>disk_write</tt> function. Valid values are 512, 1024, 2048 and 4096. <tt>_MIN_SS</tt> defines minimum sector size and <tt>_MAX_SS</tt> defines the maximum sector size. Always set both 512 for any type of memory card and harddisk. But a larger value may be required for on-board flash memory and some type of optical media. When <tt>_MAX_SS > _MIN_SS</tt>, FatFs is configured to variable sector size and <tt>GET_SECTOR_SIZE</tt> command must be implemented to the <tt>disk_ioctl</tt> function.</p>
|
||||
<p>This set of options defines the size of sector on low level disk I/O interface, <tt>disk_read</tt> and <tt>disk_write</tt> function. Valid values are 512, 1024, 2048 and 4096. <tt>_MIN_SS</tt> defines minimum sector size and <tt>_MAX_SS</tt> defines the maximum sector size. Always set both 512 for memory card and harddisk. But a larger value may be required for on-board flash memory and some type of optical media. When <tt>_MAX_SS > _MIN_SS</tt>, support of variable sector size is enabled and <tt>GET_SECTOR_SIZE</tt> command needs to be implemented to the <tt>disk_ioctl</tt> function.</p>
|
||||
|
||||
<h4 id="use_trim">_USE_TRIM</h4>
|
||||
<p>Disable (0) or Enable (1). This option switches ATA-TRIM function. To enable Trim function, also <tt>CTRL_TRIM</tt> command should be implemented to the <tt>disk_ioctl</tt> function.</p>
|
||||
@ -175,7 +175,7 @@
|
||||
<p>This option switches support for the exFAT file system in addition to the FAT file system, Enabled(1) or Disabled(1). To enable this feature, also LFN must be enabled and configureing <tt>_LFN_UNICODE = 1</tt> and <tt>_MAX_LFN = 255</tt> is recommended for full-featured exFAT function. Note that enabling exFAT discards C89 compatibility because of need for 64-bit integer type.</p>
|
||||
|
||||
<h4 id="fs_nortc">_FS_NORTC</h4>
|
||||
<p>Use RTC (0) or Do not use RTC (1). This option controls timestamp function. If the system does not have an RTC function or valid timestamp is not needed, set <tt>_FS_NORTC</tt> to 1 to disable the timestamp function. Any object modified by FatFs will have a fixed timestamp value defined by <tt>_NORTC_MON</tt>, <tt>_NORTC_MDAY</tt> and <tt>_NORTC_YEAR</tt>. To use the timestamp function, set <tt>_FS_NORTC = 0</tt> and add <tt>get_fattime</tt> function to the project to get the current time form real-time clock. This option has no effect at read-only configuration.</p>
|
||||
<p>Use RTC (0) or Do not use RTC (1). This option controls timestamp function. If the system does not have an RTC function or valid timestamp is not needed, set <tt>_FS_NORTC</tt> to 1 to disable the timestamp function. Any object modified by FatFs will have a fixed timestamp defined by <tt>_NORTC_MON</tt>, <tt>_NORTC_MDAY</tt> and <tt>_NORTC_YEAR</tt>. To use the timestamp function, set <tt>_FS_NORTC = 0</tt> and add <tt>get_fattime</tt> function to the project to get the current time form real-time clock. This option has no effect at read-only configuration.</p>
|
||||
|
||||
<h4 id="nortc_time">_NORTC_MON, _NORTC_MDAY, _NORTC_YEAR</h4>
|
||||
<p>This set of options defines the time to be used at no RTC systems. This option has no effect at read-only configuration or <tt>_FS_NORTC = 0</tt>.</p>
|
||||
@ -184,12 +184,12 @@
|
||||
<p>This option switches file lock function to control duplicated file open and illegal operations to open objects. Note that the file lock function is independent of re-entrancy. This option must be 0 at read-only configuration.</p>
|
||||
<table class="lst1">
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td>0</td><td>Disable file lock function. To avoid volume corruption, application program should avoid illegal open, remove and rename to the open objects.</td></tr>
|
||||
<tr><td>>0</td><td>Enable file lock function. The value defines how many files/sub-directories can be opened simultaneously under file lock control. Illigal operations to the open object will be rejected with <tt>FR_LOCKED</tt>.</td></tr>
|
||||
<tr><td>0</td><td>Disable file lock function. To avoid collapsing file by wrong file operation, application program needs to avoid illegal open, remove and rename to the open objects.</td></tr>
|
||||
<tr><td>>0</td><td>Enable file lock function. The value defines how many files/sub-directories can be opened simultaneously under the file lock control. Illigal operations to the open object will be rejected with <tt>FR_LOCKED</tt>.</td></tr>
|
||||
</table>
|
||||
|
||||
<h4 id="fs_reentrant">_FS_REENTRANT</h4>
|
||||
<p>Disable (0) or Enable (1). This option switches the re-entrancy (thread safe) of the FatFs module itself. Note that file/directory access to the different volume is always re-entrant and it can work simultaneously regardless of this option but volume control functions, <tt>f_mount</tt>, <tt>f_mkfs</tt> and <tt>f_fdisk</tt>, are always not re-entrant. Only file/directory access to the same volume, in other words, exclusive use of each file system object, is under control of this function. To enable this feature, also user provided synchronization handlers, <tt>ff_req_grant</tt>, <tt>ff_rel_grant</tt>, <tt>ff_del_syncobj</tt> and <tt>ff_cre_syncobj</tt>, need to be added to the project. Sample code is available in <tt>option/syscall.c</tt>.</p>
|
||||
<p>Disable (0) or Enable (1). This option switches the re-entrancy (thread safe) of the FatFs module itself. Note that file/directory access to the different volume is always re-entrant and it can work simultaneously regardless of this option but volume control functions. <tt>f_mount</tt>, <tt>f_mkfs</tt> and <tt>f_fdisk</tt>, are always not re-entrant. Only file/directory access to the same volume, in other words, exclusive use of each file system object, is under control of this function. To enable this feature, also user provided synchronization handlers, <tt>ff_req_grant</tt>, <tt>ff_rel_grant</tt>, <tt>ff_del_syncobj</tt> and <tt>ff_cre_syncobj</tt>, need to be added to the project. Sample code is available in <tt>option/syscall.c</tt>.</p>
|
||||
|
||||
<h4 id="fs_timeout">_FS_TIMEOUT</h4>
|
||||
<p>Number of time ticks to abort the file function with <tt>FR_TIMEOUT</tt> when wait time is too long. This option has no effect when <tt>_FS_REENTRANT = 0</tt>.</p>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_initialize</h2>
|
||||
<p>The disk_initialize function initializes the storage device.</p>
|
||||
<p>The disk_initialize function is called to initializes the storage device.</p>
|
||||
<pre>
|
||||
DSTATUS disk_initialize (
|
||||
BYTE <span class="arg">pdrv</span> <span class="c">/* [IN] Physical drive number */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_ioctl</h2>
|
||||
<p>The disk_ioctl function controls device specific features and miscellaneous functions other than generic read/write.</p>
|
||||
<p>The disk_ioctl function is called to control device specific features and miscellaneous functions other than generic read/write.</p>
|
||||
<pre>
|
||||
DRESULT disk_ioctl (
|
||||
BYTE <span class="arg">pdrv</span>, <span class="c">/* [IN] Drive number */</span>
|
||||
@ -59,9 +59,9 @@ DRESULT disk_ioctl (
|
||||
<tr><th>Command</th><th>Description</th></tr>
|
||||
<tr><td>CTRL_SYNC</td><td>Make sure that the device has finished pending write process. If the disk I/O module has a write back cache, the dirty buffers must be written back to the media immediately. Nothing to do for this command if each write operation to the media is completed within the <tt>disk_write</tt> function.</td></tr>
|
||||
<tr><td>GET_SECTOR_COUNT</td><td>Returns number of available sectors on the drive into the <tt>DWORD</tt> variable pointed by <tt class="arg">buff</tt>. This command is used by only <tt>f_mkfs</tt> and <tt>f_fdisk</tt> function to determine the volume/partition size to be created. Required at <tt>_USE_MKFS == 1</tt> or <tt>_MULTI_PARTITION == 1</tt>.</td></tr>
|
||||
<tr><td>GET_SECTOR_SIZE</td><td>Returns sector size of the media into the <tt>WORD</tt> variable pointed by <tt class="arg">buff</tt>. Valid return values of this command are 512, 1024, 2048 and 4096. This command is required only at variable sector size configuration, <tt>_MAX_SS > _MIN_SS</tt>. At fixed sector size configuration, <tt>_MAX_SS == _MIN_SS</tt>, this command is not used and the device must work at that sector size.</td></tr>
|
||||
<tr><td>GET_BLOCK_SIZE</td><td>Returns erase block size of the flash memory media in unit of sector into the <tt>DWORD</tt> variable pointed by <tt class="arg">buff</tt>. The allowable value is from 1 to 32768 in power of 2. Return 1 if the erase block size is unknown or non flash memory media. This command is used by only <tt>f_mkfs</tt> function and it attempts to align data area to the erase block boundary. Required at <tt>_USE_MKFS == 1</tt>.</td></tr>
|
||||
<tr><td>CTRL_TRIM</td><td>Informs the device the data on the block of sectors that specified by <tt>DWORD</tt> array {<start sector>, <end sector>} pointed by <tt class="arg">buff</tt> is no longer needed and it may be erased. This is an identical command to Trim of ATA device. Nothing to do for this command if this funcion is not supported or not a flash memory device. The FatFs does not check the result code and the file function is not affected even if the sector block was not erased well. This command is called on remove a cluster chain and in the <tt>f_mkfs</tt> function. Required at <tt>_USE_TRIM == 1</tt>.</td></tr>
|
||||
<tr><td>GET_SECTOR_SIZE</td><td>Returns sector size of the device into the <tt>WORD</tt> variable pointed by <tt class="arg">buff</tt>. Valid return values of this command are 512, 1024, 2048 and 4096. This command is required only at variable sector size configuration, <tt>_MAX_SS > _MIN_SS</tt>. At the fixed sector size configuration, <tt>_MAX_SS == _MIN_SS</tt>, this command is not used and the device must work at that sector size.</td></tr>
|
||||
<tr><td>GET_BLOCK_SIZE</td><td>Returns erase block size of the flash memory media in unit of sector into the <tt>DWORD</tt> variable pointed by <tt class="arg">buff</tt>. The allowable value is from 1 to 32768 in power of 2. Return 1 if the erase block size is unknown or non flash memory media. This command is used by only <tt>f_mkfs</tt> function and it attempts to align data area on the erase block boundary. Required at <tt>_USE_MKFS == 1</tt>.</td></tr>
|
||||
<tr><td>CTRL_TRIM</td><td>Informs the device the data on the block of sectors is no longer needed and it can be erased. The sector block is specified by <tt>DWORD</tt> array {<start sector>, <end sector>} pointed by <tt class="arg">buff</tt>. This is an identical command to Trim of ATA device. Nothing to do for this command if this funcion is not supported or not a flash memory device. The FatFs does not check the result code and the file function is not affected even if the sector block was not erased well. This command is called on remove a cluster chain and in the <tt>f_mkfs</tt> function. Required at <tt>_USE_TRIM == 1</tt>.</td></tr>
|
||||
</table>
|
||||
|
||||
<p>FatFs never uses any device dependent command nor user defined command. Following table shows an example of non-standard commands usable for some applications.</p>
|
||||
@ -69,8 +69,8 @@ DRESULT disk_ioctl (
|
||||
<caption>Example of optional ioctl command</caption>
|
||||
<tr><th>Command</th><th>Description</th></tr>
|
||||
<tr><td>CTRL_FORMAT</td><td>Create a physical format on the media. If <tt class="arg">buff</tt> is not null, it is pointer to the call-back function for progress notification.</td></tr>
|
||||
<tr><td>CTRL_POWER_IDLE</td><td>Put the device idle state. <tt>STA_NOINIT</tt> in status flag may not be set if the device goes active state by generic read/write function.</td></tr>
|
||||
<tr><td>CTRL_POWER_OFF</td><td>Put the device off state. Shut-down the power to the device and deinitialize the device interface if needed. <tt>STA_NOINIT</tt> in status flag must be set. The device goes active state by <tt>disk_initialize</tt> function.</td></tr>
|
||||
<tr><td>CTRL_POWER_IDLE</td><td>Put the device idle state. <tt>STA_NOINIT</tt> in the current status flags may not be set if the device goes active state by generic read/write function.</td></tr>
|
||||
<tr><td>CTRL_POWER_OFF</td><td>Put the device off state. Shut-down the power to the device and deinitialize the device interface if needed. <tt>STA_NOINIT</tt> in the current status flags must be set. The device goes active state by <tt>disk_initialize</tt> function.</td></tr>
|
||||
<tr><td>CTRL_LOCK</td><td>Lock media eject mechanism.</td></tr>
|
||||
<tr><td>CTRL_UNLOCK</td><td>Unlock media eject mechanism.</td></tr>
|
||||
<tr><td>CTRL_EJECT</td><td>Eject media cartridge. <tt>STA_NOINIT</tt> and <tt>STA_NODISK</tt> in status flag are set after the function succeeded.</td></tr>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_read</h2>
|
||||
<p>The disk_read function reads sector(s) from the storage device.</p>
|
||||
<p>The disk_read function is called to read data from the sector(s) of storage device.</p>
|
||||
<pre>
|
||||
DRESULT disk_read (
|
||||
BYTE <span class="arg">pdrv</span>, <span class="c">/* [IN] Physical drive number */</span>
|
||||
@ -30,7 +30,7 @@ DRESULT disk_read (
|
||||
<dt>pdrv</dt>
|
||||
<dd>Physical drive number to identify the target device.</dd>
|
||||
<dt>buff</dt>
|
||||
<dd>Pointer to the <em>byte array</em> to store the read data.</dd>
|
||||
<dd>Pointer to the first item of the <em>byte array</em> to store read data.</dd>
|
||||
<dt>sector</dt>
|
||||
<dd>Start sector number in 32-bit LBA.</dd>
|
||||
<dt>count</dt>
|
||||
@ -45,7 +45,7 @@ DRESULT disk_read (
|
||||
<dt>RES_OK (0)</dt>
|
||||
<dd>The function succeeded.</dd>
|
||||
<dt>RES_ERROR</dt>
|
||||
<dd>Any hard error occured during the read operation and could not recover it.</dd>
|
||||
<dd>A hard error occured during the read operation and could not recover it.</dd>
|
||||
<dt>RES_PARERR</dt>
|
||||
<dd>Invalid parameter.</dd>
|
||||
<dt>RES_NOTRDY</dt>
|
||||
@ -60,8 +60,8 @@ DRESULT disk_read (
|
||||
<p>The memory address specified by <tt class="arg">buff</tt> is not that always aligned to word boundary because the argument is defined as <tt>BYTE*</tt>. The unaligned read/write request can occure at <a href="appnote.html#fs1">direct transfer</a>. If the bus architecture, especially DMA controller, does not allow unaligned memory access, it should be solved in this function. There are some workarounds described below to avoid this issue.</p>
|
||||
<ul>
|
||||
<li>Convert word transfer to byte transfer in this function if needed. - Recommended.</li>
|
||||
<li>On the <tt>f_read</tt> calls, avoid long read request that includes a whole of sector. - Any direct transfer never occures.</li>
|
||||
<li>On the <tt>f_read</tt> calls, make sure that <tt>(((UINT)data & 3) == (f_tell(fp) & 3))</tt> is true. - Word alignment of <tt>buff</tt> is guaranteed.</li>
|
||||
<li>On the <tt>f_read()</tt> calls, avoid long read request that includes a whole of sector. - Any direct transfer never occures.</li>
|
||||
<li>On the <tt>f_read(fp, data, btw, bw)</tt> calls, make sure that <tt>(((UINT)data & 3) == (f_tell(fp) & 3))</tt> is true. - Word alignment of <tt class="arg">buff</tt> is guaranteed.</li>
|
||||
</ul>
|
||||
<p>Generally, a multiple sector transfer request must not be split into single sector transactions to the storage device, or you will not get good read throughput.</p>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_status</h2>
|
||||
<p>The disk_status function returns the current drive status.</p>
|
||||
<p>The disk_status function is called to inquire the current drive status.</p>
|
||||
<pre>
|
||||
DSTATUS disk_status (
|
||||
BYTE <span class="arg">pdrv</span> <span class="c">/* [IN] Physical drive number */</span>
|
||||
@ -35,7 +35,7 @@ DSTATUS disk_status (
|
||||
<p>The current drive status is returned in combination of status flags described below. FatFs refers only <tt>STA_NOINIT</tt> and <tt>STA_PROTECT</tt>.</p>
|
||||
<dl class="ret">
|
||||
<dt>STA_NOINIT</dt>
|
||||
<dd>Indicates that the device is not initialized and not ready to work. This flag is set on system reset, media removal or failure of <tt>disk_initialize</tt> function. It is cleared on <tt>disk_initialize</tt> function succeeded. Any media change that occurs asynchronously must be captured and reflect it to the status flags, or auto-mount function will not work correctly. If the system does not support media change detection, application program needs to force de-initialize the file system object and re-mount the volume with <tt>f_mount</tt> function after each media change.</dd>
|
||||
<dd>Indicates that the device is not initialized and not ready to work. This flag is set on system reset, media removal or failure of <tt>disk_initialize</tt> function. It is cleared on <tt>disk_initialize</tt> function succeeded. Any media change that occurs asynchronously must be captured and reflect it to the status flags, or auto-mount function will not work correctly. If the system does not support media change detection, application program needs to explicitly re-mount the volume with <tt>f_mount</tt> function after each media change.</dd>
|
||||
<dt>STA_NODISK</dt>
|
||||
<dd>Indicates that no medium in the drive. This is always cleared at fixed disk drive. Note that FatFs does not refer this flag.</dd>
|
||||
<dt>STA_PROTECT</dt>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_write</h2>
|
||||
<p>The disk_write writes sector(s) to the storage device.</p>
|
||||
<p>The disk_write function is called to write data to the sector(s) of storage device.</p>
|
||||
<pre>
|
||||
DRESULT disk_write (
|
||||
BYTE <span class="arg">drv</span>, <span class="c">/* [IN] Physical drive number */</span>
|
||||
@ -30,7 +30,7 @@ DRESULT disk_write (
|
||||
<dt>pdrv</dt>
|
||||
<dd>Physical drive number to identify the target device.</dd>
|
||||
<dt>buff</dt>
|
||||
<dd>Pointer to the <em>byte array</em> to be written. The size of data to be written is sector size * <tt class="arg">count</tt> bytes.</dd>
|
||||
<dd>Pointer to the first item of the <em>byte array</em> to be written. The size of data to be written is sector size * <tt class="arg">count</tt> bytes.</dd>
|
||||
<dt>sector</dt>
|
||||
<dd>Start sector number in 32-bit LBA.</dd>
|
||||
<dt>count</dt>
|
||||
@ -45,7 +45,7 @@ DRESULT disk_write (
|
||||
<dt>RES_OK (0)</dt>
|
||||
<dd>The function succeeded.</dd>
|
||||
<dt>RES_ERROR</dt>
|
||||
<dd>Any hard error occured during the write operation and could not recover it.</dd>
|
||||
<dd>A hard error occured during the write operation and could not recover it.</dd>
|
||||
<dt>RES_WRPRT</dt>
|
||||
<dd>The medium is write protected.</dd>
|
||||
<dt>RES_PARERR</dt>
|
||||
@ -60,7 +60,7 @@ DRESULT disk_write (
|
||||
<h4>Description</h4>
|
||||
<p>The specified memory address is not that always aligned to word boundary because the type of pointer is defined as <tt>BYTE*</tt>. For more information, refer to the description of <a href="dread.html"><tt>disk_read</tt></a> function.</p>
|
||||
<p>Generally, a multiple sector transfer request must not be split into single sector transactions to the storage device, or you will never get good write throughput.</p>
|
||||
<p>FatFs expects delayed write function of the disk control layer. The write operation to the media does not need to be completed when return from this function by what write operation is in progress or data is only stored into the write-back cache. But write data on the <tt class="arg">buff</tt> is invalid after return from this function. The write completion request is done by <tt>CTRL_SYNC</tt> command of <tt><a href="dioctl.html">disk_ioctl</a></tt> function. Therefore, if a delayed write function is implemented, the write throughput will be improved.</p>
|
||||
<p>FatFs expects delayed write function of the disk control layer. The write operation to the media does not need to be completed when return from this function by what write operation is in progress or data is only stored into the write-back cache. But write data on the <tt class="arg">buff</tt> is invalid after return from this function. The write completion request is done by <tt>CTRL_SYNC</tt> command of <tt><a href="dioctl.html">disk_ioctl</a></tt> function. Therefore, if a delayed write function is implemented, the write throughput of the file system will be improved.</p>
|
||||
<p><em>Remarks: Application program MUST NOT call this function, or FAT structure on the volume can be collapsed.</em></p>
|
||||
</div>
|
||||
|
||||
|
@ -59,9 +59,9 @@ FRESULT f_expand (
|
||||
<li>The file has been opened in read-only mode.</li>
|
||||
<li>Not allowable file size. (>= 4GiB on FAT volume)</li>
|
||||
</ul>
|
||||
<p>When <tt class="arg">opt</tt> is 0, the function finds a contiguous data area and set it as suggested point for next allocation instead of allocating it to the file. The next cluster allocation is started at top of the contiguous area found by this function. Thus the write file is guaranteed be contiguous and no allocation delay until the size reaches that size at least unless any other operation to the volume with changes of FAT is performed.</p>
|
||||
<p>The contiguous file would have an advantage at time-critical read/write operations. It reduces some overheads in the file system and the storage media caused by random access due to fragmented file data. Especially, at the exFAT volume, any FAT access for the contiguous file is completely eliminated and storage media will be accessed sequentially.</p>
|
||||
<p>Also the contiguous file data can be easily accessed directly via low-level disk functions but it is not recommended in consideration for future compatibility.</p>
|
||||
<p>When <tt class="arg">opt</tt> is 0, the function finds a contiguous data area and set it as suggested point for next allocation instead of allocating it to the file. The next cluster allocation is started at top of the contiguous area found by this function. Thus the write file is guaranteed be contiguous and no allocation delay until the size reaches that size at least unless any other changes to the volume is performed.</p>
|
||||
<p>The contiguous file would have an advantage at time-critical read/write operations. It eliminates some overheads in the file system and the storage media caused by random access due to fragmented file data. Especially FAT access for the contiguous file on the exFAT volume is completely eliminated and storage media will be accessed sequentially.</p>
|
||||
<p>Also the contiguous file can be easily accessed directly via low-level disk functions. But this is not recommended in consideration for future compatibility.</p>
|
||||
</div>
|
||||
|
||||
<div class="para comp">
|
||||
@ -79,28 +79,29 @@ FRESULT f_expand (
|
||||
res = f_open(fp = malloc(sizeof (FIL)), "file.dat", FA_WRITE|FA_CREATE_ALWAYS);
|
||||
if (res) { <span class="c">/* Check if the file has been opened */</span>
|
||||
free(fp);
|
||||
...
|
||||
die("Failed to open the file.");
|
||||
}
|
||||
|
||||
<span class="c">/* Alloacte a 100 MiB of contiguous area to the file */</span>
|
||||
res = f_expand(fp, 104857600, 1);
|
||||
if (res) { <span class="c">/* Check if the file has been expanded */</span>
|
||||
...
|
||||
f_close(fp);
|
||||
free(fp);
|
||||
...
|
||||
die("Failed to allocate contiguous area.");
|
||||
}
|
||||
|
||||
<span class="c">/* Now you have a contiguous file accessible with fp */</span>
|
||||
|
||||
</pre>
|
||||
<pre>
|
||||
<span class="c">/* Accessing the file data directly via low-level disk functions */</span>
|
||||
<span class="c">/* Accessing the contiguous file via low-level disk functions */</span>
|
||||
|
||||
<span class="c">/* Get physical location of the file data */</span>
|
||||
drv = fp->obj.fs->drv;
|
||||
sect = fp->obj.fs->database + fp->obj.fs->csize * (fp->obj.sclust - 2);
|
||||
lba = fp->obj.fs->database + fp->obj.fs->csize * (fp->obj.sclust - 2);
|
||||
|
||||
<span class="c">/* Write 2048 sectors from top of the file at a time */</span>
|
||||
res = disk_write(drv, buffer, sect, 2048);
|
||||
res = disk_write(drv, buffer, lba, 2048);
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>get_fattime</h2>
|
||||
<p>The get_fattime function gets current time.</p>
|
||||
<p>The get_fattime function is called to get the current time.</p>
|
||||
<pre>
|
||||
DWORD get_fattime (void);
|
||||
</pre>
|
||||
@ -22,7 +22,7 @@ DWORD get_fattime (void);
|
||||
|
||||
<div class="para ret">
|
||||
<h4>Return Value</h4>
|
||||
<p>Currnet local time is returned with packed into a <tt>DWORD</tt> value. The bit field is as follows:</p>
|
||||
<p>Currnet local time shall be returned as bit-fields packed into a <tt>DWORD</tt> value. The bit fields are as follows:</p>
|
||||
<dl class="ret">
|
||||
<dt>bit31:25</dt>
|
||||
<dd>Year origin from the 1980 (0..127)</dd>
|
||||
|
@ -62,22 +62,21 @@ FRESULT f_fdisk (
|
||||
<span class="c">/* Volume management table defined by user (required when _MULTI_PARTITION == 1) */</span>
|
||||
|
||||
PARTITION VolToPart[] = {
|
||||
{0, 1}, <span class="c">/* Logical drive 0 ==> Physical drive 0, 1st partition */</span>
|
||||
{0, 2}, <span class="c">/* Logical drive 1 ==> Physical drive 0, 2nd partition */</span>
|
||||
{1, 0} <span class="c">/* Logical drive 2 ==> Physical drive 1, auto detection */</span>
|
||||
{0, 1}, <span class="c">/* "0:" ==> Physical drive 0, 1st partition */</span>
|
||||
{0, 2}, <span class="c">/* "1:" ==> Physical drive 0, 2nd partition */</span>
|
||||
{1, 0} <span class="c">/* "2:" ==> Physical drive 1, auto detection */</span>
|
||||
};
|
||||
</pre>
|
||||
<pre>
|
||||
<span class="c">/* Initialize a brand-new disk drive mapped to physical drive 0 */</span>
|
||||
|
||||
FATFS fs;
|
||||
DWORD plist[] = {50, 50, 0, 0}; <span class="c">/* Divide drive into two partitions */</span>
|
||||
BYTE work[_MAX_SS];
|
||||
|
||||
f_fdisk(0, plist, work); <span class="c">/* Divide physical drive 0 */</span>
|
||||
f_fdisk(0, plist, work); <span class="c">/* Divide physical drive 0 */</span>
|
||||
|
||||
f_mkfs("0:", FMT_ANY, work, sizeof work); <span class="c">/* Create FAT volume on the logical drive 0 */</span>
|
||||
f_mkfs("1:", FMT_ANY, work, sizeof work); <span class="c">/* Create FAT volume on the logical drive 1 */</span>
|
||||
f_mkfs("0:", FM_ANY, work, sizeof work); <span class="c">/* Create FAT volume on the logical drive 0 */</span>
|
||||
f_mkfs("1:", FM_ANY, work, sizeof work); <span class="c">/* Create FAT volume on the logical drive 1 */</span>
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Path Names</h1>
|
||||
<h1>Path Names on the FatFs</h1>
|
||||
|
||||
<div class="para doc" id="nam">
|
||||
<h3>Format of the path names</h3>
|
||||
@ -19,7 +19,7 @@
|
||||
<p>The FatFs module supports long file name (LFN) and 8.3 format file name (SFN). The LFN can be used when (<tt><a href="config.html#use_lfn">_USE_LFN</a> != 0</tt>). The sub directories are separated with a \ or / in the same way as DOS/Windows API. Duplicated separators are skipped and ignored. Only a difference is that the logical drive is specified in a numeral with a colon. When drive number is omitted, the drive number is assumed as <em>default drive</em> (drive 0 or current drive).</p>
|
||||
<p>Control characters (<tt>'\0'</tt> to <tt>'\x1F'</tt>) are recognized as end of the path name. Leading/embedded spaces in the path name are valid as a part of the name at LFN configuration but the space is recognized as end of the path name at non-LFN configuration. Trailing spaces and dots are ignored at both configurations.</p>
|
||||
<p>In default configuration (<tt><a href="config.html#fs_rpath">_FS_RPATH</a> == 0</tt>), it does not have a concept of current directory like OS oriented file system. All objects on the volume are always specified in full path name that follows from the root directory. Dot directory names (<tt>".", ".."</tt>) are not allowed. Heading separator is ignored and it can be exist or omitted. The default drive is fixed to drive 0.</p>
|
||||
<p>When relative path is enabled (<tt>_FS_RPATH >= 1</tt>), specified path is followed from the root directory if a heading separator is exist. If not, it is followed from the current directory of the drive set by <a href="chdir.html">f_chdir</a> function. Dot names are also allowed for the path names. The default drive is the current drive set by <a href="chdrive.html">f_chdrive</a> function.</p>
|
||||
<p>When relative path is enabled (<tt>_FS_RPATH >= 1</tt>), specified path is followed from the root directory if a heading separator is exist. If not, it is followed from the current directory of the drive set by <a href="chdir.html"><tt>f_chdir</tt></a> function. Dot names are also allowed for the path names. The default drive is the current drive set by <a href="chdrive.html"><tt>f_chdrive</tt></a> function.</p>
|
||||
<table class="lst2">
|
||||
<tr><td>Path name</td><td>_FS_RPATH == 0</td><td>_FS_RPATH >= 1</td></tr>
|
||||
<tr class="lst3"><td>file.txt</td><td>A file in the root directory of the drive 0</td><td>A file in the current directory of the current drive</td></tr>
|
||||
@ -36,12 +36,12 @@
|
||||
<tr><td>/..</td><td>Invalid name</td><td>The root directory (sticks the top level)</td></tr>
|
||||
</table>
|
||||
<p>When option <tt><a href="config.html#str_volume_id">_STR_VOLUME_ID</a></tt> is specified, also pre-defined strings can be used as drive identifier in the path name instead of a numeral. e.g. <tt>"sd:file1.txt"</tt>, <tt>"ram:swapfile.dat"</tt> and DOS/Windows style drive letter, of course.</p>
|
||||
<p><em>Remark: In this revision, R0.12, double dot name <tt>".."</tt> cannot follow the parent directory on the exFAT volume. It will work as <tt>"."</tt> and stay there.</em></p>
|
||||
<p><em>Remark: In this revision, double dot name <tt>".."</tt> cannot follow the parent directory on the exFAT volume. It will work as <tt>"."</tt> and stay there.</em></p>
|
||||
</div>
|
||||
|
||||
<div class="para doc" id="case">
|
||||
<h3>Legal Characters and Case Sensitivity</h3>
|
||||
<p>On the FAT file system, legal characters for file name are, <tt>0-9 A-Z ! # $ % & ' ( ) - @ ^ _ ` { } ~</tt> and extended characters (<tt>\x80</tt>-<tt>\xFF</tt>). Under LFN supported system, also white space and <tt>+ , ; = [ ]</tt> are legal for the file name and the white spaces and periods can be placed anywhere in the name except for end of the name string.</p>
|
||||
<p>On the FAT file system, legal characters for object name (file/directory name) are, <tt>0-9 A-Z ! # $ % & ' ( ) - @ ^ _ ` { } ~</tt> and extended characters (<tt>\x80</tt>-<tt>\xFF</tt>). Under LFN supported system, also <tt>+ , ; = [ ]</tt> and space are legal for the object name and the white spaces and periods can be placed anywhere in the path name except for end of the object name.</p>
|
||||
<p>FAT file system is case-insensitive to the object names on the volume. All object names are compared in case-insensitive. For example, these three names, <tt>file.txt</tt>, <tt>File.Txt</tt> and <tt>FILE.TXT</tt>, are identical. This is applied to also extended charactres. When an object is created on the FAT volume, upper converted name is recorded to the SFN entry, and the raw name is recorded to the LFN entry.</p>
|
||||
<p>As for the DBCS language MS-DOS, it was case-sensitive to the extended characters. To follow this specification, FatFs works with case-sensitive to the extended characters at only non-LFN with DBCS configuration (DOS/DBCS specs). But at LFN configuration, FatFs works with case-insensitive to all characters (WindowsNT specs). This can cause a problem on compatibility with Windows system when an object with extended characters is created on the volume at non-LFN and DBCS configuration; therfore the object names with DBCS extended characters should not be used on the FAT volume shared by those systems.</p>
|
||||
</div>
|
||||
|
@ -61,11 +61,11 @@ FRESULT f_findfirst (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>After the directory specified by <tt class="arg">path</tt> could be opened, it starts to search the directory for the items with a name specified by <tt class="arg">pattern</tt>. If found, the information about the object is stored into the file information structure. For more information about file information structure, refer to <a href="readdir.html"><tt>f_readdir</tt></a> function.</p>
|
||||
<p>After the directory specified by <tt class="arg">path</tt> could be opened, it starts to search the directory for items with the name specified by <tt class="arg">pattern</tt>. If the first item is found, the information about the object is stored into the file information structure. For more information about file information structure, refer to <a href="readdir.html"><tt>f_readdir</tt></a> function.</p>
|
||||
<p>The matching pattern can contain wildcard characters (<tt>?</tt> and <tt>*</tt>). A <tt>?</tt> matches an any character and an <tt>*</tt> matches an any string in length of zero or longer. When support of long file name is enabled, only <tt>fname[]</tt> is tested at <tt>_USE_FIND == 1</tt> and also <tt>altname[]</tt> is tested at <tt>_USE_FIND == 2</tt>. In this revision, there are some differences listed below between FatFs and standard systems in matching condition.</p>
|
||||
<ul>
|
||||
<li><tt>"*.*"</tt> never matches any name without extension while it matches any names at the standard systems.</li>
|
||||
<li>Any patterns terminated with a period never matches any name while it matches any names without extensiton at the standard systems.</li>
|
||||
<li><tt>"*.*"</tt> never matches any name without extension while it matches any name with or without extension at the standard systems.</li>
|
||||
<li>Any pattern terminated with a period never matches any name while it matches any name without extensiton at the standard systems.</li>
|
||||
<li><a href="filename.html#case">DBCS extended characters</a> are compared in case-sensitive at LFN with non-Unicode configuration.</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -82,7 +82,7 @@ FRESULT f_findfirst (
|
||||
<pre>
|
||||
<span class="c">/* Search a directory for objects and display it */</span>
|
||||
|
||||
void find_image (void)
|
||||
void find_image_file (void)
|
||||
{
|
||||
FRESULT fr; <span class="c">/* Return value */</span>
|
||||
DIR dj; <span class="c">/* Directory search object */</span>
|
||||
@ -94,6 +94,7 @@ void find_image (void)
|
||||
printf("%s\n", fno.fname); <span class="c">/* Display the object name */</span>
|
||||
fr = f_findnext(&dj, &fno); <span class="c">/* Search for next item */</span>
|
||||
}
|
||||
|
||||
f_closedir(&dj);
|
||||
}
|
||||
</pre>
|
||||
|
@ -46,6 +46,7 @@ FRESULT f_forward (
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
</div>
|
||||
@ -114,7 +115,7 @@ FRESULT play_file (
|
||||
<span class="c">/* Repeat until the file pointer reaches end of the file */</span>
|
||||
while (rc == FR_OK && !f_eof(&fil)) {
|
||||
|
||||
<span class="c">/* any other processes... */</span>
|
||||
<span class="c">/* some processes... */</span>
|
||||
|
||||
<span class="c">/* Fill output stream periodicaly or on-demand */</span>
|
||||
rc = f_forward(&fil, out_stream, 1000, &dmy);
|
||||
|
@ -51,7 +51,7 @@ FRESULT f_getcwd (
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>The <tt>f_getcwd</tt> function retrieves full path name of the current directory of the current drive. When <tt>_VOLUMES</tt> is larger than 1, a logical drive number is added to top of the path name.</p>
|
||||
<p><em>Note: In this revision, R0.12, this function cannot retrieve the current directory path on the exFAT volume. It always returns the root directory path.</em></p>
|
||||
<p><em>Note: In this revision, this function cannot retrieve the current directory path on the exFAT volume. It always returns the root directory path.</em></p>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -29,7 +29,7 @@ FRESULT f_lseek (
|
||||
<dt>fp</dt>
|
||||
<dd>Pointer to the open file object.</dd>
|
||||
<dt>ofs</dt>
|
||||
<dd>Byte offset from top of the file. The data type <tt>FSIZE_t</tt> is an alias of either <tt>DWORD</tt>(32-bit) or <tt>QWORD</tt>(64-bit) depends on the configuration option <tt>_FS_EXFAT</tt>.</dd>
|
||||
<dd>Byte offset from top of the file to set read/write pointer. The data type <tt>FSIZE_t</tt> is an alias of either <tt>DWORD</tt>(32-bit) or <tt>QWORD</tt>(64-bit) depends on the configuration option <tt>_FS_EXFAT</tt>.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -48,7 +48,8 @@ FRESULT f_lseek (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>The <tt>f_lseek</tt> function moves the file read/write pointer of an open file. The offset can be specified in only origin from top of the file. When an offset beyond the file size is specified at write mode, the file size is expanded to the specified offset. The file data in the expanded area is <em>undefined</em> because no data is written to the file in this process. This is suitable to pre-allocate a cluster chain quickly, for fast write operation. When a contiguous data area needs to be allocated to the file, use <tt>f_expand</tt> function instead. After the <tt>f_lseek</tt> function succeeded, the current read/write pointer should be checked in order to make sure the read/write pointer has been moved correctry. In case of the read/write pointer is not the expected value, either of followings has been occured.</p>
|
||||
<p>File read/write ponter in the open file object points the data byte to be read/written at next read/write operation. It advances as the number of bytes read/written. The <tt>f_lseek</tt> function moves the file read/write pointer without any read/write operation to the file.</p>
|
||||
<p>When an offset beyond the file size is specified at write mode, the file size is expanded to the specified offset. The file data in the expanded area is <em>undefined</em> because no data is written to the file in this process. This is suitable to pre-allocate a data area to the file quickly for fast write operation. When a contiguous data area needs to be allocated to the file, use <tt>f_expand</tt> function instead. After the <tt>f_lseek</tt> function succeeded, the current read/write pointer should be checked in order to make sure the read/write pointer has been moved correctry. In case of the read/write pointer is not the expected value, either of followings has been occured.</p>
|
||||
<ul>
|
||||
<li>End of file. The specified <tt class="arg">ofs</tt> was clipped at end of the file because the file has been opened in read-only mode.</li>
|
||||
<li>Disk full. There is no free space on the volume to expand the file.</li>
|
||||
|
@ -39,7 +39,7 @@ FRESULT f_mkdir (
|
||||
<a href="rc.html#nr">FR_NOT_READY</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#ex">FR_EXIST</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
<a href="rc.html#id">FR_INVALID_DRIVE</a>,
|
||||
|
@ -29,15 +29,15 @@ FRESULT f_mkfs (
|
||||
<h4>Parameters</h4>
|
||||
<dl class="par">
|
||||
<dt>path</dt>
|
||||
<dd>Pointer to the null-terminated string specifies the <a href="filename.html">logical drive</a> to be formatted. If there is no drive number in it, it means the default drive. The logical drive does not need to be mounted.</dd>
|
||||
<dd>Pointer to the null-terminated string specifies the <a href="filename.html">logical drive</a> to be formatted. If it has no drive number in it, it means the default drive. The logical drive may or may not be mounted for the format process.</dd>
|
||||
<dt>opt</dt>
|
||||
<dd>Specifies the format option in combination of <tt>FM_FAT</tt>, <tt>FM_FAT32</tt>, <tt>FM_EXFAT</tt> and bitwise-or of these three, <tt>FM_ANY</tt>. <tt>FM_EXFAT</tt> is ignored when exFAT is not enabled. These flags specify which FAT type to be created on the volume. If two or more types are specified, one out of them will be selected depends on the volume size. The flag <tt>FM_SFD</tt> specifies to place the volume on the drive in SFD format.</dd>
|
||||
<dt>au</dt>
|
||||
<dd>Specifies size of the allocation unit (cluter) in unit of byte. The valid value is N times the sector size. N is power of 2 from 1 to 128 for FAT volume and upto 16MiB for exFAT volume. If zero is given, the default allocation unit size is selected depends on the volume size.</dd>
|
||||
<dd>Specifies size of the allocation unit (cluter) in unit of byte. The valid value is <tt>n</tt> times the sector size. The <tt>n</tt> is power of 2 from 1 to 128 for FAT volume and upto 16MiB for exFAT volume. If zero is given, the default allocation unit size is selected depends on the volume size.</dd>
|
||||
<dt>work</dt>
|
||||
<dd>Pointer to the working buffer for the format process.</dd>
|
||||
<dd>Pointer to the working buffer used for the format process.</dd>
|
||||
<dt>len</dt>
|
||||
<dd>Size of the working buffer in unit of byte. It needs to be the sector size at least. Plenty of working buffer reduces number of write transaction to the device and the format process will be finished quickly.</dd>
|
||||
<dd>Size of the working buffer in unit of byte. It needs to be the sector size at least. Plenty of working buffer reduces number of write transactions to the drive and the format process will be finished quickly.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -57,9 +57,9 @@ FRESULT f_mkfs (
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>The FAT sub-type, FAT12/FAT16/FAT32, of FAT volume except exFAT is determined by only number of clusters on the volume and nothing else, according to the FAT specification issued by Microsoft. Thus which FAT sub-type is selected, is depends on the volume size and the specified cluster size. In case of the combination of FAT type and cluter size specified by argument cannot be valid on the volume, the function will fail with <tt>FR_MKFS_ABORTED</tt>.</p>
|
||||
<p>The allocation unit, also called 'cluster', is a unit of disk space allocation for files. When the size of allocation unit is 32768 bytes, a file with 100 bytes in size occupies 32768 bytes of disk space. The space efficiency of disk usage gets worse as increasing size of allocation unit, but, on the other hand, the read/write performance increases as the size of allocation unit. Therefore the allocation unit is a trade-off between space efficiency and performance. For the large storages in GB order, 32768 bytes or larger cluster (this is automatically selected by default) is recommended for most case unless extremely many files are created on a volume.</p>
|
||||
<p>The allocation unit, also called 'cluster', is a unit of disk space allocation for files. When the size of allocation unit is 32768 bytes, a file with 100 bytes in size occupies 32768 bytes of disk space. The space efficiency of disk usage gets worse as increasing size of allocation unit, but, on the other hand, the read/write performance increases as the size of allocation unit. Therefore the size of allocation unit is a trade-off between space efficiency and performance. For the large storages in GB order, 32768 bytes or larger cluster (this is automatically selected by default) is recommended for most case unless extremely many small files are created on a volume.</p>
|
||||
<p>There are two disk formats, FDISK and SFD. The FDISK format is usually used for harddisk, MMC, SDC, CFC and U Disk. It can divide a physical drive into one or more partitions with a partition table on the MBR (maser boot record, the first sector of the physical drive). The SFD (super-floppy disk) is non-partitioned disk format. The FAT volume starts at the first sector of the physical drive without any disk partitioning. It is usually used for floppy disk, Microdrive, optical disk and most type of super-floppy media. Some systems support only either one of two formats and other is not supported.</p>
|
||||
<p>When <tt>FM_SFD</tt> is not specified, a primary partition occupies whole drive space is created and then the FAT volume is created in it. When <tt>FM_SFD</tt> is specified, the FAT volume occupies from the first sector of the drive is created.</p>
|
||||
<p>When <tt>FM_SFD</tt> is not specified (the volume is bound to a physical drive), a primary partition occupies whole drive space is created and then the FAT volume is created in it. When <tt>FM_SFD</tt> is specified, the FAT volume occupies from the first sector of the drive is created.</p>
|
||||
<p>If the logical drive to be formatted is bound to the specific partition (1-4) by support of multiple partition, <tt><a href="config.html#multi_partition">_MULTI_PARTITION</a></tt>, the FAT volume is created into the partition and <tt>FM_SFD</tt> flag is ignored. The physical drive needs to be partitioned with <tt>f_fdisk</tt> function or any other partitioning tools prior to create the FAT volume with this function.</p>
|
||||
</div>
|
||||
|
||||
@ -78,7 +78,7 @@ int main (void)
|
||||
FIL fil; <span class="c">/* File object */</span>
|
||||
FRESULT res; <span class="c">/* API result code */</span>
|
||||
UINT bw; <span class="c">/* Bytes written */</span>
|
||||
BYTE work[_MAX_SS]; <span class="c">/* Work area (larger is better for process time) */</span>
|
||||
BYTE work[_MAX_SS]; <span class="c">/* Work area (larger is better for processing time) */</span>
|
||||
|
||||
|
||||
<span class="c">/* Create FAT volume */</span>
|
||||
|
@ -31,7 +31,7 @@ FRESULT f_mount (
|
||||
<dt>path</dt>
|
||||
<dd>Pointer to the null-terminated string that specifies the <a href="filename.html">logical drive</a>. The string without drive number means the default drive.</dd>
|
||||
<dt>opt</dt>
|
||||
<dd>Initialization option. 0: Do not mount now (to be mounted later), 1: Force mounted the volume to check if the volume is ready to work.</dd>
|
||||
<dd>Mounting option. 0: Do not mount now (to be mounted on the first access to the volume), 1: Force mounted the volume to check if it is ready to work.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -54,15 +54,15 @@ FRESULT f_mount (
|
||||
<li>Determines the logical drive which specified by <tt class="arg">path</tt>.</li>
|
||||
<li>Clears and unregisters the regsitered work area of the drive if exist.</li>
|
||||
<li>Clears and registers the new work area to the drive if <tt class="arg">fs</tt> is not NULL.</li>
|
||||
<li>Performs volume mount process to the drive if forced mount is specified.</li>
|
||||
<li>Performs volume mount process to the drive if forced mounting is specified.</li>
|
||||
</ol>
|
||||
<p>The file system object is the work area needed for each logical drive. It must be given to the logical drive with this function prior to use any other file functions except for <tt>f_fdisk</tt> function to the logical drive. To unregister the work area, specify a NULL to the <tt class="arg">fs</tt>, and then the work area can be discarded.</p>
|
||||
<p>If forced mounting is not specified, this function always succeeds regardless of the physical drive status due to delayed mount feature. It only clears (de-initializes) the given work area and registers its address to the internal table. There is no activity of the physical drive in this function. It can also be used to force de-initialized the registered work area of a logical drive. The volume mount processes, initialize the corresponding physical drive, find the FAT volume in it and initialize the work area, is performed in the subsequent file access functions when either or both of following condition is true.</p>
|
||||
<p>The file system object is the work area needed for each logical drive. It must be given to the logical drive with this function prior to use any API functions except for <tt>f_mkfs/f_fdisk</tt> function to the logical drive.</p>
|
||||
<p>If forced mounting is not specified (<tt>opt = 0</tt>), this function always succeeds regardless of the physical drive status. It only clears (de-initializes) the given work area and registers its address to the internal table and no activity of the physical drive in this function. To unregister the work area, specify a NULL to the <tt class="arg">fs</tt>, and then the work area can be discarded. The volume mount processes, initialize the corresponding physical drive, find the FAT volume in it and initialize the work area, is performed in the subsequent file access functions when either or both of following condition is true.</p>
|
||||
<ul>
|
||||
<li>File system object is not initialized. It is de-initialized by <tt>f_mount</tt> function.</li>
|
||||
<li>File system object has not been initialized. It is de-initialized by <tt>f_mount</tt> function.</li>
|
||||
<li>Physical drive is not initialized. It is de-initialized by system reset or media removal.</li>
|
||||
</ul>
|
||||
<p>If the function with forced mounting failed, it means that the file system object has been registered successfully but the volume is currently not ready to work. The volume mount process will also be attempted at subsequent file access functions.</p>
|
||||
<p>If the function with forced mounting (<tt>opt = 1</tt>) failed, it means that the file system object has been registered successfully but the volume is currently not ready to work. The volume mount process will be attempted at subsequent file access functions if the file system object is not initialized. (delayed mounting)</p>
|
||||
<p>If implementation of the disk I/O layer lacks media change detection, application program needs to perform a <tt>f_mount</tt> function after each media change to force cleared the file system object.</p>
|
||||
</div>
|
||||
|
||||
|
@ -40,7 +40,7 @@ FRESULT f_open (
|
||||
<tr><td>FA_CREATE_NEW</td><td>Creates a new file. The function fails with <tt>FR_EXIST</tt> if the file is existing.</td></tr>
|
||||
<tr><td>FA_CREATE_ALWAYS</td><td>Creates a new file. If the file is existing, it will be truncated and overwritten.</td></tr>
|
||||
<tr><td>FA_OPEN_ALWAYS</td><td>Opens the file if it is existing. If not, a new file will be created.</td></tr>
|
||||
<tr><td>FA_OPEN_APPEND</td><td>Same as <tt>FA_OPEN_ALWAYS</tt> except read/write pointer is set end of the file.</td></tr>
|
||||
<tr><td>FA_OPEN_APPEND</td><td>Same as <tt>FA_OPEN_ALWAYS</tt> except the read/write pointer is set end of the file.</td></tr>
|
||||
</table>
|
||||
</dd>
|
||||
</dl>
|
||||
@ -57,7 +57,7 @@ FRESULT f_open (
|
||||
<a href="rc.html#ok">FR_NO_FILE</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#ex">FR_EXIST</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
@ -74,7 +74,7 @@ FRESULT f_open (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>Before using any file function, a work area (file system object) must be registered to the logical drive with <a href="mount.html"><tt>f_mount</tt></a> function. All API functions except for <tt>f_mkfs</tt> and <tt>f_fdisk</tt> function can work after this procedure.</p>
|
||||
<p>Before using any file function, a work area (file system object) needs to be registered to the logical drive with <a href="mount.html"><tt>f_mount</tt></a> function. All API functions except for <tt>f_mkfs/f_fdisk</tt> function get ready to work after this procedure.</p>
|
||||
<p>After <tt>f_open</tt> function succeeded, the file object is valid. The file object is used for subsequent operations to the file to identify the file. Open file must be closed prior to power down, media removal or re-mount, or the file can be collapsed. To close an open file, use <a href="close.html"><tt>f_close</tt></a> function.</p>
|
||||
<p>If duplicated file open is needed, read <a href="appnote.html#dup">here</a> carefully. However duplicated open of a file with any write mode flag is always prohibited.</p>
|
||||
</div>
|
||||
|
@ -39,7 +39,7 @@ int f_printf (
|
||||
|
||||
<div class="para ret">
|
||||
<h4>Return Values</h4>
|
||||
<p>When the function succeeded, it returns number of characters written. When the function failed due to disk full or any error, an <tt>EOF (-1)</tt> will be returned.</p>
|
||||
<p>When the function succeeded, it returns number of characters written. If the function could not write the generated string to the file due to disk full or an error, <tt>EOF (-1)</tt> will be returned.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -6,12 +6,12 @@
|
||||
<link rel="up" title="FatFs" href="../00index_e.html">
|
||||
<link rel="alternate" hreflang="ja" title="Japanese" href="../ja/rc.html">
|
||||
<link rel="stylesheet" href="../css_e.css" type="text/css" media="screen" title="ELM Default">
|
||||
<title>FatFs - Return Codes</title>
|
||||
<title>FatFs - API Return Code</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Return Code of the File Functions</h1>
|
||||
<p>On the FatFs API, most of file functions return common result code as enum type <tt>FRESULT</tt>. When a function succeeded, it returns zero, otherwise returns non-zero value that indicates type of error.</p>
|
||||
<h1>Return Code of API Functions</h1>
|
||||
<p>Most of API functions return common result code as enum type <tt>FRESULT</tt>. When an API function succeeded, it returns zero (<tt>FR_OK</tt>), otherwise it returns non-zero value indicates type of error.</p>
|
||||
|
||||
<dl class="ret">
|
||||
|
||||
@ -19,19 +19,27 @@
|
||||
<dd>The function succeeded.</dd>
|
||||
|
||||
<dt id="de">FR_DISK_ERR</dt>
|
||||
<dd>An unrecoverable hard error occured in the lower layer, <tt>disk_read</tt>, <tt>disk_write</tt> or <tt>disk_ioctl</tt> function.<br>Note that if once this error occured at any operation to an open file, the file object is aborted and all operations to the file except for close will be rejected.</dd>
|
||||
<dd>The lower layer, <tt>disk_read</tt>, <tt>disk_write</tt> or <tt>disk_ioctl</tt> function, reported that an unrecoverable hard error occured.<br>Note that if once this error occured at any operation to an open file, the file object is aborted and all operations to the file except for close will be rejected.</dd>
|
||||
|
||||
<dt id="ie">FR_INT_ERR</dt>
|
||||
<dd>Assertion failed. An insanity is detected in the internal process. One of the following possibilities is suspected.
|
||||
<ul>
|
||||
<li>Work area (file system object, file object or etc...) has been broken by stack overflow or any other tasks. This is the reason in most case.</li>
|
||||
<li>There is any error of the FAT structure on the volume.</li>
|
||||
<li>There is an error of the FAT structure on the volume.</li>
|
||||
<li>There is a bug in the FatFs module itself.</li>
|
||||
</ul>
|
||||
Note that if once this error occured at any operation to an open file, the file object is aborted and all operations to the file except for close will be rejected.
|
||||
</dd>
|
||||
|
||||
<dt id="nr">FR_NOT_READY</dt>
|
||||
<dd>The storage device cannot work due to a failure of <a href="dinit.html"><tt>disk_initialize</tt></a> function due to no medium or any other reason.</dd>
|
||||
<dd>The lower layer, <a href="dinit.html"><tt>disk_initialize</tt></a> function, reported that the storage device could not be got ready to work. One of the following possibilities is suspected.
|
||||
<ul>
|
||||
<li>No medium in the drive.</li>
|
||||
<li>Wrong lower layer implementation for the storage device.</li>
|
||||
<li>Wrong hardware configuration.</li>
|
||||
<li>The storage device is broken.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt id="nf">FR_NO_FILE</dt>
|
||||
<dd>Could not find the file.</dd>
|
||||
@ -50,25 +58,25 @@ Note that if once this error occured at any operation to an open file, the file
|
||||
<li>Deleting the non-empty directory or current directory.</li>
|
||||
<li>Reading the file opened without <tt>FA_READ</tt> flag.</li>
|
||||
<li>Any modification to the file opened without <tt>FA_WRITE</tt> flag.</li>
|
||||
<li>Could not create the file or directory due to the directory table is full.</li>
|
||||
<li>Could not create the object due to root directory full or disk full.</li>
|
||||
<li>Could not allocate a contiguous area to the file.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt id="ex">FR_EXIST</dt>
|
||||
<dd>Name collision. Any object that has the same name is already existing.</dd>
|
||||
<dd>Name collision. An object with the same name is already existing.</dd>
|
||||
|
||||
<dt id="io">FR_INVALID_OBJECT</dt>
|
||||
<dd>The file/directory object is invalid or a null pointer is given. There are some reasons as follows:
|
||||
<ul>
|
||||
<li>It has been closed, it is not opened or it can be collapsed.</li>
|
||||
<li>It has been invalidated by a voulme mount process. All open objects of the volume are invalidated as well.</li>
|
||||
<li>The corresponding physical drive is not ready due to a media removal.</li>
|
||||
<li>It has been closed, it has not been opened or it has been collapsed.</li>
|
||||
<li>It has been invalidated by a voulme mount process. Open objects on the volume are invalidated by voulme mount process.</li>
|
||||
<li>Physical drive is not ready to work due to a media removal.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt id="wp">FR_WRITE_PROTECTED</dt>
|
||||
<dd>Any write mode operation against the write-protected media.</dd>
|
||||
<dd>A write mode operation against the write-protected media.</dd>
|
||||
|
||||
<dt id="id">FR_INVALID_DRIVE</dt>
|
||||
<dd>Invalid drive number is specified in the path name. A null pointer is given as the path name. (Related option: <tt><a href="config.html#volumes">_VOLUMES</a></tt>)</dd>
|
||||
@ -107,7 +115,7 @@ Note that if once this error occured at any operation to an open file, the file
|
||||
<dd>Number of open objects has been reached maximum value and no more object can be opened. (Related option: <tt><a href="config.html#fs_lock">_FS_LOCK</a></tt>)</dd>
|
||||
|
||||
<dt id="ip">FR_INVALID_PARAMETER</dt>
|
||||
<dd>The given parameter is invalid or there is any inconsistent.</dd>
|
||||
<dd>The given parameter is invalid or there is an inconsistent for the volume.</dd>
|
||||
</dl>
|
||||
|
||||
<p class="foot"><a href="../00index_e.html">Return</a></p>
|
||||
|
@ -45,6 +45,7 @@ FRESULT f_read (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
@ -53,7 +54,7 @@ FRESULT f_read (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>The function starts to read data from the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes read. After the function succeeded, <tt class="arg">*br</tt> should be checked to detect end of the file. In case of <tt class="arg">*br</tt> is less than <tt class="arg">btr</tt>, it means the read/write pointer reached end of the file during read operation.</p>
|
||||
<p>The function starts to read data from the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes read. After the function succeeded, <tt class="arg">*br</tt> should be checked to detect end of the file. In case of <tt class="arg">*br</tt> < <tt class="arg">btr</tt>, it means the read/write pointer reached end of the file during read operation.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ FRESULT f_readdir (
|
||||
<li>Setting of <tt>_MAX_LFN</tt> is insufficient for the long file name. (Not the case at <tt>_MAX_LFN == 255</tt>)</li>
|
||||
<li>The long file name contains any character not allowed in ANSI/OEM code. (Not the case at <tt>_LFN_UNICODE == 1</tt>)</li>
|
||||
</ul>
|
||||
<p>There is a problem on reading a directory of exFAT volume. The exFAT does not support short file name. This means no name can be returned on the condition above. If it is the case, a "?" is returned as file name to indicate that the object is not accessible. To avoid this problem, configure FatFs <tt>_LFN_UNICODE = 1</tt> and <tt>_MAX_LFN = 255</tt> to support the full feature of LFN specification.</p>
|
||||
<p>There is a problem on reading a directory of exFAT volume. The exFAT does not support short file name. This means no name can be returned on the condition above. If it is the case, "?" is returned into the <tt>fname[]</tt> to indicate that the object is not accessible. To avoid this problem, configure FatFs <tt>_LFN_UNICODE = 1</tt> and <tt>_MAX_LFN = 255</tt> to support the full feature of LFN specification.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>f_rename</h2>
|
||||
<p>Renames a file or sub-directory.</p>
|
||||
<p>The f_rename function renames and/or moves a file or sub-directory.</p>
|
||||
<pre>
|
||||
FRESULT f_rename (
|
||||
const TCHAR* <span class="arg">old_name</span>, <span class="c">/* [IN] Old object name */</span>
|
||||
@ -28,7 +28,7 @@ FRESULT f_rename (
|
||||
<dt>old_name</dt>
|
||||
<dd>Pointer to a null-terminated string that specifies the existing <a href="filename.html">file or sub-directory</a> to be renamed.</dd>
|
||||
<dt>new_name</dt>
|
||||
<dd>Pointer to a null-terminated string that specifies the new object name. Any drive number may be specified in this string but it is ignored and assumed as the same drive of the <tt class="arg">old_name</tt>.</dd>
|
||||
<dd>Pointer to a null-terminated string that specifies the new object name. A drive number may be specified in this string but it is ignored and assumed as the same drive of the <tt class="arg">old_name</tt>. Any object with this path name except <tt class="arg">old_name</tt> must not be exist, or the function fails with <tt>FR_EXIST</tt>.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -43,7 +43,6 @@ FRESULT f_rename (
|
||||
<a href="rc.html#ok">FR_NO_FILE</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#ex">FR_EXIST</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
<a href="rc.html#id">FR_INVALID_DRIVE</a>,
|
||||
@ -58,7 +57,7 @@ FRESULT f_rename (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>Renames a file or sub-directory and can also move it to other directory in the same logical drive. The object to be renamed must not be an open object, or <em>the FAT volume can be collapsed</em>. Such the wrong operation can be rejected safely when <a href="appnote.html#dup">file lock feature</a> is enabled.</p>
|
||||
<p>Renames a file or sub-directory and can also move it to other directory in the same volume. The object to be renamed must not be an open object, or <em>the FAT volume can be collapsed</em>. Such the wrong operation is rejected safely when <a href="appnote.html#dup">file lock function</a> is enabled.</p>
|
||||
</div>
|
||||
|
||||
|
||||
@ -77,7 +76,7 @@ FRESULT f_rename (
|
||||
<span class="c">/* Rename an object in the drive 2 */</span>
|
||||
f_rename("2:oldname.txt", "newname.txt");
|
||||
|
||||
<span class="c">/* Rename an object and move it to other directory */</span>
|
||||
<span class="c">/* Rename an object and move it to other directory in the volume */</span>
|
||||
f_rename("log.txt", "old/log0001.txt");
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para">
|
||||
<h2>DIR</h2>
|
||||
<p>The <tt>DIR</tt> structure is used for the work area to read a directory by <tt>f_oepndir</tt>, <tt>f_readdir</tt>, <tt>f_findfirst</tt> and <tt>f_findnext</tt> function. Application program must not modify any member in this structure, or any data on the FAT volume can be collapsed.</p>
|
||||
<p>The <tt>DIR</tt> structure is used for the work area to read a directory by <tt>f_oepndir</tt>, <tt>f_readdir</tt>, <tt>f_findfirst</tt> and <tt>f_findnext</tt> function. Application program must not modify any member in this structure, or any file on the volume can be collapsed.</p>
|
||||
<pre>
|
||||
<span class="k">typedef</span> <span class="k">struct</span> {
|
||||
_FDID obj; <span class="c">/* Owner file sytem object and object identifier */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para">
|
||||
<h2>FATFS</h2>
|
||||
<p>The <tt>FATFS</tt> structure (file system object) holds dynamic work area of individual logical drives. It is given by application program and registerd/unregisterd to the FatFs module with <tt>f_mount</tt> function. Initialization is done on first API call after <tt>f_mount</tt> function or media change. Application program must not modify any member in this structure, or any data on the FAT volume can be collapsed.</p>
|
||||
<p>The <tt>FATFS</tt> structure (file system object) holds dynamic work area of individual logical drives. It is given by application program and registerd/unregisterd to the FatFs module with <tt>f_mount</tt> function. Initialization of the structure is done by volume mount process whenever necessary. Application program must not modify any member in this structure, or the FAT volume can be collapsed.</p>
|
||||
<pre>
|
||||
<span class="k">typedef</span> <span class="k">struct</span> {
|
||||
BYTE fs_type; <span class="c">/* File system type (0, FS_FAT12, FS_FAT16, FS_FAT32 or FS_EXFAT) */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para">
|
||||
<h2>FILINFO</h2>
|
||||
<p>The <tt>FILINFO</tt> structure holds information about the object returned by <tt>f_readdir</tt>, <tt>f_findfirst</tt>, <tt>f_findnext</tt> and <tt>f_stat</tt> function.</p>
|
||||
<p>The <tt>FILINFO</tt> structure holds information about the object returned by <tt>f_readdir</tt>, <tt>f_findfirst</tt>, <tt>f_findnext</tt> and <tt>f_stat</tt> function. Be careful in the size of structure when LFN is enabled.</p>
|
||||
<pre>
|
||||
<span class="k">typedef struct</span> {
|
||||
FSIZE_t fsize; <span class="c">/* File size */</span>
|
||||
@ -33,7 +33,7 @@
|
||||
<h4>Members</h4>
|
||||
<dl>
|
||||
<dt>fsize</dt>
|
||||
<dd>Indicates size of the file in unit of byte. Always zero for directories. <tt>FSIZE_t</tt> is an alias of integer type either <tt>DWORD</tt>(32-bit) or <tt>QWORD</tt>(64-bit) depends on the configuration option <tt>_FS_EXFAT</tt>.</dd>
|
||||
<dd>Indicates size of the file in unit of byte. <tt>FSIZE_t</tt> is an alias of integer type either <tt>DWORD</tt>(32-bit) or <tt>QWORD</tt>(64-bit) depends on the configuration option <tt>_FS_EXFAT</tt>. Do not care when the item is a directory.</dd>
|
||||
<dt>fdate</dt>
|
||||
<dd>Indicates the date when the file was modified or the directory was created.<br>
|
||||
<dl>
|
||||
|
@ -40,7 +40,7 @@ FRESULT f_unlink (
|
||||
<a href="rc.html#ok">FR_NO_FILE</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#ex">FR_EXIST</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
<a href="rc.html#id">FR_INVALID_DRIVE</a>,
|
||||
|
@ -45,6 +45,7 @@ FRESULT f_write (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
@ -53,7 +54,7 @@ FRESULT f_write (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>Description</h4>
|
||||
<p>The function starts to write data to the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes written. After the function succeeded, <tt class="arg">*bw</tt> should be checked to detect the disk full. In case of <tt class="arg">*bw</tt> is less than <tt class="arg">btw</tt>, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.</p>
|
||||
<p>The function starts to write data to the file at the position pointed by the read/write pointer. The read/write pointer advances as number of bytes written. After the function succeeded, <tt class="arg">*bw</tt> should be checked to detect the disk full. In case of <tt class="arg">*bw</tt> < <tt class="arg">btw</tt>, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ FatFsモジュールはANSI C(C89)準拠で記述されているので、普通
|
||||
<p><img src="../res/funcs.png" width="750" height="420" alt="functional diagram"></p>
|
||||
|
||||
<h4>ユーザの作成する関数</h4>
|
||||
<p>ポーティング作業は、要求されるデバイス制御関数を用意することが全てで、それ以外にすることは何もありません。既に動作しているデバイス制御モジュールがあるなら、そのAPIをFatFsに合わせるかグルー関数を介してつなぐだけで済みますが、無い場合はほかから移植するか最初から書くかする必要があります。定義されている全ての関数が常に必要なわけではありません。例えば、リード オンリ構成では書き込み系関数は必要ありません。次の表に構成オプションと要求される関数の対応を示します。</p>
|
||||
<p>ポーティング作業は、要求されるデバイス制御関数を用意することが全てで、それ以外にすることは何もありません。既に動作しているデバイス制御モジュールがあるなら、そのインターフェースをFatFsに合わせるかグルー関数を介してつなぐだけで済みますが、無い場合はほかから移植するか最初から書くかする必要があります。定義されている全ての関数が常に必要なわけではありません。例えば、リード オンリ構成では書き込み系関数は必要ありません。次の表に構成オプションと要求される関数の対応を示します。</p>
|
||||
<table class="lst2">
|
||||
<tr><th>必要な関数</th><th>必要となる条件</th><th>備考</th></tr>
|
||||
<tr><td>disk_status<br>disk_initialize<br>disk_read</td><td>常時</td><td rowspan="5">ffsample.zip (サンプル)<br>その他web上に多数</td></tr>
|
||||
@ -64,7 +64,7 @@ FatFsモジュールはANSI C(C89)準拠で記述されているので、普通
|
||||
<div class="para doc" id="limits">
|
||||
<h3>限界値</h3>
|
||||
<ul>
|
||||
<li>ファイルシステム: FAT12, FAT16, FAT32(r0.0) および exFAT(r1.0)。</li>
|
||||
<li>ファイルシステム: FAT, FAT32(r0.0) および exFAT(r1.0)。</li>
|
||||
<li>同時オープン ファイル数: 無制限。(利用可能メモリによる)</li>
|
||||
<li>同時マウント ボリューム数: 最大 10。</li>
|
||||
<li>ファイル サイズ: 最大 4GiB - 1 (FATボリューム) および、事実上無制限(exFATボリューム)。</li>
|
||||
@ -81,16 +81,16 @@ FatFsモジュールはANSI C(C89)準拠で記述されているので、普通
|
||||
<tr><th></th><th>ARM7<small><br>32bit</small></th><th>ARM7<small><br>Thumb</small></th><th>CM3<small><br>Thumb-2</small></th><th>AVR</th><th>H8/300H</th><th>PIC24</th><th>RL78</th><th>V850ES</th><th>SH-2A</th><th>RX600</th><th>IA-32</th></tr>
|
||||
<tr class="cal"> <td>Compiler</td><td>GCC</td><td>GCC</td><td>GCC</td><td>GCC</td><td>CH38</td><td>C30</td><td>CC78K0R</td><td>CA850</td><td>SHC</td><td>RXC</td><td>MSC</td></tr>
|
||||
<!-- ARM Thumb CM3 AVR H8 PIC24 RL78 V850ES SH-2A RX600 IA-32 -->
|
||||
<tr class="ral"><td class="cal">text (Full, R/W)</td><td>10.1k</td><td>6.6k</td><td>6.2k</td><td>12.1k</td><td>10.5k</td><td>11.2k</td><td>12.6k</td><td>8.5k</td><td>8.7k</td><td>6.3k</td><td>8.4k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/W)</td> <td>6.6k</td><td>4.5k</td><td>4.2k</td> <td>7.9k</td> <td>7.0k</td> <td>7.6k</td> <td>8.8k</td><td>5.9k</td><td>5.8k</td><td>4.3k</td><td>5.8k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Full, R/O)</td> <td>4.8k</td><td>3.1k</td><td>2.9k</td> <td>5.8k</td> <td>5.1k</td> <td>5.5k</td> <td>6.4k</td><td>4.1k</td><td>4.0k</td><td>3.1k</td><td>4.0k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/O)</td> <td>3.5k</td><td>2.4k</td><td>2.3k</td> <td>4.4k</td> <td>3.9k</td> <td>4.2k</td> <td>5.0k</td><td>3.3k</td><td>3.1k</td><td>2.4k</td><td>3.1k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Full, R/W)</td><td>10.4k</td><td>6.8k</td><td>6.3k</td><td>12.4k</td> <td>9.8k</td><td>11.1k</td><td>12.8k</td><td>8.6k</td><td>8.9k</td><td>6.4k</td><td>8.5k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/W)</td> <td>6.8k</td><td>4.6k</td><td>4.3k</td> <td>8.2k</td> <td>6.7k</td> <td>7.6k</td> <td>9.1k</td><td>6.0k</td><td>5.9k</td><td>4.5k</td><td>5.9k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Full, R/O)</td> <td>4.8k</td><td>3.1k</td><td>2.8k</td> <td>5.6k</td> <td>4.6k</td> <td>5.3k</td> <td>6.3k</td><td>4.0k</td><td>3.9k</td><td>3.0k</td><td>3.9k</td></tr>
|
||||
<tr class="ral"><td class="cal">text (Min, R/O)</td> <td>3.6k</td><td>2.4k</td><td>2.3k</td> <td>4.4k</td> <td>3.5k</td> <td>4.0k</td> <td>4.9k</td><td>3.3k</td><td>3.0k</td><td>2.4k</td><td>3.1k</td></tr>
|
||||
<tr class="ral"><td class="cal">bss</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*2 + 2</td><td>V*4 + 2</td><td>V*2 + 2</td><td>V*2 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td><td>V*4 + 2</td></tr>
|
||||
<tr class="ral"><td class="cal">Work area<br><small>(_FS_TINY == 0)</small></td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*560<br>+ F*546</td><td>V*560<br>+ F*546</td><td>V*560<br>+ F*546</td><td>V*560<br>+ F*546</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td><td>V*564<br>+ F*552</td></tr>
|
||||
<tr class="ral"><td class="cal">Work area<br><small>(_FS_TINY == 1)</small></td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*560<br>+ F*34</td><td>V*560<br>+ F*34</td><td>V*560<br>+ F*34</td><td>V*560<br>+ F*34</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td><td>V*564<br>+ F*40</td></tr>
|
||||
</table>
|
||||
<pre>
|
||||
FatFs R0.12 options:
|
||||
FatFs R0.12b options:
|
||||
_FS_READONLY 0 (R/W) or 1 (R/O)
|
||||
_FS_MINIMIZE 0 (Full, with all basic functions) or 3 (Min, with fully minimized)
|
||||
_FS_TINY 0 (Default) or 1 (Tiny file object)
|
||||
@ -144,7 +144,7 @@ And any other options are left not changed from default setting.
|
||||
<div class="para doc" id="lfn">
|
||||
<h3>長いファイル名</h3>
|
||||
<p>FatFsモジュールは、長いファイル名(LFN)をサポートします。ファイルに付けられた2つの異なる名前(短いファル名と長いファイル名)は、<tt>f_readdir</tt>関数を除くファイル操作関数において透過です。デフォルト構成では、LFN機能はOFFになっています。LFN機能を有効にするには、<tt><a href="config.html#use_lfn">_USE_LFN</a></tt>を1,2または3に設定し、<tt>option/unicode.c</tt>をプロジェクトに追加します。LFN機能は、加えてある程度のワーク エリア(LFN操作バッファ)を必要とします。バッファ長は使用できるメモリに応じて<tt><a href="config.html#max_lfn">_MAX_LFN</a></tt>で構成されることができます。LFNの長さは最大255文字に達するので、LFN完全対応のためには<tt>_MAX_LFN</tt>は255に設定されるべきです。与えられたファイル名に対してバッファ長が不足した場合、ファイル関数は<tt>FR_INVALID_NAME</tt>で失敗します。</p>
|
||||
<p>ファイル関数に再入を行う条件の下でLFN機能を使用する場合は、<tt>_USE_LFN</tt>は2または3に設定されなければなりません。この場合、ファイル関数はワーク エリアを動的に確保(スタックまたはヒープ)します。ワーク エリアのサイズは、<tt>(_MAX_LFN + 1) * 2</tt>バイト(exFAT利用時はさらに+608バイト)になるので、スタック等のサイズはそれを考慮した十分な余裕がなければなりません。</p>
|
||||
<p>ファイル関数に再入を行う条件の下でLFN機能を使用する場合は、<tt>_USE_LFN</tt>は2または3に設定されなければなりません。この場合、ファイル関数はワーク エリアを動的に確保(スタックまたはヒープ)します。ワーク エリアのサイズは、<tt>(_MAX_LFN + 1) * 2</tt>バイト(exFAT利用時は加えて<tt>((_MAX_LFN + 44) / 15 * 32</tt>バイト)になるので、これらのメモリ消費量に注意を払う必要があります。</p>
|
||||
<table class="lst2 rset">
|
||||
<caption>LFN構成 at CM3</caption>
|
||||
<tr><th><tt>_CODE_PAGE</tt></th><th>追加コード</th></tr>
|
||||
@ -165,10 +165,9 @@ And any other options are left not changed from default setting.
|
||||
|
||||
<div class="para doc" id="exfat">
|
||||
<h3>exFATファイルシステム</h3>
|
||||
<p>exFAT(Microsoft's Extended File Allocation Table)ファイルシステムは、既に組み込みシステムや情報家電で広く使われているFATファイルシステムを置き換える目的で開発されました。exFATは、64GiB以上のSDメモリ カードで標準ファイルシステムに採用されるなど、FATに並びリムーバブル メディアの標準ファイルシステムの一つとなりつつあります。</p>
|
||||
<p>exFATボリュームでは、FATボリュームで制約となっていた4GiB以上のサイズのファイルを扱え、ファイルシステムのオーバーヘッド(特にファイル アロケーション ディレイ)も大幅に低減され、書き込みスループットがFATより向上しています。しかし、現リビジョンのFatFsでは、実装上の理由から不連続ファイルへのサイズ拡大を伴う書き込み時のとき、スループットがFATより低下します。<tt>f_expand</tt>関数による連続領域の割り当て機能は、この問題の回避に有効かもしれません。</p>
|
||||
<p>exFATはマイクロソフト社が開発したものなので、マイクロソフト社はexFATについていくつかの特許を保有しています。FatFsのexFAT機能は、それの US. Pat. App. Pub. No. 2009/0164440 A1 に基づいた実装です。このため、商用製品でexFAT機能を利用する場合、製品の最終仕向地によってはライセンスが必要になります。最近のFATドライバの多くはexFAT機能を含んでいるため、それらの使用に当たってライセンスが必要になりますが、FatFsは構成オプションでexFAT機能を任意にON/OFFできるため、無効にしてライセンス問題を回避することもできます。</p>
|
||||
<p><em>exFATを有効にすると、FatFsモジュールのC89互換は失われます(64ビット整数型が必要なため)。</em></p>
|
||||
<p>exFAT(Microsoft's Extended File Allocation Table)ファイルシステムは、既に組み込みシステムや情報家電で広く使われているFATファイルシステムを置き換える目的で開発されました。exFATは、64GiB以上のSDメモリ カードで標準ファイルシステムに採用されるなど、FATに並びリムーバブル メディアの標準ファイルシステムの一つとなっています。exFATボリュームでは、FATボリュームで制約となっていた4GiB以上のサイズのファイルを扱え、ファイルシステムのオーバーヘッド(特にファイル アロケーション ディレイ)も大幅に低減され、書き込みスループットがFATより向上しています。</p>
|
||||
<p>exFATはマイクロソフト社が開発したものなので、マイクロソフト社はexFATについていくつかの特許を保有しています。FatFsのexFAT機能は、それの<cite>US. Pat. App. Pub. No. 2009/0164440 A1</cite>に基づいた実装です。このため、商用製品でexFAT機能を利用する場合、製品の最終仕向地によってはライセンスが必要になります。最近のFATドライバの多くはexFAT機能を含んでいるため、それらの使用に当たってライセンスが必要になりますが、FatFsは構成オプションでexFAT機能を任意にON/OFFできるため、無効にしてライセンス問題を回避することもできます。</p>
|
||||
<p><em>exFATを有効にすると、FatFsモジュールのANSI C(C89)互換は失われます(64ビット整数型が必要なため)。</em></p>
|
||||
</div>
|
||||
|
||||
<div class="para doc" id="reentrant">
|
||||
@ -254,13 +253,13 @@ And any other options are left not changed from default setting.
|
||||
|
||||
<div class="para doc" id="license">
|
||||
<h3>FatFsのライセンスについて</h3>
|
||||
<p>FatFsは、作者(ChaN)の個人プロジェクトとして開発されています。現在のリビジョンにおいてコントリビューターはいないため、作者の書いたソース コード以外は含まれません。ソース ファイルにライセンス条件が記述されているので、利用の際はそれに従うこと。原文は英語ですが、参考までに以下に日本語訳を示しておきます。</p>
|
||||
<p>FatFsは、作者(ChaN)の個人プロジェクトとして開発されています。現在までのリビジョンにおいてコントリビューターはいないため、作者以外の書いたソース コードは含まれません。ソース ファイルにライセンス条件が記述されているので、利用の際はそれに従うこと。原文は英語ですが、参考までに以下に日本語訳を示しておきます。</p>
|
||||
<pre>
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT file system module R0.12a /
|
||||
/ FatFs - Generic FAT file system module Rx.xx /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2016, ChaN, all right reserved.
|
||||
/ Copyright (C) 20xx, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFsモジュールはオープンソースソフトウェアです。FatFsの再配布および使用は、
|
||||
/ ソースコードかバイナリ形式か、また変更の有無にかかわらず、次の条件が満たされ
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_initialize</h2>
|
||||
<p>ストレージ デバイスを初期化します。</p>
|
||||
<p>ストレージ デバイスの初期化の際に呼ばれます。</p>
|
||||
<pre>
|
||||
DSTATUS disk_initialize (
|
||||
BYTE <span class="arg">pdrv</span> <span class="c">/* [IN] 物理ドライブ番号 */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_ioctl</h2>
|
||||
<p>一般的なデータ読み書き以外のストレージ デバイス自体に対する様々な制御を行います。</p>
|
||||
<p>一般的なデータ読み書き以外のストレージ デバイス自体に対する様々な制御を行うときに呼ばれます。</p>
|
||||
<pre>
|
||||
DRESULT disk_ioctl (
|
||||
BYTE <span class="arg">pdrv</span>, <span class="c">/* [IN] 物理ドライブ番号 */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_read</h2>
|
||||
<p>ストレージ デバイスからデータを読み出します。</p>
|
||||
<p>ストレージ デバイスからデータを読み出すときに呼ばれます。</p>
|
||||
<pre>
|
||||
DRESULT disk_read (
|
||||
BYTE <span class="arg">pdrv</span>, <span class="c">/* [IN] 物理ドライブ番号 */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_status</h2>
|
||||
<p>ストレージ デバイスの状態を取得します。</p>
|
||||
<p>ストレージ デバイスの状態を取得するために呼ばれます。</p>
|
||||
<pre>
|
||||
DSTATUS disk_status (
|
||||
BYTE <span class="arg">pdrv</span> <span class="c">/* [IN] 物理ドライブ番号 */</span>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>disk_write</h2>
|
||||
<p>ストレージ デバイスにデータを書き込みます。</p>
|
||||
<p>ストレージ デバイスにデータを書き込むときに呼ばれます。</p>
|
||||
<pre>
|
||||
DRESULT disk_write (
|
||||
BYTE <span class="arg">pdrv</span>, <span class="c">/* [IN] 物理ドライブ番号 */</span>
|
||||
|
@ -30,7 +30,7 @@ FRESULT f_expand (
|
||||
<dt>fp</dt>
|
||||
<dd>対象となるファイル オブジェクト構造体へのポインタを指定します。</dd>
|
||||
<dt>fsz</dt>
|
||||
<dd>ファイルに割り当てるバイト単位のサイズ。データ型<tt>FSIZE_t</tt>は、<tt>DWORD</tt>(32-bit)または<tt>QWORD</tt>(64-bit)のエリアスで、exFATサポートの有無により切り替わります。</dd>
|
||||
<dd>ファイルに割り当てるバイト単位のサイズ。データ型<tt>FSIZE_t</tt>は、<tt>DWORD</tt>(32ビット)または<tt>QWORD</tt>(64ビット)のエリアスで、exFATサポートの有無により切り替わります。</dd>
|
||||
<dt>opt</dt>
|
||||
<dd>実際に割り当てを行うかどうか指定するフラグ。</dd>
|
||||
</dl>
|
||||
@ -43,8 +43,8 @@ FRESULT f_expand (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
</div>
|
||||
@ -79,15 +79,15 @@ FRESULT f_expand (
|
||||
res = f_open(fp = malloc(sizeof (FIL)), "file.dat", FA_WRITE|FA_CREATE_ALWAYS);
|
||||
if (res) { <span class="c">/* ファイルが開かれたかチェック */</span>
|
||||
free(fp);
|
||||
...
|
||||
die("Failed to open the file.");
|
||||
}
|
||||
|
||||
<span class="c">/* 100 MiB の連続領域を割り当てる */</span>
|
||||
res = f_expand(fp, 104857600, 1);
|
||||
if (res) { <span class="c">/* 割り当てられたかチェック */</span>
|
||||
...
|
||||
f_close(fp);
|
||||
free(fp);
|
||||
...
|
||||
die("Failed to allocate contiguous area.");
|
||||
}
|
||||
<span class="c">/* 連続ファイル作成成功 fp でアクセス可能 */</span>
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para func">
|
||||
<h2>get_fattime</h2>
|
||||
<p>現在時刻を取得します。</p>
|
||||
<p>現在時刻を取得する際に呼ばれます。</p>
|
||||
<pre>
|
||||
DWORD get_fattime (void);
|
||||
</pre>
|
||||
|
@ -62,22 +62,21 @@ FRESULT f_fdisk (
|
||||
<span class="c">/* ユーザ定義のボリューム管理テーブル (_MULTI_PARTITION == 1 のとき必要) */</span>
|
||||
|
||||
PARTITION VolToPart[] = {
|
||||
{0, 1}, <span class="c">/* 論理ドライブ 0 ==> 物理ドライブ 0, 第1区画 */</span>
|
||||
{0, 2}, <span class="c">/* 論理ドライブ 1 ==> 物理ドライブ 0, 第2区画 */</span>
|
||||
{1, 0} <span class="c">/* 論理ドライブ 2 ==> 物理ドライブ 1, 自動検出 */</span>
|
||||
{0, 1}, <span class="c">/* "0:" ==> 物理ドライブ 0, 第1区画 */</span>
|
||||
{0, 2}, <span class="c">/* "1:" ==> 物理ドライブ 0, 第2区画 */</span>
|
||||
{1, 0} <span class="c">/* "2:" ==> 物理ドライブ 1, 自動検出 */</span>
|
||||
};
|
||||
</pre>
|
||||
<pre>
|
||||
<span class="c">/* 新しい物理ドライブ(0)の初期化 */</span>
|
||||
|
||||
FATFS fs;
|
||||
DWORD plist[] = {50, 50, 0, 0}; <span class="c">/* 第1区画,第2区画それぞれに50%ずつ割り当て */</span>
|
||||
BYTE work[_MAX_SS];
|
||||
|
||||
f_fdisk(0, plist, work); <span class="c">/* 物理ドライブ 0 の分割 */</span>
|
||||
f_fdisk(0, plist, work); <span class="c">/* 物理ドライブ 0 の分割 */</span>
|
||||
|
||||
f_mkfs("0:", FMT_ANY, work, sizeof work); <span class="c">/* 論理ドライブ 0: のフォーマット */</span>
|
||||
f_mkfs("1:", FMT_ANY, work, sizeof work); <span class="c">/* 論理ドライブ 1: のフォーマット */</span>
|
||||
f_mkfs("0:", FM_ANY, work, sizeof work); <span class="c">/* 論理ドライブ 0: のフォーマット */</span>
|
||||
f_mkfs("1:", FM_ANY, work, sizeof work); <span class="c">/* 論理ドライブ 1: のフォーマット */</span>
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
@ -80,9 +80,9 @@ FRESULT f_findfirst (
|
||||
<div class="para use">
|
||||
<h4>使用例</h4>
|
||||
<pre>
|
||||
<span class="c">/* ディレクトリ内のオブジェクトの検索と表示 */</span>
|
||||
<span class="c">/* ディレクトリ内のjpegファイルの検索 */</span>
|
||||
|
||||
void find_image (void)
|
||||
void find_image_file (void)
|
||||
{
|
||||
FRESULT fr; <span class="c">/* API戻り値 */</span>
|
||||
DIR dj; <span class="c">/* ディレクトリ オブジェクト */</span>
|
||||
@ -94,6 +94,7 @@ void find_image (void)
|
||||
printf("%s\n", fno.fname); <span class="c">/* 見つけた項目の名前を表示 */</span>
|
||||
fr = f_findnext(&dj, &fno); <span class="c">/* 次を検索 */</span>
|
||||
}
|
||||
|
||||
f_closedir(&dj);
|
||||
}
|
||||
</pre>
|
||||
|
@ -45,7 +45,7 @@ FRESULT f_forward (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
|
@ -28,7 +28,7 @@ FRESULT f_lseek (
|
||||
<dt>fp</dt>
|
||||
<dd>対象となるファイル オブジェクト構造体へのポインタを指定します。</dd>
|
||||
<dt>ofs</dt>
|
||||
<dd>移動先のオフセット(リード/ライト ポインタ)値。ファイル先頭からのオフセットをバイト単位で指定します。データ型<tt>FSIZE_t</tt>は、<tt>DWORD</tt>(32-bit)または<tt>QWORD</tt>(64-bit)のエリアスで、exFATサポートの有無により切り替わります。</dd>
|
||||
<dd>移動先のオフセット(リード/ライト ポインタ)値。ファイル先頭からのオフセットをバイト単位で指定します。データ型<tt>FSIZE_t</tt>は、<tt>DWORD</tt>(32ビット)または<tt>QWORD</tt>(64ビット)のエリアスで、exFATサポートの有無により切り替わります。</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@ -48,7 +48,8 @@ FRESULT f_lseek (
|
||||
|
||||
<div class="para desc">
|
||||
<h4>解説</h4>
|
||||
<p>ファイルのリード/ライト ポインタ(次に読み出し・書き込みされるバイトのオフセット)を移動します。オフセットの原点はファイル先頭です。書き込みモードでファイル サイズより大きな値を指定すると、そこまでファイル サイズが拡張され、拡張された部分のデータは未定義となります。データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイル サイズを拡張しておくと良いでしょう。ファイルに連続したデータ領域を割り当てる必要があるときは、<tt>f_expand</tt>関数を使用してください。<tt>f_lseek</tt>関数が正常終了したあとは、リード/ライト ポインタが正しく移動したかチェックするべきです。リード/ライト ポインタが指定より小さいときは、次の原因が考えられます。</p>
|
||||
<p>各ファイル オブジェクトが持つリード/ライト ポインタは、次に読み出し・書き込みされるバイトのオフセットを保持し、読み書きされただけ進みます。この関数は、ファイルへの読み書きを行わずにリード/ライト ポインタのみ移動します。</p>
|
||||
<p>書き込みモードでファイル サイズより大きな値を指定すると、そこまでファイル サイズが拡張されますが、拡張された部分のデータは未定義となります。データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイル サイズを拡張しておくと良いでしょう。ファイルに連続したデータ領域を割り当てる必要があるときは、<tt>f_expand</tt>関数を使用してください。<tt>f_lseek</tt>関数が正常終了したあとは、リード/ライト ポインタが正しく移動したかチェックするべきです。リード/ライト ポインタが指定より小さいときは、次の原因が考えられます。</p>
|
||||
<ul>
|
||||
<li>非書き込みモードまたは高速シーク モードのため、ファイル サイズでクリップされた。</li>
|
||||
<li>ファイル拡張中にディスクが満杯になった。</li>
|
||||
|
@ -39,7 +39,7 @@ FRESULT f_mkdir (
|
||||
<a href="rc.html#nr">FR_NOT_READY</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#ex">FR_EXIST</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
<a href="rc.html#id">FR_INVALID_DRIVE</a>,
|
||||
|
@ -52,8 +52,8 @@ FRESULT f_mount (
|
||||
<p>FatFsモジュールでは、それぞれの論理ドライブに<em>ファイル システム オブジェクト</em>というワーク エリアが必要です。この関数は論理ドライブにファイル システム オブジェクトを登録したり抹消したりします。何らかのファイル関数を使用する前に、この関数でその論理ドライブのファイル システム オブジェクトを与えておかなければなりません。<tt class="arg">fs</tt>にヌル ポインタを指定すると、その論理ドライブのファイル システム オブジェクトの登録は抹消されるだけです。登録抹消されたファイル システム オブジェクトのメモリは解放できます。操作の対象の論理ドライブ上に開かれたままのファイルやディレクトリがあった場合、それらに対して作成された構造体は全て無効になります。この関数の内部処理は次のような順に行われます。</p>
|
||||
<ol>
|
||||
<li>対象の論理ドライブを<tt class="arg">path</tt>から得る。</li>
|
||||
<li>既に登録されているファイル システム オブジェクトはクリア(無効化)し、登録を解除する。</li>
|
||||
<li><tt class="arg">fs</tt>が有効なポインタのときは、そのファイル システム オブジェクトをクリアし登録する。</li>
|
||||
<li>登録されているファイル システム オブジェクトがあるときは、それをクリア(無効化)し、登録を解除する。</li>
|
||||
<li><tt class="arg">fs</tt>が有効なポインタのときは、そのファイル システム オブジェクトをクリアし、登録する。</li>
|
||||
<li>マウント動作が指定されているときは、それを実行する。</li>
|
||||
</ol>
|
||||
<p><tt class="arg">opt</tt>に0を指定すると、マウント動作(物理ドライブの初期化、FATボリュームの検索、BPBを解析しファイル システム オブジェクトを初期化)は行われず、関数は物理ドライブの状態に関わらず常に成功します。関数内では下位レイヤへのアクセスは発生せず、指定されたファイル システム オブジェクトをクリア(無効化)し、そのアドレスを内部配列に登録するだけです。単に登録済みのファイル システム オブジェクトをクリアする目的にも使えます。実際のマウント動作は、ボリュームへのアクセス(パス名を渡すもの全て)が行われたときに、次のうちいずれかの条件が真の場合に行われます。</p>
|
||||
|
@ -57,7 +57,7 @@ FRESULT f_open (
|
||||
<a href="rc.html#ok">FR_NO_FILE</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#ex">FR_EXIST</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
|
@ -11,22 +11,30 @@
|
||||
|
||||
<body>
|
||||
<h1>ファイル関数の戻り値</h1>
|
||||
<p>FatFsのAPIでは、一部の関数を除き結果に応じた共通のリザルト コード(FRESULT型(enum))を返します。関数が成功した場合は0を返します。失敗した場合は0以外の値を返し、値はエラーの種類を示します。</p>
|
||||
<p>FatFsのAPIでは、一部の関数を除き結果に応じた共通のリザルト コード(FRESULT型(enum))を返します。関数が成功した場合は0 (<tt>FR_OK</tt>)を返します。失敗した場合は0以外の値を返し、値はエラーの種類を示します。</p>
|
||||
|
||||
<dl class="ret">
|
||||
<dt id="ok">FR_OK (0)</dt>
|
||||
<dd>関数は成功した。</dd>
|
||||
<dt id="de">FR_DISK_ERR</dt>
|
||||
<dd>下位レイヤ(<tt>disk_read/disk_write/disk_ioctl</tt>関数)で回復不能なエラーが発生した。<br>※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外のの操作ができなくなります。</dd>
|
||||
<dd>下位レイヤ(<tt>disk_read/disk_write/disk_ioctl</tt>関数)で回復不能なエラーが発生した。<br>※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外の操作ができなくなります。</dd>
|
||||
<dt id="ie">FR_INT_ERR</dt>
|
||||
<dd>内部処理の健全性に異常が検出された。原因としては次のようなことが考えられます。
|
||||
<dd>内部処理の健全性チェックで何らかの異常が検出された。原因としては次のようなことが考えられます。
|
||||
<ul>
|
||||
<li>ボリューム上のFAT構造にエラーがある。</li>
|
||||
<li>スタック不足や不正なメモリ操作等によるワーク エリアの破壊。多くはこれが原因。</li>
|
||||
<li>ボリューム上のFAT構造にエラーがある。</li>
|
||||
<li>FatFsモジュール自体のバグ。</li>
|
||||
</ul>
|
||||
※開かれたファイルの操作においてこのエラーが発生すると、そのファイル オブジェクトはアボート状態となり、クローズ以外の操作ができなくなります。</dd>
|
||||
<dt id="nr">FR_NOT_READY</dt>
|
||||
<dd><a href="dinit.html"><tt>disk_initialize</tt>関数</a>の失敗。物理ドライブが動作可能な状態にない。</dd>
|
||||
<dd>下位レイヤ(<tt>disk_initialize</tt>関数)の失敗。次のような理由が考えられる。
|
||||
<ul>
|
||||
<li>ドライブにメディアがセットされていない。</li>
|
||||
<li>下位レイヤの実装が不完全。</li>
|
||||
<li>間違ったハードウェア構成。</li>
|
||||
<li>ストレージ デバイスの故障。</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt id="nf">FR_NO_FILE</dt>
|
||||
<dd>指定されたファイルが見つからなかった。</dd>
|
||||
<dt id="np">FR_NO_PATH</dt>
|
||||
@ -41,7 +49,8 @@
|
||||
<li>空でないディレクトリまたはカレント ディレクトリを削除しようとした。</li>
|
||||
<li><tt>FA_READ</tt>フラグを付けずに開いたファイルに対して読み出しを行った。</li>
|
||||
<li><tt>FA_WRITE</tt>フラグを付けずに開いたファイルに対して変更を加えようとした。</li>
|
||||
<li>ボリュームまたは静的ディレクトリが満杯でオブジェクトの新規作成ができなかった。</li>
|
||||
<li>ボリュームまたは静的ディレクトリ(FAT12/16のルート)が満杯でディレクトリ エントリの新規作成ができなかった。</li>
|
||||
<li>ファイルに割り当てる連続領域が見つからなかった。</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt id="ex">FR_EXIST</dt>
|
||||
@ -49,9 +58,9 @@
|
||||
<dt id="io">FR_INVALID_OBJECT</dt>
|
||||
<dd>指定されたファイル オブジェクトやディレクトリ オブジェクトが無効、またはヌル ポインタが渡された。無効になる理由は次のことが考えられます。
|
||||
<ul>
|
||||
<li>オープンされていない、既に閉じられた、破損しているなど。</li>
|
||||
<li>それの属するボリュームのマウント動作があった。ボリューム上で開かれたオブジェクトは全て無効化される。</li>
|
||||
<li>関連する物理ドライブがメディアの取り外しで動作不可能になっている。</li>
|
||||
<li>オープンされていない、既に閉じられている、破損しているなど。</li>
|
||||
<li>そのボリュームでマウント動作があり、ボリューム上の開かれたオブジェクトが全て無効化された。</li>
|
||||
<li>物理ドライブがメディアの取り外し等で動作不可能になっている。</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt id="wp">FR_WRITE_PROTECTED</dt>
|
||||
|
@ -45,7 +45,7 @@ FRESULT f_read (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
|
@ -28,7 +28,7 @@ FRESULT f_rename (
|
||||
<dt>old_name</dt>
|
||||
<dd>変更対象のファイルまたはサブ ディレクトリの<a href="filename.html">パス名</a>を示すヌル文字<tt>'\0'</tt>終端の文字列へのポインタを指定します。</dd>
|
||||
<dt>new_name</dt>
|
||||
<dd>新しいパス名を示すヌル文字<tt>'\0'</tt>終端の文字列へのポインタを指定します。既に存在するオブジェクトと同じ名前は使えません。また、ドライブ番号は指定しても無視され、<tt class="arg">old_name</tt>で決められた論理ドライブ上のオブジェクトとして扱われます。</dd>
|
||||
<dd>新しいパス名を示すヌル文字<tt>'\0'</tt>終端の文字列へのポインタを指定します。また、ドライブ番号は指定しても無視され、<tt class="arg">old_name</tt>で決められたボリューム上のオブジェクトとして扱われます。これと同じパス名(<tt class="arg">old_name</tt>は除く)のオブジェクトが存在すると、関数は<tt>FR_EXIST</tt>で失敗します。</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para">
|
||||
<h2>FATFS</h2>
|
||||
<p><tt>FATFS</tt>構造体(ファイル システム オブジェクト)は、個々の論理ドライブのダイナミック ワーク エリアを保持し、<tt>f_mount</tt>関数でFatFsモジュールに登録されます。初期化が行われるタイミングは、<tt>f_mount</tt>関数(強制マウント指定)の実行またはメディア交換の後の最初のファイル アクセスの時です。アプリケーションは、この構造体のメンバを書き換えてはなりません。</p>
|
||||
<p><tt>FATFS</tt>構造体(ファイル システム オブジェクト)は、個々の論理ドライブのダイナミック ワーク エリアを保持し、<tt>f_mount</tt>関数でFatFsモジュールに登録されます。構造体の作成は、随時ボリューム マウント プロセスにより行われます。アプリケーションは、この構造体のメンバを書き換えてはなりません。</p>
|
||||
|
||||
<pre>
|
||||
<span class="k">typedef</span> <span class="k">struct</span> {
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<div class="para">
|
||||
<h2>FILINFO</h2>
|
||||
<p><tt>FILINFO</tt>構造体は、<tt>f_stat/f_readdir/f_findfirst/f_findnext</tt>関数で返されるオブジェクトに関する情報を保持します。</p>
|
||||
<p><tt>FILINFO</tt>構造体は、<tt>f_stat/f_readdir/f_findfirst/f_findnext</tt>関数で返されるオブジェクトに関する情報を保持します。LFN使用時はサイズが大きく増加するので注意が必要です。</p>
|
||||
<pre>
|
||||
<span class="k">typedef</span> <span class="k">struct</span> {
|
||||
FSIZE_t fsize; <span class="c">/* ファイル サイズ */</span>
|
||||
|
@ -36,7 +36,7 @@ FRESULT f_truncate (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
|
@ -40,7 +40,7 @@ FRESULT f_unlink (
|
||||
<a href="rc.html#ok">FR_NO_FILE</a>,
|
||||
<a href="rc.html#np">FR_NO_PATH</a>,
|
||||
<a href="rc.html#in">FR_INVALID_NAME</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#wp">FR_WRITE_PROTECTED</a>,
|
||||
<a href="rc.html#id">FR_INVALID_DRIVE</a>,
|
||||
<a href="rc.html#ne">FR_NOT_ENABLED</a>,
|
||||
|
@ -45,7 +45,7 @@ FRESULT f_write (
|
||||
<a href="rc.html#ok">FR_OK</a>,
|
||||
<a href="rc.html#de">FR_DISK_ERR</a>,
|
||||
<a href="rc.html#ie">FR_INT_ERR</a>,
|
||||
<a href="rc.html#de">FR_DENIED</a>,
|
||||
<a href="rc.html#dn">FR_DENIED</a>,
|
||||
<a href="rc.html#io">FR_INVALID_OBJECT</a>,
|
||||
<a href="rc.html#tm">FR_TIMEOUT</a>
|
||||
</p>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*----------------------------------------------------------------------/
|
||||
/ Low level disk I/O module function checker
|
||||
/ Low level disk I/O module function checker /
|
||||
/-----------------------------------------------------------------------/
|
||||
/ WARNING: The data on the target drive will be lost!
|
||||
*/
|
||||
@ -41,8 +41,8 @@ int test_diskio (
|
||||
)
|
||||
{
|
||||
UINT n, cc, ns;
|
||||
DWORD sz_drv, lba, lba2, pns = 1;
|
||||
WORD sz_sect, sz_eblk;
|
||||
DWORD sz_drv, lba, lba2, sz_eblk, pns = 1;
|
||||
WORD sz_sect;
|
||||
BYTE *pbuff = (BYTE*)buff;
|
||||
DSTATUS ds;
|
||||
DRESULT dr;
|
||||
@ -113,7 +113,7 @@ int test_diskio (
|
||||
printf(" - failed.\n");
|
||||
}
|
||||
if (dr == RES_OK || sz_eblk >= 2) {
|
||||
printf(" Size of the erase block is %u sectors.\n", sz_eblk);
|
||||
printf(" Size of the erase block is %lu sectors.\n", sz_eblk);
|
||||
} else {
|
||||
printf(" Size of the erase block is unknown.\n");
|
||||
}
|
||||
@ -196,7 +196,7 @@ int test_diskio (
|
||||
pns++;
|
||||
|
||||
/* Single sector write test (misaligned memory address) */
|
||||
printf("**** Single sector write test 2 ****\n");
|
||||
printf("**** Single sector write test (misaligned address) ****\n");
|
||||
lba = 5;
|
||||
for (n = 0, pn(pns); n < sz_sect; n++) pbuff[n+3] = (BYTE)pn(0);
|
||||
printf(" disk_write(%u, 0x%X, %lu, 1)", pdrv, (UINT)(pbuff+3), lba);
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 68 KiB |
195
firmware/chibios-portapack/ext/fatfs/doc/updates.txt
Normal file
195
firmware/chibios-portapack/ext/fatfs/doc/updates.txt
Normal file
@ -0,0 +1,195 @@
|
||||
R0.12c (March 04, 2017)
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
R0.12b (September 4, 2016)
|
||||
Make f_rename() 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)
|
||||
|
||||
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.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 and removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
R0.11a (September 5, 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.11 (February 9, 2015)
|
||||
Added f_findfirst() and f_findnext(). (_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.10c (November 9, 2014)
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
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.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 its lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added an option for 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 larger than 0. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed volume lock is left acquired after return from f_closedir(). (appeared at R0.10)
|
||||
Fixed creation of a directory entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
R0.10 (October 2, 2013)
|
||||
Added an option for character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan option for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount option 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 result code on error.
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
Added f_getlabel() and f_setlabel(). (_USE_LABEL = 1)
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
Changed file functions reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
|
||||
R0.09 (September 6, 2011)
|
||||
f_mkfs() supports multiple partition on a physical drive.
|
||||
Added f_fdisk(). (_MULTI_PARTITION = 2)
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
Fast seek function 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 names.
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase function. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
Added a memory configuration option. (_USE_LFN)
|
||||
Added support of file lock. (_FS_SHARE)
|
||||
Added fast seek function. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed fname member in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
R0.07e (November 3, 2009)
|
||||
Separated out configuration options from ff.h to ffconf.h.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||
Fixed name matching error on the 13 char boundary.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
R0.07c (Junuary 21, 2009)
|
||||
Fixed f_unlink() may return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added support of relative path.
|
||||
Added f_chdir().
|
||||
Added f_chdrive().
|
||||
Added proper case conversion to extended characters.
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
Separated out OS dependent code on re-entrant configuration.
|
||||
Added multiple sector size support.
|
||||
|
||||
R0.07 (April 1, 2009)
|
||||
Merged Tiny-FatFs into FatFs as a buffer configuration option.
|
||||
Added long file name support.
|
||||
Added multiple code page support.
|
||||
Added re-entrancy for multitask operation.
|
||||
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.06 (April 1, 2008)
|
||||
Added f_forward. (Tiny-FatFs)
|
||||
Added string functions: fgets, fputc, fputs and fprintf.
|
||||
Improved performance of f_lseek on moving to the same or following cluster.
|
||||
|
||||
R0.05a (February 3, 2008)
|
||||
Added f_truncate.
|
||||
Added f_utime.
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read can be mistruncated.
|
||||
Fixed cached sector is left not flushed when create and close without write.
|
||||
|
||||
R0.05 (August 26, 2007)
|
||||
Changed arguments of f_read, f_write.
|
||||
Changed arguments of f_mkfs. (FatFs)
|
||||
Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
|
||||
Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
|
||||
|
||||
R0.04b (May 5, 2007)
|
||||
Added _USE_NTFLAG option.
|
||||
Added FSInfo support.
|
||||
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
R0.04a (April 1, 2007)
|
||||
Supported multiple partitions on a plysical drive. (FatFs)
|
||||
Added minimization level 3.
|
||||
Added a capability of extending file size to f_lseek.
|
||||
Fixed an endian sensitive code in f_mkfs. (FatFs)
|
||||
Fixed a problem corresponds to FAT32 support. (Tiny-FatFs)
|
||||
|
||||
R0.04 (February 4, 2007)
|
||||
Supported multiple drive system. (FatFs)
|
||||
Changed some APIs for multiple drive system.
|
||||
Added f_mkfs. (FatFs)
|
||||
Added _USE_FAT32 option. (Tiny-FatFs)
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
Improved cluster scan algolithm to write files fast.
|
||||
Fixed f_mkdir creates incorrect directory on FAT32.
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
Added f_rename.
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
Added a configuration option _FS_MINIMUM.
|
||||
|
||||
R0.02 (Jun 01, 2006)
|
||||
Added FAT12.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) patition.
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
First release
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
Prototype (not released)
|
||||
|
@ -212,7 +212,7 @@ R0.10a (January 15, 2014)
|
||||
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)
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
@ -260,8 +260,29 @@ 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.
|
||||
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.
|
||||
Fixed wrong memory read in create_name().
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() 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)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
FatFs Module Source Files R0.12a
|
||||
FatFs Module Source Files R0.12c
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
history.txt Revision history.
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external functions.
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external modules.
|
||||
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and not depend on any specific
|
||||
storage device. You have to provide a low level disk I/O module that written
|
||||
to control the target storage device.
|
||||
module is only a generic file system layer and it does not depend on any specific
|
||||
storage device. You have to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
||||
|
@ -41,7 +41,7 @@ DSTATUS disk_status (
|
||||
|
||||
return stat;
|
||||
|
||||
case DEB_USB :
|
||||
case DEV_USB :
|
||||
result = USB_disk_status();
|
||||
|
||||
// translate the reslut code here
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT file system module R0.12a /
|
||||
/ FatFs - Generic FAT file system module R0.12c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2016, ChaN, all right reserved.
|
||||
/ Copyright (C) 2017, 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
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 80186 /* Revision ID */
|
||||
#define _FATFS 68300 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -42,13 +42,6 @@ typedef struct {
|
||||
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
|
||||
|
||||
|
||||
@ -140,14 +133,15 @@ 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) */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, 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 n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
|
||||
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) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
|
||||
#endif
|
||||
#if _FS_LOCK != 0
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
@ -159,11 +153,11 @@ typedef struct {
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier */
|
||||
_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 clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||
@ -185,7 +179,7 @@ typedef struct {
|
||||
_FDID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
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
|
||||
@ -285,6 +279,7 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
|
@ -1,265 +0,0 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FFCONF 80186 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define _USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define _USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* 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.
|
||||
/
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 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
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
#define _MAX_LFN 255
|
||||
/* The _USE_LFN switches the support of long file name (LFN).
|
||||
/
|
||||
/ 0: Disable support of LFN. _MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
||||
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
|
||||
/ It should be set 255 to support full featured LFN operations.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree(), must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0
|
||||
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
|
||||
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
|
||||
/ This option also affects behavior of string I/O functions. */
|
||||
|
||||
|
||||
#define _STRF_ENCODE 3
|
||||
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
|
||||
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||
/
|
||||
/ 0: ANSI/OEM
|
||||
/ 1: UTF-16LE
|
||||
/ 2: UTF-16BE
|
||||
/ 3: UTF-8
|
||||
/
|
||||
/ This option has no effect when _LFN_UNICODE == 0. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0
|
||||
/* This option configures support of relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* _STR_VOLUME_ID switches string support of volume ID.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0
|
||||
/* 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 _MIN_SS 512
|
||||
#define _MAX_SS 512
|
||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _USE_TRIM 0
|
||||
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define _FS_EXFAT 0
|
||||
/* This option switches support of exFAT file system in addition to the traditional
|
||||
/ FAT file system. (0:Disable or 1:Enable) To enable exFAT, also LFN must be enabled.
|
||||
/ Note that enabling exFAT discards C89 compatibility. */
|
||||
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 1
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2016
|
||||
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define _FS_LOCK 0
|
||||
/* The option _FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable 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_REENTRANT 0
|
||||
#define _FS_TIMEOUT 1000
|
||||
#define _SYNC_t HANDLE
|
||||
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.c. */
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
@ -30,7 +30,7 @@ typedef unsigned short WCHAR;
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
312
firmware/common/ak4951.cpp
Normal file
312
firmware/common/ak4951.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "ak4951.hpp"
|
||||
|
||||
#include "portapack_io.hpp"
|
||||
using namespace portapack;
|
||||
|
||||
#include <ch.h>
|
||||
|
||||
namespace asahi_kasei {
|
||||
namespace ak4951 {
|
||||
|
||||
void AK4951::configure_digital_interface() {
|
||||
// Configure for external slave mode.
|
||||
map.r.mode_control_1.DIF = 0b11; // I2S compatible
|
||||
map.r.mode_control_1.BCKO = 0; // BICK = 32fs
|
||||
update(Register::ModeControl1);
|
||||
|
||||
map.r.mode_control_2.CM = 0b00; // MCKI = 256fs
|
||||
map.r.mode_control_2.FS = 0b1011; // fs = 48kHz
|
||||
update(Register::ModeControl2);
|
||||
|
||||
// map.r.mode_control_3.DVOLC = 1; // Control L/R channels with DVL (LchDigitalVolumeControl)
|
||||
// update(Register::ModeControl3);
|
||||
|
||||
map.r.power_management_2.MS = 0; // Slave mode
|
||||
map.r.power_management_2.PMPLL = 0; // EXT mode
|
||||
update(Register::PowerManagement2);
|
||||
}
|
||||
|
||||
void AK4951::init() {
|
||||
reset();
|
||||
|
||||
// Write dummy address to "release" the reset.
|
||||
write(0x00, 0x00);
|
||||
|
||||
configure_digital_interface();
|
||||
|
||||
map.r.power_management_1.PMVCM = 1;
|
||||
update(Register::PowerManagement1);
|
||||
|
||||
// Headphone output is hi-Z when not active, reduces crosstalk from speaker output.
|
||||
map.r.beep_control.HPZ = 1;
|
||||
update(Register::BeepControl);
|
||||
|
||||
// Pause for VCOM and REGFIL pins to stabilize.
|
||||
chThdSleepMilliseconds(2);
|
||||
|
||||
headphone_mute();
|
||||
|
||||
// SPK-Amp gain setting: SPKG1-0 bits = “00” → “01”
|
||||
map.r.signal_select_2.SPKG = 0b01;
|
||||
update(Register::SignalSelect2);
|
||||
|
||||
map.r.signal_select_3.MONO = 0b00;
|
||||
update(Register::SignalSelect3);
|
||||
|
||||
map.r.digital_filter_mode.PFSDO = 0; // ADC bypass digital filter block.
|
||||
map.r.digital_filter_mode.ADCPF = 1; // ADC output
|
||||
map.r.digital_filter_mode.PFDAC = 0b00; // SDTI
|
||||
update(Register::DigitalFilterMode);
|
||||
|
||||
// Set up FRN, FRATT and ADRST1-0 bits (Addr = 09H)
|
||||
// map.r.timer_select.FRN = 0;
|
||||
// map.r.timer_select.FRATT = 0;
|
||||
// map.r.timer_select.ADRST = 0b00;
|
||||
// update(Register::TimerSelect);
|
||||
|
||||
// Set up ALC mode (Addr = 0AH, 0BH)
|
||||
// map.r.alc_timer_select. = ;
|
||||
// update(Register::ALCTimerSelect);
|
||||
// map.r.alc_mode_control_1. = ;
|
||||
// update(Register::ALCModeControl1);
|
||||
|
||||
// Set up REF value of ALC (Addr = 0CH)
|
||||
// map.r.alc_mode_control_2. = ;
|
||||
// update(Register::ALCModeControl2);
|
||||
|
||||
// Set up IVOL value of ALC operation start (Addr = 0DH)
|
||||
// map.r.l_ch_input_volume_control. = ;
|
||||
// update(Register::LchInputVolumeControl);
|
||||
// map.r.r_ch_input_volume_control. = ;
|
||||
// update(Register::RchInputVolumeControl);
|
||||
|
||||
// Set up the output digital volume. (Addr = 13H)
|
||||
// set_headphone_volume(...);
|
||||
|
||||
// Set up Programmable Filter Path: PFDAC1-0 bits=“01”, PFSDO=ADCPF bits=“0” (Addr = 1DH)
|
||||
// map.r.digital_filter_mode.PFDAC = 0b01;
|
||||
// update(Register::DigitalFilterMode);
|
||||
}
|
||||
|
||||
bool AK4951::reset() {
|
||||
io.audio_reset_state(true);
|
||||
|
||||
// PDN# pulse must be >200ns
|
||||
chThdSleepMicroseconds(10);
|
||||
|
||||
io.audio_reset_state(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AK4951::set_digtal_volume_control(const reg_t value) {
|
||||
map.r.l_ch_digital_volume_control.DV = value;
|
||||
update(Register::LchDigitalVolumeControl);
|
||||
}
|
||||
|
||||
void AK4951::set_headphone_volume(const volume_t volume) {
|
||||
const auto normalized = headphone_gain_range().normalize(volume);
|
||||
auto n = normalized.centibel() / 5;
|
||||
set_digtal_volume_control(0xcb - n);
|
||||
}
|
||||
|
||||
void AK4951::headphone_mute() {
|
||||
set_digtal_volume_control(0xff);
|
||||
}
|
||||
|
||||
void AK4951::set_dac_power(const bool enable) {
|
||||
map.r.power_management_1.PMDAC = enable;
|
||||
update(Register::PowerManagement1);
|
||||
}
|
||||
|
||||
void AK4951::set_headphone_power(const bool enable) {
|
||||
map.r.power_management_2.PMHPL = map.r.power_management_2.PMHPR = enable;
|
||||
update(Register::PowerManagement2);
|
||||
}
|
||||
|
||||
void AK4951::set_speaker_power(const bool enable) {
|
||||
map.r.power_management_2.PMSL = enable;
|
||||
update(Register::PowerManagement2);
|
||||
}
|
||||
|
||||
void AK4951::select_line_out(const LineOutSelect value) {
|
||||
map.r.power_management_2.LOSEL = (value == LineOutSelect::Line) ? 1 : 0;
|
||||
update(Register::PowerManagement2);
|
||||
}
|
||||
|
||||
void AK4951::headphone_enable() {
|
||||
set_dac_power(true);
|
||||
set_headphone_power(true);
|
||||
|
||||
// Wait for headphone amplifier charge pump power-up.
|
||||
chThdSleepMilliseconds(35);
|
||||
}
|
||||
|
||||
void AK4951::headphone_disable() {
|
||||
set_headphone_power(false);
|
||||
set_dac_power(false);
|
||||
}
|
||||
|
||||
void AK4951::speaker_enable() {
|
||||
// Set up the path of DAC → SPK-Amp: DACS bit = “0” → “1”
|
||||
map.r.signal_select_1.DACS = 1;
|
||||
update(Register::SignalSelect1);
|
||||
|
||||
// Enter Speaker-Amp Output Mode: LOSEL bit = “0”
|
||||
select_line_out(LineOutSelect::Speaker);
|
||||
|
||||
// Power up DAC, Programmable Filter and Speaker-Amp: PMDAC=PMPFIL=PMSL bits=“0”→“1”
|
||||
set_dac_power(true);
|
||||
// map.r.power_management_1.PMPFIL = 1;
|
||||
// update(Register::PowerManagement1);
|
||||
set_speaker_power(true);
|
||||
|
||||
// Time from PMSL=1 to SLPSN=1.
|
||||
chThdSleepMilliseconds(1);
|
||||
|
||||
// Exit the power-save mode of Speaker-Amp: SLPSN bit = “0” → “1”
|
||||
map.r.signal_select_1.SLPSN = 1;
|
||||
update(Register::SignalSelect1);
|
||||
}
|
||||
|
||||
void AK4951::speaker_disable() {
|
||||
// Enter Speaker-Amp Power Save Mode: SLPSN bit = “1” → “0”
|
||||
map.r.signal_select_1.SLPSN = 0;
|
||||
update(Register::SignalSelect1);
|
||||
|
||||
// Disable the path of DAC → SPK-Amp: DACS bit = “1” → “0”
|
||||
map.r.signal_select_1.DACS = 0;
|
||||
update(Register::SignalSelect1);
|
||||
|
||||
// Power down DAC, Programmable Filter and speaker: PMDAC=PMPFIL=PMSL bits= “1”→“0”
|
||||
set_dac_power(false);
|
||||
// map.r.power_management_1.PMPFIL = 0;
|
||||
// update(Register::PowerManagement1);
|
||||
set_speaker_power(false);
|
||||
}
|
||||
|
||||
void AK4951::microphone_enable() {
|
||||
// map.r.digital_mic.DMIC = 0;
|
||||
// update(Register::DigitalMic);
|
||||
|
||||
map.r.signal_select_1.MGAIN20 = 0b110;
|
||||
map.r.signal_select_1.PMMP = 1;
|
||||
map.r.signal_select_1.MPSEL = 1; // MPWR2 pin
|
||||
map.r.signal_select_1.MGAIN3 = 0b0;
|
||||
update(Register::SignalSelect1);
|
||||
|
||||
map.r.signal_select_2.INL = 0b01; // Lch input signal = LIN2
|
||||
map.r.signal_select_2.INR = 0b01; // Rch input signal = RIN2
|
||||
map.r.signal_select_2.MICL = 0; // MPWR = 2.4V
|
||||
update(Register::SignalSelect2);
|
||||
|
||||
// map.r.r_ch_mic_gain_setting.MGR = 0x80; // Microphone sensitivity correction = 0dB.
|
||||
// update(Register::RchMicGainSetting);
|
||||
/*
|
||||
map.r.timer_select.FRN = ?;
|
||||
map.r.timer_select.FRATT = ?;
|
||||
map.r.timer_select.ADRST = 0b??;
|
||||
update(Register::TimerSelect);
|
||||
|
||||
map.r.alc_timer_select. = ?;
|
||||
update(Register::ALCTimerSelect);
|
||||
map.r.alc_mode_control_1. = ?;
|
||||
map.r.alc_mode_control_1.ALC = 1;
|
||||
update(Register::ALCModeControl1);
|
||||
|
||||
map.r.alc_mode_control_2.REF = ?;
|
||||
update(Register::ALCModeControl2);
|
||||
*/
|
||||
// map.r.l_ch_input_volume_control.IV = 0xe1;
|
||||
// update(Register::LchInputVolumeControl);
|
||||
// map.r.r_ch_input_volume_control.IV = 0xe1;
|
||||
// update(Register::RchInputVolumeControl);
|
||||
/*
|
||||
map.r.auto_hpf_control.STG = 0b00;
|
||||
map.r.auto_hpf_control.SENC = 0b011;
|
||||
map.r.auto_hpf_control.AHPF = 0;
|
||||
update(Register::AutoHPFControl);
|
||||
*/
|
||||
map.r.digital_filter_select_1.HPFAD = 1; // HPF1 (after ADC) = on
|
||||
map.r.digital_filter_select_1.HPFC = 0b11; // 2336.8 Hz @ fs=48k
|
||||
update(Register::DigitalFilterSelect1);
|
||||
/*
|
||||
map.r.digital_filter_select_2.HPF = 0;
|
||||
map.r.digital_filter_select_2.LPF = 0;
|
||||
map.r.digital_filter_select_2.FIL3 = 0;
|
||||
map.r.digital_filter_select_2.EQ0 = 0;
|
||||
map.r.digital_filter_select_2.GN = 0b00;
|
||||
update(Register::DigitalFilterSelect2);
|
||||
|
||||
map.r.digital_filter_select_3.EQ1 = 0;
|
||||
map.r.digital_filter_select_3.EQ2 = 0;
|
||||
map.r.digital_filter_select_3.EQ3 = 0;
|
||||
map.r.digital_filter_select_3.EQ4 = 0;
|
||||
map.r.digital_filter_select_3.EQ5 = 0;
|
||||
update(Register::DigitalFilterSelect3);
|
||||
*/
|
||||
map.r.digital_filter_mode.PFSDO = 0; // ADC (+ 1st order HPF) Output
|
||||
map.r.digital_filter_mode.ADCPF = 1; // ADC Output (default)
|
||||
update(Register::DigitalFilterMode);
|
||||
|
||||
// ... Set coefficients ...
|
||||
|
||||
map.r.power_management_1.PMADL = 1; // ADC Lch = Lch input signal
|
||||
map.r.power_management_1.PMADR = 1; // ADC Rch = Rch input signal
|
||||
map.r.power_management_1.PMPFIL = 0; // Programmable filter unused, routed around.
|
||||
update(Register::PowerManagement1);
|
||||
|
||||
// 1059/fs, 22ms @ 48kHz
|
||||
chThdSleepMilliseconds(22);
|
||||
}
|
||||
|
||||
void AK4951::microphone_disable() {
|
||||
map.r.power_management_1.PMADL = 0;
|
||||
map.r.power_management_1.PMADR = 0;
|
||||
map.r.power_management_1.PMPFIL = 0;
|
||||
update(Register::PowerManagement1);
|
||||
|
||||
map.r.alc_mode_control_1.ALC = 0;
|
||||
update(Register::ALCModeControl1);
|
||||
}
|
||||
|
||||
reg_t AK4951::read(const address_t reg_address) {
|
||||
const std::array<uint8_t, 1> tx { reg_address };
|
||||
std::array<uint8_t, 1> rx { 0x00 };
|
||||
bus.transmit(bus_address, tx.data(), tx.size());
|
||||
bus.receive(bus_address, rx.data(), rx.size());
|
||||
return rx[0];
|
||||
}
|
||||
|
||||
void AK4951::update(const Register reg) {
|
||||
write(toUType(reg), map.w[toUType(reg)]);
|
||||
}
|
||||
|
||||
void AK4951::write(const address_t reg_address, const reg_t value) {
|
||||
const std::array<uint8_t, 2> tx { reg_address, value };
|
||||
bus.transmit(bus_address, tx.data(), tx.size());
|
||||
}
|
||||
|
||||
} /* namespace ak4951 */
|
||||
} /* namespace asahi_kasei */
|
882
firmware/common/ak4951.hpp
Normal file
882
firmware/common/ak4951.hpp
Normal file
@ -0,0 +1,882 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __AK4951_H__
|
||||
#define __AK4951_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
#include "i2c_pp.hpp"
|
||||
|
||||
#include "audio.hpp"
|
||||
|
||||
namespace asahi_kasei {
|
||||
namespace ak4951 {
|
||||
|
||||
using address_t = uint8_t;
|
||||
using reg_t = uint8_t;
|
||||
|
||||
constexpr size_t reg_count = 0x50;
|
||||
|
||||
enum class Register : address_t {
|
||||
PowerManagement1 = 0x00,
|
||||
PowerManagement2 = 0x01,
|
||||
SignalSelect1 = 0x02,
|
||||
SignalSelect2 = 0x03,
|
||||
SignalSelect3 = 0x04,
|
||||
ModeControl1 = 0x05,
|
||||
ModeControl2 = 0x06,
|
||||
ModeControl3 = 0x07,
|
||||
DigitalMic = 0x08,
|
||||
TimerSelect = 0x09,
|
||||
ALCTimerSelect = 0x0a,
|
||||
ALCModeControl1 = 0x0b,
|
||||
ALCModeControl2 = 0x0c,
|
||||
LchInputVolumeControl = 0x0d,
|
||||
RchInputVolumeControl = 0x0e,
|
||||
ALCVolume = 0x0f,
|
||||
_Reserved_0x10 = 0x10,
|
||||
RchMicGainSetting = 0x11,
|
||||
BeepControl = 0x12,
|
||||
LchDigitalVolumeControl = 0x13,
|
||||
RchDigitalVolumeControl = 0x14,
|
||||
EQCommonGainSelect = 0x15,
|
||||
EQ2CommonGainSetting = 0x16,
|
||||
EQ3CommonGainSetting = 0x17,
|
||||
EQ4CommonGainSetting = 0x18,
|
||||
EQ5CommonGainSetting = 0x19,
|
||||
AutoHPFControl = 0x1a,
|
||||
DigitalFilterSelect1 = 0x1b,
|
||||
DigitalFilterSelect2 = 0x1c,
|
||||
DigitalFilterMode = 0x1d,
|
||||
HPF2Coefficient0 = 0x1e,
|
||||
HPF2Coefficient1 = 0x1f,
|
||||
HPF2Coefficient2 = 0x20,
|
||||
HPF2Coefficient3 = 0x21,
|
||||
LPFCoefficient0 = 0x22,
|
||||
LPFCoefficient1 = 0x23,
|
||||
LPFCoefficient2 = 0x24,
|
||||
LPFCoefficient3 = 0x25,
|
||||
FIL3Coefficient0 = 0x26,
|
||||
FIL3Coefficient1 = 0x27,
|
||||
FIL3Coefficient2 = 0x28,
|
||||
FIL3Coefficient3 = 0x29,
|
||||
EQCoefficient0 = 0x2a,
|
||||
EQCoefficient1 = 0x2b,
|
||||
EQCoefficient2 = 0x2c,
|
||||
EQCoefficient3 = 0x2d,
|
||||
EQCoefficient4 = 0x2e,
|
||||
EQCoefficient5 = 0x2f,
|
||||
DigitalFilterSelect3 = 0x30,
|
||||
DeviceInformation = 0x31,
|
||||
E1Coefficient0 = 0x32,
|
||||
E1Coefficient1 = 0x33,
|
||||
E1Coefficient2 = 0x34,
|
||||
E1Coefficient3 = 0x35,
|
||||
E1Coefficient4 = 0x36,
|
||||
E1Coefficient5 = 0x37,
|
||||
E2Coefficient0 = 0x38,
|
||||
E2Coefficient1 = 0x39,
|
||||
E2Coefficient2 = 0x3a,
|
||||
E2Coefficient3 = 0x3b,
|
||||
E2Coefficient4 = 0x3c,
|
||||
E2Coefficient5 = 0x3d,
|
||||
E3Coefficient0 = 0x3e,
|
||||
E3Coefficient1 = 0x3f,
|
||||
E3Coefficient2 = 0x40,
|
||||
E3Coefficient3 = 0x41,
|
||||
E3Coefficient4 = 0x42,
|
||||
E3Coefficient5 = 0x43,
|
||||
E4Coefficient0 = 0x44,
|
||||
E4Coefficient1 = 0x45,
|
||||
E4Coefficient2 = 0x46,
|
||||
E4Coefficient3 = 0x47,
|
||||
E4Coefficient4 = 0x48,
|
||||
E4Coefficient5 = 0x49,
|
||||
E5Coefficient0 = 0x4a,
|
||||
E5Coefficient1 = 0x4b,
|
||||
E5Coefficient2 = 0x4c,
|
||||
E5Coefficient3 = 0x4d,
|
||||
E5Coefficient4 = 0x4e,
|
||||
E5Coefficient5 = 0x4f,
|
||||
_count,
|
||||
};
|
||||
|
||||
static_assert(toUType(Register::_count) == reg_count, "Register::_count != reg_count");
|
||||
|
||||
struct PowerManagement1 {
|
||||
reg_t PMADL : 1;
|
||||
reg_t PMADR : 1;
|
||||
reg_t PMDAC : 1;
|
||||
reg_t reserved0 : 2;
|
||||
reg_t PMBP : 1;
|
||||
reg_t PMVCM : 1;
|
||||
reg_t PMPFIL : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(PowerManagement1) == sizeof(reg_t), "wrong size `struct");
|
||||
|
||||
struct PowerManagement2 {
|
||||
reg_t LOSEL : 1;
|
||||
reg_t PMSL : 1;
|
||||
reg_t PMPLL : 1;
|
||||
reg_t MS : 1;
|
||||
reg_t PMHPL : 1;
|
||||
reg_t PMHPR : 1;
|
||||
reg_t reserved0 : 1;
|
||||
reg_t PMOSC : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(PowerManagement2) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct SignalSelect1 {
|
||||
reg_t MGAIN20 : 3;
|
||||
reg_t PMMP : 1;
|
||||
reg_t MPSEL : 1;
|
||||
reg_t DACS : 1;
|
||||
reg_t MGAIN3 : 1;
|
||||
reg_t SLPSN : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SignalSelect1) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct SignalSelect2 {
|
||||
reg_t INR : 2;
|
||||
reg_t INL : 2;
|
||||
reg_t MICL : 1;
|
||||
reg_t reserved0 : 1;
|
||||
reg_t SPKG : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SignalSelect2) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct SignalSelect3 {
|
||||
reg_t MONO : 2;
|
||||
reg_t PTS : 2;
|
||||
reg_t reserved0 : 1;
|
||||
reg_t DACL : 1;
|
||||
reg_t LVCM : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SignalSelect3) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct ModeControl1 {
|
||||
reg_t DIF : 2;
|
||||
reg_t CKOFF : 1;
|
||||
reg_t BCKO : 1;
|
||||
reg_t PLL : 4;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ModeControl1) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct ModeControl2 {
|
||||
reg_t FS : 4;
|
||||
reg_t reserved0 : 2;
|
||||
reg_t CM : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ModeControl2) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct ModeControl3 {
|
||||
reg_t reserved0 : 2;
|
||||
reg_t IVOLC : 1;
|
||||
reg_t reserved1 : 1;
|
||||
reg_t DVOLC : 1;
|
||||
reg_t SMUTE : 1;
|
||||
reg_t THDET : 1;
|
||||
reg_t TSDSEL : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ModeControl3) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct DigitalMIC {
|
||||
reg_t DMIC : 1;
|
||||
reg_t DCLKP : 1;
|
||||
reg_t reserved0 : 1;
|
||||
reg_t DCLKE : 1;
|
||||
reg_t PMDML : 1;
|
||||
reg_t PMDMR : 1;
|
||||
reg_t reserved1 : 1;
|
||||
reg_t READ : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DigitalMIC) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct TimerSelect {
|
||||
reg_t DVTM : 1;
|
||||
reg_t MOFF : 1;
|
||||
reg_t reserved0 : 2;
|
||||
reg_t FRN : 1;
|
||||
reg_t FRATT : 1;
|
||||
reg_t ADRST : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(TimerSelect) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct ALCTimerSelect {
|
||||
reg_t RFST : 2;
|
||||
reg_t WTM : 2;
|
||||
reg_t EQFC : 2;
|
||||
reg_t IVTM : 1;
|
||||
reg_t reserved0 : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ALCTimerSelect) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct ALCModeControl1 {
|
||||
reg_t LMTH10 : 2;
|
||||
reg_t RGAIN : 3;
|
||||
reg_t ALC : 1;
|
||||
reg_t LMTH2 : 1;
|
||||
reg_t ALCEQN : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ALCModeControl1) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct ALCModeControl2 {
|
||||
reg_t REF : 8;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ALCModeControl2) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct InputVolumeControl {
|
||||
reg_t IV : 8;
|
||||
};
|
||||
|
||||
static_assert(sizeof(InputVolumeControl) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using LchInputVolumeControl = InputVolumeControl;
|
||||
using RchInputVolumeControl = InputVolumeControl;
|
||||
|
||||
struct ALCVolume {
|
||||
reg_t VOL : 8;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ALCVolume) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct RchMICGainSetting {
|
||||
reg_t MGR : 8;
|
||||
};
|
||||
|
||||
static_assert(sizeof(RchMICGainSetting) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct BeepControl {
|
||||
reg_t BPLVL : 4;
|
||||
reg_t BEEPH : 1;
|
||||
reg_t BEEPS : 1;
|
||||
reg_t BPVCM : 1;
|
||||
reg_t HPZ : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(BeepControl) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct DigitalVolumeControl {
|
||||
reg_t DV : 8;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DigitalVolumeControl) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using LchDigitalVolumeControl = DigitalVolumeControl;
|
||||
using RchDigitalVolumeControl = DigitalVolumeControl;
|
||||
|
||||
struct EQCommonGainSelect {
|
||||
reg_t reserved0 : 1;
|
||||
reg_t EQC2 : 1;
|
||||
reg_t EQC3 : 1;
|
||||
reg_t EQC4 : 1;
|
||||
reg_t EQC5 : 1;
|
||||
reg_t reserved1 : 3;
|
||||
};
|
||||
|
||||
static_assert(sizeof(EQCommonGainSelect) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct EQCommonGainSetting {
|
||||
reg_t EQnT : 2;
|
||||
reg_t EQnG : 6;
|
||||
};
|
||||
|
||||
static_assert(sizeof(EQCommonGainSetting) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using EQ2CommonGainSetting = EQCommonGainSetting;
|
||||
using EQ3CommonGainSetting = EQCommonGainSetting;
|
||||
using EQ4CommonGainSetting = EQCommonGainSetting;
|
||||
using EQ5CommonGainSetting = EQCommonGainSetting;
|
||||
|
||||
struct AutoHPFControl {
|
||||
reg_t STG : 2;
|
||||
reg_t SENC : 3;
|
||||
reg_t AHPF : 1;
|
||||
reg_t reserved0 : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(AutoHPFControl) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct DigitalFilterSelect1 {
|
||||
reg_t HPFAD : 1;
|
||||
reg_t HPFC : 2;
|
||||
reg_t reserved0 : 5;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DigitalFilterSelect1) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct DigitalFilterSelect2 {
|
||||
reg_t HPF : 1;
|
||||
reg_t LPF : 1;
|
||||
reg_t reserved0 : 2;
|
||||
reg_t FIL3 : 1;
|
||||
reg_t EQ0 : 1;
|
||||
reg_t GN : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DigitalFilterSelect2) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct DigitalFilterMode {
|
||||
reg_t PFSDO : 1;
|
||||
reg_t ADCPF : 1;
|
||||
reg_t PFDAC : 2;
|
||||
reg_t PFVOL : 2;
|
||||
reg_t reserved0 : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DigitalFilterMode) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct Coefficient14L {
|
||||
reg_t l : 8;
|
||||
};
|
||||
|
||||
struct Coefficient14H {
|
||||
reg_t h : 6;
|
||||
reg_t reserved0 : 2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Coefficient14L) == sizeof(reg_t), "wrong size struct");
|
||||
static_assert(sizeof(Coefficient14H) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using Coefficient16L = Coefficient14L;
|
||||
|
||||
struct Coefficient16H {
|
||||
reg_t h : 8;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Coefficient16H) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using HPF2Coefficient0 = Coefficient14L;
|
||||
using HPF2Coefficient1 = Coefficient14H;
|
||||
using HPF2Coefficient2 = Coefficient14L;
|
||||
using HPF2Coefficient3 = Coefficient14H;
|
||||
|
||||
using LPFCoefficient0 = Coefficient14L;
|
||||
using LPFCoefficient1 = Coefficient14H;
|
||||
using LPFCoefficient2 = Coefficient14L;
|
||||
using LPFCoefficient3 = Coefficient14H;
|
||||
|
||||
using FIL3Coefficient0 = Coefficient14L;
|
||||
|
||||
struct FIL3Coefficient1 {
|
||||
reg_t h : 6;
|
||||
reg_t reserved0 : 1;
|
||||
reg_t s : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(FIL3Coefficient1) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using FIL3Coefficient2 = Coefficient14L;
|
||||
using FIL3Coefficient3 = Coefficient14H;
|
||||
|
||||
using EQCoefficient0 = Coefficient16L;
|
||||
using EQCoefficient1 = Coefficient16H;
|
||||
using EQCoefficient2 = Coefficient14L;
|
||||
using EQCoefficient3 = Coefficient14H;
|
||||
using EQCoefficient4 = Coefficient16L;
|
||||
using EQCoefficient5 = Coefficient16H;
|
||||
|
||||
struct DigitalFilterSelect3 {
|
||||
reg_t EQ1 : 1;
|
||||
reg_t EQ2 : 1;
|
||||
reg_t EQ3 : 1;
|
||||
reg_t EQ4 : 1;
|
||||
reg_t EQ5 : 1;
|
||||
reg_t reserved0 : 3;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DigitalFilterSelect3) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
struct DeviceInformation {
|
||||
reg_t DVN : 4;
|
||||
reg_t REV : 4;
|
||||
};
|
||||
|
||||
static_assert(sizeof(DeviceInformation) == sizeof(reg_t), "wrong size struct");
|
||||
|
||||
using E1Coefficient0 = Coefficient16L;
|
||||
using E1Coefficient1 = Coefficient16H;
|
||||
using E1Coefficient2 = Coefficient16L;
|
||||
using E1Coefficient3 = Coefficient16H;
|
||||
using E1Coefficient4 = Coefficient16L;
|
||||
using E1Coefficient5 = Coefficient16H;
|
||||
|
||||
using E2Coefficient0 = Coefficient16L;
|
||||
using E2Coefficient1 = Coefficient16H;
|
||||
using E2Coefficient2 = Coefficient16L;
|
||||
using E2Coefficient3 = Coefficient16H;
|
||||
using E2Coefficient4 = Coefficient16L;
|
||||
using E2Coefficient5 = Coefficient16H;
|
||||
|
||||
using E3Coefficient0 = Coefficient16L;
|
||||
using E3Coefficient1 = Coefficient16H;
|
||||
using E3Coefficient2 = Coefficient16L;
|
||||
using E3Coefficient3 = Coefficient16H;
|
||||
using E3Coefficient4 = Coefficient16L;
|
||||
using E3Coefficient5 = Coefficient16H;
|
||||
|
||||
using E4Coefficient0 = Coefficient16L;
|
||||
using E4Coefficient1 = Coefficient16H;
|
||||
using E4Coefficient2 = Coefficient16L;
|
||||
using E4Coefficient3 = Coefficient16H;
|
||||
using E4Coefficient4 = Coefficient16L;
|
||||
using E4Coefficient5 = Coefficient16H;
|
||||
|
||||
using E5Coefficient0 = Coefficient16L;
|
||||
using E5Coefficient1 = Coefficient16H;
|
||||
using E5Coefficient2 = Coefficient16L;
|
||||
using E5Coefficient3 = Coefficient16H;
|
||||
using E5Coefficient4 = Coefficient16L;
|
||||
using E5Coefficient5 = Coefficient16H;
|
||||
|
||||
struct Register_Type {
|
||||
PowerManagement1 power_management_1;
|
||||
PowerManagement2 power_management_2;
|
||||
SignalSelect1 signal_select_1;
|
||||
SignalSelect2 signal_select_2;
|
||||
SignalSelect3 signal_select_3;
|
||||
ModeControl1 mode_control_1;
|
||||
ModeControl2 mode_control_2;
|
||||
ModeControl3 mode_control_3;
|
||||
DigitalMIC digital_mic;
|
||||
TimerSelect timer_select;
|
||||
ALCTimerSelect alc_timer_select;
|
||||
ALCModeControl1 alc_mode_control_1;
|
||||
ALCModeControl2 alc_mode_control_2;
|
||||
LchInputVolumeControl l_ch_input_volume_control;
|
||||
RchInputVolumeControl r_ch_input_volume_control;
|
||||
ALCVolume alc_volume;
|
||||
reg_t _reserved_0x10;
|
||||
RchMICGainSetting r_ch_mic_gain_setting;
|
||||
BeepControl beep_control;
|
||||
LchDigitalVolumeControl l_ch_digital_volume_control;
|
||||
RchDigitalVolumeControl r_ch_digital_volume_control;
|
||||
EQCommonGainSelect eq_common_gain_select;
|
||||
EQ2CommonGainSetting eq2_common_gain_setting;
|
||||
EQ3CommonGainSetting eq3_common_gain_setting;
|
||||
EQ4CommonGainSetting eq4_common_gain_setting;
|
||||
EQ5CommonGainSetting eq5_common_gain_setting;
|
||||
AutoHPFControl auto_hpf_control;
|
||||
DigitalFilterSelect1 digital_filter_select_1;
|
||||
DigitalFilterSelect2 digital_filter_select_2;
|
||||
DigitalFilterMode digital_filter_mode;
|
||||
HPF2Coefficient0 hpf_2_coefficient_0;
|
||||
HPF2Coefficient1 hpf_2_coefficient_1;
|
||||
HPF2Coefficient2 hpf_2_coefficient_2;
|
||||
HPF2Coefficient3 hpf_2_coefficient_3;
|
||||
LPFCoefficient0 lpf_coefficient_0;
|
||||
LPFCoefficient1 lpf_coefficient_1;
|
||||
LPFCoefficient2 lpf_coefficient_2;
|
||||
LPFCoefficient3 lpf_coefficient_3;
|
||||
FIL3Coefficient0 fil_3_coefficient_0;
|
||||
FIL3Coefficient1 fil_3_coefficient_1;
|
||||
FIL3Coefficient2 fil_3_coefficient_2;
|
||||
FIL3Coefficient3 fil_3_coefficient_3;
|
||||
EQCoefficient0 eq_coefficient_0;
|
||||
EQCoefficient1 eq_coefficient_1;
|
||||
EQCoefficient2 eq_coefficient_2;
|
||||
EQCoefficient3 eq_coefficient_3;
|
||||
EQCoefficient4 eq_coefficient_4;
|
||||
EQCoefficient5 eq_coefficient_5;
|
||||
DigitalFilterSelect3 digital_filter_select_3;
|
||||
DeviceInformation device_information;
|
||||
E1Coefficient0 e1_coefficient_0;
|
||||
E1Coefficient1 e1_coefficient_1;
|
||||
E1Coefficient2 e1_coefficient_2;
|
||||
E1Coefficient3 e1_coefficient_3;
|
||||
E1Coefficient4 e1_coefficient_4;
|
||||
E1Coefficient5 e1_coefficient_5;
|
||||
E2Coefficient0 e2_coefficient_0;
|
||||
E2Coefficient1 e2_coefficient_1;
|
||||
E2Coefficient2 e2_coefficient_2;
|
||||
E2Coefficient3 e2_coefficient_3;
|
||||
E2Coefficient4 e2_coefficient_4;
|
||||
E2Coefficient5 e2_coefficient_5;
|
||||
E3Coefficient0 e3_coefficient_0;
|
||||
E3Coefficient1 e3_coefficient_1;
|
||||
E3Coefficient2 e3_coefficient_2;
|
||||
E3Coefficient3 e3_coefficient_3;
|
||||
E3Coefficient4 e3_coefficient_4;
|
||||
E3Coefficient5 e3_coefficient_5;
|
||||
E4Coefficient0 e4_coefficient_0;
|
||||
E4Coefficient1 e4_coefficient_1;
|
||||
E4Coefficient2 e4_coefficient_2;
|
||||
E4Coefficient3 e4_coefficient_3;
|
||||
E4Coefficient4 e4_coefficient_4;
|
||||
E4Coefficient5 e4_coefficient_5;
|
||||
E5Coefficient0 e5_coefficient_0;
|
||||
E5Coefficient1 e5_coefficient_1;
|
||||
E5Coefficient2 e5_coefficient_2;
|
||||
E5Coefficient3 e5_coefficient_3;
|
||||
E5Coefficient4 e5_coefficient_4;
|
||||
E5Coefficient5 e5_coefficient_5;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Register_Type) == reg_count * sizeof(reg_t), "Register_Type wrong size");
|
||||
|
||||
struct RegisterMap {
|
||||
constexpr RegisterMap(
|
||||
Register_Type values
|
||||
) : r(values)
|
||||
{
|
||||
}
|
||||
|
||||
union {
|
||||
Register_Type r;
|
||||
std::array<reg_t, reg_count> w;
|
||||
};
|
||||
};
|
||||
|
||||
static_assert(sizeof(RegisterMap) == reg_count * sizeof(reg_t), "RegisterMap type wrong size");
|
||||
|
||||
constexpr RegisterMap default_after_reset { Register_Type {
|
||||
.power_management_1 = {
|
||||
.PMADL = 0,
|
||||
.PMADR = 0,
|
||||
.PMDAC = 0,
|
||||
.reserved0 = 0,
|
||||
.PMBP = 0,
|
||||
.PMVCM = 0,
|
||||
.PMPFIL = 0,
|
||||
},
|
||||
.power_management_2 = {
|
||||
.LOSEL = 0,
|
||||
.PMSL = 0,
|
||||
.PMPLL = 0,
|
||||
.MS = 0,
|
||||
.PMHPL = 0,
|
||||
.PMHPR = 0,
|
||||
.reserved0 = 0,
|
||||
.PMOSC = 0,
|
||||
},
|
||||
.signal_select_1 = {
|
||||
.MGAIN20 = 0b110,
|
||||
.PMMP = 0,
|
||||
.MPSEL = 0,
|
||||
.DACS = 0,
|
||||
.MGAIN3 = 0,
|
||||
.SLPSN = 0,
|
||||
},
|
||||
.signal_select_2 = {
|
||||
.INR = 0b00,
|
||||
.INL = 0b00,
|
||||
.MICL = 0,
|
||||
.reserved0 = 0,
|
||||
.SPKG = 0b00,
|
||||
},
|
||||
.signal_select_3 = {
|
||||
.MONO = 0b00,
|
||||
.PTS = 0b01,
|
||||
.reserved0 = 0,
|
||||
.DACL = 0,
|
||||
.LVCM = 0b01,
|
||||
},
|
||||
.mode_control_1 = {
|
||||
.DIF = 0b10,
|
||||
.CKOFF = 0,
|
||||
.BCKO = 0,
|
||||
.PLL = 0b0101,
|
||||
},
|
||||
.mode_control_2 = {
|
||||
.FS = 0b1011,
|
||||
.reserved0 = 0,
|
||||
.CM = 0b00,
|
||||
},
|
||||
.mode_control_3 = {
|
||||
.reserved0 = 0,
|
||||
.IVOLC = 1,
|
||||
.reserved1 = 0,
|
||||
.DVOLC = 1,
|
||||
.SMUTE = 0,
|
||||
.THDET = 0,
|
||||
.TSDSEL = 0,
|
||||
},
|
||||
.digital_mic = {
|
||||
.DMIC = 0,
|
||||
.DCLKP = 0,
|
||||
.reserved0 = 0,
|
||||
.DCLKE = 0,
|
||||
.PMDML = 0,
|
||||
.PMDMR = 1,
|
||||
.reserved1 = 0,
|
||||
.READ = 0,
|
||||
},
|
||||
.timer_select = {
|
||||
.DVTM = 0,
|
||||
.MOFF = 0,
|
||||
.reserved0 = 0,
|
||||
.FRN = 0,
|
||||
.FRATT = 0,
|
||||
.ADRST = 0b00,
|
||||
},
|
||||
.alc_timer_select = {
|
||||
.RFST = 0b00,
|
||||
.WTM = 0b00,
|
||||
.EQFC = 0b10,
|
||||
.IVTM = 1,
|
||||
.reserved0 = 0,
|
||||
},
|
||||
.alc_mode_control_1 = {
|
||||
.LMTH10 = 0b00,
|
||||
.RGAIN = 0b000,
|
||||
.ALC = 0,
|
||||
.LMTH2 = 0,
|
||||
.ALCEQN = 0,
|
||||
},
|
||||
.alc_mode_control_2 = {
|
||||
.REF = 0xe1,
|
||||
},
|
||||
.l_ch_input_volume_control = {
|
||||
.IV = 0xe1,
|
||||
},
|
||||
.r_ch_input_volume_control = {
|
||||
.IV = 0xe1,
|
||||
},
|
||||
.alc_volume = {
|
||||
.VOL = 0x00, // Read-only.
|
||||
},
|
||||
._reserved_0x10 = 0x80,
|
||||
.r_ch_mic_gain_setting = {
|
||||
.MGR = 0x80,
|
||||
},
|
||||
.beep_control = {
|
||||
.BPLVL = 0b0000,
|
||||
.BEEPH = 0,
|
||||
.BEEPS = 0,
|
||||
.BPVCM = 0,
|
||||
.HPZ = 0,
|
||||
},
|
||||
.l_ch_digital_volume_control = {
|
||||
.DV = 0x18,
|
||||
},
|
||||
.r_ch_digital_volume_control = {
|
||||
.DV = 0x18,
|
||||
},
|
||||
.eq_common_gain_select = {
|
||||
.reserved0 = 0,
|
||||
.EQC2 = 0,
|
||||
.EQC3 = 0,
|
||||
.EQC4 = 0,
|
||||
.EQC5 = 0,
|
||||
.reserved1 = 0,
|
||||
},
|
||||
.eq2_common_gain_setting = {
|
||||
.EQnT = 0b00,
|
||||
.EQnG = 0b000000,
|
||||
},
|
||||
.eq3_common_gain_setting = {
|
||||
.EQnT = 0b00,
|
||||
.EQnG = 0b000000,
|
||||
},
|
||||
.eq4_common_gain_setting = {
|
||||
.EQnT = 0b00,
|
||||
.EQnG = 0b000000,
|
||||
},
|
||||
.eq5_common_gain_setting = {
|
||||
.EQnT = 0b00,
|
||||
.EQnG = 0b000000,
|
||||
},
|
||||
.auto_hpf_control = {
|
||||
.STG = 0b00,
|
||||
.SENC = 0b011,
|
||||
.AHPF = 0,
|
||||
.reserved0 = 0,
|
||||
},
|
||||
.digital_filter_select_1 = {
|
||||
.HPFAD = 1,
|
||||
.HPFC = 0b00,
|
||||
.reserved0 = 0,
|
||||
},
|
||||
.digital_filter_select_2 = {
|
||||
.HPF = 0,
|
||||
.LPF = 0,
|
||||
.reserved0 = 0,
|
||||
.FIL3 = 0,
|
||||
.EQ0 = 0,
|
||||
.GN = 0b00,
|
||||
},
|
||||
.digital_filter_mode = {
|
||||
.PFSDO = 1,
|
||||
.ADCPF = 1,
|
||||
.PFDAC = 0b00,
|
||||
.PFVOL = 0b00,
|
||||
.reserved0 = 0,
|
||||
},
|
||||
|
||||
.hpf_2_coefficient_0 = { .l = 0xb0 },
|
||||
.hpf_2_coefficient_1 = { .h = 0x1f, .reserved0 = 0 },
|
||||
.hpf_2_coefficient_2 = { .l = 0x9f },
|
||||
.hpf_2_coefficient_3 = { .h = 0x20, .reserved0 = 0 },
|
||||
|
||||
.lpf_coefficient_0 = { .l = 0x00 },
|
||||
.lpf_coefficient_1 = { .h = 0x00, .reserved0 = 0 },
|
||||
.lpf_coefficient_2 = { .l = 0x00 },
|
||||
.lpf_coefficient_3 = { .h = 0x00, .reserved0 = 0 },
|
||||
|
||||
.fil_3_coefficient_0 = { .l = 0x00 },
|
||||
.fil_3_coefficient_1 = { .h = 0x00, .reserved0 = 0, .s = 0 },
|
||||
.fil_3_coefficient_2 = { .l = 0x00 },
|
||||
.fil_3_coefficient_3 = { .h = 0x00, .reserved0 = 0 },
|
||||
|
||||
.eq_coefficient_0 = { .l = 0x00 },
|
||||
.eq_coefficient_1 = { .h = 0x00 },
|
||||
.eq_coefficient_2 = { .l = 0x00 },
|
||||
.eq_coefficient_3 = { .h = 0x00, .reserved0 = 0 },
|
||||
.eq_coefficient_4 = { .l = 0x00 },
|
||||
.eq_coefficient_5 = { .h = 0x00 },
|
||||
|
||||
.digital_filter_select_3 = {
|
||||
.EQ1 = 0,
|
||||
.EQ2 = 0,
|
||||
.EQ3 = 0,
|
||||
.EQ4 = 0,
|
||||
.EQ5 = 0,
|
||||
.reserved0 = 0,
|
||||
},
|
||||
.device_information = {
|
||||
.DVN = 0b0001,
|
||||
.REV = 0b1100,
|
||||
},
|
||||
|
||||
.e1_coefficient_0 = { .l = 0x00 },
|
||||
.e1_coefficient_1 = { .h = 0x00 },
|
||||
.e1_coefficient_2 = { .l = 0x00 },
|
||||
.e1_coefficient_3 = { .h = 0x00 },
|
||||
.e1_coefficient_4 = { .l = 0x00 },
|
||||
.e1_coefficient_5 = { .h = 0x00 },
|
||||
|
||||
.e2_coefficient_0 = { .l = 0x00 },
|
||||
.e2_coefficient_1 = { .h = 0x00 },
|
||||
.e2_coefficient_2 = { .l = 0x00 },
|
||||
.e2_coefficient_3 = { .h = 0x00 },
|
||||
.e2_coefficient_4 = { .l = 0x00 },
|
||||
.e2_coefficient_5 = { .h = 0x00 },
|
||||
|
||||
.e3_coefficient_0 = { .l = 0x00 },
|
||||
.e3_coefficient_1 = { .h = 0x00 },
|
||||
.e3_coefficient_2 = { .l = 0x00 },
|
||||
.e3_coefficient_3 = { .h = 0x00 },
|
||||
.e3_coefficient_4 = { .l = 0x00 },
|
||||
.e3_coefficient_5 = { .h = 0x00 },
|
||||
|
||||
.e4_coefficient_0 = { .l = 0x00 },
|
||||
.e4_coefficient_1 = { .h = 0x00 },
|
||||
.e4_coefficient_2 = { .l = 0x00 },
|
||||
.e4_coefficient_3 = { .h = 0x00 },
|
||||
.e4_coefficient_4 = { .l = 0x00 },
|
||||
.e4_coefficient_5 = { .h = 0x00 },
|
||||
|
||||
.e5_coefficient_0 = { .l = 0x00 },
|
||||
.e5_coefficient_1 = { .h = 0x00 },
|
||||
.e5_coefficient_2 = { .l = 0x00 },
|
||||
.e5_coefficient_3 = { .h = 0x00 },
|
||||
.e5_coefficient_4 = { .l = 0x00 },
|
||||
.e5_coefficient_5 = { .h = 0x00 },
|
||||
} };
|
||||
|
||||
class AK4951 : public audio::Codec {
|
||||
public:
|
||||
constexpr AK4951(
|
||||
I2C& bus,
|
||||
const I2C::address_t bus_address
|
||||
) : bus(bus),
|
||||
bus_address(bus_address)
|
||||
{
|
||||
}
|
||||
|
||||
std::string name() const override {
|
||||
return "AK4951";
|
||||
}
|
||||
|
||||
void init() override;
|
||||
bool reset() override;
|
||||
|
||||
volume_range_t headphone_gain_range() const override {
|
||||
return { -89.5_dB, 12.0_dB };
|
||||
}
|
||||
|
||||
void headphone_enable() override;
|
||||
void headphone_disable() override;
|
||||
|
||||
void speaker_enable();
|
||||
void speaker_disable();
|
||||
|
||||
void set_headphone_volume(const volume_t volume) override;
|
||||
void headphone_mute();
|
||||
|
||||
void microphone_enable();
|
||||
void microphone_disable();
|
||||
|
||||
size_t reg_count() const override {
|
||||
return asahi_kasei::ak4951::reg_count;
|
||||
}
|
||||
|
||||
size_t reg_bits() const override {
|
||||
return 8;
|
||||
}
|
||||
|
||||
uint32_t reg_read(const size_t reg_address) override {
|
||||
return read(reg_address);
|
||||
}
|
||||
|
||||
private:
|
||||
I2C& bus;
|
||||
const I2C::address_t bus_address;
|
||||
RegisterMap map { default_after_reset };
|
||||
|
||||
enum class LineOutSelect {
|
||||
Speaker,
|
||||
Line,
|
||||
};
|
||||
|
||||
void configure_digital_interface();
|
||||
void set_digtal_volume_control(const reg_t value);
|
||||
void set_dac_power(const bool enable);
|
||||
void set_headphone_power(const bool enable);
|
||||
void set_speaker_power(const bool enable);
|
||||
void select_line_out(const LineOutSelect value);
|
||||
|
||||
reg_t read(const address_t reg_address);
|
||||
void update(const Register reg);
|
||||
void write(const address_t reg_address, const reg_t value);
|
||||
};
|
||||
|
||||
} /* namespace ak4951 */
|
||||
} /* namespace asahi_kasei */
|
||||
|
||||
#endif/*__AK4951_H__*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user