1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-25 17:25:13 +03:00

Merge branch 'next' into schwabe/spektrum_dsm2_bind

# Conflicts:
#	radio/src/translations/de.h.txt
This commit is contained in:
Andre Bernet 2016-10-21 19:35:46 +02:00
commit 978867d509
92 changed files with 11241 additions and 9188 deletions

View file

@ -18,6 +18,8 @@ if(POLICY CMP0043)
cmake_policy(SET CMP0043 NEW) cmake_policy(SET CMP0043 NEW)
endif() endif()
set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio) set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio)

View file

@ -1,4 +1,4 @@
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(C9X_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR}) set(C9X_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR})
set(COMPANION_NAME "companion${C9X_NAME_SUFFIX}") set(COMPANION_NAME "companion${C9X_NAME_SUFFIX}")
set(SIMULATOR_NAME "simulator${C9X_NAME_SUFFIX}") set(SIMULATOR_NAME "simulator${C9X_NAME_SUFFIX}")
@ -6,11 +6,17 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
else(${CMAKE_SYSTEM_NAME} MATCHES "Linux") else(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(COMPANION_NAME "companion") set(COMPANION_NAME "companion")
set(SIMULATOR_NAME "simulator") set(SIMULATOR_NAME "simulator")
if(APPLE)
set(SIMULATOR_LIB_PATH ${CMAKE_INSTALL_PREFIX}/Contents/companion.app/Ressources)
endif()
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# This the name that the user will see in the generated DMG and what the application
# will be called under /Applications. We include the version string to make installing
# different versions for different eeproms easier, i.e. without manually renaming
set(COMPANION_OSX_APP_BUNDLE_NAME "OpenTX Companion ${VERSION_MAJOR}.${VERSION_MINOR}")
# On OS X we copy dfu-util to the application bundle. This the path from which we copy
# the binary (default homebrew path)
set(DFU_UTIL_PATH "/usr/local/bin/dfu-util")
option(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default option(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default
if(ALLOW_NIGHTLY_BUILDS) if(ALLOW_NIGHTLY_BUILDS)
add_definitions(-DALLOW_NIGHTLY_BUILDS) add_definitions(-DALLOW_NIGHTLY_BUILDS)
@ -225,13 +231,7 @@ add_custom_target(gen_qrc DEPENDS ${companion_RCC})
add_definitions(-DQT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}") add_definitions(-DQT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}")
if(APPLE) add_executable(${COMPANION_NAME} MACOSX_BUNDLE WIN32 ${companion_SRCS} ${companion_RCC} ${companion_QM})
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${companion_SRCS} ${companion_RCC} ${companion_QM})
# OS X compiler no longer automatically includes /Library/Frameworks in search path
set(CMAKE_EXE_LINKER_FLAGS -F/Library/Frameworks)
else()
add_executable(${COMPANION_NAME} WIN32 ${companion_SRCS} ${companion_RCC} ${companion_QM})
endif()
add_dependencies(${COMPANION_NAME} gen_qrc) add_dependencies(${COMPANION_NAME} gen_qrc)
qt5_use_modules(${COMPANION_NAME} Core Widgets Network) qt5_use_modules(${COMPANION_NAME} Core Widgets Network)
@ -255,11 +255,8 @@ if(WIN32)
set(simu_SRCS ${simu_SRCS} icon.rc) set(simu_SRCS ${simu_SRCS} icon.rc)
endif() endif()
if(APPLE)
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${simu_SRCS} ${companion_RCC}) add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE WIN32 ${simu_SRCS} ${companion_RCC})
else()
add_executable(${SIMULATOR_NAME} WIN32 ${simu_SRCS} ${companion_RCC})
endif()
add_dependencies(${SIMULATOR_NAME} gen_qrc) add_dependencies(${SIMULATOR_NAME} gen_qrc)
# TODO not the same link command than companion? # TODO not the same link command than companion?
@ -267,15 +264,11 @@ target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common qxtcommandopti
############# Packaging #################### ############# Packaging ####################
message(STATUS ${CMAKE_BINARY_DIR} ${CMAKE_INSTALL_PREFIX}/bin) message(STATUS ${CMAKE_BINARY_DIR} ${CMAKE_INSTALL_PREFIX}/bin)
if(APPLE) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install(DIRECTORY ${CMAKE_BINARY_DIR}/ DESTINATION ${SIMULATOR_LIB_PATH} USE_SOURCE_PERMISSIONS
FILES_MATCHING PATTERN "libopentx-*.dylib"
)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install(TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) install(TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) install(TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install(DIRECTORY ${CMAKE_BINARY_DIR}/ DESTINATION ${SIMULATOR_LIB_PATH} USE_SOURCE_PERMISSIONS install(DIRECTORY ${CMAKE_BINARY_DIR}/ DESTINATION ${SIMULATOR_LIB_PATH} USE_SOURCE_PERMISSIONS
FILES_MATCHING PATTERN "libopentx-*.so" FILES_MATCHING PATTERN "libopentx-*${CMAKE_SHARED_LIBRARY_SUFFIX}"
PATTERN "CMakeFiles" EXCLUDE PATTERN "CMakeFiles" EXCLUDE
PATTERN "_CPack_Packages" EXCLUDE PATTERN "_CPack_Packages" EXCLUDE
PATTERN "companion" EXCLUDE PATTERN "companion" EXCLUDE
@ -353,37 +346,6 @@ if(WIN32)
) )
endif() endif()
if(APPLE)
set(MACOSX_BUNDLE_ICON_FILE iconmac.icns)
SET_SOURCE_FILES_PROPERTIES(${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set(${COMPANION_SOURCES} ${COMPANION_SOURCES} ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE})
if(CMAKE_GENERATOR STREQUAL Xcode)
set(WORK_DIR ${CMAKE_BINARY_DIR}/Debug)
else()
set(WORK_DIR ${PROJECT_BINARY_DIR})
endif()
add_custom_target(addframeworks
COMMAND mkdir -p companion.app/Contents/Frameworks
COMMAND mkdir -p companion.app/Contents/Resources
COMMAND mkdir -p companion.app/Contents/translations
COMMAND rsync ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE} companion.app/Contents/Resources/${MACOSX_BUNDLE_ICON_FILE} # Copy the icon files
COMMAND rsync -r --exclude=.svn ${PROJECT_SOURCE_DIR}/../targets/mac/qt_menu.nib companion.app/Contents/Resources/
COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations
COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations
COMMAND rsync -r /Library/Frameworks/SDL.framework companion.app/Contents/Frameworks/
COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app
COMMAND install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL companion.app/Contents/MacOS/companion
WORKING_DIRECTORY ${WORK_DIR}
DEPENDS ${COMPANION_NAME})
add_custom_target(makedmg
COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app -dmg -no-plugins
WORKING_DIRECTORY ${WORK_DIR}
DEPENDS addframeworks opentx-simulators-bundle)
endif()
if(LUPDATE_FOUND) if(LUPDATE_FOUND)
add_custom_target(translations add_custom_target(translations
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@ -396,23 +358,92 @@ else()
endif() endif()
set(CPACK_PACKAGE_NAME "companion${C9X_NAME_SUFFIX}") set(CPACK_PACKAGE_NAME "companion${C9X_NAME_SUFFIX}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTx open source firmware") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTX open source firmware")
string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE) string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE)
# The file stripping is deliberately disabled, with the stripped file we get # The file stripping is deliberately disabled, with the stripped file we get
# very poor trace-backs from the users when they report Companion crash # very poor trace-backs from the users when they report Companion crash
set(CPACK_STRIP_FILES FALSE) set(CPACK_STRIP_FILES FALSE)
set(plugin_dest_dir bin)
set(qtconf_dest_dir bin)
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${COMPANION_NAME}")
IF(APPLE)
set(plugin_dest_dir ${COMPANION_NAME}.app/Contents/Plugins)
set(qtconf_dest_dir ${COMPANION_NAME}.app/Contents/Resources)
set(translations_dest_dir ${COMPANION_NAME}.app/Contents/translations)
set(APPS "\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app")
set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Companion ${VERSION_MAJOR}.${VERSION_MINOR}")
set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simulator ${VERSION_MAJOR}.${VERSION_MINOR}")
ENDIF(APPLE)
IF(WIN32)
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/QtTest.exe")
ENDIF(WIN32)
INSTALL(TARGETS ${COMPANION_NAME} INSTALL(TARGETS ${COMPANION_NAME}
BUNDLE DESTINATION . COMPONENT Runtime BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION bin COMPONENT Runtime RUNTIME DESTINATION bin COMPONENT Runtime
) )
# Qt5 + Cmake + Mac is poorly documented. A lot of this is guesswork
# and trial and error. Do not hesitate to fix it for the better
if(APPLE)
set(APPS "\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app")
# directories to look for dependencies file(GLOB simulator_plugins "${CMAKE_BINARY_DIR}/libopentx-*${CMAKE_SHARED_LIBRARY_SUFFIX}")
SET(DIRS ${QT_LIBRARY_DIRS}) set(companion_res_dir ${COMPANION_NAME}.app/Contents/Resources)
install(FILES ${simulator_plugins} DESTINATION "${companion_res_dir}" COMPONENT Runtime)
# Write qt.conf to tell qt where to find it plugins
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = Plugins\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
DESTINATION "${companion_res_dir}"
COMPONENT Runtime)
# menu file
install(DIRECTORY ${PROJECT_SOURCE_DIR}/companion/targets/mac/qt_menu.nib DESTINATION "${companion_res_dir}" COMPONENT Runtime)
# translations file
install(FILES ${companion_QM} DESTINATION "${translations_dest_dir}" COMPONENT Runtime)
# manually add the cocoa plugin
get_target_property(QPA_PLUGIN Qt5::QCocoaIntegrationPlugin LOCATION)
install(FILES ${QPA_PLUGIN} DESTINATION "${plugin_dest_dir}/platforms/" COMPONENT Runtime)
set(bundle_qt_libs "\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/platforms/libqcocoa.dylib")
# Add icon
set(MACOSX_BUNDLE_ICON_FILE iconmac.icns)
set(MAC_ICON_FILE ${COMPANION_SRC_DIRECTORY}/images/${MACOSX_BUNDLE_ICON_FILE})
SET_SOURCE_FILES_PROPERTIES(${MAC_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set(${COMPANION_SOURCES} ${COMPANION_SOURCES} ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE})
install(FILES ${MAC_ICON_FILE} DESTINATION ${companion_res_dir} COMPONENT Runtime)
# Copy dfu-util, resolve symlink first
get_filename_component(DFU_UTIL_ABSOLUTE_PATH ${DFU_UTIL_PATH} REALPATH)
install(FILES ${DFU_UTIL_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
set(bundle_dfu_util_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util")
# These needs to be relative to CMAKE_INSTALL_PREFIX
get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION)
get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH)
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
# Include depencies (adding frameworks, fixing the embbeded libraries)
# I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is
# technically a hack (that is already is in the Bundle library ....)
install(CODE "
include(BundleUtilities)
file(GLOB bundle_simulator_libs \"\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/libopentx-*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
set(BU_CHMOD_BUNDLE_ITEMS on)
fixup_bundle(\"${APPS}\" \"\${bundle_simulator_libs};${bundle_qt_libs};${bundle_dfu_util_path}\" \"${QT_LIBRARY_DIR}\")
file(RENAME \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app\" \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_OSX_APP_BUNDLE_NAME}.app\")
" COMPONENT Runtime)
endif()
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
if(DPKG_PROGRAM) if(DPKG_PROGRAM)
set(CPACK_GENERATOR "DEB") set(CPACK_GENERATOR "DEB")
execute_process( execute_process(
@ -428,26 +459,19 @@ if(DPKG_PROGRAM)
set(CPACK_DEBIAN_ARCHITECTURE $(CMAKE_SYSTEM_PROCESSOR)) set(CPACK_DEBIAN_ARCHITECTURE $(CMAKE_SYSTEM_PROCESSOR))
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
elseif(APPLE) elseif(APPLE)
set(APPS "${COMPANION_NAME}.app")
set(CPACK_GENERATOR "DragNDrop") set(CPACK_GENERATOR "DragNDrop")
# set(CPACK_GENERATOR "TGZ") # for quick testing
set(CPACK_BINARY_DRAGNDROP ON) set(CPACK_BINARY_DRAGNDROP ON)
set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/dmg_background.png) set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/splash22_3_dmg.png)
set(CPACK_DMG_VOLUME_NAME "OpenTX Companion") set(CPACK_DMG_VOLUME_NAME "OpenTX Companion")
set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store) set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store)
set(CPACK_PACKAGE_FILE_NAME "opentx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}")
else(DPKG_PROGRAM) else(DPKG_PROGRAM)
set(CPACK_GENERATOR "RPM") set(CPACK_GENERATOR "RPM")
set(CPACK_RPM_PACKAGE_VERSION ${VERSION}) set(CPACK_RPM_PACKAGE_VERSION ${VERSION})
set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}-${CMAKE_SYSTEM_PROCESSOR}") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}-${CMAKE_SYSTEM_PROCESSOR}")
SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib /lib/udev /lib/udev/rules.d") set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib /lib/udev /lib/udev/rules.d")
endif(DPKG_PROGRAM) endif(DPKG_PROGRAM)
INSTALL(CODE "
include(BundleUtilities)
" COMPONENT Runtime
VERIFY_APP(${COMPANION_NAME})
)
include(CPack) include(CPack)

View file

@ -478,7 +478,7 @@ void LogsDialog::updateCursorsLabel()
QString LogsDialog::formatTimeDelta(double timeDelta) QString LogsDialog::formatTimeDelta(double timeDelta)
{ {
if (abs(timeDelta) < 10) { if (abs(int(timeDelta)) < 10) {
return QString("%1 s").arg(timeDelta, 1, 'f', 1); return QString("%1 s").arg(timeDelta, 1, 'f', 1);
} }

View file

@ -134,7 +134,7 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
if (i<limit) { if (i<limit) {
ui->curvesLayout->addWidget(edit, i, 1, 1, 1); ui->curvesLayout->addWidget(edit, i, 1, 1, 1);
} else { } else {
ui->curvesLayout2->addWidget(edit, i-limit, 1, 1, 1); ui->curvesLayout2->addWidget(edit, i-limit, 2, 1, 1);
} }
// The curve plot checkbox // The curve plot checkbox
@ -145,7 +145,7 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
if (i<limit) { if (i<limit) {
ui->curvesLayout->addWidget(plot, i, 2, 1, 1); ui->curvesLayout->addWidget(plot, i, 2, 1, 1);
} else { } else {
ui->curvesLayout2->addWidget(plot, i-limit, 2, 1, 1); ui->curvesLayout2->addWidget(plot, i-limit, 1, 1, 1);
} }
} }
QSpacerItem * item = new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding); QSpacerItem * item = new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding);
@ -570,13 +570,13 @@ void Curves::ShowContextMenu(const QPoint& pos) // this is a slot
QAction *action; QAction *action;
action = myMenu.addAction(CompanionIcon("copy.png"),tr("Copy")); action = myMenu.addAction(CompanionIcon("copy.png"),tr("Copy"));
action->setProperty("index", CURVE_COPY); action->setProperty("index", CURVE_COPY);
action = myMenu.addAction(CompanionIcon("paste.png"),tr("Paste")); action = myMenu.addAction(CompanionIcon("paste.png"),tr("Paste"));
if (!mimeData->hasFormat("application/x-companion-curve-item")) { if (!mimeData->hasFormat("application/x-companion-curve-item")) {
action->setEnabled(false); action->setEnabled(false);
} }
action->setProperty("index", CURVE_PASTE); action->setProperty("index", CURVE_PASTE);
action = myMenu.addAction(CompanionIcon("clear.png"),tr("Clear")); action = myMenu.addAction(CompanionIcon("clear.png"),tr("Clear"));
action->setProperty("index", CURVE_RESET); action->setProperty("index", CURVE_RESET);
action = myMenu.addAction(CompanionIcon("clear.png"),tr("Clear all curves")); action = myMenu.addAction(CompanionIcon("clear.png"),tr("Clear all curves"));
@ -591,14 +591,14 @@ void Curves::ShowContextMenu(const QPoint& pos) // this is a slot
curveData.append((char*)&model->curves[index], sizeof(CurveData)); curveData.append((char*)&model->curves[index], sizeof(CurveData));
mimeData2->setData("application/x-companion-curve-item", curveData); mimeData2->setData("application/x-companion-curve-item", curveData);
QApplication::clipboard()->setMimeData(mimeData2, QClipboard::Clipboard); QApplication::clipboard()->setMimeData(mimeData2, QClipboard::Clipboard);
} }
else if (action==CURVE_PASTE) { else if (action==CURVE_PASTE) {
QByteArray curveData = mimeData->data("application/x-companion-curve-item"); QByteArray curveData = mimeData->data("application/x-companion-curve-item");
CurveData *curve = &model->curves[index]; CurveData *curve = &model->curves[index];
memcpy(curve, curveData.constData(), sizeof(CurveData)); memcpy(curve, curveData.constData(), sizeof(CurveData));
update(); update();
emit modified(); emit modified();
} }
else if (action==CURVE_RESET) { else if (action==CURVE_RESET) {
int res = QMessageBox::question(this, "companion", tr("Are you sure you want to reset curve %1?").arg(index+1), QMessageBox::Yes | QMessageBox::No); int res = QMessageBox::question(this, "companion", tr("Are you sure you want to reset curve %1?").arg(index+1), QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::Yes) { if (res == QMessageBox::Yes) {
@ -606,7 +606,7 @@ void Curves::ShowContextMenu(const QPoint& pos) // this is a slot
update(); update();
emit modified(); emit modified();
} }
} }
else if (action==CURVE_RESETALL) { else if (action==CURVE_RESETALL) {
int res = QMessageBox::question(this, "companion", tr("Are you sure you want to reset all curves?"), QMessageBox::Yes | QMessageBox::No); int res = QMessageBox::question(this, "companion", tr("Are you sure you want to reset all curves?"), QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::Yes) { if (res == QMessageBox::Yes) {

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>624</width> <width>672</width>
<height>539</height> <height>539</height>
</rect> </rect>
</property> </property>
@ -20,7 +20,7 @@
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_1"> <layout class="QVBoxLayout" name="verticalLayout_1">
<property name="rightMargin"> <property name="rightMargin">
<number>10</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QGraphicsView" name="curvePreview"> <widget class="QGraphicsView" name="curvePreview">

View file

@ -46,8 +46,6 @@
#include <math.h> #include <math.h>
static const double Pi = 3.14159265358979323846264338327950288419717;
Edge::Edge(Node *sourceNode, Node *destNode) Edge::Edge(Node *sourceNode, Node *destNode)
: arrowSize(10) : arrowSize(10)
{ {

View file

@ -5,8 +5,7 @@
VerticalScrollArea::VerticalScrollArea(QWidget * parent, GenericPanel * panel): VerticalScrollArea::VerticalScrollArea(QWidget * parent, GenericPanel * panel):
QScrollArea(parent), QScrollArea(parent),
panel(panel), panel(panel)
parent(parent)
{ {
setWidgetResizable(true); setWidgetResizable(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@ -14,7 +13,7 @@ VerticalScrollArea::VerticalScrollArea(QWidget * parent, GenericPanel * panel):
panel->installEventFilter(this); panel->installEventFilter(this);
} }
bool VerticalScrollArea::eventFilter(QObject *o, QEvent *e) bool VerticalScrollArea::eventFilter(QObject * o, QEvent * e)
{ {
if (o == panel && e->type() == QEvent::Resize) { if (o == panel && e->type() == QEvent::Resize) {
setMinimumWidth(panel->minimumSizeHint().width() + verticalScrollBar()->width()); setMinimumWidth(panel->minimumSizeHint().width() + verticalScrollBar()->width());

View file

@ -11,11 +11,10 @@ class VerticalScrollArea : public QScrollArea
VerticalScrollArea(QWidget * parent, GenericPanel * panel); VerticalScrollArea(QWidget * parent, GenericPanel * panel);
protected: protected:
virtual bool eventFilter(QObject *o, QEvent *e); virtual bool eventFilter(QObject * o, QEvent * e);
private: private:
GenericPanel * panel; GenericPanel * panel;
QWidget * parent;
}; };
#endif #endif

Binary file not shown.

View file

@ -35,7 +35,7 @@ set(FATFS_DIR ${THIRDPARTY_DIR}/FatFs)
set(RADIO_BIN_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(RADIO_BIN_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set(GUI_LANGUAGES cz de en es fr it pt sk se pl hu nl) set(GUI_LANGUAGES cz de en es fr it pt sk se pl hu nl)
set(TTS_LANGUAGES cz de en es fr it pt sk se pl hu nl) set(TTS_LANGUAGES cz de en es fr it pt sk se pl hu)
configure_file(stamp.h.in stamp.h @ONLY) configure_file(stamp.h.in stamp.h @ONLY)
@ -337,14 +337,17 @@ set(CMAKE_EXECUTABLE_SUFFIX ".elf")
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
set(CMAKE_COMMON_FLAGS "") set(CMAKE_COMMON_FLAGS "")
# similar for -mmacosx-version-min="
set(CMAKE_C_OSX_DEPLOYMENT_TARGET_FLAG "")
set(CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG "")
set(CMAKE_EXE_LINKER_FLAGS "") set(CMAKE_EXE_LINKER_FLAGS "")
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET>") set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET>")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET>") set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET>")
if(NOT MSVC) if(NOT MSVC)
if(ARCH STREQUAL ARM) if(ARCH STREQUAL ARM)
cmake_force_c_compiler(arm-none-eabi-gcc GNU) set(CMAKE_C_COMPILER arm-none-eabi-gcc)
cmake_force_cxx_compiler(arm-none-eabi-g++ GNU) set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-as) set(CMAKE_ASM_COMPILER arm-none-eabi-as)
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_NAME Generic)
@ -387,10 +390,10 @@ if(NOT MSVC)
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
) )
else() else()
cmake_force_c_compiler(avr-gcc GNU) set(CMAKE_C_COMPILER avr-gcc)
cmake_force_cxx_compiler(avr-gcc GNU) set(CMAKE_CXX_COMPILER avr-gcc)
set(CMAKE_CXX_FLAGS "-mmcu=${MCU} -DF_CPU=16000000UL -O${OPT} -gdwarf-2 -fno-exceptions -flto -fwhole-program -fno-inline-small-functions -mstrict-X ${WARNING_FLAGS}") set(CMAKE_CXX_FLAGS "-mmcu=${MCU} -DF_CPU=16000000UL -O${OPT} -gdwarf-2 -fno-exceptions -flto -fwhole-program -fno-inline-small-functions -mstrict-X ${WARNING_FLAGS}")
# Remove once the minimum cmake version is set to 3.1 in the main CmakeLists.tx # Remove once the minimum cmake version is set to 3.1 in the main CmakeLists.tx
if (${CMAKE_VERSION} VERSION_LESS 3.1.0}) if (${CMAKE_VERSION} VERSION_LESS 3.1.0})
set(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}")

View file

@ -23,10 +23,6 @@
extern OS_MutexID audioMutex; extern OS_MutexID audioMutex;
#if defined(SOFTWARE_VOLUME)
extern uint8_t currentSpeakerVolume;
#endif
const int16_t sineValues[] = const int16_t sineValues[] =
{ {
0, 196, 392, 588, 784, 980, 1175, 1370, 1564, 1758, 0, 196, 392, 588, 784, 980, 1175, 1370, 1564, 1758,
@ -245,18 +241,13 @@ void getSystemAudioFile(char * filename, int index)
void referenceSystemAudioFiles() void referenceSystemAudioFiles()
{ {
static_assert(sizeof(audioFilenames)==AU_SPECIAL_SOUND_FIRST*sizeof(char *), "Invalid audioFilenames size");
char path[AUDIO_FILENAME_MAXLEN+1]; char path[AUDIO_FILENAME_MAXLEN+1];
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
sdAvailableSystemAudioFiles.reset(); sdAvailableSystemAudioFiles.reset();
assert(sizeof(audioFilenames)==AU_SPECIAL_SOUND_FIRST*sizeof(char *));
char * filename = strAppendSystemAudioPath(path); char * filename = strAppendSystemAudioPath(path);
*(filename-1) = '\0'; *(filename-1) = '\0';
@ -265,15 +256,14 @@ void referenceSystemAudioFiles()
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
fn = *fno.lfname ? fno.lfname : fno.fname; uint8_t len = strlen(fno.fname);
uint8_t len = strlen(fn);
// Eliminates directories / non wav files // Eliminates directories / non wav files
if (len < 5 || strcasecmp(fn+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue; if (len < 5 || strcasecmp(fno.fname+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue;
for (int i=0; i<AU_SPECIAL_SOUND_FIRST; i++) { for (int i=0; i<AU_SPECIAL_SOUND_FIRST; i++) {
getSystemAudioFile(path, i); getSystemAudioFile(path, i);
if (!strcasecmp(filename, fn)) { if (!strcasecmp(filename, fno.fname)) {
sdAvailableSystemAudioFiles.setBit(i); sdAvailableSystemAudioFiles.setBit(i);
break; break;
} }
@ -360,10 +350,6 @@ void referenceModelAudioFiles()
char path[AUDIO_FILENAME_MAXLEN+1]; char path[AUDIO_FILENAME_MAXLEN+1];
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
sdAvailablePhaseAudioFiles.reset(); sdAvailablePhaseAudioFiles.reset();
sdAvailableSwitchAudioFiles.reset(); sdAvailableSwitchAudioFiles.reset();
@ -377,20 +363,19 @@ void referenceModelAudioFiles()
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
fn = *fno.lfname ? fno.lfname : fno.fname; uint8_t len = strlen(fno.fname);
uint8_t len = strlen(fn);
bool found = false; bool found = false;
// Eliminates directories / non wav files // Eliminates directories / non wav files
if (len < 5 || strcasecmp(fn+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue; if (len < 5 || strcasecmp(fno.fname+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue;
TRACE("referenceModelAudioFiles(): using file: %s", fn); TRACE("referenceModelAudioFiles(): using file: %s", fno.fname);
// Phases Audio Files <phasename>-[on|off].wav // Phases Audio Files <phasename>-[on|off].wav
for (int i=0; i<MAX_FLIGHT_MODES && !found; i++) { for (int i=0; i<MAX_FLIGHT_MODES && !found; i++) {
for (int event=0; event<2; event++) { for (int event=0; event<2; event++) {
getPhaseAudioFile(path, i, event); getPhaseAudioFile(path, i, event);
// TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn); // TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fno.fname);
if (!strcasecmp(filename, fn)) { if (!strcasecmp(filename, fno.fname)) {
sdAvailablePhaseAudioFiles.setBit(INDEX_PHASE_AUDIO_FILE(i, event)); sdAvailablePhaseAudioFiles.setBit(INDEX_PHASE_AUDIO_FILE(i, event));
found = true; found = true;
TRACE("\tfound: %s", filename); TRACE("\tfound: %s", filename);
@ -402,8 +387,8 @@ void referenceModelAudioFiles()
// Switches Audio Files <switchname>-[up|mid|down].wav // Switches Audio Files <switchname>-[up|mid|down].wav
for (int i=SWSRC_FIRST_SWITCH; i<=SWSRC_LAST_SWITCH+NUM_XPOTS*XPOTS_MULTIPOS_COUNT && !found; i++) { for (int i=SWSRC_FIRST_SWITCH; i<=SWSRC_LAST_SWITCH+NUM_XPOTS*XPOTS_MULTIPOS_COUNT && !found; i++) {
getSwitchAudioFile(path, i); getSwitchAudioFile(path, i);
// TRACE("referenceModelAudioFiles(): searching for %s in %s (%d)", path, fn, i); // TRACE("referenceModelAudioFiles(): searching for %s in %s (%d)", path, fno.fname, i);
if (!strcasecmp(filename, fn)) { if (!strcasecmp(filename, fno.fname)) {
sdAvailableSwitchAudioFiles.setBit(i-SWSRC_FIRST_SWITCH); sdAvailableSwitchAudioFiles.setBit(i-SWSRC_FIRST_SWITCH);
found = true; found = true;
TRACE("\tfound: %s", filename); TRACE("\tfound: %s", filename);
@ -414,8 +399,8 @@ void referenceModelAudioFiles()
for (int i=0; i<MAX_LOGICAL_SWITCHES && !found; i++) { for (int i=0; i<MAX_LOGICAL_SWITCHES && !found; i++) {
for (int event=0; event<2; event++) { for (int event=0; event<2; event++) {
getLogicalSwitchAudioFile(path, i, event); getLogicalSwitchAudioFile(path, i, event);
// TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn); // TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fno.fname);
if (!strcasecmp(filename, fn)) { if (!strcasecmp(filename, fno.fname)) {
sdAvailableLogicalSwitchAudioFiles.setBit(INDEX_LOGICAL_SWITCH_AUDIO_FILE(i, event)); sdAvailableLogicalSwitchAudioFiles.setBit(INDEX_LOGICAL_SWITCH_AUDIO_FILE(i, event));
found = true; found = true;
TRACE("\tfound: %s", filename); TRACE("\tfound: %s", filename);
@ -475,7 +460,6 @@ void playModelEvent(uint8_t category, uint8_t index, event_t event)
} }
} }
void playModelName() void playModelName()
{ {
char filename[AUDIO_FILENAME_MAXLEN+1]; char filename[AUDIO_FILENAME_MAXLEN+1];
@ -493,18 +477,18 @@ void playModelName()
const int16_t alawTable[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 }; const int16_t alawTable[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 };
const int16_t ulawTable[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; const int16_t ulawTable[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 };
AudioQueue audioQueue __DMA; AudioQueue audioQueue __DMA; // to place it in the RAM section on Horus, to have file buffers in RAM for DMA access
AudioBuffer audioBuffers[AUDIO_BUFFER_COUNT] __DMA; AudioBuffer audioBuffers[AUDIO_BUFFER_COUNT] __DMA;
AudioQueue::AudioQueue() AudioQueue::AudioQueue()
: buffersFifo(),
_started(false),
normalContext(),
backgroundContext(),
priorityContext(),
varioContext(),
fragmentsFifo()
{ {
memset(this, 0, sizeof(AudioQueue));
memset(audioBuffers, 0, sizeof(audioBuffers));
}
void AudioQueue::start()
{
state = 1;
} }
#define CODEC_ID_PCM_S16LE 1 #define CODEC_ID_PCM_S16LE 1
@ -534,7 +518,7 @@ void audioTask(void * pdata)
} }
#endif #endif
void mixSample(audio_data_t * result, int sample, unsigned int fade) inline void mixSample(audio_data_t * result, int sample, unsigned int fade)
{ {
*result = limit(AUDIO_DATA_MIN, *result + ((sample >> fade) >> (16-AUDIO_BITS_PER_SAMPLE)), AUDIO_DATA_MAX); *result = limit(AUDIO_DATA_MIN, *result + ((sample >> fade) >> (16-AUDIO_BITS_PER_SAMPLE)), AUDIO_DATA_MAX);
} }
@ -590,8 +574,8 @@ int WavContext::mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade)
} }
} }
read = 0;
if (result == FR_OK) { if (result == FR_OK) {
read = 0;
result = f_read(&state.file, wavBuffer, state.readSize, &read); result = f_read(&state.file, wavBuffer, state.readSize, &read);
if (result == FR_OK) { if (result == FR_OK) {
if (read > state.size) { if (read > state.size) {
@ -632,7 +616,10 @@ int WavContext::mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade)
} }
} }
return -result; if (result != FR_OK) {
clear();
}
return 0;
} }
#else #else
int WavContext::mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade) int WavContext::mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade)
@ -742,8 +729,8 @@ void AudioQueue::wakeup()
audioConsumeCurrentBuffer(); audioConsumeCurrentBuffer();
DEBUG_TIMER_STOP(debugTimerAudioConsume); DEBUG_TIMER_STOP(debugTimerAudioConsume);
AudioBuffer * buffer = getEmptyBuffer(); AudioBuffer * buffer;
if (buffer) { while ((buffer = buffersFifo.getEmptyBuffer()) != 0) {
int result; int result;
unsigned int fade = 0; unsigned int fade = 0;
int size = 0; int size = 0;
@ -761,32 +748,16 @@ void AudioQueue::wakeup()
} }
// mix the normal context (tones and wavs) // mix the normal context (tones and wavs)
if (normalContext.fragment.type == FRAGMENT_TONE) { if (normalContext.isEmpty() && !fragmentsFifo.empty()) {
result = normalContext.tone.mixBuffer(buffer, g_eeGeneral.beepVolume, fade); CoEnterMutexSection(audioMutex);
} normalContext.setFragment(fragmentsFifo.get());
else if (normalContext.fragment.type == FRAGMENT_FILE) { CoLeaveMutexSection(audioMutex);
result = normalContext.wav.mixBuffer(buffer, g_eeGeneral.wavVolume, fade);
if (result < 0) {
normalContext.wav.clear();
}
}
else {
result = 0;
} }
result = normalContext.mixBuffer(buffer, g_eeGeneral.beepVolume, g_eeGeneral.wavVolume, fade);
if (result > 0) { if (result > 0) {
size = max(size, result); size = max(size, result);
fade += 1; fade += 1;
} }
else {
CoEnterMutexSection(audioMutex);
if (ridx != widx) {
normalContext.tone.setFragment(fragments[ridx]);
if (!fragments[ridx].repeat--) {
ridx = (ridx + 1) % AUDIO_QUEUE_LENGTH;
}
}
CoLeaveMutexSection(audioMutex);
}
// mix the vario context // mix the vario context
result = varioContext.mixBuffer(buffer, g_eeGeneral.varioVolume, fade); result = varioContext.mixBuffer(buffer, g_eeGeneral.varioVolume, fade);
@ -805,9 +776,7 @@ void AudioQueue::wakeup()
// push the buffer if needed // push the buffer if needed
if (size > 0) { if (size > 0) {
audioDisableIrq(); // TRACE("pushing buffer %p", buffer);
// TRACE("pushing buffer %d\n", bufferWIdx);
bufferWIdx = nextBufferIdx(bufferWIdx);
buffer->size = size; buffer->size = size;
#if defined(SOFTWARE_VOLUME) #if defined(SOFTWARE_VOLUME)
for(uint32_t i=0; i<buffer->size; ++i) { for(uint32_t i=0; i<buffer->size; ++i) {
@ -815,11 +784,15 @@ void AudioQueue::wakeup()
buffer->data[i] = (int16_t) (((tmpSample * currentSpeakerVolume) / VOLUME_LEVEL_MAX) + AUDIO_DATA_SILENCE); buffer->data[i] = (int16_t) (((tmpSample * currentSpeakerVolume) / VOLUME_LEVEL_MAX) + AUDIO_DATA_SILENCE);
} }
#endif #endif
DEBUG_TIMER_START(debugTimerAudioPush); buffersFifo.audioPushBuffer();
audioPushBuffer(buffer);
DEBUG_TIMER_STOP(debugTimerAudioPush);
audioEnableIrq();
} }
else {
// break the endless loop
break;
}
DEBUG_TIMER_START(debugTimerAudioConsume);
audioConsumeCurrentBuffer();
DEBUG_TIMER_STOP(debugTimerAudioConsume);
} }
} }
@ -842,17 +815,9 @@ void AudioQueue::pause(uint16_t len)
bool AudioQueue::isPlaying(uint8_t id) bool AudioQueue::isPlaying(uint8_t id)
{ {
if (normalContext.fragment.id == id || (isFunctionActive(FUNCTION_BACKGND_MUSIC) && backgroundContext.fragment.id == id)) return normalContext.hasId(id) ||
return true; (isFunctionActive(FUNCTION_BACKGND_MUSIC) && backgroundContext.hasId(id)) ||
fragmentsFifo.hasId(id);
uint8_t i = ridx;
while (i != widx) {
AudioFragment & fragment = fragments[i];
if (fragment.id == id)
return true;
i = (i + 1) % AUDIO_QUEUE_LENGTH;
}
return false;
} }
void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t flags, int8_t freqIncr) void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t flags, int8_t freqIncr)
@ -868,42 +833,21 @@ void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t f
} }
if (flags & PLAY_BACKGROUND) { if (flags & PLAY_BACKGROUND) {
AudioFragment & fragment = varioContext.fragment; varioContext.setFragment(freq, len, pause, 0, 0, (flags & PLAY_NOW));
fragment.type = FRAGMENT_TONE;
fragment.tone.freq = freq;
fragment.tone.duration = len;
fragment.tone.pause = pause;
fragment.tone.reset = (flags & PLAY_NOW);
} }
else { else {
// adjust frequency and length according to the user preferences
freq += g_eeGeneral.speakerPitch * 15; freq += g_eeGeneral.speakerPitch * 15;
len = getToneLength(len); len = getToneLength(len);
if (flags & PLAY_NOW) { if (flags & PLAY_NOW) {
AudioFragment & fragment = priorityContext.fragment; if (priorityContext.isFree()) {
if (fragment.type == FRAGMENT_EMPTY) {
priorityContext.clear(); priorityContext.clear();
fragment.type = FRAGMENT_TONE; priorityContext.setFragment(freq, len, pause, flags & 0x0f, freqIncr, false);
fragment.repeat = flags & 0x0f;
fragment.tone.freq = freq;
fragment.tone.duration = len;
fragment.tone.pause = pause;
fragment.tone.freqIncr = freqIncr;
} }
} }
else { else {
uint8_t next_widx = (widx + 1) % AUDIO_QUEUE_LENGTH; fragmentsFifo.push(AudioFragment(freq, len, pause, flags & 0x0f, freqIncr, false));
if (next_widx != ridx) {
AudioFragment & fragment = fragments[widx];
fragment.clear();
fragment.type = FRAGMENT_TONE;
fragment.repeat = flags & 0x0f;
fragment.tone.freq = freq;
fragment.tone.duration = len;
fragment.tone.pause = pause;
fragment.tone.freqIncr = freqIncr;
widx = next_widx;
}
} }
} }
@ -940,22 +884,10 @@ void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id)
if (flags & PLAY_BACKGROUND) { if (flags & PLAY_BACKGROUND) {
backgroundContext.clear(); backgroundContext.clear();
AudioFragment & fragment = backgroundContext.fragment; backgroundContext.setFragment(filename, 0, id);
fragment.type = FRAGMENT_FILE;
strcpy(fragment.file, filename);
fragment.id = id;
} }
else { else {
uint8_t next_widx = (widx + 1) % AUDIO_QUEUE_LENGTH; fragmentsFifo.push(AudioFragment(filename, flags & 0x0f, id));
if (next_widx != ridx) {
AudioFragment & fragment = fragments[widx];
fragment.clear();
fragment.type = FRAGMENT_FILE;
strcpy(fragment.file, filename);
fragment.repeat = flags & 0x0f;
fragment.id = id;
widx = next_widx;
}
} }
CoLeaveMutexSection(audioMutex); CoLeaveMutexSection(audioMutex);
@ -972,10 +904,7 @@ void AudioQueue::stopPlay(uint8_t id)
#endif #endif
// For the moment it's only needed to stop the background music // For the moment it's only needed to stop the background music
if (backgroundContext.fragment.id == id) { backgroundContext.stop(id);
backgroundContext.fragment.type = FRAGMENT_EMPTY;
backgroundContext.fragment.id = 0;
}
} }
void AudioQueue::stopSD() void AudioQueue::stopSD()
@ -989,19 +918,17 @@ void AudioQueue::stopSD()
void AudioQueue::stopAll() void AudioQueue::stopAll()
{ {
flush();
CoEnterMutexSection(audioMutex); CoEnterMutexSection(audioMutex);
widx = ridx; // clean the queue
priorityContext.clear(); priorityContext.clear();
normalContext.fragment.clear(); normalContext.clear();
varioContext.clear();
backgroundContext.clear();
CoLeaveMutexSection(audioMutex); CoLeaveMutexSection(audioMutex);
} }
void AudioQueue::flush() void AudioQueue::flush()
{ {
CoEnterMutexSection(audioMutex); CoEnterMutexSection(audioMutex);
widx = ridx; // clean the queue fragmentsFifo.clear();
varioContext.clear(); varioContext.clear();
backgroundContext.clear(); backgroundContext.clear();
CoLeaveMutexSection(audioMutex); CoLeaveMutexSection(audioMutex);
@ -1022,7 +949,6 @@ void audioKeyPress()
if (g_eeGeneral.beepMode == e_mode_all) { if (g_eeGeneral.beepMode == e_mode_all) {
audioQueue.playTone(BEEP_DEFAULT_FREQ, 40, 20, PLAY_NOW); audioQueue.playTone(BEEP_DEFAULT_FREQ, 40, 20, PLAY_NOW);
} }
#if defined(HAPTIC) #if defined(HAPTIC)
if (g_eeGeneral.hapticMode == e_mode_all) { if (g_eeGeneral.hapticMode == e_mode_all) {
haptic.play(5, 0, PLAY_NOW); haptic.play(5, 0, PLAY_NOW);
@ -1045,10 +971,8 @@ void audioKeyError()
void audioTrimPress(int value) void audioTrimPress(int value)
{ {
value = limit(TRIM_MIN, value, TRIM_MAX);
value <<= 3;
value += 120*16;
if (g_eeGeneral.beepMode >= e_mode_nokeys) { if (g_eeGeneral.beepMode >= e_mode_nokeys) {
value = limit(TRIM_MIN, value, TRIM_MAX) * 8 + 120*16;
audioQueue.playTone(value, 40, 20, PLAY_NOW); audioQueue.playTone(value, 40, 20, PLAY_NOW);
} }
} }

View file

@ -66,16 +66,16 @@ template <unsigned int NUM_BITS> class BitField {
#define AUDIO_FILENAME_MAXLEN (42) // max length (example: /SOUNDS/fr/123456789012/1234567890-off.wav) #define AUDIO_FILENAME_MAXLEN (42) // max length (example: /SOUNDS/fr/123456789012/1234567890-off.wav)
#define AUDIO_QUEUE_LENGTH (20) #define AUDIO_QUEUE_LENGTH (16) // must be a power of 2!
#define AUDIO_SAMPLE_RATE (32000) #define AUDIO_SAMPLE_RATE (32000)
#define AUDIO_BUFFER_DURATION (10) #define AUDIO_BUFFER_DURATION (10)
#define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_RATE*AUDIO_BUFFER_DURATION/1000) #define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_RATE*AUDIO_BUFFER_DURATION/1000)
#if defined(SIMU_AUDIO) #if defined(SIMU) && defined(SIMU_AUDIO)
#define AUDIO_BUFFER_COUNT (10) // simulator needs more buffers for smooth audio #define AUDIO_BUFFER_COUNT (10) // simulator needs more buffers for smooth audio
#elif defined(PCBHORUS) #elif defined(PCBHORUS)
#define AUDIO_BUFFER_COUNT (2) #define AUDIO_BUFFER_COUNT (2) // smaller than Taranis since there is also a buffer on the ADC chip
#else #else
#define AUDIO_BUFFER_COUNT (3) #define AUDIO_BUFFER_COUNT (3)
#endif #endif
@ -116,7 +116,6 @@ enum AudioBufferState
struct AudioBuffer { struct AudioBuffer {
audio_data_t data[AUDIO_BUFFER_SIZE]; audio_data_t data[AUDIO_BUFFER_SIZE];
uint16_t size; uint16_t size;
uint8_t state;
}; };
extern AudioBuffer audioBuffers[AUDIO_BUFFER_COUNT]; extern AudioBuffer audioBuffers[AUDIO_BUFFER_COUNT];
@ -127,30 +126,65 @@ enum FragmentTypes {
FRAGMENT_FILE, FRAGMENT_FILE,
}; };
struct Tone {
uint16_t freq;
uint16_t duration;
uint16_t pause;
int8_t freqIncr;
uint8_t reset;
Tone() {};
Tone(uint16_t freq, uint16_t duration, uint16_t pause, int8_t freqIncr, bool reset):
freq(freq),
duration(duration),
pause(pause),
freqIncr(freqIncr),
reset(reset)
{};
};
struct AudioFragment { struct AudioFragment {
uint8_t type; uint8_t type;
uint8_t id; uint8_t id;
uint8_t repeat; uint8_t repeat;
union { union {
struct { Tone tone;
uint16_t freq;
uint16_t duration;
uint16_t pause;
int8_t freqIncr;
uint8_t reset;
} tone;
char file[AUDIO_FILENAME_MAXLEN+1]; char file[AUDIO_FILENAME_MAXLEN+1];
}; };
void clear() AudioFragment() { clear(); };
AudioFragment(uint16_t freq, uint16_t duration, uint16_t pause, uint8_t repeat, int8_t freqIncr, bool reset, uint8_t id=0):
type(FRAGMENT_TONE),
id(id),
repeat(repeat),
tone(freq, duration, pause, freqIncr, reset)
{};
AudioFragment(const char * filename, uint8_t repeat, uint8_t id=0):
type(FRAGMENT_FILE),
id(id),
repeat(repeat)
{ {
memset(this, 0, sizeof(AudioFragment)); strcpy(file, filename);
} }
void clear() { memset(this, 0, sizeof(AudioFragment)); };
}; };
class ToneContext { class ToneContext {
public: public:
inline void clear() { memset(this, 0, sizeof(ToneContext)); };
bool isFree() const { return fragment.type == FRAGMENT_EMPTY; };
int mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade);
void setFragment(uint16_t freq, uint16_t duration, uint16_t pause, uint8_t repeat, int8_t freqIncr, bool reset, uint8_t id=0)
{
fragment = AudioFragment(freq, duration, pause, repeat, freqIncr, reset, id);
}
private:
AudioFragment fragment; AudioFragment fragment;
struct { struct {
@ -162,22 +196,29 @@ class ToneContext {
uint16_t pause; uint16_t pause;
} state; } state;
inline void setFragment(AudioFragment & fragment)
{
this->fragment = fragment;
memset(&state, 0, sizeof(state));
}
inline void clear()
{
memset(this, 0, sizeof(ToneContext));
}
int mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade);
}; };
class WavContext { class WavContext {
public: public:
inline void clear() { fragment.clear(); };
int mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade);
bool hasId(uint8_t id) const { return fragment.id == id; };
void setFragment(const char * filename, uint8_t repeat, uint8_t id)
{
fragment = AudioFragment(filename, repeat, id);
}
void stop(uint8_t id)
{
if (fragment.id == id) {
fragment.clear();
}
}
private:
AudioFragment fragment; AudioFragment fragment;
struct { struct {
@ -188,136 +229,230 @@ class WavContext {
uint8_t resampleRatio; uint8_t resampleRatio;
uint16_t readSize; uint16_t readSize;
} state; } state;
inline void clear()
{
fragment.clear();
}
int mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade);
}; };
class MixedContext { class MixedContext {
public:
union {
AudioFragment fragment;
ToneContext tone;
WavContext wav;
};
int mixBuffer(AudioBuffer *buffer, int volume, unsigned int fade);
};
void audioPushBuffer(AudioBuffer * buffer);
class AudioQueue {
friend void audioTask(void* pdata);
#if defined(SIMU_AUDIO)
friend void * audioThread(void *);
#endif
#if defined(CLI) #if defined(CLI)
friend void printAudioVars(); friend void printAudioVars();
#endif #endif
public: public:
AudioQueue(); MixedContext()
void start();
void playTone(uint16_t freq, uint16_t len, uint16_t pause=0, uint8_t flags=0, int8_t freqIncr=0);
void playFile(const char *filename, uint8_t flags=0, uint8_t id=0);
void stopPlay(uint8_t id);
void stopAll();
void flush();
void pause(uint16_t tLen);
void stopSD();
bool isPlaying(uint8_t id);
bool started()
{ {
return state; clear();
} }
bool empty() void setFragment(const AudioFragment * frag)
{ {
return ridx == widx; if (frag) {
} fragment = *frag;
inline AudioBuffer * getNextFilledBuffer()
{
if (audioBuffers[bufferRIdx].state == AUDIO_BUFFER_PLAYING) {
audioBuffers[bufferRIdx].state = AUDIO_BUFFER_FREE;
bufferRIdx = nextBufferIdx(bufferRIdx);
} }
uint8_t idx = bufferRIdx;
do {
AudioBuffer * buffer = &audioBuffers[idx];
if (buffer->state == AUDIO_BUFFER_FILLED) {
buffer->state = AUDIO_BUFFER_PLAYING;
bufferRIdx = idx;
return buffer;
}
idx = nextBufferIdx(idx);
} while (idx != bufferWIdx); //this fixes a bug if all buffers are filled
return NULL;
} }
bool filledAtleast(int noBuffers) inline void clear()
{ {
int count = 0; tone.clear(); // the biggest member of the uninon
for(int n= 0; n<AUDIO_BUFFER_COUNT; ++n) { }
if (audioBuffers[n].state == AUDIO_BUFFER_FILLED) {
if (++count >= noBuffers) { bool isEmpty() const { return fragment.type == FRAGMENT_EMPTY; };
return true; bool isTone() const { return fragment.type == FRAGMENT_TONE; };
} bool isFile() const { return fragment.type == FRAGMENT_FILE; };
} bool hasId(uint8_t id) const { return fragment.id == id; };
int mixBuffer(AudioBuffer *buffer, int toneVolume, int wavVolume, unsigned int fade)
{
if (isTone()) return tone.mixBuffer(buffer, toneVolume, fade);
else if (isFile()) return wav.mixBuffer(buffer, wavVolume, fade);
return 0;
}
private:
union {
AudioFragment fragment; // a hack: fragment is used to access the fragment members of tone and wav
ToneContext tone;
WavContext wav;
};
};
class AudioBufferFifo {
#if defined(CLI)
friend void printAudioVars();
#endif
private:
volatile uint8_t readIdx;
volatile uint8_t writeIdx;
volatile bool bufferFull;
// readIdx == writeIdx -> buffer empty
// readIdx == writeIdx + 1 -> buffer full
inline uint8_t nextBufferIdx(uint8_t idx) const
{
return (idx >= AUDIO_BUFFER_COUNT-1 ? 0 : idx+1);
}
bool full() const
{
return bufferFull;
}
bool empty() const
{
return (readIdx == writeIdx) && !bufferFull;
}
uint8_t used() const
{
return bufferFull ? AUDIO_BUFFER_COUNT : writeIdx - readIdx;
}
public:
AudioBufferFifo() : readIdx(0), writeIdx(0), bufferFull(false)
{
memset(audioBuffers, 0, sizeof(audioBuffers));
}
// returns an empty buffer to be filled wit data and put back into FIFO with audioPushBuffer()
AudioBuffer * getEmptyBuffer() const
{
return full() ? 0 : &audioBuffers[writeIdx];
}
// puts filled buffer into FIFO
void audioPushBuffer()
{
// AudioBuffer * buffer = &audioBuffers[writeIdx];
audioDisableIrq();
writeIdx = nextBufferIdx(writeIdx);
bufferFull = (writeIdx == readIdx);
audioEnableIrq();
// buffer->state = AUDIO_BUFFER_FILLED;
}
// returns a pointer to the audio buffer to be played
const AudioBuffer * getNextFilledBuffer() const
{
return empty() ? 0 : &audioBuffers[readIdx];
}
// frees the last played buffer
void freeNextFilledBuffer()
{
audioDisableIrq();
readIdx = nextBufferIdx(readIdx);
bufferFull = false;
audioEnableIrq();
}
bool filledAtleast(int noBuffers) const
{
return used() >= noBuffers;
}
};
class AudioFragmentFifo
{
#if defined(CLI)
friend void printAudioVars();
#endif
private:
volatile uint8_t ridx;
volatile uint8_t widx;
AudioFragment fragments[AUDIO_QUEUE_LENGTH];
uint8_t nextIdx(uint8_t idx) const
{
return (idx + 1) & (AUDIO_QUEUE_LENGTH - 1);
}
public:
AudioFragmentFifo() : ridx(0), widx(0), fragments() {};
bool hasId(uint8_t id)
{
uint8_t i = ridx;
while (i != widx) {
AudioFragment & fragment = fragments[i];
if (fragment.id == id) return true;
i = nextIdx(i);
} }
return false; return false;
} }
protected: bool empty() const
{
return ridx == widx;
}
bool full() const
{
return ridx == nextIdx(widx);
}
void clear()
{
widx = ridx; // clean the queue
}
const AudioFragment * get()
{
if (!empty()) {
const AudioFragment * result = &fragments[ridx];
if (!fragments[ridx].repeat--) {
// repeat is done, move to the next fragment
ridx = nextIdx(ridx);
}
return result;
}
return 0;
}
void push(const AudioFragment & fragment)
{
if (!full()) {
TRACE("frament %d at %d", fragment.type, widx);
fragments[widx] = fragment;
widx = nextIdx(widx);
}
}
};
class AudioQueue {
#if defined(SIMU_AUDIO)
friend void fillAudioBuffer(void *, uint8_t *, int);
#endif
#if defined(CLI)
friend void printAudioVars();
#endif
public:
AudioQueue();
void start() { _started = true; };
void playTone(uint16_t freq, uint16_t len, uint16_t pause=0, uint8_t flags=0, int8_t freqIncr=0);
void playFile(const char *filename, uint8_t flags=0, uint8_t id=0);
void stopPlay(uint8_t id);
void stopAll();
void flush();
void pause(uint16_t tLen);
void stopSD();
bool isPlaying(uint8_t id);
bool isEmpty() const { return fragmentsFifo.empty(); };
void wakeup(); void wakeup();
bool started() const { return _started; };
volatile bool state; AudioBufferFifo buffersFifo;
uint8_t ridx;
uint8_t widx;
AudioFragment fragments[AUDIO_QUEUE_LENGTH];
private:
volatile bool _started;
MixedContext normalContext; MixedContext normalContext;
WavContext backgroundContext; WavContext backgroundContext;
ToneContext priorityContext; ToneContext priorityContext;
ToneContext varioContext; ToneContext varioContext;
AudioFragmentFifo fragmentsFifo;
uint8_t bufferRIdx;
uint8_t bufferWIdx;
inline uint8_t nextBufferIdx(uint8_t idx)
{
return (idx == AUDIO_BUFFER_COUNT-1 ? 0 : idx+1);
}
inline AudioBuffer * getEmptyBuffer()
{
AudioBuffer * buffer = &audioBuffers[bufferWIdx];
if (buffer->state == AUDIO_BUFFER_FREE)
return buffer;
else
return NULL;
}
}; };
extern uint8_t currentSpeakerVolume;
extern AudioQueue audioQueue; extern AudioQueue audioQueue;
enum { enum {

View file

@ -107,25 +107,13 @@ int cliLs(const char ** argv)
{ {
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
#if _USE_LFN
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
#endif
FRESULT res = f_opendir(&dir, argv[1]); /* Open the directory */ FRESULT res = f_opendir(&dir, argv[1]); /* Open the directory */
if (res == FR_OK) { if (res == FR_OK) {
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
serialPrint(fno.fname);
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
serialPrint(fn);
} }
} }
else { else {
@ -529,22 +517,21 @@ extern OS_MutexID audioMutex;
void printAudioVars() void printAudioVars()
{ {
for(int n = 0; n < AUDIO_BUFFER_COUNT; n++) { for(int n = 0; n < AUDIO_BUFFER_COUNT; n++) {
serialPrint("Audio Buffer %d: size: %u, state: %u, ", n, (uint32_t)audioBuffers[n].size, (uint32_t)audioBuffers[n].state); serialPrint("Audio Buffer %d: size: %u, ", n, (uint32_t)audioBuffers[n].size);
dump((uint8_t *)audioBuffers[n].data, 32); dump((uint8_t *)audioBuffers[n].data, 32);
} }
serialPrint("fragments:"); serialPrint("fragments:");
for(int n = 0; n < AUDIO_QUEUE_LENGTH; n++) { for(int n = 0; n < AUDIO_QUEUE_LENGTH; n++) {
serialPrint("%d: type %u: id: %u, repeat: %u, ", n, (uint32_t)audioQueue.fragments[n].type, serialPrint("%d: type %u: id: %u, repeat: %u, ", n, (uint32_t)audioQueue.fragmentsFifo.fragments[n].type,
(uint32_t)audioQueue.fragments[n].id, (uint32_t)audioQueue.fragmentsFifo.fragments[n].id,
(uint32_t)audioQueue.fragments[n].repeat); (uint32_t)audioQueue.fragmentsFifo.fragments[n].repeat);
if ( audioQueue.fragments[n].type == FRAGMENT_FILE) { if ( audioQueue.fragmentsFifo.fragments[n].type == FRAGMENT_FILE) {
serialPrint(" file: %s", audioQueue.fragments[n].file); serialPrint(" file: %s", audioQueue.fragmentsFifo.fragments[n].file);
} }
} }
serialPrint("audioQueue:"); serialPrint("FragmentFifo: ridx: %d, widx: %d", audioQueue.fragmentsFifo.ridx, audioQueue.fragmentsFifo.widx);
serialPrint(" ridx: %d, widx: %d", audioQueue.ridx, audioQueue.widx); serialPrint("audioQueue: readIdx: %d, writeIdx: %d, full: %d", audioQueue.buffersFifo.readIdx, audioQueue.buffersFifo.writeIdx, audioQueue.buffersFifo.bufferFull);
serialPrint(" bufferRIdx: %d, bufferWIdx: %d", audioQueue.bufferRIdx, audioQueue.bufferWIdx);
serialPrint("normalContext: %u", (uint32_t)audioQueue.normalContext.fragment.type); serialPrint("normalContext: %u", (uint32_t)audioQueue.normalContext.fragment.type);
@ -711,7 +698,7 @@ int cliDisplay(const char ** argv)
else if (!strcmp(argv[1], "dc")) { else if (!strcmp(argv[1], "dc")) {
DiskCacheStats stats = diskCache.getStats(); DiskCacheStats stats = diskCache.getStats();
uint32_t hitRate = diskCache.getHitRate(); uint32_t hitRate = diskCache.getHitRate();
serialPrint("Disk Cache stats: reads: %u, hits: %u, hit rate: %0.1f%%", (stats.noHits + stats.noMisses), stats.noHits, hitRate/10.0); serialPrint("Disk Cache stats: w:%u r: %u, h: %u(%0.1f%%), m: %u", stats.noWrites, (stats.noHits + stats.noMisses), stats.noHits, hitRate/10.0, stats.noMisses);
} }
#endif #endif
else if (toLongLongInt(argv, 1, &address) > 0) { else if (toLongLongInt(argv, 1, &address) > 0) {

View file

@ -920,7 +920,7 @@ PACK(struct TrainerData {
char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \ char switchNames[NUM_SWITCHES][LEN_SWITCH_NAME]; \
char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME];
#elif defined(PCBTARANIS) #elif defined(PCBTARANIS)
#if defined(PCBX9E) #if defined(PCBX9E) || defined(PCBX7D)
#define BLUETOOTH_FIELDS \ #define BLUETOOTH_FIELDS \
uint8_t bluetoothEnable; \ uint8_t bluetoothEnable; \
char bluetoothName[LEN_BLUETOOTH_NAME]; char bluetoothName[LEN_BLUETOOTH_NAME];

View file

@ -227,7 +227,6 @@ const char * debugTimerNames[DEBUG_TIMERS_COUNT] = {
,"Audio int. " // debugTimerAudioIterval ,"Audio int. " // debugTimerAudioIterval
,"Audio dur. " // debugTimerAudioDuration ,"Audio dur. " // debugTimerAudioDuration
," A. consume" // debugTimerAudioConsume, ," A. consume" // debugTimerAudioConsume,
," A push " // debugTimerAudioPush,
}; };

View file

@ -338,7 +338,6 @@ enum DebugTimers {
debugTimerAudioIterval, debugTimerAudioIterval,
debugTimerAudioDuration, debugTimerAudioDuration,
debugTimerAudioConsume, debugTimerAudioConsume,
debugTimerAudioPush,
DEBUG_TIMERS_COUNT DEBUG_TIMERS_COUNT
}; };

View file

@ -86,6 +86,7 @@ DiskCache::DiskCache():
{ {
stats.noHits = 0; stats.noHits = 0;
stats.noMisses = 0; stats.noMisses = 0;
stats.noWrites = 0;
blocks = new DiskCacheBlock[DISK_CACHE_BLOCKS_NUM]; blocks = new DiskCacheBlock[DISK_CACHE_BLOCKS_NUM];
} }
@ -94,6 +95,7 @@ void DiskCache::clear()
lastBlock = 0; lastBlock = 0;
stats.noHits = 0; stats.noHits = 0;
stats.noMisses = 0; stats.noMisses = 0;
stats.noWrites = 0;
for (int n=0; n<DISK_CACHE_BLOCKS_NUM; ++n) { for (int n=0; n<DISK_CACHE_BLOCKS_NUM; ++n) {
blocks[n].free(); blocks[n].free();
} }
@ -147,6 +149,7 @@ DRESULT DiskCache::read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
DRESULT DiskCache::write(BYTE drv, const BYTE* buff, DWORD sector, UINT count) DRESULT DiskCache::write(BYTE drv, const BYTE* buff, DWORD sector, UINT count)
{ {
++stats.noWrites;
for(int n=0; n < DISK_CACHE_BLOCKS_NUM; ++n) { for(int n=0; n < DISK_CACHE_BLOCKS_NUM; ++n) {
blocks[n].free(sector, count); blocks[n].free(sector, count);
} }

View file

@ -25,7 +25,7 @@
#include "sdio_sd.h" #include "sdio_sd.h"
// tunable parameters // tunable parameters
#define DISK_CACHE_BLOCKS_NUM 8 // no cache blocks #define DISK_CACHE_BLOCKS_NUM 32 // no cache blocks
#define DISK_CACHE_BLOCK_SECTORS 16 // no sectors #define DISK_CACHE_BLOCK_SECTORS 16 // no sectors
#define DISK_CACHE_BLOCK_SIZE (DISK_CACHE_BLOCK_SECTORS * BLOCK_SIZE) #define DISK_CACHE_BLOCK_SIZE (DISK_CACHE_BLOCK_SECTORS * BLOCK_SIZE)
@ -50,6 +50,7 @@ struct DiskCacheStats
{ {
uint32_t noHits; uint32_t noHits;
uint32_t noMisses; uint32_t noMisses;
uint32_t noWrites;
}; };
class DiskCache class DiskCache
@ -61,7 +62,7 @@ class DiskCache
const DiskCacheStats & getStats() const; const DiskCacheStats & getStats() const;
int getHitRate() const; int getHitRate() const;
void clear(); void clear();
private: private:
DiskCacheStats stats; DiskCacheStats stats;
uint32_t lastBlock; uint32_t lastBlock;

View file

@ -330,39 +330,46 @@ void evalFunctions()
break; break;
case FUNC_RESET: case FUNC_RESET:
switch (CFN_PARAM(cfn)) { if (!(functionsContext.activeSwitches & switch_mask)) {
case FUNC_RESET_TIMER1: switch (CFN_PARAM(cfn)) {
case FUNC_RESET_TIMER2: case FUNC_RESET_TIMER1:
case FUNC_RESET_TIMER2:
#if defined(CPUARM) #if defined(CPUARM)
case FUNC_RESET_TIMER3: case FUNC_RESET_TIMER3:
#endif #endif
timerReset(CFN_PARAM(cfn)); timerReset(CFN_PARAM(cfn));
break; break;
case FUNC_RESET_FLIGHT: case FUNC_RESET_FLIGHT:
flightReset(); #if defined(CPUARM)
break; mainRequestFlags |= (1 << REQUEST_FLIGHT_RESET); // on systems with threads flightReset() must not be called from the mixers thread!
#else
flightReset();
#endif // defined(CPUARM)
break;
#if defined(TELEMETRY_FRSKY) #if defined(TELEMETRY_FRSKY)
case FUNC_RESET_TELEMETRY: case FUNC_RESET_TELEMETRY:
telemetryReset(); telemetryReset();
break; break;
#endif #endif
#if ROTARY_ENCODERS > 0 #if ROTARY_ENCODERS > 0
case FUNC_RESET_ROTENC1: case FUNC_RESET_ROTENC1:
#if ROTARY_ENCODERS > 1 #if ROTARY_ENCODERS > 1
case FUNC_RESET_ROTENC2: case FUNC_RESET_ROTENC2:
#endif #endif
rotencValue[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0; rotencValue[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0;
break; break;
#endif #endif
}
#if defined(CPUARM)
if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) {
uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM;
if (item < MAX_TELEMETRY_SENSORS) {
telemetryItems[item].clear();
} }
} #if defined(CPUARM)
if (CFN_PARAM(cfn)>=FUNC_RESET_PARAM_FIRST_TELEM) {
uint8_t item = CFN_PARAM(cfn)-FUNC_RESET_PARAM_FIRST_TELEM;
if (item < MAX_TELEMETRY_SENSORS) {
telemetryItems[item].clear();
}
}
#endif #endif
}
break; break;
#if defined(CPUARM) #if defined(CPUARM)
@ -409,13 +416,13 @@ void evalFunctions()
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_PARAM(cfn))), mixerCurrentFlightMode); SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_PARAM(cfn))), mixerCurrentFlightMode);
} }
else if (CFN_GVAR_MODE(cfn) == FUNC_ADJUST_GVAR_INCDEC) { else if (CFN_GVAR_MODE(cfn) == FUNC_ADJUST_GVAR_INCDEC) {
#if defined(CPUARM)
SET_GVAR(CFN_GVAR_INDEX(cfn), limit<int16_t>(CFN_GVAR_CST_MIN+g_model.gvars[CFN_GVAR_INDEX(cfn)].min, GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + CFN_PARAM(cfn), CFN_GVAR_CST_MAX-g_model.gvars[CFN_GVAR_INDEX(cfn)].max), mixerCurrentFlightMode);
#else
if (!(functionsContext.activeSwitches & switch_mask)) { if (!(functionsContext.activeSwitches & switch_mask)) {
#if defined(CPUARM)
SET_GVAR(CFN_GVAR_INDEX(cfn), limit<int16_t>(CFN_GVAR_CST_MIN+g_model.gvars[CFN_GVAR_INDEX(cfn)].min, GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + CFN_PARAM(cfn), CFN_GVAR_CST_MAX-g_model.gvars[CFN_GVAR_INDEX(cfn)].max), mixerCurrentFlightMode);
#else
SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode); SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightMode(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode);
}
#endif #endif
}
} }
else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) { else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) {
trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn); trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn);
@ -458,7 +465,7 @@ void evalFunctions()
if (isRepeatDelayElapsed(functions, functionsContext, i)) { if (isRepeatDelayElapsed(functions, functionsContext, i)) {
if (!IS_PLAYING(PLAY_INDEX)) { if (!IS_PLAYING(PLAY_INDEX)) {
if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) { if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) {
if (audioQueue.empty()) { if (audioQueue.isEmpty()) {
AUDIO_PLAY(AU_SPECIAL_SOUND_FIRST + CFN_PARAM(cfn)); AUDIO_PLAY(AU_SPECIAL_SOUND_FIRST + CFN_PARAM(cfn));
} }
} }
@ -570,7 +577,7 @@ void evalFunctions()
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
case FUNC_SCREENSHOT: case FUNC_SCREENSHOT:
if (!(functionsContext.activeSwitches & switch_mask)) { if (!(functionsContext.activeSwitches & switch_mask)) {
requestScreenshot = true; mainRequestFlags |= (1 << REQUEST_SCREENSHOT);
} }
break; break;
#endif #endif

View file

@ -108,7 +108,8 @@ void menuRadioSdManager(event_t _event)
#if defined(CPUARM) #if defined(CPUARM)
audioQueue.stopSD(); audioQueue.stopSD();
#endif #endif
if (f_mkfs(0, 1, 0) == FR_OK) { BYTE work[_MAX_SS];
if (f_mkfs(0, FM_FAT32, 0, work, sizeof(work)) == FR_OK) {
f_chdir("/"); f_chdir("/");
reusableBuffer.sdmanager.offset = -1; reusableBuffer.sdmanager.offset = -1;
} }
@ -193,11 +194,7 @@ void menuRadioSdManager(event_t _event)
if (reusableBuffer.sdmanager.offset != menuVerticalOffset) { if (reusableBuffer.sdmanager.offset != menuVerticalOffset) {
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char * fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
reusableBuffer.sdmanager.offset = 0; reusableBuffer.sdmanager.offset = 0;
memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines));
@ -220,16 +217,11 @@ void menuRadioSdManager(event_t _event)
FRESULT res = f_opendir(&dir, "."); // Open the directory FRESULT res = f_opendir(&dir, "."); // Open the directory
if (res == FR_OK) { if (res == FR_OK) {
bool firstTime = true;
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = sdReadDir(&dir, &fno, firstTime);
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fname[0] == '.' && fno.fname[1] == '\0') continue; /* Ignore dot entry */ if (strlen(fno.fname) > SD_SCREEN_FILE_LENGTH) continue;
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue;
reusableBuffer.sdmanager.count++; reusableBuffer.sdmanager.count++;
@ -238,10 +230,10 @@ void menuRadioSdManager(event_t _event)
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
for (uint8_t i=0; i<LCD_LINES-1; i++) { for (uint8_t i=0; i<LCD_LINES-1; i++) {
char * line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { if (line[0] == '\0' || isFilenameLower(isfile, fno.fname, line)) {
if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i)); if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i));
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
strcpy(line, fn); strcpy(line, fno.fname);
line[SD_SCREEN_FILE_LENGTH+1] = isfile; line[SD_SCREEN_FILE_LENGTH+1] = isfile;
break; break;
} }
@ -250,26 +242,26 @@ void menuRadioSdManager(event_t _event)
else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) { else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) {
for (int8_t i=6; i>=0; i--) { for (int8_t i=6; i>=0; i--) {
char * line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { if (line[0] == '\0' || isFilenameGreater(isfile, fno.fname, line)) {
if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i);
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i]));
strcpy(line, fn); strcpy(line, fno.fname);
line[SD_SCREEN_FILE_LENGTH+1] = isfile; line[SD_SCREEN_FILE_LENGTH+1] = isfile;
break; break;
} }
} }
} }
else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) { else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) {
if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[6])) { if (isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[6])) {
memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[6], fn); strcpy(reusableBuffer.sdmanager.lines[6], fno.fname);
reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile; reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile;
} }
} }
else { else {
if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) { if (isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[0])) {
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[0], fn); strcpy(reusableBuffer.sdmanager.lines[0], fno.fname);
reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile; reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile;
} }
} }

View file

@ -165,7 +165,8 @@ void menuRadioSdManager(event_t _event)
showMessageBox(STR_FORMATTING); showMessageBox(STR_FORMATTING);
logsClose(); logsClose();
audioQueue.stopSD(); audioQueue.stopSD();
if (f_mkfs(0, 1, 0) == FR_OK) { BYTE work[_MAX_SS];
if (f_mkfs(0, FM_FAT32, 0, work, sizeof(work)) == FR_OK) {
f_chdir("/"); f_chdir("/");
REFRESH_FILES(); REFRESH_FILES();
} }
@ -272,10 +273,6 @@ void menuRadioSdManager(event_t _event)
if (reusableBuffer.sdmanager.offset != menuVerticalOffset) { if (reusableBuffer.sdmanager.offset != menuVerticalOffset) {
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
reusableBuffer.sdmanager.offset = 0; reusableBuffer.sdmanager.offset = 0;
@ -299,16 +296,11 @@ void menuRadioSdManager(event_t _event)
FRESULT res = f_opendir(&dir, "."); // Open the directory FRESULT res = f_opendir(&dir, "."); // Open the directory
if (res == FR_OK) { if (res == FR_OK) {
bool firstTime = true;
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = sdReadDir(&dir, &fno, firstTime);
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fname[0] == '.' && fno.fname[1] == '\0') continue; /* Ignore dot entry */ if (strlen(fno.fname) > SD_SCREEN_FILE_LENGTH) continue;
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue;
reusableBuffer.sdmanager.count++; reusableBuffer.sdmanager.count++;
@ -317,10 +309,10 @@ void menuRadioSdManager(event_t _event)
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
for (uint8_t i=0; i<NUM_BODY_LINES; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
char * line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { if (line[0] == '\0' || isFilenameLower(isfile, fno.fname, line)) {
if (i < NUM_BODY_LINES-1) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (NUM_BODY_LINES-1-i)); if (i < NUM_BODY_LINES-1) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (NUM_BODY_LINES-1-i));
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(line, fn); strcpy(line, fno.fname);
NODE_TYPE(line) = isfile; NODE_TYPE(line) = isfile;
break; break;
} }
@ -329,26 +321,26 @@ void menuRadioSdManager(event_t _event)
else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) { else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) {
for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) { for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) {
char * line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { if (line[0] == '\0' || isFilenameGreater(isfile, fno.fname, line)) {
if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i);
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(line, fn); strcpy(line, fno.fname);
NODE_TYPE(line) = isfile; NODE_TYPE(line) = isfile;
break; break;
} }
} }
} }
else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) { else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) {
if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-2]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1])) { if (isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-2]) && isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1])) {
memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], fn); strcpy(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], fno.fname);
NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = isfile; NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = isfile;
} }
} }
else { else {
if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) { if (isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[0])) {
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[0], fn); strcpy(reusableBuffer.sdmanager.lines[0], fno.fname);
NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile; NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile;
} }
} }

View file

@ -31,7 +31,12 @@ enum ModelSelectMode {
MODE_MOVE_MODEL, MODE_MOVE_MODEL,
}; };
uint8_t selectMode; enum ModelDeleteMode {
MODE_DELETE_MODEL,
MODE_DELETE_CATEGORY,
};
uint8_t selectMode, deleteMode;
ModelsList modelslist; ModelsList modelslist;
ModelsCategory * currentCategory; ModelsCategory * currentCategory;
@ -108,6 +113,7 @@ void onModelSelectMenu(const char * result)
else if (result == STR_DELETE_MODEL) { else if (result == STR_DELETE_MODEL) {
POPUP_CONFIRMATION(STR_DELETEMODEL); POPUP_CONFIRMATION(STR_DELETEMODEL);
SET_WARNING_INFO(currentModel->name, LEN_MODEL_FILENAME, 0); SET_WARNING_INFO(currentModel->name, LEN_MODEL_FILENAME, 0);
deleteMode = MODE_DELETE_MODEL;
} }
else if (result == STR_CREATE_MODEL) { else if (result == STR_CREATE_MODEL) {
storageCheck(true); storageCheck(true);
@ -141,9 +147,15 @@ void onModelSelectMenu(const char * result)
editNameCursorPos = 0; editNameCursorPos = 0;
} }
else if (result == STR_DELETE_CATEGORY) { else if (result == STR_DELETE_CATEGORY) {
modelslist.removeCategory(currentCategory); if (currentCategory->size() > 0){
modelslist.save(); POPUP_WARNING(STR_DELETE_ERROR);
setCurrentCategory(currentCategoryIndex > 0 ? currentCategoryIndex-1 : currentCategoryIndex); SET_WARNING_INFO(STR_CAT_NOT_EMPTY, sizeof(TR_CAT_NOT_EMPTY), 0);
}
else {
POPUP_CONFIRMATION(STR_DELETEMODEL);
SET_WARNING_INFO(currentCategory->name, LEN_MODEL_FILENAME, 0);
deleteMode = MODE_DELETE_CATEGORY;
}
} }
} }
@ -184,14 +196,22 @@ bool menuModelSelect(event_t event)
{ {
if (warningResult) { if (warningResult) {
warningResult = 0; warningResult = 0;
int modelIndex = MODEL_INDEX(); if (deleteMode == MODE_DELETE_CATEGORY) {
modelslist.removeModel(currentCategory, currentModel); TRACE("DELETE CATEGORY");
s_copyMode = 0; modelslist.removeCategory(currentCategory);
event = EVT_REFRESH; modelslist.save();
if (modelIndex > 0) { setCurrentCategory(currentCategoryIndex > 0 ? currentCategoryIndex-1 : currentCategoryIndex);
modelIndex--; }
else if (deleteMode == MODE_DELETE_MODEL){
int modelIndex = MODEL_INDEX();
modelslist.removeModel(currentCategory, currentModel);
s_copyMode = 0;
event = EVT_REFRESH;
if (modelIndex > 0) {
modelIndex--;
}
setCurrentModel(modelIndex);
} }
setCurrentModel(modelIndex);
} }
switch(event) { switch(event) {

View file

@ -164,7 +164,8 @@ bool menuRadioSdManager(event_t _event)
showMessageBox(STR_FORMATTING); showMessageBox(STR_FORMATTING);
logsClose(); logsClose();
audioQueue.stopSD(); audioQueue.stopSD();
if (f_mkfs(0, 1, 0) == FR_OK) { BYTE work[_MAX_SS];
if (f_mkfs(0, FM_FAT32, 0, work, sizeof(work)) == FR_OK) {
f_chdir("/"); f_chdir("/");
REFRESH_FILES(); REFRESH_FILES();
} }
@ -262,10 +263,6 @@ bool menuRadioSdManager(event_t _event)
if (reusableBuffer.sdmanager.offset != menuVerticalOffset) { if (reusableBuffer.sdmanager.offset != menuVerticalOffset) {
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char *fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
reusableBuffer.sdmanager.offset = 0; reusableBuffer.sdmanager.offset = 0;
@ -289,16 +286,11 @@ bool menuRadioSdManager(event_t _event)
FRESULT res = f_opendir(&dir, "."); // Open the directory FRESULT res = f_opendir(&dir, "."); // Open the directory
if (res == FR_OK) { if (res == FR_OK) {
bool firstTime = true;
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = sdReadDir(&dir, &fno, firstTime);
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fname[0] == '.' && fno.fname[1] == '\0') continue; /* Ignore dot entry */ if (strlen(fno.fname) > SD_SCREEN_FILE_LENGTH) continue;
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue;
reusableBuffer.sdmanager.count++; reusableBuffer.sdmanager.count++;
@ -307,10 +299,10 @@ bool menuRadioSdManager(event_t _event)
if (menuVerticalOffset == 0) { if (menuVerticalOffset == 0) {
for (uint8_t i=0; i<NUM_BODY_LINES; i++) { for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
char * line = reusableBuffer.sdmanager.lines[i]; char * line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { if (line[0] == '\0' || isFilenameLower(isfile, fno.fname, line)) {
if (i < NUM_BODY_LINES-1) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (NUM_BODY_LINES-1-i)); if (i < NUM_BODY_LINES-1) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (NUM_BODY_LINES-1-i));
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(line, fn); strcpy(line, fno.fname);
NODE_TYPE(line) = isfile; NODE_TYPE(line) = isfile;
break; break;
} }
@ -319,26 +311,26 @@ bool menuRadioSdManager(event_t _event)
else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) { else if (reusableBuffer.sdmanager.offset == menuVerticalOffset) {
for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) { for (int8_t i=NUM_BODY_LINES-1; i>=0; i--) {
char *line = reusableBuffer.sdmanager.lines[i]; char *line = reusableBuffer.sdmanager.lines[i];
if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { if (line[0] == '\0' || isFilenameGreater(isfile, fno.fname, line)) {
if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i);
memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(line, fn); strcpy(line, fno.fname);
NODE_TYPE(line) = isfile; NODE_TYPE(line) = isfile;
break; break;
} }
} }
} }
else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) { else if (menuVerticalOffset > reusableBuffer.sdmanager.offset) {
if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-2]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1])) { if (isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-2]) && isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1])) {
memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], fn); strcpy(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1], fno.fname);
NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = isfile; NODE_TYPE(reusableBuffer.sdmanager.lines[NUM_BODY_LINES-1]) = isfile;
} }
} }
else { else {
if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) { if (isFilenameLower(isfile, fno.fname, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fno.fname, reusableBuffer.sdmanager.lines[0])) {
memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0]));
strcpy(reusableBuffer.sdmanager.lines[0], fn); strcpy(reusableBuffer.sdmanager.lines[0], fno.fname);
NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile; NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile;
} }
} }

View file

@ -256,7 +256,7 @@ bool sportUpdateUploadFile(const char *filename)
sportUpdateState = SPORT_DATA_TRANSFER, sportUpdateState = SPORT_DATA_TRANSFER,
sportWritePacket(packet); sportWritePacket(packet);
if (i==0) { if (i==0) {
updateProgressBar(file.fptr, file.fsize); updateProgressBar(file.fptr, file.obj.objsize);
} }
} }

View file

@ -99,7 +99,7 @@ const pm_char * logsOpen()
strcpy_P(tmp, STR_LOGS_EXT); strcpy_P(tmp, STR_LOGS_EXT);
result = f_open(&g_oLogFile, filename, FA_OPEN_ALWAYS | FA_WRITE); result = f_open(&g_oLogFile, filename, FA_OPEN_ALWAYS | FA_WRITE | FA_OPEN_APPEND);
if (result != FR_OK) { if (result != FR_OK) {
return SDCARD_ERROR(result); return SDCARD_ERROR(result);
} }
@ -107,12 +107,6 @@ const pm_char * logsOpen()
if (f_size(&g_oLogFile) == 0) { if (f_size(&g_oLogFile) == 0) {
writeHeader(); writeHeader();
} }
else {
result = f_lseek(&g_oLogFile, f_size(&g_oLogFile)); // append
if (result != FR_OK) {
return SDCARD_ERROR(result);
}
}
return NULL; return NULL;
} }
@ -123,7 +117,7 @@ void logsClose()
{ {
if (f_close(&g_oLogFile) != FR_OK) { if (f_close(&g_oLogFile) != FR_OK) {
// close failed, forget file // close failed, forget file
g_oLogFile.fs = 0; g_oLogFile.obj.fs = 0;
} }
lastLogTime = 0; lastLogTime = 0;
} }
@ -221,7 +215,7 @@ void logsWrite()
if (lastLogTime == 0 || (tmr10ms_t)(tmr10ms - lastLogTime) >= (tmr10ms_t)logDelay*10) { if (lastLogTime == 0 || (tmr10ms_t)(tmr10ms - lastLogTime) >= (tmr10ms_t)logDelay*10) {
lastLogTime = tmr10ms; lastLogTime = tmr10ms;
if (!g_oLogFile.fs) { if (!g_oLogFile.obj.fs) {
const pm_char * result = logsOpen(); const pm_char * result = logsOpen();
if (result != NULL) { if (result != NULL) {
if (result != error_displayed) { if (result != error_displayed) {
@ -389,7 +383,7 @@ void logsWrite()
} }
else { else {
error_displayed = NULL; error_displayed = NULL;
if (g_oLogFile.fs) { if (g_oLogFile.obj.fs) {
logsClose(); logsClose();
} }
} }

View file

@ -1118,10 +1118,6 @@ void luaLoadFiles(const char * directory, void (*callback)())
char path[LUA_FULLPATH_MAXLEN+1]; char path[LUA_FULLPATH_MAXLEN+1];
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char * fn; /* This function is assuming non-Unicode cfg. */
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
strcpy(path, directory); strcpy(path, directory);
@ -1133,10 +1129,9 @@ void luaLoadFiles(const char * directory, void (*callback)())
for (;;) { for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
fn = * fno.lfname ? fno.lfname : fno.fname; uint8_t len = strlen(fno.fname);
uint8_t len = strlen(fn); if (len > 0 && fno.fname[0]!='.' && (fno.fattrib & AM_DIR)) {
if (len > 0 && fn[0]!='.' && (fno.fattrib & AM_DIR)) { strcpy(&path[pathlen], fno.fname);
strcpy(&path[pathlen], fn);
strcat(&path[pathlen], "/main.lua"); strcat(&path[pathlen], "/main.lua");
if (isFileAvailable(path)) { if (isFileAvailable(path)) {
luaLoadFile(path, callback); luaLoadFile(path, callback);

View file

@ -22,7 +22,7 @@
uint8_t currentSpeakerVolume = 255; uint8_t currentSpeakerVolume = 255;
uint8_t requiredSpeakerVolume = 255; uint8_t requiredSpeakerVolume = 255;
uint8_t requestScreenshot = false; uint8_t mainRequestFlags = 0;
void handleUsbConnection() void handleUsbConnection()
{ {
@ -72,7 +72,9 @@ void checkSpeakerVolume()
{ {
if (currentSpeakerVolume != requiredSpeakerVolume) { if (currentSpeakerVolume != requiredSpeakerVolume) {
currentSpeakerVolume = requiredSpeakerVolume; currentSpeakerVolume = requiredSpeakerVolume;
#if !defined(SOFTWARE_VOLUME)
setScaledVolume(currentSpeakerVolume); setScaledVolume(currentSpeakerVolume);
#endif
} }
} }
@ -397,6 +399,12 @@ void perMain()
periodicTick(); periodicTick();
DEBUG_TIMER_STOP(debugTimerPerMain1); DEBUG_TIMER_STOP(debugTimerPerMain1);
if (mainRequestFlags & (1 << REQUEST_FLIGHT_RESET)) {
TRACE("Executing requested Flight Reset");
flightReset();
mainRequestFlags &= ~(1 << REQUEST_FLIGHT_RESET);
}
event_t evt = getEvent(false); event_t evt = getEvent(false);
if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) { if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) {
// on keypress turn the light on // on keypress turn the light on
@ -453,9 +461,9 @@ void perMain()
#endif #endif
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
if (requestScreenshot) { if (mainRequestFlags & (1 << REQUEST_SCREENSHOT)) {
requestScreenshot = false;
writeScreenshot(); writeScreenshot();
mainRequestFlags &= ~(1 << REQUEST_SCREENSHOT);
} }
#endif #endif

View file

@ -985,28 +985,30 @@ void doSplash()
void checkSDVersion() void checkSDVersion()
{ {
if (sdMounted()) { if (sdMounted()) {
FIL versionFile = {0}; FIL versionFile;
UINT read = 0; UINT read = 0;
char version[sizeof(REQUIRED_SDCARD_VERSION)-1]; char version[sizeof(REQUIRED_SDCARD_VERSION)-1];
char error[sizeof(TR_WRONG_SDCARDVERSION)+ sizeof(version)];
strAppend(strAppend(error, STR_WRONG_SDCARDVERSION, sizeof(TR_WRONG_SDCARDVERSION)), REQUIRED_SDCARD_VERSION, sizeof(REQUIRED_SDCARD_VERSION));
FRESULT result = f_open(&versionFile, "/opentx.sdcard.version", FA_OPEN_EXISTING | FA_READ); FRESULT result = f_open(&versionFile, "/opentx.sdcard.version", FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK) { if (result == FR_OK) {
if (f_read(&versionFile, &version, sizeof(version), &read) != FR_OK || if (f_read(&versionFile, &version, sizeof(version), &read) != FR_OK ||
read != sizeof(version) || read != sizeof(version) ||
strncmp(version, REQUIRED_SDCARD_VERSION, sizeof(version)) != 0) { strncmp(version, REQUIRED_SDCARD_VERSION, sizeof(version)) != 0) {
TRACE("SD card version mismatch: %.*s, %s", sizeof(REQUIRED_SDCARD_VERSION)-1, version, REQUIRED_SDCARD_VERSION); TRACE("SD card version mismatch: %.*s, %s", sizeof(REQUIRED_SDCARD_VERSION)-1, version, REQUIRED_SDCARD_VERSION);
ALERT(STR_SD_CARD, STR_WRONG_SDCARDVERSION, AU_ERROR); ALERT(STR_SD_CARD, error, AU_ERROR);
} }
f_close(&versionFile); f_close(&versionFile);
} }
else { else {
ALERT(STR_SD_CARD, STR_WRONG_SDCARDVERSION, AU_ERROR); ALERT(STR_SD_CARD, error, AU_ERROR);
} }
} }
} }
#endif #endif
#if defined(PCBTARANIS) #if defined(PCBTARANIS) || defined(PCBHORUS)
void checkFailsafe() void checkFailsafe()
{ {
for (int i=0; i<NUM_MODULES; i++) { for (int i=0; i<NUM_MODULES; i++) {
@ -2454,8 +2456,11 @@ void opentxInit(OPENTX_INIT_ARGS)
} }
#endif #endif
#if defined(VOICE) #if defined(VOICE) && defined(CPUARM)
setScaledVolume(g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF); currentSpeakerVolume = g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF;
#if !defined(SOFTWARE_VOLUME)
setScaledVolume(currentSpeakerVolume);
#endif
#endif #endif
#if defined(CPUARM) #if defined(CPUARM)

View file

@ -924,27 +924,27 @@ inline int divRoundClosest(const int n, const int d)
#define calc100to256_16Bits(x) calc100to256(x) #define calc100to256_16Bits(x) calc100to256(x)
#define calc100toRESX_16Bits(x) calc100toRESX(x) #define calc100toRESX_16Bits(x) calc100toRESX(x)
inline int calc100to256(register int x) inline int calc100to256(int x)
{ {
return divRoundClosest(x*256, 100); return divRoundClosest(x*256, 100);
} }
inline int calc100toRESX(register int x) inline int calc100toRESX(int x)
{ {
return divRoundClosest(x*RESX, 100); return divRoundClosest(x*RESX, 100);
} }
inline int calc1000toRESX(register int x) inline int calc1000toRESX(int x)
{ {
return divRoundClosest(x*RESX, 1000); return divRoundClosest(x*RESX, 1000);
} }
inline int calcRESXto1000(register int x) inline int calcRESXto1000(int x)
{ {
return divRoundClosest(x*1000, RESX); return divRoundClosest(x*1000, RESX);
} }
inline int calcRESXto100(register int x) inline int calcRESXto100(int x)
{ {
return divRoundClosest(x*100, RESX); return divRoundClosest(x*100, RESX);
} }
@ -1354,8 +1354,13 @@ void clearMFP();
extern uint8_t requiredSpeakerVolume; extern uint8_t requiredSpeakerVolume;
#endif #endif
#if defined(PCBTARANIS) #if defined(CPUARM)
extern uint8_t requestScreenshot; enum MainRequest {
REQUEST_SCREENSHOT,
REQUEST_FLIGHT_RESET,
};
extern uint8_t mainRequestFlags;
#endif #endif
void checkBattery(); void checkBattery();

View file

@ -123,12 +123,6 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
{ {
FILINFO fno; FILINFO fno;
DIR dir; DIR dir;
char * fn; /* This function is assuming non-Unicode cfg. */
#if _USE_LFN
TCHAR lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
#endif
#if defined(PCBTARANIS) || defined(PCBHORUS) #if defined(PCBTARANIS) || defined(PCBHORUS)
popupMenuOffsetType = MENU_OFFSET_EXTERNAL; popupMenuOffsetType = MENU_OFFSET_EXTERNAL;
@ -201,33 +195,27 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
res = f_readdir(&dir, &fno); /* Read a directory item */ res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
#if _USE_LFN uint8_t len = strlen(fno.fname);
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
uint8_t len = strlen(fn);
uint8_t maxlen_with_extension = (flags & LIST_SD_FILE_EXT) ? maxlen : maxlen+LEN_FILE_EXTENSION; uint8_t maxlen_with_extension = (flags & LIST_SD_FILE_EXT) ? maxlen : maxlen+LEN_FILE_EXTENSION;
if (len < LEN_FILE_EXTENSION+1 || len > maxlen_with_extension || !isExtensionMatching(fn+len-LEN_FILE_EXTENSION, extension, flags) || (fno.fattrib & AM_DIR)) continue; if (len < LEN_FILE_EXTENSION+1 || len > maxlen_with_extension || !isExtensionMatching(fno.fname+len-LEN_FILE_EXTENSION, extension, flags) || (fno.fattrib & AM_DIR)) continue;
popupMenuNoItems++; popupMenuNoItems++;
if (!(flags & LIST_SD_FILE_EXT)) { if (!(flags & LIST_SD_FILE_EXT)) {
fn[len-LEN_FILE_EXTENSION] = '\0'; fno.fname[len-LEN_FILE_EXTENSION] = '\0';
} }
if (popupMenuOffset == 0) { if (popupMenuOffset == 0) {
if (selection && strncasecmp(fn, selection, maxlen) < 0) { if (selection && strncasecmp(fno.fname, selection, maxlen) < 0) {
lastpopupMenuOffset++; lastpopupMenuOffset++;
} }
else { else {
for (uint8_t i=0; i<MENU_MAX_DISPLAY_LINES; i++) { for (uint8_t i=0; i<MENU_MAX_DISPLAY_LINES; i++) {
char * line = reusableBuffer.modelsel.menu_bss[i]; char * line = reusableBuffer.modelsel.menu_bss[i];
if (line[0] == '\0' || strcasecmp(fn, line) < 0) { if (line[0] == '\0' || strcasecmp(fno.fname, line) < 0) {
if (i < MENU_MAX_DISPLAY_LINES-1) memmove(reusableBuffer.modelsel.menu_bss[i+1], line, sizeof(reusableBuffer.modelsel.menu_bss[i]) * (MENU_MAX_DISPLAY_LINES-1-i)); if (i < MENU_MAX_DISPLAY_LINES-1) memmove(reusableBuffer.modelsel.menu_bss[i+1], line, sizeof(reusableBuffer.modelsel.menu_bss[i]) * (MENU_MAX_DISPLAY_LINES-1-i));
memset(line, 0, MENU_LINE_LENGTH); memset(line, 0, MENU_LINE_LENGTH);
strcpy(line, fn); strcpy(line, fno.fname);
break; break;
} }
} }
@ -240,10 +228,10 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
else if (lastpopupMenuOffset == 0xffff) { else if (lastpopupMenuOffset == 0xffff) {
for (int i=MENU_MAX_DISPLAY_LINES-1; i>=0; i--) { for (int i=MENU_MAX_DISPLAY_LINES-1; i>=0; i--) {
char * line = reusableBuffer.modelsel.menu_bss[i]; char * line = reusableBuffer.modelsel.menu_bss[i];
if (line[0] == '\0' || strcasecmp(fn, line) > 0) { if (line[0] == '\0' || strcasecmp(fno.fname, line) > 0) {
if (i > 0) memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], sizeof(reusableBuffer.modelsel.menu_bss[i]) * i); if (i > 0) memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], sizeof(reusableBuffer.modelsel.menu_bss[i]) * i);
memset(line, 0, MENU_LINE_LENGTH); memset(line, 0, MENU_LINE_LENGTH);
strcpy(line, fn); strcpy(line, fno.fname);
break; break;
} }
} }
@ -252,15 +240,15 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
} }
} }
else if (popupMenuOffset > lastpopupMenuOffset) { else if (popupMenuOffset > lastpopupMenuOffset) {
if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-2]) > 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-1]) < 0) { if (strcasecmp(fno.fname, reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-2]) > 0 && strcasecmp(fno.fname, reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-1]) < 0) {
memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-1], 0, MENU_LINE_LENGTH); memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-1], 0, MENU_LINE_LENGTH);
strcpy(reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-1], fn); strcpy(reusableBuffer.modelsel.menu_bss[MENU_MAX_DISPLAY_LINES-1], fno.fname);
} }
} }
else { else {
if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[1]) < 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[0]) > 0) { if (strcasecmp(fno.fname, reusableBuffer.modelsel.menu_bss[1]) < 0 && strcasecmp(fno.fname, reusableBuffer.modelsel.menu_bss[0]) > 0) {
memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH);
strcpy(reusableBuffer.modelsel.menu_bss[0], fn); strcpy(reusableBuffer.modelsel.menu_bss[0], fno.fname);
} }
} }
} }
@ -274,6 +262,37 @@ bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen
return popupMenuNoItems; return popupMenuNoItems;
} }
// returns true if current working dir is at the root level
bool isCwdAtRoot()
{
char path[10];
if (f_getcwd(path, sizeof(path)-1) == FR_OK) {
return (strcasecmp("/", path) == 0);
}
return false;
}
/*
Wrapper around the f_readdir() function which
also returns ".." entry for sub-dirs. (FatFS 0.12 does
not return ".", ".." dirs anymore)
*/
FRESULT sdReadDir(DIR * dir, FILINFO * fno, bool & firstTime)
{
FRESULT res;
if (firstTime && !isCwdAtRoot()) {
// fake parent directory entry
strcpy(fno->fname, "..");
fno->fattrib = AM_DIR;
res = FR_OK;
}
else {
res = f_readdir(dir, fno); /* Read a directory item */
}
firstTime = false;
return res;
}
#if defined(CPUARM) && defined(SDCARD) #if defined(CPUARM) && defined(SDCARD)
const char * sdCopyFile(const char * srcPath, const char * destPath) const char * sdCopyFile(const char * srcPath, const char * destPath)
{ {

View file

@ -133,4 +133,7 @@ const char * sdCopyFile(const char * srcFilename, const char * srcDir, const cha
#define LIST_SD_FILE_EXT 2 #define LIST_SD_FILE_EXT 2
bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen, const char * selection, uint8_t flags=0); bool sdListFiles(const char * path, const char * extension, const uint8_t maxlen, const char * selection, uint8_t flags=0);
bool isCwdAtRoot();
FRESULT sdReadDir(DIR * dir, FILINFO * fno, bool & firstTime);
#endif // _SDCARD_H_ #endif // _SDCARD_H_

View file

@ -364,7 +364,7 @@ uint8_t * currentBuffer = NULL;
uint32_t currentSize = 0; uint32_t currentSize = 0;
int16_t newVolume = -1; int16_t newVolume = -1;
void audioSetCurrentBuffer(AudioBuffer * buffer) void audioSetCurrentBuffer(const AudioBuffer * buffer)
{ {
currentBuffer = (uint8_t *)buffer->data; currentBuffer = (uint8_t *)buffer->data;
currentSize = buffer->size * 2; currentSize = buffer->size * 2;
@ -379,35 +379,22 @@ void audioConsumeCurrentBuffer()
newVolume = -1; newVolume = -1;
} }
if (!currentBuffer) {
audioSetCurrentBuffer(audioQueue.buffersFifo.getNextFilledBuffer());
}
if (currentBuffer) { if (currentBuffer) {
uint32_t written = audioSpiWriteData(currentBuffer, currentSize); uint32_t written = audioSpiWriteData(currentBuffer, currentSize);
currentBuffer += written; currentBuffer += written;
currentSize -= written; currentSize -= written;
if (currentSize == 0) { if (currentSize == 0) {
AudioBuffer * buffer = audioQueue.getNextFilledBuffer(); audioQueue.buffersFifo.freeNextFilledBuffer();
if (buffer) { currentBuffer = NULL;
audioSetCurrentBuffer(buffer); currentSize = 0;
}
else {
currentBuffer = NULL;
currentSize = 0;
}
} }
} }
} }
void audioPushBuffer(AudioBuffer * buffer)
{
if (!currentBuffer) {
buffer->state = AUDIO_BUFFER_PLAYING;
audioSetCurrentBuffer(buffer);
audioConsumeCurrentBuffer();
}
else {
buffer->state = AUDIO_BUFFER_FILLED;
}
}
// adjust this value for a volume level just above the silence // adjust this value for a volume level just above the silence
// values is attenuation in dB, higher value - less volume // values is attenuation in dB, higher value - less volume
// max value is 126 // max value is 126

View file

@ -27,6 +27,13 @@
extern "C" { extern "C" {
#endif #endif
#if __clang__
// clang is very picky about the use of "register"
// Tell clang to ignore the warnings for the following files
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-register"
#endif
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h"
@ -44,7 +51,12 @@ extern "C" {
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dma2d.h"
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h" #include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/misc.h"
#if __clang__
// Restore warnings about registers
#pragma clang diagnostic pop
#endif
#if !defined(SIMU) #if !defined(SIMU)
#include "usbd_cdc_core.h" #include "usbd_cdc_core.h"
#include "usbd_msc_core.h" #include "usbd_msc_core.h"

View file

@ -93,7 +93,7 @@ uint8_t keyDown()
void checkRotaryEncoder() void checkRotaryEncoder()
{ {
register uint32_t newpos = ROTARY_ENCODER_POSITION(); uint32_t newpos = ROTARY_ENCODER_POSITION();
if (newpos != rotencPosition) { if (newpos != rotencPosition) {
if ((rotencPosition & 0x01) ^ ((newpos & 0x02) >> 1)) { if ((rotencPosition & 0x01) ^ ((newpos & 0x02) >> 1)) {
--rotencValue[0]; --rotencValue[0];
@ -108,7 +108,7 @@ void checkRotaryEncoder()
/* TODO common to ARM */ /* TODO common to ARM */
void readKeysAndTrims() void readKeysAndTrims()
{ {
register uint32_t i; uint32_t i;
uint8_t index = 0; uint8_t index = 0;
uint32_t in = readKeys(); uint32_t in = readKeys();
@ -161,7 +161,7 @@ uint8_t keyState(uint8_t index)
uint32_t switchState(uint8_t index) uint32_t switchState(uint8_t index)
{ {
register uint32_t xxx = 0; uint32_t xxx = 0;
switch (index) { switch (index) {
ADD_3POS_CASE(A, 0); ADD_3POS_CASE(A, 0);

View file

@ -364,18 +364,11 @@ struct SimulatorAudio {
bool threadRunning; bool threadRunning;
pthread_t threadPid; pthread_t threadPid;
} simuAudio; } simuAudio;
void audioPushBuffer(AudioBuffer * buffer)
{
buffer->state = AUDIO_BUFFER_FILLED;
}
#endif #endif
#if defined(PCBHORUS)
void audioConsumeCurrentBuffer() void audioConsumeCurrentBuffer()
{ {
} }
#endif
#if defined(MASTER_VOLUME) #if defined(MASTER_VOLUME)
void setScaledVolume(uint8_t volume) void setScaledVolume(uint8_t volume)
@ -395,7 +388,7 @@ int32_t getVolume()
#endif #endif
#if defined(SIMU_AUDIO) && defined(CPUARM) #if defined(SIMU_AUDIO) && defined(CPUARM)
void copyBuffer(uint8_t * dest, uint16_t * buff, unsigned int samples) void copyBuffer(uint8_t * dest, const uint16_t * buff, unsigned int samples)
{ {
for(unsigned int i=0; i<samples; i++) { for(unsigned int i=0; i<samples; i++) {
int sample = ((int32_t)(uint32_t)(buff[i]) - 0x8000); // conversion from uint16_t int sample = ((int32_t)(uint32_t)(buff[i]) - 0x8000); // conversion from uint16_t
@ -409,22 +402,25 @@ void fillAudioBuffer(void *udata, Uint8 *stream, int len)
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
if (simuAudio.leftoverLen) { if (simuAudio.leftoverLen) {
copyBuffer(stream, simuAudio.leftoverData, simuAudio.leftoverLen); int len1 = min(len/2, simuAudio.leftoverLen);
len -= simuAudio.leftoverLen*2; copyBuffer(stream, simuAudio.leftoverData, len1);
stream += simuAudio.leftoverLen*2; len -= len1*2;
simuAudio.leftoverLen = 0; stream += len1*2;
simuAudio.leftoverLen -= len1;
// putchar('l'); // putchar('l');
if (simuAudio.leftoverLen) return; // buffer fully filled
} }
if (audioQueue.filledAtleast(len/(AUDIO_BUFFER_SIZE*2)+1) ) { if (audioQueue.buffersFifo.filledAtleast(len/(AUDIO_BUFFER_SIZE*2)+1) ) {
while(true) { while(true) {
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer(); const AudioBuffer * nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer();
if (nextBuffer) { if (nextBuffer) {
if (len >= nextBuffer->size*2) { if (len >= nextBuffer->size*2) {
copyBuffer(stream, nextBuffer->data, nextBuffer->size); copyBuffer(stream, nextBuffer->data, nextBuffer->size);
stream += nextBuffer->size*2; stream += nextBuffer->size*2;
len -= nextBuffer->size*2; len -= nextBuffer->size*2;
// putchar('+'); // putchar('+');
audioQueue.buffersFifo.freeNextFilledBuffer();
} }
else { else {
//partial //partial
@ -433,6 +429,7 @@ void fillAudioBuffer(void *udata, Uint8 *stream, int len)
memcpy(simuAudio.leftoverData, &nextBuffer->data[len/2], simuAudio.leftoverLen*2); memcpy(simuAudio.leftoverData, &nextBuffer->data[len/2], simuAudio.leftoverLen*2);
len = 0; len = 0;
// putchar('p'); // putchar('p');
audioQueue.buffersFifo.freeNextFilledBuffer();
break; break;
} }
} }
@ -657,20 +654,20 @@ FRESULT f_open (FIL * fil, const TCHAR *name, BYTE flag)
{ {
char * path = convertSimuPath(name); char * path = convertSimuPath(name);
char * realPath = findTrueFileName(path); char * realPath = findTrueFileName(path);
fil->fs = 0; fil->obj.fs = 0;
if (!(flag & FA_WRITE)) { if (!(flag & FA_WRITE)) {
struct stat tmp; struct stat tmp;
if (stat(realPath, &tmp)) { if (stat(realPath, &tmp)) {
TRACE("f_open(%s) = INVALID_NAME (FIL %p)", path, fil); TRACE("f_open(%s) = INVALID_NAME (FIL %p)", path, fil);
return FR_INVALID_NAME; return FR_INVALID_NAME;
} }
fil->fsize = tmp.st_size; fil->obj.objsize = tmp.st_size;
fil->fptr = 0; fil->fptr = 0;
} }
fil->fs = (FATFS*)fopen(realPath, (flag & FA_WRITE) ? ((flag & FA_CREATE_ALWAYS) ? "wb+" : "ab+") : "rb+"); fil->obj.fs = (FATFS*)fopen(realPath, (flag & FA_WRITE) ? ((flag & FA_CREATE_ALWAYS) ? "wb+" : "ab+") : "rb+");
fil->fptr = 0; fil->fptr = 0;
if (fil->fs) { if (fil->obj.fs) {
TRACE("f_open(%s, %x) = %p (FIL %p)", path, flag, fil->fs, fil); TRACE("f_open(%s, %x) = %p (FIL %p)", path, flag, fil->obj.fs, fil);
return FR_OK; return FR_OK;
} }
TRACE("f_open(%s) = error %d (%s) (FIL %p)", path, errno, strerror(errno), fil); TRACE("f_open(%s) = error %d (%s) (FIL %p)", path, errno, strerror(errno), fil);
@ -679,39 +676,39 @@ FRESULT f_open (FIL * fil, const TCHAR *name, BYTE flag)
FRESULT f_read (FIL* fil, void* data, UINT size, UINT* read) FRESULT f_read (FIL* fil, void* data, UINT size, UINT* read)
{ {
if (fil && fil->fs) { if (fil && fil->obj.fs) {
*read = fread(data, 1, size, (FILE*)fil->fs); *read = fread(data, 1, size, (FILE*)fil->obj.fs);
fil->fptr += *read; fil->fptr += *read;
// TRACE("fread(%p) %u, %u", fil->fs, size, *read); // TRACE("fread(%p) %u, %u", fil->obj.fs, size, *read);
} }
return FR_OK; return FR_OK;
} }
FRESULT f_write (FIL* fil, const void* data, UINT size, UINT* written) FRESULT f_write (FIL* fil, const void* data, UINT size, UINT* written)
{ {
if (fil && fil->fs) { if (fil && fil->obj.fs) {
*written = fwrite(data, 1, size, (FILE*)fil->fs); *written = fwrite(data, 1, size, (FILE*)fil->obj.fs);
fil->fptr += size; fil->fptr += size;
// TRACE("fwrite(%p) %u, %u", fil->fs, size, *written); // TRACE("fwrite(%p) %u, %u", fil->obj.fs, size, *written);
} }
return FR_OK; return FR_OK;
} }
FRESULT f_lseek (FIL* fil, DWORD offset) FRESULT f_lseek (FIL* fil, DWORD offset)
{ {
if (fil && fil->fs) fseek((FILE*)fil->fs, offset, SEEK_SET); if (fil && fil->obj.fs) fseek((FILE*)fil->obj.fs, offset, SEEK_SET);
fil->fptr = offset; fil->fptr = offset;
return FR_OK; return FR_OK;
} }
UINT f_size(FIL* fil) UINT f_size(FIL* fil)
{ {
if (fil && fil->fs) { if (fil && fil->obj.fs) {
long curr = ftell((FILE*)fil->fs); long curr = ftell((FILE*)fil->obj.fs);
fseek((FILE*)fil->fs, 0, SEEK_END); fseek((FILE*)fil->obj.fs, 0, SEEK_END);
long size = ftell((FILE*)fil->fs); long size = ftell((FILE*)fil->obj.fs);
fseek((FILE*)fil->fs, curr, SEEK_SET); fseek((FILE*)fil->obj.fs, curr, SEEK_SET);
TRACE("f_size(%p) %u", fil->fs, size); TRACE("f_size(%p) %u", fil->obj.fs, size);
return size; return size;
} }
return 0; return 0;
@ -719,10 +716,10 @@ UINT f_size(FIL* fil)
FRESULT f_close (FIL * fil) FRESULT f_close (FIL * fil)
{ {
TRACE("f_close(%p) (FIL:%p)", fil->fs, fil); TRACE("f_close(%p) (FIL:%p)", fil->obj.fs, fil);
if (fil->fs) { if (fil->obj.fs) {
fclose((FILE*)fil->fs); fclose((FILE*)fil->obj.fs);
fil->fs = NULL; fil->obj.fs = NULL;
} }
return FR_OK; return FR_OK;
} }
@ -736,8 +733,8 @@ FRESULT f_chdir (const TCHAR *name)
FRESULT f_opendir (DIR * rep, const TCHAR * name) FRESULT f_opendir (DIR * rep, const TCHAR * name)
{ {
char *path = convertSimuPath(name); char *path = convertSimuPath(name);
rep->fs = (FATFS *)simu::opendir(path); rep->obj.fs = (FATFS *)simu::opendir(path);
if ( rep->fs ) { if ( rep->obj.fs ) {
TRACE("f_opendir(%s) = OK", path); TRACE("f_opendir(%s) = OK", path);
return FR_OK; return FR_OK;
} }
@ -748,15 +745,19 @@ FRESULT f_opendir (DIR * rep, const TCHAR * name)
FRESULT f_closedir (DIR * rep) FRESULT f_closedir (DIR * rep)
{ {
TRACE("f_closedir(%p)", rep); TRACE("f_closedir(%p)", rep);
if (rep->fs) simu::closedir((simu::DIR *)rep->fs); if (rep->obj.fs) simu::closedir((simu::DIR *)rep->obj.fs);
return FR_OK; return FR_OK;
} }
FRESULT f_readdir (DIR * rep, FILINFO * fil) FRESULT f_readdir (DIR * rep, FILINFO * fil)
{ {
if (!rep->fs) return FR_NO_FILE; simu::dirent * ent;
simu::dirent * ent = simu::readdir((simu::DIR *)rep->fs); if (!rep->obj.fs) return FR_NO_FILE;
if (!ent) return FR_NO_FILE; for(;;) {
ent = simu::readdir((simu::DIR *)rep->obj.fs);
if (!ent) return FR_NO_FILE;
if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..") ) break;
}
#if defined(WIN32) || !defined(__GNUC__) || defined(__APPLE__) #if defined(WIN32) || !defined(__GNUC__) || defined(__APPLE__)
fil->fattrib = (ent->d_type == DT_DIR ? AM_DIR : 0); fil->fattrib = (ent->d_type == DT_DIR ? AM_DIR : 0);
@ -773,15 +774,13 @@ FRESULT f_readdir (DIR * rep, FILINFO * fil)
} }
#endif #endif
memset(fil->fname, 0, 13); memset(fil->fname, 0, SD_SCREEN_FILE_LENGTH);
memset(fil->lfname, 0, SD_SCREEN_FILE_LENGTH); strcpy(fil->fname, ent->d_name);
strncpy(fil->fname, ent->d_name, 13-1);
strcpy(fil->lfname, ent->d_name);
// TRACE("f_readdir(): %s", fil->fname); // TRACE("f_readdir(): %s", fil->fname);
return FR_OK; return FR_OK;
} }
FRESULT f_mkfs (const TCHAR * path, BYTE, UINT) FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len)
{ {
TRACE("Format SD..."); TRACE("Format SD...");
return FR_OK; return FR_OK;
@ -830,7 +829,7 @@ FRESULT f_rename(const TCHAR *oldname, const TCHAR *newname)
int f_putc (TCHAR c, FIL * fil) int f_putc (TCHAR c, FIL * fil)
{ {
if (fil && fil->fs) fwrite(&c, 1, 1, (FILE*)fil->fs); if (fil && fil->obj.fs) fwrite(&c, 1, 1, (FILE*)fil->obj.fs);
return FR_OK; return FR_OK;
} }
@ -847,7 +846,7 @@ int f_printf (FIL *fil, const TCHAR * format, ...)
{ {
va_list arglist; va_list arglist;
va_start(arglist, format); va_start(arglist, format);
if (fil && fil->fs) vfprintf((FILE*)fil->fs, format, arglist); if (fil && fil->obj.fs) vfprintf((FILE*)fil->obj.fs, format, arglist);
va_end(arglist); va_end(arglist);
return 0; return 0;
} }
@ -867,9 +866,18 @@ FRESULT f_getcwd (TCHAR *path, UINT sz_path)
return FR_NO_PATH; return FR_NO_PATH;
} }
if (sz_path < (strlen(cwd) - strlen(simuSdDirectory))) {
TRACE("f_getcwd(): buffer too short");
return FR_NOT_ENOUGH_CORE;
}
// remove simuSdDirectory from the cwd // remove simuSdDirectory from the cwd
strcpy(path, cwd + strlen(simuSdDirectory)); strcpy(path, cwd + strlen(simuSdDirectory));
if (strlen(path) == 0) {
strcpy(path, "/"); // fix for the root directory
}
TRACE("f_getcwd() = %s", path); TRACE("f_getcwd() = %s", path);
return FR_OK; return FR_OK;
} }

View file

@ -43,8 +43,8 @@ const char ana_direction[NUMBER_ANALOG] = {1, 1, 0, 1 ,0 ,1 ,0, 0, 0};
// TRGEN = 0 (software trigger only) // TRGEN = 0 (software trigger only)
void adcInit() void adcInit()
{ {
register Adc *padc ; Adc *padc ;
register uint32_t timer ; uint32_t timer ;
timer = ( Master_frequency / (3600000*2) ) << 8 ; timer = ( Master_frequency / (3600000*2) ) << 8 ;
// Enable peripheral clock ADC = bit 29 // Enable peripheral clock ADC = bit 29
@ -65,9 +65,9 @@ void adcInit()
// Documented bug, must do them 1 by 1 // Documented bug, must do them 1 by 1
void adcSingleRead() void adcSingleRead()
{ {
register Adc *padc; Adc *padc;
register uint32_t y; uint32_t y;
register uint32_t x; uint32_t x;
for (uint8_t i=0; i<4; i++) for (uint8_t i=0; i<4; i++)
padc = ADC; padc = ADC;

View file

@ -19,6 +19,7 @@
*/ */
#include "opentx.h" #include "opentx.h"
const AudioBuffer * nextBuffer = 0;
const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = const int8_t volumeScale[VOLUME_LEVEL_MAX+1] =
{ {
@ -30,8 +31,8 @@ const int8_t volumeScale[VOLUME_LEVEL_MAX+1] =
void setSampleRate(uint32_t frequency) void setSampleRate(uint32_t frequency)
{ {
register Tc *ptc ; Tc *ptc ;
register uint32_t timer ; uint32_t timer ;
timer = Master_frequency / (8 * frequency) ; // MCK/8 and 100 000 Hz timer = Master_frequency / (8 * frequency) ; // MCK/8 and 100 000 Hz
if (timer > 65535) if (timer > 65535)
@ -49,8 +50,8 @@ void setSampleRate(uint32_t frequency)
// Start TIMER1 at 100000Hz, used for DACC trigger // Start TIMER1 at 100000Hz, used for DACC trigger
void dacTimerStart() void dacTimerStart()
{ {
register Tc *ptc ; Tc *ptc ;
register uint32_t timer ; uint32_t timer ;
// Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28
PMC->PMC_PCER0 |= 0x01000000L ; // Enable peripheral clock to TC1 PMC->PMC_PCER0 |= 0x01000000L ; // Enable peripheral clock to TC1
@ -77,7 +78,7 @@ void dacInit()
PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC
register Dacc *dacptr = DACC; Dacc *dacptr = DACC;
#if defined(REVA) #if defined(REVA)
dacptr->DACC_MR = 0x0B010215L ; // 0000 1011 0000 0001 0000 0010 0001 0101 dacptr->DACC_MR = 0x0B010215L ; // 0000 1011 0000 0001 0000 0010 0001 0101
@ -93,17 +94,24 @@ void dacInit()
NVIC_EnableIRQ(DACC_IRQn) ; NVIC_EnableIRQ(DACC_IRQn) ;
} }
void audioPushBuffer(AudioBuffer *buffer) void audioConsumeCurrentBuffer()
{ {
buffer->state = AUDIO_BUFFER_FILLED; if (nextBuffer == 0) {
dacStart(); nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer();
if (nextBuffer) {
dacStart();
}
}
} }
extern "C" void DAC_IRQHandler() extern "C" void DAC_IRQHandler()
{ {
uint32_t sr = DACC->DACC_ISR; uint32_t sr = DACC->DACC_ISR;
if (sr & DACC_ISR_ENDTX) { if (sr & DACC_ISR_ENDTX) {
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer(); if (nextBuffer) audioQueue.buffersFifo.freeNextFilledBuffer();
nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer();
if (nextBuffer) { if (nextBuffer) {
// Try the first PDC buffer // Try the first PDC buffer
if ((DACC->DACC_TCR == 0) && (DACC->DACC_TNCR == 0)) { if ((DACC->DACC_TCR == 0) && (DACC->DACC_TNCR == 0)) {
@ -129,7 +137,7 @@ extern "C" void DAC_IRQHandler()
// Sound routines // Sound routines
void audioInit() void audioInit()
{ {
register Pio *pioptr ; Pio *pioptr ;
dacInit() ; dacInit() ;
@ -161,17 +169,15 @@ void audioEnd()
PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC
} }
#if !defined(SOFTWARE_VOLUME)
void setScaledVolume(uint8_t volume) void setScaledVolume(uint8_t volume)
{ {
#if !defined(SOFTWARE_VOLUME)
volumeRequired = volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)]; volumeRequired = volumeScale[min<uint8_t>(volume, VOLUME_LEVEL_MAX)];
#ifndef AR9X
__disable_irq() ; __disable_irq() ;
i2cCheck() ; i2cCheck() ;
__enable_irq() ; __enable_irq() ;
#endif
#endif
} }
#endif
#endif // #if !defined(SIMU) #endif // #if !defined(SIMU)

View file

@ -23,7 +23,7 @@
void audioInit( void ) ; void audioInit( void ) ;
void audioEnd( void ) ; void audioEnd( void ) ;
#define audioConsumeCurrentBuffer() void audioConsumeCurrentBuffer();
#define audioDisableIrq() __disable_irq() #define audioDisableIrq() __disable_irq()
#define audioEnableIrq() __enable_irq() #define audioEnableIrq() __enable_irq()

View file

@ -50,7 +50,7 @@ extern "C" void sam_boot( void ) ;
inline void config_free_pins() inline void config_free_pins()
{ {
#if defined(REVA) #if defined(REVA)
register Pio * pioptr = PIOA ; Pio * pioptr = PIOA ;
pioptr->PIO_PER = 0x03800000L ; // Enable bits A25,24,23 pioptr->PIO_PER = 0x03800000L ; // Enable bits A25,24,23
pioptr->PIO_ODR = 0x03800000L ; // Set as input pioptr->PIO_ODR = 0x03800000L ; // Set as input
pioptr->PIO_PUER = 0x03800000L ; // Enable pullups pioptr->PIO_PUER = 0x03800000L ; // Enable pullups
@ -73,7 +73,7 @@ inline void config_free_pins()
inline void setup_switches() inline void setup_switches()
{ {
#if defined(REVA) #if defined(REVA)
register Pio *pioptr = PIOA ; Pio *pioptr = PIOA ;
pioptr->PIO_PER = 0xF8008184 ; // Enable bits pioptr->PIO_PER = 0xF8008184 ; // Enable bits
pioptr->PIO_ODR = 0xF8008184 ; // Set bits input pioptr->PIO_ODR = 0xF8008184 ; // Set bits input
pioptr->PIO_PUER = 0xF8008184 ; // Set bits with pullups pioptr->PIO_PUER = 0xF8008184 ; // Set bits with pullups
@ -97,7 +97,7 @@ inline void setup_switches()
#if !defined(SIMU) #if !defined(SIMU)
inline void UART3_Configure(uint32_t baudrate, uint32_t masterClock) inline void UART3_Configure(uint32_t baudrate, uint32_t masterClock)
{ {
register Uart *pUart = BT_USART; Uart *pUart = BT_USART;
/* Configure PIO */ /* Configure PIO */
configure_pins( (PIO_PB2 | PIO_PB3), PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTB | PIN_NO_PULLUP ) ; configure_pins( (PIO_PB2 | PIO_PB3), PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTB | PIN_NO_PULLUP ) ;
@ -139,7 +139,7 @@ void UART3_Stop()
// This was 6 MHz, we may need to slow it to TIMER_CLOCK2 (MCK/8=4.5 MHz) // This was 6 MHz, we may need to slow it to TIMER_CLOCK2 (MCK/8=4.5 MHz)
inline void start_timer0() inline void start_timer0()
{ {
register Tc *ptc ; Tc *ptc ;
// Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28
PMC->PMC_PCER0 |= 0x00800000L ; // Enable peripheral clock to TC0 PMC->PMC_PCER0 |= 0x00800000L ; // Enable peripheral clock to TC0
@ -158,8 +158,8 @@ inline void start_timer0()
// Starts TIMER2 at 200Hz, commentd out drive of TIOA2 (A26, EXT2) // Starts TIMER2 at 200Hz, commentd out drive of TIOA2 (A26, EXT2)
inline void start_timer2() inline void start_timer2()
{ {
register Tc *ptc ; Tc *ptc ;
register uint32_t timer ; uint32_t timer ;
// Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28
PMC->PMC_PCER0 |= 0x02000000L ; // Enable peripheral clock to TC2 PMC->PMC_PCER0 |= 0x02000000L ; // Enable peripheral clock to TC2
@ -195,7 +195,7 @@ void interrupt5ms()
extern "C" void TC2_IRQHandler() extern "C" void TC2_IRQHandler()
{ {
register uint32_t dummy; uint32_t dummy;
/* Clear status bit to acknowledge interrupt */ /* Clear status bit to acknowledge interrupt */
dummy = TC0->TC_CHANNEL[2].TC_SR; dummy = TC0->TC_CHANNEL[2].TC_SR;
@ -220,8 +220,8 @@ extern "C" void TC2_IRQHandler()
// For testing, just drive it out with PWM // For testing, just drive it out with PWM
void init_pwm() void init_pwm()
{ {
register Pwm *pwmptr ; Pwm *pwmptr ;
register uint32_t timer ; uint32_t timer ;
PMC->PMC_PCER0 |= ( 1 << ID_PWM ) ; // Enable peripheral clock to PWM PMC->PMC_PCER0 |= ( 1 << ID_PWM ) ; // Enable peripheral clock to PWM
@ -229,7 +229,7 @@ void init_pwm()
/* Configure PIO */ /* Configure PIO */
#if defined(REVA) #if defined(REVA)
register Pio *pioptr = PIOB ; Pio *pioptr = PIOB ;
pioptr->PIO_PER = 0x00000020L ; // Enable bit B5 pioptr->PIO_PER = 0x00000020L ; // Enable bit B5
pioptr->PIO_ODR = 0x00000020L ; // set as input pioptr->PIO_ODR = 0x00000020L ; // set as input
#else #else
@ -299,7 +299,7 @@ void init_pwm()
void configure_pins( uint32_t pins, uint16_t config ) void configure_pins( uint32_t pins, uint16_t config )
{ {
register Pio *pioptr ; Pio *pioptr ;
pioptr = PIOA + ( ( config & PIN_PORT_MASK ) >> 6) ; pioptr = PIOA + ( ( config & PIN_PORT_MASK ) >> 6) ;
if ( config & PIN_PULLUP ) if ( config & PIN_PULLUP )
@ -374,8 +374,8 @@ void opentxBootloader();
#if !defined(AR9X) #if !defined(AR9X)
void i2cInit() void i2cInit()
{ {
register Pio *pioptr; Pio *pioptr;
register uint32_t timing; uint32_t timing;
PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0
@ -410,7 +410,7 @@ void boardInit()
} }
} }
register Pio *pioptr ; Pio *pioptr ;
ResetReason = RSTC->RSTC_SR; ResetReason = RSTC->RSTC_SR;
@ -547,7 +547,7 @@ uint8_t getTemperature()
void setSticksGain(uint8_t gains) void setSticksGain(uint8_t gains)
{ {
register Adc *padc ; Adc *padc ;
uint32_t gain ; uint32_t gain ;
uint32_t offset ; uint32_t offset ;

View file

@ -111,8 +111,8 @@ static uint32_t BOARD_ConfigurePmc(void)
#undef CLOCK_TIMEOUT #undef CLOCK_TIMEOUT
#define CLOCK_TIMEOUT 0xFFFFFFFF #define CLOCK_TIMEOUT 0xFFFFFFFF
register uint32_t timeout = 0 ; uint32_t timeout = 0 ;
register Pmc *pmcptr ; Pmc *pmcptr ;
pmcptr = PMC ; pmcptr = PMC ;
@ -179,8 +179,8 @@ static uint32_t BOARD_ConfigurePmc(void)
void revert_osc() void revert_osc()
{ {
register uint32_t timeout = 0; uint32_t timeout = 0;
register Pmc *pmcptr; Pmc *pmcptr;
pmcptr = PMC; pmcptr = PMC;

View file

@ -1,23 +1,23 @@
/* /*
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#define __CRT_C__ #define __CRT_C__
#include <stdint.h> #include <stdint.h>
@ -71,9 +71,9 @@ extern uint32_t Master_frequency ;
void ResetHandler (void) void ResetHandler (void)
{ {
{ {
register uint32_t *pSrc; uint32_t *pSrc;
register uint32_t *pDest; uint32_t *pDest;
register uint32_t m_freq ; uint32_t m_freq ;
/* /*
* Call the SystemInit code from CMSIS interface if available. * Call the SystemInit code from CMSIS interface if available.

View file

@ -28,10 +28,10 @@ uint8_t eepromIsTransferComplete()
return Spi_complete; return Spi_complete;
} }
uint32_t eepromTransmitData(register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count) uint32_t eepromTransmitData(uint8_t *command, uint8_t *tx, uint8_t *rx, uint32_t comlen, uint32_t count)
{ {
register Spi * spiptr = SPI; Spi * spiptr = SPI;
register uint32_t condition; uint32_t condition;
static uint8_t discard_rx_command[4]; static uint8_t discard_rx_command[4];
if (comlen > 4) { if (comlen > 4) {
@ -76,8 +76,8 @@ uint32_t eepromTransmitData(register uint8_t *command, register uint8_t *tx, reg
uint8_t eepromTransmitByte(uint8_t out, bool skipFirst) uint8_t eepromTransmitByte(uint8_t out, bool skipFirst)
{ {
register Spi * spiptr = SPI; Spi * spiptr = SPI;
register uint32_t delay; uint32_t delay;
spiptr->SPI_CR = 1; // Enable spiptr->SPI_CR = 1; // Enable
(void) spiptr->SPI_RDR; // Dump any rx data (void) spiptr->SPI_RDR; // Dump any rx data
@ -172,8 +172,8 @@ void eepromBlockErase(uint32_t address)
// Set clock to 3 MHz, AT25 device is rated to 70MHz, 18MHz would be better // Set clock to 3 MHz, AT25 device is rated to 70MHz, 18MHz would be better
void eepromInit() void eepromInit()
{ {
register Spi * spiptr = SPI; Spi * spiptr = SPI;
register uint32_t timer; uint32_t timer;
PMC->PMC_PCER0 |= 0x00200000L; // Enable peripheral clock to SPI PMC->PMC_PCER0 |= 0x00200000L; // Enable peripheral clock to SPI
/* Configure PIO */ /* Configure PIO */
@ -190,7 +190,7 @@ void eepromInit()
extern "C" void SPI_IRQHandler() extern "C" void SPI_IRQHandler()
{ {
register Spi * spiptr = SPI; Spi * spiptr = SPI;
SPI->SPI_IDR = 0x07FF; // All interrupts off SPI->SPI_IDR = 0x07FF; // All interrupts off
spiptr->SPI_CR = 2; // Disable spiptr->SPI_CR = 2; // Disable
(void) spiptr->SPI_RDR; // Dump any rx data (void) spiptr->SPI_RDR; // Dump any rx data

View file

@ -30,7 +30,7 @@ void hapticOff()
// pwmPercent 0-100 // pwmPercent 0-100
void hapticOn( uint32_t pwmPercent ) void hapticOn( uint32_t pwmPercent )
{ {
register Pwm *pwmptr ; Pwm *pwmptr ;
pwmptr = PWM ; pwmptr = PWM ;

View file

@ -51,7 +51,7 @@ bool i2cInit()
//Enable Peripheral Clock //Enable Peripheral Clock
PMC->PMC_PCER0 |= 0x00080000L; PMC->PMC_PCER0 |= 0x00080000L;
//Enable TWI PIOs //Enable TWI PIOs
register Pio *pioptr; Pio *pioptr;
pioptr = PIOA; pioptr = PIOA;
pioptr->PIO_ABCDSR[0] &= ~0x00000018; // Peripheral A pioptr->PIO_ABCDSR[0] &= ~0x00000018; // Peripheral A
pioptr->PIO_ABCDSR[1] &= ~0x00000018; // Peripheral A pioptr->PIO_ABCDSR[1] &= ~0x00000018; // Peripheral A

View file

@ -32,8 +32,8 @@
// LCD pins 5 DOWN, 4 RIGHT, 3 LEFT, 1 UP // LCD pins 5 DOWN, 4 RIGHT, 3 LEFT, 1 UP
uint32_t readKeys() uint32_t readKeys()
{ {
register uint32_t x; uint32_t x;
register uint32_t result = 0; uint32_t result = 0;
x = lcdLock ? lcdInputs : PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () x = lcdLock ? lcdInputs : PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP ()
x = ~x; x = ~x;
@ -73,7 +73,7 @@ uint32_t readKeys()
uint32_t readTrims() uint32_t readTrims()
{ {
register uint32_t result = 0; uint32_t result = 0;
if (~TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL) if (~TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL)
result |= 0x01; result |= 0x01;
@ -107,7 +107,7 @@ uint8_t keyDown()
void readKeysAndTrims() void readKeysAndTrims()
{ {
register uint32_t i; uint32_t i;
#if ROTARY_ENCODERS > 0 #if ROTARY_ENCODERS > 0
keys[BTN_REa].input(REA_DOWN()); keys[BTN_REa].input(REA_DOWN());
@ -135,8 +135,8 @@ uint8_t keyState(uint8_t index)
uint32_t switchState(uint8_t index) uint32_t switchState(uint8_t index)
{ {
register uint32_t a = PIOA->PIO_PDSR; uint32_t a = PIOA->PIO_PDSR;
register uint32_t c = PIOC->PIO_PDSR; uint32_t c = PIOC->PIO_PDSR;
uint32_t xxx = 0; uint32_t xxx = 0;

View file

@ -71,7 +71,7 @@ const uint8_t Lcd_lookup[] =
void lcdSendCtl(uint8_t val) void lcdSendCtl(uint8_t val)
{ {
register Pio *pioptr; Pio *pioptr;
#if defined(REVA) #if defined(REVA)
pioptr = PIOC; pioptr = PIOC;
@ -112,7 +112,7 @@ void lcdSendCtl(uint8_t val)
void lcdInit() void lcdInit()
{ {
register Pio *pioptr; Pio *pioptr;
// /home/thus/txt/datasheets/lcd/KS0713.pdf // /home/thus/txt/datasheets/lcd/KS0713.pdf
// ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid=
@ -191,7 +191,7 @@ void lcdInit()
void lcdSetRefVolt(uint8_t val) void lcdSetRefVolt(uint8_t val)
{ {
register Pio *pioptr; Pio *pioptr;
pioptr = PIOC; pioptr = PIOC;
// read the inputs, and lock the LCD lines // read the inputs, and lock the LCD lines
@ -221,14 +221,14 @@ void lcdSetRefVolt(uint8_t val)
void lcdRefresh() void lcdRefresh()
{ {
register Pio *pioptr; Pio *pioptr;
register uint8_t *p = displayBuf; uint8_t *p = displayBuf;
register uint32_t y; uint32_t y;
register uint32_t x; uint32_t x;
register uint32_t z; uint32_t z;
register uint32_t ebit; uint32_t ebit;
#if defined(REVA) #if defined(REVA)
register uint8_t *lookup; uint8_t *lookup;
lookup = (uint8_t *) Lcd_lookup; lookup = (uint8_t *) Lcd_lookup;
#endif #endif

View file

@ -22,7 +22,7 @@
void setExternalModulePolarity() void setExternalModulePolarity()
{ {
register Pwm * pwmptr = PWM; Pwm * pwmptr = PWM;
pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = GET_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS pwmptr->PWM_CH_NUM[3].PWM_CDTYUPD = GET_PPM_DELAY(EXTERNAL_MODULE) * 2; // Duty in half uS
if (GET_PPM_POLARITY(EXTERNAL_MODULE)) if (GET_PPM_POLARITY(EXTERNAL_MODULE))
pwmptr->PWM_CH_NUM[3].PWM_CMR &= ~0x00000200; // CPOL pwmptr->PWM_CH_NUM[3].PWM_CMR &= ~0x00000200; // CPOL
@ -32,7 +32,7 @@ void setExternalModulePolarity()
void setExtraModulePolarity() void setExtraModulePolarity()
{ {
register Pwm * pwmptr = PWM; Pwm * pwmptr = PWM;
pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE) * 2; // Duty in half uS pwmptr->PWM_CH_NUM[1].PWM_CDTYUPD = GET_PPM_DELAY(EXTRA_MODULE) * 2; // Duty in half uS
if (GET_PPM_POLARITY(EXTRA_MODULE)) if (GET_PPM_POLARITY(EXTRA_MODULE))
pwmptr->PWM_CH_NUM[1].PWM_CMR &= ~0x00000200; // CPOL pwmptr->PWM_CH_NUM[1].PWM_CMR &= ~0x00000200; // CPOL
@ -42,7 +42,7 @@ void setExtraModulePolarity()
void module_output_active() void module_output_active()
{ {
register Pio *pioptr = PIOA; Pio *pioptr = PIOA;
pioptr->PIO_ABCDSR[0] &= ~PIO_PA17; // Peripheral C pioptr->PIO_ABCDSR[0] &= ~PIO_PA17; // Peripheral C
pioptr->PIO_ABCDSR[1] |= PIO_PA17; // Peripheral C pioptr->PIO_ABCDSR[1] |= PIO_PA17; // Peripheral C
pioptr->PIO_PDR = PIO_PA17; // Disable bit A17 Assign to peripheral pioptr->PIO_PDR = PIO_PA17; // Disable bit A17 Assign to peripheral
@ -61,7 +61,7 @@ void module_output_active()
void init_main_ppm(uint32_t period, uint32_t out_enable) void init_main_ppm(uint32_t period, uint32_t out_enable)
{ {
register Pwm * pwmptr; Pwm * pwmptr;
setupPulsesPPMModule(EXTERNAL_MODULE); setupPulsesPPMModule(EXTERNAL_MODULE);
@ -86,7 +86,7 @@ void init_main_ppm(uint32_t period, uint32_t out_enable)
void disable_main_ppm() void disable_main_ppm()
{ {
register Pio * pioptr = PIOA; Pio * pioptr = PIOA;
pioptr->PIO_PER = PIO_PA17; // Assign A17 to PIO pioptr->PIO_PER = PIO_PA17; // Assign A17 to PIO
PWM->PWM_IDR1 = PWM_IDR1_CHID3; PWM->PWM_IDR1 = PWM_IDR1_CHID3;
} }
@ -95,7 +95,7 @@ void init_second_ppm(uint32_t period)
{ {
#if !defined(REVA) #if !defined(REVA)
// PWM1 for PPM2 // PWM1 for PPM2
register Pwm * pwmptr = PWM; Pwm * pwmptr = PWM;
configure_pins(PIO_PC15, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_NO_PULLUP ); configure_pins(PIO_PC15, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_NO_PULLUP );
pwmptr->PWM_CH_NUM[1].PWM_CMR = 0x0000000B; // CLKB pwmptr->PWM_CH_NUM[1].PWM_CMR = 0x0000000B; // CLKB
if (!GET_PPM_POLARITY(EXTRA_MODULE)) { if (!GET_PPM_POLARITY(EXTRA_MODULE)) {
@ -113,7 +113,7 @@ void init_second_ppm(uint32_t period)
void disable_second_ppm() void disable_second_ppm()
{ {
#if !defined(REVA) #if !defined(REVA)
register Pio * pioptr = PIOC; Pio * pioptr = PIOC;
pioptr->PIO_PER = PIO_PC15; // Assign C17 to PIO pioptr->PIO_PER = PIO_PC15; // Assign C17 to PIO
PWM->PWM_IDR1 = PWM_IDR1_CHID1; PWM->PWM_IDR1 = PWM_IDR1_CHID1;
#endif #endif
@ -163,7 +163,7 @@ void disable_ppm(uint32_t port)
// TD is on PA17, peripheral A // TD is on PA17, peripheral A
void init_ssc() void init_ssc()
{ {
register Ssc * sscptr; Ssc * sscptr;
PMC->PMC_PCER0 |= 0x00400000L; // Enable peripheral clock to SSC PMC->PMC_PCER0 |= 0x00400000L; // Enable peripheral clock to SSC
@ -185,8 +185,8 @@ void init_ssc()
void disable_ssc() void disable_ssc()
{ {
register Pio *pioptr; Pio *pioptr;
register Ssc *sscptr; Ssc *sscptr;
// Revert back to pwm output // Revert back to pwm output
pioptr = PIOA; pioptr = PIOA;
@ -243,7 +243,7 @@ void disable_dsm2(uint32_t port)
#if !defined(SIMU) #if !defined(SIMU)
extern "C" void PWM_IRQHandler(void) extern "C" void PWM_IRQHandler(void)
{ {
register Pwm * pwmptr = PWM; Pwm * pwmptr = PWM;
uint32_t reason = pwmptr->PWM_ISR1; uint32_t reason = pwmptr->PWM_ISR1;
uint32_t period; uint32_t period;
@ -266,7 +266,7 @@ extern "C" void PWM_IRQHandler(void)
} }
else { else {
// Kick off serial output here // Kick off serial output here
register Ssc * sscptr = SSC; Ssc * sscptr = SSC;
sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.pulses); sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.pulses);
sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].pxx.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].pxx.pulses; sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].pxx.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].pxx.pulses;
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers
@ -290,7 +290,7 @@ extern "C" void PWM_IRQHandler(void)
} }
else { else {
// Kick off serial output here // Kick off serial output here
register Ssc * sscptr = SSC; Ssc * sscptr = SSC;
sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses); sscptr->SSC_TPR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses);
sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.pulses; sscptr->SSC_TCR = (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - (uint8_t *)modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers sscptr->SSC_PTCR = SSC_PTCR_TXTEN; // Start transfers

View file

@ -37,7 +37,7 @@ void rotencEnd()
volatile uint32_t Rotary_position ; volatile uint32_t Rotary_position ;
extern "C" void PIOC_IRQHandler() extern "C" void PIOC_IRQHandler()
{ {
register uint32_t dummy; uint32_t dummy;
dummy = PIOC->PIO_ISR ; // Read and clear status register dummy = PIOC->PIO_ISR ; // Read and clear status register
(void) dummy ; // Discard value - prevents compiler warning (void) dummy ; // Discard value - prevents compiler warning

View file

@ -62,7 +62,7 @@ uint8_t serial2TracesEnabled()
*/ */
void SECOND_UART_Configure(uint32_t baudrate, uint32_t masterClock) void SECOND_UART_Configure(uint32_t baudrate, uint32_t masterClock)
{ {
register Uart *pUart = SECOND_SERIAL_UART; Uart *pUart = SECOND_SERIAL_UART;
/* Configure PIO */ /* Configure PIO */
configure_pins( (PIO_PA9 | PIO_PA10), PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTA | PIN_NO_PULLUP ) ; configure_pins( (PIO_PA9 | PIO_PA10), PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTA | PIN_NO_PULLUP ) ;

View file

@ -36,7 +36,7 @@ uint16_t DsmRxTimeout;
// Uses PA5 and PA6 (RXD and TXD) // Uses PA5 and PA6 (RXD and TXD)
void UART2_Configure(uint32_t baudrate, uint32_t masterClock, int mode) void UART2_Configure(uint32_t baudrate, uint32_t masterClock, int mode)
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
// Configure PIO // Configure PIO
configure_pins( (PIO_PA5 | PIO_PA6), PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTA | PIN_NO_PULLUP ) ; configure_pins( (PIO_PA5 | PIO_PA6), PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTA | PIN_NO_PULLUP ) ;
@ -66,7 +66,7 @@ void UART2_Configure(uint32_t baudrate, uint32_t masterClock, int mode)
void UART2_timeout_enable() void UART2_timeout_enable()
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
pUsart->US_CR = US_CR_STTTO ; pUsart->US_CR = US_CR_STTTO ;
pUsart->US_RTOR = 115 ; // Bits @ 115200 ~= 1mS pUsart->US_RTOR = 115 ; // Bits @ 115200 ~= 1mS
pUsart->US_IER = US_IER_TIMEOUT ; pUsart->US_IER = US_IER_TIMEOUT ;
@ -76,7 +76,7 @@ void UART2_timeout_enable()
void UART2_timeout_disable() void UART2_timeout_disable()
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
pUsart->US_RTOR = 0 ; pUsart->US_RTOR = 0 ;
pUsart->US_IDR = US_IDR_TIMEOUT ; pUsart->US_IDR = US_IDR_TIMEOUT ;
NVIC_DisableIRQ(USART0_IRQn); NVIC_DisableIRQ(USART0_IRQn);
@ -84,14 +84,14 @@ void UART2_timeout_disable()
extern "C" void USART0_IRQHandler() extern "C" void USART0_IRQHandler()
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
pUsart->US_CR = US_CR_STTTO ; // Clears timeout bit pUsart->US_CR = US_CR_STTTO ; // Clears timeout bit
DsmRxTimeout = 1; DsmRxTimeout = 1;
} }
void startPdcUsartReceive() void startPdcUsartReceive()
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
TelemetryInBuffer.outPtr = TelemetryInBuffer.fifo ; TelemetryInBuffer.outPtr = TelemetryInBuffer.fifo ;
#ifndef SIMU #ifndef SIMU
pUsart->US_RPR = (uint32_t)TelemetryInBuffer.fifo ; pUsart->US_RPR = (uint32_t)TelemetryInBuffer.fifo ;
@ -105,7 +105,7 @@ void startPdcUsartReceive()
void rxPdcUsart( void (*pChProcess)(uint8_t x) ) void rxPdcUsart( void (*pChProcess)(uint8_t x) )
{ {
#if !defined(SIMU) #if !defined(SIMU)
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
uint8_t *ptr ; uint8_t *ptr ;
uint8_t *endPtr ; uint8_t *endPtr ;
@ -137,7 +137,7 @@ void rxPdcUsart( void (*pChProcess)(uint8_t x) )
uint32_t txPdcUsart(uint8_t *buffer, uint32_t size) uint32_t txPdcUsart(uint8_t *buffer, uint32_t size)
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
if ( pUsart->US_TNCR == 0 ) if ( pUsart->US_TNCR == 0 )
{ {
@ -153,7 +153,7 @@ uint32_t txPdcUsart(uint8_t *buffer, uint32_t size)
uint32_t telemetryTransmitPending() uint32_t telemetryTransmitPending()
{ {
register Usart *pUsart = SECOND_USART; Usart *pUsart = SECOND_USART;
uint32_t x ; uint32_t x ;
__disable_irq() ; __disable_irq() ;

View file

@ -23,7 +23,7 @@
// Start TIMER3 for input capture // Start TIMER3 for input capture
inline void start_timer3() inline void start_timer3()
{ {
register Tc *ptc ; Tc *ptc ;
// Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28
PMC->PMC_PCER0 |= 0x04000000L ; // Enable peripheral clock to TC3 PMC->PMC_PCER0 |= 0x04000000L ; // Enable peripheral clock to TC3
@ -45,8 +45,8 @@ inline void start_timer3()
// Start Timer4 to provide 0.5uS clock for input capture // Start Timer4 to provide 0.5uS clock for input capture
void start_timer4() void start_timer4()
{ {
register Tc *ptc ; Tc *ptc ;
register uint32_t timer ; uint32_t timer ;
timer = Master_frequency / (2*2000000) ; // MCK/2 and 2MHz timer = Master_frequency / (2*2000000) ; // MCK/2 and 2MHz

View file

@ -57,8 +57,12 @@ elseif(PCB STREQUAL X7D)
set(HAPTIC YES) set(HAPTIC YES)
set(LUA_EXPORT lua_export_taranis) set(LUA_EXPORT lua_export_taranis)
set(FLAVOUR x7d) set(FLAVOUR x7d)
add_definitions(-DPCBX7D) add_definitions(-DPCBX7D -DSOFTWARE_VOLUME)
add_definitions(-DEEPROM_VARIANT=0) add_definitions(-DEEPROM_VARIANT=0)
set(FIRMWARE_TARGET_SRC
${FIRMWARE_TARGET_SRC}
bluetooth_driver.cpp
)
set(GUI_DIR 128x64) set(GUI_DIR 128x64)
set(BITMAPS_TARGET 9x_bitmaps) set(BITMAPS_TARGET 9x_bitmaps)
set(LCD_DRIVER lcd_driver_spi.cpp) set(LCD_DRIVER lcd_driver_spi.cpp)

View file

@ -31,7 +31,7 @@
#elif defined(PCBX9DP) #elif defined(PCBX9DP)
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1,-1, -1,1, 1}; const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1,-1, -1,1, 1};
#elif defined(PCBX7D) #elif defined(PCBX7D)
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1, 1}; const int8_t ana_direction[NUMBER_ANALOG] = {-1,1,-1,1, 1,1, 1};
#elif defined(REV4a) #elif defined(REV4a)
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,-1,0, -1,1, 1}; const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,-1,0, -1,1, 1};
#else #else
@ -40,14 +40,14 @@
#if defined(PCBX9E) #if defined(PCBX9E)
#define NUMBER_ANALOG_ADC1 10 #define NUMBER_ANALOG_ADC1 10
#define NUMBER_ANALOG_ADC3 3 #define NUMBER_ANALOG_ADC3 (NUMBER_ANALOG - 10)
// mapping from adcValues order to enum Analogs // mapping from adcValues order to enum Analogs
const uint8_t ana_mapping[NUMBER_ANALOG] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/, const uint8_t ana_mapping[NUMBER_ANALOG] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/,
10 /*POT1*/, 4 /*POT2*/, 5 /*POT3*/, 6 /*POT4*/, 10 /*POT1*/, 4 /*POT2*/, 5 /*POT3*/, 6 /*POT4*/,
11 /*SLIDER1*/, 12 /*SLIDER2*/, 7 /*SLIDER3*/, 8 /*SLIDER4*/, 11 /*SLIDER1*/, 12 /*SLIDER2*/, 7 /*SLIDER3*/, 8 /*SLIDER4*/,
9 /*TX_VOLTAGE*/ }; 9 /*TX_VOLTAGE*/ };
#else #else
#define NUMBER_ANALOG_ADC1 10 #define NUMBER_ANALOG_ADC1 NUMBER_ANALOG
#endif #endif
uint16_t adcValues[NUMBER_ANALOG] __DMA; uint16_t adcValues[NUMBER_ANALOG] __DMA;
@ -79,6 +79,9 @@ void adcInit()
#if defined(PCBX9E) #if defined(PCBX9E)
ADC1->SQR2 = (ADC_CHANNEL_POT4<<0) + (ADC_CHANNEL_SLIDER3<<5) + (ADC_CHANNEL_SLIDER4<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more ADC1->SQR2 = (ADC_CHANNEL_POT4<<0) + (ADC_CHANNEL_SLIDER3<<5) + (ADC_CHANNEL_SLIDER4<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more
ADC1->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT2<<20) + (ADC_CHANNEL_POT3<<25); // conversions 1 to 6 ADC1->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT2<<20) + (ADC_CHANNEL_POT3<<25); // conversions 1 to 6
#elif defined(PCBX7D)
ADC1->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more
ADC1->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<25) + (ADC_CHANNEL_POT2<<20); // conversions 1 to 6
#else #else
ADC1->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more ADC1->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more
ADC1->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 ADC1->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6

View file

@ -21,11 +21,11 @@
#include "opentx.h" #include "opentx.h"
#if !defined(SIMU) #if !defined(SIMU)
bool dacIdle = true; const AudioBuffer * nextBuffer = 0;
void setSampleRate(uint32_t frequency) void setSampleRate(uint32_t frequency)
{ {
register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz
AUDIO_TIMER->CR1 &= ~TIM_CR1_CEN ; AUDIO_TIMER->CR1 &= ~TIM_CR1_CEN ;
AUDIO_TIMER->CNT = 0 ; AUDIO_TIMER->CNT = 0 ;
@ -77,22 +77,22 @@ void dacInit()
NVIC_SetPriority(AUDIO_DMA_Stream_IRQn, 7); NVIC_SetPriority(AUDIO_DMA_Stream_IRQn, 7);
} }
void audioPushBuffer(AudioBuffer * buffer) void audioConsumeCurrentBuffer()
{ {
if (dacIdle) { if (nextBuffer == 0) {
dacIdle = false;
buffer->state = AUDIO_BUFFER_PLAYING; nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer();
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel if (nextBuffer) {
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(buffer->data); AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
AUDIO_DMA_Stream->NDTR = buffer->size; AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(nextBuffer->data);
AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt AUDIO_DMA_Stream->NDTR = nextBuffer->size;
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
} DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
else { }
buffer->state = AUDIO_BUFFER_FILLED;
} }
} }
void dacStart() void dacStart()
@ -140,7 +140,9 @@ extern "C" void AUDIO_DMA_Stream_IRQHandler()
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
AudioBuffer * nextBuffer = audioQueue.getNextFilledBuffer(); if (nextBuffer) audioQueue.buffersFifo.freeNextFilledBuffer();
nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer();
if (nextBuffer) { if (nextBuffer) {
AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(nextBuffer->data); AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(nextBuffer->data);
AUDIO_DMA_Stream->NDTR = nextBuffer->size; AUDIO_DMA_Stream->NDTR = nextBuffer->size;
@ -148,8 +150,5 @@ extern "C" void AUDIO_DMA_Stream_IRQHandler()
AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel
DAC->SR = DAC_SR_DMAUDR1; // Write 1 to clear flag DAC->SR = DAC_SR_DMAUDR1; // Write 1 to clear flag
} }
else {
dacIdle = true;
}
} }
#endif // #if !defined(SIMU) #endif // #if !defined(SIMU)

View file

@ -51,22 +51,26 @@ void bluetoothInit(uint32_t baudrate)
RCC_AHB1PeriphClockCmd(BT_RCC_AHB1Periph, ENABLE); RCC_AHB1PeriphClockCmd(BT_RCC_AHB1Periph, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
GPIO_InitStructure.GPIO_Pin = BT_BRTS_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = BT_EN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(BT_BRTS_GPIO, &GPIO_InitStructure);
GPIO_SetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = BT_EN_GPIO_PIN;
GPIO_Init(BT_EN_GPIO, &GPIO_InitStructure); GPIO_Init(BT_EN_GPIO, &GPIO_InitStructure);
#if defined(BT_BRTS_GPIO_PIN)
GPIO_InitStructure.GPIO_Pin = BT_BRTS_GPIO_PIN;
GPIO_Init(BT_BRTS_GPIO, &GPIO_InitStructure);
GPIO_SetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
#endif
#if defined(BT_BCTS_GPIO_PIN)
GPIO_InitStructure.GPIO_Pin = BT_BCTS_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = BT_BCTS_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(BT_BCTS_GPIO, &GPIO_InitStructure); GPIO_Init(BT_BCTS_GPIO, &GPIO_InitStructure);
#endif
GPIO_InitStructure.GPIO_Pin = BT_TX_GPIO_PIN|BT_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = BT_TX_GPIO_PIN|BT_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
@ -144,7 +148,9 @@ void bluetoothWriteWakeup(void)
if (bluetoothWriteState == BLUETOOTH_WRITE_IDLE) { if (bluetoothWriteState == BLUETOOTH_WRITE_IDLE) {
if (!btTxFifo.isEmpty()) { if (!btTxFifo.isEmpty()) {
bluetoothWriteState = BLUETOOTH_WRITE_INIT; bluetoothWriteState = BLUETOOTH_WRITE_INIT;
#if defined(BT_BRTS_GPIO_PIN)
GPIO_ResetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN); GPIO_ResetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
#endif
} }
} }
else if (bluetoothWriteState == BLUETOOTH_WRITE_INIT) { else if (bluetoothWriteState == BLUETOOTH_WRITE_INIT) {
@ -153,7 +159,9 @@ void bluetoothWriteWakeup(void)
} }
else if (bluetoothWriteState == BLUETOOTH_WRITE_DONE) { else if (bluetoothWriteState == BLUETOOTH_WRITE_DONE) {
bluetoothWriteState = BLUETOOTH_WRITE_IDLE; bluetoothWriteState = BLUETOOTH_WRITE_IDLE;
#if defined(BT_BRTS_GPIO_PIN)
GPIO_SetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN); GPIO_SetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
#endif
} }
} }

View file

@ -143,7 +143,7 @@ void boardInit()
hapticInit(); hapticInit();
#endif #endif
#if defined(PCBX9E) #if defined(PCBX9E) || defined(PCBX7D)
bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE); bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@
#include "stamp.h" #include "stamp.h"
#define BOOTLOADER_TITLE " Taranis BootLoader - " VERSION #define BOOTLOADER_TITLE " Taranis BootLoader - " VERSION
#if defined(PCBX9E) #if defined(PCBX9E) || defined(PCBX7D)
#define BOOT_KEY_UP KEY_MINUS #define BOOT_KEY_UP KEY_MINUS
#define BOOT_KEY_DOWN KEY_PLUS #define BOOT_KEY_DOWN KEY_PLUS
#else #else
@ -83,7 +83,7 @@ FIL FlashFile;
DIR Dj; DIR Dj;
FILINFO Finfo; FILINFO Finfo;
TCHAR Filenames[20][50]; TCHAR Filenames[20][_MAX_LFN + 1];
uint32_t FileSize[20]; uint32_t FileSize[20];
uint32_t Valid; uint32_t Valid;
@ -126,19 +126,19 @@ void interrupt10ms(void)
void init10msTimer() void init10msTimer()
{ {
TIM14->ARR = 9999; // 10mS INTERRUPT_5MS_TIMER->ARR = 9999; // 10mS
TIM14->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS from 12MHz INTERRUPT_5MS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS from 12MHz
TIM14->CCER = 0; INTERRUPT_5MS_TIMER->CCER = 0;
TIM14->CCMR1 = 0; INTERRUPT_5MS_TIMER->CCMR1 = 0;
TIM14->EGR = 0; INTERRUPT_5MS_TIMER->EGR = 0;
TIM14->CR1 = 5; INTERRUPT_5MS_TIMER->CR1 = 5;
TIM14->DIER |= 1; INTERRUPT_5MS_TIMER->DIER |= 1;
NVIC_EnableIRQ(TIM8_TRG_COM_TIM14_IRQn); NVIC_EnableIRQ(INTERRUPT_5MS_IRQn);
} }
extern "C" void TIM8_TRG_COM_TIM14_IRQHandler() extern "C" void INTERRUPT_5MS_IRQHandler()
{ {
TIM14->SR &= ~TIM_SR_UIF; INTERRUPT_5MS_TIMER->SR &= ~TIM_SR_UIF;
interrupt10ms(); interrupt10ms();
} }
@ -153,23 +153,20 @@ FRESULT readBinDir(DIR *dj, FILINFO *fno)
if (fr != FR_OK || fno->fname[0] == 0) { if (fr != FR_OK || fno->fname[0] == 0) {
break; break;
} }
if (*fno->lfname == 0) { int32_t len = strlen(fno->fname) - 4;
strAppend(fno->lfname, fno->fname); // Copy 8.3 name
}
int32_t len = strlen(fno->lfname) - 4;
if (len < 0) { if (len < 0) {
loop = 1; loop = 1;
} }
if (fno->lfname[len] != '.') { if (fno->fname[len] != '.') {
loop = 1; loop = 1;
} }
if ((fno->lfname[len + 1] != 'b') && (fno->lfname[len + 1] != 'B')) { if ((fno->fname[len + 1] != 'b') && (fno->fname[len + 1] != 'B')) {
loop = 1; loop = 1;
} }
if ((fno->lfname[len + 2] != 'i') && (fno->lfname[len + 2] != 'I')) { if ((fno->fname[len + 2] != 'i') && (fno->fname[len + 2] != 'I')) {
loop = 1; loop = 1;
} }
if ((fno->lfname[len + 3] != 'n') && (fno->lfname[len + 3] != 'N')) { if ((fno->fname[len + 3] != 'n') && (fno->fname[len + 3] != 'N')) {
loop = 1; loop = 1;
} }
@ -181,27 +178,22 @@ uint32_t fillNames(uint32_t index)
{ {
uint32_t i; uint32_t i;
FRESULT fr; FRESULT fr;
Finfo.lfname = Filenames[0];
Finfo.lfsize = 48;
fr = f_readdir(&Dj, 0); // rewind fr = f_readdir(&Dj, 0); // rewind
fr = f_readdir(&Dj, &Finfo); // Skip . for (i = 0; i <= index; ++i) {
fr = f_readdir(&Dj, &Finfo); // Skip ..
i = 0;
while (i <= index) {
fr = readBinDir(&Dj, &Finfo); // First entry fr = readBinDir(&Dj, &Finfo); // First entry
FileSize[0] = Finfo.fsize;
i += 1;
if (fr == FR_NO_FILE) { if (fr == FR_NO_FILE) {
return 0; return 0;
} }
} }
strAppend(Filenames[0], Finfo.fname);
FileSize[0] = Finfo.fsize;
for (i = 1; i < 7; i += 1) { for (i = 1; i < 7; i += 1) {
Finfo.lfname = Filenames[i]; fr = readBinDir(&Dj, &Finfo);
fr = readBinDir(&Dj, &Finfo); // First entry
FileSize[i] = Finfo.fsize;
if (fr != FR_OK || Finfo.fname[0] == 0) { if (fr != FR_OK || Finfo.fname[0] == 0) {
break; break;
} }
strAppend(Filenames[i], Finfo.fname);
FileSize[i] = Finfo.fsize;
} }
return i; return i;
} }

View file

@ -24,11 +24,11 @@
// Keys // Keys
#if defined(PCBX7D) #if defined(PCBX7D)
#define KEYS_GPIO_REG_PAGE GPIOD->IDR #define KEYS_GPIO_REG_PAGE GPIOD->IDR
#define KEYS_GPIO_PIN_PAGE GPIO_Pin_2 // PD.02 #define KEYS_GPIO_PIN_PAGE GPIO_Pin_3 // PD.03
#define KEYS_GPIO_REG_MENU GPIOD->IDR #define KEYS_GPIO_REG_MENU GPIOD->IDR
#define KEYS_GPIO_PIN_MENU GPIO_Pin_7 // PD.07 #define KEYS_GPIO_PIN_MENU GPIO_Pin_7 // PD.07
#define KEYS_GPIO_REG_EXIT GPIOD->IDR #define KEYS_GPIO_REG_EXIT GPIOD->IDR
#define KEYS_GPIO_PIN_EXIT GPIO_Pin_3 // PD.03 #define KEYS_GPIO_PIN_EXIT GPIO_Pin_2 // PD.02
#else #else
#define KEYS_GPIO_REG_MENU GPIOD->IDR #define KEYS_GPIO_REG_MENU GPIOD->IDR
#define KEYS_GPIO_PIN_MENU GPIO_Pin_7 // PD.07 #define KEYS_GPIO_PIN_MENU GPIO_Pin_7 // PD.07
@ -92,6 +92,23 @@
#define TRIMS_GPIO_PIN_RVU GPIO_Pin_2 // PC.02 #define TRIMS_GPIO_PIN_RVU GPIO_Pin_2 // PC.02
#define TRIMS_GPIO_REG_RHR GPIOC->IDR #define TRIMS_GPIO_REG_RHR GPIOC->IDR
#define TRIMS_GPIO_PIN_RHR GPIO_Pin_13 // PC.13 #define TRIMS_GPIO_PIN_RHR GPIO_Pin_13 // PC.13
#elif defined(PCBX7D)
#define TRIMS_GPIO_REG_LHL GPIOD->IDR
#define TRIMS_GPIO_PIN_LHL GPIO_Pin_15 // PD.15
#define TRIMS_GPIO_REG_LHR GPIOC->IDR
#define TRIMS_GPIO_PIN_LHR GPIO_Pin_1 // PC.01
#define TRIMS_GPIO_REG_LVD GPIOE->IDR
#define TRIMS_GPIO_PIN_LVD GPIO_Pin_6 // PE.06
#define TRIMS_GPIO_REG_LVU GPIOE->IDR
#define TRIMS_GPIO_PIN_LVU GPIO_Pin_5 // PE.05
#define TRIMS_GPIO_REG_RVD GPIOC->IDR
#define TRIMS_GPIO_PIN_RVD GPIO_Pin_3 // PC.03
#define TRIMS_GPIO_REG_RHL GPIOE->IDR
#define TRIMS_GPIO_PIN_RHL GPIO_Pin_3 // PE.03
#define TRIMS_GPIO_REG_RVU GPIOC->IDR
#define TRIMS_GPIO_PIN_RVU GPIO_Pin_2 // PC.02
#define TRIMS_GPIO_REG_RHR GPIOE->IDR
#define TRIMS_GPIO_PIN_RHR GPIO_Pin_4 // PE.04
#else #else
#define TRIMS_GPIO_REG_LHL GPIOE->IDR #define TRIMS_GPIO_REG_LHL GPIOE->IDR
#define TRIMS_GPIO_PIN_LHL GPIO_Pin_4 // PE.04 #define TRIMS_GPIO_PIN_LHL GPIO_Pin_4 // PE.04
@ -147,10 +164,10 @@
#define SWITCHES_GPIO_REG_C_L GPIOF->IDR #define SWITCHES_GPIO_REG_C_L GPIOF->IDR
#define SWITCHES_GPIO_PIN_C_L GPIO_Pin_14 // PF.14 #define SWITCHES_GPIO_PIN_C_L GPIO_Pin_14 // PF.14
#elif defined(PCBX7D) #elif defined(PCBX7D)
#define SWITCHES_GPIO_REG_C_H GPIOD->IDR #define SWITCHES_GPIO_REG_C_H GPIOE->IDR
#define SWITCHES_GPIO_PIN_C_H GPIO_Pin_14 // PD.14 #define SWITCHES_GPIO_PIN_C_H GPIO_Pin_15 // PE.15
#define SWITCHES_GPIO_REG_C_L GPIOD->IDR #define SWITCHES_GPIO_REG_C_L GPIOA->IDR
#define SWITCHES_GPIO_PIN_C_L GPIO_Pin_15 // PD.15 #define SWITCHES_GPIO_PIN_C_L GPIO_Pin_5 // PA.05
#else #else
#define SWITCHES_GPIO_REG_C_H GPIOE->IDR #define SWITCHES_GPIO_REG_C_H GPIOE->IDR
#define SWITCHES_GPIO_PIN_C_H GPIO_Pin_15 // PE.15 #define SWITCHES_GPIO_PIN_C_H GPIO_Pin_15 // PE.15
@ -190,6 +207,9 @@
#if defined(PCBX9E) #if defined(PCBX9E)
#define SWITCHES_GPIO_REG_F GPIOE->IDR #define SWITCHES_GPIO_REG_F GPIOE->IDR
#define SWITCHES_GPIO_PIN_F GPIO_Pin_11 // PE.11 #define SWITCHES_GPIO_PIN_F GPIO_Pin_11 // PE.11
#elif defined(PCBX7D)
#define SWITCHES_GPIO_REG_F GPIOD->IDR
#define SWITCHES_GPIO_PIN_F GPIO_Pin_14 // PD.14
#else #else
#define SWITCHES_GPIO_REG_F GPIOE->IDR #define SWITCHES_GPIO_REG_F GPIOE->IDR
#define SWITCHES_GPIO_PIN_F GPIO_Pin_14 // PE.14 #define SWITCHES_GPIO_PIN_F GPIO_Pin_14 // PE.14
@ -215,7 +235,7 @@
#define SWITCHES_GPIO_PIN_H GPIO_Pin_14 // PD.14 #define SWITCHES_GPIO_PIN_H GPIO_Pin_14 // PD.14
#elif defined(PCBX7D) #elif defined(PCBX7D)
#define SWITCHES_GPIO_REG_H GPIOE->IDR #define SWITCHES_GPIO_REG_H GPIOE->IDR
#define SWITCHES_GPIO_PIN_H GPIO_Pin_15 // PE.15 #define SWITCHES_GPIO_PIN_H GPIO_Pin_14 // PE.14
#else #else
#define SWITCHES_GPIO_REG_H GPIOE->IDR #define SWITCHES_GPIO_REG_H GPIOE->IDR
#define SWITCHES_GPIO_PIN_H GPIO_Pin_13 // PE.13 #define SWITCHES_GPIO_PIN_H GPIO_Pin_13 // PE.13
@ -282,9 +302,10 @@
#define KEYS_GPIOE_PINS (KEYS_GPIO_PIN_PLUS | KEYS_GPIO_PIN_ENTER | KEYS_GPIO_PIN_MINUS | TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_LHL | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | SWITCHES_GPIO_PIN_F | SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_H | SWITCHES_GPIO_PIN_D_H | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L) #define KEYS_GPIOE_PINS (KEYS_GPIO_PIN_PLUS | KEYS_GPIO_PIN_ENTER | KEYS_GPIO_PIN_MINUS | TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_LHL | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | SWITCHES_GPIO_PIN_F | SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_H | SWITCHES_GPIO_PIN_D_H | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L)
#elif defined(PCBX7D) #elif defined(PCBX7D)
#define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE) #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE)
#define KEYS_GPIOC_PINS (TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_RHR) #define KEYS_GPIOA_PINS SWITCHES_GPIO_PIN_C_L
#define KEYS_GPIOD_PINS (KEYS_GPIO_PIN_MENU | KEYS_GPIO_PIN_EXIT | KEYS_GPIO_PIN_PAGE | SWITCHES_GPIO_PIN_A_H | SWITCHES_GPIO_PIN_C_L | SWITCHES_GPIO_PIN_C_H) #define KEYS_GPIOC_PINS (TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU)
#define KEYS_GPIOE_PINS (ENC_GPIO_PIN_A | ENC_GPIO_PIN_B | KEYS_GPIO_PIN_ENTER | TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_LHL | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_D_H | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_F | SWITCHES_GPIO_PIN_H) #define KEYS_GPIOD_PINS (TRIMS_GPIO_PIN_LHL | KEYS_GPIO_PIN_MENU | KEYS_GPIO_PIN_EXIT | KEYS_GPIO_PIN_PAGE | SWITCHES_GPIO_PIN_A_H | SWITCHES_GPIO_PIN_F)
#define KEYS_GPIOE_PINS (ENC_GPIO_PIN_A | ENC_GPIO_PIN_B | KEYS_GPIO_PIN_ENTER | TRIMS_GPIO_PIN_RHR | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | SWITCHES_GPIO_PIN_A_L | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_H | SWITCHES_GPIO_PIN_D_H | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_H)
#else #else
#define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE) #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE)
#define KEYS_GPIOA_PINS (SWITCHES_GPIO_PIN_C_L) #define KEYS_GPIOA_PINS (SWITCHES_GPIO_PIN_C_L)
@ -304,12 +325,19 @@
#endif #endif
#define ADC_GPIO_PIN_STICK_RV GPIO_Pin_0 // PA.00 #define ADC_GPIO_PIN_STICK_RV GPIO_Pin_0 // PA.00
#define ADC_GPIO_PIN_STICK_RH GPIO_Pin_1 // PA.01 #define ADC_GPIO_PIN_STICK_RH GPIO_Pin_1 // PA.01
#define ADC_GPIO_PIN_STICK_LH GPIO_Pin_2 // PA.02 #if defined(PCBX7D)
#define ADC_GPIO_PIN_STICK_LV GPIO_Pin_3 // PA.03 #define ADC_GPIO_PIN_STICK_LV GPIO_Pin_2 // PA.02
#define ADC_GPIO_PIN_STICK_LH GPIO_Pin_3 // PA.03
#define ADC_CHANNEL_STICK_LV ADC_Channel_2 // ADC1_IN2
#define ADC_CHANNEL_STICK_LH ADC_Channel_3 // ADC1_IN3
#else
#define ADC_GPIO_PIN_STICK_LH GPIO_Pin_2 // PA.02
#define ADC_GPIO_PIN_STICK_LV GPIO_Pin_3 // PA.03
#define ADC_CHANNEL_STICK_LH ADC_Channel_2 // ADC1_IN2
#define ADC_CHANNEL_STICK_LV ADC_Channel_3 // ADC1_IN3
#endif
#define ADC_CHANNEL_STICK_RV ADC_Channel_0 // ADC1_IN0 #define ADC_CHANNEL_STICK_RV ADC_Channel_0 // ADC1_IN0
#define ADC_CHANNEL_STICK_RH ADC_Channel_1 // ADC1_IN1 #define ADC_CHANNEL_STICK_RH ADC_Channel_1 // ADC1_IN1
#define ADC_CHANNEL_STICK_LH ADC_Channel_2 // ADC1_IN2
#define ADC_CHANNEL_STICK_LV ADC_Channel_3 // ADC1_IN3
#define ADC1_DMA DMA2 #define ADC1_DMA DMA2
#define ADC1_DMA_Stream DMA2_Stream4 #define ADC1_DMA_Stream DMA2_Stream4
#define ADC1_DMA_FLAGS (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) #define ADC1_DMA_FLAGS (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4)
@ -748,7 +776,7 @@
#define BT_RCC_APB1Periph RCC_APB1Periph_USART3 #define BT_RCC_APB1Periph RCC_APB1Periph_USART3
#define BT_EN_GPIO GPIOE #define BT_EN_GPIO GPIOE
#define BT_EN_GPIO_PIN GPIO_Pin_12 // PE.12 #define BT_EN_GPIO_PIN GPIO_Pin_12 // PE.12
#define BT_GPIO GPIOB #define BT_GPIO_TXRX GPIOB
#define BT_TX_GPIO_PIN GPIO_Pin_10 // PB.10 #define BT_TX_GPIO_PIN GPIO_Pin_10 // PB.10
#define BT_RX_GPIO_PIN GPIO_Pin_11 // PB.11 #define BT_RX_GPIO_PIN GPIO_Pin_11 // PB.11
#define BT_TX_GPIO_PinSource GPIO_PinSource10 #define BT_TX_GPIO_PinSource GPIO_PinSource10

View file

@ -247,7 +247,7 @@ void eepromWaitEepromStandbyState(void)
} }
} }
#if !defined(BOOT) #if !defined(BOOT) && !defined(SOFTWARE_VOLUME)
const uint8_t volumeScale[VOLUME_LEVEL_MAX+1] = { const uint8_t volumeScale[VOLUME_LEVEL_MAX+1] = {
0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40, 0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40,
64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127

View file

@ -88,7 +88,7 @@ uint8_t keyDown()
#if defined(ROTARY_ENCODER_NAVIGATION) #if defined(ROTARY_ENCODER_NAVIGATION)
void checkRotaryEncoder() void checkRotaryEncoder()
{ {
register uint32_t newpos = ROTARY_ENCODER_POSITION(); uint32_t newpos = ROTARY_ENCODER_POSITION();
if (newpos != rotencPosition) { if (newpos != rotencPosition) {
if ((rotencPosition & 0x01) ^ ((newpos & 0x02) >> 1)) { if ((rotencPosition & 0x01) ^ ((newpos & 0x02) >> 1)) {
--rotencValue[0]; --rotencValue[0];
@ -168,7 +168,7 @@ uint8_t keyState(uint8_t index)
uint32_t switchState(uint8_t index) uint32_t switchState(uint8_t index)
{ {
register uint32_t xxx = 0; uint32_t xxx = 0;
switch (index) { switch (index) {
ADD_3POS_CASE(A, 0); ADD_3POS_CASE(A, 0);

View file

@ -0,0 +1,124 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#include "gtests.h"
#if defined(CPUARM)
TEST(SpecialFunctions, SwitchFiledSize)
{
// test the size of swtch member
g_model.customFn[0].swtch = SWSRC_LAST;
EXPECT_EQ(g_model.customFn[0].swtch, SWSRC_LAST) << "CustomFunctionData.swtch member is too small to hold all possible values";
g_model.customFn[0].swtch = -SWSRC_LAST;
EXPECT_EQ(g_model.customFn[0].swtch, -SWSRC_LAST) << "CustomFunctionData.swtch member is too small to hold all possible values";
}
#if defined(PCBTARANIS) || defined(PCBHORUS)
TEST(SpecialFunctions, FlightReset)
{
RADIO_RESET();
MODEL_RESET();
g_model.customFn[0].swtch = SWSRC_SA0;
g_model.customFn[0].func = FUNC_RESET;
g_model.customFn[0].all.val = FUNC_RESET_FLIGHT;
g_model.customFn[0].active = true;
mainRequestFlags = 0;
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ((bool)(mainRequestFlags & (1 << REQUEST_FLIGHT_RESET)), false);
// now trigger SA0
simuSetSwitch(0, -1);
// flightReset() should be called
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ((bool)(mainRequestFlags & (1 << REQUEST_FLIGHT_RESET)), true);
// now reset mainRequestFlags, and it should stay reset (flightReset() should not be called again)
mainRequestFlags = 0;
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ((bool)(mainRequestFlags & (1 << REQUEST_FLIGHT_RESET)), false);
}
#if defined(GVARS)
TEST(SpecialFunctions, GvarsInc)
{
RADIO_RESET();
MODEL_RESET();
simuSetSwitch(0, 0); // SA-
g_model.customFn[0].swtch = SWSRC_SA0;
g_model.customFn[0].func = FUNC_ADJUST_GVAR;
g_model.customFn[0].all.mode = FUNC_ADJUST_GVAR_INCDEC;
g_model.customFn[0].all.param = 0; // GV1
g_model.customFn[0].all.val = -1; // inc/dec value
g_model.customFn[0].active = true;
g_model.flightModeData[0].gvars[0] = 10; // GV1 = 10;
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 10);
// now trigger SA0
simuSetSwitch(0, -1); // SAdown
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9);
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9);
simuSetSwitch(0, 0); // SA-
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 9);
simuSetSwitch(0, -1); // SAdown
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8);
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8);
simuSetSwitch(0, 0); // SA-
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 8);
g_model.customFn[0].all.val = 10; // inc/dec value
simuSetSwitch(0, -1); // SAdown
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18);
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18);
simuSetSwitch(0, 0); // SA-
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 18);
simuSetSwitch(0, -1); // SAdown
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 28);
evalFunctions(g_model.customFn, modelFunctionsContext);
EXPECT_EQ(g_model.flightModeData[0].gvars[0], 28);
}
#endif // #if defined(GVARS)
#endif // #if defined(PCBTARANIS) || defined(PCBHORUS)
#endif // #if defined(CPUARM)

279
radio/src/thirdparty/FatFs/00history.txt vendored Normal file
View file

@ -0,0 +1,279 @@
----------------------------------------------------------------------------
Revision history of FatFs module
----------------------------------------------------------------------------
R0.00 (February 26, 2006)
Prototype.
R0.01 (April 29, 2006)
The first release.
R0.02 (June 01, 2006)
Added FAT12 support.
Removed unbuffered mode.
Fixed a problem on small (<32M) partition.
R0.02a (June 10, 2006)
Added a configuration option (_FS_MINIMUM).
R0.03 (September 22, 2006)
Added f_rename().
Changed option _FS_MINIMUM to _FS_MINIMIZE.
R0.03a (December 11, 2006)
Improved cluster scan algorithm to write files fast.
Fixed f_mkdir() creates incorrect directory on FAT32.
R0.04 (February 04, 2007)
Added f_mkfs().
Supported multiple drive system.
Changed some interfaces for multiple drive system.
Changed f_mountdrv() to f_mount().
R0.04a (April 01, 2007)
Supported multiple partitions on a physical drive.
Added a capability of extending file size to f_lseek().
Added minimization level 3.
Fixed an endian sensitive code in f_mkfs().
R0.04b (May 05, 2007)
Added a configuration option _USE_NTFLAG.
Added FSINFO support.
Fixed DBCS name can result FR_INVALID_NAME.
Fixed short seek (<= csize) collapses the file object.
R0.05 (August 25, 2007)
Changed arguments of f_read(), f_write() and f_mkfs().
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
Fixed f_mkdir() on FAT32 creates incorrect directory.
R0.05a (February 03, 2008)
Added f_truncate() and f_utime().
Fixed off by one error at FAT sub-type determination.
Fixed btr in f_read() can be mistruncated.
Fixed cached sector is not flushed when create and close without write.
R0.06 (April 01, 2008)
Added fputc(), fputs(), fprintf() and fgets().
Improved performance of f_lseek() on moving to the same or following cluster.
R0.07 (April 01, 2009)
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
Added long file name feature. (_USE_LFN)
Added multiple code page feature. (_CODE_PAGE)
Added re-entrancy for multitask operation. (_FS_REENTRANT)
Added auto cluster size selection to f_mkfs().
Added rewind option to f_readdir().
Changed result code of critical errors.
Renamed string functions to avoid name collision.
R0.07a (April 14, 2009)
Septemberarated out OS dependent code on reentrant cfg.
Added multiple sector size feature.
R0.07c (June 21, 2009)
Fixed f_unlink() can return FR_OK on error.
Fixed wrong cache control in f_lseek().
Added relative path feature.
Added f_chdir() and f_chdrive().
Added proper case conversion to extended character.
R0.07e (November 03, 2009)
Septemberarated out configuration options from ff.h to ffconf.h.
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
Fixed name matching error on the 13 character boundary.
Added a configuration option, _LFN_UNICODE.
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
R0.08 (May 15, 2010)
Added a memory configuration option. (_USE_LFN = 3)
Added file lock feature. (_FS_SHARE)
Added fast seek feature. (_USE_FASTSEEK)
Changed some types on the API, XCHAR->TCHAR.
Changed .fname in the FILINFO structure on Unicode cfg.
String functions support UTF-8 encoding files on Unicode cfg.
R0.08a (August 16, 2010)
Added f_getcwd(). (_FS_RPATH = 2)
Added sector erase feature. (_USE_ERASE)
Moved file lock semaphore table from fs object to the bss.
Fixed f_mkfs() creates wrong FAT32 volume.
R0.08b (January 15, 2011)
Fast seek feature is also applied to f_read() and f_write().
f_lseek() reports required table size on creating CLMP.
Extended format syntax of f_printf().
Ignores duplicated directory separators in given path name.
R0.09 (September 06, 2011)
f_mkfs() supports multiple partition to complete the multiple partition feature.
Added f_fdisk().
R0.09a (August 27, 2012)
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
Changed option name _FS_SHARE to _FS_LOCK.
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
R0.09b (January 24, 2013)
Added f_setlabel() and f_getlabel().
R0.10 (October 02, 2013)
Added selection of character encoding on the file. (_STRF_ENCODE)
Added f_closedir().
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
Added forced mount feature with changes of f_mount().
Improved behavior of volume auto detection.
Improved write throughput of f_puts() and f_printf().
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
Fixed f_write() can be truncated when the file size is close to 4GB.
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
R0.10a (January 15, 2014)
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
Added a configuration option of minimum sector size. (_MIN_SS)
2nd argument of f_rename() can have a drive number and it will be ignored.
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
Fixed f_close() invalidates the file object without volume lock.
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
R0.10b (May 19, 2014)
Fixed a hard error in the disk I/O layer can collapse the directory entry.
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
R0.10c (November 09, 2014)
Added a configuration option for the platforms without RTC. (_FS_NORTC)
Changed option name _USE_ERASE to _USE_TRIM.
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
Fixed a potential problem of FAT access that can appear on disk error.
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
R0.11 (February 09, 2015)
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
R0.11a (September 05, 2015)
Fixed wrong media change can lead a deadlock at thread-safe configuration.
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
Fixed errors in the case conversion teble of Unicode (cc*.c).
R0.12 (April 12, 2016)
Added support for exFAT file system. (_FS_EXFAT)
Added f_expand(). (_USE_EXPAND)
Changed some members in FINFO structure and behavior of f_readdir().
Added an option _USE_CHMOD.
Removed an option _WORD_ACCESS.
Fixed errors in the case conversion table of Unicode (cc*.c).
R0.12a (July 10, 2016)
Added support for creating exFAT volume with some changes of f_mkfs().
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
f_forward() is available regardless of _FS_TINY.
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
Fixed wrong memory read in create_name(). (appeared at R0.12)
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
R0.12b (September 04, 2016)
Improved f_rename() to be able to rename objects with the same name but case.
Fixed an error in the case conversion teble of code page 866. (ff.c)
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)

View file

@ -1,163 +1,21 @@
FatFs Module Source Files R0.10c (C)ChaN, 2014 FatFs Module Source Files R0.12a
FILES FILES
ffconf.h Configuration file for FatFs module. 00readme.txt This file.
ff.h Common include file for FatFs and application module. history.txt Revision history.
ff.c FatFs module. ffconf.h Configuration file for FatFs module.
diskio.h Common include file for FatFs and disk I/O module. ff.h Common include file for FatFs and application module.
diskio.c An example of glue function to attach existing disk I/O module to FatFs. ff.c FatFs module.
integer.h Integer type definitions for FatFs. diskio.h Common include file for FatFs and disk I/O module.
option Optional external functions. 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.
Low level disk I/O module is not included in this archive because the FatFs 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 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 storage device. You have to provide a low level disk I/O module that written
to control your storage device. to control the target storage device.
AGREEMENTS
FatFs module is an open source software to implement FAT file system to
small embedded systems. This is a free software and is opened for education,
research and commercial developments under license policy of following trems.
Copyright (C) 2014, ChaN, all right reserved.
* The FatFs module is a free software and there is NO WARRANTY.
* No restriction on use. You can use, modify and redistribute it for
personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
* Redistributions of source code must retain the above copyright notice.
REVISION HISTORY
Feb 26, 2006 R0.00 Prototype
Apr 29, 2006 R0.01 First release.
Jun 01, 2006 R0.02 Added FAT12.
Removed unbuffered mode.
Fixed a problem on small (<32M) patition.
Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
Sep 22, 2006 R0.03 Added f_rename.
Changed option _FS_MINIMUM to _FS_MINIMIZE.
Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
Fixed f_mkdir creates incorrect directory on FAT32.
Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
Changed some APIs for multiple drive system.
Added f_mkfs. (FatFs)
Added _USE_FAT32 option. (Tiny-FatFs)
Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
Fixed an endian sensitive code in f_mkfs. (FatFs)
Added a capability of extending the file size to f_lseek.
Added minimization level 3.
Fixed a problem that can collapse a sector when recreate an
existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
May 05, 2007 R0.04b 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 (0 < ofs <= csize) collapses the file object.
Aug 25, 2007 R0.05 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)
Feb 03, 2008 R0.05a 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 not flushed when create and close without write.
Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
Added string functions: fputc(), fputs(), fprintf() and fgets().
Improved performance of f_lseek() on move to the same or following cluster.
Apr 01, 2009, R0.07 Merged Tiny-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.
Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
Added multiple sector size support.
Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
Fixed wrong cache control in f_lseek().
Added relative path feature.
Added f_chdir().
Added f_chdrive().
Added proper case conversion for extended characters.
Nov 03, 2009 R0.07e 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.
May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
Added file lock feature. (_FS_SHARE)
Added fast seek feature. (_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.
Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
Added sector erase feature. (_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.
Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
f_lseek() reports required table size on creating CLMP.
Extended format syntax of f_printf function.
Ignores duplicated directory separators in given path names.
Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
Added f_fdisk(). (_MULTI_PARTITION = 2)
Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16.
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
Changed option name _FS_SHARE to _FS_LOCK.
Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL)
Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
Added f_closedir().
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
Added forced mount feature with changes of f_mount().
Improved behavior of volume auto detection.
Improved write throughput of f_puts() and f_printf().
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
Fixed f_write() can be truncated when the file size is close to 4GB.
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
Added a configuration option of minimum sector size. (_MIN_SS)
2nd argument of f_rename() can have a drive number and it will be ignored.
Fixed f_mount() with forced mount fails when drive number is >= 1.
Fixed f_close() invalidates the file object without volume lock.
Fixed f_closedir() returns but the volume lock is left acquired.
Fixed creation of an entry with LFN fails on too many SFN collisions.
Mar 19,'14 R0.10b 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.
Nov 09,'14 R0.10c 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().
Fixed a potential problem of FAT access that can appear on disk error.
Fixed null pointer dereference on attempting to delete the root direcotry.

View file

@ -5,13 +5,10 @@
#ifndef _DISKIO_DEFINED #ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED #define _DISKIO_DEFINED
#if defined(__cplusplus) #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define _USE_WRITE 1 /* 1: Enable disk_write function */
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
#include "integer.h" #include "integer.h"
@ -67,13 +64,16 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
#define MMC_GET_CID 12 /* Get CID */ #define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */ #define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */ #define MMC_GET_SDSTAT 14 /* Get SD status */
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
/* ATA/CF specific ioctl command */ /* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */ #define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */ #define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */ #define ATA_GET_SN 22 /* Get serial number */
#if defined(__cplusplus) #ifdef __cplusplus
} }
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,28 +1,33 @@
/*---------------------------------------------------------------------------/ /*----------------------------------------------------------------------------/
/ FatFs - FAT file system module include file R0.10c (C)ChaN, 2014 / FatFs - Generic FAT file system module R0.12b /
/----------------------------------------------------------------------------/ /-----------------------------------------------------------------------------/
/ FatFs module is a generic FAT file system module for small embedded systems.
/ This is a free software that opened for education, research and commercial
/ developments under license policy of following terms.
/ /
/ Copyright (C) 2014, ChaN, all right reserved. / Copyright (C) 2016, ChaN, all right reserved.
/ /
/ * The FatFs module is a free software and there is NO WARRANTY. / FatFs module is an open source software. Redistribution and use of FatFs in
/ * No restriction on use. You can use, modify and redistribute it for / source and binary forms, with or without modification, are permitted provided
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. / that the following condition is met:
/ * Redistributions of source code must retain the above copyright notice.
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/ /
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/ /----------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS 80376 /* Revision ID */
#if defined(__cplusplus) #ifndef _FATFS
#define _FATFS 68020 /* Revision ID */
#ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "integer.h" /* Basic integer types */ #include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */ #include "ffconf.h" /* FatFs configuration options */
#if _FATFS != _FFCONF #if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h). #error Wrong configuration file (ffconf.h).
#endif #endif
@ -50,8 +55,8 @@ extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
/* Type of path name strings on FatFs API */ /* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode string */ #if _LFN_UNICODE /* Unicode (UTF-16) string */
#if !_USE_LFN #if _USE_LFN == 0
#error _LFN_UNICODE must be 0 at non-LFN cfg. #error _LFN_UNICODE must be 0 at non-LFN cfg.
#endif #endif
#ifndef _INC_TCHAR #ifndef _INC_TCHAR
@ -59,14 +64,25 @@ typedef WCHAR TCHAR;
#define _T(x) L ## x #define _T(x) L ## x
#define _TEXT(x) L ## x #define _TEXT(x) L ## x
#endif #endif
#else /* ANSI/OEM string */ #else /* ANSI/OEM string */
#ifndef _INC_TCHAR #ifndef _INC_TCHAR
typedef char TCHAR; typedef char TCHAR;
#define _T(x) x #define _T(x) x
#define _TEXT(x) x #define _TEXT(x) x
#endif #endif
#endif
/* Type of file size variables */
#if _FS_EXFAT
#if _USE_LFN == 0
#error LFN must be enabled when enable exFAT
#endif
typedef QWORD FSIZE_t;
#else
typedef DWORD FSIZE_t;
#endif #endif
@ -74,60 +90,87 @@ typedef char TCHAR;
/* File system object structure (FATFS) */ /* File system object structure (FATFS) */
typedef struct { typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) */ BYTE fs_type; /* File system type (0:N/A) */
BYTE drv; /* Physical drive number */ BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */ BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE n_fats; /* Number of FAT copies (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */ BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* File system mount ID */ WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
#if _MAX_SS != _MIN_SS #if _MAX_SS != _MIN_SS
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */ WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
#endif
#if _USE_LFN != 0
WCHAR* lfnbuf; /* LFN working buffer */
#endif
#if _FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
#endif #endif
#if _FS_REENTRANT #if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */ _SYNC_t sobj; /* Identifier of sync object */
#endif #endif
#if !_FS_READONLY #if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */ DWORD last_clst; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */ DWORD free_clst; /* Number of free clusters */
#endif #endif
#if _FS_RPATH #if _FS_RPATH != 0
DWORD cdir; /* Current directory start cluster (0:root) */ DWORD cdir; /* Current directory start cluster (0:root) */
#if _FS_EXFAT
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
#endif #endif
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */ #endif
DWORD fsize; /* Sectors per FAT */ DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD volbase; /* Volume start sector */ DWORD fsize; /* Size of an FAT [sectors] */
DWORD fatbase; /* FAT start sector */ DWORD volbase; /* Volume base sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ DWORD fatbase; /* FAT base sector */
DWORD database; /* Data start sector */ DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */
DWORD winsect; /* Current sector appearing in the win[] */ DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS; } FATFS;
/* Object ID and allocation information (_FDID) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if _FS_EXFAT
DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */
#endif
#if _FS_LOCK != 0
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} _FDID;
/* File object structure (FIL) */ /* File object structure (FIL) */
typedef struct { typedef struct {
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */ _FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
WORD id; /* Owner file system mount ID (**do not change order**) */ BYTE flag; /* File status flags */
BYTE flag; /* Status flags */
BYTE err; /* Abort flag (error code) */ BYTE err; /* Abort flag (error code) */
DWORD fptr; /* File read/write pointer (Zeroed on file open) */ FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD fsize; /* File size */ DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */ DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY #if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */ DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */ BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
#endif #endif
#if _USE_FASTSEEK #if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */ DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if _FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif #endif
#if !_FS_TINY #if !_FS_TINY
BYTE buf[_MAX_SS]; /* File private data read/write window */ BYTE buf[_MAX_SS]; /* File private data read/write window */
@ -139,36 +182,34 @@ typedef struct {
/* Directory object structure (DIR) */ /* Directory object structure (DIR) */
typedef struct { typedef struct {
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */ _FDID obj; /* Object identifier */
WORD id; /* Owner file system mount ID (**do not change order**) */ DWORD dptr; /* Current read/write offset */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */ DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */ DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the current SFN entry in the win[] */ BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if _FS_LOCK #if _USE_LFN != 0
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */ DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif #endif
#if _USE_LFN #if _USE_FIND
WCHAR* lfn; /* Pointer to the LFN working buffer */ const TCHAR* pat; /* Pointer to the name matching pattern */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif #endif
} DIR; } DIR;
/* File status structure (FILINFO) */ /* File information structure (FILINFO) */
typedef struct { typedef struct {
DWORD fsize; /* File size */ FSIZE_t fsize; /* File size */
WORD fdate; /* Last modified date */ WORD fdate; /* Modified date */
WORD ftime; /* Last modified time */ WORD ftime; /* Modified time */
BYTE fattrib; /* Attribute */ BYTE fattrib; /* File attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */ #if _USE_LFN != 0
#if _USE_LFN TCHAR altname[13]; /* Altenative file name */
TCHAR* lfname; /* Pointer to the LFN buffer */ TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
UINT lfsize; /* Size of LFN buffer in TCHAR */ #else
TCHAR fname[13]; /* File name */
#endif #endif
} FILINFO; } FILINFO;
@ -191,11 +232,11 @@ typedef enum {
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */ FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT; } FRESULT;
@ -206,43 +247,48 @@ typedef enum {
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */ FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */ FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */ FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */ FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_truncate (FIL* fp); /* Truncate file */ FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */ FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */ FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */ FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */ FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */ FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */ FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize)) #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err) #define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr) #define f_tell(fp) ((fp)->fptr)
#if !defined(SIMU) || defined(SIMU_DISKIO) #if !defined(SIMU) || defined(SIMU_DISKIO)
#define f_size(fp) ((fp)->fsize) #define f_size(fp) ((fp)->obj.objsize)
#else #else
UINT f_size(FIL* fil); UINT f_size(FIL* fil);
#endif #endif
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#ifndef EOF #ifndef EOF
#define EOF (-1) #define EOF (-1)
@ -260,7 +306,7 @@ DWORD get_fattime (void);
#endif #endif
/* Unicode support functions */ /* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */ #if _USE_LFN != 0 /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */ #if _USE_LFN == 3 /* Memory functions */
@ -284,61 +330,40 @@ int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
/* Flags and offset address */ /* Flags and offset address */
/* File access control and file status flags (FIL.flag) */ /* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01 #define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#if !_FS_READONLY
#define FA_WRITE 0x02 #define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04 #define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08 #define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10 #define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20 #define FA_OPEN_APPEND 0x30
#define FA__DIRTY 0x40
#endif
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* FAT sub type (FATFS.fs_type) */ /* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1 #define FS_FAT12 1
#define FS_FAT16 2 #define FS_FAT16 2
#define FS_FAT32 3 #define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */ #define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */ #define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */ #define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */ #define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */ #define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Fast seek feature */ #ifdef __cplusplus
#define CREATE_LINKMAP 0xFFFFFFFF
/*--------------------------------*/
/* Multi-byte word access macros */
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
#if defined(__cplusplus)
} }
#endif #endif

View file

@ -1,8 +1,8 @@
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014 / FatFs - FAT file system module configuration file
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FFCONF 80376 /* Revision ID */ #define _FFCONF 68020 /* Revision ID */
#if defined(CPUARM) && !defined(SIMU) #if defined(CPUARM) && !defined(SIMU)
#ifdef __cplusplus #ifdef __cplusplus
@ -15,46 +15,38 @@ extern "C" {
#endif #endif
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations / Function 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. */
#if defined(BOOT) #if defined(BOOT)
#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */ #define _FS_READONLY 1
#else #else
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ #define _FS_READONLY 0
#endif #endif
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) /* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes basic writing API functions, f_write(), / Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ f_getfree() and optional writing functions as well. */ / and optional writing functions as well. */
#if defined(BOOT) #if defined(BOOT)
#define _FS_MINIMIZE 1 /* 0 to 3 */ #define _FS_MINIMIZE 1
#else #else
#define _FS_MINIMIZE 0 /* 0 to 3 */ #define _FS_MINIMIZE 0
#endif #endif
/* This option defines minimization level to remove some API functions. /* This option defines minimization level to remove some basic API functions.
/ /
/ 0: All basic functions are enabled. / 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ f_truncate() and f_rename() function are removed. / are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */ / 3: f_lseek() function is removed in addition to 2. */
#if defined(BOOT) #if defined(BOOT)
#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */ #define _USE_STRFUNC 0
#else #else
#define _USE_STRFUNC 1 /* 0:Disable or 1-2:Enable */ #define _USE_STRFUNC 1
#endif #endif
/* This option switches string functions, f_gets(), f_putc(), f_puts() and /* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf(). / f_printf().
@ -64,13 +56,25 @@ extern "C" {
/ 2: Enable with 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 1 #define _USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
/ To enable it, also _FS_READONLY need to be set to 0. */
#define _USE_FASTSEEK 0 #define _USE_FASTSEEK 0
/* This option switches fast seek feature. (0:Disable or 1:Enable) */ /* 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 #define _USE_LABEL 0
@ -80,74 +84,72 @@ extern "C" {
#define _USE_FORWARD 0 #define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */ /* This option switches f_forward() function. (0:Disable or 1:Enable) */
/* To enable it, also _FS_TINY need to be set to 1. */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations / Locale and Namespace Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _CODE_PAGE 1252 #define _CODE_PAGE 437
/* This option specifies the OEM code page to be used on the target system. /* 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. / Incorrect setting of the code page can cause a file open failure.
/ /
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows) / 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) / 437 - U.S.
/ 949 - Korean (DBCS, OEM, Windows) / 720 - Arabic
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) / 737 - Greek
/ 1250 - Central Europe (Windows) / 771 - KBL
/ 1251 - Cyrillic (Windows) / 775 - Baltic
/ 1252 - Latin 1 (Windows) / 850 - Latin 1
/ 1253 - Greek (Windows) / 852 - Latin 2
/ 1254 - Turkish (Windows) / 855 - Cyrillic
/ 1255 - Hebrew (Windows) / 857 - Turkish
/ 1256 - Arabic (Windows) / 860 - Portuguese
/ 1257 - Baltic (Windows) / 861 - Icelandic
/ 1258 - Vietnam (OEM, Windows) / 862 - Hebrew
/ 437 - U.S. (OEM) / 863 - Canadian French
/ 720 - Arabic (OEM) / 864 - Arabic
/ 737 - Greek (OEM) / 865 - Nordic
/ 775 - Baltic (OEM) / 866 - Russian
/ 850 - Multilingual Latin 1 (OEM) / 869 - Greek 2
/ 858 - Multilingual Latin 1 + Euro (OEM) / 932 - Japanese (DBCS)
/ 852 - Latin 2 (OEM) / 936 - Simplified Chinese (DBCS)
/ 855 - Cyrillic (OEM) / 949 - Korean (DBCS)
/ 866 - Russian (OEM) / 950 - Traditional Chinese (DBCS)
/ 857 - Turkish (OEM) */
/ 862 - Hebrew (OEM)
/ 874 - Thai (OEM, Windows)
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
#if defined(CPUARM) #if defined(CPUARM)
#define _USE_LFN 2 /* 0 to 3 */ #define _USE_LFN 2
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ #define _MAX_LFN 255
#else #else
#define _USE_LFN 1 /* 0 to 3 */ #define _USE_LFN 1
#define _MAX_LFN 32 /* Maximum LFN length to handle (12 to 255) */ #define _MAX_LFN 32
#endif #endif
/* The _USE_LFN option switches the LFN feature. /* The _USE_LFN switches the support of long file name (LFN).
/ /
/ 0: Disable LFN feature. _MAX_LFN has no effect. / 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK. / 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP. / 3: Enable LFN with dynamic working buffer on the HEAP.
/ /
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must / To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. / 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 / 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 / memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */ / ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 #define _LFN_UNICODE 0
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode) /* 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 feature and set _LFN_UNICODE / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ to 1. This option also affects behavior of string I/O functions. */ / This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3 #define _STRF_ENCODE 3
/* When _LFN_UNICODE is 1, this option selects the character encoding on the file to /* 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(). / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/ /
/ 0: ANSI/OEM / 0: ANSI/OEM
@ -155,17 +157,16 @@ extern "C" {
/ 2: UTF-16BE / 2: UTF-16BE
/ 3: UTF-8 / 3: UTF-8
/ /
/ When _LFN_UNICODE is 0, this option has no effect. */ / This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 2 #define _FS_RPATH 2
/* This option configures relative path feature. /* This option configures support of relative path.
/ /
/ 0: Disable relative path feature and remove related functions. / 0: Disable relative path and remove related functions.
/ 1: Enable relative path feature. f_chdir() and f_chdrive() are available. / 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1. / 2: f_getcwd() function is available in addition to 1.
/ */
/ Note that directory items read via f_readdir() are affected by this option. */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
@ -177,8 +178,8 @@ extern "C" {
#define _STR_VOLUME_ID 0 #define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" #define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* _STR_VOLUME_ID option switches string volume ID feature. /* _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 / 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 / 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 / logical drives. Number of items must be equal to _VOLUMES. Valid characters for
@ -186,11 +187,12 @@ extern "C" {
#define _MULTI_PARTITION 0 #define _MULTI_PARTITION 0
/* This option switches multi-partition feature. By default (0), each logical drive /* This option switches support of multi-partition on a physical drive.
/ number is bound to the same physical drive number and only an FAT volume found on / By default (0), each logical drive number is bound to the same physical drive
/ the physical drive will be mounted. When multi-partition feature is enabled (1), / number and only an FAT volume found on the physical drive will be mounted.
/ each logical drive number is bound to arbitrary physical drive and partition / When multi-partition is enabled (1), each logical drive number can be bound to
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */ / arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define _MIN_SS 512 #define _MIN_SS 512
@ -204,8 +206,8 @@ extern "C" {
#define _USE_TRIM 0 #define _USE_TRIM 0
/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable) /* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim feature, also CTRL_TRIM command should be implemented to the / To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */ / disk_ioctl() function. */
@ -226,30 +228,43 @@ extern "C" {
/ System Configurations / System Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of 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. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0 #define _FS_NORTC 0
#define _NORTC_MON 11 #define _NORTC_MON 1
#define _NORTC_MDAY 9 #define _NORTC_MDAY 1
#define _NORTC_YEAR 2014 #define _NORTC_YEAR 2016
/* The _FS_NORTC option switches timestamp feature. If the system does not have /* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable / any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp / the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR. / defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need / To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ to be added to the project to read current time form RTC. _NORTC_MON, / 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). */ / These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 0 #define _FS_LOCK 0
/* The _FS_LOCK option switches file lock feature to control duplicated file open /* 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 / and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1. / is 1.
/ /
/ 0: Disable file lock feature. To avoid volume corruption, application program / 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects. / should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock feature. The value defines how many files/sub-directories / >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 / can be opened simultaneously under file lock control. Note that the file
/ lock feature is independent of re-entrancy. */ / lock control is independent of re-entrancy. */
#if defined(CPUARM) && !defined(BOOT) #if defined(CPUARM) && !defined(BOOT)
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */ #define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */
@ -260,11 +275,11 @@ extern "C" {
#define _FS_TIMEOUT 1000 #define _FS_TIMEOUT 1000
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs /* 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 / 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() / 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 / and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this feature. / to the same volume is under control of this function.
/ /
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. / 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers, / 1: Enable re-entrancy. Also user provided synchronization handlers,
@ -274,29 +289,9 @@ extern "C" {
/ /
/ The _FS_TIMEOUT defines timeout period in unit of time tick. / 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*, / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. */ / SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
#define _WORD_ACCESS 0
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/
/ 0: Byte-by-byte access. Always compatible with all platforms.
/ 1: Word access. Do not choose this unless under both the following conditions.
/
/ * Address misaligned memory access is always allowed to ALL instructions.
/ * Byte order on the memory is little-endian.
/
/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
/ Following table shows allowable settings of some processor types.
/
/ ARM7TDMI 0 ColdFire 0 V850E 0
/ Cortex-M3 0 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 x86 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
/ AVR32 0 RL78 0 R32C 0
/ PIC18 0/1 SH-2 0 M16C 0/1
/ PIC24 0 H8S 0 MSP430 0
/ PIC32 0 H8/300H 0 8051 0/1
*/
/*--- End of configuration options ---*/

View file

@ -9,25 +9,30 @@
#include <windows.h> #include <windows.h>
#include <tchar.h> #include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */ #else /* Embedded platform */
/* This type MUST be 8 bit */ /* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE; typedef unsigned char BYTE;
/* These types MUST be 16 bit */ /* These types MUST be 16-bit */
typedef short SHORT; typedef short SHORT;
typedef unsigned short WORD; typedef unsigned short WORD;
typedef unsigned short WCHAR; typedef unsigned short WCHAR;
/* These types MUST be 16 bit or 32 bit */ /* These types MUST be 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* These types MUST be 32 bit */
typedef long LONG; typedef long LONG;
typedef unsigned long DWORD; typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
typedef unsigned long long QWORD;
#endif #endif
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ /* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */
/* */
/* CP936 (Simplified Chinese GBK) */ /* CP936 (Simplified Chinese GBK) */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -10923,7 +10922,7 @@ const WCHAR oem2uni[] = {
WCHAR ff_convert ( /* Converted code, 0 means conversion error */ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR chr, /* Character code to be converted */ WCHAR chr, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
) )
{ {
const WCHAR *p; const WCHAR *p;
@ -10934,10 +10933,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
if (chr < 0x80) { /* ASCII */ if (chr < 0x80) { /* ASCII */
c = chr; c = chr;
} else { } else {
if (dir) { /* OEMCP to unicode */ if (dir) { /* OEM code to unicode */
p = oem2uni; p = oem2uni;
hi = sizeof oem2uni / 4 - 1; hi = sizeof oem2uni / 4 - 1;
} else { /* Unicode to OEMCP */ } else { /* Unicode to OEM code */
p = uni2oem; p = uni2oem;
hi = sizeof uni2oem / 4 - 1; hi = sizeof uni2oem / 4 - 1;
} }
@ -10958,16 +10957,89 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR ff_wtoupper ( /* Upper converted character */ WCHAR ff_wtoupper ( /* Returns upper converted character */
WCHAR chr /* Input character */ WCHAR chr /* Unicode character to be upper converted (BMP only) */
) )
{ {
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; /* Compressed upper conversion table */
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
int i; /* Basic Latin */
0x0061,0x031A,
/* Latin-1 Supplement */
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
/* Latin Extended-A */
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
/* Latin Extended-B */
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
/* IPA Extensions */
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
/* Greek, Coptic */
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
/* Cyrillic */
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
/* Armenian */
0x0561,0x0426,
0x0000
};
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
/* Phonetic Extensions */
0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */
0x1E00,0x0196, 0x1EA0,0x015A,
/* Greek Extended */
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
/* Letterlike Symbols */
0x214E,0x0001,0x2132,
/* Number forms */
0x2170,0x0210, 0x2184,0x0001,0x2183,
/* Enclosed Alphanumerics */
0x24D0,0x051A, 0x2C30,0x042F,
/* Latin Extended-C */
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
/* Coptic */
0x2C80,0x0164,
/* Georgian Supplement */
0x2D00,0x0826,
/* Full-width */
0xFF41,0x031A,
0x0000
};
const WCHAR *p;
WCHAR bc, nc, cmd;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; p = chr < 0x1000 ? cvt1 : cvt2;
for (;;) {
bc = *p++; /* Get block base */
if (!bc || chr < bc) break;
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
if (chr < bc + nc) { /* In the block? */
switch (cmd) {
case 0: chr = p[chr - bc]; break; /* Table conversion */
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
case 2: chr -= 16; break; /* Shift -16 */
case 3: chr -= 32; break; /* Shift -32 */
case 4: chr -= 48; break; /* Shift -48 */
case 5: chr -= 26; break; /* Shift -26 */
case 6: chr += 8; break; /* Shift +8 */
case 7: chr -= 80; break; /* Shift -80 */
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
}
if (!cmd) p += nc;
}
return tbl_lower[i] ? tbl_upper[i] : chr; return chr;
} }

View file

@ -1,6 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ /* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */
/* */
/* CP949 (Korean EUC-KR) */ /* CP949 (Korean EUC-KR) */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -8552,7 +8551,7 @@ const WCHAR oem2uni[] = {
WCHAR ff_convert ( /* Converted code, 0 means conversion error */ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR chr, /* Character code to be converted */ WCHAR chr, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
) )
{ {
const WCHAR *p; const WCHAR *p;
@ -8563,10 +8562,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
if (chr < 0x80) { /* ASCII */ if (chr < 0x80) { /* ASCII */
c = chr; c = chr;
} else { } else {
if (dir) { /* OEMCP to unicode */ if (dir) { /* OEM code to unicode */
p = oem2uni; p = oem2uni;
hi = sizeof oem2uni / 4 - 1; hi = sizeof oem2uni / 4 - 1;
} else { /* Unicode to OEMCP */ } else { /* Unicode to OEM code */
p = uni2oem; p = uni2oem;
hi = sizeof uni2oem / 4 - 1; hi = sizeof uni2oem / 4 - 1;
} }
@ -8587,17 +8586,89 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR ff_wtoupper ( /* Returns upper converted character */
WCHAR ff_wtoupper ( /* Upper converted character */ WCHAR chr /* Unicode character to be upper converted (BMP only) */
WCHAR chr /* Input character */
) )
{ {
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; /* Compressed upper conversion table */
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
int i; /* Basic Latin */
0x0061,0x031A,
/* Latin-1 Supplement */
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
/* Latin Extended-A */
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
/* Latin Extended-B */
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
/* IPA Extensions */
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
/* Greek, Coptic */
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
/* Cyrillic */
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
/* Armenian */
0x0561,0x0426,
0x0000
};
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
/* Phonetic Extensions */
0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */
0x1E00,0x0196, 0x1EA0,0x015A,
/* Greek Extended */
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
/* Letterlike Symbols */
0x214E,0x0001,0x2132,
/* Number forms */
0x2170,0x0210, 0x2184,0x0001,0x2183,
/* Enclosed Alphanumerics */
0x24D0,0x051A, 0x2C30,0x042F,
/* Latin Extended-C */
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
/* Coptic */
0x2C80,0x0164,
/* Georgian Supplement */
0x2D00,0x0826,
/* Full-width */
0xFF41,0x031A,
0x0000
};
const WCHAR *p;
WCHAR bc, nc, cmd;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; p = chr < 0x1000 ? cvt1 : cvt2;
for (;;) {
bc = *p++; /* Get block base */
if (!bc || chr < bc) break;
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
if (chr < bc + nc) { /* In the block? */
switch (cmd) {
case 0: chr = p[chr - bc]; break; /* Table conversion */
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
case 2: chr -= 16; break; /* Shift -16 */
case 3: chr -= 32; break; /* Shift -32 */
case 4: chr -= 48; break; /* Shift -48 */
case 5: chr -= 26; break; /* Shift -26 */
case 6: chr += 8; break; /* Shift +8 */
case 7: chr -= 80; break; /* Shift -80 */
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
}
if (!cmd) p += nc;
}
return tbl_lower[i] ? tbl_upper[i] : chr; return chr;
} }

View file

@ -1,6 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ /* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */
/* */
/* CP950 (Traditional Chinese Big5) */ /* CP950 (Traditional Chinese Big5) */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -6778,7 +6777,7 @@ const WCHAR oem2uni[] = {
WCHAR ff_convert ( /* Converted code, 0 means conversion error */ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR chr, /* Character code to be converted */ WCHAR chr, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
) )
{ {
const WCHAR *p; const WCHAR *p;
@ -6789,10 +6788,10 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
if (chr < 0x80) { /* ASCII */ if (chr < 0x80) { /* ASCII */
c = chr; c = chr;
} else { } else {
if (dir) { /* OEMCP to unicode */ if (dir) { /* OEM code to unicode */
p = oem2uni; p = oem2uni;
hi = sizeof oem2uni / 4 - 1; hi = sizeof oem2uni / 4 - 1;
} else { /* Unicode to OEMCP */ } else { /* Unicode to OEM code */
p = uni2oem; p = uni2oem;
hi = sizeof uni2oem / 4 - 1; hi = sizeof uni2oem / 4 - 1;
} }
@ -6813,17 +6812,89 @@ WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR ff_wtoupper ( /* Returns upper converted character */
WCHAR ff_wtoupper ( /* Upper converted character */ WCHAR chr /* Unicode character to be upper converted (BMP only) */
WCHAR chr /* Input character */
) )
{ {
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; /* Compressed upper conversion table */
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
int i; /* Basic Latin */
0x0061,0x031A,
/* Latin-1 Supplement */
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
/* Latin Extended-A */
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
/* Latin Extended-B */
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
/* IPA Extensions */
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
/* Greek, Coptic */
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
/* Cyrillic */
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
/* Armenian */
0x0561,0x0426,
0x0000
};
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
/* Phonetic Extensions */
0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */
0x1E00,0x0196, 0x1EA0,0x015A,
/* Greek Extended */
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
/* Letterlike Symbols */
0x214E,0x0001,0x2132,
/* Number forms */
0x2170,0x0210, 0x2184,0x0001,0x2183,
/* Enclosed Alphanumerics */
0x24D0,0x051A, 0x2C30,0x042F,
/* Latin Extended-C */
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
/* Coptic */
0x2C80,0x0164,
/* Georgian Supplement */
0x2D00,0x0826,
/* Full-width */
0xFF41,0x031A,
0x0000
};
const WCHAR *p;
WCHAR bc, nc, cmd;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; p = chr < 0x1000 ? cvt1 : cvt2;
for (;;) {
bc = *p++; /* Get block base */
if (!bc || chr < bc) break;
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
if (chr < bc + nc) { /* In the block? */
switch (cmd) {
case 0: chr = p[chr - bc]; break; /* Table conversion */
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
case 2: chr -= 16; break; /* Shift -16 */
case 3: chr -= 32; break; /* Shift -32 */
case 4: chr -= 48; break; /* Shift -48 */
case 5: chr -= 26; break; /* Shift -26 */
case 6: chr += 8; break; /* Shift +8 */
case 7: chr -= 80; break; /* Shift -80 */
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
}
if (!cmd) p += nc;
}
return tbl_lower[i] ? tbl_upper[i] : chr; return chr;
} }

View file

@ -1,28 +1,24 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode - Local code bidirectional converter (C)ChaN, 2012 */ /* Unicode - Local code bidirectional converter (C)ChaN, 2015 */
/* (SBCS code pages) */ /* (SBCS code pages) */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* 437 U.S. (OEM) /* 437 U.S.
/ 720 Arabic (OEM) / 720 Arabic
/ 1256 Arabic (Windows) / 737 Greek
/ 737 Greek (OEM) / 771 KBL
/ 1253 Greek (Windows) / 775 Baltic
/ 1250 Central Europe (Windows) / 850 Latin 1
/ 775 Baltic (OEM) / 852 Latin 2
/ 1257 Baltic (Windows) / 855 Cyrillic
/ 850 Multilingual Latin 1 (OEM) / 857 Turkish
/ 852 Latin 2 (OEM) / 860 Portuguese
/ 1252 Latin 1 (Windows) / 861 Icelandic
/ 855 Cyrillic (OEM) / 862 Hebrew
/ 1251 Cyrillic (Windows) / 863 Canadian French
/ 866 Russian (OEM) / 864 Arabic
/ 857 Turkish (OEM) / 865 Nordic
/ 1254 Turkish (Windows) / 866 Russian
/ 858 Multilingual Latin 1 + Euro (OEM) / 869 Greek 2
/ 862 Hebrew (OEM)
/ 1255 Hebrew (Windows)
/ 874 Thai (OEM, Windows)
/ 1258 Vietnam (OEM, Windows)
*/ */
#include "../ff.h" #include "../ff.h"
@ -32,475 +28,253 @@
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 720 #elif _CODE_PAGE == 720
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 737 #elif _CODE_PAGE == 737
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, };
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, #elif _CODE_PAGE == 771
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, #define _TBLDEF 1
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, static
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 775 #elif _CODE_PAGE == 775
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 850 #elif _CODE_PAGE == 850
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 852 #elif _CODE_PAGE == 852
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 855 #elif _CODE_PAGE == 855
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 857 #elif _CODE_PAGE == 857
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 858 #elif _CODE_PAGE == 860
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, };
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE, #elif _CODE_PAGE == 861
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580, #define _TBLDEF 1
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, static
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 862 #elif _CODE_PAGE == 862
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, };
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, #elif _CODE_PAGE == 863
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, #define _TBLDEF 1
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, static
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 864
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
};
#elif _CODE_PAGE == 865
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 866 #elif _CODE_PAGE == 866
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
}; };
#elif _CODE_PAGE == 874 #elif _CODE_PAGE == 869
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, 0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
};
#elif _CODE_PAGE == 1250
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};
#elif _CODE_PAGE == 1251
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
};
#elif _CODE_PAGE == 1252
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
#elif _CODE_PAGE == 1253
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
};
#elif _CODE_PAGE == 1254
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
};
#elif _CODE_PAGE == 1255
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
};
#elif _CODE_PAGE == 1256
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
};
#elif _CODE_PAGE == 1257
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
};
#elif _CODE_PAGE == 1258
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
}; };
#endif #endif
#if !_TBLDEF || !_USE_LFN #if !_TBLDEF || !_USE_LFN
#error This file is not needed in current configuration. Remove from the project. #error This file is not needed at current configuration. Remove from the project.
#endif #endif
WCHAR ff_convert ( /* Converted character, Returns zero on error */ WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR chr, /* Character code to be converted */ WCHAR chr, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */ UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
) )
{ {
WCHAR c; WCHAR c;
@ -510,10 +284,10 @@ WCHAR ff_convert ( /* Converted character, Returns zero on error */
c = chr; c = chr;
} else { } else {
if (dir) { /* OEMCP to Unicode */ if (dir) { /* OEM code to Unicode */
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80]; c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
} else { /* Unicode to OEMCP */ } else { /* Unicode to OEM code */
for (c = 0; c < 0x80; c++) { for (c = 0; c < 0x80; c++) {
if (chr == Tbl[c]) break; if (chr == Tbl[c]) break;
} }
@ -525,16 +299,90 @@ WCHAR ff_convert ( /* Converted character, Returns zero on error */
} }
WCHAR ff_wtoupper ( /* Upper converted character */
WCHAR chr /* Input character */ WCHAR ff_wtoupper ( /* Returns upper converted character */
WCHAR chr /* Unicode character to be upper converted (BMP only) */
) )
{ {
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 }; /* Compressed upper conversion table */
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 }; static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
int i; /* Basic Latin */
0x0061,0x031A,
/* Latin-1 Supplement */
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
/* Latin Extended-A */
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
/* Latin Extended-B */
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
/* IPA Extensions */
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
/* Greek, Coptic */
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
/* Cyrillic */
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
/* Armenian */
0x0561,0x0426,
0x0000
};
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
/* Phonetic Extensions */
0x1D7D,0x0001,0x2C63,
/* Latin Extended Additional */
0x1E00,0x0196, 0x1EA0,0x015A,
/* Greek Extended */
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
/* Letterlike Symbols */
0x214E,0x0001,0x2132,
/* Number forms */
0x2170,0x0210, 0x2184,0x0001,0x2183,
/* Enclosed Alphanumerics */
0x24D0,0x051A, 0x2C30,0x042F,
/* Latin Extended-C */
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
/* Coptic */
0x2C80,0x0164,
/* Georgian Supplement */
0x2D00,0x0826,
/* Full-width */
0xFF41,0x031A,
0x0000
};
const WCHAR *p;
WCHAR bc, nc, cmd;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ; p = chr < 0x1000 ? cvt1 : cvt2;
for (;;) {
bc = *p++; /* Get block base */
if (!bc || chr < bc) break;
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
if (chr < bc + nc) { /* In the block? */
switch (cmd) {
case 0: chr = p[chr - bc]; break; /* Table conversion */
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
case 2: chr -= 16; break; /* Shift -16 */
case 3: chr -= 32; break; /* Shift -32 */
case 4: chr -= 48; break; /* Shift -48 */
case 5: chr -= 26; break; /* Shift -26 */
case 6: chr += 8; break; /* Shift +8 */
case 7: chr -= 80; break; /* Shift -80 */
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
}
break;
}
if (!cmd) p += nc;
}
return tbl_lower[i] ? tbl_upper[i] : chr; return chr;
} }

View file

@ -16,8 +16,8 @@
/ the f_mount() function fails with FR_INT_ERR. / the f_mount() function fails with FR_INT_ERR.
*/ */
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */ int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding logical drive being processed */ BYTE vol, /* Corresponding volume (logical drive number) */
_SYNC_t *sobj /* Pointer to return the created sync object */ _SYNC_t *sobj /* Pointer to return the created sync object */
) )
{ {
@ -27,7 +27,7 @@ int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */ *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
ret = (int)(*sobj != INVALID_HANDLE_VALUE); ret = (int)(*sobj != INVALID_HANDLE_VALUE);
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */ // *sobj = SyncObjects[vol]; /* uITRON (give a static sync object) */
// ret = 1; /* The initial value of the semaphore must be 1. */ // ret = 1; /* The initial value of the semaphore must be 1. */
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */ // *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
@ -45,11 +45,11 @@ int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any
/* Delete a Synchronization Object */ /* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization /* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj function. When a 0 is returned, / object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR. / the f_mount() function fails with FR_INT_ERR.
*/ */
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */ int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
) )
{ {

View file

@ -10,7 +10,7 @@
#include "cc949.c" #include "cc949.c"
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ #elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#include "cc950.c" #include "cc950.c"
#else /* Small character-set */ #else /* Single Byte Character-Set */
#include "ccsbcs.c" #include "ccsbcs.c"
#endif #endif

View file

@ -492,6 +492,9 @@ const pm_char STR_MODELS_PATH[] PROGMEM = MODELS_PATH;
const pm_char STR_MODELS_EXT[] PROGMEM = MODELS_EXT; const pm_char STR_MODELS_EXT[] PROGMEM = MODELS_EXT;
#endif #endif
const pm_char STR_DELETE_ERROR[] PROGMEM = TR_DELETE_ERROR;
const pm_char STR_CAT_NOT_EMPTY[] PROGMEM = TR_CAT_NOT_EMPTY;
const pm_char STR_WARNING[] PROGMEM = TR_WARNING; const pm_char STR_WARNING[] PROGMEM = TR_WARNING;
const pm_char STR_THROTTLEWARN[] PROGMEM = TR_THROTTLEWARN; const pm_char STR_THROTTLEWARN[] PROGMEM = TR_THROTTLEWARN;
const pm_char STR_ALARMSWARN[] PROGMEM = TR_ALARMSWARN; const pm_char STR_ALARMSWARN[] PROGMEM = TR_ALARMSWARN;

View file

@ -703,7 +703,7 @@ extern const pm_char STR_RESET_BTN[];
#if defined(SDCARD) #if defined(SDCARD)
extern const pm_char STR_BACKUP_MODEL[]; extern const pm_char STR_BACKUP_MODEL[];
extern const pm_char STR_RESTORE_MODEL[]; extern const pm_char STR_RESTORE_MODEL[];
extern const pm_char STR_SDCARD_ERROR[]; extern const pm_char STR_DELETE_ERROR[];
extern const pm_char STR_NO_SDCARD[]; extern const pm_char STR_NO_SDCARD[];
extern const pm_char STR_SDCARD_FULL[]; extern const pm_char STR_SDCARD_FULL[];
extern const pm_char STR_INCOMPATIBLE[]; extern const pm_char STR_INCOMPATIBLE[];
@ -714,6 +714,8 @@ extern const pm_char STR_RESET_BTN[];
#define STR_UPDATE_LIST STR_DELAYDOWN #define STR_UPDATE_LIST STR_DELAYDOWN
#endif #endif
extern const pm_char STR_SDCARD_ERROR[];
extern const pm_char STR_CAT_NOT_EMPTY[];
extern const pm_char STR_WARNING[]; extern const pm_char STR_WARNING[];
extern const pm_char STR_STORAGE_WARNING[]; extern const pm_char STR_STORAGE_WARNING[];
extern const pm_char STR_EEPROM_CONVERTING[]; extern const pm_char STR_EEPROM_CONVERTING[];

View file

@ -925,6 +925,8 @@
#define TR_BACKUP_MODEL "Zálohovat na SD" #define TR_BACKUP_MODEL "Zálohovat na SD"
#define TR_DELETE_MODEL "Smaž model" #define TR_DELETE_MODEL "Smaž model"
#define TR_RESTORE_MODEL "Obnov model z SD" #define TR_RESTORE_MODEL "Obnov model z SD"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "Chyba SD karty" #define TR_SDCARD_ERROR "Chyba SD karty"
#define TR_NO_SDCARD "Není SD karta" #define TR_NO_SDCARD "Není SD karta"
#define TR_SDCARD_FULL "Plná SD karta" #define TR_SDCARD_FULL "Plná SD karta"
@ -937,7 +939,7 @@
#define TR_ALARMSWARN "ALARMU" #define TR_ALARMSWARN "ALARMU"
#define TR_SWITCHWARN "POZICE" #define TR_SWITCHWARN "POZICE"
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Chybná verze souborů na kartě" #define TR_WRONG_SDCARDVERSION "Doporučená ver.: "
#define TR_WRONG_PCBREV "Jiná verze PCB/firmware" #define TR_WRONG_PCBREV "Jiná verze PCB/firmware"
#define TR_EMERGENCY_MODE "NOUZOVÝ REŽIM" #define TR_EMERGENCY_MODE "NOUZOVÝ REŽIM"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

File diff suppressed because it is too large Load diff

View file

@ -894,6 +894,8 @@
#define TR_BACKUP_MODEL "Backup model" #define TR_BACKUP_MODEL "Backup model"
#define TR_DELETE_MODEL "Delete model" #define TR_DELETE_MODEL "Delete model"
#define TR_RESTORE_MODEL "Restore model" #define TR_RESTORE_MODEL "Restore model"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR TR("SD error", "SD card error") #define TR_SDCARD_ERROR TR("SD error", "SD card error")
#define TR_NO_SDCARD "No SD card" #define TR_NO_SDCARD "No SD card"
#define TR_SDCARD_FULL "SD card full" #define TR_SDCARD_FULL "SD card full"
@ -906,7 +908,7 @@
#define TR_ALARMSWARN "ALARMS" #define TR_ALARMSWARN "ALARMS"
#define TR_SWITCHWARN TR("SWITCH", "CONTROL") #define TR_SWITCHWARN TR("SWITCH", "CONTROL")
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Wrong files version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -873,6 +873,8 @@
#define TR_BACKUP_MODEL "Copia Sgdad Mod." #define TR_BACKUP_MODEL "Copia Sgdad Mod."
#define TR_DELETE_MODEL "Borrar Modelo" #define TR_DELETE_MODEL "Borrar Modelo"
#define TR_RESTORE_MODEL "Restaurar Modelo" #define TR_RESTORE_MODEL "Restaurar Modelo"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SDCARD Error" #define TR_SDCARD_ERROR "SDCARD Error"
#define TR_NO_SDCARD "No SDCARD" #define TR_NO_SDCARD "No SDCARD"
#define TR_SDCARD_FULL "SD Card Full" #define TR_SDCARD_FULL "SD Card Full"
@ -885,7 +887,7 @@
#define TR_ALARMSWARN "ALARMAS" #define TR_ALARMSWARN "ALARMAS"
#define TR_SWITCHWARN "INTERPTOR" #define TR_SWITCHWARN "INTERPTOR"
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Wrong files version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -873,6 +873,8 @@
#define TR_BACKUP_MODEL "Backup Model" #define TR_BACKUP_MODEL "Backup Model"
#define TR_DELETE_MODEL "Delete Model" #define TR_DELETE_MODEL "Delete Model"
#define TR_RESTORE_MODEL "Restore Model" #define TR_RESTORE_MODEL "Restore Model"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SDCARD Error" #define TR_SDCARD_ERROR "SDCARD Error"
#define TR_NO_SDCARD "No SDCARD" #define TR_NO_SDCARD "No SDCARD"
#define TR_SDCARD_FULL "SD Card Full" #define TR_SDCARD_FULL "SD Card Full"
@ -885,7 +887,7 @@
#define TR_ALARMSWARN "ALARMS" #define TR_ALARMSWARN "ALARMS"
#define TR_SWITCHWARN TR("SWITCH","CONTROL") #define TR_SWITCHWARN TR("SWITCH","CONTROL")
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Wrong files version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -905,6 +905,8 @@
#define TR_BACKUP_MODEL "Archiver modèle" #define TR_BACKUP_MODEL "Archiver modèle"
#define TR_DELETE_MODEL "Supprimer modèle" #define TR_DELETE_MODEL "Supprimer modèle"
#define TR_RESTORE_MODEL "Restaurer modèle" #define TR_RESTORE_MODEL "Restaurer modèle"
#define TR_DELETE_ERROR "Effacement impossible"
#define TR_CAT_NOT_EMPTY "Categorie non vide"
#define TR_SDCARD_ERROR "Erreur carte SD" #define TR_SDCARD_ERROR "Erreur carte SD"
#define TR_NO_SDCARD "Carte SD indisponible" #define TR_NO_SDCARD "Carte SD indisponible"
#define TR_SDCARD_FULL "Carte SD pleine" #define TR_SDCARD_FULL "Carte SD pleine"
@ -917,7 +919,7 @@
#define TR_ALARMSWARN "SON" #define TR_ALARMSWARN "SON"
#define TR_SWITCHWARN TR("INTERS","CONTROLES") #define TR_SWITCHWARN TR("INTERS","CONTROLES")
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Version des fichiers incompatible" #define TR_WRONG_SDCARDVERSION "Version requise : "
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -908,6 +908,8 @@
#define TR_BACKUP_MODEL "Salva Modello" #define TR_BACKUP_MODEL "Salva Modello"
#define TR_DELETE_MODEL TR("Elim. Modello","Elimina Modello") // TODO merged into DELETEMODEL? #define TR_DELETE_MODEL TR("Elim. Modello","Elimina Modello") // TODO merged into DELETEMODEL?
#define TR_RESTORE_MODEL TR("Ripr. Modello","Ripristina Modello") #define TR_RESTORE_MODEL TR("Ripr. Modello","Ripristina Modello")
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "Errore SD" #define TR_SDCARD_ERROR "Errore SD"
#define TR_NO_SDCARD "No SDCARD" #define TR_NO_SDCARD "No SDCARD"
#define TR_SDCARD_FULL "SD Card Piena" #define TR_SDCARD_FULL "SD Card Piena"
@ -920,7 +922,7 @@
#define TR_ALARMSWARN "ALLARMI" #define TR_ALARMSWARN "ALLARMI"
#define TR_SWITCHWARN "CONTROLLI" #define TR_SWITCHWARN "CONTROLLI"
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Wrong files version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -902,6 +902,8 @@
#define TR_BACKUP_MODEL "Backup Model" #define TR_BACKUP_MODEL "Backup Model"
#define TR_DELETE_MODEL "Wis Model" #define TR_DELETE_MODEL "Wis Model"
#define TR_RESTORE_MODEL "Model Terugzetten" #define TR_RESTORE_MODEL "Model Terugzetten"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SD-Kaart fout" #define TR_SDCARD_ERROR "SD-Kaart fout"
#define TR_NO_SDCARD "Geen SD-Kaart" #define TR_NO_SDCARD "Geen SD-Kaart"
#define TR_SDCARD_FULL "SD-Kaart vol" #define TR_SDCARD_FULL "SD-Kaart vol"
@ -914,7 +916,7 @@
#define TR_ALARMSWARN "ALARM" #define TR_ALARMSWARN "ALARM"
#define TR_SWITCHWARN "SCHAKELAAR" #define TR_SWITCHWARN "SCHAKELAAR"
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Verkeerde versie van bestanden" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Verkeerde PCB gedetecteerd" #define TR_WRONG_PCBREV "Verkeerde PCB gedetecteerd"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB fout" #define TR_PCBREV_ERROR "PCB fout"

View file

@ -910,6 +910,8 @@
#define TR_BACKUP_MODEL "Zbackupuj model" #define TR_BACKUP_MODEL "Zbackupuj model"
#define TR_DELETE_MODEL "Skasuj model" #define TR_DELETE_MODEL "Skasuj model"
#define TR_RESTORE_MODEL "Odtwórz model" #define TR_RESTORE_MODEL "Odtwórz model"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "Błąd karty SD" #define TR_SDCARD_ERROR "Błąd karty SD"
#define TR_NO_SDCARD "Brak karty SD" #define TR_NO_SDCARD "Brak karty SD"
#define TR_SDCARD_FULL "Karta Pełna " #define TR_SDCARD_FULL "Karta Pełna "
@ -922,7 +924,7 @@
#define TR_ALARMSWARN "ALARM" #define TR_ALARMSWARN "ALARM"
#define TR_SWITCHWARN TR("Przełą","Kontrola") #define TR_SWITCHWARN TR("Przełą","Kontrola")
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Wrong files version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -868,6 +868,8 @@
#define TR_BACKUP_MODEL "Salvar Modelo" #define TR_BACKUP_MODEL "Salvar Modelo"
#define TR_DELETE_MODEL "Apagar Modelo" #define TR_DELETE_MODEL "Apagar Modelo"
#define TR_RESTORE_MODEL "Restaura Modelo" #define TR_RESTORE_MODEL "Restaura Modelo"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SDCARD Erro" #define TR_SDCARD_ERROR "SDCARD Erro"
#define TR_NO_SDCARD "Sem SDCARD" #define TR_NO_SDCARD "Sem SDCARD"
#define TR_SDCARD_FULL "SD Card Full" #define TR_SDCARD_FULL "SD Card Full"
@ -880,7 +882,7 @@
#define TR_ALARMSWARN "ALARMES" #define TR_ALARMSWARN "ALARMES"
#define TR_SWITCHWARN "CHAVES" #define TR_SWITCHWARN "CHAVES"
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_WRONG_SDCARDVERSION "Wrong files version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -921,6 +921,8 @@
#define TR_BACKUP_MODEL "Modell-backup" #define TR_BACKUP_MODEL "Modell-backup"
#define TR_DELETE_MODEL "Ta Bort Modell" #define TR_DELETE_MODEL "Ta Bort Modell"
#define TR_RESTORE_MODEL "Återställ Modell" #define TR_RESTORE_MODEL "Återställ Modell"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SDCARD-fel" #define TR_SDCARD_ERROR "SDCARD-fel"
#define TR_NO_SDCARD "SDCARD saknas" #define TR_NO_SDCARD "SDCARD saknas"
#define TR_SDCARD_FULL "SD-kort Fullt" #define TR_SDCARD_FULL "SD-kort Fullt"
@ -934,7 +936,7 @@
#define TR_SWITCHWARN "BRYTARE" #define TR_SWITCHWARN "BRYTARE"
#define TR_FAILSAFEWARN "FAILSAFE" #define TR_FAILSAFEWARN "FAILSAFE"
#define TR_SDCARDVERSIONWARN "SD Card Check" #define TR_SDCARDVERSIONWARN "SD Card Check"
#define TR_WRONG_SDCARDVERSION "Wrong SDCARD file version" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ")
#define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_WRONG_PCBREV "Wrong PCB detected"
#define TR_EMERGENCY_MODE "EMERGENCY MODE" #define TR_EMERGENCY_MODE "EMERGENCY MODE"
#define TR_PCBREV_ERROR "PCB error" #define TR_PCBREV_ERROR "PCB error"

View file

@ -8,8 +8,19 @@ SRCDIR=$1
OUTDIR=$2 OUTDIR=$2
COMMON_OPTIONS="-DALLOW_NIGHTLY_BUILDS=YES -DVERSION_SUFFIX=$3 -DGVARS=YES -DHELI=YES" COMMON_OPTIONS="-DALLOW_NIGHTLY_BUILDS=YES -DVERSION_SUFFIX=$3 -DGVARS=YES -DHELI=YES"
if [ "$(uname)" = "Darwin" ]; then
COMMON_OPTIONS="${COMMON_OPTIONS} -DCMAKE_PREFIX_PATH=~/Qt/5.7/clang_64/ -DCMAKE_OSX_DEPLOYMENT_TARGET='10.9'"
fi
STM32_OPTIONS="${COMMON_OPTIONS} -DLUA=YES" STM32_OPTIONS="${COMMON_OPTIONS} -DLUA=YES"
if [ "$3" == "" ]; then
echo "Usage $0 SRCDIR OUTDIR VERSION_SUFFIX"
exit 1
fi
rm -rf build rm -rf build
mkdir build mkdir build
cd build cd build
@ -46,4 +57,8 @@ make -j2 libsimulator
make -j2 package make -j2 package
cp *.deb ${OUTDIR} if [ "$(uname)" = "Darwin" ]; then
cp *.dmg ${OUTDIR}
else
cp *.deb ${OUTDIR}
fi

View file

@ -35,7 +35,7 @@ docker exec companion rm -rf build
docker exec companion /opentx/code/tools/build-companion.sh /opentx/code /opentx/binaries/ $suffix docker exec companion /opentx/code/tools/build-companion.sh /opentx/code /opentx/binaries/ $suffix
docker stop companion docker stop companion
docker rm companion docker rm companion
cp binaries/*.deb $output/companion/linux/ cp binaries/*.deb $output/companion/linux/opentx-companion-linux-2.2.0$suffix_amd64.deb
# Clean binaries It will be hosting built on demand firmware # Clean binaries It will be hosting built on demand firmware
rm -rf binaries/* rm -rf binaries/*
@ -44,7 +44,7 @@ rm -rf binaries/.lock
# Request companion compilation on Windows # Request companion compilation on Windows
cd $output/companion/windows cd $output/companion/windows
wget -qO- http://winbox.open-tx.org/companion-builds/compile22.php?branch=$branch\&suffix=$suffix wget -qO- http://winbox.open-tx.org/companion-builds/compile22.php?branch=$branch\&suffix=$suffix
wget -O companion-windows-2.2.0$suffix.exe http://winbox.open-tx.org/companion-builds/companion-windows-2.2.0$suffix.exe wget -O opentx-companion-windows-2.2.0$suffix.exe http://winbox.open-tx.org/companion-builds/companion-windows-2.2.0$suffix.exe
chmod -Rf g+w companion-windows-2.2.0$suffix.exe chmod -Rf g+w companion-windows-2.2.0$suffix.exe
# Update windows stamp # Update windows stamp

View file

@ -7,8 +7,10 @@ workdir=/home/opentx/nightly22
output=/var/www/html/2.2/nightly output=/var/www/html/2.2/nightly
# Handle opentx.sdcard.version # Handle opentx.sdcard.version
grep 'set(SDCARD_REVISION' ${workdir}/code/CMakeLists.txt | grep -o '".*"' | sed 's/"//g' > ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version sdcard_version="2.2V"+$(grep 'set(SDCARD_VERSION' ${workdir}/code/CMakeLists.txt | grep -o '".*"' | sed 's/"//g')
grep 'set(SDCARD_REVISION' ${workdir}/code/CMakeLists.txt | grep -o '".*"' | sed 's/"//g' > ${workdir}/code/radio/sdcard/taranis/opentx.sdcard.version echo $sdcard_version > ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version
echo $sdcard_version > ${workdir}/code/radio/sdcard/taranis/opentx.sdcard.version
if cmp --silent ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version ${workdir}/opentx.sdcard.version if cmp --silent ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version ${workdir}/opentx.sdcard.version
then then
exit exit
@ -41,6 +43,8 @@ else
rm -f ${output}/sdcard/*.zip rm -f ${output}/sdcard/*.zip
cd ${workdir}/sdcard/taranis && zip -r ${output}/sdcard/sdcard-taranis.zip * cd ${workdir}/sdcard/taranis && zip -r ${output}/sdcard/sdcard-taranis.zip *
cd ${workdir}/sdcard/horus && zip -r ${output}/sdcard/sdcard-horus.zip * cd ${workdir}/sdcard/horus && zip -r ${output}/sdcard/sdcard-horus.zip *
mv ${output}/sdcard/sdcard-horus.zip ${output}/sdcard/sdcard-horus-$sdcard_version.zip
mv ${output}/sdcard/sdcard-taranis.zip ${output}/sdcard/sdcard-taranis-$sdcard_version.zip
rm -Rf ${workdir}/sdcard rm -Rf ${workdir}/sdcard
fi fi