Merge branch 'master' into nrf52
This commit is contained in:
commit
4cf7fd151e
@ -23,6 +23,7 @@ CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=co
|
|||||||
CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os
|
CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os
|
||||||
CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access
|
CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access
|
||||||
CFLAGS += -Iboards/$(BOARD)
|
CFLAGS += -Iboards/$(BOARD)
|
||||||
|
CFLAGS += $(CFLAGS_MOD)
|
||||||
|
|
||||||
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map
|
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ APP_INC += -Iutil
|
|||||||
APP_INC += -Ibootmgr
|
APP_INC += -Ibootmgr
|
||||||
APP_INC += -I$(BUILD)
|
APP_INC += -I$(BUILD)
|
||||||
APP_INC += -I$(BUILD)/genhdr
|
APP_INC += -I$(BUILD)/genhdr
|
||||||
APP_INC += -I../lib/fatfs
|
|
||||||
APP_INC += -I../lib/mp-readline
|
APP_INC += -I../lib/mp-readline
|
||||||
APP_INC += -I../lib/netutils
|
APP_INC += -I../lib/netutils
|
||||||
APP_INC += -I../lib/timeutils
|
APP_INC += -I../lib/timeutils
|
||||||
@ -29,9 +28,6 @@ APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
|||||||
APP_FATFS_SRC_C = $(addprefix fatfs/src/,\
|
APP_FATFS_SRC_C = $(addprefix fatfs/src/,\
|
||||||
drivers/sflash_diskio.c \
|
drivers/sflash_diskio.c \
|
||||||
drivers/sd_diskio.c \
|
drivers/sd_diskio.c \
|
||||||
option/syscall.c \
|
|
||||||
diskio.c \
|
|
||||||
ffconf.c \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_RTOS_SRC_C = $(addprefix FreeRTOS/Source/,\
|
APP_RTOS_SRC_C = $(addprefix FreeRTOS/Source/,\
|
||||||
@ -81,7 +77,6 @@ APP_MISC_SRC_C = $(addprefix misc/,\
|
|||||||
mpirq.c \
|
mpirq.c \
|
||||||
mperror.c \
|
mperror.c \
|
||||||
mpexception.c \
|
mpexception.c \
|
||||||
mpsystick.c \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_MODS_SRC_C = $(addprefix mods/,\
|
APP_MODS_SRC_C = $(addprefix mods/,\
|
||||||
@ -98,6 +93,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\
|
|||||||
pybpin.c \
|
pybpin.c \
|
||||||
pybi2c.c \
|
pybi2c.c \
|
||||||
pybrtc.c \
|
pybrtc.c \
|
||||||
|
pybflash.c \
|
||||||
pybsd.c \
|
pybsd.c \
|
||||||
pybsleep.c \
|
pybsleep.c \
|
||||||
pybspi.c \
|
pybspi.c \
|
||||||
@ -143,11 +139,12 @@ APP_MAIN_SRC_C = \
|
|||||||
main.c \
|
main.c \
|
||||||
mptask.c \
|
mptask.c \
|
||||||
mpthreadport.c \
|
mpthreadport.c \
|
||||||
serverstask.c
|
serverstask.c \
|
||||||
|
fatfs_port.c \
|
||||||
|
|
||||||
APP_LIB_SRC_C = $(addprefix lib/,\
|
APP_LIB_SRC_C = $(addprefix lib/,\
|
||||||
fatfs/ff.c \
|
oofatfs/ff.c \
|
||||||
fatfs/option/ccsbcs.c \
|
oofatfs/option/unicode.c \
|
||||||
libc/string0.c \
|
libc/string0.c \
|
||||||
mp-readline/readline.c \
|
mp-readline/readline.c \
|
||||||
netutils/netutils.c \
|
netutils/netutils.c \
|
||||||
@ -157,8 +154,6 @@ APP_LIB_SRC_C = $(addprefix lib/,\
|
|||||||
|
|
||||||
APP_STM_SRC_C = $(addprefix stmhal/,\
|
APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||||
bufhelper.c \
|
bufhelper.c \
|
||||||
builtin_open.c \
|
|
||||||
import.c \
|
|
||||||
input.c \
|
input.c \
|
||||||
irq.c \
|
irq.c \
|
||||||
pybstdio.c \
|
pybstdio.c \
|
||||||
|
@ -1,209 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* If a working storage control module is available, it should be */
|
|
||||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
|
||||||
/* This is an example of glue functions to attach various exsisting */
|
|
||||||
/* storage control modules to the FatFs module with a defined API. */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/obj.h"
|
|
||||||
#include "lib/fatfs/ff.h"
|
|
||||||
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
|
|
||||||
#include "sflash_diskio.h" /* Serial flash disk IO API */
|
|
||||||
#include "sd_diskio.h" /* SDCARD disk IO API */
|
|
||||||
#include "inc/hw_types.h"
|
|
||||||
#include "inc/hw_ints.h"
|
|
||||||
#include "inc/hw_memmap.h"
|
|
||||||
#include "rom_map.h"
|
|
||||||
#include "prcm.h"
|
|
||||||
#include "pybrtc.h"
|
|
||||||
#include "timeutils.h"
|
|
||||||
#include "pybsd.h"
|
|
||||||
#include "moduos.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get Drive Status */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_status (
|
|
||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pdrv == PD_FLASH) {
|
|
||||||
return sflash_disk_status();
|
|
||||||
} else {
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
|
||||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
|
||||||
return STA_PROTECT;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return STA_NODISK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Inidialize a Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (
|
|
||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pdrv == PD_FLASH) {
|
|
||||||
if (RES_OK != sflash_disk_init()) {
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
|
||||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
|
||||||
return STA_PROTECT;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return STA_NODISK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_read (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
BYTE *buff, /* Data buffer to store read data */
|
|
||||||
DWORD sector, /* Sector address in LBA */
|
|
||||||
UINT count /* Number of sectors to read */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pdrv == PD_FLASH) {
|
|
||||||
return sflash_disk_read(buff, sector, count);
|
|
||||||
} else {
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
|
||||||
// optimization for the built-in sd card device
|
|
||||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
|
||||||
return sd_disk_read(buff, sector, count);
|
|
||||||
}
|
|
||||||
mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
|
||||||
mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
|
|
||||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
|
|
||||||
}
|
|
||||||
// nothing mounted
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if _USE_WRITE
|
|
||||||
DRESULT disk_write (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
const BYTE *buff, /* Data to be written */
|
|
||||||
DWORD sector, /* Sector address in LBA */
|
|
||||||
UINT count /* Number of sectors to write */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pdrv == PD_FLASH) {
|
|
||||||
return sflash_disk_write(buff, sector, count);
|
|
||||||
} else {
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
|
||||||
// optimization for the built-in sd card device
|
|
||||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
|
||||||
return sd_disk_write(buff, sector, count);
|
|
||||||
}
|
|
||||||
mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
|
||||||
mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
|
|
||||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
|
|
||||||
}
|
|
||||||
// nothing mounted
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Miscellaneous Functions */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if _USE_IOCTL
|
|
||||||
DRESULT disk_ioctl (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
|
||||||
BYTE cmd, /* Control code */
|
|
||||||
void *buff /* Buffer to send/receive control data */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (pdrv == PD_FLASH) {
|
|
||||||
switch (cmd) {
|
|
||||||
case CTRL_SYNC:
|
|
||||||
return sflash_disk_flush();
|
|
||||||
case GET_SECTOR_COUNT:
|
|
||||||
*((DWORD*)buff) = SFLASH_SECTOR_COUNT;
|
|
||||||
return RES_OK;
|
|
||||||
case GET_SECTOR_SIZE:
|
|
||||||
*((DWORD*)buff) = SFLASH_SECTOR_SIZE;
|
|
||||||
return RES_OK;
|
|
||||||
case GET_BLOCK_SIZE:
|
|
||||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
|
||||||
switch (cmd) {
|
|
||||||
case CTRL_SYNC:
|
|
||||||
if (mount_obj->sync[0] != MP_OBJ_NULL) {
|
|
||||||
mp_call_method_n_kw(0, 0, mount_obj->sync);
|
|
||||||
}
|
|
||||||
return RES_OK;
|
|
||||||
case GET_SECTOR_COUNT:
|
|
||||||
// optimization for the built-in sd card device
|
|
||||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
|
||||||
*((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
|
|
||||||
} else {
|
|
||||||
*((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
|
|
||||||
}
|
|
||||||
return RES_OK;
|
|
||||||
case GET_SECTOR_SIZE:
|
|
||||||
*((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
|
|
||||||
return RES_OK;
|
|
||||||
case GET_BLOCK_SIZE:
|
|
||||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
|
||||||
return RES_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// nothing mounted
|
|
||||||
return RES_ERROR;
|
|
||||||
}
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !_FS_READONLY && !_FS_NORTC
|
|
||||||
DWORD get_fattime (
|
|
||||||
void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
timeutils_struct_time_t tm;
|
|
||||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
|
||||||
|
|
||||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
|
||||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
|
||||||
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -39,11 +39,12 @@
|
|||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/oofatfs/diskio.h"
|
||||||
#include "hw_types.h"
|
#include "hw_types.h"
|
||||||
#include "hw_memmap.h"
|
#include "hw_memmap.h"
|
||||||
#include "hw_ints.h"
|
#include "hw_ints.h"
|
||||||
#include "rom_map.h"
|
#include "rom_map.h"
|
||||||
#include "diskio.h"
|
|
||||||
#include "sd_diskio.h"
|
#include "sd_diskio.h"
|
||||||
#include "sdhost.h"
|
#include "sdhost.h"
|
||||||
#include "pin.h"
|
#include "pin.h"
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/oofatfs/diskio.h"
|
||||||
#include "simplelink.h"
|
#include "simplelink.h"
|
||||||
#include "diskio.h"
|
|
||||||
#include "sflash_diskio.h"
|
#include "sflash_diskio.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "modnetwork.h"
|
#include "modnetwork.h"
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/mpstate.h"
|
|
||||||
#include "lib/fatfs/ff.h"
|
|
||||||
#include "lib/fatfs/ffconf.h"
|
|
||||||
#include "lib/fatfs/diskio.h"
|
|
||||||
#include "moduos.h"
|
|
||||||
|
|
||||||
#if _FS_RPATH
|
|
||||||
extern BYTE ff_CurrVol;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
|
||||||
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
|
||||||
if ((*path)[mount_point_len] == '/') {
|
|
||||||
*path += mount_point_len;
|
|
||||||
return true;
|
|
||||||
} else if ((*path)[mount_point_len] == '\0') {
|
|
||||||
*path = "/";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// "path" is the path to lookup; will advance this pointer beyond the volume name.
|
|
||||||
// Returns logical drive number (-1 means invalid path).
|
|
||||||
int ff_get_ldnumber (const TCHAR **path) {
|
|
||||||
if (!(*path)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (**path != '/') {
|
|
||||||
#if _FS_RPATH
|
|
||||||
return ff_CurrVol;
|
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_path(path, "/flash", 6)) {
|
|
||||||
return PD_FLASH;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
|
||||||
if (check_path(path, mount_obj->path, mount_obj->pathlen)) {
|
|
||||||
return mount_obj->vol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ff_get_volname(BYTE vol, TCHAR **dest) {
|
|
||||||
if (vol == PD_FLASH) {
|
|
||||||
memcpy(*dest, "/flash", 6);
|
|
||||||
*dest += 6;
|
|
||||||
} else {
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_volume(vol))) {
|
|
||||||
memcpy(*dest, mount_obj->path, mount_obj->pathlen);
|
|
||||||
*dest += mount_obj->pathlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Sample code of OS dependent controls for FatFs */
|
|
||||||
/* (C)ChaN, 2014 */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "ff.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if _FS_REENTRANT
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Create a Synchronization Object */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called in f_mount() function to create a new
|
|
||||||
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
|
||||||
/ the f_mount() function fails with FR_INT_ERR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
|
|
||||||
BYTE vol, /* Corresponding logical drive being processed */
|
|
||||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
//
|
|
||||||
// *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
|
||||||
// ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
|
|
||||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
|
||||||
|
|
||||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
|
||||||
// ret = (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
vSemaphoreCreateBinary( (*sobj) ); /* FreeRTOS */
|
|
||||||
ret = (int)(*sobj != NULL);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Delete a Synchronization Object */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called in f_mount() function to delete a synchronization
|
|
||||||
/ object that created with ff_cre_syncobj function. When a 0 is returned,
|
|
||||||
/ the f_mount() function fails with FR_INT_ERR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
|
|
||||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
|
|
||||||
// ret = CloseHandle(sobj); /* Win32 */
|
|
||||||
|
|
||||||
// ret = 1; /* uITRON (nothing to do) */
|
|
||||||
|
|
||||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
|
||||||
// ret = (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
vSemaphoreDelete(sobj); /* FreeRTOS */
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Request Grant to Access the Volume */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called on entering file functions to lock the volume.
|
|
||||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
|
||||||
_SYNC_t sobj /* Sync object to wait */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
// ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
|
||||||
|
|
||||||
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
|
||||||
|
|
||||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
|
||||||
// ret = (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Release Grant to Access the Volume */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called on leaving file functions to unlock the volume.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ff_rel_grant (
|
|
||||||
_SYNC_t sobj /* Sync object to be signaled */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// ReleaseMutex(sobj); /* Win32 */
|
|
||||||
|
|
||||||
// sig_sem(sobj); /* uITRON */
|
|
||||||
|
|
||||||
// OSMutexPost(sobj); /* uC/OS-II */
|
|
||||||
|
|
||||||
xSemaphoreGive(sobj); /* FreeRTOS */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Allocate a memory block */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
|
||||||
UINT msize /* Number of bytes to allocate */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Free a memory block */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void ff_memfree (
|
|
||||||
void* mblock /* Pointer to the memory block to free */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
vPortFree(mblock); /* Discard the memory block with POSIX API */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
74
cc3200/fatfs_port.c
Normal file
74
cc3200/fatfs_port.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2017 Damien P. George
|
||||||
|
* Parts of this file are (C)ChaN, 2014, from FatFs option/syscall.c
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/timeutils/timeutils.h"
|
||||||
|
#include "mods/pybrtc.h"
|
||||||
|
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
// Create a Synchronization Object
|
||||||
|
// This function is called in f_mount() function to create a new
|
||||||
|
// synchronization object, such as semaphore and mutex.
|
||||||
|
// A return of 0 indicates failure, and then f_mount() fails with FR_INT_ERR.
|
||||||
|
int ff_cre_syncobj(FATFS *fatfs, _SYNC_t *sobj) {
|
||||||
|
vSemaphoreCreateBinary((*sobj));
|
||||||
|
return (int)(*sobj != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a Synchronization Object
|
||||||
|
// This function is called in f_mount() function to delete a synchronization
|
||||||
|
// object that created with ff_cre_syncobj function.
|
||||||
|
// A return of 0 indicates failure, and then f_mount() fails with FR_INT_ERR.
|
||||||
|
int ff_del_syncobj(_SYNC_t sobj) {
|
||||||
|
vSemaphoreDelete(sobj);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request Grant to Access the Volume
|
||||||
|
// This function is called on entering file functions to lock the volume.
|
||||||
|
// When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||||
|
int ff_req_grant(_SYNC_t sobj) {
|
||||||
|
return (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release Grant to Access the Volume
|
||||||
|
// This function is called on leaving file functions to unlock the volume.
|
||||||
|
void ff_rel_grant(_SYNC_t sobj) {
|
||||||
|
xSemaphoreGive(sobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DWORD get_fattime(void) {
|
||||||
|
timeutils_struct_time_t tm;
|
||||||
|
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||||
|
|
||||||
|
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||||
|
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||||
|
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
||||||
|
}
|
135
cc3200/ftp/ftp.c
135
cc3200/ftp/ftp.c
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
#include "py/mpstate.h"
|
#include "py/mpstate.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
#include "inc/hw_types.h"
|
#include "inc/hw_types.h"
|
||||||
#include "inc/hw_ints.h"
|
#include "inc/hw_ints.h"
|
||||||
#include "inc/hw_memmap.h"
|
#include "inc/hw_memmap.h"
|
||||||
@ -43,7 +46,6 @@
|
|||||||
#include "modusocket.h"
|
#include "modusocket.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "serverstask.h"
|
#include "serverstask.h"
|
||||||
#include "ff.h"
|
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "socketfifo.h"
|
#include "socketfifo.h"
|
||||||
#include "updater.h"
|
#include "updater.h"
|
||||||
@ -115,7 +117,7 @@ typedef struct {
|
|||||||
uint8_t *dBuffer;
|
uint8_t *dBuffer;
|
||||||
uint32_t ctimeout;
|
uint32_t ctimeout;
|
||||||
union {
|
union {
|
||||||
DIR dp;
|
FF_DIR dp;
|
||||||
FIL fp;
|
FIL fp;
|
||||||
};
|
};
|
||||||
int16_t lc_sd;
|
int16_t lc_sd;
|
||||||
@ -192,6 +194,80 @@ static const ftp_month_t ftp_month[] = { { "Jan" }, { "Feb" }, { "Mar" }, { "Apr
|
|||||||
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
||||||
static FIFO_t ftp_socketfifo;
|
static FIFO_t ftp_socketfifo;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
DEFINE VFS WRAPPER FUNCTIONS
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// These wrapper functions are used so that the FTP server can access the
|
||||||
|
// mounted FATFS devices directly without going through the costly mp_vfs_XXX
|
||||||
|
// functions. The latter may raise exceptions and we would then need to wrap
|
||||||
|
// all calls in an nlr handler. The wrapper functions below assume that there
|
||||||
|
// are only FATFS filesystems mounted.
|
||||||
|
|
||||||
|
STATIC FATFS *lookup_path(const TCHAR **path) {
|
||||||
|
mp_vfs_mount_t *fs = mp_vfs_lookup_path(*path, path);
|
||||||
|
if (fs == MP_VFS_NONE || fs == MP_VFS_ROOT) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// here we assume that the mounted device is FATFS
|
||||||
|
return &((fs_user_mount_t*)MP_OBJ_TO_PTR(fs->obj))->fatfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC FRESULT f_open_helper(FIL *fp, const TCHAR *path, BYTE mode) {
|
||||||
|
FATFS *fs = lookup_path(&path);
|
||||||
|
if (fs == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
return f_open(fs, fp, path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC FRESULT f_opendir_helper(FF_DIR *dp, const TCHAR *path) {
|
||||||
|
FATFS *fs = lookup_path(&path);
|
||||||
|
if (fs == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
return f_opendir(fs, dp, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC FRESULT f_stat_helper(const TCHAR *path, FILINFO *fno) {
|
||||||
|
FATFS *fs = lookup_path(&path);
|
||||||
|
if (fs == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
return f_stat(fs, path, fno);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC FRESULT f_mkdir_helper(const TCHAR *path) {
|
||||||
|
FATFS *fs = lookup_path(&path);
|
||||||
|
if (fs == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
return f_mkdir(fs, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC FRESULT f_unlink_helper(const TCHAR *path) {
|
||||||
|
FATFS *fs = lookup_path(&path);
|
||||||
|
if (fs == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
return f_unlink(fs, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC FRESULT f_rename_helper(const TCHAR *path_old, const TCHAR *path_new) {
|
||||||
|
FATFS *fs_old = lookup_path(&path_old);
|
||||||
|
if (fs_old == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
FATFS *fs_new = lookup_path(&path_new);
|
||||||
|
if (fs_new == NULL) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
if (fs_old != fs_new) {
|
||||||
|
return FR_NO_PATH;
|
||||||
|
}
|
||||||
|
return f_rename(fs_new, path_old, path_new);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DECLARE PRIVATE FUNCTIONS
|
DECLARE PRIVATE FUNCTIONS
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -210,7 +286,7 @@ static void ftp_close_cmd_data (void);
|
|||||||
static ftp_cmd_index_t ftp_pop_command (char **str);
|
static ftp_cmd_index_t ftp_pop_command (char **str);
|
||||||
static void ftp_pop_param (char **str, char *param);
|
static void ftp_pop_param (char **str, char *param);
|
||||||
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
||||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
|
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name);
|
||||||
static bool ftp_open_file (const char *path, int mode);
|
static bool ftp_open_file (const char *path, int mode);
|
||||||
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
||||||
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
||||||
@ -604,10 +680,6 @@ static void ftp_process_cmd (void) {
|
|||||||
ftp_result_t result;
|
ftp_result_t result;
|
||||||
FRESULT fres;
|
FRESULT fres;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
|
||||||
fno.lfname = NULL;
|
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ftp_data.closechild = false;
|
ftp_data.closechild = false;
|
||||||
// also use the reply buffer to receive new commands
|
// also use the reply buffer to receive new commands
|
||||||
@ -634,7 +706,7 @@ static void ftp_process_cmd (void) {
|
|||||||
fres = FR_NO_PATH;
|
fres = FR_NO_PATH;
|
||||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||||
ftp_open_child (ftp_path, ftp_scratch_buffer);
|
ftp_open_child (ftp_path, ftp_scratch_buffer);
|
||||||
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir_helper (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
||||||
if (fres == FR_OK) {
|
if (fres == FR_OK) {
|
||||||
f_closedir(&ftp_data.dp);
|
f_closedir(&ftp_data.dp);
|
||||||
}
|
}
|
||||||
@ -653,7 +725,7 @@ static void ftp_process_cmd (void) {
|
|||||||
case E_FTP_CMD_SIZE:
|
case E_FTP_CMD_SIZE:
|
||||||
{
|
{
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||||
// send the size
|
// send the size
|
||||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u", (_u32)fno.fsize);
|
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u", (_u32)fno.fsize);
|
||||||
ftp_send_reply(213, (char *)ftp_data.dBuffer);
|
ftp_send_reply(213, (char *)ftp_data.dBuffer);
|
||||||
@ -665,7 +737,7 @@ static void ftp_process_cmd (void) {
|
|||||||
break;
|
break;
|
||||||
case E_FTP_CMD_MDTM:
|
case E_FTP_CMD_MDTM:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||||
// send the last modified time
|
// send the last modified time
|
||||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u%02u%02u%02u%02u%02u",
|
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u%02u%02u%02u%02u%02u",
|
||||||
1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f,
|
1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f,
|
||||||
@ -773,7 +845,7 @@ static void ftp_process_cmd (void) {
|
|||||||
case E_FTP_CMD_DELE:
|
case E_FTP_CMD_DELE:
|
||||||
case E_FTP_CMD_RMD:
|
case E_FTP_CMD_RMD:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_unlink(ftp_path)) {
|
if (FR_OK == f_unlink_helper(ftp_path)) {
|
||||||
ftp_send_reply(250, NULL);
|
ftp_send_reply(250, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -782,7 +854,7 @@ static void ftp_process_cmd (void) {
|
|||||||
break;
|
break;
|
||||||
case E_FTP_CMD_MKD:
|
case E_FTP_CMD_MKD:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_mkdir(ftp_path)) {
|
if (FR_OK == f_mkdir_helper(ftp_path)) {
|
||||||
ftp_send_reply(250, NULL);
|
ftp_send_reply(250, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -791,7 +863,7 @@ static void ftp_process_cmd (void) {
|
|||||||
break;
|
break;
|
||||||
case E_FTP_CMD_RNFR:
|
case E_FTP_CMD_RNFR:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_stat (ftp_path, &fno)) {
|
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
||||||
ftp_send_reply(350, NULL);
|
ftp_send_reply(350, NULL);
|
||||||
// save the current path
|
// save the current path
|
||||||
strcpy ((char *)ftp_data.dBuffer, ftp_path);
|
strcpy ((char *)ftp_data.dBuffer, ftp_path);
|
||||||
@ -803,7 +875,7 @@ static void ftp_process_cmd (void) {
|
|||||||
case E_FTP_CMD_RNTO:
|
case E_FTP_CMD_RNTO:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
// old path was saved in the data buffer
|
// old path was saved in the data buffer
|
||||||
if (FR_OK == (fres = f_rename ((char *)ftp_data.dBuffer, ftp_path))) {
|
if (FR_OK == (fres = f_rename_helper((char *)ftp_data.dBuffer, ftp_path))) {
|
||||||
ftp_send_reply(250, NULL);
|
ftp_send_reply(250, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -898,24 +970,16 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
|
|||||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
||||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||||
#if _USE_LFN
|
|
||||||
1980 + ((fno->fdate >> 9) & 0x7f), *fno->lfname ? fno->lfname : fno->fname);
|
|
||||||
#else
|
|
||||||
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
|
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
|
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
|
||||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||||
#if _USE_LFN
|
|
||||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, *fno->lfname ? fno->lfname : fno->fname);
|
|
||||||
#else
|
|
||||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
|
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name) {
|
||||||
timeutils_struct_time_t tm;
|
timeutils_struct_time_t tm;
|
||||||
uint32_t tseconds;
|
uint32_t tseconds;
|
||||||
char *type = "d";
|
char *type = "d";
|
||||||
@ -934,7 +998,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool ftp_open_file (const char *path, int mode) {
|
static bool ftp_open_file (const char *path, int mode) {
|
||||||
FRESULT res = f_open(&ftp_data.fp, path, mode);
|
FRESULT res = f_open_helper(&ftp_data.fp, path, mode);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -976,7 +1040,7 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path) {
|
|||||||
ftp_data.listroot = true;
|
ftp_data.listroot = true;
|
||||||
} else {
|
} else {
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
res = f_opendir_helper(&ftp_data.dp, path); /* Open the directory */
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
return E_FTP_RESULT_FAILED;
|
return E_FTP_RESULT_FAILED;
|
||||||
}
|
}
|
||||||
@ -993,9 +1057,6 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
|||||||
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
#if _USE_LFN
|
||||||
fno.lfname = mem_Malloc(_MAX_LFN);
|
|
||||||
fno.lfsize = _MAX_LFN;
|
|
||||||
|
|
||||||
// read up to 2 directory items
|
// read up to 2 directory items
|
||||||
while (listcount < 2) {
|
while (listcount < 2) {
|
||||||
#else
|
#else
|
||||||
@ -1004,17 +1065,20 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
|||||||
#endif
|
#endif
|
||||||
if (ftp_data.listroot) {
|
if (ftp_data.listroot) {
|
||||||
// root directory "hack"
|
// root directory "hack"
|
||||||
if (0 == ftp_data.volcount) {
|
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
|
||||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
int i = ftp_data.volcount;
|
||||||
} else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
|
while (vfs != NULL && i != 0) {
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
|
vfs = vfs->next;
|
||||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
|
i -= 1;
|
||||||
} else {
|
}
|
||||||
|
if (vfs == NULL) {
|
||||||
if (!next) {
|
if (!next) {
|
||||||
// no volume found this time, we are done
|
// no volume found this time, we are done
|
||||||
ftp_data.volcount = 0;
|
ftp_data.volcount = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), vfs->str + 1);
|
||||||
}
|
}
|
||||||
ftp_data.volcount++;
|
ftp_data.volcount++;
|
||||||
} else {
|
} else {
|
||||||
@ -1036,9 +1100,6 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
|||||||
ftp_close_files();
|
ftp_close_files();
|
||||||
}
|
}
|
||||||
*listsize = next;
|
*listsize = next;
|
||||||
#if _USE_LFN
|
|
||||||
mem_Free(fno.lfname);
|
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,19 @@ mp_uint_t mp_hal_ticks_ms(void) {
|
|||||||
return HAL_tickCount;
|
return HAL_tickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The SysTick timer counts down at HAL_FCPU_HZ, so we can use that knowledge
|
||||||
|
// to grab a microsecond counter.
|
||||||
|
mp_uint_t mp_hal_ticks_us(void) {
|
||||||
|
mp_uint_t irq_state = disable_irq();
|
||||||
|
uint32_t counter = SysTickValueGet();
|
||||||
|
uint32_t milliseconds = mp_hal_ticks_ms();
|
||||||
|
enable_irq(irq_state);
|
||||||
|
|
||||||
|
uint32_t load = SysTickPeriodGet();
|
||||||
|
counter = load - counter; // Convert from decrementing to incrementing
|
||||||
|
return (milliseconds * 1000) + ((counter * 1000) / load);
|
||||||
|
}
|
||||||
|
|
||||||
void mp_hal_delay_ms(mp_uint_t delay) {
|
void mp_hal_delay_ms(mp_uint_t delay) {
|
||||||
// only if we are not within interrupt context and interrupts are enabled
|
// only if we are not within interrupt context and interrupts are enabled
|
||||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
||||||
@ -211,4 +224,3 @@ static void hal_TickInit (void) {
|
|||||||
MAP_SysTickEnable();
|
MAP_SysTickEnable();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "hal/utils.h"
|
||||||
|
#include "hal/systick.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DEFINE CONSTANTS
|
DEFINE CONSTANTS
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -64,4 +67,7 @@ extern void HAL_SystemDeInit (void);
|
|||||||
extern void HAL_IncrementTick(void);
|
extern void HAL_IncrementTick(void);
|
||||||
extern void mp_hal_set_interrupt_char (int c);
|
extern void mp_hal_set_interrupt_char (int c);
|
||||||
|
|
||||||
|
#define mp_hal_delay_us(usec) UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec))
|
||||||
|
#define mp_hal_ticks_cpu() (SysTickPeriodGet() - SysTickValueGet())
|
||||||
|
|
||||||
#endif /* CC3200_LAUNCHXL_HAL_CC3200_HAL_H_ */
|
#endif /* CC3200_LAUNCHXL_HAL_CC3200_HAL_H_ */
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
|
||||||
* Copyright (c) 2015 Daniel Campora
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
|
||||||
#include "py/obj.h"
|
|
||||||
#include "py/mphal.h"
|
|
||||||
#include "mpsystick.h"
|
|
||||||
#include "systick.h"
|
|
||||||
#include "inc/hw_types.h"
|
|
||||||
#include "inc/hw_nvic.h"
|
|
||||||
|
|
||||||
#ifdef USE_FREERTOS
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
bool sys_tick_has_passed(uint32_t start_tick, uint32_t delay_ms) {
|
|
||||||
return mp_hal_ticks_ms() - start_tick >= delay_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
// waits until at least delay_ms milliseconds have passed from the sampling of
|
|
||||||
// startTick. Handles overflow properly. Assumes stc was taken from
|
|
||||||
// mp_hal_ticks_ms() some time before calling this function.
|
|
||||||
void sys_tick_wait_at_least(uint32_t start_tick, uint32_t delay_ms) {
|
|
||||||
#ifdef USE_FREERTOS
|
|
||||||
vTaskDelay (delay_ms / portTICK_PERIOD_MS);
|
|
||||||
#else
|
|
||||||
while (!sys_tick_has_passed(start_tick, delay_ms)) {
|
|
||||||
__WFI(); // enter sleep mode, waiting for interrupt
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// The SysTick timer counts down at HAL_FCPU_HZ, so we can use that knowledge
|
|
||||||
// to grab a microsecond counter.
|
|
||||||
// We assume that mp_hal_ticks_ms returns milliseconds.
|
|
||||||
uint32_t sys_tick_get_microseconds(void) {
|
|
||||||
mp_uint_t irq_state = disable_irq();
|
|
||||||
uint32_t counter = SysTickValueGet();
|
|
||||||
uint32_t milliseconds = mp_hal_ticks_ms();
|
|
||||||
enable_irq(irq_state);
|
|
||||||
|
|
||||||
uint32_t load = SysTickPeriodGet();
|
|
||||||
counter = load - counter; // Convert from decrementing to incrementing
|
|
||||||
return (milliseconds * 1000) + ((counter * 1000) / load);
|
|
||||||
}
|
|
@ -33,11 +33,13 @@
|
|||||||
#include "py/objtuple.h"
|
#include "py/objtuple.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/oofatfs/diskio.h"
|
||||||
#include "genhdr/mpversion.h"
|
#include "genhdr/mpversion.h"
|
||||||
#include "moduos.h"
|
#include "moduos.h"
|
||||||
#include "diskio.h"
|
|
||||||
#include "sflash_diskio.h"
|
#include "sflash_diskio.h"
|
||||||
#include "extmod/vfs_fat_file.h"
|
#include "extmod/vfs.h"
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "mpexception.h"
|
#include "mpexception.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@ -59,155 +61,20 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DECLARE PRIVATE DATA
|
DECLARE PRIVATE DATA
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
STATIC uint32_t os_num_mounted_devices;
|
|
||||||
STATIC os_term_dup_obj_t os_term_dup_obj;
|
STATIC os_term_dup_obj_t os_term_dup_obj;
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
DECLARE PRIVATE FUNCTIONS
|
|
||||||
******************************************************************************/
|
|
||||||
STATIC void unmount (os_fs_mount_t *mount_obj);
|
|
||||||
STATIC bool path_equal(const char *path, const char *path_canonical);
|
|
||||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string);
|
|
||||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly);
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DEFINE PUBLIC FUNCTIONS
|
DEFINE PUBLIC FUNCTIONS
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void moduos_init0 (void) {
|
|
||||||
// initialize the mount objects list
|
|
||||||
mp_obj_list_init(&MP_STATE_PORT(mount_obj_list), 0);
|
|
||||||
os_num_mounted_devices = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_fs_mount_t *osmount_find_by_path (const char *path) {
|
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
|
||||||
if (!strcmp(path, mount_obj->path)) {
|
|
||||||
return mount_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol) {
|
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
|
||||||
if (vol == mount_obj->vol) {
|
|
||||||
return mount_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_fs_mount_t *osmount_find_by_device (mp_obj_t device) {
|
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
|
||||||
if (device == mount_obj->device) {
|
|
||||||
return mount_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osmount_unmount_all (void) {
|
void osmount_unmount_all (void) {
|
||||||
|
//TODO
|
||||||
|
/*
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||||
unmount(mount_obj);
|
unmount(mount_obj);
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
DEFINE PRIVATE FUNCTIONS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
// Checks for path equality, ignoring trailing slashes:
|
|
||||||
// path_equal(/, /) -> true
|
|
||||||
// path_equal(/flash//, /flash) -> true
|
|
||||||
// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
|
|
||||||
STATIC bool path_equal(const char *path, const char *path_canonical) {
|
|
||||||
for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
|
|
||||||
}
|
|
||||||
if (*path_canonical != '\0') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (; *path == '/'; ++path) {
|
|
||||||
}
|
|
||||||
return *path == '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string) {
|
|
||||||
// make a string object for this entry
|
|
||||||
mp_obj_t entry_o;
|
|
||||||
if (string) {
|
|
||||||
entry_o = mp_obj_new_str(item, strlen(item), false);
|
|
||||||
} else {
|
|
||||||
entry_o = mp_obj_new_bytes((const byte*)item, strlen(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the entry to the list
|
|
||||||
mp_obj_list_append(dirlist, entry_o);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly) {
|
|
||||||
// is the mount point already in use?
|
|
||||||
FILINFO fno;
|
|
||||||
#if _USE_LFN
|
|
||||||
fno.lfname = NULL;
|
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
// cannot mount twice or on existing paths
|
|
||||||
if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a new object
|
|
||||||
os_fs_mount_t *self = m_new_obj(os_fs_mount_t);
|
|
||||||
self->device = device;
|
|
||||||
self->path = path;
|
|
||||||
self->pathlen = pathlen;
|
|
||||||
self->vol = os_num_mounted_devices + 1; // '/flash' is volume 0
|
|
||||||
|
|
||||||
if (device == (mp_obj_t)&pybsd_obj) {
|
|
||||||
// need to make it different to NULL, otherwise it's read only by default
|
|
||||||
self->writeblocks[0] = mp_const_none;
|
|
||||||
self->sync[0] = MP_OBJ_NULL; // no need to sync the SD card
|
|
||||||
self->count[0] = MP_OBJ_NULL;
|
|
||||||
} else {
|
|
||||||
// load block protocol methods
|
|
||||||
mp_load_method(device, MP_QSTR_readblocks, self->readblocks);
|
|
||||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, self->writeblocks);
|
|
||||||
mp_load_method_maybe(device, MP_QSTR_sync, self->sync);
|
|
||||||
mp_load_method(device, MP_QSTR_count, self->count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
|
||||||
// User can specify read-only device by:
|
|
||||||
// 1. readonly=True keyword argument
|
|
||||||
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
|
||||||
if (readonly) {
|
|
||||||
self->writeblocks[0] = MP_OBJ_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to add it before doing the actual mount, so that the volume can be found
|
|
||||||
mp_obj_list_append(&MP_STATE_PORT(mount_obj_list), self);
|
|
||||||
|
|
||||||
// actually mount it
|
|
||||||
if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
|
|
||||||
// remove it and raise
|
|
||||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// mount succeeded, increment the count
|
|
||||||
os_num_mounted_devices++;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void unmount (os_fs_mount_t *mount_obj) {
|
|
||||||
// remove it from the list and then call FatFs
|
|
||||||
f_mount (NULL, mount_obj->path, 1);
|
|
||||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), mount_obj);
|
|
||||||
os_num_mounted_devices--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -239,193 +106,6 @@ STATIC mp_obj_t os_uname(void) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
||||||
|
|
||||||
/// \function chdir(path)
|
|
||||||
/// Change current directory.
|
|
||||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
|
||||||
const char *path;
|
|
||||||
path = mp_obj_str_get_str(path_in);
|
|
||||||
|
|
||||||
FRESULT res = f_chdrive(path);
|
|
||||||
|
|
||||||
if (res == FR_OK) {
|
|
||||||
res = f_chdir(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != FR_OK) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_getcwd(void) {
|
|
||||||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
|
||||||
FRESULT res = f_getcwd(buf, sizeof buf);
|
|
||||||
if (res != FR_OK) {
|
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
|
||||||
}
|
|
||||||
return mp_obj_new_str(buf, strlen(buf), false);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
|
||||||
bool is_str_type = true;
|
|
||||||
const char *path;
|
|
||||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
|
||||||
|
|
||||||
if (n_args == 1) {
|
|
||||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
|
||||||
is_str_type = false;
|
|
||||||
}
|
|
||||||
path = mp_obj_str_get_str(args[0]);
|
|
||||||
} else {
|
|
||||||
path = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// "hack" to list the root directory
|
|
||||||
if (path[0] == '/' && path[1] == '\0') {
|
|
||||||
// add 'flash' to the list
|
|
||||||
append_dir_item (dir_list, "flash", is_str_type);
|
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
|
||||||
append_dir_item (dir_list, &mount_obj->path[1], is_str_type);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FRESULT res;
|
|
||||||
DIR dir;
|
|
||||||
FILINFO fno;
|
|
||||||
#if _USE_LFN
|
|
||||||
char lfn_buf[_MAX_LFN + 1];
|
|
||||||
fno.lfname = lfn_buf;
|
|
||||||
fno.lfsize = sizeof(lfn_buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
res = f_opendir(&dir, path); /* Open the directory */
|
|
||||||
if (res != FR_OK) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( ; ; ) {
|
|
||||||
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 (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
|
||||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
|
||||||
|
|
||||||
#if _USE_LFN
|
|
||||||
char *fn = *fno.lfname ? fno.lfname : fno.fname;
|
|
||||||
#else
|
|
||||||
char *fn = fno.fname;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// add the entry to the list
|
|
||||||
append_dir_item (dir_list, fn, is_str_type);
|
|
||||||
}
|
|
||||||
f_closedir(&dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir_list;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
|
||||||
const char *path = mp_obj_str_get_str(path_o);
|
|
||||||
FRESULT res = f_mkdir(path);
|
|
||||||
switch (res) {
|
|
||||||
case FR_OK:
|
|
||||||
return mp_const_none;
|
|
||||||
case FR_EXIST:
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
|
|
||||||
const char *old_path = mp_obj_str_get_str(path_in);
|
|
||||||
const char *new_path = mp_obj_str_get_str(path_out);
|
|
||||||
FRESULT res = f_rename(old_path, new_path);
|
|
||||||
switch (res) {
|
|
||||||
case FR_OK:
|
|
||||||
return mp_const_none;
|
|
||||||
default:
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
|
||||||
const char *path = mp_obj_str_get_str(path_o);
|
|
||||||
FRESULT res = f_unlink(path);
|
|
||||||
switch (res) {
|
|
||||||
case FR_OK:
|
|
||||||
return mp_const_none;
|
|
||||||
default:
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
|
||||||
const char *path = mp_obj_str_get_str(path_in);
|
|
||||||
bool isbuilt_in = false;
|
|
||||||
FILINFO fno;
|
|
||||||
FRESULT res;
|
|
||||||
#if _USE_LFN
|
|
||||||
fno.lfname = NULL;
|
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// check on the user mounted devices
|
|
||||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
|
||||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
|
||||||
if (path_equal(path, mount_obj->path)) {
|
|
||||||
isbuilt_in = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_equal(path, "/") || path_equal(path, "/flash") || isbuilt_in) {
|
|
||||||
// stat built-in directory
|
|
||||||
fno.fsize = 0;
|
|
||||||
fno.fdate = 0;
|
|
||||||
fno.ftime = 0;
|
|
||||||
fno.fattrib = AM_DIR;
|
|
||||||
} else if ((res = f_stat(path, &fno)) != FR_OK) {
|
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
|
|
||||||
mp_int_t mode = 0;
|
|
||||||
if (fno.fattrib & AM_DIR) {
|
|
||||||
mode |= 0x4000; // stat.S_IFDIR
|
|
||||||
} else {
|
|
||||||
mode |= 0x8000; // stat.S_IFREG
|
|
||||||
}
|
|
||||||
mp_int_t seconds = timeutils_seconds_since_2000(
|
|
||||||
1980 + ((fno.fdate >> 9) & 0x7f),
|
|
||||||
(fno.fdate >> 5) & 0x0f,
|
|
||||||
fno.fdate & 0x1f,
|
|
||||||
(fno.ftime >> 11) & 0x1f,
|
|
||||||
(fno.ftime >> 5) & 0x3f,
|
|
||||||
2 * (fno.ftime & 0x1f)
|
|
||||||
);
|
|
||||||
t->items[0] = mp_obj_new_int(mode); // st_mode
|
|
||||||
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
|
|
||||||
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
|
|
||||||
t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
|
|
||||||
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
|
|
||||||
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
|
|
||||||
t->items[6] = mp_obj_new_int(fno.fsize); // st_size
|
|
||||||
t->items[7] = mp_obj_new_int(seconds); // st_atime
|
|
||||||
t->items[8] = t->items[7]; // st_mtime
|
|
||||||
t->items[9] = t->items[7]; // st_ctime
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_sync(void) {
|
STATIC mp_obj_t os_sync(void) {
|
||||||
sflash_disk_flush();
|
sflash_disk_flush();
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
@ -443,110 +123,6 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||||
|
|
||||||
STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
static const mp_arg_t mount_args[] = {
|
|
||||||
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
|
||||||
};
|
|
||||||
|
|
||||||
// parse args
|
|
||||||
mp_obj_t device = pos_args[0];
|
|
||||||
mp_obj_t mount_point = pos_args[1];
|
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(mount_args)];
|
|
||||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(mount_args), mount_args, args);
|
|
||||||
|
|
||||||
// get the mount point
|
|
||||||
mp_uint_t pathlen;
|
|
||||||
const char *path_in = mp_obj_str_get_data(mount_point, &pathlen);
|
|
||||||
if (pathlen == 0) {
|
|
||||||
goto invalid_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *path = m_new(char, pathlen + 1);
|
|
||||||
memcpy(path, path_in, pathlen);
|
|
||||||
path[pathlen] = '\0';
|
|
||||||
|
|
||||||
// "remove" any extra slahes at the end
|
|
||||||
while (path[(pathlen - 1)] == '/') {
|
|
||||||
path[--pathlen] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// is the mount point valid?
|
|
||||||
if (pathlen < 2 || path[0] !='/' || strchr(&path[1], '/')) {
|
|
||||||
goto invalid_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now mount it
|
|
||||||
mount(device, path, pathlen, args[0].u_bool);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
|
|
||||||
invalid_args:
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_value_invalid_arguments);
|
|
||||||
}
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
|
|
||||||
const char *path = mp_obj_str_get_str(path_o);
|
|
||||||
|
|
||||||
// '/flash' cannot be unmounted, also not the current working directory
|
|
||||||
if (path_equal(path, "/flash")) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now unmount it
|
|
||||||
os_fs_mount_t *mount_obj;
|
|
||||||
if ((mount_obj = osmount_find_by_path(path))) {
|
|
||||||
unmount (mount_obj);
|
|
||||||
} else {
|
|
||||||
mp_raise_msg(&mp_type_ValueError, mpexception_value_invalid_arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_unmount_obj, os_unmount);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_mkfs(mp_obj_t device) {
|
|
||||||
const char *path = "/__mkfs__mnt__";
|
|
||||||
os_fs_mount_t *mount_obj = NULL;
|
|
||||||
bool unmt = false;
|
|
||||||
FRESULT res;
|
|
||||||
|
|
||||||
if (MP_OBJ_IS_STR_OR_BYTES(device)) {
|
|
||||||
path = mp_obj_str_get_str(device);
|
|
||||||
// otherwise the relative path check will pass...
|
|
||||||
if (path[0] != '/') {
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_value_invalid_arguments);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// mount it briefly
|
|
||||||
mount(device, path, strlen(path), false);
|
|
||||||
unmt = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte sfd = 0;
|
|
||||||
if (!memcmp(path, "/flash", strlen("/flash"))) {
|
|
||||||
sfd = 1;
|
|
||||||
} else if ((mount_obj = osmount_find_by_path(path))) {
|
|
||||||
if (mount_obj->device != (mp_obj_t)&pybsd_obj &&
|
|
||||||
mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count)) < 2048) {
|
|
||||||
sfd = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now format the device
|
|
||||||
res = f_mkfs(path, sfd, 0);
|
|
||||||
|
|
||||||
if (unmt && mount_obj) {
|
|
||||||
unmount (mount_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != FR_OK) {
|
|
||||||
mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkfs_obj, os_mkfs);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_dupterm(uint n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t os_dupterm(uint n_args, const mp_obj_t *args) {
|
||||||
if (n_args == 0) {
|
if (n_args == 0) {
|
||||||
if (MP_STATE_PORT(os_term_dup_obj) == MP_OBJ_NULL) {
|
if (MP_STATE_PORT(os_term_dup_obj) == MP_OBJ_NULL) {
|
||||||
@ -576,22 +152,26 @@ STATIC const mp_map_elem_t os_module_globals_table[] = {
|
|||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||||
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&mp_vfs_chdir_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&mp_vfs_getcwd_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&mp_vfs_listdir_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rename), (mp_obj_t)&os_rename_obj},
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&mp_vfs_mkdir_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_rename), (mp_obj_t)&mp_vfs_rename_obj},
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&mp_vfs_remove_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&mp_vfs_rmdir_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&mp_vfs_stat_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&mp_vfs_remove_obj }, // unlink aliases to remove
|
||||||
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||||
|
|
||||||
// MicroPython additions
|
// MicroPython additions
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj },
|
// removed: mkfs
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj },
|
// renamed: unmount -> umount
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&mp_vfs_mount_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_umount), (mp_obj_t)&mp_vfs_umount_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_VfsFat), (mp_obj_t)&mp_fat_vfs_type },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&os_dupterm_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&os_dupterm_obj },
|
||||||
|
|
||||||
/// \constant sep - separation character used in paths
|
/// \constant sep - separation character used in paths
|
||||||
|
@ -28,22 +28,11 @@
|
|||||||
#ifndef MODUOS_H_
|
#ifndef MODUOS_H_
|
||||||
#define MODUOS_H_
|
#define MODUOS_H_
|
||||||
|
|
||||||
#include "ff.h"
|
#include "py/obj.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DEFINE PUBLIC TYPES
|
DEFINE PUBLIC TYPES
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
typedef struct _os_fs_mount_t {
|
|
||||||
mp_obj_t device;
|
|
||||||
const char *path;
|
|
||||||
mp_uint_t pathlen;
|
|
||||||
mp_obj_t readblocks[4];
|
|
||||||
mp_obj_t writeblocks[4];
|
|
||||||
mp_obj_t sync[2];
|
|
||||||
mp_obj_t count[2];
|
|
||||||
FATFS fatfs;
|
|
||||||
uint8_t vol;
|
|
||||||
} os_fs_mount_t;
|
|
||||||
|
|
||||||
typedef struct _os_term_dup_obj_t {
|
typedef struct _os_term_dup_obj_t {
|
||||||
mp_obj_t stream_o;
|
mp_obj_t stream_o;
|
||||||
@ -54,9 +43,6 @@ typedef struct _os_term_dup_obj_t {
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DECLARE PUBLIC FUNCTIONS
|
DECLARE PUBLIC FUNCTIONS
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void moduos_init0 (void);
|
|
||||||
os_fs_mount_t *osmount_find_by_path (const char *path);
|
|
||||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol);
|
|
||||||
void osmount_unmount_all (void);
|
void osmount_unmount_all (void);
|
||||||
|
|
||||||
#endif // MODUOS_H_
|
#endif // MODUOS_H_
|
||||||
|
@ -522,7 +522,6 @@ STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
|
|||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&mod_usocket_getaddrinfo_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&mod_usocket_getaddrinfo_obj },
|
||||||
|
|
||||||
// class exceptions
|
// class exceptions
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_error), (mp_obj_t)&mp_type_OSError },
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_timeout), (mp_obj_t)&mp_type_TimeoutError },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_timeout), (mp_obj_t)&mp_type_TimeoutError },
|
||||||
|
|
||||||
// class constants
|
// class constants
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/smallint.h"
|
#include "py/smallint.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "extmod/utime_mphal.h"
|
||||||
#include "timeutils.h"
|
#include "timeutils.h"
|
||||||
#include "inc/hw_types.h"
|
#include "inc/hw_types.h"
|
||||||
#include "inc/hw_ints.h"
|
#include "inc/hw_ints.h"
|
||||||
@ -41,7 +42,6 @@
|
|||||||
#include "prcm.h"
|
#include "prcm.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
#include "pybrtc.h"
|
#include "pybrtc.h"
|
||||||
#include "mpsystick.h"
|
|
||||||
#include "mpexception.h"
|
#include "mpexception.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@ -143,38 +143,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
|
|||||||
STATIC mp_obj_t time_sleep_us (mp_obj_t usec_in) {
|
STATIC mp_obj_t time_sleep_us (mp_obj_t usec_in) {
|
||||||
mp_int_t usec = mp_obj_get_int(usec_in);
|
mp_int_t usec = mp_obj_get_int(usec_in);
|
||||||
if (usec > 0) {
|
if (usec > 0) {
|
||||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
|
mp_hal_delay_us(usec);
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
|
||||||
|
|
||||||
STATIC mp_obj_t time_ticks_ms(void) {
|
|
||||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
|
|
||||||
|
|
||||||
STATIC mp_obj_t time_ticks_us(void) {
|
|
||||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds() & MP_SMALL_INT_POSITIVE_MASK);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
|
|
||||||
|
|
||||||
STATIC mp_obj_t time_ticks_cpu(void) {
|
|
||||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
|
||||||
return MP_OBJ_NEW_SMALL_INT((SysTickPeriodGet() - SysTickValueGet()) & MP_SMALL_INT_POSITIVE_MASK);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
|
|
||||||
|
|
||||||
STATIC mp_obj_t time_ticks_diff(mp_obj_t t0, mp_obj_t t1) {
|
|
||||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
|
||||||
uint32_t start = mp_obj_get_int(t0);
|
|
||||||
uint32_t end = mp_obj_get_int(t1);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
|
|
||||||
|
|
||||||
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||||
|
|
||||||
@ -186,10 +160,11 @@ STATIC const mp_map_elem_t time_module_globals_table[] = {
|
|||||||
// MicroPython additions
|
// MicroPython additions
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mp_utime_ticks_ms_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mp_utime_ticks_us_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&mp_utime_ticks_cpu_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_add), (mp_obj_t)&mp_utime_ticks_add_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mp_utime_ticks_diff_obj },
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||||
|
109
cc3200/mods/pybflash.c
Normal file
109
cc3200/mods/pybflash.c
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#include <stdint.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/oofatfs/diskio.h"
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
|
|
||||||
|
#include "fatfs/src/drivers/sflash_diskio.h"
|
||||||
|
#include "mods/pybflash.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
// MicroPython bindings to expose the internal flash as an object with the
|
||||||
|
// block protocol.
|
||||||
|
|
||||||
|
// there is a singleton Flash object
|
||||||
|
STATIC const mp_obj_base_t pyb_flash_obj = {&pyb_flash_type};
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
|
// check arguments
|
||||||
|
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||||
|
|
||||||
|
// return singleton object
|
||||||
|
return (mp_obj_t)&pyb_flash_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_flash_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||||
|
mp_buffer_info_t bufinfo;
|
||||||
|
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||||
|
DRESULT res = sflash_disk_read(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SFLASH_SECTOR_SIZE);
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_readblocks_obj, pyb_flash_readblocks);
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_flash_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||||
|
mp_buffer_info_t bufinfo;
|
||||||
|
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||||
|
DRESULT res = sflash_disk_write(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SFLASH_SECTOR_SIZE);
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_writeblocks_obj, pyb_flash_writeblocks);
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_flash_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||||
|
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||||
|
switch (cmd) {
|
||||||
|
case BP_IOCTL_INIT: return MP_OBJ_NEW_SMALL_INT(sflash_disk_init() != RES_OK);
|
||||||
|
case BP_IOCTL_DEINIT: sflash_disk_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||||
|
case BP_IOCTL_SYNC: sflash_disk_flush(); return MP_OBJ_NEW_SMALL_INT(0);
|
||||||
|
case BP_IOCTL_SEC_COUNT: return MP_OBJ_NEW_SMALL_INT(SFLASH_SECTOR_COUNT);
|
||||||
|
case BP_IOCTL_SEC_SIZE: return MP_OBJ_NEW_SMALL_INT(SFLASH_SECTOR_SIZE);
|
||||||
|
default: return mp_const_none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_ioctl_obj, pyb_flash_ioctl);
|
||||||
|
|
||||||
|
STATIC const mp_map_elem_t pyb_flash_locals_dict_table[] = {
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_flash_readblocks_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_flash_writeblocks_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_flash_ioctl_obj },
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table);
|
||||||
|
|
||||||
|
const mp_obj_type_t pyb_flash_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_Flash,
|
||||||
|
.make_new = pyb_flash_make_new,
|
||||||
|
.locals_dict = (mp_obj_t)&pyb_flash_locals_dict,
|
||||||
|
};
|
||||||
|
|
||||||
|
void pyb_flash_init_vfs(fs_user_mount_t *vfs) {
|
||||||
|
vfs->base.type = &mp_fat_vfs_type;
|
||||||
|
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
|
||||||
|
vfs->fatfs.drv = vfs;
|
||||||
|
vfs->readblocks[0] = (mp_obj_t)&pyb_flash_readblocks_obj;
|
||||||
|
vfs->readblocks[1] = (mp_obj_t)&pyb_flash_obj;
|
||||||
|
vfs->readblocks[2] = (mp_obj_t)sflash_disk_read; // native version
|
||||||
|
vfs->writeblocks[0] = (mp_obj_t)&pyb_flash_writeblocks_obj;
|
||||||
|
vfs->writeblocks[1] = (mp_obj_t)&pyb_flash_obj;
|
||||||
|
vfs->writeblocks[2] = (mp_obj_t)sflash_disk_write; // native version
|
||||||
|
vfs->u.ioctl[0] = (mp_obj_t)&pyb_flash_ioctl_obj;
|
||||||
|
vfs->u.ioctl[1] = (mp_obj_t)&pyb_flash_obj;
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
* Copyright (c) 2017 Damien P. George
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -23,14 +23,13 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
#ifndef MICROPY_INCLUDED_CC3200_MODS_PYBFLASH_H
|
||||||
|
#define MICROPY_INCLUDED_CC3200_MODS_PYBFLASH_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "py/obj.h"
|
||||||
|
|
||||||
#include "py/lexer.h"
|
extern const mp_obj_type_t pyb_flash_type;
|
||||||
#include "lib/fatfs/ff.h"
|
|
||||||
|
|
||||||
mp_import_stat_t fat_vfs_import_stat(const char *path);
|
void pyb_flash_init_vfs(fs_user_mount_t *vfs);
|
||||||
|
|
||||||
mp_import_stat_t mp_import_stat(const char *path) {
|
#endif // MICROPY_INCLUDED_CC3200_MODS_PYBFLASH_H
|
||||||
return fat_vfs_import_stat(path);
|
|
||||||
}
|
|
@ -27,6 +27,9 @@
|
|||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/oofatfs/diskio.h"
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
#include "inc/hw_types.h"
|
#include "inc/hw_types.h"
|
||||||
#include "inc/hw_gpio.h"
|
#include "inc/hw_gpio.h"
|
||||||
#include "inc/hw_ints.h"
|
#include "inc/hw_ints.h"
|
||||||
@ -36,8 +39,6 @@
|
|||||||
#include "prcm.h"
|
#include "prcm.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "sdhost.h"
|
#include "sdhost.h"
|
||||||
#include "ff.h"
|
|
||||||
#include "diskio.h"
|
|
||||||
#include "sd_diskio.h"
|
#include "sd_diskio.h"
|
||||||
#include "pybsd.h"
|
#include "pybsd.h"
|
||||||
#include "mpexception.h"
|
#include "mpexception.h"
|
||||||
@ -163,9 +164,50 @@ STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sd_deinit_obj, pyb_sd_deinit);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sd_deinit_obj, pyb_sd_deinit);
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_sd_readblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||||
|
mp_buffer_info_t bufinfo;
|
||||||
|
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
|
||||||
|
DRESULT res = sd_disk_read(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SD_SECTOR_SIZE);
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_readblocks_obj, pyb_sd_readblocks);
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_sd_writeblocks(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
|
||||||
|
mp_buffer_info_t bufinfo;
|
||||||
|
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
|
||||||
|
DRESULT res = sd_disk_write(bufinfo.buf, mp_obj_get_int(block_num), bufinfo.len / SD_SECTOR_SIZE);
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(res != RES_OK); // return of 0 means success
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_writeblocks_obj, pyb_sd_writeblocks);
|
||||||
|
|
||||||
|
STATIC mp_obj_t pyb_sd_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||||
|
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||||
|
switch (cmd) {
|
||||||
|
case BP_IOCTL_INIT:
|
||||||
|
case BP_IOCTL_DEINIT:
|
||||||
|
case BP_IOCTL_SYNC:
|
||||||
|
// nothing to do
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(0); // success
|
||||||
|
|
||||||
|
case BP_IOCTL_SEC_COUNT:
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512));
|
||||||
|
|
||||||
|
case BP_IOCTL_SEC_SIZE:
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(SD_SECTOR_SIZE);
|
||||||
|
|
||||||
|
default: // unknown command
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(-1); // error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sd_ioctl_obj, pyb_sd_ioctl);
|
||||||
|
|
||||||
STATIC const mp_map_elem_t pyb_sd_locals_dict_table[] = {
|
STATIC const mp_map_elem_t pyb_sd_locals_dict_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_sd_init_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_sd_init_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_sd_deinit_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_sd_deinit_obj },
|
||||||
|
// block device protocol
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_sd_readblocks_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_sd_writeblocks_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_sd_ioctl_obj },
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table);
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||||
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
||||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
||||||
#define MICROPY_READER_FATFS (1)
|
#define MICROPY_READER_VFS (1)
|
||||||
#ifndef DEBUG // we need ram on the launchxl while debugging
|
#ifndef DEBUG // we need ram on the launchxl while debugging
|
||||||
#define MICROPY_CPYTHON_COMPAT (1)
|
#define MICROPY_CPYTHON_COMPAT (1)
|
||||||
#else
|
#else
|
||||||
@ -68,15 +68,15 @@
|
|||||||
#define MICROPY_FATFS_MAX_LFN (MICROPY_ALLOC_PATH_MAX)
|
#define MICROPY_FATFS_MAX_LFN (MICROPY_ALLOC_PATH_MAX)
|
||||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
|
#define MICROPY_FATFS_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
|
||||||
#define MICROPY_FATFS_RPATH (2)
|
#define MICROPY_FATFS_RPATH (2)
|
||||||
#define MICROPY_FATFS_VOLUMES (2)
|
|
||||||
#define MICROPY_FATFS_REENTRANT (1)
|
#define MICROPY_FATFS_REENTRANT (1)
|
||||||
#define MICROPY_FATFS_TIMEOUT (2500)
|
#define MICROPY_FATFS_TIMEOUT (2500)
|
||||||
#define MICROPY_FATFS_SYNC_T SemaphoreHandle_t
|
#define MICROPY_FATFS_SYNC_T SemaphoreHandle_t
|
||||||
#define MICROPY_FSUSERMOUNT_ADHOC (1)
|
|
||||||
|
|
||||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||||
|
#define MICROPY_VFS (1)
|
||||||
|
#define MICROPY_VFS_FAT (1)
|
||||||
#define MICROPY_PY_ASYNC_AWAIT (0)
|
#define MICROPY_PY_ASYNC_AWAIT (0)
|
||||||
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (1)
|
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (1)
|
||||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
||||||
@ -116,10 +116,20 @@
|
|||||||
#define MICROPY_PY_UHEAPQ (0)
|
#define MICROPY_PY_UHEAPQ (0)
|
||||||
#define MICROPY_PY_UHASHLIB (0)
|
#define MICROPY_PY_UHASHLIB (0)
|
||||||
#define MICROPY_PY_USELECT (1)
|
#define MICROPY_PY_USELECT (1)
|
||||||
|
#define MICROPY_PY_UTIME_MP_HAL (1)
|
||||||
|
|
||||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||||
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
|
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
|
||||||
|
|
||||||
|
// TODO these should be generic, not bound to fatfs
|
||||||
|
#define mp_type_fileio fatfs_type_fileio
|
||||||
|
#define mp_type_textio fatfs_type_textio
|
||||||
|
|
||||||
|
// use vfs's functions for import stat and builtin open
|
||||||
|
#define mp_import_stat mp_vfs_import_stat
|
||||||
|
#define mp_builtin_open mp_vfs_open
|
||||||
|
#define mp_builtin_open_obj mp_vfs_open_obj
|
||||||
|
|
||||||
// extra built in names to add to the global namespace
|
// extra built in names to add to the global namespace
|
||||||
#define MICROPY_PORT_BUILTINS \
|
#define MICROPY_PORT_BUILTINS \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
|
||||||
@ -174,7 +184,6 @@ extern const struct _mp_obj_module_t mp_module_ussl;
|
|||||||
mp_obj_list_t pyb_sleep_obj_list; \
|
mp_obj_list_t pyb_sleep_obj_list; \
|
||||||
mp_obj_list_t mp_irq_obj_list; \
|
mp_obj_list_t mp_irq_obj_list; \
|
||||||
mp_obj_list_t pyb_timer_channel_obj_list; \
|
mp_obj_list_t pyb_timer_channel_obj_list; \
|
||||||
mp_obj_list_t mount_obj_list; \
|
|
||||||
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
|
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
|
||||||
struct _os_term_dup_obj_t *os_term_dup_obj; \
|
struct _os_term_dup_obj_t *os_term_dup_obj; \
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/gc.h"
|
#include "py/gc.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "lib/oofatfs/diskio.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
#include "inc/hw_memmap.h"
|
#include "inc/hw_memmap.h"
|
||||||
#include "inc/hw_types.h"
|
#include "inc/hw_types.h"
|
||||||
#include "inc/hw_ints.h"
|
#include "inc/hw_ints.h"
|
||||||
@ -56,13 +60,12 @@
|
|||||||
#include "serverstask.h"
|
#include "serverstask.h"
|
||||||
#include "telnet.h"
|
#include "telnet.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "ff.h"
|
|
||||||
#include "diskio.h"
|
|
||||||
#include "sflash_diskio.h"
|
#include "sflash_diskio.h"
|
||||||
#include "mpexception.h"
|
#include "mpexception.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "pybi2c.h"
|
#include "pybi2c.h"
|
||||||
#include "pins.h"
|
#include "pins.h"
|
||||||
|
#include "mods/pybflash.h"
|
||||||
#include "pybsleep.h"
|
#include "pybsleep.h"
|
||||||
#include "pybtimer.h"
|
#include "pybtimer.h"
|
||||||
#include "cryptohash.h"
|
#include "cryptohash.h"
|
||||||
@ -94,7 +97,8 @@ OsiTaskHandle svTaskHandle;
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DECLARE PRIVATE DATA
|
DECLARE PRIVATE DATA
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static FATFS *sflash_fatfs;
|
static fs_user_mount_t *sflash_vfs_fat;
|
||||||
|
static mp_vfs_mount_t sflash_vfs_mount;
|
||||||
|
|
||||||
static const char fresh_main_py[] = "# main.py -- put your code here!\r\n";
|
static const char fresh_main_py[] = "# main.py -- put your code here!\r\n";
|
||||||
static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n"
|
static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n"
|
||||||
@ -149,7 +153,6 @@ soft_reset:
|
|||||||
timer_init0();
|
timer_init0();
|
||||||
readline_init0();
|
readline_init0();
|
||||||
mod_network_init0();
|
mod_network_init0();
|
||||||
moduos_init0();
|
|
||||||
rng_init0();
|
rng_init0();
|
||||||
|
|
||||||
pybsleep_reset_cause_t rstcause = pyb_sleep_get_reset_cause();
|
pybsleep_reset_cause_t rstcause = pyb_sleep_get_reset_cause();
|
||||||
@ -270,7 +273,7 @@ STATIC void mptask_pre_init (void) {
|
|||||||
ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY));
|
ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY));
|
||||||
|
|
||||||
// Allocate memory for the flash file system
|
// Allocate memory for the flash file system
|
||||||
ASSERT ((sflash_fatfs = mem_Malloc(sizeof(FATFS))) != NULL);
|
ASSERT ((sflash_vfs_fat = mem_Malloc(sizeof(*sflash_vfs_fat))) != NULL);
|
||||||
|
|
||||||
// this one allocates memory for the nvic vault
|
// this one allocates memory for the nvic vault
|
||||||
pyb_sleep_pre_init();
|
pyb_sleep_pre_init();
|
||||||
@ -296,17 +299,21 @@ STATIC void mptask_pre_init (void) {
|
|||||||
|
|
||||||
STATIC void mptask_init_sflash_filesystem (void) {
|
STATIC void mptask_init_sflash_filesystem (void) {
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
|
||||||
fno.lfname = NULL;
|
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initialise the local flash filesystem.
|
// Initialise the local flash filesystem.
|
||||||
|
// init the vfs object
|
||||||
|
fs_user_mount_t *vfs_fat = sflash_vfs_fat;
|
||||||
|
vfs_fat->str = NULL;
|
||||||
|
vfs_fat->len = 0;
|
||||||
|
vfs_fat->flags = 0;
|
||||||
|
pyb_flash_init_vfs(vfs_fat);
|
||||||
|
|
||||||
// Create it if needed, and mount in on /flash.
|
// Create it if needed, and mount in on /flash.
|
||||||
FRESULT res = f_mount(sflash_fatfs, "/flash", 1);
|
FRESULT res = f_mount(&vfs_fat->fatfs);
|
||||||
if (res == FR_NO_FILESYSTEM) {
|
if (res == FR_NO_FILESYSTEM) {
|
||||||
// no filesystem, so create a fresh one
|
// no filesystem, so create a fresh one
|
||||||
res = f_mkfs("/flash", 1, 0);
|
uint8_t working_buf[_MAX_SS];
|
||||||
|
res = f_mkfs(&vfs_fat->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
// success creating fresh LFS
|
// success creating fresh LFS
|
||||||
} else {
|
} else {
|
||||||
@ -316,7 +323,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
|||||||
mptask_create_main_py();
|
mptask_create_main_py();
|
||||||
} else if (res == FR_OK) {
|
} else if (res == FR_OK) {
|
||||||
// mount sucessful
|
// mount sucessful
|
||||||
if (FR_OK != f_stat("/flash/main.py", &fno)) {
|
if (FR_OK != f_stat(&vfs_fat->fatfs, "/main.py", &fno)) {
|
||||||
// create empty main.py
|
// create empty main.py
|
||||||
mptask_create_main_py();
|
mptask_create_main_py();
|
||||||
}
|
}
|
||||||
@ -324,25 +331,33 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
|||||||
__fatal_error("failed to create /flash");
|
__fatal_error("failed to create /flash");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mount the flash device (there should be no other devices mounted at this point)
|
||||||
|
mp_vfs_mount_t *vfs = &sflash_vfs_mount;
|
||||||
|
vfs->str = "/flash";
|
||||||
|
vfs->len = 6;
|
||||||
|
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
|
||||||
|
vfs->next = NULL;
|
||||||
|
MP_STATE_VM(vfs_mount_table) = vfs;
|
||||||
|
|
||||||
// The current directory is used as the boot up directory.
|
// The current directory is used as the boot up directory.
|
||||||
// It is set to the internal flash filesystem by default.
|
// It is set to the internal flash filesystem by default.
|
||||||
f_chdrive("/flash");
|
MP_STATE_PORT(vfs_cur) = vfs;
|
||||||
|
|
||||||
// create /flash/sys, /flash/lib and /flash/cert if they don't exist
|
// create /flash/sys, /flash/lib and /flash/cert if they don't exist
|
||||||
if (FR_OK != f_chdir ("/flash/sys")) {
|
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/sys")) {
|
||||||
f_mkdir("/flash/sys");
|
f_mkdir(&vfs_fat->fatfs, "/sys");
|
||||||
}
|
}
|
||||||
if (FR_OK != f_chdir ("/flash/lib")) {
|
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/lib")) {
|
||||||
f_mkdir("/flash/lib");
|
f_mkdir(&vfs_fat->fatfs, "/lib");
|
||||||
}
|
}
|
||||||
if (FR_OK != f_chdir ("/flash/cert")) {
|
if (FR_OK != f_chdir(&vfs_fat->fatfs, "/cert")) {
|
||||||
f_mkdir("/flash/cert");
|
f_mkdir(&vfs_fat->fatfs, "/cert");
|
||||||
}
|
}
|
||||||
|
|
||||||
f_chdir ("/flash");
|
f_chdir(&vfs_fat->fatfs, "/");
|
||||||
|
|
||||||
// make sure we have a /flash/boot.py. Create it if needed.
|
// make sure we have a /flash/boot.py. Create it if needed.
|
||||||
res = f_stat("/flash/boot.py", &fno);
|
res = f_stat(&vfs_fat->fatfs, "/boot.py", &fno);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
if (fno.fattrib & AM_DIR) {
|
if (fno.fattrib & AM_DIR) {
|
||||||
// exists as a directory
|
// exists as a directory
|
||||||
@ -354,7 +369,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
|||||||
} else {
|
} else {
|
||||||
// doesn't exist, create fresh file
|
// doesn't exist, create fresh file
|
||||||
FIL fp;
|
FIL fp;
|
||||||
f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
f_open(&vfs_fat->fatfs, &fp, "/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
UINT n;
|
UINT n;
|
||||||
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
|
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
|
||||||
// TODO check we could write n bytes
|
// TODO check we could write n bytes
|
||||||
@ -374,9 +389,8 @@ STATIC void mptask_enter_ap_mode (void) {
|
|||||||
STATIC void mptask_create_main_py (void) {
|
STATIC void mptask_create_main_py (void) {
|
||||||
// create empty main.py
|
// create empty main.py
|
||||||
FIL fp;
|
FIL fp;
|
||||||
f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
f_open(&sflash_vfs_fat->fatfs, &fp, "/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||||
UINT n;
|
UINT n;
|
||||||
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
|
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
docs/conf.py
10
docs/conf.py
@ -90,7 +90,7 @@ source_suffix = '.rst'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'MicroPython'
|
project = 'MicroPython'
|
||||||
copyright = '2014-2016, Damien P. George and contributors'
|
copyright = '2014-2017, Damien P. George, Paul Sokolovsky, and contributors'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
@ -178,7 +178,7 @@ else:
|
|||||||
# The name of an image file (within the static path) to use as favicon of the
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
# pixels large.
|
# pixels large.
|
||||||
#html_favicon = None
|
html_favicon = 'favicon.ico'
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
@ -253,7 +253,7 @@ latex_elements = {
|
|||||||
# author, documentclass [howto, manual, or own class]).
|
# author, documentclass [howto, manual, or own class]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, 'MicroPython.tex', 'MicroPython Documentation',
|
(master_doc, 'MicroPython.tex', 'MicroPython Documentation',
|
||||||
'Damien P. George and contributors', 'manual'),
|
'Damien P. George, Paul Sokolovsky, and contributors', 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
@ -283,7 +283,7 @@ latex_documents = [
|
|||||||
# (source start file, name, description, authors, manual section).
|
# (source start file, name, description, authors, manual section).
|
||||||
man_pages = [
|
man_pages = [
|
||||||
('index', 'micropython', 'MicroPython Documentation',
|
('index', 'micropython', 'MicroPython Documentation',
|
||||||
['Damien P. George and contributors'], 1),
|
['Damien P. George, Paul Sokolovsky, and contributors'], 1),
|
||||||
]
|
]
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
# If true, show URL addresses after external links.
|
||||||
@ -297,7 +297,7 @@ man_pages = [
|
|||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
(master_doc, 'MicroPython', 'MicroPython Documentation',
|
(master_doc, 'MicroPython', 'MicroPython Documentation',
|
||||||
'Damien P. George and contributors', 'MicroPython', 'One line description of project.',
|
'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.',
|
||||||
'Miscellaneous'),
|
'Miscellaneous'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ terminal programs that will work, so pick your favourite!
|
|||||||
|
|
||||||
For example, on Linux you can try running::
|
For example, on Linux you can try running::
|
||||||
|
|
||||||
picocom /dev/ttyUSB0
|
picocom /dev/ttyUSB0 -b115200
|
||||||
|
|
||||||
Once you have made the connection over the serial port you can test if it is
|
Once you have made the connection over the serial port you can test if it is
|
||||||
working by hitting enter a few times. You should see the Python REPL prompt,
|
working by hitting enter a few times. You should see the Python REPL prompt,
|
||||||
|
@ -170,6 +170,7 @@ the following libraries.
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
pyb.rst
|
pyb.rst
|
||||||
|
lcd160cr.rst
|
||||||
|
|
||||||
.. only:: port_wipy
|
.. only:: port_wipy
|
||||||
|
|
||||||
|
379
docs/library/lcd160cr.rst
Normal file
379
docs/library/lcd160cr.rst
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
:mod:`lcd160cr` --- control of LCD160CR display
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
.. module:: lcd160cr
|
||||||
|
:synopsis: control of LCD160CR display
|
||||||
|
|
||||||
|
This module provides control of the MicroPython LCD160CR display.
|
||||||
|
|
||||||
|
.. image:: http://micropython.org/resources/LCD160CRv10-persp.jpg
|
||||||
|
:alt: LCD160CRv1.0 picture
|
||||||
|
:width: 640px
|
||||||
|
|
||||||
|
Further resources are available via the following links:
|
||||||
|
|
||||||
|
* `LCD160CRv1.0 reference manual <http://micropython.org/resources/LCD160CRv10-refmanual.pdf>`_ (100KiB PDF)
|
||||||
|
* `LCD160CRv1.0 schematics <http://micropython.org/resources/LCD160CRv10-schematics.pdf>`_ (1.6MiB PDF)
|
||||||
|
|
||||||
|
class LCD160CR
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The LCD160CR class provides an interface to the display. Create an
|
||||||
|
instance of this class and use its methods to draw to the LCD and get
|
||||||
|
the status of the touch panel.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
import lcd160cr
|
||||||
|
|
||||||
|
lcd = lcd160cr.LCD160CR('X')
|
||||||
|
lcd.set_orient(lcd160cr.PORTRAIT)
|
||||||
|
lcd.set_pos(0, 0)
|
||||||
|
lcd.set_text_color(lcd.rgb(255, 0, 0), lcd.rgb(0, 0, 0))
|
||||||
|
lcd.set_font(1)
|
||||||
|
lcd.write('Hello MicroPython!')
|
||||||
|
print('touch:', lcd.get_touch())
|
||||||
|
|
||||||
|
Constructors
|
||||||
|
------------
|
||||||
|
|
||||||
|
.. class:: LCD160CR(connect=None, \*, pwr=None, i2c=None, spi=None, i2c_addr=98)
|
||||||
|
|
||||||
|
Construct an LCD160CR object. The parameters are:
|
||||||
|
|
||||||
|
- `connect` is a string specifying the physical connection of the LCD
|
||||||
|
display to the board; valid values are "X", "Y", "XY", "YX".
|
||||||
|
Use "X" when the display is connected to a pyboard in the X-skin
|
||||||
|
position, and "Y" when connected in the Y-skin position. "XY"
|
||||||
|
and "YX" are used when the display is connected to the right or
|
||||||
|
left side of the pyboard, respectively.
|
||||||
|
- `pwr` is a Pin object connected to the LCD's power/enabled pin.
|
||||||
|
- `i2c` is an I2C object connected to the LCD's I2C interface.
|
||||||
|
- `spi` is an SPI object connected to the LCD's SPI interface.
|
||||||
|
- `i2c_addr` is the I2C address of the display.
|
||||||
|
|
||||||
|
One must specify either a valid `connect` or all of `pwr`, `i2c` and `spi`.
|
||||||
|
If a valid `connect` is given then any of `pwr`, `i2c` or `spi` which are
|
||||||
|
not passed as parameters (ie they are `None`) will be created based on the
|
||||||
|
value of `connect`. This allows to override the default interface to the
|
||||||
|
display if needed.
|
||||||
|
|
||||||
|
The default values are:
|
||||||
|
|
||||||
|
- "X" is for the X-skin and uses:
|
||||||
|
``pwr=Pin("X4")``, ``i2c=I2C("X")``, ``spi=SPI("X")``
|
||||||
|
- "Y" is for the Y-skin and uses:
|
||||||
|
``pwr=Pin("Y4")``, ``i2c=I2C("Y")``, ``spi=SPI("Y")``
|
||||||
|
- "XY" is for the right-side and uses:
|
||||||
|
``pwr=Pin("X4")``, ``i2c=I2C("Y")``, ``spi=SPI("X")``
|
||||||
|
- "YX" is for the left-side and uses:
|
||||||
|
``pwr=Pin("Y4")``, ``i2c=I2C("X")``, ``spi=SPI("Y")``
|
||||||
|
|
||||||
|
See `this image <http://micropython.org/resources/LCD160CRv10-positions.jpg>`_
|
||||||
|
for how the display can be connected to the pyboard.
|
||||||
|
|
||||||
|
Static methods
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. staticmethod:: LCD160CR.rgb(r, g, b)
|
||||||
|
|
||||||
|
Return a 16-bit integer representing the given rgb color values. The
|
||||||
|
16-bit value can be used to set the font color (see
|
||||||
|
:meth:`LCD160CR.set_text_color`) pen color (see :meth:`LCD160CR.set_pen`)
|
||||||
|
and draw individual pixels.
|
||||||
|
|
||||||
|
.. staticmethod:: LCD160CR.clip_line(data, w, h):
|
||||||
|
|
||||||
|
Clip the given line data. This is for internal use.
|
||||||
|
|
||||||
|
Instance members
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The following instance members are publicly accessible.
|
||||||
|
|
||||||
|
.. data:: LCD160CR.w
|
||||||
|
.. data:: LCD160CR.h
|
||||||
|
|
||||||
|
The width and height of the display, respectively, in pixels. These
|
||||||
|
members are updated when calling :meth:`LCD160CR.set_orient` and should
|
||||||
|
be considered read-only.
|
||||||
|
|
||||||
|
Setup commands
|
||||||
|
--------------
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_power(on)
|
||||||
|
|
||||||
|
Turn the display on or off, depending on the given value.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_orient(orient)
|
||||||
|
|
||||||
|
Set the orientation of the display. The `orient` parameter can be one
|
||||||
|
of `PORTRAIT`, `LANDSCAPE`, `PORTRAIT_UPSIDEDOWN`, `LANDSCAPE_UPSIDEDOWN`.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_brightness(value)
|
||||||
|
|
||||||
|
Set the brightness of the display, between 0 and 31.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_i2c_addr(addr)
|
||||||
|
|
||||||
|
Set the I2C address of the display. The `addr` value must have the
|
||||||
|
lower 2 bits cleared.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_uart_baudrate(baudrate)
|
||||||
|
|
||||||
|
Set the baudrate of the UART interface.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_startup_deco(value)
|
||||||
|
|
||||||
|
Set the start-up decoration of the display. The `value` parameter can be a
|
||||||
|
logical or of `STARTUP_DECO_NONE`, `STARTUP_DECO_MLOGO`, `STARTUP_DECO_INFO`.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.save_to_flash()
|
||||||
|
|
||||||
|
Save the following parameters to flash so they persist on restart and power up:
|
||||||
|
initial decoration, orientation, brightness, UART baud rate, I2C address.
|
||||||
|
|
||||||
|
Pixel access methods
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The following methods manipulate individual pixels on the display.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_pixel(x, y, c)
|
||||||
|
|
||||||
|
Set the specified pixel to the given color. The color should be a 16-bit
|
||||||
|
integer and can be created by :meth:`LCD160CR.rgb`.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.get_pixel(x, y)
|
||||||
|
|
||||||
|
Get the 16-bit value of the specified pixel.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.get_line(x, y, buf)
|
||||||
|
|
||||||
|
Get a line of pixels into the given buffer.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.screen_dump(buf)
|
||||||
|
|
||||||
|
Dump the entire screen to the given buffer.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.screen_load(buf)
|
||||||
|
|
||||||
|
Load the entire screen from the given buffer.
|
||||||
|
|
||||||
|
Drawing text
|
||||||
|
------------
|
||||||
|
|
||||||
|
To draw text one sets the position, color and font, and then uses
|
||||||
|
`write` to draw the text.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_pos(x, y)
|
||||||
|
|
||||||
|
Set the position for text output using :meth:`LCD160CR.write`. The position
|
||||||
|
is the upper-left corner of the text.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_text_color(fg, bg)
|
||||||
|
|
||||||
|
Set the foreground and background color of the text.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_font(font, scale=0, bold=0, trans=0, scroll=0)
|
||||||
|
|
||||||
|
Set the font for the text. Subsequent calls to `write` will use the newly
|
||||||
|
configured font. The parameters are:
|
||||||
|
|
||||||
|
- `font` is the font family to use, valid values are 0, 1, 2, 3.
|
||||||
|
- `scale` is a scaling value for each character pixel, where the pixels
|
||||||
|
are drawn as a square with side length equal to `scale + 1`. The value
|
||||||
|
can be between 0 and 63.
|
||||||
|
- `bold` controls the number of pixels to overdraw each character pixel,
|
||||||
|
making a bold effect. The lower 2 bits of `bold` are the number of
|
||||||
|
pixels to overdraw in the horizontal direction, and the next 2 bits are
|
||||||
|
for the vertical direction. For example, a `bold` value of 5 will
|
||||||
|
overdraw 1 pixel in both the horizontal and vertical directions.
|
||||||
|
- `trans` can be either 0 or 1 and if set to 1 the characters will be
|
||||||
|
drawn with a transparent background.
|
||||||
|
- `scroll` can be either 0 or 1 and if set to 1 the display will do a
|
||||||
|
soft scroll if the text moves to the next line.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.write(s)
|
||||||
|
|
||||||
|
Write text to the display, using the current position, color and font.
|
||||||
|
As text is written the position is automatically incremented. The
|
||||||
|
display supports basic VT100 control codes such as newline and backspace.
|
||||||
|
|
||||||
|
Drawing primitive shapes
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Primitive drawing commands use a foreground and background color set by the
|
||||||
|
`set_pen` method.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_pen(line, fill)
|
||||||
|
|
||||||
|
Set the line and fill color for primitive shapes.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.erase()
|
||||||
|
|
||||||
|
Erase the entire display to the pen fill color.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.dot(x, y)
|
||||||
|
|
||||||
|
Draw a single pixel at the given location using the pen line color.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.rect(x, y, w, h)
|
||||||
|
.. method:: LCD160CR.rect_outline(x, y, w, h)
|
||||||
|
.. method:: LCD160CR.rect_interior(x, y, w, h)
|
||||||
|
|
||||||
|
Draw a rectangle at the given location and size using the pen line
|
||||||
|
color for the outline, and the pen fill color for the interior.
|
||||||
|
The `rect` method draws the outline and interior, while the other methods
|
||||||
|
just draw one or the other.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.line(x1, y1, x2, y2)
|
||||||
|
|
||||||
|
Draw a line between the given coordinates using the pen line color.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.dot_no_clip(x, y)
|
||||||
|
.. method:: LCD160CR.rect_no_clip(x, y, w, h)
|
||||||
|
.. method:: LCD160CR.rect_outline_no_clip(x, y, w, h)
|
||||||
|
.. method:: LCD160CR.rect_interior_no_clip(x, y, w, h)
|
||||||
|
.. method:: LCD160CR.line_no_clip(x1, y1, x2, y2)
|
||||||
|
|
||||||
|
These methods are as above but don't do any clipping on the input
|
||||||
|
coordinates. They are faster than the clipping versions and can be
|
||||||
|
used when you know that the coordinates are within the display.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.poly_dot(data)
|
||||||
|
|
||||||
|
Draw a sequence of dots using the pen line color.
|
||||||
|
The `data` should be a buffer of bytes, with each successive pair of
|
||||||
|
bytes corresponding to coordinate pairs (x, y).
|
||||||
|
|
||||||
|
.. method:: LCD160CR.poly_line(data)
|
||||||
|
|
||||||
|
Similar to :meth:`LCD160CR.poly_dot` but draws lines between the dots.
|
||||||
|
|
||||||
|
Touch screen methods
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. method:: LCD160CR.touch_config(calib=False, save=False, irq=None)
|
||||||
|
|
||||||
|
Configure the touch panel:
|
||||||
|
|
||||||
|
- If `calib` is `True` then the call will trigger a touch calibration of
|
||||||
|
the resistive touch sensor. This requires the user to touch various
|
||||||
|
parts of the screen.
|
||||||
|
- If `save` is `True` then the touch parameters will be saved to NVRAM
|
||||||
|
to persist across reset/power up.
|
||||||
|
- If `irq` is `True` then the display will be configured to pull the IRQ
|
||||||
|
line low when a touch force is detected. If `irq` is `False` then this
|
||||||
|
feature is disabled. If `irq` is `None` (the default value) then no
|
||||||
|
change is made to this setting.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.is_touched()
|
||||||
|
|
||||||
|
Returns a boolean: `True` if there is currently a touch force on the screen,
|
||||||
|
`False` otherwise.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.get_touch()
|
||||||
|
|
||||||
|
Returns a 3-tuple of: (active, x, y). If there is currently a touch force
|
||||||
|
on the screen then `active` is 1, otherwise it is 0. The `x` and `y` values
|
||||||
|
indicate the position of the current or most recent touch.
|
||||||
|
|
||||||
|
Advanced commands
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_spi_win(x, y, w, h)
|
||||||
|
|
||||||
|
Set the window that SPI data is written to.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.fast_spi(flush=True)
|
||||||
|
|
||||||
|
Ready the display to accept RGB pixel data on the SPI bus, resetting the location
|
||||||
|
of the first byte to go to the top-left corner of the window set by
|
||||||
|
:meth:`LCD160CR.set_spi_win`.
|
||||||
|
The method returns an SPI object which can be used to write the pixel data.
|
||||||
|
|
||||||
|
Pixels should be sent as 16-bit RGB values in the 5-6-5 format. The destination
|
||||||
|
counter will increase as data is sent, and data can be sent in arbitrary sized
|
||||||
|
chunks. Once the destination counter reaches the end of the window specified by
|
||||||
|
:meth:`LCD160CR.set_spi_win` it will wrap around to the top-left corner of that window.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.show_framebuf(buf)
|
||||||
|
|
||||||
|
Show the given buffer on the display. `buf` should be an array of bytes containing
|
||||||
|
the 16-bit RGB values for the pixels, and they will be written to the area
|
||||||
|
specified by :meth:`LCD160CR.set_spi_win`, starting from the top-left corner.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_scroll(on)
|
||||||
|
|
||||||
|
Turn scrolling on or off. This controls globally whether any window regions will
|
||||||
|
scroll.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_scroll_win(win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0)
|
||||||
|
|
||||||
|
Configure a window region for scrolling:
|
||||||
|
|
||||||
|
- `win` is the window id to configure. There are 0..7 standard windows for
|
||||||
|
general purpose use. Window 8 is the text scroll window (the ticker).
|
||||||
|
- `x`, `y`, `w`, `h` specify the location of the window in the display.
|
||||||
|
- `vec` specifies the direction and speed of scroll: it is a 16-bit value
|
||||||
|
of the form ``0bF.ddSSSSSSSSSSSS``. `dd` is 0, 1, 2, 3 for +x, +y, -x,
|
||||||
|
-y scrolling. `F` sets the speed format, with 0 meaning that the window
|
||||||
|
is shifted `S % 256` pixel every frame, and 1 meaning that the window
|
||||||
|
is shifted 1 pixel every `S` frames.
|
||||||
|
- `pat` is a 16-bit pattern mask for the background.
|
||||||
|
- `fill` is the fill color.
|
||||||
|
- `color` is the extra color, either of the text or pattern foreground.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_scroll_win_param(win, param, value)
|
||||||
|
|
||||||
|
Set a single parameter of a scrolling window region:
|
||||||
|
|
||||||
|
- `win` is the window id, 0..8.
|
||||||
|
- `param` is the parameter number to configure, 0..7, and corresponds
|
||||||
|
to the parameters in the `set_scroll_win` method.
|
||||||
|
- `value` is the value to set.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.set_scroll_buf(s)
|
||||||
|
|
||||||
|
Set the string for scrolling in window 8. The parameter `s` must be a string
|
||||||
|
with length 32 or less.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.jpeg(buf)
|
||||||
|
|
||||||
|
Display a JPEG. `buf` should contain the entire JPEG data.
|
||||||
|
The origin of the JPEG is set by :meth:`LCD160CR.set_pos`.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.jpeg_start(total_len)
|
||||||
|
.. method:: LCD160CR.jpeg_data(buf)
|
||||||
|
|
||||||
|
Display a JPEG with the data split across multiple buffers. There must be
|
||||||
|
a single call to `jpeg_start` to begin with, specifying the total number of
|
||||||
|
bytes in the JPEG. Then this number of bytes must be transferred to the
|
||||||
|
display using one or more calls to the `jpeg_data` command.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.feed_wdt()
|
||||||
|
|
||||||
|
The first call to this method will start the display's internal watchdog
|
||||||
|
timer. Subsequent calls will feed the watchdog. The timeout is roughly 30
|
||||||
|
seconds.
|
||||||
|
|
||||||
|
.. method:: LCD160CR.reset()
|
||||||
|
|
||||||
|
Reset the display.
|
||||||
|
|
||||||
|
Constants
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. data:: lcd160cr.PORTRAIT
|
||||||
|
.. data:: lcd160cr.LANDSCAPE
|
||||||
|
.. data:: lcd160cr.PORTRAIT_UPSIDEDOWN
|
||||||
|
.. data:: lcd160cr.LANDSCAPE_UPSIDEDOWN
|
||||||
|
|
||||||
|
orientation of the display, used by :meth:`LCD160CR.set_orient`
|
||||||
|
|
||||||
|
.. data:: lcd160cr.STARTUP_DECO_NONE
|
||||||
|
.. data:: lcd160cr.STARTUP_DECO_MLOGO
|
||||||
|
.. data:: lcd160cr.STARTUP_DECO_INFO
|
||||||
|
|
||||||
|
type of start-up decoration, can be or'd together, used by
|
||||||
|
:meth:`LCD160CR.set_startup_deco`
|
@ -1,53 +1,17 @@
|
|||||||
.. currentmodule:: machine
|
.. currentmodule:: machine
|
||||||
|
|
||||||
class Timer -- control internal timers
|
class Timer -- control hardware timers
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
.. only:: port_wipy
|
Hardware timers deal with timing of periods and events. Timers are perhaps
|
||||||
|
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
|
||||||
|
differently greatly from a model to a model. MicroPython's Timer class
|
||||||
|
defines a baseline operation of executing a callback with a given period
|
||||||
|
(or once after some delay), and allow specific boards to define more
|
||||||
|
non-standard behavior (which thus won't be portable to other boards).
|
||||||
|
|
||||||
Timers can be used for a great variety of tasks, calling a function periodically,
|
See discussion of :ref:`important constraints <machine_callbacks>` on
|
||||||
counting events, and generating a PWM signal are among the most common use cases.
|
Timer callbacks.
|
||||||
Each timer consists of two 16-bit channels and this channels can be tied together to
|
|
||||||
form one 32-bit timer. The operating mode needs to be configured per timer, but then
|
|
||||||
the period (or the frequency) can be independently configured on each channel.
|
|
||||||
By using the callback method, the timer event can call a Python function.
|
|
||||||
|
|
||||||
Example usage to toggle an LED at a fixed frequency::
|
|
||||||
|
|
||||||
from machine import Timer
|
|
||||||
from machine import Pin
|
|
||||||
led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
|
|
||||||
tim = Timer(3) # create a timer object using timer 3
|
|
||||||
tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode
|
|
||||||
tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz
|
|
||||||
tim_ch.irq(handler=lambda t:led.toggle(), trigger=Timer.TIMEOUT) # toggle a LED on every cycle of the timer
|
|
||||||
|
|
||||||
Example using named function for the callback::
|
|
||||||
|
|
||||||
from machine import Timer
|
|
||||||
from machine import Pin
|
|
||||||
tim = Timer(1, mode=Timer.PERIODIC, width=32)
|
|
||||||
tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer
|
|
||||||
|
|
||||||
led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
|
|
||||||
|
|
||||||
def tick(timer): # we will receive the timer object when being called
|
|
||||||
global led
|
|
||||||
led.toggle() # toggle the LED
|
|
||||||
|
|
||||||
tim_a.irq(handler=tick, trigger=Timer.TIMEOUT) # create the interrupt
|
|
||||||
|
|
||||||
Further examples::
|
|
||||||
|
|
||||||
from machine import Timer
|
|
||||||
tim1 = Timer(1, mode=Timer.ONE_SHOT) # initialize it in one shot mode
|
|
||||||
tim2 = Timer(2, mode=Timer.PWM) # initialize it in PWM mode
|
|
||||||
tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges
|
|
||||||
tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=5000) # start the PWM on channel B with a 50% duty cycle
|
|
||||||
tim2_ch.freq(20) # set the frequency (can also get)
|
|
||||||
tim2_ch.duty_cycle(3010) # set the duty cycle to 30.1% (can also get)
|
|
||||||
tim2_ch.duty_cycle(3020, Timer.NEGATIVE) # set the duty cycle to 30.2% and change the polarity to negative
|
|
||||||
tim2_ch.period(2000000) # change the period to 2 seconds
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@ -61,10 +25,8 @@ Constructors
|
|||||||
|
|
||||||
.. class:: Timer(id, ...)
|
.. class:: Timer(id, ...)
|
||||||
|
|
||||||
.. only:: port_wipy
|
Construct a new timer object of the given id. Id of -1 constructs a
|
||||||
|
virtual timer (if supported by a board).
|
||||||
Construct a new timer object of the given id. ``id`` can take values from 0 to 3.
|
|
||||||
|
|
||||||
|
|
||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
@ -94,8 +56,7 @@ Methods
|
|||||||
|
|
||||||
.. method:: Timer.deinit()
|
.. method:: Timer.deinit()
|
||||||
|
|
||||||
Deinitialises the timer. Disables all channels and associated IRQs.
|
Deinitialises the timer. Stops the timer, and disables the timer peripheral.
|
||||||
Stops the timer, and disables the timer peripheral.
|
|
||||||
|
|
||||||
.. only:: port_wipy
|
.. only:: port_wipy
|
||||||
|
|
||||||
@ -138,18 +99,18 @@ Methods
|
|||||||
- ``GP10`` on Timer 3 channel A.
|
- ``GP10`` on Timer 3 channel A.
|
||||||
- ``GP11`` on Timer 3 channel B.
|
- ``GP11`` on Timer 3 channel B.
|
||||||
|
|
||||||
class TimerChannel --- setup a channel for a timer
|
|
||||||
==================================================
|
|
||||||
|
|
||||||
Timer channels are used to generate/capture a signal using a timer.
|
|
||||||
|
|
||||||
TimerChannel objects are created using the Timer.channel() method.
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. only:: port_wipy
|
.. only:: port_wipy
|
||||||
|
|
||||||
|
class TimerChannel --- setup a channel for a timer
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
Timer channels are used to generate/capture a signal using a timer.
|
||||||
|
|
||||||
|
TimerChannel objects are created using the Timer.channel() method.
|
||||||
|
|
||||||
|
Methods
|
||||||
|
-------
|
||||||
|
|
||||||
.. method:: timerchannel.irq(\*, trigger, priority=1, handler=None)
|
.. method:: timerchannel.irq(\*, trigger, priority=1, handler=None)
|
||||||
|
|
||||||
The behavior of this callback is heavily dependent on the operating
|
The behavior of this callback is heavily dependent on the operating
|
||||||
@ -194,22 +155,5 @@ Constants
|
|||||||
|
|
||||||
.. data:: Timer.ONE_SHOT
|
.. data:: Timer.ONE_SHOT
|
||||||
.. data:: Timer.PERIODIC
|
.. data:: Timer.PERIODIC
|
||||||
.. data:: Timer.PWM
|
|
||||||
|
|
||||||
Selects the timer operating mode.
|
Timer operating mode.
|
||||||
|
|
||||||
.. data:: Timer.A
|
|
||||||
.. data:: Timer.B
|
|
||||||
|
|
||||||
Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when
|
|
||||||
using a 32-bit timer.
|
|
||||||
|
|
||||||
.. data:: Timer.POSITIVE
|
|
||||||
.. data:: Timer.NEGATIVE
|
|
||||||
|
|
||||||
Timer channel polarity selection (only relevant in PWM mode).
|
|
||||||
|
|
||||||
.. data:: Timer.TIMEOUT
|
|
||||||
.. data:: Timer.MATCH
|
|
||||||
|
|
||||||
Timer channel IRQ triggers.
|
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
:mod:`machine` --- functions related to the board
|
:mod:`machine` --- functions related to the hardware
|
||||||
=================================================
|
====================================================
|
||||||
|
|
||||||
.. module:: machine
|
.. module:: machine
|
||||||
:synopsis: functions related to the board
|
:synopsis: functions related to the hardware
|
||||||
|
|
||||||
The ``machine`` module contains specific functions related to the board.
|
The ``machine`` module contains specific functions related to the hardware
|
||||||
|
on a particular board. Most functions in this module allow to achieve direct
|
||||||
|
and unrestricted access to and control of hardware blocks on a system
|
||||||
|
(like CPU, timers, buses, etc.). Used incorrectly, this can lead to
|
||||||
|
malfunction, lockups, crashes of your board, and in extreme cases, hardware
|
||||||
|
damage.
|
||||||
|
|
||||||
|
.. _machine_callbacks:
|
||||||
|
|
||||||
|
A note of callbacks used by functions and class methods of ``machine`` module:
|
||||||
|
all these callbacks should be considered as executing in an interrupt context.
|
||||||
|
This is true for both physical devices with IDs >= 0 and "virtual" devices
|
||||||
|
with negative IDs like -1 (these "virtual" devices are still thin shims on
|
||||||
|
top of real hardware and real hardware intrerrupts). See :ref:`isr_rules`.
|
||||||
|
|
||||||
Reset related functions
|
Reset related functions
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -105,12 +118,15 @@ Miscellaneous functions
|
|||||||
microseconds. The `pulse_level` argument should be 0 to time a low pulse
|
microseconds. The `pulse_level` argument should be 0 to time a low pulse
|
||||||
or 1 to time a high pulse.
|
or 1 to time a high pulse.
|
||||||
|
|
||||||
The function first waits while the pin input is different to the `pulse_level`
|
If the current input value of the pin is different to `pulse_level`,
|
||||||
parameter, then times the duration that the pin is equal to `pulse_level`.
|
the function first (*) waits until the pin input becomes equal to `pulse_level`,
|
||||||
|
then (**) times the duration that the pin is equal to `pulse_level`.
|
||||||
If the pin is already equal to `pulse_level` then timing starts straight away.
|
If the pin is already equal to `pulse_level` then timing starts straight away.
|
||||||
|
|
||||||
The function will raise an OSError with ETIMEDOUT if either of the waits is
|
The function will return -2 if there was timeout waiting for condition marked
|
||||||
longer than the given timeout value (which is in microseconds).
|
(*) above, and -1 if there was timeout during the main measurement, marked (**)
|
||||||
|
above. The timeout is the same for both cases and given by `timeout_us` (which
|
||||||
|
is in microseconds).
|
||||||
|
|
||||||
.. _machine_constants:
|
.. _machine_constants:
|
||||||
|
|
||||||
|
@ -80,6 +80,19 @@ Reset related functions
|
|||||||
|
|
||||||
Activate the bootloader without BOOT\* pins.
|
Activate the bootloader without BOOT\* pins.
|
||||||
|
|
||||||
|
.. function:: fault_debug(value)
|
||||||
|
|
||||||
|
Enable or disable hard-fault debugging. A hard-fault is when there is a fatal
|
||||||
|
error in the underlying system, like an invalid memory access.
|
||||||
|
|
||||||
|
If the `value` argument is `False` then the board will automatically reset if
|
||||||
|
there is a hard fault.
|
||||||
|
|
||||||
|
If `value` is `True` then, when the board has a hard fault, it will print the
|
||||||
|
registers and the stack trace, and then cycle the LEDs indefinitely.
|
||||||
|
|
||||||
|
The default value is disabled, i.e. to automatically reset.
|
||||||
|
|
||||||
Interrupt related functions
|
Interrupt related functions
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
@ -7,6 +7,71 @@
|
|||||||
This module contains additional types of stream (file-like) objects
|
This module contains additional types of stream (file-like) objects
|
||||||
and helper functions.
|
and helper functions.
|
||||||
|
|
||||||
|
Conceptual hierarchy
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
Conceptual hierarchy of stream base classes is simplified in MicroPython,
|
||||||
|
as described in this section.
|
||||||
|
|
||||||
|
(Abstract) base stream classes, which serve as a foundation for behavior
|
||||||
|
of all the concrete classes, adhere to few dichotomies (pair-wise
|
||||||
|
classifications) in CPython. In MicroPython, they are somewhat simplified
|
||||||
|
and made implicit to achieve higher efficiencies and save resources.
|
||||||
|
|
||||||
|
An important dichotomy in CPython is unbuffered vs buffered streams. In
|
||||||
|
MicroPython, all streams are currently unbuffered. This is because all
|
||||||
|
modern OSes, and even many RTOSes and filesystem drivers already perform
|
||||||
|
buffering on their side. Adding another layer of buffering is counter-
|
||||||
|
productive (an issue known as "bufferbloat") and takes precious memory.
|
||||||
|
Note that there still cases where buffering may be useful, so we may
|
||||||
|
introduce optional buffering support at a later time.
|
||||||
|
|
||||||
|
But in CPython, another important dichotomy is tied with "bufferedness" -
|
||||||
|
it's whether a stream may incur short read/writes or not. A short read
|
||||||
|
is when a user asks e.g. 10 bytes from a stream, but gets less, similarly
|
||||||
|
for writes. In CPython, unbuffered streams are automatically short
|
||||||
|
operation susceptible, while buffered are guarantee against them. The
|
||||||
|
no short read/writes is an important trait, as it allows to develop
|
||||||
|
more concise and efficient programs - something which is highly desirable
|
||||||
|
for MicroPython. So, while MicroPython doesn't support buffered streams,
|
||||||
|
it still provides for no-short-operations streams. Whether there will
|
||||||
|
be short operations or not depends on each particular class' needs, but
|
||||||
|
developers are strongly advised to favor no-short-operations behavior
|
||||||
|
for the reasons stated above. For example, MicroPython sockets are
|
||||||
|
guaranteed to avoid short read/writes. Actually, at this time, there is
|
||||||
|
no example of a short-operations stream class in the core, and one would
|
||||||
|
be a port-specific class, where such a need is governed by hardware
|
||||||
|
peculiarities.
|
||||||
|
|
||||||
|
The no-short-operations behavior gets tricky in case of non-blocking
|
||||||
|
streams, blocking vs non-blocking behavior being another CPython dichotomy,
|
||||||
|
fully supported by MicroPython. Non-blocking streams never wait for
|
||||||
|
data either to arrive or be written - they read/write whatever possible,
|
||||||
|
or signal lack of data (or ability to write data). Clearly, this conflicts
|
||||||
|
with "no-short-operations" policy, and indeed, a case of non-blocking
|
||||||
|
buffered (and this no-short-ops) streams is convoluted in CPython - in
|
||||||
|
some places, such combination is prohibited, in some it's undefined or
|
||||||
|
just not documented, in some cases it raises verbose exceptions. The
|
||||||
|
matter is much simpler in MicroPython: non-blocking stream are important
|
||||||
|
for efficient asynchronous operations, so this property prevails on
|
||||||
|
the "no-short-ops" one. So, while blocking streams will avoid short
|
||||||
|
reads/writes whenever possible (the only case to get a short read is
|
||||||
|
if end of file is reached, or in case of error (but errors don't
|
||||||
|
return short data, but raise exceptions)), non-blocking streams may
|
||||||
|
produce short data to avoid blocking the operation.
|
||||||
|
|
||||||
|
The final dichotomy is binary vs text streams. MicroPython of course
|
||||||
|
supports these, but while in CPython text streams are inherently
|
||||||
|
buffered, they aren't in MicroPython. (Indeed, that's one of the cases
|
||||||
|
for which we may introduce buffering support.)
|
||||||
|
|
||||||
|
Note that for efficiency, MicroPython doesn't provide abstract base
|
||||||
|
classes corresponding to the hierarchy above, and it's not possible
|
||||||
|
to implement, or subclass, a stream class in pure Python.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -7,13 +7,28 @@
|
|||||||
|
|
||||||
This module provides access to the BSD socket interface.
|
This module provides access to the BSD socket interface.
|
||||||
|
|
||||||
See corresponding `CPython module <https://docs.python.org/3/library/socket.html>`_ for
|
See the corresponding `CPython module <https://docs.python.org/3/library/socket.html>`_
|
||||||
comparison.
|
for comparison.
|
||||||
|
|
||||||
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
CPython used to have a ``socket.error`` exception which is now deprecated,
|
||||||
|
and is an alias of OSError. In MicroPython, use OSError directly.
|
||||||
|
|
||||||
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
For efficiency and consistency, socket objects in MicroPython implement a stream
|
||||||
|
(file-like) interface directly. In CPython, you need to convert a socket to
|
||||||
|
a file-like object using ``makefile()`` method. This method is still supported
|
||||||
|
by MicroPython (but is a no-op), so where compatibility with CPython matters,
|
||||||
|
be sure to use it.
|
||||||
|
|
||||||
Socket address format(s)
|
Socket address format(s)
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Functions below which expect a network address, accept it in the format of
|
The functions below which expect a network address, accept it in the format of
|
||||||
`(ipv4_address, port)`, where `ipv4_address` is a string with dot-notation numeric
|
`(ipv4_address, port)`, where `ipv4_address` is a string with dot-notation numeric
|
||||||
IPv4 address, e.g. ``"8.8.8.8"``, and port is integer port number in the range
|
IPv4 address, e.g. ``"8.8.8.8"``, and port is integer port number in the range
|
||||||
1-65535. Note the domain names are not accepted as `ipv4_address`, they should be
|
1-65535. Note the domain names are not accepted as `ipv4_address`, they should be
|
||||||
@ -51,33 +66,50 @@ Functions
|
|||||||
s = socket.socket()
|
s = socket.socket()
|
||||||
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
|
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
|
||||||
|
|
||||||
.. only:: port_wipy
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
Exceptions
|
CPython raises a ``socket.gaierror`` exception (OSError subclass) in case
|
||||||
----------
|
of error in this function. MicroPython doesn't have ``socket.gaierror``
|
||||||
|
and raises OSError directly. Note that error numbers of ``getaddrinfo()``
|
||||||
.. data:: socket.error
|
form a separate namespace and may not match error numbers from
|
||||||
.. data:: socket.timeout
|
``uerrno`` module. To distinguish ``getaddrinfo()`` errors, they are
|
||||||
|
represented by negative numbers, whereas standard system errors are
|
||||||
|
positive numbers (error numbers are accessible using ``e.args[0]`` property
|
||||||
|
from an exception object). The use of negative values is a provisional
|
||||||
|
detail which may change in the future.
|
||||||
|
|
||||||
Constants
|
Constants
|
||||||
---------
|
---------
|
||||||
|
|
||||||
.. data:: socket.AF_INET
|
.. data:: socket.AF_INET
|
||||||
|
socket.AF_INET6
|
||||||
|
|
||||||
family types
|
Address family types. Availability depends on a particular board.
|
||||||
|
|
||||||
.. data:: socket.SOCK_STREAM
|
.. data:: socket.SOCK_STREAM
|
||||||
.. data:: socket.SOCK_DGRAM
|
socket.SOCK_DGRAM
|
||||||
|
|
||||||
socket types
|
Socket types.
|
||||||
|
|
||||||
.. data:: socket.IPPROTO_UDP
|
.. data:: socket.IPPROTO_UDP
|
||||||
.. data:: socket.IPPROTO_TCP
|
socket.IPPROTO_TCP
|
||||||
.. only:: port_wipy
|
|
||||||
|
|
||||||
.. data:: socket.IPPROTO_SEC
|
IP protocol numbers.
|
||||||
|
|
||||||
protocol numbers
|
.. data:: socket.SOL_*
|
||||||
|
|
||||||
|
Socket option levels (an argument to ``setsockopt()``). The exact inventory depends on a board.
|
||||||
|
|
||||||
|
.. data:: socket.SO_*
|
||||||
|
|
||||||
|
Socket options (an argument to ``setsockopt()``). The exact inventory depends on a board.
|
||||||
|
|
||||||
|
Constants specific to WiPy:
|
||||||
|
|
||||||
|
.. data:: socket.IPPROTO_SEC
|
||||||
|
|
||||||
|
Special protocol value to create SSL-compatible socket.
|
||||||
|
|
||||||
class socket
|
class socket
|
||||||
============
|
============
|
||||||
@ -85,128 +117,146 @@ class socket
|
|||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. method:: socket.close
|
.. method:: socket.close
|
||||||
|
|
||||||
Mark the socket closed. Once that happens, all future operations on the socket
|
Mark the socket closed. Once that happens, all future operations on the socket
|
||||||
object will fail. The remote end will receive no more data (after queued data is flushed).
|
object will fail. The remote end will receive no more data (after queued data is flushed).
|
||||||
|
|
||||||
Sockets are automatically closed when they are garbage-collected, but it is recommended
|
Sockets are automatically closed when they are garbage-collected, but it is recommended
|
||||||
to close() them explicitly, or to use a with statement around them.
|
to close() them explicitly, or to use a with statement around them.
|
||||||
|
|
||||||
.. method:: socket.bind(address)
|
.. method:: socket.bind(address)
|
||||||
|
|
||||||
Bind the socket to address. The socket must not already be bound.
|
Bind the socket to address. The socket must not already be bound.
|
||||||
|
|
||||||
.. method:: socket.listen([backlog])
|
.. method:: socket.listen([backlog])
|
||||||
|
|
||||||
Enable a server to accept connections. If backlog is specified, it must be at least 0
|
Enable a server to accept connections. If backlog is specified, it must be at least 0
|
||||||
(if it's lower, it will be set to 0); and specifies the number of unaccepted connections
|
(if it's lower, it will be set to 0); and specifies the number of unaccepted connections
|
||||||
that the system will allow before refusing new connections. If not specified, a default
|
that the system will allow before refusing new connections. If not specified, a default
|
||||||
reasonable value is chosen.
|
reasonable value is chosen.
|
||||||
|
|
||||||
.. method:: socket.accept()
|
.. method:: socket.accept()
|
||||||
|
|
||||||
Accept a connection. The socket must be bound to an address and listening for connections.
|
Accept a connection. The socket must be bound to an address and listening for connections.
|
||||||
The return value is a pair (conn, address) where conn is a new socket object usable to send
|
The return value is a pair (conn, address) where conn is a new socket object usable to send
|
||||||
and receive data on the connection, and address is the address bound to the socket on the
|
and receive data on the connection, and address is the address bound to the socket on the
|
||||||
other end of the connection.
|
other end of the connection.
|
||||||
|
|
||||||
.. method:: socket.connect(address)
|
.. method:: socket.connect(address)
|
||||||
|
|
||||||
Connect to a remote socket at address.
|
Connect to a remote socket at address.
|
||||||
|
|
||||||
.. method:: socket.send(bytes)
|
.. method:: socket.send(bytes)
|
||||||
|
|
||||||
Send data to the socket. The socket must be connected to a remote socket.
|
Send data to the socket. The socket must be connected to a remote socket.
|
||||||
|
Returns number of bytes sent, which may be smaller than the length of data
|
||||||
|
("short write").
|
||||||
|
|
||||||
.. method:: socket.sendall(bytes)
|
.. method:: socket.sendall(bytes)
|
||||||
|
|
||||||
Send data to the socket. The socket must be connected to a remote socket.
|
Send all data to the socket. The socket must be connected to a remote socket.
|
||||||
|
Unlike ``send()``, this method will try to send all of data, by sending data
|
||||||
|
chunk by chunk consecutively.
|
||||||
|
|
||||||
.. method:: socket.recv(bufsize)
|
The behavior of this method on non-blocking sockets is undefined. Due to this,
|
||||||
|
on MicroPython, it's recommended to use ``write()`` method instead, which
|
||||||
|
has the same "no short writes" policy for blocking sockets, and will return
|
||||||
|
number of bytes sent on non-blocking sockets.
|
||||||
|
|
||||||
Receive data from the socket. The return value is a bytes object representing the data
|
.. method:: socket.recv(bufsize)
|
||||||
received. The maximum amount of data to be received at once is specified by bufsize.
|
|
||||||
|
|
||||||
.. method:: socket.sendto(bytes, address)
|
Receive data from the socket. The return value is a bytes object representing the data
|
||||||
|
received. The maximum amount of data to be received at once is specified by bufsize.
|
||||||
|
|
||||||
Send data to the socket. The socket should not be connected to a remote socket, since the
|
.. method:: socket.sendto(bytes, address)
|
||||||
destination socket is specified by `address`.
|
|
||||||
|
|
||||||
.. method:: socket.recvfrom(bufsize)
|
Send data to the socket. The socket should not be connected to a remote socket, since the
|
||||||
|
destination socket is specified by `address`.
|
||||||
|
|
||||||
Receive data from the socket. The return value is a pair (bytes, address) where bytes is a
|
.. method:: socket.recvfrom(bufsize)
|
||||||
bytes object representing the data received and address is the address of the socket sending
|
|
||||||
the data.
|
|
||||||
|
|
||||||
.. method:: socket.setsockopt(level, optname, value)
|
Receive data from the socket. The return value is a pair (bytes, address) where bytes is a
|
||||||
|
bytes object representing the data received and address is the address of the socket sending
|
||||||
|
the data.
|
||||||
|
|
||||||
Set the value of the given socket option. The needed symbolic constants are defined in the
|
.. method:: socket.setsockopt(level, optname, value)
|
||||||
socket module (SO_* etc.). The value can be an integer or a bytes-like object representing
|
|
||||||
a buffer.
|
|
||||||
|
|
||||||
.. method:: socket.settimeout(value)
|
Set the value of the given socket option. The needed symbolic constants are defined in the
|
||||||
|
socket module (SO_* etc.). The value can be an integer or a bytes-like object representing
|
||||||
|
a buffer.
|
||||||
|
|
||||||
Set a timeout on blocking socket operations. The value argument can be a nonnegative floating
|
.. method:: socket.settimeout(value)
|
||||||
point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations
|
|
||||||
will raise an ``OSError`` exception if the timeout period value has elapsed before the operation has
|
|
||||||
completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket
|
|
||||||
is put in blocking mode.
|
|
||||||
|
|
||||||
.. admonition:: Difference to CPython
|
Set a timeout on blocking socket operations. The value argument can be a nonnegative floating
|
||||||
:class: attention
|
point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations
|
||||||
|
will raise an ``OSError`` exception if the timeout period value has elapsed before the operation has
|
||||||
|
completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket
|
||||||
|
is put in blocking mode.
|
||||||
|
|
||||||
CPython raises a ``socket.timeout`` exception in case of timeout,
|
.. admonition:: Difference to CPython
|
||||||
which is an ``OSError`` subclass. MicroPython raises an OSError directly
|
:class: attention
|
||||||
instead. If you use ``except OSError:`` to catch the exception,
|
|
||||||
your code will work both in MicroPython and CPython.
|
|
||||||
|
|
||||||
.. method:: socket.setblocking(flag)
|
CPython raises a ``socket.timeout`` exception in case of timeout,
|
||||||
|
which is an ``OSError`` subclass. MicroPython raises an OSError directly
|
||||||
|
instead. If you use ``except OSError:`` to catch the exception,
|
||||||
|
your code will work both in MicroPython and CPython.
|
||||||
|
|
||||||
Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking,
|
.. method:: socket.setblocking(flag)
|
||||||
else to blocking mode.
|
|
||||||
|
|
||||||
This method is a shorthand for certain ``settimeout()`` calls::
|
Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking,
|
||||||
|
else to blocking mode.
|
||||||
|
|
||||||
sock.setblocking(True) is equivalent to sock.settimeout(None)
|
This method is a shorthand for certain ``settimeout()`` calls:
|
||||||
sock.setblocking(False) is equivalent to sock.settimeout(0.0)
|
|
||||||
|
|
||||||
.. method:: socket.makefile(mode='rb')
|
* ``sock.setblocking(True)`` is equivalent to ``sock.settimeout(None)``
|
||||||
|
* ``sock.setblocking(False)`` is equivalent to ``sock.settimeout(0)``
|
||||||
|
|
||||||
Return a file object associated with the socket. The exact returned type depends on the arguments
|
.. method:: socket.makefile(mode='rb', buffering=0)
|
||||||
given to makefile(). The support is limited to binary modes only ('rb' and 'wb').
|
|
||||||
CPython's arguments: ``encoding``, ``errors`` and ``newline`` are not supported.
|
|
||||||
|
|
||||||
The socket must be in blocking mode; it can have a timeout, but the file object’s internal buffer
|
Return a file object associated with the socket. The exact returned type depends on the arguments
|
||||||
may end up in a inconsistent state if a timeout occurs.
|
given to makefile(). The support is limited to binary modes only ('rb', 'wb', and 'rwb').
|
||||||
|
CPython's arguments: ``encoding``, ``errors`` and ``newline`` are not supported.
|
||||||
|
|
||||||
.. admonition:: Difference to CPython
|
.. admonition:: Difference to CPython
|
||||||
:class: attention
|
:class: attention
|
||||||
|
|
||||||
Closing the file object returned by makefile() WILL close the
|
As MicroPython doesn't support buffered streams, values of ``buffering``
|
||||||
original socket as well.
|
parameter is ignored and treated as if it was 0 (unbuffered).
|
||||||
|
|
||||||
.. method:: socket.read([size])
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
Read up to size bytes from the socket. Return a bytes object. If ``size`` is not given, it
|
Closing the file object returned by makefile() WILL close the
|
||||||
reads all data available from the socket until ``EOF``; as such the method will not return until
|
original socket as well.
|
||||||
the socket is closed.
|
|
||||||
|
|
||||||
.. method:: socket.readinto(buf[, nbytes])
|
.. method:: socket.read([size])
|
||||||
|
|
||||||
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
|
Read up to size bytes from the socket. Return a bytes object. If ``size`` is not given, it
|
||||||
that many bytes. Otherwise, read at most ``len(buf)`` bytes.
|
reads all data available from the socket until ``EOF``; as such the method will not return until
|
||||||
|
the socket is closed. This function tries to read as much data as
|
||||||
|
requested (no "short reads"). This may be not possible with
|
||||||
|
non-blocking socket though, and then less data will be returned.
|
||||||
|
|
||||||
Return value: number of bytes read and stored into ``buf``.
|
.. method:: socket.readinto(buf[, nbytes])
|
||||||
|
|
||||||
.. method:: socket.readline()
|
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
|
||||||
|
that many bytes. Otherwise, read at most ``len(buf)`` bytes. Just as
|
||||||
|
``read()``, this method follows "no short reads" policy.
|
||||||
|
|
||||||
Read a line, ending in a newline character.
|
Return value: number of bytes read and stored into ``buf``.
|
||||||
|
|
||||||
Return value: the line read.
|
.. method:: socket.readline()
|
||||||
|
|
||||||
.. method:: socket.write(buf)
|
Read a line, ending in a newline character.
|
||||||
|
|
||||||
Write the buffer of bytes to the socket.
|
Return value: the line read.
|
||||||
|
|
||||||
Return value: number of bytes written.
|
.. method:: socket.write(buf)
|
||||||
|
|
||||||
|
Write the buffer of bytes to the socket. This function will try to
|
||||||
|
write all data to a socket (no "short writes"). This may be not possible
|
||||||
|
with a non-blocking socket though, and returned value will be less than
|
||||||
|
the length of ``buf``.
|
||||||
|
|
||||||
|
Return value: number of bytes written.
|
||||||
|
@ -11,6 +11,11 @@ is inserted into the slot, it is available as ``/sd``.
|
|||||||
When the pyboard boots up, it needs to choose a filesystem to boot from. If
|
When the pyboard boots up, it needs to choose a filesystem to boot from. If
|
||||||
there is no SD card, then it uses the internal filesystem ``/flash`` as the boot
|
there is no SD card, then it uses the internal filesystem ``/flash`` as the boot
|
||||||
filesystem, otherwise, it uses the SD card ``/sd``.
|
filesystem, otherwise, it uses the SD card ``/sd``.
|
||||||
|
If needed, you can prevent the use of the SD card by creating an empty file
|
||||||
|
called ``/flash/SKIPSD``. If this file exists when the pyboard boots
|
||||||
|
up then the SD card will be skipped and the pyboard will always boot from the
|
||||||
|
internal filesystem (in this case the SD card won't be mounted but you can still
|
||||||
|
mount and use it later in your program using ``os.mount``).
|
||||||
|
|
||||||
(Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd``
|
(Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd``
|
||||||
is called ``1:/``).
|
is called ``1:/``).
|
||||||
|
@ -13,6 +13,7 @@ For the official skin modules:
|
|||||||
|
|
||||||
* `LCD32MKv1.0 schematics <http://micropython.org/resources/LCD32MKv10-schematics.pdf>`_ (194KiB PDF)
|
* `LCD32MKv1.0 schematics <http://micropython.org/resources/LCD32MKv10-schematics.pdf>`_ (194KiB PDF)
|
||||||
* `AMPv1.0 schematics <http://micropython.org/resources/AMPv10-schematics.pdf>`_ (209KiB PDF)
|
* `AMPv1.0 schematics <http://micropython.org/resources/AMPv10-schematics.pdf>`_ (209KiB PDF)
|
||||||
|
* LCD160CRv1.0: see :mod:`lcd160cr`
|
||||||
|
|
||||||
Datasheets for the components on the pyboard
|
Datasheets for the components on the pyboard
|
||||||
============================================
|
============================================
|
||||||
|
@ -35,6 +35,7 @@ Tutorials requiring extra components
|
|||||||
fading_led.rst
|
fading_led.rst
|
||||||
lcd_skin.rst
|
lcd_skin.rst
|
||||||
amp_skin.rst
|
amp_skin.rst
|
||||||
|
lcd160cr_skin.rst
|
||||||
|
|
||||||
Tips, tricks and useful things to know
|
Tips, tricks and useful things to know
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
134
docs/pyboard/tutorial/lcd160cr_skin.rst
Normal file
134
docs/pyboard/tutorial/lcd160cr_skin.rst
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
The LCD160CR skin
|
||||||
|
=================
|
||||||
|
|
||||||
|
This tutorial shows how to get started using the LCD160CR skin.
|
||||||
|
|
||||||
|
.. image:: http://micropython.org/resources/LCD160CRv10-positions.jpg
|
||||||
|
:alt: LCD160CRv1.0 picture
|
||||||
|
:width: 800px
|
||||||
|
|
||||||
|
For detailed documentation of the driver for the display see the
|
||||||
|
:mod:`lcd160cr` module.
|
||||||
|
|
||||||
|
Plugging in the display
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The display can be plugged directly into a pyboard (all pyboard versions
|
||||||
|
are supported). You plug the display onto the top of the pyboard either
|
||||||
|
in the X or Y positions. The display should cover half of the pyboard.
|
||||||
|
See the picture above for how to achieve this; the left half of the picture
|
||||||
|
shows the X position, and the right half shows the Y position.
|
||||||
|
|
||||||
|
Getting the driver
|
||||||
|
------------------
|
||||||
|
|
||||||
|
You can control the display directly using a power/enable pin and an I2C
|
||||||
|
bus, but it is much more convenient to use the driver provided by the
|
||||||
|
:mod:`lcd160cr` module. This driver is included in recent version of the
|
||||||
|
pyboard firmware (see `here <http://micropython.org/download>`__). You
|
||||||
|
can also find the driver in the GitHub repository
|
||||||
|
`here <https://github.com/micropython/micropython/blob/master/drivers/display/lcd160cr.py>`__, and to use this version you will need to copy the file to your
|
||||||
|
board, into a directory that is searched by import (usually the lib/
|
||||||
|
directory).
|
||||||
|
|
||||||
|
Once you have the driver installed you need to import it to use it::
|
||||||
|
|
||||||
|
import lcd160cr
|
||||||
|
|
||||||
|
Testing the display
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
There is a test program which you can use to test the features of the display,
|
||||||
|
and which also serves as a basis to start creating your own code that uses the
|
||||||
|
LCD. This test program is included in recent versions of the pyboard firmware
|
||||||
|
and is also available on GitHub
|
||||||
|
`here <https://github.com/micropython/micropython/blob/master/drivers/display/lcd160cr_test.py>`__.
|
||||||
|
|
||||||
|
To run the test from the MicroPython prompt do::
|
||||||
|
|
||||||
|
>>> import lcd160cr_test
|
||||||
|
|
||||||
|
It will then print some brief instructions. You will need to know which
|
||||||
|
position your display is connected to (X or Y) and then you can run (assuming
|
||||||
|
you have the display on position X)::
|
||||||
|
|
||||||
|
>>> test_all('X')
|
||||||
|
|
||||||
|
Drawing some graphics
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
You must first create an LCD160CR object which will control the display. Do this
|
||||||
|
using::
|
||||||
|
|
||||||
|
>>> import lcd160cr
|
||||||
|
>>> lcd = lcd160cr.LCD160CR('X')
|
||||||
|
|
||||||
|
This assumes your display is connected in the X position. If it's in the Y
|
||||||
|
position then use ``lcd = lcd160cr.LCD160CR('Y')`` instead.
|
||||||
|
|
||||||
|
To erase the screen and draw a line, try::
|
||||||
|
|
||||||
|
>>> lcd.set_pen(lcd.rgb(255, 0, 0), lcd.rgb(64, 64, 128))
|
||||||
|
>>> lcd.erase()
|
||||||
|
>>> lcd.line(10, 10, 50, 80)
|
||||||
|
|
||||||
|
The next example draws random rectangles on the screen. You can copy-and-paste it
|
||||||
|
into the MicroPython prompt by first pressing "Ctrl-E" at the prompt, then "Ctrl-D"
|
||||||
|
once you have pasted the text. ::
|
||||||
|
|
||||||
|
from random import randint
|
||||||
|
for i in range(1000):
|
||||||
|
fg = lcd.rgb(randint(128, 255), randint(128, 255), randint(128, 255))
|
||||||
|
bg = lcd.rgb(randint(0, 128), randint(0, 128), randint(0, 128))
|
||||||
|
lcd.set_pen(fg, bg)
|
||||||
|
lcd.rect(randint(0, lcd.w), randint(0, lcd.h), randint(10, 40), randint(10, 40))
|
||||||
|
|
||||||
|
Using the touch sensor
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The display includes a resistive touch sensor that can report the position (in
|
||||||
|
pixels) of a single force-based touch on the screen. To see if there is a touch
|
||||||
|
on the screen use::
|
||||||
|
|
||||||
|
>>> lcd.is_touched()
|
||||||
|
|
||||||
|
This will return either ``False`` or ``True``. Run the above command while touching
|
||||||
|
the screen to see the result.
|
||||||
|
|
||||||
|
To get the location of the touch you can use the method::
|
||||||
|
|
||||||
|
>>> lcd.get_touch()
|
||||||
|
|
||||||
|
This will return a 3-tuple, with the first entry being 0 or 1 depending on whether
|
||||||
|
there is currently anything touching the screen (1 if there is), and the second and
|
||||||
|
third entries in the tuple being the x and y coordinates of the current (or most
|
||||||
|
recent) touch.
|
||||||
|
|
||||||
|
Directing the MicroPython output to the display
|
||||||
|
-----------------------------------------------
|
||||||
|
|
||||||
|
The display supports input from a UART and implements basic VT100 commands, which
|
||||||
|
means it can be used as a simple, general purpose terminal. Let's set up the
|
||||||
|
pyboard to redirect its output to the display.
|
||||||
|
|
||||||
|
First you need to create a UART object::
|
||||||
|
|
||||||
|
>>> import pyb
|
||||||
|
>>> uart = pyb.UART('XA', 115200)
|
||||||
|
|
||||||
|
This assumes your display is connected to position X. If it's on position Y then
|
||||||
|
use ``uart = pyb.UART('YA', 115200)`` instead.
|
||||||
|
|
||||||
|
Now, connect the REPL output to this UART::
|
||||||
|
|
||||||
|
>>> pyb.repl_uart(uart)
|
||||||
|
|
||||||
|
From now on anything you type at the MicroPython prompt, and any output you
|
||||||
|
receive, will appear on the display.
|
||||||
|
|
||||||
|
No set-up commands are required for this mode to work and you can use the display
|
||||||
|
to monitor the output of any UART, not just from the pyboard. All that is needed
|
||||||
|
is for the display to have power, ground and the power/enable pin driven high.
|
||||||
|
Then any characters on the display's UART input will be printed to the screen.
|
||||||
|
You can adjust the UART baudrate from the default of 115200 using the
|
||||||
|
`set_uart_baudrate` method.
|
BIN
docs/static/favicon.ico
vendored
Normal file
BIN
docs/static/favicon.ico
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -44,7 +44,8 @@ See :ref:`machine.Pin <machine.Pin>`. ::
|
|||||||
Timers
|
Timers
|
||||||
------
|
------
|
||||||
|
|
||||||
See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`. ::
|
See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`.
|
||||||
|
Timer ``id``'s take values from 0 to 3.::
|
||||||
|
|
||||||
from machine import Timer
|
from machine import Timer
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
|
@ -14,4 +14,5 @@ for instructions see :ref:`OTA How-To <wipy_firmware_upgrade>`.
|
|||||||
repl.rst
|
repl.rst
|
||||||
blynk.rst
|
blynk.rst
|
||||||
wlan.rst
|
wlan.rst
|
||||||
|
timer.rst
|
||||||
reset.rst
|
reset.rst
|
||||||
|
70
docs/wipy/tutorial/timer.rst
Normal file
70
docs/wipy/tutorial/timer.rst
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
Hardware timers
|
||||||
|
===============
|
||||||
|
|
||||||
|
Timers can be used for a great variety of tasks, calling a function periodically,
|
||||||
|
counting events, and generating a PWM signal are among the most common use cases.
|
||||||
|
Each timer consists of two 16-bit channels and this channels can be tied together to
|
||||||
|
form one 32-bit timer. The operating mode needs to be configured per timer, but then
|
||||||
|
the period (or the frequency) can be independently configured on each channel.
|
||||||
|
By using the callback method, the timer event can call a Python function.
|
||||||
|
|
||||||
|
Example usage to toggle an LED at a fixed frequency::
|
||||||
|
|
||||||
|
from machine import Timer
|
||||||
|
from machine import Pin
|
||||||
|
led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
|
||||||
|
tim = Timer(3) # create a timer object using timer 3
|
||||||
|
tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode
|
||||||
|
tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz
|
||||||
|
tim_ch.irq(handler=lambda t:led.toggle(), trigger=Timer.TIMEOUT) # toggle a LED on every cycle of the timer
|
||||||
|
|
||||||
|
Example using named function for the callback::
|
||||||
|
|
||||||
|
from machine import Timer
|
||||||
|
from machine import Pin
|
||||||
|
tim = Timer(1, mode=Timer.PERIODIC, width=32)
|
||||||
|
tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer
|
||||||
|
|
||||||
|
led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED
|
||||||
|
|
||||||
|
def tick(timer): # we will receive the timer object when being called
|
||||||
|
global led
|
||||||
|
led.toggle() # toggle the LED
|
||||||
|
|
||||||
|
tim_a.irq(handler=tick, trigger=Timer.TIMEOUT) # create the interrupt
|
||||||
|
|
||||||
|
Further examples::
|
||||||
|
|
||||||
|
from machine import Timer
|
||||||
|
tim1 = Timer(1, mode=Timer.ONE_SHOT) # initialize it in one shot mode
|
||||||
|
tim2 = Timer(2, mode=Timer.PWM) # initialize it in PWM mode
|
||||||
|
tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges
|
||||||
|
tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=5000) # start the PWM on channel B with a 50% duty cycle
|
||||||
|
tim2_ch.freq(20) # set the frequency (can also get)
|
||||||
|
tim2_ch.duty_cycle(3010) # set the duty cycle to 30.1% (can also get)
|
||||||
|
tim2_ch.duty_cycle(3020, Timer.NEGATIVE) # set the duty cycle to 30.2% and change the polarity to negative
|
||||||
|
tim2_ch.period(2000000) # change the period to 2 seconds
|
||||||
|
|
||||||
|
|
||||||
|
Additional constants for Timer class
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
.. data:: Timer.PWM
|
||||||
|
|
||||||
|
PWM timer operating mode.
|
||||||
|
|
||||||
|
.. data:: Timer.A
|
||||||
|
.. data:: Timer.B
|
||||||
|
|
||||||
|
Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when
|
||||||
|
using a 32-bit timer.
|
||||||
|
|
||||||
|
.. data:: Timer.POSITIVE
|
||||||
|
.. data:: Timer.NEGATIVE
|
||||||
|
|
||||||
|
Timer channel polarity selection (only relevant in PWM mode).
|
||||||
|
|
||||||
|
.. data:: Timer.TIMEOUT
|
||||||
|
.. data:: Timer.MATCH
|
||||||
|
|
||||||
|
Timer channel IRQ triggers.
|
@ -65,7 +65,7 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
|
|||||||
|
|
||||||
// time pulse, should be 80us
|
// time pulse, should be 80us
|
||||||
ticks = machine_time_pulse_us(pin, 1, 150);
|
ticks = machine_time_pulse_us(pin, 1, 150);
|
||||||
if (ticks == (mp_uint_t)-1) {
|
if ((mp_int_t)ticks < 0) {
|
||||||
goto timeout;
|
goto timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ STATIC mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
|
|||||||
uint8_t *buf = bufinfo.buf;
|
uint8_t *buf = bufinfo.buf;
|
||||||
for (int i = 0; i < 40; ++i) {
|
for (int i = 0; i < 40; ++i) {
|
||||||
ticks = machine_time_pulse_us(pin, 1, 100);
|
ticks = machine_time_pulse_us(pin, 1, 100);
|
||||||
if (ticks == (mp_uint_t)-1) {
|
if ((mp_int_t)ticks < 0) {
|
||||||
goto timeout;
|
goto timeout;
|
||||||
}
|
}
|
||||||
buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48);
|
buf[i / 8] = (buf[i / 8] << 1) | (ticks > 48);
|
||||||
|
464
drivers/display/lcd160cr.py
Normal file
464
drivers/display/lcd160cr.py
Normal file
@ -0,0 +1,464 @@
|
|||||||
|
# Driver for official MicroPython LCD160CR display
|
||||||
|
# MIT license; Copyright (c) 2017 Damien P. George
|
||||||
|
|
||||||
|
from micropython import const
|
||||||
|
from utime import sleep_ms
|
||||||
|
from ustruct import calcsize, pack_into
|
||||||
|
import uerrno, machine
|
||||||
|
|
||||||
|
# for set_orient
|
||||||
|
PORTRAIT = const(0)
|
||||||
|
LANDSCAPE = const(1)
|
||||||
|
PORTRAIT_UPSIDEDOWN = const(2)
|
||||||
|
LANDSCAPE_UPSIDEDOWN = const(3)
|
||||||
|
|
||||||
|
# for set_startup_deco; can be or'd
|
||||||
|
STARTUP_DECO_NONE = const(0)
|
||||||
|
STARTUP_DECO_MLOGO = const(1)
|
||||||
|
STARTUP_DECO_INFO = const(2)
|
||||||
|
|
||||||
|
_uart_baud_table = {
|
||||||
|
2400: 0,
|
||||||
|
4800: 1,
|
||||||
|
9600: 2,
|
||||||
|
19200: 3,
|
||||||
|
38400: 4,
|
||||||
|
57600: 5,
|
||||||
|
115200: 6,
|
||||||
|
230400: 7,
|
||||||
|
460800: 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
class LCD160CR:
|
||||||
|
def __init__(self, connect=None, *, pwr=None, i2c=None, spi=None, i2c_addr=98):
|
||||||
|
if connect in ('X', 'Y', 'XY', 'YX'):
|
||||||
|
i = connect[-1]
|
||||||
|
j = connect[0]
|
||||||
|
y = j + '4'
|
||||||
|
elif connect == 'C':
|
||||||
|
i = 2
|
||||||
|
j = 2
|
||||||
|
y = 'A7'
|
||||||
|
else:
|
||||||
|
if pwr is None or i2c is None or spi is None:
|
||||||
|
raise ValueError('must specify valid "connect" or all of "pwr", "i2c" and "spi"')
|
||||||
|
|
||||||
|
if pwr is None:
|
||||||
|
pwr = machine.Pin(y, machine.Pin.OUT)
|
||||||
|
if i2c is None:
|
||||||
|
i2c = machine.I2C(i, freq=1000000)
|
||||||
|
if spi is None:
|
||||||
|
spi = machine.SPI(j, baudrate=13500000, polarity=0, phase=0)
|
||||||
|
|
||||||
|
if not pwr.value():
|
||||||
|
pwr(1)
|
||||||
|
sleep_ms(10)
|
||||||
|
# else:
|
||||||
|
# alread have power
|
||||||
|
# lets be optimistic...
|
||||||
|
|
||||||
|
# set connections
|
||||||
|
self.pwr = pwr
|
||||||
|
self.i2c = i2c
|
||||||
|
self.spi = spi
|
||||||
|
self.i2c_addr = i2c_addr
|
||||||
|
|
||||||
|
# create temp buffers and memoryviews
|
||||||
|
self.buf16 = bytearray(16)
|
||||||
|
self.buf19 = bytearray(19)
|
||||||
|
self.buf = [None] * 10
|
||||||
|
for i in range(1, 10):
|
||||||
|
self.buf[i] = memoryview(self.buf16)[0:i]
|
||||||
|
self.buf1 = self.buf[1]
|
||||||
|
self.array4 = [0, 0, 0, 0]
|
||||||
|
|
||||||
|
# set default orientation and window
|
||||||
|
self.set_orient(PORTRAIT)
|
||||||
|
self._fcmd2b('<BBBBBB', 0x76, 0, 0, self.w, self.h) # viewport 'v'
|
||||||
|
self._fcmd2b('<BBBBBB', 0x79, 0, 0, self.w, self.h) # window 'y'
|
||||||
|
|
||||||
|
def _send(self, cmd):
|
||||||
|
i = self.i2c.writeto(self.i2c_addr, cmd)
|
||||||
|
if i == len(cmd):
|
||||||
|
return
|
||||||
|
cmd = memoryview(cmd)
|
||||||
|
n = len(cmd)
|
||||||
|
while True:
|
||||||
|
i += self.i2c.writeto(self.i2c_addr, cmd[i:])
|
||||||
|
if i == n:
|
||||||
|
return
|
||||||
|
sleep_ms(10)
|
||||||
|
|
||||||
|
def _fcmd2(self, fmt, a0, a1=0, a2=0):
|
||||||
|
buf = self.buf[calcsize(fmt)]
|
||||||
|
pack_into(fmt, buf, 0, 2, a0, a1, a2)
|
||||||
|
self._send(buf)
|
||||||
|
|
||||||
|
def _fcmd2b(self, fmt, a0, a1, a2, a3, a4=0):
|
||||||
|
buf = self.buf[calcsize(fmt)]
|
||||||
|
pack_into(fmt, buf, 0, 2, a0, a1, a2, a3, a4)
|
||||||
|
self._send(buf)
|
||||||
|
|
||||||
|
def _waitfor(self, n, buf):
|
||||||
|
t = 5000
|
||||||
|
while t:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, self.buf1)
|
||||||
|
if self.buf1[0] >= n:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, buf)
|
||||||
|
return
|
||||||
|
t -= 1
|
||||||
|
sleep_ms(1)
|
||||||
|
raise OSError(uerrno.ETIMEDOUT)
|
||||||
|
|
||||||
|
def oflush(self, n=255):
|
||||||
|
t = 5000
|
||||||
|
while t:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr + 1, self.buf1)
|
||||||
|
r = self.buf1[0]
|
||||||
|
if r >= n:
|
||||||
|
return
|
||||||
|
t -= 1
|
||||||
|
machine.idle()
|
||||||
|
raise OSError(uerrno.ETIMEDOUT)
|
||||||
|
|
||||||
|
def iflush(self):
|
||||||
|
t = 5000
|
||||||
|
while t:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, self.buf16)
|
||||||
|
if self.buf16[0] == 0:
|
||||||
|
return
|
||||||
|
t -= 1
|
||||||
|
sleep_ms(1)
|
||||||
|
raise OSError(uerrno.ETIMEDOUT)
|
||||||
|
|
||||||
|
#### MISC METHODS ####
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rgb(r, g, b):
|
||||||
|
return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | (r >> 3)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clip_line(c, w, h):
|
||||||
|
while True:
|
||||||
|
ca = ce = 0
|
||||||
|
if c[1] < 0:
|
||||||
|
ca |= 8
|
||||||
|
elif c[1] > h:
|
||||||
|
ca |= 4
|
||||||
|
if c[0] < 0:
|
||||||
|
ca |= 1
|
||||||
|
elif c[0] > w:
|
||||||
|
ca |= 2
|
||||||
|
if c[3] < 0:
|
||||||
|
ce |= 8
|
||||||
|
elif c[3] > h:
|
||||||
|
ce |= 4
|
||||||
|
if c[2] < 0:
|
||||||
|
ce |= 1
|
||||||
|
elif c[2] > w:
|
||||||
|
ce |= 2
|
||||||
|
if ca & ce:
|
||||||
|
return False
|
||||||
|
elif ca | ce:
|
||||||
|
ca |= ce
|
||||||
|
if ca & 1:
|
||||||
|
if c[2] < c[0]:
|
||||||
|
c[0], c[2] = c[2], c[0]
|
||||||
|
c[1], c[3] = c[3], c[1]
|
||||||
|
c[1] += ((-c[0]) * (c[3] - c[1])) // (c[2] - c[0])
|
||||||
|
c[0] = 0
|
||||||
|
elif ca & 2:
|
||||||
|
if c[2] < c[0]:
|
||||||
|
c[0], c[2] = c[2], c[0]
|
||||||
|
c[1], c[3] = c[3], c[1]
|
||||||
|
c[3] += ((w - 1 - c[2]) * (c[3] - c[1])) // (c[2] - c[0])
|
||||||
|
c[2] = w - 1
|
||||||
|
elif ca & 4:
|
||||||
|
if c[0] == c[2]:
|
||||||
|
if c[1] >= h:
|
||||||
|
c[1] = h - 1
|
||||||
|
if c[3] >= h:
|
||||||
|
c[3] = h - 1
|
||||||
|
else:
|
||||||
|
if c[3] < c[1]:
|
||||||
|
c[0], c[2] = c[2], c[0]
|
||||||
|
c[1], c[3] = c[3], c[1]
|
||||||
|
c[2] += ((h - 1 - c[3]) * (c[2] - c[0])) // (c[3] - c[1])
|
||||||
|
c[3] = h - 1
|
||||||
|
else:
|
||||||
|
if c[0] == c[2]:
|
||||||
|
if c[1] < 0:
|
||||||
|
c[1] = 0
|
||||||
|
if c[3] < 0:
|
||||||
|
c[3] = 0
|
||||||
|
else:
|
||||||
|
if c[3] < c[1]:
|
||||||
|
c[0], c[2] = c[2], c[0]
|
||||||
|
c[1], c[3] = c[3], c[1]
|
||||||
|
c[0] += ((-c[1]) * (c[2] - c[0])) // (c[3] - c[1])
|
||||||
|
c[1] = 0
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
#### SETUP COMMANDS ####
|
||||||
|
|
||||||
|
def set_power(self, on):
|
||||||
|
self.pwr(value)
|
||||||
|
sleep_ms(15)
|
||||||
|
|
||||||
|
def set_orient(self, orient):
|
||||||
|
self._fcmd2('<BBB', 0x14, (orient & 3) + 4)
|
||||||
|
# update width and height variables
|
||||||
|
self.iflush()
|
||||||
|
self._send(b'\x02g0')
|
||||||
|
self._waitfor(4, self.buf[5])
|
||||||
|
self.w = self.buf[5][1]
|
||||||
|
self.h = self.buf[5][2]
|
||||||
|
|
||||||
|
def set_brightness(self, value):
|
||||||
|
self._fcmd2('<BBB', 0x16, value)
|
||||||
|
|
||||||
|
def set_i2c_addr(self, addr):
|
||||||
|
# 0x0e set i2c addr
|
||||||
|
if addr & 3:
|
||||||
|
raise ValueError('must specify mod 4 aligned address')
|
||||||
|
self._fcmd2('<BBW', 0x0e, 0x433249 | (addr << 24))
|
||||||
|
|
||||||
|
def set_uart_baudrate(self, baudrate):
|
||||||
|
try:
|
||||||
|
baudrate = _uart_baud_table[baudrate]
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError('invalid baudrate')
|
||||||
|
self._fcmd2('<BBB', 0x18, baudrate)
|
||||||
|
|
||||||
|
def set_startup_deco(self, value):
|
||||||
|
self._fcmd2('<BBB', 0x19, value)
|
||||||
|
|
||||||
|
def save_to_flash(self):
|
||||||
|
self._fcmd2('<BBB', 0x66, 'n')
|
||||||
|
|
||||||
|
#### PIXEL ACCESS ####
|
||||||
|
|
||||||
|
def set_pixel(self, x, y, c):
|
||||||
|
self._fcmd2b('<BBBBH', 0x41, x, y, c)
|
||||||
|
|
||||||
|
def get_pixel(self, x, y):
|
||||||
|
self._fcmd2b('<BBBB', 0x61, x, y)
|
||||||
|
t = 1000
|
||||||
|
while t:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, self.buf1)
|
||||||
|
if self.buf1[0] >= 2:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, self.buf[3])
|
||||||
|
return self.buf[3][1] + self.buf[3][2] << 8
|
||||||
|
t -= 1
|
||||||
|
sleep_ms(1)
|
||||||
|
raise OSError(uerrno.ETIMEDOUT)
|
||||||
|
|
||||||
|
def get_line(self, x, y, buf):
|
||||||
|
l = len(buf) // 2
|
||||||
|
self._fcmd2b('<BBBBB', 0x10, l, x, y)
|
||||||
|
t = 1000
|
||||||
|
while t:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, self.buf1)
|
||||||
|
if self.buf1[0] >= l:
|
||||||
|
self.i2c.readfrom_into(self.i2c_addr, buf)
|
||||||
|
return
|
||||||
|
t -= 1
|
||||||
|
sleep_ms(1)
|
||||||
|
raise OSError(uerrno.ETIMEDOUT)
|
||||||
|
|
||||||
|
def screen_dump(self, buf):
|
||||||
|
line = bytearray(self.w + 1)
|
||||||
|
h = len(buf) // (2 * self.w)
|
||||||
|
if h > self.h:
|
||||||
|
h = self.h
|
||||||
|
for i in range(h):
|
||||||
|
ix = i * self.w * 2
|
||||||
|
self.get_line(0, i, line)
|
||||||
|
for j in range(1, len(line)):
|
||||||
|
buf[ix] = line[j]
|
||||||
|
ix += 1
|
||||||
|
self.get_line(self.w // 2, i, line)
|
||||||
|
for j in range(1, len(line)):
|
||||||
|
buf[ix] = line[j]
|
||||||
|
ix += 1
|
||||||
|
|
||||||
|
def screen_load(self, buf):
|
||||||
|
l = self.w * self.h * 2+2
|
||||||
|
self._fcmd2b('<BBHBBB', 0x70, l, 16, self.w, self.h)
|
||||||
|
n = 0
|
||||||
|
ar = memoryview(buf)
|
||||||
|
while n < len(buf):
|
||||||
|
if len(buf) - n >= 0x200:
|
||||||
|
self._send(ar[n:n + 0x200])
|
||||||
|
n += 0x200
|
||||||
|
else:
|
||||||
|
self._send(ar[n:])
|
||||||
|
while n < self.w * self.h * 2:
|
||||||
|
self._send(b'\x00')
|
||||||
|
n += 1
|
||||||
|
|
||||||
|
#### TEXT COMMANDS ####
|
||||||
|
|
||||||
|
def set_pos(self, x, y):
|
||||||
|
self._fcmd2('<BBBB', 0x58, x, y)
|
||||||
|
|
||||||
|
def set_text_color(self, fg, bg):
|
||||||
|
self._fcmd2('<BBHH', 0x63, fg, bg)
|
||||||
|
|
||||||
|
def set_font(self, font, scale=0, bold=0, trans=0, scroll=0):
|
||||||
|
self._fcmd2('<BBBB', 0x46, (scroll << 7) | (trans << 6) | ((font & 3) << 4) | (bold & 0xf), scale & 0xff)
|
||||||
|
|
||||||
|
def write(self, s):
|
||||||
|
# TODO: eventually check for room in LCD input queue
|
||||||
|
self._send(s)
|
||||||
|
|
||||||
|
#### PRIMITIVE DRAWING COMMANDS ####
|
||||||
|
|
||||||
|
def set_pen(self, line, fill):
|
||||||
|
self._fcmd2('<BBHH', 0x50, line, fill)
|
||||||
|
|
||||||
|
def erase(self):
|
||||||
|
self._send(b'\x02\x45')
|
||||||
|
|
||||||
|
def dot(self, x, y):
|
||||||
|
if 0 <= x < self.w and 0 <= y < self.h:
|
||||||
|
self._fcmd2('<BBBB', 0x4b, x, y)
|
||||||
|
|
||||||
|
def rect(self, x, y, w, h, cmd=0x72):
|
||||||
|
if x + w <= 0 or y + h <= 0 or x >= self.w or y >= self.h:
|
||||||
|
return
|
||||||
|
elif x < 0 or y < 0:
|
||||||
|
left = top = True
|
||||||
|
if x < 0:
|
||||||
|
left = False
|
||||||
|
w += x
|
||||||
|
x = 0
|
||||||
|
if y < 0:
|
||||||
|
top = False
|
||||||
|
h += y
|
||||||
|
y = 0
|
||||||
|
if cmd == 0x51 or cmd == 0x72:
|
||||||
|
# draw interior
|
||||||
|
self._fcmd2b('<BBBBBB', 0x51, x, y, min(w, 255), min(h, 255))
|
||||||
|
if cmd == 0x57 or cmd == 0x72:
|
||||||
|
# draw outline
|
||||||
|
if left:
|
||||||
|
self._fcmd2b('<BBBBBB', 0x57, x, y, 1, min(h, 255))
|
||||||
|
if top:
|
||||||
|
self._fcmd2b('<BBBBBB', 0x57, x, y, min(w, 255), 1)
|
||||||
|
if x + w < self.w:
|
||||||
|
self._fcmd2b('<BBBBBB', 0x57, x + w, y, 1, min(h, 255))
|
||||||
|
if y + h < self.h:
|
||||||
|
self._fcmd2b('<BBBBBB', 0x57, x, y + h, min(w, 255), 1)
|
||||||
|
else:
|
||||||
|
self._fcmd2b('<BBBBBB', cmd, x, y, min(w, 255), min(h, 255))
|
||||||
|
|
||||||
|
def rect_outline(self, x, y, w, h):
|
||||||
|
self.rect(x, y, w, h, 0x57)
|
||||||
|
|
||||||
|
def rect_interior(self, x, y, w, h):
|
||||||
|
self.rect(x, y, w, h, 0x51)
|
||||||
|
|
||||||
|
def line(self, x1, y1, x2, y2):
|
||||||
|
ar4 = self.array4
|
||||||
|
ar4[0] = x1
|
||||||
|
ar4[1] = y1
|
||||||
|
ar4[2] = x2
|
||||||
|
ar4[3] = y2
|
||||||
|
if self.clip_line(ar4, self.w, self.h):
|
||||||
|
self._fcmd2b('<BBBBBB', 0x4c, ar4[0], ar4[1], ar4[2], ar4[3])
|
||||||
|
|
||||||
|
def dot_no_clip(self, x, y):
|
||||||
|
self._fcmd2('<BBBB', 0x4b, x, y)
|
||||||
|
|
||||||
|
def rect_no_clip(self, x, y, w, h):
|
||||||
|
self._fcmd2b('<BBBBBB', 0x72, x, y, w, h)
|
||||||
|
|
||||||
|
def rect_outline_no_clip(self, x, y, w, h):
|
||||||
|
self._fcmd2b('<BBBBBB', 0x57, x, y, w, h)
|
||||||
|
|
||||||
|
def rect_interior_no_clip(self, x, y, w, h):
|
||||||
|
self._fcmd2b('<BBBBBB', 0x51, x, y, w, h)
|
||||||
|
|
||||||
|
def line_no_clip(self, x1, y1, x2, y2):
|
||||||
|
self._fcmd2b('<BBBBBB', 0x4c, x1, y1, x2, y2)
|
||||||
|
|
||||||
|
def poly_dot(self, data):
|
||||||
|
if len(data) & 1:
|
||||||
|
raise ValueError('must specify even number of bytes')
|
||||||
|
self._fcmd2('<BBB', 0x71, len(data) // 2)
|
||||||
|
self._send(data)
|
||||||
|
|
||||||
|
def poly_line(self, data):
|
||||||
|
if len(data) & 1:
|
||||||
|
raise ValueError('must specify even number of bytes')
|
||||||
|
self._fcmd2('<BBB', 0x78, len(data) // 2)
|
||||||
|
self._send(data)
|
||||||
|
|
||||||
|
#### TOUCH COMMANDS ####
|
||||||
|
|
||||||
|
def touch_config(self, calib=False, save=False, irq=None):
|
||||||
|
self._fcmd2('<BBBB', 0x7a, (irq is not None) << 2 | save << 1 | calib, bool(irq) << 7)
|
||||||
|
|
||||||
|
def is_touched(self):
|
||||||
|
self._send(b'\x02T')
|
||||||
|
b = self.buf[4]
|
||||||
|
self._waitfor(3, b)
|
||||||
|
return b[1] >> 7 != 0
|
||||||
|
|
||||||
|
def get_touch(self):
|
||||||
|
self._send(b'\x02T') # implicit LCD output flush
|
||||||
|
b = self.buf[4]
|
||||||
|
self._waitfor(3, b)
|
||||||
|
return b[1] >> 7, b[2], b[3]
|
||||||
|
|
||||||
|
#### ADVANCED COMMANDS ####
|
||||||
|
|
||||||
|
def set_spi_win(self, x, y, w, h):
|
||||||
|
pack_into('<BBBHHHHHHHH', self.buf19, 0, 2, 0x55, 10, x, y, x + w - 1, y + h - 1, 0, 0, 0, 0xffff)
|
||||||
|
self._send(self.buf19)
|
||||||
|
|
||||||
|
def fast_spi(self, flush=True):
|
||||||
|
if flush:
|
||||||
|
self.oflush()
|
||||||
|
self._send(b'\x02\x12')
|
||||||
|
return self.spi
|
||||||
|
|
||||||
|
def show_framebuf(self, buf):
|
||||||
|
self.fast_spi().write(buf)
|
||||||
|
|
||||||
|
def set_scroll(self, on):
|
||||||
|
self._fcmd2('<BBB', 0x15, on)
|
||||||
|
|
||||||
|
def set_scroll_win(self, win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0):
|
||||||
|
pack_into('<BBBHHHHHHHH', self.buf19, 0, 2, 0x55, win, x, y, w, h, vec, pat, fill, color)
|
||||||
|
self._send(self.buf19)
|
||||||
|
|
||||||
|
def set_scroll_win_param(self, win, param, value):
|
||||||
|
self._fcmd2b('<BBBBH', 0x75, win, param, value)
|
||||||
|
|
||||||
|
def set_scroll_buf(self, s):
|
||||||
|
l = len(s)
|
||||||
|
if l > 32:
|
||||||
|
raise ValueError('length must be 32 or less')
|
||||||
|
self._fcmd2('<BBB', 0x11, l)
|
||||||
|
self._send(s)
|
||||||
|
|
||||||
|
def jpeg_start(self, l):
|
||||||
|
self.oflush()
|
||||||
|
self._fcmd2('<BBH', 0x6a, l)
|
||||||
|
|
||||||
|
def jpeg_data(self, buf):
|
||||||
|
self._send(buf)
|
||||||
|
|
||||||
|
def jpeg(self, buf):
|
||||||
|
self.jpeg_start(len(buf))
|
||||||
|
self.jpeg_data(buf)
|
||||||
|
|
||||||
|
def feed_wdt(self):
|
||||||
|
self._send(b'\x02\x17')
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self._send(b'\x02Y\xef\xbe\xad\xde')
|
||||||
|
sleep_ms(15)
|
161
drivers/display/lcd160cr_test.py
Normal file
161
drivers/display/lcd160cr_test.py
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
# Driver test for official MicroPython LCD160CR display
|
||||||
|
# MIT license; Copyright (c) 2017 Damien P. George
|
||||||
|
|
||||||
|
import time, math, framebuf, lcd160cr
|
||||||
|
|
||||||
|
def get_lcd(lcd):
|
||||||
|
if type(lcd) is str:
|
||||||
|
lcd = lcd160cr.LCD160CR(lcd)
|
||||||
|
return lcd
|
||||||
|
|
||||||
|
def show_adc(lcd, adc):
|
||||||
|
data = [adc.read_core_temp(), adc.read_core_vbat(), 3.3]
|
||||||
|
try:
|
||||||
|
data[2] = adc.read_vref()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
for i in range(3):
|
||||||
|
lcd.set_text_color((825, 1625, 1600)[i], 0)
|
||||||
|
lcd.set_font(2)
|
||||||
|
lcd.set_pos(0, 100 + i * 16)
|
||||||
|
lcd.write('%4s: ' % ('TEMP', 'VBAT', 'VREF')[i])
|
||||||
|
if i > 0:
|
||||||
|
s = '%6.3fV' % data[i]
|
||||||
|
else:
|
||||||
|
s = '%5.1f°C' % data[i]
|
||||||
|
lcd.set_font(1, bold=0, scale=1)
|
||||||
|
lcd.write(s)
|
||||||
|
|
||||||
|
def test_features(lcd):
|
||||||
|
# if we run on pyboard then use ADC and RTC features
|
||||||
|
try:
|
||||||
|
import pyb
|
||||||
|
adc = pyb.ADCAll(12, 0xf0000)
|
||||||
|
rtc = pyb.RTC()
|
||||||
|
except:
|
||||||
|
adc = None
|
||||||
|
rtc = None
|
||||||
|
|
||||||
|
# set orientation and clear screen
|
||||||
|
lcd = get_lcd(lcd)
|
||||||
|
lcd.set_orient(lcd160cr.PORTRAIT)
|
||||||
|
lcd.set_pen(0, 0)
|
||||||
|
lcd.erase()
|
||||||
|
|
||||||
|
# create M-logo
|
||||||
|
mlogo = framebuf.FrameBuffer(bytearray(17 * 17 * 2), 17, 17, framebuf.RGB565)
|
||||||
|
mlogo.fill(0)
|
||||||
|
mlogo.fill_rect(1, 1, 15, 15, 0xffffff)
|
||||||
|
mlogo.vline(4, 4, 12, 0)
|
||||||
|
mlogo.vline(8, 1, 12, 0)
|
||||||
|
mlogo.vline(12, 4, 12, 0)
|
||||||
|
mlogo.vline(14, 13, 2, 0)
|
||||||
|
|
||||||
|
# create inline framebuf
|
||||||
|
offx = 14
|
||||||
|
offy = 19
|
||||||
|
w = 100
|
||||||
|
h = 75
|
||||||
|
fbuf = framebuf.FrameBuffer(bytearray(w * h * 2), w, h, framebuf.RGB565)
|
||||||
|
lcd.set_spi_win(offx, offy, w, h)
|
||||||
|
|
||||||
|
# initialise loop parameters
|
||||||
|
tx = ty = 0
|
||||||
|
t0 = time.ticks_us()
|
||||||
|
|
||||||
|
for i in range(300):
|
||||||
|
# update position of cross-hair
|
||||||
|
t, tx2, ty2 = lcd.get_touch()
|
||||||
|
if t:
|
||||||
|
tx2 -= offx
|
||||||
|
ty2 -= offy
|
||||||
|
if tx2 >= 0 and ty2 >= 0 and tx2 < w and ty2 < h:
|
||||||
|
tx, ty = tx2, ty2
|
||||||
|
else:
|
||||||
|
tx = (tx + 1) % w
|
||||||
|
ty = (ty + 1) % h
|
||||||
|
|
||||||
|
# create and show the inline framebuf
|
||||||
|
fbuf.fill(lcd.rgb(128 + int(64 * math.cos(0.1 * i)), 128, 192))
|
||||||
|
fbuf.line(w // 2, h // 2,
|
||||||
|
w // 2 + int(40 * math.cos(0.2 * i)),
|
||||||
|
h // 2 + int(40 * math.sin(0.2 * i)),
|
||||||
|
lcd.rgb(128, 255, 64))
|
||||||
|
fbuf.hline(0, ty, w, lcd.rgb(64, 64, 64))
|
||||||
|
fbuf.vline(tx, 0, h, lcd.rgb(64, 64, 64))
|
||||||
|
fbuf.rect(tx - 3, ty - 3, 7, 7, lcd.rgb(64, 64, 64))
|
||||||
|
for phase in (-0.2, 0, 0.2):
|
||||||
|
x = w // 2 - 8 + int(50 * math.cos(0.05 * i + phase))
|
||||||
|
y = h // 2 - 8 + int(32 * math.sin(0.05 * i + phase))
|
||||||
|
fbuf.blit(mlogo, x, y)
|
||||||
|
for j in range(-3, 3):
|
||||||
|
fbuf.text('MicroPython',
|
||||||
|
5, h // 2 + 9 * j + int(20 * math.sin(0.1 * (i + j))),
|
||||||
|
lcd.rgb(128 + 10 * j, 0, 128 - 10 * j))
|
||||||
|
lcd.show_framebuf(fbuf)
|
||||||
|
|
||||||
|
# show results from the ADC
|
||||||
|
if adc:
|
||||||
|
show_adc(lcd, adc)
|
||||||
|
|
||||||
|
# show the time
|
||||||
|
if rtc:
|
||||||
|
lcd.set_pos(2, 0)
|
||||||
|
lcd.set_font(1)
|
||||||
|
t = rtc.datetime()
|
||||||
|
lcd.write('%4d-%02d-%02d %2d:%02d:%02d.%01d' % (t[0], t[1], t[2], t[4], t[5], t[6], t[7] // 100000))
|
||||||
|
|
||||||
|
# compute the frame rate
|
||||||
|
t1 = time.ticks_us()
|
||||||
|
dt = time.ticks_diff(t1, t0)
|
||||||
|
t0 = t1
|
||||||
|
|
||||||
|
# show the frame rate
|
||||||
|
lcd.set_pos(2, 9)
|
||||||
|
lcd.write('%.2f fps' % (1000000 / dt))
|
||||||
|
|
||||||
|
def test_mandel(lcd):
|
||||||
|
# set orientation and clear screen
|
||||||
|
lcd = get_lcd(lcd)
|
||||||
|
lcd.set_orient(lcd160cr.PORTRAIT)
|
||||||
|
lcd.set_pen(0, 0xffff)
|
||||||
|
lcd.erase()
|
||||||
|
|
||||||
|
# function to compute Mandelbrot pixels
|
||||||
|
def in_set(c):
|
||||||
|
z = 0
|
||||||
|
for i in range(32):
|
||||||
|
z = z * z + c
|
||||||
|
if abs(z) > 100:
|
||||||
|
return i
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# cache width and height of LCD
|
||||||
|
w = lcd.w
|
||||||
|
h = lcd.h
|
||||||
|
|
||||||
|
# create the buffer for each line and set SPI parameters
|
||||||
|
line = bytearray(w * 2)
|
||||||
|
lcd.set_spi_win(0, 0, w, h)
|
||||||
|
spi = lcd.fast_spi()
|
||||||
|
|
||||||
|
# draw the Mandelbrot set line-by-line
|
||||||
|
for v in range(h):
|
||||||
|
for u in range(w):
|
||||||
|
c = in_set((v / ((h - 1) / 3.2) - 2.3) + (u / ((w - 1) / 2.4) - 1.2) * 1j)
|
||||||
|
if c < 16:
|
||||||
|
rgb = c << 12 | c << 6
|
||||||
|
else:
|
||||||
|
rgb = 0xf800 | c << 6
|
||||||
|
line[2 * u] = rgb
|
||||||
|
line[2 * u + 1] = rgb >> 8
|
||||||
|
spi.write(line)
|
||||||
|
|
||||||
|
def test_all(lcd):
|
||||||
|
lcd = get_lcd(lcd)
|
||||||
|
test_features(lcd)
|
||||||
|
test_mandel(lcd)
|
||||||
|
|
||||||
|
print('To run all tests: test_all(<lcd>)')
|
||||||
|
print('Individual tests are: test_features, test_mandel')
|
||||||
|
print('<lcd> argument should be a connection, eg "X", or an LCD160CR object')
|
200
drivers/memory/spiflash.c
Normal file
200
drivers/memory/spiflash.c
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "py/mperrno.h"
|
||||||
|
#include "py/mphal.h"
|
||||||
|
#include "extmod/machine_spi.h"
|
||||||
|
#include "drivers/memory/spiflash.h"
|
||||||
|
|
||||||
|
#define CMD_WRITE (0x02)
|
||||||
|
#define CMD_READ (0x03)
|
||||||
|
#define CMD_WRDI (0x04)
|
||||||
|
#define CMD_RDSR (0x05)
|
||||||
|
#define CMD_WREN (0x06)
|
||||||
|
#define CMD_SEC_ERASE (0x20)
|
||||||
|
#define WAIT_SR_TIMEOUT (1000000)
|
||||||
|
|
||||||
|
#define PAGE_SIZE (256) // maximum bytes we can write in one SPI transfer
|
||||||
|
#define SECTOR_SIZE (4096) // size of erase sector
|
||||||
|
|
||||||
|
// Note: this code is not reentrant with this shared buffer
|
||||||
|
STATIC uint8_t buf[SECTOR_SIZE];
|
||||||
|
|
||||||
|
void mp_spiflash_init(mp_spiflash_t *self) {
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
mp_hal_pin_output(self->cs);
|
||||||
|
mp_hal_pin_write(self->spi.sck, 0);
|
||||||
|
mp_hal_pin_output(self->spi.sck);
|
||||||
|
mp_hal_pin_output(self->spi.mosi);
|
||||||
|
mp_hal_pin_input(self->spi.miso);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mp_spiflash_acquire_bus(mp_spiflash_t *self) {
|
||||||
|
// can be used for actions needed to acquire bus
|
||||||
|
(void)self;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) {
|
||||||
|
// can be used for actions needed to release bus
|
||||||
|
(void)self;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mp_spiflash_transfer(mp_spiflash_t *self, size_t len, const uint8_t *src, uint8_t *dest) {
|
||||||
|
mp_machine_soft_spi_transfer(&self->spi.base, len, src, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) {
|
||||||
|
uint8_t cmd[1] = {CMD_RDSR};
|
||||||
|
mp_hal_pin_write(self->cs, 0);
|
||||||
|
mp_spiflash_transfer(self, 1, cmd, NULL);
|
||||||
|
for (; timeout; --timeout) {
|
||||||
|
mp_spiflash_transfer(self, 1, cmd, cmd);
|
||||||
|
if ((cmd[0] & mask) == val) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
if ((cmd[0] & mask) == val) {
|
||||||
|
return 0; // success
|
||||||
|
} else if (timeout == 0) {
|
||||||
|
return -MP_ETIMEDOUT;
|
||||||
|
} else {
|
||||||
|
return -MP_EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int mp_spiflash_wait_wel1(mp_spiflash_t *self) {
|
||||||
|
return mp_spiflash_wait_sr(self, 2, 2, WAIT_SR_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int mp_spiflash_wait_wip0(mp_spiflash_t *self) {
|
||||||
|
return mp_spiflash_wait_sr(self, 1, 0, WAIT_SR_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) {
|
||||||
|
mp_hal_pin_write(self->cs, 0);
|
||||||
|
mp_spiflash_transfer(self, 1, &cmd, NULL);
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int mp_spiflash_erase_sector(mp_spiflash_t *self, uint32_t addr) {
|
||||||
|
// enable writes
|
||||||
|
mp_spiflash_write_cmd(self, CMD_WREN);
|
||||||
|
|
||||||
|
// wait WEL=1
|
||||||
|
int ret = mp_spiflash_wait_wel1(self);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// erase the sector
|
||||||
|
mp_hal_pin_write(self->cs, 0);
|
||||||
|
uint8_t cmd[4] = {CMD_SEC_ERASE, addr >> 16, addr >> 8, addr};
|
||||||
|
mp_spiflash_transfer(self, 4, cmd, NULL);
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
|
||||||
|
// wait WIP=0
|
||||||
|
return mp_spiflash_wait_wip0(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, const uint8_t *src) {
|
||||||
|
// enable writes
|
||||||
|
mp_spiflash_write_cmd(self, CMD_WREN);
|
||||||
|
|
||||||
|
// wait WEL=1
|
||||||
|
int ret = mp_spiflash_wait_wel1(self);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the page
|
||||||
|
mp_hal_pin_write(self->cs, 0);
|
||||||
|
uint8_t cmd[4] = {CMD_WRITE, addr >> 16, addr >> 8, addr};
|
||||||
|
mp_spiflash_transfer(self, 4, cmd, NULL);
|
||||||
|
mp_spiflash_transfer(self, PAGE_SIZE, src, NULL);
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
|
||||||
|
// wait WIP=0
|
||||||
|
return mp_spiflash_wait_wip0(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
|
||||||
|
mp_spiflash_acquire_bus(self);
|
||||||
|
uint8_t cmd[4] = {CMD_READ, addr >> 16, addr >> 8, addr};
|
||||||
|
mp_hal_pin_write(self->cs, 0);
|
||||||
|
mp_spiflash_transfer(self, 4, cmd, NULL);
|
||||||
|
mp_spiflash_transfer(self, len, dest, dest);
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
mp_spiflash_release_bus(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
|
||||||
|
// TODO optimise so we don't need to erase multiple times for successive writes to a sector
|
||||||
|
|
||||||
|
// align to 4096 sector
|
||||||
|
uint32_t offset = addr & 0xfff;
|
||||||
|
addr = (addr >> 12) << 12;
|
||||||
|
|
||||||
|
// restriction for now, so we don't need to erase multiple pages
|
||||||
|
if (offset + len > sizeof(buf)) {
|
||||||
|
printf("mp_spiflash_write: len is too large\n");
|
||||||
|
return -MP_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_spiflash_acquire_bus(self);
|
||||||
|
|
||||||
|
// read sector
|
||||||
|
uint8_t cmd[4] = {CMD_READ, addr >> 16, addr >> 8, addr};
|
||||||
|
mp_hal_pin_write(self->cs, 0);
|
||||||
|
mp_spiflash_transfer(self, 4, cmd, NULL);
|
||||||
|
mp_spiflash_transfer(self, SECTOR_SIZE, buf, buf);
|
||||||
|
mp_hal_pin_write(self->cs, 1);
|
||||||
|
|
||||||
|
// erase sector
|
||||||
|
int ret = mp_spiflash_erase_sector(self, addr);
|
||||||
|
if (ret != 0) {
|
||||||
|
mp_spiflash_release_bus(self);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy new block into buffer
|
||||||
|
memcpy(buf + offset, src, len);
|
||||||
|
|
||||||
|
// write sector in pages of 256 bytes
|
||||||
|
for (int i = 0; i < SECTOR_SIZE; i += 256) {
|
||||||
|
ret = mp_spiflash_write_page(self, addr + i, buf + i);
|
||||||
|
if (ret != 0) {
|
||||||
|
mp_spiflash_release_bus(self);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_spiflash_release_bus(self);
|
||||||
|
return 0; // success
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
* Copyright (c) 2016 Damien P. George
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -24,9 +24,19 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern const byte fresult_to_errno_table[20];
|
#ifndef MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H
|
||||||
|
#define MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H
|
||||||
|
|
||||||
mp_obj_t fatfs_builtin_open(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
|
#include "extmod/machine_spi.h"
|
||||||
MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj);
|
|
||||||
|
|
||||||
mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type);
|
typedef struct _mp_spiflash_t {
|
||||||
|
mp_hal_pin_obj_t cs;
|
||||||
|
// TODO replace with generic SPI object
|
||||||
|
mp_machine_soft_spi_obj_t spi;
|
||||||
|
} mp_spiflash_t;
|
||||||
|
|
||||||
|
void mp_spiflash_init(mp_spiflash_t *self);
|
||||||
|
void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest);
|
||||||
|
int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H
|
@ -133,8 +133,8 @@ LIB_SRC_C = $(addprefix lib/,\
|
|||||||
|
|
||||||
ifeq ($(MICROPY_FATFS), 1)
|
ifeq ($(MICROPY_FATFS), 1)
|
||||||
LIB_SRC_C += \
|
LIB_SRC_C += \
|
||||||
lib/fatfs/ff.c \
|
lib/oofatfs/ff.c \
|
||||||
lib/fatfs/option/ccsbcs.c
|
lib/oofatfs/option/unicode.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DRIVERS_SRC_C = $(addprefix drivers/,\
|
DRIVERS_SRC_C = $(addprefix drivers/,\
|
||||||
|
@ -8,298 +8,5 @@ MEMORY
|
|||||||
irom0_0_seg : org = 0x40209000, len = 0x87000
|
irom0_0_seg : org = 0x40209000, len = 0x87000
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define the top of RAM */
|
/* define common sections and symbols */
|
||||||
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);
|
INCLUDE esp8266_common.ld
|
||||||
|
|
||||||
PHDRS
|
|
||||||
{
|
|
||||||
dport0_0_phdr PT_LOAD;
|
|
||||||
dram0_0_phdr PT_LOAD;
|
|
||||||
dram0_0_bss_phdr PT_LOAD;
|
|
||||||
iram1_0_phdr PT_LOAD;
|
|
||||||
irom0_0_phdr PT_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY(firmware_start)
|
|
||||||
EXTERN(_DebugExceptionVector)
|
|
||||||
EXTERN(_DoubleExceptionVector)
|
|
||||||
EXTERN(_KernelExceptionVector)
|
|
||||||
EXTERN(_NMIExceptionVector)
|
|
||||||
EXTERN(_UserExceptionVector)
|
|
||||||
|
|
||||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
|
||||||
|
|
||||||
/* Various memory-map dependent cache attribute settings: */
|
|
||||||
_memmap_cacheattr_wb_base = 0x00000110;
|
|
||||||
_memmap_cacheattr_wt_base = 0x00000110;
|
|
||||||
_memmap_cacheattr_bp_base = 0x00000220;
|
|
||||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
|
||||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
|
||||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
|
||||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
|
||||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
|
||||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
|
||||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
|
||||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
|
||||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
|
|
||||||
.dport0.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_rodata_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.rodata)
|
|
||||||
*(.dport.rodata)
|
|
||||||
_dport0_rodata_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.dport0.literal : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_literal_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.literal)
|
|
||||||
*(.dport.literal)
|
|
||||||
_dport0_literal_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.dport0.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_data_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.data)
|
|
||||||
*(.dport.data)
|
|
||||||
_dport0_data_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.irom0.text : ALIGN(4)
|
|
||||||
{
|
|
||||||
_irom0_text_start = ABSOLUTE(.);
|
|
||||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
|
||||||
|
|
||||||
/* we put some specific text in this section */
|
|
||||||
|
|
||||||
*py/argcheck.o*(.literal* .text*)
|
|
||||||
*py/asm*.o*(.literal* .text*)
|
|
||||||
*py/bc.o*(.literal* .text*)
|
|
||||||
*py/binary.o*(.literal* .text*)
|
|
||||||
*py/builtin*.o*(.literal* .text*)
|
|
||||||
*py/compile.o*(.literal* .text*)
|
|
||||||
*py/emit*.o*(.literal* .text*)
|
|
||||||
*py/persistentcode*.o*(.literal* .text*)
|
|
||||||
*py/formatfloat.o*(.literal* .text*)
|
|
||||||
*py/frozenmod.o*(.literal* .text*)
|
|
||||||
*py/gc.o*(.literal* .text*)
|
|
||||||
*py/reader*.o*(.literal* .text*)
|
|
||||||
*py/lexer*.o*(.literal* .text*)
|
|
||||||
*py/malloc*.o*(.literal* .text*)
|
|
||||||
*py/map*.o*(.literal* .text*)
|
|
||||||
*py/mod*.o*(.literal* .text*)
|
|
||||||
*py/mpprint.o*(.literal* .text*)
|
|
||||||
*py/mpstate.o*(.literal* .text*)
|
|
||||||
*py/mpz.o*(.literal* .text*)
|
|
||||||
*py/native*.o*(.literal* .text*)
|
|
||||||
*py/nlr*.o*(.literal* .text*)
|
|
||||||
*py/obj*.o*(.literal* .text*)
|
|
||||||
*py/opmethods.o*(.literal* .text*)
|
|
||||||
*py/parse*.o*(.literal* .text*)
|
|
||||||
*py/qstr.o*(.literal* .text*)
|
|
||||||
*py/repl.o*(.literal* .text*)
|
|
||||||
*py/runtime.o*(.literal* .text*)
|
|
||||||
*py/scope.o*(.literal* .text*)
|
|
||||||
*py/sequence.o*(.literal* .text*)
|
|
||||||
*py/showbc.o*(.literal* .text*)
|
|
||||||
*py/smallint.o*(.literal* .text*)
|
|
||||||
*py/stackctrl.o*(.literal* .text*)
|
|
||||||
*py/stream.o*(.literal* .text*)
|
|
||||||
*py/unicode.o*(.literal* .text*)
|
|
||||||
*py/vm.o*(.literal* .text*)
|
|
||||||
*py/vstr.o*(.literal* .text*)
|
|
||||||
*py/warning.o*(.literal* .text*)
|
|
||||||
|
|
||||||
*extmod/*.o*(.literal* .text*)
|
|
||||||
|
|
||||||
*lib/fatfs/*.o*(.literal*, .text*)
|
|
||||||
*/libaxtls.a:(.literal*, .text*)
|
|
||||||
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
|
||||||
*lib/libm/*.o*(.literal*, .text*)
|
|
||||||
*lib/mp-readline/*.o(.literal*, .text*)
|
|
||||||
*lib/netutils/*.o*(.literal*, .text*)
|
|
||||||
*lib/timeutils/*.o*(.literal*, .text*)
|
|
||||||
*lib/utils/*.o*(.literal*, .text*)
|
|
||||||
|
|
||||||
*stmhal/pybstdio.o(.literal*, .text*)
|
|
||||||
|
|
||||||
build/main.o(.literal* .text*)
|
|
||||||
*gccollect.o(.literal* .text*)
|
|
||||||
*gchelper.o(.literal* .text*)
|
|
||||||
*help.o(.literal* .text*)
|
|
||||||
*lexerstr32.o(.literal* .text*)
|
|
||||||
*utils.o(.literal* .text*)
|
|
||||||
*modpyb.o(.literal*, .text*)
|
|
||||||
*machine_pin.o(.literal*, .text*)
|
|
||||||
*machine_pwm.o(.literal*, .text*)
|
|
||||||
*machine_rtc.o(.literal*, .text*)
|
|
||||||
*machine_adc.o(.literal*, .text*)
|
|
||||||
*machine_uart.o(.literal*, .text*)
|
|
||||||
*modpybi2c.o(.literal*, .text*)
|
|
||||||
*modmachine.o(.literal*, .text*)
|
|
||||||
*machine_wdt.o(.literal*, .text*)
|
|
||||||
*machine_spi.o(.literal*, .text*)
|
|
||||||
*machine_hspi.o(.literal*, .text*)
|
|
||||||
*hspi.o(.literal*, .text*)
|
|
||||||
*modesp.o(.literal* .text*)
|
|
||||||
*modnetwork.o(.literal* .text*)
|
|
||||||
*moduos.o(.literal* .text*)
|
|
||||||
*modutime.o(.literal* .text*)
|
|
||||||
*modlwip.o(.literal* .text*)
|
|
||||||
*modsocket.o(.literal* .text*)
|
|
||||||
*modonewire.o(.literal* .text*)
|
|
||||||
|
|
||||||
/* we put as much rodata as possible in this section */
|
|
||||||
/* note that only rodata accessed as a machine word is allowed here */
|
|
||||||
*py/qstr.o(.rodata.const_pool)
|
|
||||||
*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
|
||||||
*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
|
||||||
*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
|
||||||
*/frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
|
|
||||||
*/frozen.o(.rodata.mp_frozen_content) /* frozen modules */
|
|
||||||
|
|
||||||
/* for -mforce-l32 */
|
|
||||||
build/*.o(.rodata*)
|
|
||||||
|
|
||||||
_irom0_text_end = ABSOLUTE(.);
|
|
||||||
} >irom0_0_seg :irom0_0_phdr
|
|
||||||
|
|
||||||
.text : ALIGN(4)
|
|
||||||
{
|
|
||||||
_stext = .;
|
|
||||||
_text_start = ABSOLUTE(.);
|
|
||||||
*(.UserEnter.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.DebugExceptionVector.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.NMIExceptionVector.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.KernelExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.UserExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.DoubleExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN (16);
|
|
||||||
*(.entry.text)
|
|
||||||
*(.init.literal)
|
|
||||||
*(.init)
|
|
||||||
*(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*)
|
|
||||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
|
||||||
*(.fini.literal)
|
|
||||||
*(.fini)
|
|
||||||
*(.gnu.version)
|
|
||||||
_text_end = ABSOLUTE(.);
|
|
||||||
_etext = .;
|
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
|
||||||
|
|
||||||
.lit4 : ALIGN(4)
|
|
||||||
{
|
|
||||||
_lit4_start = ABSOLUTE(.);
|
|
||||||
*(*.lit4)
|
|
||||||
*(.lit4.*)
|
|
||||||
*(.gnu.linkonce.lit4.*)
|
|
||||||
_lit4_end = ABSOLUTE(.);
|
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
|
||||||
|
|
||||||
.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
_data_start = ABSOLUTE(.);
|
|
||||||
*(.data)
|
|
||||||
*(.data.*)
|
|
||||||
*(.gnu.linkonce.d.*)
|
|
||||||
*(.data1)
|
|
||||||
*(.sdata)
|
|
||||||
*(.sdata.*)
|
|
||||||
*(.gnu.linkonce.s.*)
|
|
||||||
*(.sdata2)
|
|
||||||
*(.sdata2.*)
|
|
||||||
*(.gnu.linkonce.s2.*)
|
|
||||||
*(.jcr)
|
|
||||||
_data_end = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_phdr
|
|
||||||
|
|
||||||
.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
_rodata_start = ABSOLUTE(.);
|
|
||||||
*(.sdk.version)
|
|
||||||
*(.rodata)
|
|
||||||
*(.rodata.*)
|
|
||||||
*(.gnu.linkonce.r.*)
|
|
||||||
*(.rodata1)
|
|
||||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_table)
|
|
||||||
*(.gcc_except_table)
|
|
||||||
*(.gnu.linkonce.e.*)
|
|
||||||
*(.gnu.version_r)
|
|
||||||
*(.eh_frame)
|
|
||||||
/* C++ constructor and destructor tables, properly ordered: */
|
|
||||||
KEEP (*crtbegin.o(.ctors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
/* C++ exception handlers table: */
|
|
||||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_desc)
|
|
||||||
*(.gnu.linkonce.h.*)
|
|
||||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_desc_end)
|
|
||||||
*(.dynamic)
|
|
||||||
*(.gnu.version_d)
|
|
||||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
|
||||||
_bss_table_start = ABSOLUTE(.);
|
|
||||||
LONG(_bss_start)
|
|
||||||
LONG(_bss_end)
|
|
||||||
_bss_table_end = ABSOLUTE(.);
|
|
||||||
_rodata_end = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_phdr
|
|
||||||
|
|
||||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
|
||||||
{
|
|
||||||
. = ALIGN (8);
|
|
||||||
_bss_start = ABSOLUTE(.);
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss)
|
|
||||||
*(.sbss.*)
|
|
||||||
*(.gnu.linkonce.sb.*)
|
|
||||||
*(.scommon)
|
|
||||||
*(.sbss2)
|
|
||||||
*(.sbss2.*)
|
|
||||||
*(.gnu.linkonce.sb2.*)
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.bss.*)
|
|
||||||
*(.gnu.linkonce.b.*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN (8);
|
|
||||||
_bss_end = ABSOLUTE(.);
|
|
||||||
_heap_start = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_bss_phdr
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get ROM code address */
|
|
||||||
INCLUDE "eagle.rom.addr.v6.ld"
|
|
||||||
|
@ -8,298 +8,5 @@ MEMORY
|
|||||||
irom0_0_seg : org = 0x40209000, len = 0x72000
|
irom0_0_seg : org = 0x40209000, len = 0x72000
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define the top of RAM */
|
/* define common sections and symbols */
|
||||||
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);
|
INCLUDE esp8266_common.ld
|
||||||
|
|
||||||
PHDRS
|
|
||||||
{
|
|
||||||
dport0_0_phdr PT_LOAD;
|
|
||||||
dram0_0_phdr PT_LOAD;
|
|
||||||
dram0_0_bss_phdr PT_LOAD;
|
|
||||||
iram1_0_phdr PT_LOAD;
|
|
||||||
irom0_0_phdr PT_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY(firmware_start)
|
|
||||||
EXTERN(_DebugExceptionVector)
|
|
||||||
EXTERN(_DoubleExceptionVector)
|
|
||||||
EXTERN(_KernelExceptionVector)
|
|
||||||
EXTERN(_NMIExceptionVector)
|
|
||||||
EXTERN(_UserExceptionVector)
|
|
||||||
|
|
||||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
|
||||||
|
|
||||||
/* Various memory-map dependent cache attribute settings: */
|
|
||||||
_memmap_cacheattr_wb_base = 0x00000110;
|
|
||||||
_memmap_cacheattr_wt_base = 0x00000110;
|
|
||||||
_memmap_cacheattr_bp_base = 0x00000220;
|
|
||||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
|
||||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
|
||||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
|
||||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
|
||||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
|
||||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
|
||||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
|
||||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
|
||||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
|
|
||||||
.dport0.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_rodata_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.rodata)
|
|
||||||
*(.dport.rodata)
|
|
||||||
_dport0_rodata_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.dport0.literal : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_literal_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.literal)
|
|
||||||
*(.dport.literal)
|
|
||||||
_dport0_literal_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.dport0.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_data_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.data)
|
|
||||||
*(.dport.data)
|
|
||||||
_dport0_data_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.irom0.text : ALIGN(4)
|
|
||||||
{
|
|
||||||
_irom0_text_start = ABSOLUTE(.);
|
|
||||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
|
||||||
|
|
||||||
/* we put some specific text in this section */
|
|
||||||
|
|
||||||
*py/argcheck.o*(.literal* .text*)
|
|
||||||
*py/asm*.o*(.literal* .text*)
|
|
||||||
*py/bc.o*(.literal* .text*)
|
|
||||||
*py/binary.o*(.literal* .text*)
|
|
||||||
*py/builtin*.o*(.literal* .text*)
|
|
||||||
*py/compile.o*(.literal* .text*)
|
|
||||||
*py/emit*.o*(.literal* .text*)
|
|
||||||
*py/persistentcode*.o*(.literal* .text*)
|
|
||||||
*py/formatfloat.o*(.literal* .text*)
|
|
||||||
*py/frozenmod.o*(.literal* .text*)
|
|
||||||
*py/gc.o*(.literal* .text*)
|
|
||||||
*py/reader*.o*(.literal* .text*)
|
|
||||||
*py/lexer*.o*(.literal* .text*)
|
|
||||||
*py/malloc*.o*(.literal* .text*)
|
|
||||||
*py/map*.o*(.literal* .text*)
|
|
||||||
*py/mod*.o*(.literal* .text*)
|
|
||||||
*py/mpprint.o*(.literal* .text*)
|
|
||||||
*py/mpstate.o*(.literal* .text*)
|
|
||||||
*py/mpz.o*(.literal* .text*)
|
|
||||||
*py/native*.o*(.literal* .text*)
|
|
||||||
*py/nlr*.o*(.literal* .text*)
|
|
||||||
*py/obj*.o*(.literal* .text*)
|
|
||||||
*py/opmethods.o*(.literal* .text*)
|
|
||||||
*py/parse*.o*(.literal* .text*)
|
|
||||||
*py/qstr.o*(.literal* .text*)
|
|
||||||
*py/repl.o*(.literal* .text*)
|
|
||||||
*py/runtime.o*(.literal* .text*)
|
|
||||||
*py/scope.o*(.literal* .text*)
|
|
||||||
*py/sequence.o*(.literal* .text*)
|
|
||||||
*py/showbc.o*(.literal* .text*)
|
|
||||||
*py/smallint.o*(.literal* .text*)
|
|
||||||
*py/stackctrl.o*(.literal* .text*)
|
|
||||||
*py/stream.o*(.literal* .text*)
|
|
||||||
*py/unicode.o*(.literal* .text*)
|
|
||||||
*py/vm.o*(.literal* .text*)
|
|
||||||
*py/vstr.o*(.literal* .text*)
|
|
||||||
*py/warning.o*(.literal* .text*)
|
|
||||||
|
|
||||||
*extmod/*.o*(.literal* .text*)
|
|
||||||
|
|
||||||
*lib/fatfs/*.o*(.literal*, .text*)
|
|
||||||
*/libaxtls.a:(.literal*, .text*)
|
|
||||||
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
|
||||||
*lib/libm/*.o*(.literal*, .text*)
|
|
||||||
*lib/mp-readline/*.o(.literal*, .text*)
|
|
||||||
*lib/netutils/*.o*(.literal*, .text*)
|
|
||||||
*lib/timeutils/*.o*(.literal*, .text*)
|
|
||||||
*lib/utils/*.o*(.literal*, .text*)
|
|
||||||
|
|
||||||
*stmhal/pybstdio.o(.literal*, .text*)
|
|
||||||
|
|
||||||
build/main.o(.literal* .text*)
|
|
||||||
*gccollect.o(.literal* .text*)
|
|
||||||
*gchelper.o(.literal* .text*)
|
|
||||||
*help.o(.literal* .text*)
|
|
||||||
*lexerstr32.o(.literal* .text*)
|
|
||||||
*utils.o(.literal* .text*)
|
|
||||||
*modpyb.o(.literal*, .text*)
|
|
||||||
*machine_pin.o(.literal*, .text*)
|
|
||||||
*machine_pwm.o(.literal*, .text*)
|
|
||||||
*machine_rtc.o(.literal*, .text*)
|
|
||||||
*machine_adc.o(.literal*, .text*)
|
|
||||||
*machine_uart.o(.literal*, .text*)
|
|
||||||
*modpybi2c.o(.literal*, .text*)
|
|
||||||
*modmachine.o(.literal*, .text*)
|
|
||||||
*machine_wdt.o(.literal*, .text*)
|
|
||||||
*machine_spi.o(.literal*, .text*)
|
|
||||||
*machine_hspi.o(.literal*, .text*)
|
|
||||||
*hspi.o(.literal*, .text*)
|
|
||||||
*modesp.o(.literal* .text*)
|
|
||||||
*modnetwork.o(.literal* .text*)
|
|
||||||
*moduos.o(.literal* .text*)
|
|
||||||
*modutime.o(.literal* .text*)
|
|
||||||
*modlwip.o(.literal* .text*)
|
|
||||||
*modsocket.o(.literal* .text*)
|
|
||||||
*modonewire.o(.literal* .text*)
|
|
||||||
|
|
||||||
/* we put as much rodata as possible in this section */
|
|
||||||
/* note that only rodata accessed as a machine word is allowed here */
|
|
||||||
*py/qstr.o(.rodata.const_pool)
|
|
||||||
*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
|
||||||
*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
|
||||||
*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
|
||||||
*/frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
|
|
||||||
*/frozen.o(.rodata.mp_frozen_content) /* frozen modules */
|
|
||||||
|
|
||||||
/* for -mforce-l32 */
|
|
||||||
build/*.o(.rodata*)
|
|
||||||
|
|
||||||
_irom0_text_end = ABSOLUTE(.);
|
|
||||||
} >irom0_0_seg :irom0_0_phdr
|
|
||||||
|
|
||||||
.text : ALIGN(4)
|
|
||||||
{
|
|
||||||
_stext = .;
|
|
||||||
_text_start = ABSOLUTE(.);
|
|
||||||
*(.UserEnter.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.DebugExceptionVector.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.NMIExceptionVector.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.KernelExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.UserExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.DoubleExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN (16);
|
|
||||||
*(.entry.text)
|
|
||||||
*(.init.literal)
|
|
||||||
*(.init)
|
|
||||||
*(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*)
|
|
||||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
|
||||||
*(.fini.literal)
|
|
||||||
*(.fini)
|
|
||||||
*(.gnu.version)
|
|
||||||
_text_end = ABSOLUTE(.);
|
|
||||||
_etext = .;
|
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
|
||||||
|
|
||||||
.lit4 : ALIGN(4)
|
|
||||||
{
|
|
||||||
_lit4_start = ABSOLUTE(.);
|
|
||||||
*(*.lit4)
|
|
||||||
*(.lit4.*)
|
|
||||||
*(.gnu.linkonce.lit4.*)
|
|
||||||
_lit4_end = ABSOLUTE(.);
|
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
|
||||||
|
|
||||||
.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
_data_start = ABSOLUTE(.);
|
|
||||||
*(.data)
|
|
||||||
*(.data.*)
|
|
||||||
*(.gnu.linkonce.d.*)
|
|
||||||
*(.data1)
|
|
||||||
*(.sdata)
|
|
||||||
*(.sdata.*)
|
|
||||||
*(.gnu.linkonce.s.*)
|
|
||||||
*(.sdata2)
|
|
||||||
*(.sdata2.*)
|
|
||||||
*(.gnu.linkonce.s2.*)
|
|
||||||
*(.jcr)
|
|
||||||
_data_end = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_phdr
|
|
||||||
|
|
||||||
.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
_rodata_start = ABSOLUTE(.);
|
|
||||||
*(.sdk.version)
|
|
||||||
*(.rodata)
|
|
||||||
*(.rodata.*)
|
|
||||||
*(.gnu.linkonce.r.*)
|
|
||||||
*(.rodata1)
|
|
||||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_table)
|
|
||||||
*(.gcc_except_table)
|
|
||||||
*(.gnu.linkonce.e.*)
|
|
||||||
*(.gnu.version_r)
|
|
||||||
*(.eh_frame)
|
|
||||||
/* C++ constructor and destructor tables, properly ordered: */
|
|
||||||
KEEP (*crtbegin.o(.ctors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
/* C++ exception handlers table: */
|
|
||||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_desc)
|
|
||||||
*(.gnu.linkonce.h.*)
|
|
||||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_desc_end)
|
|
||||||
*(.dynamic)
|
|
||||||
*(.gnu.version_d)
|
|
||||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
|
||||||
_bss_table_start = ABSOLUTE(.);
|
|
||||||
LONG(_bss_start)
|
|
||||||
LONG(_bss_end)
|
|
||||||
_bss_table_end = ABSOLUTE(.);
|
|
||||||
_rodata_end = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_phdr
|
|
||||||
|
|
||||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
|
||||||
{
|
|
||||||
. = ALIGN (8);
|
|
||||||
_bss_start = ABSOLUTE(.);
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss)
|
|
||||||
*(.sbss.*)
|
|
||||||
*(.gnu.linkonce.sb.*)
|
|
||||||
*(.scommon)
|
|
||||||
*(.sbss2)
|
|
||||||
*(.sbss2.*)
|
|
||||||
*(.gnu.linkonce.sb2.*)
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.bss.*)
|
|
||||||
*(.gnu.linkonce.b.*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN (8);
|
|
||||||
_bss_end = ABSOLUTE(.);
|
|
||||||
_heap_start = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_bss_phdr
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get ROM code address */
|
|
||||||
INCLUDE "eagle.rom.addr.v6.ld"
|
|
||||||
|
297
esp8266/esp8266_common.ld
Normal file
297
esp8266/esp8266_common.ld
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/* GNU linker script for ESP8266, common sections and symbols */
|
||||||
|
|
||||||
|
/* define the top of RAM */
|
||||||
|
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);
|
||||||
|
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
dport0_0_phdr PT_LOAD;
|
||||||
|
dram0_0_phdr PT_LOAD;
|
||||||
|
dram0_0_bss_phdr PT_LOAD;
|
||||||
|
iram1_0_phdr PT_LOAD;
|
||||||
|
irom0_0_phdr PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY(firmware_start)
|
||||||
|
EXTERN(_DebugExceptionVector)
|
||||||
|
EXTERN(_DoubleExceptionVector)
|
||||||
|
EXTERN(_KernelExceptionVector)
|
||||||
|
EXTERN(_NMIExceptionVector)
|
||||||
|
EXTERN(_UserExceptionVector)
|
||||||
|
|
||||||
|
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||||
|
|
||||||
|
/* Various memory-map dependent cache attribute settings: */
|
||||||
|
_memmap_cacheattr_wb_base = 0x00000110;
|
||||||
|
_memmap_cacheattr_wt_base = 0x00000110;
|
||||||
|
_memmap_cacheattr_bp_base = 0x00000220;
|
||||||
|
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||||
|
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||||
|
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||||
|
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||||
|
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||||
|
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||||
|
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||||
|
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||||
|
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
.dport0.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_rodata_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.rodata)
|
||||||
|
*(.dport.rodata)
|
||||||
|
_dport0_rodata_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.dport0.literal : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_literal_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.literal)
|
||||||
|
*(.dport.literal)
|
||||||
|
_dport0_literal_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.dport0.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_data_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.data)
|
||||||
|
*(.dport.data)
|
||||||
|
_dport0_data_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.irom0.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
_irom0_text_start = ABSOLUTE(.);
|
||||||
|
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||||
|
|
||||||
|
/* we put some specific text in this section */
|
||||||
|
|
||||||
|
*py/argcheck.o*(.literal* .text*)
|
||||||
|
*py/asm*.o*(.literal* .text*)
|
||||||
|
*py/bc.o*(.literal* .text*)
|
||||||
|
*py/binary.o*(.literal* .text*)
|
||||||
|
*py/builtin*.o*(.literal* .text*)
|
||||||
|
*py/compile.o*(.literal* .text*)
|
||||||
|
*py/emit*.o*(.literal* .text*)
|
||||||
|
*py/persistentcode*.o*(.literal* .text*)
|
||||||
|
*py/formatfloat.o*(.literal* .text*)
|
||||||
|
*py/frozenmod.o*(.literal* .text*)
|
||||||
|
*py/gc.o*(.literal* .text*)
|
||||||
|
*py/reader*.o*(.literal* .text*)
|
||||||
|
*py/lexer*.o*(.literal* .text*)
|
||||||
|
*py/malloc*.o*(.literal* .text*)
|
||||||
|
*py/map*.o*(.literal* .text*)
|
||||||
|
*py/mod*.o*(.literal* .text*)
|
||||||
|
*py/mpprint.o*(.literal* .text*)
|
||||||
|
*py/mpstate.o*(.literal* .text*)
|
||||||
|
*py/mpz.o*(.literal* .text*)
|
||||||
|
*py/native*.o*(.literal* .text*)
|
||||||
|
*py/nlr*.o*(.literal* .text*)
|
||||||
|
*py/obj*.o*(.literal* .text*)
|
||||||
|
*py/opmethods.o*(.literal* .text*)
|
||||||
|
*py/parse*.o*(.literal* .text*)
|
||||||
|
*py/qstr.o*(.literal* .text*)
|
||||||
|
*py/repl.o*(.literal* .text*)
|
||||||
|
*py/runtime.o*(.literal* .text*)
|
||||||
|
*py/scope.o*(.literal* .text*)
|
||||||
|
*py/sequence.o*(.literal* .text*)
|
||||||
|
*py/showbc.o*(.literal* .text*)
|
||||||
|
*py/smallint.o*(.literal* .text*)
|
||||||
|
*py/stackctrl.o*(.literal* .text*)
|
||||||
|
*py/stream.o*(.literal* .text*)
|
||||||
|
*py/unicode.o*(.literal* .text*)
|
||||||
|
*py/vm.o*(.literal* .text*)
|
||||||
|
*py/vstr.o*(.literal* .text*)
|
||||||
|
*py/warning.o*(.literal* .text*)
|
||||||
|
|
||||||
|
*extmod/*.o*(.literal* .text*)
|
||||||
|
|
||||||
|
*lib/oofatfs/*.o*(.literal*, .text*)
|
||||||
|
*/libaxtls.a:(.literal*, .text*)
|
||||||
|
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
||||||
|
*lib/libm/*.o*(.literal*, .text*)
|
||||||
|
*lib/mp-readline/*.o(.literal*, .text*)
|
||||||
|
*lib/netutils/*.o*(.literal*, .text*)
|
||||||
|
*lib/timeutils/*.o*(.literal*, .text*)
|
||||||
|
*lib/utils/*.o*(.literal*, .text*)
|
||||||
|
|
||||||
|
*stmhal/pybstdio.o(.literal*, .text*)
|
||||||
|
|
||||||
|
build/main.o(.literal* .text*)
|
||||||
|
*gccollect.o(.literal* .text*)
|
||||||
|
*gchelper.o(.literal* .text*)
|
||||||
|
*help.o(.literal* .text*)
|
||||||
|
*lexerstr32.o(.literal* .text*)
|
||||||
|
*utils.o(.literal* .text*)
|
||||||
|
*modpyb.o(.literal*, .text*)
|
||||||
|
*machine_pin.o(.literal*, .text*)
|
||||||
|
*machine_pwm.o(.literal*, .text*)
|
||||||
|
*machine_rtc.o(.literal*, .text*)
|
||||||
|
*machine_adc.o(.literal*, .text*)
|
||||||
|
*machine_uart.o(.literal*, .text*)
|
||||||
|
*modpybi2c.o(.literal*, .text*)
|
||||||
|
*modmachine.o(.literal*, .text*)
|
||||||
|
*machine_wdt.o(.literal*, .text*)
|
||||||
|
*machine_spi.o(.literal*, .text*)
|
||||||
|
*machine_hspi.o(.literal*, .text*)
|
||||||
|
*hspi.o(.literal*, .text*)
|
||||||
|
*modesp.o(.literal* .text*)
|
||||||
|
*modnetwork.o(.literal* .text*)
|
||||||
|
*moduos.o(.literal* .text*)
|
||||||
|
*modutime.o(.literal* .text*)
|
||||||
|
*modlwip.o(.literal* .text*)
|
||||||
|
*modsocket.o(.literal* .text*)
|
||||||
|
*modonewire.o(.literal* .text*)
|
||||||
|
|
||||||
|
/* we put as much rodata as possible in this section */
|
||||||
|
/* note that only rodata accessed as a machine word is allowed here */
|
||||||
|
*py/qstr.o(.rodata.const_pool)
|
||||||
|
*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
||||||
|
*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
||||||
|
*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
||||||
|
*/frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
|
||||||
|
*/frozen.o(.rodata.mp_frozen_content) /* frozen modules */
|
||||||
|
|
||||||
|
/* for -mforce-l32 */
|
||||||
|
build/*.o(.rodata*)
|
||||||
|
|
||||||
|
_irom0_text_end = ABSOLUTE(.);
|
||||||
|
} >irom0_0_seg :irom0_0_phdr
|
||||||
|
|
||||||
|
.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
_stext = .;
|
||||||
|
_text_start = ABSOLUTE(.);
|
||||||
|
*(.UserEnter.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.DebugExceptionVector.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.NMIExceptionVector.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.KernelExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.UserExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.DoubleExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN (16);
|
||||||
|
*(.entry.text)
|
||||||
|
*(.init.literal)
|
||||||
|
*(.init)
|
||||||
|
*(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*)
|
||||||
|
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
*(.fini.literal)
|
||||||
|
*(.fini)
|
||||||
|
*(.gnu.version)
|
||||||
|
_text_end = ABSOLUTE(.);
|
||||||
|
_etext = .;
|
||||||
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
|
||||||
|
.lit4 : ALIGN(4)
|
||||||
|
{
|
||||||
|
_lit4_start = ABSOLUTE(.);
|
||||||
|
*(*.lit4)
|
||||||
|
*(.lit4.*)
|
||||||
|
*(.gnu.linkonce.lit4.*)
|
||||||
|
_lit4_end = ABSOLUTE(.);
|
||||||
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
|
||||||
|
.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
*(.data1)
|
||||||
|
*(.sdata)
|
||||||
|
*(.sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
*(.sdata2)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s2.*)
|
||||||
|
*(.jcr)
|
||||||
|
_data_end = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_phdr
|
||||||
|
|
||||||
|
.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
*(.sdk.version)
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.rodata1)
|
||||||
|
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_table)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.gnu.linkonce.e.*)
|
||||||
|
*(.gnu.version_r)
|
||||||
|
*(.eh_frame)
|
||||||
|
/* C++ constructor and destructor tables, properly ordered: */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
/* C++ exception handlers table: */
|
||||||
|
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc)
|
||||||
|
*(.gnu.linkonce.h.*)
|
||||||
|
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc_end)
|
||||||
|
*(.dynamic)
|
||||||
|
*(.gnu.version_d)
|
||||||
|
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||||
|
_bss_table_start = ABSOLUTE(.);
|
||||||
|
LONG(_bss_start)
|
||||||
|
LONG(_bss_end)
|
||||||
|
_bss_table_end = ABSOLUTE(.);
|
||||||
|
_rodata_end = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_phdr
|
||||||
|
|
||||||
|
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_start = ABSOLUTE(.);
|
||||||
|
*(.dynsbss)
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.scommon)
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_end = ABSOLUTE(.);
|
||||||
|
_heap_start = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_bss_phdr
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get ROM code address */
|
||||||
|
INCLUDE "eagle.rom.addr.v6.ld"
|
@ -9,298 +9,5 @@ MEMORY
|
|||||||
irom0_0_seg : org = 0x40200000 + 0x3c000 + 0x9000, len = 0x87000
|
irom0_0_seg : org = 0x40200000 + 0x3c000 + 0x9000, len = 0x87000
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define the top of RAM */
|
/* define common sections and symbols */
|
||||||
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);
|
INCLUDE esp8266_common.ld
|
||||||
|
|
||||||
PHDRS
|
|
||||||
{
|
|
||||||
dport0_0_phdr PT_LOAD;
|
|
||||||
dram0_0_phdr PT_LOAD;
|
|
||||||
dram0_0_bss_phdr PT_LOAD;
|
|
||||||
iram1_0_phdr PT_LOAD;
|
|
||||||
irom0_0_phdr PT_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTRY(firmware_start)
|
|
||||||
EXTERN(_DebugExceptionVector)
|
|
||||||
EXTERN(_DoubleExceptionVector)
|
|
||||||
EXTERN(_KernelExceptionVector)
|
|
||||||
EXTERN(_NMIExceptionVector)
|
|
||||||
EXTERN(_UserExceptionVector)
|
|
||||||
|
|
||||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
|
||||||
|
|
||||||
/* Various memory-map dependent cache attribute settings: */
|
|
||||||
_memmap_cacheattr_wb_base = 0x00000110;
|
|
||||||
_memmap_cacheattr_wt_base = 0x00000110;
|
|
||||||
_memmap_cacheattr_bp_base = 0x00000220;
|
|
||||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
|
||||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
|
||||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
|
||||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
|
||||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
|
||||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
|
||||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
|
||||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
|
||||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
|
||||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
|
|
||||||
.dport0.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_rodata_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.rodata)
|
|
||||||
*(.dport.rodata)
|
|
||||||
_dport0_rodata_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.dport0.literal : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_literal_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.literal)
|
|
||||||
*(.dport.literal)
|
|
||||||
_dport0_literal_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.dport0.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
_dport0_data_start = ABSOLUTE(.);
|
|
||||||
*(.dport0.data)
|
|
||||||
*(.dport.data)
|
|
||||||
_dport0_data_end = ABSOLUTE(.);
|
|
||||||
} >dport0_0_seg :dport0_0_phdr
|
|
||||||
|
|
||||||
.irom0.text : ALIGN(4)
|
|
||||||
{
|
|
||||||
_irom0_text_start = ABSOLUTE(.);
|
|
||||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
|
||||||
|
|
||||||
/* we put some specific text in this section */
|
|
||||||
|
|
||||||
*py/argcheck.o*(.literal* .text*)
|
|
||||||
*py/asm*.o*(.literal* .text*)
|
|
||||||
*py/bc.o*(.literal* .text*)
|
|
||||||
*py/binary.o*(.literal* .text*)
|
|
||||||
*py/builtin*.o*(.literal* .text*)
|
|
||||||
*py/compile.o*(.literal* .text*)
|
|
||||||
*py/emit*.o*(.literal* .text*)
|
|
||||||
*py/persistentcode*.o*(.literal* .text*)
|
|
||||||
*py/formatfloat.o*(.literal* .text*)
|
|
||||||
*py/frozenmod.o*(.literal* .text*)
|
|
||||||
*py/gc.o*(.literal* .text*)
|
|
||||||
*py/reader*.o*(.literal* .text*)
|
|
||||||
*py/lexer*.o*(.literal* .text*)
|
|
||||||
*py/malloc*.o*(.literal* .text*)
|
|
||||||
*py/map*.o*(.literal* .text*)
|
|
||||||
*py/mod*.o*(.literal* .text*)
|
|
||||||
*py/mpprint.o*(.literal* .text*)
|
|
||||||
*py/mpstate.o*(.literal* .text*)
|
|
||||||
*py/mpz.o*(.literal* .text*)
|
|
||||||
*py/native*.o*(.literal* .text*)
|
|
||||||
*py/nlr*.o*(.literal* .text*)
|
|
||||||
*py/obj*.o*(.literal* .text*)
|
|
||||||
*py/opmethods.o*(.literal* .text*)
|
|
||||||
*py/parse*.o*(.literal* .text*)
|
|
||||||
*py/qstr.o*(.literal* .text*)
|
|
||||||
*py/repl.o*(.literal* .text*)
|
|
||||||
*py/runtime.o*(.literal* .text*)
|
|
||||||
*py/scope.o*(.literal* .text*)
|
|
||||||
*py/sequence.o*(.literal* .text*)
|
|
||||||
*py/showbc.o*(.literal* .text*)
|
|
||||||
*py/smallint.o*(.literal* .text*)
|
|
||||||
*py/stackctrl.o*(.literal* .text*)
|
|
||||||
*py/stream.o*(.literal* .text*)
|
|
||||||
*py/unicode.o*(.literal* .text*)
|
|
||||||
*py/vm.o*(.literal* .text*)
|
|
||||||
*py/vstr.o*(.literal* .text*)
|
|
||||||
*py/warning.o*(.literal* .text*)
|
|
||||||
|
|
||||||
*extmod/*.o*(.literal* .text*)
|
|
||||||
|
|
||||||
*lib/fatfs/*.o*(.literal*, .text*)
|
|
||||||
*/libaxtls.a:(.literal*, .text*)
|
|
||||||
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
|
||||||
*lib/libm/*.o*(.literal*, .text*)
|
|
||||||
*lib/mp-readline/*.o(.literal*, .text*)
|
|
||||||
*lib/netutils/*.o*(.literal*, .text*)
|
|
||||||
*lib/timeutils/*.o*(.literal*, .text*)
|
|
||||||
*lib/utils/*.o*(.literal*, .text*)
|
|
||||||
|
|
||||||
*stmhal/pybstdio.o(.literal*, .text*)
|
|
||||||
|
|
||||||
build/main.o(.literal* .text*)
|
|
||||||
*gccollect.o(.literal* .text*)
|
|
||||||
*gchelper.o(.literal* .text*)
|
|
||||||
*help.o(.literal* .text*)
|
|
||||||
*lexerstr32.o(.literal* .text*)
|
|
||||||
*utils.o(.literal* .text*)
|
|
||||||
*modpyb.o(.literal*, .text*)
|
|
||||||
*machine_pin.o(.literal*, .text*)
|
|
||||||
*machine_pwm.o(.literal*, .text*)
|
|
||||||
*machine_rtc.o(.literal*, .text*)
|
|
||||||
*machine_adc.o(.literal*, .text*)
|
|
||||||
*machine_uart.o(.literal*, .text*)
|
|
||||||
*modpybi2c.o(.literal*, .text*)
|
|
||||||
*modmachine.o(.literal*, .text*)
|
|
||||||
*machine_wdt.o(.literal*, .text*)
|
|
||||||
*machine_spi.o(.literal*, .text*)
|
|
||||||
*machine_hspi.o(.literal*, .text*)
|
|
||||||
*hspi.o(.literal*, .text*)
|
|
||||||
*modesp.o(.literal* .text*)
|
|
||||||
*modnetwork.o(.literal* .text*)
|
|
||||||
*moduos.o(.literal* .text*)
|
|
||||||
*modutime.o(.literal* .text*)
|
|
||||||
*modlwip.o(.literal* .text*)
|
|
||||||
*modsocket.o(.literal* .text*)
|
|
||||||
*modonewire.o(.literal* .text*)
|
|
||||||
|
|
||||||
/* we put as much rodata as possible in this section */
|
|
||||||
/* note that only rodata accessed as a machine word is allowed here */
|
|
||||||
*py/qstr.o(.rodata.const_pool)
|
|
||||||
*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
|
||||||
*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
|
||||||
*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
|
||||||
*/frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
|
|
||||||
*/frozen.o(.rodata.mp_frozen_content) /* frozen modules */
|
|
||||||
|
|
||||||
/* for -mforce-l32 */
|
|
||||||
build/*.o(.rodata*)
|
|
||||||
|
|
||||||
_irom0_text_end = ABSOLUTE(.);
|
|
||||||
} >irom0_0_seg :irom0_0_phdr
|
|
||||||
|
|
||||||
.text : ALIGN(4)
|
|
||||||
{
|
|
||||||
_stext = .;
|
|
||||||
_text_start = ABSOLUTE(.);
|
|
||||||
*(.UserEnter.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.DebugExceptionVector.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.NMIExceptionVector.text)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.KernelExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.UserExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN(16);
|
|
||||||
*(.DoubleExceptionVector.text)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
LONG(0)
|
|
||||||
. = ALIGN (16);
|
|
||||||
*(.entry.text)
|
|
||||||
*(.init.literal)
|
|
||||||
*(.init)
|
|
||||||
*(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*)
|
|
||||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
|
||||||
*(.fini.literal)
|
|
||||||
*(.fini)
|
|
||||||
*(.gnu.version)
|
|
||||||
_text_end = ABSOLUTE(.);
|
|
||||||
_etext = .;
|
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
|
||||||
|
|
||||||
.lit4 : ALIGN(4)
|
|
||||||
{
|
|
||||||
_lit4_start = ABSOLUTE(.);
|
|
||||||
*(*.lit4)
|
|
||||||
*(.lit4.*)
|
|
||||||
*(.gnu.linkonce.lit4.*)
|
|
||||||
_lit4_end = ABSOLUTE(.);
|
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
|
||||||
|
|
||||||
.data : ALIGN(4)
|
|
||||||
{
|
|
||||||
_data_start = ABSOLUTE(.);
|
|
||||||
*(.data)
|
|
||||||
*(.data.*)
|
|
||||||
*(.gnu.linkonce.d.*)
|
|
||||||
*(.data1)
|
|
||||||
*(.sdata)
|
|
||||||
*(.sdata.*)
|
|
||||||
*(.gnu.linkonce.s.*)
|
|
||||||
*(.sdata2)
|
|
||||||
*(.sdata2.*)
|
|
||||||
*(.gnu.linkonce.s2.*)
|
|
||||||
*(.jcr)
|
|
||||||
_data_end = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_phdr
|
|
||||||
|
|
||||||
.rodata : ALIGN(4)
|
|
||||||
{
|
|
||||||
_rodata_start = ABSOLUTE(.);
|
|
||||||
*(.sdk.version)
|
|
||||||
*(.rodata)
|
|
||||||
*(.rodata.*)
|
|
||||||
*(.gnu.linkonce.r.*)
|
|
||||||
*(.rodata1)
|
|
||||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_table)
|
|
||||||
*(.gcc_except_table)
|
|
||||||
*(.gnu.linkonce.e.*)
|
|
||||||
*(.gnu.version_r)
|
|
||||||
*(.eh_frame)
|
|
||||||
/* C++ constructor and destructor tables, properly ordered: */
|
|
||||||
KEEP (*crtbegin.o(.ctors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
/* C++ exception handlers table: */
|
|
||||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_desc)
|
|
||||||
*(.gnu.linkonce.h.*)
|
|
||||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
|
||||||
*(.xt_except_desc_end)
|
|
||||||
*(.dynamic)
|
|
||||||
*(.gnu.version_d)
|
|
||||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
|
||||||
_bss_table_start = ABSOLUTE(.);
|
|
||||||
LONG(_bss_start)
|
|
||||||
LONG(_bss_end)
|
|
||||||
_bss_table_end = ABSOLUTE(.);
|
|
||||||
_rodata_end = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_phdr
|
|
||||||
|
|
||||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
|
||||||
{
|
|
||||||
. = ALIGN (8);
|
|
||||||
_bss_start = ABSOLUTE(.);
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss)
|
|
||||||
*(.sbss.*)
|
|
||||||
*(.gnu.linkonce.sb.*)
|
|
||||||
*(.scommon)
|
|
||||||
*(.sbss2)
|
|
||||||
*(.sbss2.*)
|
|
||||||
*(.gnu.linkonce.sb2.*)
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.bss.*)
|
|
||||||
*(.gnu.linkonce.b.*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN (8);
|
|
||||||
_bss_end = ABSOLUTE(.);
|
|
||||||
_heap_start = ABSOLUTE(.);
|
|
||||||
} >dram0_0_seg :dram0_0_bss_phdr
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get ROM code address */
|
|
||||||
INCLUDE "eagle.rom.addr.v6.ld"
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "lib/fatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "timeutils.h"
|
#include "timeutils.h"
|
||||||
#include "modmachine.h"
|
#include "modmachine.h"
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/gc.h"
|
#include "py/gc.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "extmod/virtpin.h"
|
||||||
#include "modmachine.h"
|
#include "modmachine.h"
|
||||||
|
|
||||||
#define GET_TRIGGER(phys_port) \
|
#define GET_TRIGGER(phys_port) \
|
||||||
@ -374,6 +375,23 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_irq_obj, 1, pyb_pin_irq);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_irq_obj, 1, pyb_pin_irq);
|
||||||
|
|
||||||
|
STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode);
|
||||||
|
STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||||
|
(void)errcode;
|
||||||
|
pyb_pin_obj_t *self = self_in;
|
||||||
|
|
||||||
|
switch (request) {
|
||||||
|
case MP_PIN_READ: {
|
||||||
|
return pin_get(self->phys_port);
|
||||||
|
}
|
||||||
|
case MP_PIN_WRITE: {
|
||||||
|
pin_set(self->phys_port, arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = {
|
STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = {
|
||||||
// instance methods
|
// instance methods
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_pin_init_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_pin_init_obj },
|
||||||
@ -396,12 +414,17 @@ STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = {
|
|||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(pyb_pin_locals_dict, pyb_pin_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(pyb_pin_locals_dict, pyb_pin_locals_dict_table);
|
||||||
|
|
||||||
|
STATIC const mp_pin_p_t pin_pin_p = {
|
||||||
|
.ioctl = pin_ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
const mp_obj_type_t pyb_pin_type = {
|
const mp_obj_type_t pyb_pin_type = {
|
||||||
{ &mp_type_type },
|
{ &mp_type_type },
|
||||||
.name = MP_QSTR_Pin,
|
.name = MP_QSTR_Pin,
|
||||||
.print = pyb_pin_print,
|
.print = pyb_pin_print,
|
||||||
.make_new = pyb_pin_make_new,
|
.make_new = pyb_pin_make_new,
|
||||||
.call = pyb_pin_call,
|
.call = pyb_pin_call,
|
||||||
|
.protocol = &pin_pin_p,
|
||||||
.locals_dict = (mp_obj_t)&pyb_pin_locals_dict,
|
.locals_dict = (mp_obj_t)&pyb_pin_locals_dict,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -255,8 +255,22 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
||||||
*errcode = MP_EINVAL;
|
pyb_uart_obj_t *self = self_in;
|
||||||
return MP_STREAM_ERROR;
|
mp_uint_t ret;
|
||||||
|
if (request == MP_STREAM_POLL) {
|
||||||
|
mp_uint_t flags = arg;
|
||||||
|
ret = 0;
|
||||||
|
if ((flags & MP_STREAM_POLL_RD) && uart_rx_any(self->uart_id)) {
|
||||||
|
ret |= MP_STREAM_POLL_RD;
|
||||||
|
}
|
||||||
|
if ((flags & MP_STREAM_POLL_WR) && uart_tx_any_room(self->uart_id)) {
|
||||||
|
ret |= MP_STREAM_POLL_WR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*errcode = MP_EINVAL;
|
||||||
|
ret = MP_STREAM_ERROR;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC const mp_stream_p_t uart_stream_p = {
|
STATIC const mp_stream_p_t uart_stream_p = {
|
||||||
|
@ -49,8 +49,8 @@ STATIC void mp_reset(void) {
|
|||||||
mp_init();
|
mp_init();
|
||||||
mp_obj_list_init(mp_sys_path, 0);
|
mp_obj_list_init(mp_sys_path, 0);
|
||||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
|
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
|
||||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
|
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
|
||||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_));
|
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
|
||||||
mp_obj_list_init(mp_sys_argv, 0);
|
mp_obj_list_init(mp_sys_argv, 0);
|
||||||
MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
|
MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
|
||||||
MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
|
MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
|
||||||
@ -109,34 +109,23 @@ void user_init(void) {
|
|||||||
system_init_done_cb(init_done);
|
system_init_done_cb(init_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_import_stat_t fat_vfs_import_stat(const char *path);
|
#if !MICROPY_VFS
|
||||||
|
|
||||||
#if !MICROPY_VFS_FAT
|
|
||||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
mp_import_stat_t mp_import_stat(const char *path) {
|
mp_import_stat_t mp_import_stat(const char *path) {
|
||||||
#if MICROPY_VFS_FAT
|
|
||||||
return fat_vfs_import_stat(path);
|
|
||||||
#else
|
|
||||||
(void)path;
|
(void)path;
|
||||||
return MP_IMPORT_STAT_NO_EXIST;
|
return MP_IMPORT_STAT_NO_EXIST;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t vfs_proxy_call(qstr method_name, mp_uint_t n_args, const mp_obj_t *args);
|
|
||||||
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||||
#if MICROPY_VFS_FAT
|
|
||||||
// TODO: Handle kwargs!
|
|
||||||
return vfs_proxy_call(MP_QSTR_open, n_args, args);
|
|
||||||
#else
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void MP_FASTCODE(nlr_jump_fail)(void *val) {
|
void MP_FASTCODE(nlr_jump_fail)(void *val) {
|
||||||
printf("NLR jump failed\n");
|
printf("NLR jump failed\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "extmod/machine_mem.h"
|
#include "extmod/machine_mem.h"
|
||||||
|
#include "extmod/machine_signal.h"
|
||||||
#include "extmod/machine_pulse.h"
|
#include "extmod/machine_pulse.h"
|
||||||
#include "extmod/machine_i2c.h"
|
#include "extmod/machine_i2c.h"
|
||||||
#include "modmachine.h"
|
#include "modmachine.h"
|
||||||
@ -251,6 +252,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&esp_timer_type) },
|
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&esp_timer_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) },
|
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
|
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) },
|
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
|
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
|
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
|
||||||
|
@ -5,7 +5,9 @@ from flashbdev import bdev
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if bdev:
|
if bdev:
|
||||||
vfs = uos.VfsFat(bdev, "")
|
vfs = uos.VfsFat(bdev)
|
||||||
|
uos.mount(vfs, '/flash')
|
||||||
|
uos.chdir('/flash')
|
||||||
except OSError:
|
except OSError:
|
||||||
import inisetup
|
import inisetup
|
||||||
vfs = inisetup.setup()
|
vfs = inisetup.setup()
|
||||||
|
@ -26,20 +26,15 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
|
||||||
#include "py/nlr.h"
|
|
||||||
#include "py/obj.h"
|
|
||||||
#include "py/objtuple.h"
|
#include "py/objtuple.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/mperrno.h"
|
|
||||||
#include "extmod/misc.h"
|
#include "extmod/misc.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
#include "genhdr/mpversion.h"
|
#include "genhdr/mpversion.h"
|
||||||
#include "esp_mphal.h"
|
#include "esp_mphal.h"
|
||||||
#include "user_interface.h"
|
#include "user_interface.h"
|
||||||
|
|
||||||
extern const mp_obj_type_t mp_fat_vfs_type;
|
|
||||||
|
|
||||||
STATIC const qstr os_uname_info_fields[] = {
|
STATIC const qstr os_uname_info_fields[] = {
|
||||||
MP_QSTR_sysname, MP_QSTR_nodename,
|
MP_QSTR_sysname, MP_QSTR_nodename,
|
||||||
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
||||||
@ -71,74 +66,6 @@ STATIC mp_obj_t os_uname(void) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
||||||
|
|
||||||
#if MICROPY_VFS_FAT
|
|
||||||
mp_obj_t vfs_proxy_call(qstr method_name, mp_uint_t n_args, const mp_obj_t *args) {
|
|
||||||
if (MP_STATE_PORT(fs_user_mount)[0] == NULL) {
|
|
||||||
mp_raise_OSError(MP_ENODEV);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t meth[n_args + 2];
|
|
||||||
mp_load_method(MP_STATE_PORT(fs_user_mount)[0], method_name, meth);
|
|
||||||
if (args != NULL) {
|
|
||||||
memcpy(meth + 2, args, n_args * sizeof(*args));
|
|
||||||
}
|
|
||||||
return mp_call_method_n_kw(n_args, 0, meth);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_listdir, n_args, args);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_mkdir(mp_obj_t path_in) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_mkdir, 1, &path_in);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_rmdir(mp_obj_t path_in) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_rmdir, 1, &path_in);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_chdir, 1, &path_in);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_getcwd(void) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_getcwd, 0, NULL);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_remove(mp_obj_t path_in) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_remove, 1, &path_in);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_rename(mp_obj_t path_old, mp_obj_t path_new) {
|
|
||||||
mp_obj_t args[2];
|
|
||||||
args[0] = path_old;
|
|
||||||
args[1] = path_new;
|
|
||||||
return vfs_proxy_call(MP_QSTR_rename, 2, args);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_stat, 1, &path_in);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_statvfs(mp_obj_t path_in) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_statvfs, 1, &path_in);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs);
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_umount(void) {
|
|
||||||
return vfs_proxy_call(MP_QSTR_umount, 0, NULL);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_umount_obj, os_umount);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||||
mp_int_t n = mp_obj_get_int(num);
|
mp_int_t n = mp_obj_get_int(num);
|
||||||
vstr_t vstr;
|
vstr_t vstr;
|
||||||
@ -167,16 +94,17 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
|||||||
#endif
|
#endif
|
||||||
#if MICROPY_VFS_FAT
|
#if MICROPY_VFS_FAT
|
||||||
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&os_listdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&os_mkdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&os_rmdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&os_chdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&os_getcwd_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&os_remove_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&os_rename_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&os_statvfs_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&os_umount_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#define MICROPY_MEM_STATS (0)
|
#define MICROPY_MEM_STATS (0)
|
||||||
#define MICROPY_DEBUG_PRINTERS (1)
|
#define MICROPY_DEBUG_PRINTERS (1)
|
||||||
#define MICROPY_DEBUG_PRINTER_DEST mp_debug_print
|
#define MICROPY_DEBUG_PRINTER_DEST mp_debug_print
|
||||||
#define MICROPY_READER_FATFS (MICROPY_VFS_FAT)
|
#define MICROPY_READER_VFS (MICROPY_VFS)
|
||||||
#define MICROPY_ENABLE_GC (1)
|
#define MICROPY_ENABLE_GC (1)
|
||||||
#define MICROPY_STACK_CHECK (1)
|
#define MICROPY_STACK_CHECK (1)
|
||||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||||
@ -94,12 +94,11 @@
|
|||||||
#define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str32
|
#define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str32
|
||||||
#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool
|
#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool
|
||||||
|
|
||||||
|
#define MICROPY_VFS (1)
|
||||||
#define MICROPY_FATFS_ENABLE_LFN (1)
|
#define MICROPY_FATFS_ENABLE_LFN (1)
|
||||||
#define MICROPY_FATFS_RPATH (2)
|
#define MICROPY_FATFS_RPATH (2)
|
||||||
#define MICROPY_FATFS_VOLUMES (2)
|
|
||||||
#define MICROPY_FATFS_MAX_SS (4096)
|
#define MICROPY_FATFS_MAX_SS (4096)
|
||||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||||
#define MICROPY_FSUSERMOUNT (1)
|
|
||||||
#define MICROPY_VFS_FAT (1)
|
#define MICROPY_VFS_FAT (1)
|
||||||
#define MICROPY_ESP8266_APA102 (1)
|
#define MICROPY_ESP8266_APA102 (1)
|
||||||
#define MICROPY_ESP8266_NEOPIXEL (1)
|
#define MICROPY_ESP8266_NEOPIXEL (1)
|
||||||
@ -140,6 +139,11 @@ void *esp_native_code_commit(void*, size_t);
|
|||||||
#define mp_type_fileio fatfs_type_fileio
|
#define mp_type_fileio fatfs_type_fileio
|
||||||
#define mp_type_textio fatfs_type_textio
|
#define mp_type_textio fatfs_type_textio
|
||||||
|
|
||||||
|
// use vfs's functions for import stat and builtin open
|
||||||
|
#define mp_import_stat mp_vfs_import_stat
|
||||||
|
#define mp_builtin_open mp_vfs_open
|
||||||
|
#define mp_builtin_open_obj mp_vfs_open_obj
|
||||||
|
|
||||||
// extra built in names to add to the global namespace
|
// extra built in names to add to the global namespace
|
||||||
#define MICROPY_PORT_BUILTINS \
|
#define MICROPY_PORT_BUILTINS \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#undef MICROPY_EMIT_INLINE_XTENSA
|
#undef MICROPY_EMIT_INLINE_XTENSA
|
||||||
#define MICROPY_EMIT_INLINE_XTENSA (0)
|
#define MICROPY_EMIT_INLINE_XTENSA (0)
|
||||||
|
|
||||||
#undef MICROPY_FSUSERMOUNT
|
#undef MICROPY_VFS
|
||||||
#define MICROPY_FSUSERMOUNT (0)
|
#define MICROPY_VFS (0)
|
||||||
#undef MICROPY_VFS_FAT
|
#undef MICROPY_VFS_FAT
|
||||||
#define MICROPY_VFS_FAT (0)
|
#define MICROPY_VFS_FAT (0)
|
||||||
|
|
||||||
@ -25,3 +25,7 @@
|
|||||||
|
|
||||||
#undef MICROPY_PY_FRAMEBUF
|
#undef MICROPY_PY_FRAMEBUF
|
||||||
#define MICROPY_PY_FRAMEBUF (0)
|
#define MICROPY_PY_FRAMEBUF (0)
|
||||||
|
|
||||||
|
#undef mp_import_stat
|
||||||
|
#undef mp_builtin_open
|
||||||
|
#undef mp_builtin_open_obj
|
||||||
|
@ -27,5 +27,5 @@
|
|||||||
// qstrs specific to this port, only needed if they aren't auto-generated
|
// qstrs specific to this port, only needed if they aren't auto-generated
|
||||||
|
|
||||||
// Entries for sys.path
|
// Entries for sys.path
|
||||||
Q(/)
|
Q(/flash)
|
||||||
Q(/lib)
|
Q(/flash/lib)
|
||||||
|
@ -37,8 +37,10 @@ def setup():
|
|||||||
print("Performing initial setup")
|
print("Performing initial setup")
|
||||||
wifi()
|
wifi()
|
||||||
uos.VfsFat.mkfs(bdev)
|
uos.VfsFat.mkfs(bdev)
|
||||||
vfs = uos.VfsFat(bdev, "")
|
vfs = uos.VfsFat(bdev)
|
||||||
with open("/boot.py", "w") as f:
|
uos.mount(vfs, '/flash')
|
||||||
|
uos.chdir('/flash')
|
||||||
|
with open("boot.py", "w") as f:
|
||||||
f.write("""\
|
f.write("""\
|
||||||
# This file is executed on every boot (including wake-boot from deepsleep)
|
# This file is executed on every boot (including wake-boot from deepsleep)
|
||||||
#import esp
|
#import esp
|
||||||
|
@ -200,6 +200,21 @@ bool uart_rx_wait(uint32_t timeout_us) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uart_rx_any(uint8 uart) {
|
||||||
|
if (input_buf.iget != input_buf.iput) {
|
||||||
|
return true; // have at least 1 char ready for reading
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uart_tx_any_room(uint8 uart) {
|
||||||
|
uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
|
||||||
|
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) >= 126) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns char from the input buffer, else -1 if buffer is empty.
|
// Returns char from the input buffer, else -1 if buffer is empty.
|
||||||
int uart_rx_char(void) {
|
int uart_rx_char(void) {
|
||||||
return ringbuf_get(&input_buf);
|
return ringbuf_get(&input_buf);
|
||||||
|
@ -99,5 +99,8 @@ void uart_tx_one_char(uint8 uart, uint8 TxChar);
|
|||||||
void uart_flush(uint8 uart);
|
void uart_flush(uint8 uart);
|
||||||
void uart_os_config(int uart);
|
void uart_os_config(int uart);
|
||||||
void uart_setup(uint8 uart);
|
void uart_setup(uint8 uart);
|
||||||
|
// check status of rx/tx
|
||||||
|
int uart_rx_any(uint8 uart);
|
||||||
|
int uart_tx_any_room(uint8 uart);
|
||||||
|
|
||||||
#endif // _INCLUDED_UART_H_
|
#endif // _INCLUDED_UART_H_
|
||||||
|
@ -11,9 +11,9 @@ Ready? Cliiiiick!
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
delay = machine.time_pulse_us(BUTTON, 1, 10*1000*1000)
|
||||||
delay = machine.time_pulse_us(BUTTON, 1, 10*1000*1000)
|
if delay < 0:
|
||||||
print("You are as slow as %d microseconds!" % delay)
|
|
||||||
except OSError:
|
|
||||||
print("Well, you're *really* slow")
|
print("Well, you're *really* slow")
|
||||||
|
else:
|
||||||
|
print("You are as slow as %d microseconds!" % delay)
|
||||||
utime.sleep_ms(10)
|
utime.sleep_ms(10)
|
||||||
|
@ -13,10 +13,10 @@ from machine import Pin
|
|||||||
# echo -n "gpio_keys" >/sys/class/input/input1/device/driver/unbind
|
# echo -n "gpio_keys" >/sys/class/input/input1/device/driver/unbind
|
||||||
|
|
||||||
# User LED 1 on gpio21
|
# User LED 1 on gpio21
|
||||||
LED = Pin(21, Pin.OUT)
|
LED = Signal(Pin(21, Pin.OUT))
|
||||||
|
|
||||||
# User LED 2 on gpio120
|
# User LED 2 on gpio120
|
||||||
LED2 = Pin(120, Pin.OUT)
|
LED2 = Signal(Pin(120, Pin.OUT))
|
||||||
|
|
||||||
# Button S3 on gpio107
|
# Button S3 on gpio107
|
||||||
BUTTON = Pin(107, Pin.IN)
|
BUTTON = Pin(107, Pin.IN)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from machine import Pin
|
from machine import Pin, Signal
|
||||||
|
|
||||||
# ESP12 module as used by many boards
|
# ESP12 module as used by many boards
|
||||||
# Blue LED on pin 2
|
# Blue LED on pin 2, active low (inverted)
|
||||||
LED = Pin(2, Pin.OUT)
|
LED = Signal(Pin(2, Pin.OUT), inverted=True)
|
||||||
|
@ -2,4 +2,4 @@ from machine import Pin
|
|||||||
|
|
||||||
# Freescale/NXP FRDM-K64F board
|
# Freescale/NXP FRDM-K64F board
|
||||||
# Blue LED on port B, pin 21
|
# Blue LED on port B, pin 21
|
||||||
LED = Pin(("GPIO_1", 21), Pin.OUT)
|
LED = Signal(Pin(("GPIO_1", 21), Pin.OUT))
|
||||||
|
@ -1,209 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014 Damien P. George
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
|
||||||
#if MICROPY_FSUSERMOUNT
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "py/nlr.h"
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/mperrno.h"
|
|
||||||
#include "lib/fatfs/ff.h"
|
|
||||||
#include "extmod/fsusermount.h"
|
|
||||||
|
|
||||||
fs_user_mount_t *fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, bool mkfs) {
|
|
||||||
static const mp_arg_t allowed_args[] = {
|
|
||||||
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
|
||||||
{ MP_QSTR_mkfs, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
|
||||||
};
|
|
||||||
|
|
||||||
// parse args
|
|
||||||
mp_obj_t device = pos_args[0];
|
|
||||||
mp_obj_t mount_point = pos_args[1];
|
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
|
||||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
|
||||||
|
|
||||||
// get the mount point
|
|
||||||
mp_uint_t mnt_len;
|
|
||||||
const char *mnt_str = mp_obj_str_get_data(mount_point, &mnt_len);
|
|
||||||
|
|
||||||
if (device == mp_const_none) {
|
|
||||||
// umount
|
|
||||||
FRESULT res = FR_NO_FILESYSTEM;
|
|
||||||
for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
|
||||||
if (vfs != NULL && !memcmp(mnt_str, vfs->str, mnt_len + 1)) {
|
|
||||||
res = f_mount(NULL, vfs->str, 0);
|
|
||||||
if (vfs->flags & FSUSER_FREE_OBJ) {
|
|
||||||
m_del_obj(fs_user_mount_t, vfs);
|
|
||||||
}
|
|
||||||
MP_STATE_PORT(fs_user_mount)[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (res != FR_OK) {
|
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't umount"));
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
// mount
|
|
||||||
size_t i = 0;
|
|
||||||
for (; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
|
||||||
if (MP_STATE_PORT(fs_user_mount)[i] == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
|
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "too many devices mounted"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create new object
|
|
||||||
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
|
|
||||||
vfs->str = mnt_str;
|
|
||||||
vfs->len = mnt_len;
|
|
||||||
vfs->flags = FSUSER_FREE_OBJ;
|
|
||||||
|
|
||||||
// load block protocol methods
|
|
||||||
mp_load_method(device, MP_QSTR_readblocks, vfs->readblocks);
|
|
||||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, vfs->writeblocks);
|
|
||||||
mp_load_method_maybe(device, MP_QSTR_ioctl, vfs->u.ioctl);
|
|
||||||
if (vfs->u.ioctl[0] != MP_OBJ_NULL) {
|
|
||||||
// device supports new block protocol, so indicate it
|
|
||||||
vfs->flags |= FSUSER_HAVE_IOCTL;
|
|
||||||
} else {
|
|
||||||
// no ioctl method, so assume the device uses the old block protocol
|
|
||||||
mp_load_method_maybe(device, MP_QSTR_sync, vfs->u.old.sync);
|
|
||||||
mp_load_method(device, MP_QSTR_count, vfs->u.old.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
|
||||||
// User can specify read-only device by:
|
|
||||||
// 1. readonly=True keyword argument
|
|
||||||
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
|
||||||
if (args[0].u_bool) {
|
|
||||||
vfs->writeblocks[0] = MP_OBJ_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the vfs object so that it can be found by the FatFS driver using
|
|
||||||
// ff_get_ldnumber. We don't register it any earlier than this point in case there
|
|
||||||
// is an exception, in which case there would remain a partially mounted device.
|
|
||||||
MP_STATE_PORT(fs_user_mount)[i] = vfs;
|
|
||||||
|
|
||||||
// mount the block device (if mkfs, only pre-mount)
|
|
||||||
FRESULT res = f_mount(&vfs->fatfs, vfs->str, !mkfs);
|
|
||||||
// check the result
|
|
||||||
if (res == FR_OK) {
|
|
||||||
if (mkfs) {
|
|
||||||
goto mkfs;
|
|
||||||
}
|
|
||||||
} else if (res == FR_NO_FILESYSTEM && args[1].u_bool) {
|
|
||||||
mkfs:
|
|
||||||
res = f_mkfs(vfs->str, 1, 0);
|
|
||||||
if (res != FR_OK) {
|
|
||||||
mkfs_error:
|
|
||||||
MP_STATE_PORT(fs_user_mount)[i] = NULL;
|
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't mkfs"));
|
|
||||||
}
|
|
||||||
if (mkfs) {
|
|
||||||
// If requested to only mkfs, unmount pre-mounted device
|
|
||||||
res = f_mount(NULL, vfs->str, 0);
|
|
||||||
if (res != FR_OK) {
|
|
||||||
goto mkfs_error;
|
|
||||||
}
|
|
||||||
MP_STATE_PORT(fs_user_mount)[i] = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MP_STATE_PORT(fs_user_mount)[i] = NULL;
|
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't mount"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (vfs->writeblocks[0] == MP_OBJ_NULL) {
|
|
||||||
printf("mounted read-only");
|
|
||||||
} else {
|
|
||||||
printf("mounted read-write");
|
|
||||||
}
|
|
||||||
DWORD nclst;
|
|
||||||
FATFS *fatfs;
|
|
||||||
f_getfree(vfs->str, &nclst, &fatfs);
|
|
||||||
printf(" on %s with %u bytes free\n", vfs->str, (uint)(nclst * fatfs->csize * 512));
|
|
||||||
*/
|
|
||||||
return vfs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t fatfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
fatfs_mount_mkfs(n_args, pos_args, kw_args, false);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(fsuser_mount_obj, 2, fatfs_mount);
|
|
||||||
|
|
||||||
mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in) {
|
|
||||||
size_t i = 0;
|
|
||||||
if (MP_OBJ_IS_STR(bdev_or_path_in)) {
|
|
||||||
mp_uint_t mnt_len;
|
|
||||||
const char *mnt_str = mp_obj_str_get_data(bdev_or_path_in, &mnt_len);
|
|
||||||
for (; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
|
||||||
if (vfs != NULL && !memcmp(mnt_str, vfs->str, mnt_len + 1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
|
||||||
if (vfs != NULL && bdev_or_path_in == vfs->readblocks[1]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
|
|
||||||
mp_raise_OSError(MP_EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
|
||||||
FRESULT res = f_mount(NULL, vfs->str, 0);
|
|
||||||
if (vfs->flags & FSUSER_FREE_OBJ) {
|
|
||||||
m_del_obj(fs_user_mount_t, vfs);
|
|
||||||
}
|
|
||||||
MP_STATE_PORT(fs_user_mount)[i] = NULL;
|
|
||||||
if (res != FR_OK) {
|
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't umount"));
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_1(fsuser_umount_obj, fatfs_umount);
|
|
||||||
|
|
||||||
STATIC mp_obj_t fatfs_mkfs(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
fatfs_mount_mkfs(n_args, pos_args, kw_args, true);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj, 2, fatfs_mkfs);
|
|
||||||
|
|
||||||
#endif // MICROPY_FSUSERMOUNT
|
|
@ -34,7 +34,7 @@ mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t
|
|||||||
mp_uint_t start = mp_hal_ticks_us();
|
mp_uint_t start = mp_hal_ticks_us();
|
||||||
while (mp_hal_pin_read(pin) != pulse_level) {
|
while (mp_hal_pin_read(pin) != pulse_level) {
|
||||||
if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
|
if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
|
||||||
return (mp_uint_t)-1;
|
return (mp_uint_t)-2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start = mp_hal_ticks_us();
|
start = mp_hal_ticks_us();
|
||||||
@ -57,9 +57,7 @@ STATIC mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) {
|
|||||||
timeout_us = mp_obj_get_int(args[2]);
|
timeout_us = mp_obj_get_int(args[2]);
|
||||||
}
|
}
|
||||||
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us);
|
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us);
|
||||||
if (us == (mp_uint_t)-1) {
|
// May return -1 or -2 in case of timeout
|
||||||
mp_raise_OSError(MP_ETIMEDOUT);
|
|
||||||
}
|
|
||||||
return mp_obj_new_int(us);
|
return mp_obj_new_int(us);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 3, machine_time_pulse_us_);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 3, machine_time_pulse_us_);
|
||||||
|
114
extmod/machine_signal.c
Normal file
114
extmod/machine_signal.c
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
#if MICROPY_PY_MACHINE
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "extmod/virtpin.h"
|
||||||
|
#include "extmod/machine_signal.h"
|
||||||
|
|
||||||
|
// Signal class
|
||||||
|
|
||||||
|
typedef struct _machine_signal_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
mp_obj_t pin;
|
||||||
|
bool inverted;
|
||||||
|
} machine_signal_t;
|
||||||
|
|
||||||
|
STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
|
enum { ARG_pin, ARG_inverted };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_, MP_ARG_OBJ | MP_ARG_REQUIRED },
|
||||||
|
{ MP_QSTR_inverted, MP_ARG_BOOL, {.u_bool = false} },
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
|
||||||
|
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args);
|
||||||
|
|
||||||
|
machine_signal_t *o = m_new_obj(machine_signal_t);
|
||||||
|
o->base.type = type;
|
||||||
|
o->pin = parsed_args[ARG_pin].u_obj;
|
||||||
|
o->inverted = parsed_args[ARG_inverted].u_bool;
|
||||||
|
return MP_OBJ_FROM_PTR(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_uint_t signal_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||||
|
(void)errcode;
|
||||||
|
machine_signal_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
switch (request) {
|
||||||
|
case MP_PIN_READ: {
|
||||||
|
return mp_virtual_pin_read(self->pin) ^ self->inverted;
|
||||||
|
}
|
||||||
|
case MP_PIN_WRITE: {
|
||||||
|
mp_virtual_pin_write(self->pin, arg ^ self->inverted);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fast method for getting/setting signal value
|
||||||
|
STATIC mp_obj_t signal_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
|
if (n_args == 0) {
|
||||||
|
// get pin
|
||||||
|
return MP_OBJ_NEW_SMALL_INT(mp_virtual_pin_read(self_in));
|
||||||
|
} else {
|
||||||
|
// set pin
|
||||||
|
mp_virtual_pin_write(self_in, mp_obj_is_true(args[0]));
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t signal_value(size_t n_args, const mp_obj_t *args) {
|
||||||
|
return signal_call(args[0], n_args - 1, 0, args + 1);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(signal_value_obj, 1, 2, signal_value);
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t signal_locals_dict_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&signal_value_obj) },
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(signal_locals_dict, signal_locals_dict_table);
|
||||||
|
|
||||||
|
STATIC const mp_pin_p_t signal_pin_p = {
|
||||||
|
.ioctl = signal_ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mp_obj_type_t machine_signal_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_Signal,
|
||||||
|
.make_new = signal_make_new,
|
||||||
|
.call = signal_call,
|
||||||
|
.protocol = &signal_pin_p,
|
||||||
|
.locals_dict = (void*)&signal_locals_dict,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_MACHINE
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
* Copyright (c) 2017 Paul Sokolovsky
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -24,7 +24,12 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "extmod/vfs_fat_file.h"
|
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, fatfs_builtin_open);
|
#ifndef __MICROPY_INCLUDED_EXTMOD_MACHINE_SIGNAL_H__
|
||||||
|
#define __MICROPY_INCLUDED_EXTMOD_MACHINE_SIGNAL_H__
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t machine_signal_type;
|
||||||
|
|
||||||
|
#endif // __MICROPY_INCLUDED_EXTMOD_MACHINE_SIGNAL_H__
|
@ -90,12 +90,6 @@ void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint
|
|||||||
if (dest != NULL) {
|
if (dest != NULL) {
|
||||||
dest[i] = data_in;
|
dest[i] = data_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some ports need a regular callback, but probably we don't need
|
|
||||||
// to do this every byte, or even at all.
|
|
||||||
#ifdef MICROPY_EVENT_POLL_HOOK
|
|
||||||
MICROPY_EVENT_POLL_HOOK;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,13 +97,66 @@ STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Functions for GS4_HMSB format
|
||||||
|
|
||||||
|
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
|
||||||
|
uint8_t *pixel = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1];
|
||||||
|
|
||||||
|
if (x % 2) {
|
||||||
|
*pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0);
|
||||||
|
} else {
|
||||||
|
*pixel = ((uint8_t)col << 4) | (*pixel & 0x0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
|
||||||
|
if (x % 2) {
|
||||||
|
return ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1] >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
|
||||||
|
col &= 0x0f;
|
||||||
|
uint8_t *pixel_pair = &((uint8_t*)fb->buf)[(x + y * fb->stride) >> 1];
|
||||||
|
uint8_t col_shifted_left = col << 4;
|
||||||
|
uint8_t colored_pixel_pair = col_shifted_left | col;
|
||||||
|
int pixel_count_till_next_line = (fb->stride - w) >> 1;
|
||||||
|
bool odd_x = (x % 2 == 1);
|
||||||
|
|
||||||
|
while (h--) {
|
||||||
|
int ww = w;
|
||||||
|
|
||||||
|
if (odd_x && ww > 0) {
|
||||||
|
*pixel_pair = (*pixel_pair & 0xf0) | col;
|
||||||
|
pixel_pair++;
|
||||||
|
ww--;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(pixel_pair, colored_pixel_pair, ww >> 1);
|
||||||
|
pixel_pair += ww >> 1;
|
||||||
|
|
||||||
|
if (ww % 2) {
|
||||||
|
*pixel_pair = col_shifted_left | (*pixel_pair & 0x0f);
|
||||||
|
if (!odd_x) {
|
||||||
|
pixel_pair++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel_pair += pixel_count_till_next_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// constants for formats
|
// constants for formats
|
||||||
#define FRAMEBUF_MVLSB (0)
|
#define FRAMEBUF_MVLSB (0)
|
||||||
#define FRAMEBUF_RGB565 (1)
|
#define FRAMEBUF_RGB565 (1)
|
||||||
|
#define FRAMEBUF_GS4_HMSB (2)
|
||||||
|
|
||||||
STATIC mp_framebuf_p_t formats[] = {
|
STATIC mp_framebuf_p_t formats[] = {
|
||||||
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
||||||
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
||||||
|
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t color) {
|
||||||
@ -152,6 +205,7 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
switch (o->format) {
|
switch (o->format) {
|
||||||
case FRAMEBUF_MVLSB:
|
case FRAMEBUF_MVLSB:
|
||||||
case FRAMEBUF_RGB565:
|
case FRAMEBUF_RGB565:
|
||||||
|
case FRAMEBUF_GS4_HMSB:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||||
@ -302,9 +356,13 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
|
|||||||
mp_int_t e = 2 * dy - dx;
|
mp_int_t e = 2 * dy - dx;
|
||||||
for (mp_int_t i = 0; i < dx; ++i) {
|
for (mp_int_t i = 0; i < dx; ++i) {
|
||||||
if (steep) {
|
if (steep) {
|
||||||
setpixel(self, y1, x1, col);
|
if (0 <= y1 && y1 < self->width && 0 <= x1 && x1 < self->height) {
|
||||||
|
setpixel(self, y1, x1, col);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setpixel(self, x1, y1, col);
|
if (0 <= x1 && x1 < self->width && 0 <= y1 && y1 < self->height) {
|
||||||
|
setpixel(self, x1, y1, col);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (e >= 0) {
|
while (e >= 0) {
|
||||||
y1 += sy;
|
y1 += sy;
|
||||||
@ -314,7 +372,9 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
|
|||||||
e += 2 * dy;
|
e += 2 * dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
setpixel(self, x2, y2, col);
|
if (0 <= x2 && x2 < self->width && 0 <= y2 && y2 < self->height) {
|
||||||
|
setpixel(self, x2, y2, col);
|
||||||
|
}
|
||||||
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
@ -484,6 +544,7 @@ STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer1), MP_ROM_PTR(&legacy_framebuffer1_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer1), MP_ROM_PTR(&legacy_framebuffer1_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB) },
|
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565) },
|
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB) },
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
|
STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
|
||||||
|
@ -1172,6 +1172,7 @@ STATIC const mp_map_elem_t lwip_socket_locals_dict_table[] = {
|
|||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&lwip_socket_makefile_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&lwip_socket_makefile_obj },
|
||||||
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
||||||
};
|
};
|
||||||
|
309
extmod/vfs.c
Normal file
309
extmod/vfs.c
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/objstr.h"
|
||||||
|
#include "py/mperrno.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
|
#if MICROPY_VFS
|
||||||
|
|
||||||
|
#if MICROPY_VFS_FAT
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// path is the path to lookup and *path_out holds the path within the VFS
|
||||||
|
// object (starts with / if an absolute path).
|
||||||
|
// Returns MP_VFS_ROOT for root dir (and then path_out is undefined) and
|
||||||
|
// MP_VFS_NONE for path not found.
|
||||||
|
mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) {
|
||||||
|
if (path[0] == '/' && path[1] == 0) {
|
||||||
|
return MP_VFS_ROOT;
|
||||||
|
} else if (MP_STATE_VM(vfs_cur) == MP_VFS_ROOT) {
|
||||||
|
// in root dir
|
||||||
|
if (path[0] == 0) {
|
||||||
|
return MP_VFS_ROOT;
|
||||||
|
}
|
||||||
|
} else if (*path != '/') {
|
||||||
|
// a relative path within a mounted device
|
||||||
|
*path_out = path;
|
||||||
|
return MP_STATE_VM(vfs_cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
|
||||||
|
if (strncmp(path, vfs->str, vfs->len) == 0) {
|
||||||
|
if (path[vfs->len] == '/') {
|
||||||
|
*path_out = path + vfs->len;
|
||||||
|
return vfs;
|
||||||
|
} else if (path[vfs->len] == '\0') {
|
||||||
|
*path_out = "/";
|
||||||
|
return vfs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mount point not found
|
||||||
|
return MP_VFS_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version of mp_vfs_lookup_path that takes and returns uPy string objects.
|
||||||
|
STATIC mp_vfs_mount_t *lookup_path(mp_obj_t path_in, mp_obj_t *path_out) {
|
||||||
|
const char *path = mp_obj_str_get_str(path_in);
|
||||||
|
const char *p_out;
|
||||||
|
mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out);
|
||||||
|
if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) {
|
||||||
|
*path_out = mp_obj_new_str_of_type(mp_obj_get_type(path_in),
|
||||||
|
(const byte*)p_out, strlen(p_out));
|
||||||
|
}
|
||||||
|
return vfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
|
||||||
|
if (vfs == MP_VFS_NONE) {
|
||||||
|
// mount point not found
|
||||||
|
mp_raise_OSError(MP_ENODEV);
|
||||||
|
}
|
||||||
|
if (vfs == MP_VFS_ROOT) {
|
||||||
|
// can't do operation on root dir
|
||||||
|
mp_raise_OSError(MP_EPERM);
|
||||||
|
}
|
||||||
|
mp_obj_t meth[n_args + 2];
|
||||||
|
mp_load_method(vfs->obj, meth_name, meth);
|
||||||
|
if (args != NULL) {
|
||||||
|
memcpy(meth + 2, args, n_args * sizeof(*args));
|
||||||
|
}
|
||||||
|
return mp_call_method_n_kw(n_args, 0, meth);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_import_stat_t mp_vfs_import_stat(const char *path) {
|
||||||
|
const char *path_out;
|
||||||
|
mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &path_out);
|
||||||
|
if (vfs == MP_VFS_NONE || vfs == MP_VFS_ROOT) {
|
||||||
|
return MP_IMPORT_STAT_NO_EXIST;
|
||||||
|
}
|
||||||
|
#if MICROPY_VFS_FAT
|
||||||
|
// fast paths for known VFS types
|
||||||
|
if (mp_obj_get_type(vfs->obj) == &mp_fat_vfs_type) {
|
||||||
|
return fat_vfs_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// TODO delegate to vfs.stat() method
|
||||||
|
return MP_IMPORT_STAT_NO_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum { ARG_readonly, ARG_mkfs };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
|
||||||
|
{ MP_QSTR_mkfs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
|
||||||
|
};
|
||||||
|
|
||||||
|
// parse args
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
// get the mount point
|
||||||
|
mp_uint_t mnt_len;
|
||||||
|
const char *mnt_str = mp_obj_str_get_data(pos_args[1], &mnt_len);
|
||||||
|
|
||||||
|
// create new object
|
||||||
|
mp_vfs_mount_t *vfs = m_new_obj(mp_vfs_mount_t);
|
||||||
|
vfs->str = mnt_str;
|
||||||
|
vfs->len = mnt_len;
|
||||||
|
vfs->obj = pos_args[0];
|
||||||
|
vfs->next = NULL;
|
||||||
|
|
||||||
|
// call the underlying object to do any mounting operation
|
||||||
|
mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t*)&args);
|
||||||
|
|
||||||
|
// check that the destination mount point is unused
|
||||||
|
const char *path_out;
|
||||||
|
if (mp_vfs_lookup_path(mp_obj_str_get_str(pos_args[1]), &path_out) != MP_VFS_NONE) {
|
||||||
|
mp_raise_OSError(MP_EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert the vfs into the mount table
|
||||||
|
mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table);
|
||||||
|
while (*vfsp != NULL) {
|
||||||
|
vfsp = &(*vfsp)->next;
|
||||||
|
}
|
||||||
|
*vfsp = vfs;
|
||||||
|
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_KW(mp_vfs_mount_obj, 2, mp_vfs_mount);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_umount(mp_obj_t mnt_in) {
|
||||||
|
// remove vfs from the mount table
|
||||||
|
mp_vfs_mount_t *vfs = NULL;
|
||||||
|
mp_uint_t mnt_len;
|
||||||
|
const char *mnt_str = NULL;
|
||||||
|
if (MP_OBJ_IS_STR(mnt_in)) {
|
||||||
|
mnt_str = mp_obj_str_get_data(mnt_in, &mnt_len);
|
||||||
|
}
|
||||||
|
for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) {
|
||||||
|
if ((mnt_str != NULL && !memcmp(mnt_str, (*vfsp)->str, mnt_len + 1)) || (*vfsp)->obj == mnt_in) {
|
||||||
|
vfs = *vfsp;
|
||||||
|
*vfsp = (*vfsp)->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vfs == NULL) {
|
||||||
|
mp_raise_OSError(MP_EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we unmounted the current device then set current to root
|
||||||
|
if (MP_STATE_VM(vfs_cur) == vfs) {
|
||||||
|
MP_STATE_VM(vfs_cur) = MP_VFS_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call the underlying object to do any unmounting operation
|
||||||
|
mp_vfs_proxy_call(vfs, MP_QSTR_umount, 0, NULL);
|
||||||
|
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_umount_obj, mp_vfs_umount);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum { ARG_file, ARG_mode, ARG_encoding };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||||
|
{ MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_r)} },
|
||||||
|
};
|
||||||
|
|
||||||
|
// parse args
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path((mp_obj_t)args[ARG_file].u_rom_obj, &args[ARG_file].u_obj);
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_open, 2, (mp_obj_t*)&args);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_KW(mp_vfs_open_obj, 0, mp_vfs_open);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_chdir(mp_obj_t path_in) {
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
if (vfs != MP_VFS_ROOT) {
|
||||||
|
mp_vfs_proxy_call(vfs, MP_QSTR_chdir, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_STATE_VM(vfs_cur) = vfs;
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_chdir_obj, mp_vfs_chdir);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_getcwd(void) {
|
||||||
|
if (MP_STATE_VM(vfs_cur) == MP_VFS_ROOT) {
|
||||||
|
return MP_OBJ_NEW_QSTR(MP_QSTR__slash_);
|
||||||
|
}
|
||||||
|
mp_obj_t cwd_o = mp_vfs_proxy_call(MP_STATE_VM(vfs_cur), MP_QSTR_getcwd, 0, NULL);
|
||||||
|
const char *cwd = mp_obj_str_get_str(cwd_o);
|
||||||
|
vstr_t vstr;
|
||||||
|
vstr_init(&vstr, MP_STATE_VM(vfs_cur)->len + strlen(cwd) + 1);
|
||||||
|
vstr_add_strn(&vstr, MP_STATE_VM(vfs_cur)->str, MP_STATE_VM(vfs_cur)->len);
|
||||||
|
if (!(cwd[0] == '/' && cwd[1] == 0)) {
|
||||||
|
vstr_add_str(&vstr, cwd);
|
||||||
|
}
|
||||||
|
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args) {
|
||||||
|
mp_obj_t path_in;
|
||||||
|
if (n_args == 1) {
|
||||||
|
path_in = args[0];
|
||||||
|
} else {
|
||||||
|
path_in = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
|
||||||
|
if (vfs == MP_VFS_ROOT) {
|
||||||
|
// list the root directory
|
||||||
|
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||||
|
for (vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
|
||||||
|
mp_obj_list_append(dir_list, mp_obj_new_str_of_type(mp_obj_get_type(path_in),
|
||||||
|
(const byte*)vfs->str + 1, vfs->len - 1));
|
||||||
|
}
|
||||||
|
return dir_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_listdir, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_vfs_listdir_obj, 0, 1, mp_vfs_listdir);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_mkdir(mp_obj_t path_in) {
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_mkdir, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_mkdir_obj, mp_vfs_mkdir);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_remove(mp_obj_t path_in) {
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_remove, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_remove_obj, mp_vfs_remove);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_rename(mp_obj_t old_path_in, mp_obj_t new_path_in) {
|
||||||
|
mp_obj_t args[2];
|
||||||
|
mp_vfs_mount_t *old_vfs = lookup_path(old_path_in, &args[0]);
|
||||||
|
mp_vfs_mount_t *new_vfs = lookup_path(new_path_in, &args[1]);
|
||||||
|
if (old_vfs != new_vfs) {
|
||||||
|
// can't rename across filesystems
|
||||||
|
mp_raise_OSError(MP_EPERM);
|
||||||
|
}
|
||||||
|
return mp_vfs_proxy_call(old_vfs, MP_QSTR_rename, 2, args);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(mp_vfs_rename_obj, mp_vfs_rename);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_rmdir(mp_obj_t path_in) {
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_rmdir, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_rmdir_obj, mp_vfs_rmdir);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_stat(mp_obj_t path_in) {
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_stat, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_stat_obj, mp_vfs_stat);
|
||||||
|
|
||||||
|
mp_obj_t mp_vfs_statvfs(mp_obj_t path_in) {
|
||||||
|
mp_obj_t path_out;
|
||||||
|
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
|
||||||
|
return mp_vfs_proxy_call(vfs, MP_QSTR_statvfs, 1, &path_out);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_statvfs_obj, mp_vfs_statvfs);
|
||||||
|
|
||||||
|
#endif // MICROPY_VFS
|
80
extmod/vfs.h
Normal file
80
extmod/vfs.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||||
|
#define MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||||
|
|
||||||
|
#include "py/lexer.h"
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
// return values of mp_vfs_lookup_path
|
||||||
|
// ROOT is 0 so that the default current directory is the root directory
|
||||||
|
#define MP_VFS_NONE ((mp_vfs_mount_t*)1)
|
||||||
|
#define MP_VFS_ROOT ((mp_vfs_mount_t*)0)
|
||||||
|
|
||||||
|
// constants for block protocol ioctl
|
||||||
|
#define BP_IOCTL_INIT (1)
|
||||||
|
#define BP_IOCTL_DEINIT (2)
|
||||||
|
#define BP_IOCTL_SYNC (3)
|
||||||
|
#define BP_IOCTL_SEC_COUNT (4)
|
||||||
|
#define BP_IOCTL_SEC_SIZE (5)
|
||||||
|
|
||||||
|
typedef struct _mp_vfs_mount_t {
|
||||||
|
const char *str; // mount point with leading /
|
||||||
|
size_t len;
|
||||||
|
mp_obj_t obj;
|
||||||
|
struct _mp_vfs_mount_t *next;
|
||||||
|
} mp_vfs_mount_t;
|
||||||
|
|
||||||
|
mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out);
|
||||||
|
mp_import_stat_t mp_vfs_import_stat(const char *path);
|
||||||
|
mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||||
|
mp_obj_t mp_vfs_umount(mp_obj_t mnt_in);
|
||||||
|
mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||||
|
mp_obj_t mp_vfs_chdir(mp_obj_t path_in);
|
||||||
|
mp_obj_t mp_vfs_getcwd(void);
|
||||||
|
mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args);
|
||||||
|
mp_obj_t mp_vfs_mkdir(mp_obj_t path_in);
|
||||||
|
mp_obj_t mp_vfs_remove(mp_obj_t path_in);
|
||||||
|
mp_obj_t mp_vfs_rename(mp_obj_t old_path_in, mp_obj_t new_path_in);
|
||||||
|
mp_obj_t mp_vfs_rmdir(mp_obj_t path_in);
|
||||||
|
mp_obj_t mp_vfs_stat(mp_obj_t path_in);
|
||||||
|
mp_obj_t mp_vfs_statvfs(mp_obj_t path_in);
|
||||||
|
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_KW(mp_vfs_mount_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_umount_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_KW(mp_vfs_open_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_chdir_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_vfs_listdir_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_mkdir_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_remove_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_2(mp_vfs_rename_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_rmdir_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_stat_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_statvfs_obj);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_EXTMOD_VFS_H
|
199
extmod/vfs_fat.c
199
extmod/vfs_fat.c
@ -28,40 +28,73 @@
|
|||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS_FAT
|
#if MICROPY_VFS_FAT
|
||||||
|
|
||||||
|
#if !MICROPY_VFS
|
||||||
|
#error "with MICROPY_VFS_FAT enabled, must also enable MICROPY_VFS"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "py/nlr.h"
|
#include "py/nlr.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "lib/fatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "lib/fatfs/diskio.h"
|
#include "extmod/vfs_fat.h"
|
||||||
#include "extmod/vfs_fat_file.h"
|
#include "lib/timeutils/timeutils.h"
|
||||||
#include "extmod/fsusermount.h"
|
|
||||||
#include "timeutils.h"
|
#if _MAX_SS == _MIN_SS
|
||||||
|
#define SECSIZE(fs) (_MIN_SS)
|
||||||
|
#else
|
||||||
|
#define SECSIZE(fs) ((fs)->ssize)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define mp_obj_fat_vfs_t fs_user_mount_t
|
#define mp_obj_fat_vfs_t fs_user_mount_t
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 2, 2, false);
|
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||||
mp_obj_fat_vfs_t *vfs = fatfs_mount_mkfs(n_args, args, (mp_map_t*)&mp_const_empty_map, false);
|
|
||||||
|
// create new object
|
||||||
|
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
|
||||||
vfs->base.type = type;
|
vfs->base.type = type;
|
||||||
|
vfs->flags = FSUSER_FREE_OBJ;
|
||||||
|
vfs->str = NULL;
|
||||||
|
vfs->len = 0;
|
||||||
|
vfs->fatfs.drv = vfs;
|
||||||
|
|
||||||
|
// load block protocol methods
|
||||||
|
mp_load_method(args[0], MP_QSTR_readblocks, vfs->readblocks);
|
||||||
|
mp_load_method_maybe(args[0], MP_QSTR_writeblocks, vfs->writeblocks);
|
||||||
|
mp_load_method_maybe(args[0], MP_QSTR_ioctl, vfs->u.ioctl);
|
||||||
|
if (vfs->u.ioctl[0] != MP_OBJ_NULL) {
|
||||||
|
// device supports new block protocol, so indicate it
|
||||||
|
vfs->flags |= FSUSER_HAVE_IOCTL;
|
||||||
|
} else {
|
||||||
|
// no ioctl method, so assume the device uses the old block protocol
|
||||||
|
mp_load_method_maybe(args[0], MP_QSTR_sync, vfs->u.old.sync);
|
||||||
|
mp_load_method(args[0], MP_QSTR_count, vfs->u.old.count);
|
||||||
|
}
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(vfs);
|
return MP_OBJ_FROM_PTR(vfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
|
STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
|
||||||
mp_obj_t args[] = {bdev_in, MP_OBJ_NEW_QSTR(MP_QSTR_mkfs)};
|
// create new object
|
||||||
fatfs_mount_mkfs(2, args, (mp_map_t*)&mp_const_empty_map, true);
|
fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, 0, &bdev_in));
|
||||||
|
|
||||||
|
// make the filesystem
|
||||||
|
uint8_t working_buf[_MAX_SS];
|
||||||
|
FRESULT res = f_mkfs(&vfs->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||||
|
if (res != FR_OK) {
|
||||||
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
|
}
|
||||||
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_mkfs_fun_obj, fat_vfs_mkfs);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_mkfs_fun_obj, fat_vfs_mkfs);
|
||||||
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(fat_vfs_mkfs_obj, MP_ROM_PTR(&fat_vfs_mkfs_fun_obj));
|
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(fat_vfs_mkfs_obj, MP_ROM_PTR(&fat_vfs_mkfs_fun_obj));
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fatfs_builtin_open_self);
|
||||||
// Skip self
|
|
||||||
return fatfs_builtin_open(n_args - 1, args + 1, kwargs);
|
|
||||||
}
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_KW(fat_vfs_open_obj, 2, fat_vfs_open);
|
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
|
||||||
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
bool is_str_type = true;
|
bool is_str_type = true;
|
||||||
const char *path;
|
const char *path;
|
||||||
if (n_args == 2) {
|
if (n_args == 2) {
|
||||||
@ -73,19 +106,16 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
|
|||||||
path = "";
|
path = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return fat_vfs_listdir(path, is_str_type);
|
return fat_vfs_listdir2(self, path, is_str_type);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func);
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
|
STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_int_t attr) {
|
||||||
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
const char *path = mp_obj_str_get_str(path_in);
|
const char *path = mp_obj_str_get_str(path_in);
|
||||||
|
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
FRESULT res = f_stat(&self->fatfs, path, &fno);
|
||||||
fno.lfname = NULL;
|
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
FRESULT res = f_stat(path, &fno);
|
|
||||||
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
@ -93,7 +123,7 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
|
|||||||
|
|
||||||
// check if path is a file or directory
|
// check if path is a file or directory
|
||||||
if ((fno.fattrib & AM_DIR) == attr) {
|
if ((fno.fattrib & AM_DIR) == attr) {
|
||||||
res = f_unlink(path);
|
res = f_unlink(&self->fatfs, path);
|
||||||
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
@ -105,27 +135,25 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) {
|
STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||||
(void)vfs_in;
|
return fat_vfs_remove_internal(vfs_in, path_in, 0); // 0 == file attribute
|
||||||
return fat_vfs_remove_internal(path_in, 0); // 0 == file attribute
|
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove);
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_rmdir(mp_obj_t vfs_in, mp_obj_t path_in) {
|
STATIC mp_obj_t fat_vfs_rmdir(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||||
(void) vfs_in;
|
return fat_vfs_remove_internal(vfs_in, path_in, AM_DIR);
|
||||||
return fat_vfs_remove_internal(path_in, AM_DIR);
|
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir);
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_out) {
|
STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_out) {
|
||||||
(void)vfs_in;
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
const char *old_path = mp_obj_str_get_str(path_in);
|
const char *old_path = mp_obj_str_get_str(path_in);
|
||||||
const char *new_path = mp_obj_str_get_str(path_out);
|
const char *new_path = mp_obj_str_get_str(path_out);
|
||||||
FRESULT res = f_rename(old_path, new_path);
|
FRESULT res = f_rename(&self->fatfs, old_path, new_path);
|
||||||
if (res == FR_EXIST) {
|
if (res == FR_EXIST) {
|
||||||
// if new_path exists then try removing it (but only if it's a file)
|
// if new_path exists then try removing it (but only if it's a file)
|
||||||
fat_vfs_remove_internal(path_out, 0); // 0 == file attribute
|
fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute
|
||||||
// try to rename again
|
// try to rename again
|
||||||
res = f_rename(old_path, new_path);
|
res = f_rename(&self->fatfs, old_path, new_path);
|
||||||
}
|
}
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
@ -137,9 +165,9 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
|
|||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_rename_obj, fat_vfs_rename);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_rename_obj, fat_vfs_rename);
|
||||||
|
|
||||||
STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
|
STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
|
||||||
(void)vfs_in;
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
const char *path = mp_obj_str_get_str(path_o);
|
const char *path = mp_obj_str_get_str(path_o);
|
||||||
FRESULT res = f_mkdir(path);
|
FRESULT res = f_mkdir(&self->fatfs, path);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
} else {
|
} else {
|
||||||
@ -150,15 +178,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir);
|
|||||||
|
|
||||||
/// Change current directory.
|
/// Change current directory.
|
||||||
STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) {
|
STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||||
(void)vfs_in;
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
const char *path;
|
const char *path;
|
||||||
path = mp_obj_str_get_str(path_in);
|
path = mp_obj_str_get_str(path_in);
|
||||||
|
|
||||||
FRESULT res = f_chdrive(path);
|
FRESULT res = f_chdir(&self->fatfs, path);
|
||||||
|
|
||||||
if (res == FR_OK) {
|
|
||||||
res = f_chdir(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
@ -170,71 +194,31 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_chdir_obj, fat_vfs_chdir);
|
|||||||
|
|
||||||
/// Get the current directory.
|
/// Get the current directory.
|
||||||
STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
|
STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
|
||||||
(void)vfs_in;
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
||||||
FRESULT res = f_getcwd(buf, sizeof buf);
|
FRESULT res = f_getcwd(&self->fatfs, buf, sizeof(buf));
|
||||||
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mp_obj_new_str(buf, strlen(buf), false);
|
return mp_obj_new_str(buf, strlen(buf), false);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);
|
||||||
|
|
||||||
// Checks for path equality, ignoring trailing slashes:
|
|
||||||
// path_equal(/, /) -> true
|
|
||||||
// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
|
|
||||||
STATIC bool path_equal(const char *path, const char *path_canonical) {
|
|
||||||
while (*path_canonical != '\0' && *path == *path_canonical) {
|
|
||||||
++path;
|
|
||||||
++path_canonical;
|
|
||||||
}
|
|
||||||
if (*path_canonical != '\0') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
while (*path == '/') {
|
|
||||||
++path;
|
|
||||||
}
|
|
||||||
return *path == '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \function stat(path)
|
/// \function stat(path)
|
||||||
/// Get the status of a file or directory.
|
/// Get the status of a file or directory.
|
||||||
STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
|
STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||||
(void)vfs_in;
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
const char *path = mp_obj_str_get_str(path_in);
|
const char *path = mp_obj_str_get_str(path_in);
|
||||||
|
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
if (path[0] == 0 || (path[0] == '/' && path[1] == 0)) {
|
||||||
fno.lfname = NULL;
|
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
FRESULT res;
|
|
||||||
|
|
||||||
if (path_equal(path, "/")) {
|
|
||||||
// stat root directory
|
// stat root directory
|
||||||
fno.fsize = 0;
|
fno.fsize = 0;
|
||||||
fno.fdate = 0x2821; // Jan 1, 2000
|
fno.fdate = 0x2821; // Jan 1, 2000
|
||||||
fno.ftime = 0;
|
fno.ftime = 0;
|
||||||
fno.fattrib = AM_DIR;
|
fno.fattrib = AM_DIR;
|
||||||
} else {
|
} else {
|
||||||
res = FR_NO_PATH;
|
FRESULT res = f_stat(&self->fatfs, path, &fno);
|
||||||
for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
|
||||||
if (vfs != NULL && path_equal(path, vfs->str)) {
|
|
||||||
// stat mounted device directory
|
|
||||||
fno.fsize = 0;
|
|
||||||
fno.fdate = 0x2821; // Jan 1, 2000
|
|
||||||
fno.ftime = 0;
|
|
||||||
fno.fattrib = AM_DIR;
|
|
||||||
res = FR_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (res == FR_NO_PATH) {
|
|
||||||
// stat normal file
|
|
||||||
res = f_stat(path, &fno);
|
|
||||||
}
|
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
}
|
}
|
||||||
@ -272,19 +256,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
|
|||||||
|
|
||||||
// Get the status of a VFS.
|
// Get the status of a VFS.
|
||||||
STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
|
STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||||
(void)vfs_in;
|
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||||
const char *path = mp_obj_str_get_str(path_in);
|
(void)path_in;
|
||||||
|
|
||||||
FATFS *fatfs;
|
|
||||||
DWORD nclst;
|
DWORD nclst;
|
||||||
FRESULT res = f_getfree(path, &nclst, &fatfs);
|
FATFS *fatfs = &self->fatfs;
|
||||||
|
FRESULT res = f_getfree(fatfs, &nclst);
|
||||||
if (FR_OK != res) {
|
if (FR_OK != res) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
|
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
|
||||||
|
|
||||||
t->items[0] = MP_OBJ_NEW_SMALL_INT(fatfs->csize * fatfs->ssize); // f_bsize
|
t->items[0] = MP_OBJ_NEW_SMALL_INT(fatfs->csize * SECSIZE(fatfs)); // f_bsize
|
||||||
t->items[1] = t->items[0]; // f_frsize
|
t->items[1] = t->items[0]; // f_frsize
|
||||||
t->items[2] = MP_OBJ_NEW_SMALL_INT((fatfs->n_fatent - 2) * fatfs->csize); // f_blocks
|
t->items[2] = MP_OBJ_NEW_SMALL_INT((fatfs->n_fatent - 2) * fatfs->csize); // f_blocks
|
||||||
t->items[3] = MP_OBJ_NEW_SMALL_INT(nclst); // f_bfree
|
t->items[3] = MP_OBJ_NEW_SMALL_INT(nclst); // f_bfree
|
||||||
@ -299,12 +283,42 @@ STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_statvfs_obj, fat_vfs_statvfs);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_statvfs_obj, fat_vfs_statvfs);
|
||||||
|
|
||||||
// Unmount the filesystem
|
STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs) {
|
||||||
STATIC mp_obj_t fat_vfs_umount(mp_obj_t vfs_in) {
|
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
fatfs_umount(((fs_user_mount_t *)vfs_in)->readblocks[1]);
|
|
||||||
|
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
||||||
|
// User can specify read-only device by:
|
||||||
|
// 1. readonly=True keyword argument
|
||||||
|
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
||||||
|
if (mp_obj_is_true(readonly)) {
|
||||||
|
self->writeblocks[0] = MP_OBJ_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mount the block device
|
||||||
|
FRESULT res = f_mount(&self->fatfs);
|
||||||
|
|
||||||
|
// check if we need to make the filesystem
|
||||||
|
if (res == FR_NO_FILESYSTEM && mp_obj_is_true(mkfs)) {
|
||||||
|
uint8_t working_buf[_MAX_SS];
|
||||||
|
res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||||
|
}
|
||||||
|
if (res != FR_OK) {
|
||||||
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
|
}
|
||||||
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, fat_vfs_umount);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(vfs_fat_mount_obj, vfs_fat_mount);
|
||||||
|
|
||||||
|
STATIC mp_obj_t vfs_fat_umount(mp_obj_t self_in) {
|
||||||
|
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
FRESULT res = f_umount(&self->fatfs);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount);
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
|
||||||
@ -318,6 +332,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&fat_vfs_rename_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&fat_vfs_stat_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_fat_mount_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 Damien P. George
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -24,18 +24,16 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "py/lexer.h"
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "lib/oofatfs/ff.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
// these are the values for fs_user_mount_t.flags
|
// these are the values for fs_user_mount_t.flags
|
||||||
#define FSUSER_NATIVE (0x0001) // readblocks[2]/writeblocks[2] contain native func
|
#define FSUSER_NATIVE (0x0001) // readblocks[2]/writeblocks[2] contain native func
|
||||||
#define FSUSER_FREE_OBJ (0x0002) // fs_user_mount_t obj should be freed on umount
|
#define FSUSER_FREE_OBJ (0x0002) // fs_user_mount_t obj should be freed on umount
|
||||||
#define FSUSER_HAVE_IOCTL (0x0004) // new protocol with ioctl
|
#define FSUSER_HAVE_IOCTL (0x0004) // new protocol with ioctl
|
||||||
|
|
||||||
// constants for block protocol ioctl
|
|
||||||
#define BP_IOCTL_INIT (1)
|
|
||||||
#define BP_IOCTL_DEINIT (2)
|
|
||||||
#define BP_IOCTL_SYNC (3)
|
|
||||||
#define BP_IOCTL_SEC_COUNT (4)
|
|
||||||
#define BP_IOCTL_SEC_SIZE (5)
|
|
||||||
|
|
||||||
typedef struct _fs_user_mount_t {
|
typedef struct _fs_user_mount_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
const char *str;
|
const char *str;
|
||||||
@ -54,9 +52,11 @@ typedef struct _fs_user_mount_t {
|
|||||||
FATFS fatfs;
|
FATFS fatfs;
|
||||||
} fs_user_mount_t;
|
} fs_user_mount_t;
|
||||||
|
|
||||||
fs_user_mount_t *fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, bool mkfs);
|
extern const byte fresult_to_errno_table[20];
|
||||||
mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in);
|
extern const mp_obj_type_t mp_fat_vfs_type;
|
||||||
|
|
||||||
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mount_obj);
|
mp_import_stat_t fat_vfs_import_stat(struct _fs_user_mount_t *vfs, const char *path);
|
||||||
MP_DECLARE_CONST_FUN_OBJ_1(fsuser_umount_obj);
|
mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode);
|
||||||
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj);
|
MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj);
|
||||||
|
|
||||||
|
mp_obj_t fat_vfs_listdir2(struct _fs_user_mount_t *vfs, const char *path, bool is_str_type);
|
@ -28,7 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_FSUSERMOUNT
|
#if MICROPY_VFS
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -36,9 +36,9 @@
|
|||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "lib/fatfs/ff.h" /* FatFs lower layer API */
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
|
#include "lib/oofatfs/diskio.h"
|
||||||
#include "extmod/fsusermount.h"
|
#include "extmod/vfs_fat.h"
|
||||||
|
|
||||||
#if _MAX_SS == _MIN_SS
|
#if _MAX_SS == _MIN_SS
|
||||||
#define SECSIZE(fs) (_MIN_SS)
|
#define SECSIZE(fs) (_MIN_SS)
|
||||||
@ -46,20 +46,18 @@
|
|||||||
#define SECSIZE(fs) ((fs)->ssize)
|
#define SECSIZE(fs) ((fs)->ssize)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATIC fs_user_mount_t *disk_get_device(uint id) {
|
typedef void *bdev_t;
|
||||||
if (id < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
|
STATIC fs_user_mount_t *disk_get_device(void *bdev) {
|
||||||
return MP_STATE_PORT(fs_user_mount)[id];
|
return (fs_user_mount_t*)bdev;
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Initialize a Drive */
|
/* Initialize a Drive */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
STATIC
|
||||||
DSTATUS disk_initialize (
|
DSTATUS disk_initialize (
|
||||||
BYTE pdrv /* Physical drive nmuber (0..) */
|
bdev_t pdrv /* Physical drive nmuber (0..) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
fs_user_mount_t *vfs = disk_get_device(pdrv);
|
fs_user_mount_t *vfs = disk_get_device(pdrv);
|
||||||
@ -89,8 +87,9 @@ DSTATUS disk_initialize (
|
|||||||
/* Get Disk Status */
|
/* Get Disk Status */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
STATIC
|
||||||
DSTATUS disk_status (
|
DSTATUS disk_status (
|
||||||
BYTE pdrv /* Physical drive nmuber (0..) */
|
bdev_t pdrv /* Physical drive nmuber (0..) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
fs_user_mount_t *vfs = disk_get_device(pdrv);
|
fs_user_mount_t *vfs = disk_get_device(pdrv);
|
||||||
@ -110,7 +109,7 @@ DSTATUS disk_status (
|
|||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
DRESULT disk_read (
|
DRESULT disk_read (
|
||||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
bdev_t pdrv, /* Physical drive nmuber (0..) */
|
||||||
BYTE *buff, /* Data buffer to store read data */
|
BYTE *buff, /* Data buffer to store read data */
|
||||||
DWORD sector, /* Sector address (LBA) */
|
DWORD sector, /* Sector address (LBA) */
|
||||||
UINT count /* Number of sectors to read (1..128) */
|
UINT count /* Number of sectors to read (1..128) */
|
||||||
@ -140,9 +139,8 @@ DRESULT disk_read (
|
|||||||
/* Write Sector(s) */
|
/* Write Sector(s) */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if _USE_WRITE
|
|
||||||
DRESULT disk_write (
|
DRESULT disk_write (
|
||||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
bdev_t pdrv, /* Physical drive nmuber (0..) */
|
||||||
const BYTE *buff, /* Data to be written */
|
const BYTE *buff, /* Data to be written */
|
||||||
DWORD sector, /* Sector address (LBA) */
|
DWORD sector, /* Sector address (LBA) */
|
||||||
UINT count /* Number of sectors to write (1..128) */
|
UINT count /* Number of sectors to write (1..128) */
|
||||||
@ -172,16 +170,14 @@ DRESULT disk_write (
|
|||||||
|
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Miscellaneous Functions */
|
/* Miscellaneous Functions */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if _USE_IOCTL
|
|
||||||
DRESULT disk_ioctl (
|
DRESULT disk_ioctl (
|
||||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
bdev_t pdrv, /* Physical drive nmuber (0..) */
|
||||||
BYTE cmd, /* Control code */
|
BYTE cmd, /* Control code */
|
||||||
void *buff /* Buffer to send/receive control data */
|
void *buff /* Buffer to send/receive control data */
|
||||||
)
|
)
|
||||||
@ -218,6 +214,10 @@ DRESULT disk_ioctl (
|
|||||||
} else {
|
} else {
|
||||||
*((WORD*)buff) = mp_obj_get_int(ret);
|
*((WORD*)buff) = mp_obj_get_int(ret);
|
||||||
}
|
}
|
||||||
|
#if _MAX_SS != _MIN_SS
|
||||||
|
// need to store ssize because we use it in disk_read/disk_write
|
||||||
|
vfs->fatfs.ssize = *((WORD*)buff);
|
||||||
|
#endif
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +225,14 @@ DRESULT disk_ioctl (
|
|||||||
*((DWORD*)buff) = 1; // erase block size in units of sector size
|
*((DWORD*)buff) = 1; // erase block size in units of sector size
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|
||||||
|
case IOCTL_INIT:
|
||||||
|
*((DSTATUS*)buff) = disk_initialize(pdrv);
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
|
case IOCTL_STATUS:
|
||||||
|
*((DSTATUS*)buff) = disk_status(pdrv);
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
}
|
}
|
||||||
@ -245,17 +253,28 @@ DRESULT disk_ioctl (
|
|||||||
|
|
||||||
case GET_SECTOR_SIZE:
|
case GET_SECTOR_SIZE:
|
||||||
*((WORD*)buff) = 512; // old protocol had fixed sector size
|
*((WORD*)buff) = 512; // old protocol had fixed sector size
|
||||||
|
#if _MAX_SS != _MIN_SS
|
||||||
|
// need to store ssize because we use it in disk_read/disk_write
|
||||||
|
vfs->fatfs.ssize = 512;
|
||||||
|
#endif
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|
||||||
case GET_BLOCK_SIZE:
|
case GET_BLOCK_SIZE:
|
||||||
*((DWORD*)buff) = 1; // erase block size in units of sector size
|
*((DWORD*)buff) = 1; // erase block size in units of sector size
|
||||||
return RES_OK;
|
return RES_OK;
|
||||||
|
|
||||||
|
case IOCTL_INIT:
|
||||||
|
*((DSTATUS*)buff) = disk_initialize(pdrv);
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
|
case IOCTL_STATUS:
|
||||||
|
*((DSTATUS*)buff) = disk_status(pdrv);
|
||||||
|
return RES_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_FSUSERMOUNT
|
#endif // MICROPY_VFS
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
|
||||||
*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
|
||||||
#if MICROPY_FSUSERMOUNT
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/mpstate.h"
|
|
||||||
#include "lib/fatfs/ff.h"
|
|
||||||
#include "lib/fatfs/ffconf.h"
|
|
||||||
#include "lib/fatfs/diskio.h"
|
|
||||||
#include "extmod/fsusermount.h"
|
|
||||||
|
|
||||||
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
|
||||||
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
|
||||||
if ((*path)[mount_point_len] == '/') {
|
|
||||||
*path += mount_point_len;
|
|
||||||
return true;
|
|
||||||
} else if ((*path)[mount_point_len] == '\0') {
|
|
||||||
*path = "/";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// "path" is the path to lookup; will advance this pointer beyond the volume name.
|
|
||||||
// Returns logical drive number (-1 means invalid path).
|
|
||||||
int ff_get_ldnumber (const TCHAR **path) {
|
|
||||||
if (!(*path)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (**path != '/') {
|
|
||||||
#if _FS_RPATH
|
|
||||||
return ff_CurrVol;
|
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
|
|
||||||
if (vfs != NULL && check_path(path, vfs->str, vfs->len)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ff_get_volname(BYTE vol, TCHAR **dest) {
|
|
||||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[vol];
|
|
||||||
memcpy(*dest, vfs->str, vfs->len);
|
|
||||||
*dest += vfs->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MICROPY_FSUSERMOUNT
|
|
@ -25,9 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
// *_ADHOC part is for cc3200 port which doesn't use general uPy
|
#if MICROPY_VFS
|
||||||
// infrastructure and instead duplicates code. TODO: Resolve.
|
|
||||||
#if MICROPY_FSUSERMOUNT || MICROPY_FSUSERMOUNT_ADHOC
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -36,8 +34,8 @@
|
|||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/stream.h"
|
#include "py/stream.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "lib/fatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "extmod/vfs_fat_file.h"
|
#include "extmod/vfs_fat.h"
|
||||||
|
|
||||||
#if MICROPY_VFS_FAT
|
#if MICROPY_VFS_FAT
|
||||||
#define mp_type_fileio fatfs_type_fileio
|
#define mp_type_fileio fatfs_type_fileio
|
||||||
@ -112,7 +110,7 @@ STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t siz
|
|||||||
STATIC mp_obj_t file_obj_close(mp_obj_t self_in) {
|
STATIC mp_obj_t file_obj_close(mp_obj_t self_in) {
|
||||||
pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
// if fs==NULL then the file is closed and in that case this method is a no-op
|
// if fs==NULL then the file is closed and in that case this method is a no-op
|
||||||
if (self->fp.fs != NULL) {
|
if (self->fp.obj.fs != NULL) {
|
||||||
FRESULT res = f_close(&self->fp);
|
FRESULT res = f_close(&self->fp);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
@ -178,7 +176,7 @@ STATIC const mp_arg_t file_open_args[] = {
|
|||||||
};
|
};
|
||||||
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
||||||
|
|
||||||
STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
|
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
||||||
// TODO make sure only one of r, w, x, a, and b, t are specified
|
// TODO make sure only one of r, w, x, a, and b, t are specified
|
||||||
@ -214,7 +212,8 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
|
|||||||
o->base.type = type;
|
o->base.type = type;
|
||||||
|
|
||||||
const char *fname = mp_obj_str_get_str(args[0].u_obj);
|
const char *fname = mp_obj_str_get_str(args[0].u_obj);
|
||||||
FRESULT res = f_open(&o->fp, fname, mode);
|
assert(vfs != NULL);
|
||||||
|
FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
m_del_obj(pyb_file_obj_t, o);
|
m_del_obj(pyb_file_obj_t, o);
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
@ -231,7 +230,7 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
|
|||||||
STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
||||||
mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
|
mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
|
||||||
return file_open(type, arg_vals);
|
return file_open(NULL, type, arg_vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO gc hook to close the file if not already closed
|
// TODO gc hook to close the file if not already closed
|
||||||
@ -291,11 +290,14 @@ const mp_obj_type_t mp_type_textio = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Factory function for I/O stream classes
|
// Factory function for I/O stream classes
|
||||||
mp_obj_t fatfs_builtin_open(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode) {
|
||||||
// TODO: analyze buffering args and instantiate appropriate type
|
// TODO: analyze buffering args and instantiate appropriate type
|
||||||
|
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
|
||||||
mp_arg_parse_all(n_args, args, kwargs, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
|
arg_vals[0].u_obj = path;
|
||||||
return file_open(&mp_type_textio, arg_vals);
|
arg_vals[1].u_obj = mode;
|
||||||
|
arg_vals[2].u_obj = mp_const_none;
|
||||||
|
return file_open(self, &mp_type_textio, arg_vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MICROPY_FSUSERMOUNT
|
#endif // MICROPY_VFS
|
||||||
|
@ -25,34 +25,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
// *_ADHOC part is for cc3200 port which doesn't use general uPy
|
#if MICROPY_VFS_FAT
|
||||||
// infrastructure and instead duplicates code. TODO: Resolve.
|
|
||||||
#if MICROPY_VFS_FAT || MICROPY_FSUSERMOUNT || MICROPY_FSUSERMOUNT_ADHOC
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "py/nlr.h"
|
#include "py/nlr.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "lib/fatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "lib/fatfs/diskio.h"
|
#include "extmod/vfs_fat.h"
|
||||||
#include "extmod/vfs_fat_file.h"
|
|
||||||
#include "extmod/fsusermount.h"
|
|
||||||
#include "py/lexer.h"
|
#include "py/lexer.h"
|
||||||
|
|
||||||
#if _USE_LFN
|
|
||||||
STATIC char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: actually, the core function should be ilistdir()
|
// TODO: actually, the core function should be ilistdir()
|
||||||
mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type) {
|
|
||||||
|
mp_obj_t fat_vfs_listdir2(fs_user_mount_t *vfs, const char *path, bool is_str_type) {
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
DIR dir;
|
FF_DIR dir;
|
||||||
#if _USE_LFN
|
|
||||||
fno.lfname = lfn;
|
|
||||||
fno.lfsize = sizeof lfn;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
res = f_opendir(&dir, path); /* Open the directory */
|
res = f_opendir(&vfs->fatfs, &dir, path);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||||
}
|
}
|
||||||
@ -65,11 +54,7 @@ mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type) {
|
|||||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||||
|
|
||||||
#if _USE_LFN
|
|
||||||
char *fn = *fno.lfname ? fno.lfname : fno.fname;
|
|
||||||
#else
|
|
||||||
char *fn = fno.fname;
|
char *fn = fno.fname;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (fno.fattrib & AM_DIR) {
|
if (fno.fattrib & AM_DIR) {
|
||||||
@ -96,15 +81,10 @@ mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type) {
|
|||||||
return dir_list;
|
return dir_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_import_stat_t fat_vfs_import_stat(const char *path);
|
mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) {
|
||||||
|
|
||||||
mp_import_stat_t fat_vfs_import_stat(const char *path) {
|
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
assert(vfs != NULL);
|
||||||
fno.lfname = NULL;
|
FRESULT res = f_stat(&vfs->fatfs, path, &fno);
|
||||||
fno.lfsize = 0;
|
|
||||||
#endif
|
|
||||||
FRESULT res = f_stat(path, &fno);
|
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
if ((fno.fattrib & AM_DIR) != 0) {
|
if ((fno.fattrib & AM_DIR) != 0) {
|
||||||
return MP_IMPORT_STAT_DIR;
|
return MP_IMPORT_STAT_DIR;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2016 Damien P. George
|
* Copyright (c) 2013-2017 Damien P. George
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -25,64 +25,74 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "py/mperrno.h"
|
#include "py/nlr.h"
|
||||||
|
#include "py/stream.h"
|
||||||
#include "py/reader.h"
|
#include "py/reader.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
#if MICROPY_READER_FATFS
|
#if MICROPY_READER_VFS
|
||||||
|
|
||||||
#include "lib/fatfs/ff.h"
|
typedef struct _mp_reader_vfs_t {
|
||||||
#include "extmod/vfs_fat_file.h"
|
mp_obj_t file;
|
||||||
|
|
||||||
typedef struct _mp_reader_fatfs_t {
|
|
||||||
FIL fp;
|
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint16_t pos;
|
uint16_t pos;
|
||||||
byte buf[20];
|
byte buf[24];
|
||||||
} mp_reader_fatfs_t;
|
} mp_reader_vfs_t;
|
||||||
|
|
||||||
STATIC mp_uint_t mp_reader_fatfs_readbyte(void *data) {
|
STATIC mp_uint_t mp_reader_vfs_readbyte(void *data) {
|
||||||
mp_reader_fatfs_t *reader = (mp_reader_fatfs_t*)data;
|
mp_reader_vfs_t *reader = (mp_reader_vfs_t*)data;
|
||||||
if (reader->pos >= reader->len) {
|
if (reader->pos >= reader->len) {
|
||||||
if (reader->len < sizeof(reader->buf)) {
|
if (reader->len < sizeof(reader->buf)) {
|
||||||
return MP_READER_EOF;
|
return MP_READER_EOF;
|
||||||
} else {
|
} else {
|
||||||
UINT n;
|
int errcode;
|
||||||
f_read(&reader->fp, reader->buf, sizeof(reader->buf), &n);
|
reader->len = mp_stream_rw(reader->file, reader->buf, sizeof(reader->buf),
|
||||||
if (n == 0) {
|
&errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
||||||
|
if (errcode != 0) {
|
||||||
|
// TODO handle errors properly
|
||||||
|
return MP_READER_EOF;
|
||||||
|
}
|
||||||
|
if (reader->len == 0) {
|
||||||
return MP_READER_EOF;
|
return MP_READER_EOF;
|
||||||
}
|
}
|
||||||
reader->len = n;
|
|
||||||
reader->pos = 0;
|
reader->pos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reader->buf[reader->pos++];
|
return reader->buf[reader->pos++];
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void mp_reader_fatfs_close(void *data) {
|
STATIC void mp_reader_vfs_close(void *data) {
|
||||||
mp_reader_fatfs_t *reader = (mp_reader_fatfs_t*)data;
|
mp_reader_vfs_t *reader = (mp_reader_vfs_t*)data;
|
||||||
f_close(&reader->fp);
|
mp_stream_close(reader->file);
|
||||||
m_del_obj(mp_reader_fatfs_t, reader);
|
m_del_obj(mp_reader_vfs_t, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
|
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
|
||||||
mp_reader_fatfs_t *rf = m_new_obj_maybe(mp_reader_fatfs_t);
|
mp_reader_vfs_t *rf = m_new_obj_maybe(mp_reader_vfs_t);
|
||||||
if (rf == NULL) {
|
if (rf == NULL) {
|
||||||
return MP_ENOMEM;
|
return MP_ENOMEM;
|
||||||
}
|
}
|
||||||
FRESULT res = f_open(&rf->fp, filename, FA_READ);
|
// TODO we really should just let this function raise a uPy exception
|
||||||
if (res != FR_OK) {
|
nlr_buf_t nlr;
|
||||||
return fresult_to_errno_table[res];
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false);
|
||||||
|
rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map);
|
||||||
|
int errcode;
|
||||||
|
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
||||||
|
nlr_pop();
|
||||||
|
if (errcode != 0) {
|
||||||
|
return errcode;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return MP_ENOENT; // assume error was "file not found"
|
||||||
}
|
}
|
||||||
UINT n;
|
|
||||||
f_read(&rf->fp, rf->buf, sizeof(rf->buf), &n);
|
|
||||||
rf->len = n;
|
|
||||||
rf->pos = 0;
|
rf->pos = 0;
|
||||||
reader->data = rf;
|
reader->data = rf;
|
||||||
reader->readbyte = mp_reader_fatfs_readbyte;
|
reader->readbyte = mp_reader_vfs_readbyte;
|
||||||
reader->close = mp_reader_fatfs_close;
|
reader->close = mp_reader_vfs_close;
|
||||||
return 0; // success
|
return 0; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // MICROPY_READER_VFS
|
@ -1,21 +0,0 @@
|
|||||||
FatFs Module Source Files R0.11
|
|
||||||
|
|
||||||
|
|
||||||
FILES
|
|
||||||
|
|
||||||
00readme.txt This file.
|
|
||||||
history.txt Revision history.
|
|
||||||
ffconf.h Configuration file for FatFs module.
|
|
||||||
ff.h Common include file for FatFs and application module.
|
|
||||||
ff.c FatFs module.
|
|
||||||
diskio.h Common include file for FatFs and disk I/O module.
|
|
||||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
|
||||||
integer.h Integer type definitions for FatFs.
|
|
||||||
option Optional external functions.
|
|
||||||
|
|
||||||
|
|
||||||
Low level disk I/O module is not included in this archive because the FatFs
|
|
||||||
module is only a generic file system layer and not depend on any specific
|
|
||||||
storage device. You have to provide a low level disk I/O module that written
|
|
||||||
to control the target storage device.
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* If a working storage control module is available, it should be */
|
|
||||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
|
||||||
/* This is an example of glue functions to attach various exsisting */
|
|
||||||
/* storage control modules to the FatFs module with a defined API. */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "diskio.h" /* FatFs lower layer API */
|
|
||||||
#include "usbdisk.h" /* Example: Header file of existing USB MSD control module */
|
|
||||||
#include "atadrive.h" /* Example: Header file of existing ATA harddisk control module */
|
|
||||||
#include "sdcard.h" /* Example: Header file of existing MMC/SDC contorl module */
|
|
||||||
|
|
||||||
/* Definitions of physical drive number for each drive */
|
|
||||||
#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */
|
|
||||||
#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
|
||||||
#define USB 2 /* Example: Map USB MSD to physical drive 2 */
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get Drive Status */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_status (
|
|
||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DSTATUS stat;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case ATA :
|
|
||||||
result = ATA_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case MMC :
|
|
||||||
result = MMC_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case USB :
|
|
||||||
result = USB_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Inidialize a Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (
|
|
||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DSTATUS stat;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case ATA :
|
|
||||||
result = ATA_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case MMC :
|
|
||||||
result = MMC_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case USB :
|
|
||||||
result = USB_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_read (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
BYTE *buff, /* Data buffer to store read data */
|
|
||||||
DWORD sector, /* Sector address in LBA */
|
|
||||||
UINT count /* Number of sectors to read */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case ATA :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = ATA_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case MMC :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = MMC_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case USB :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = USB_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if _USE_WRITE
|
|
||||||
DRESULT disk_write (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
const BYTE *buff, /* Data to be written */
|
|
||||||
DWORD sector, /* Sector address in LBA */
|
|
||||||
UINT count /* Number of sectors to write */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case ATA :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = ATA_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case MMC :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = MMC_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case USB :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = USB_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Miscellaneous Functions */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if _USE_IOCTL
|
|
||||||
DRESULT disk_ioctl (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
|
||||||
BYTE cmd, /* Control code */
|
|
||||||
void *buff /* Buffer to send/receive control data */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case ATA :
|
|
||||||
|
|
||||||
// Process of the command for the ATA drive
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case MMC :
|
|
||||||
|
|
||||||
// Process of the command for the MMC/SD card
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case USB :
|
|
||||||
|
|
||||||
// Process of the command the USB drive
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------/
|
|
||||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
|
||||||
/-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _DISKIO_DEFINED
|
|
||||||
#define _DISKIO_DEFINED
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _USE_WRITE 1 /* 1: Enable disk_write function */
|
|
||||||
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
|
|
||||||
|
|
||||||
#include "integer.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Status of Disk Functions */
|
|
||||||
typedef BYTE DSTATUS;
|
|
||||||
|
|
||||||
/* Results of Disk Functions */
|
|
||||||
typedef enum {
|
|
||||||
RES_OK = 0, /* 0: Successful */
|
|
||||||
RES_ERROR, /* 1: R/W Error */
|
|
||||||
RES_WRPRT, /* 2: Write Protected */
|
|
||||||
RES_NOTRDY, /* 3: Not Ready */
|
|
||||||
RES_PARERR /* 4: Invalid Parameter */
|
|
||||||
} DRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------*/
|
|
||||||
/* Prototypes for disk control functions */
|
|
||||||
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (BYTE pdrv);
|
|
||||||
DSTATUS disk_status (BYTE pdrv);
|
|
||||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
|
||||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
|
||||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
|
||||||
|
|
||||||
/* Definitions of physical drive number for each media */
|
|
||||||
#define PD_FLASH (0) /* Map FLASH drive to drive number 0 */
|
|
||||||
#define PD_SDCARD (1) /* Map SDCARD drive to drive number 1 */
|
|
||||||
#define PD_USER (2) /* Map USER mounts to drive number 2 */
|
|
||||||
|
|
||||||
/* Disk Status Bits (DSTATUS) */
|
|
||||||
|
|
||||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
|
||||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
|
||||||
#define STA_PROTECT 0x04 /* Write protected */
|
|
||||||
|
|
||||||
|
|
||||||
/* Command code for disk_ioctrl fucntion */
|
|
||||||
|
|
||||||
/* Generic command (Used by FatFs) */
|
|
||||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
|
||||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
|
||||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
|
||||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
|
||||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
|
||||||
|
|
||||||
/* Generic command (Not used by FatFs) */
|
|
||||||
#define CTRL_POWER 5 /* Get/Set power status */
|
|
||||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
|
||||||
#define CTRL_EJECT 7 /* Eject media */
|
|
||||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
|
||||||
|
|
||||||
/* MMC/SDC specific ioctl command */
|
|
||||||
#define MMC_GET_TYPE 10 /* Get card type */
|
|
||||||
#define MMC_GET_CSD 11 /* Get CSD */
|
|
||||||
#define MMC_GET_CID 12 /* Get CID */
|
|
||||||
#define MMC_GET_OCR 13 /* Get OCR */
|
|
||||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
|
||||||
|
|
||||||
/* ATA/CF specific ioctl command */
|
|
||||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
|
||||||
#define ATA_GET_MODEL 21 /* Get model name */
|
|
||||||
#define ATA_GET_SN 22 /* Get serial number */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
4668
lib/fatfs/ff.c
4668
lib/fatfs/ff.c
File diff suppressed because it is too large
Load Diff
359
lib/fatfs/ff.h
359
lib/fatfs/ff.h
@ -1,359 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
|
|
||||||
/----------------------------------------------------------------------------/
|
|
||||||
/ FatFs module is a free software that opened under license policy of
|
|
||||||
/ following conditions.
|
|
||||||
/
|
|
||||||
/ Copyright (C) 2015, ChaN, all right reserved.
|
|
||||||
/
|
|
||||||
/ 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 32020 /* Revision ID */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "integer.h" /* Basic integer types */
|
|
||||||
#include "ffconf.h" /* FatFs configuration options */
|
|
||||||
#if _FATFS != _FFCONF
|
|
||||||
#error Wrong configuration file (ffconf.h).
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Definitions of volume management */
|
|
||||||
|
|
||||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
|
||||||
typedef struct {
|
|
||||||
BYTE pd; /* Physical drive number */
|
|
||||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
|
||||||
} PARTITION;
|
|
||||||
// dpgeorge: make the partition config table const
|
|
||||||
extern const PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
|
||||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
|
||||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
|
||||||
|
|
||||||
#else /* Single partition configuration */
|
|
||||||
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
|
|
||||||
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Type of path name strings on FatFs API */
|
|
||||||
|
|
||||||
#if _LFN_UNICODE /* Unicode string */
|
|
||||||
#if !_USE_LFN
|
|
||||||
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
|
||||||
#endif
|
|
||||||
#ifndef _INC_TCHAR
|
|
||||||
typedef WCHAR TCHAR;
|
|
||||||
#define _T(x) L ## x
|
|
||||||
#define _TEXT(x) L ## x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* ANSI/OEM string */
|
|
||||||
#ifndef _INC_TCHAR
|
|
||||||
typedef char TCHAR;
|
|
||||||
#define _T(x) x
|
|
||||||
#define _TEXT(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File system object structure (FATFS) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
|
||||||
BYTE drv; /* Physical drive number */
|
|
||||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
|
||||||
BYTE n_fats; /* Number of FAT copies (1 or 2) */
|
|
||||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
|
||||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
|
||||||
WORD id; /* File system mount ID */
|
|
||||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
|
||||||
#if _MAX_SS != _MIN_SS
|
|
||||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
|
||||||
#endif
|
|
||||||
#if _FS_REENTRANT
|
|
||||||
_SYNC_t sobj; /* Identifier of sync object */
|
|
||||||
#endif
|
|
||||||
#if !_FS_READONLY
|
|
||||||
DWORD last_clust; /* Last allocated cluster */
|
|
||||||
DWORD free_clust; /* Number of free clusters */
|
|
||||||
#endif
|
|
||||||
#if _FS_RPATH
|
|
||||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
|
||||||
#endif
|
|
||||||
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
|
|
||||||
DWORD fsize; /* Sectors per FAT */
|
|
||||||
DWORD volbase; /* Volume start sector */
|
|
||||||
DWORD fatbase; /* FAT start sector */
|
|
||||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
|
||||||
DWORD database; /* Data start sector */
|
|
||||||
DWORD winsect; /* Current sector appearing in the win[] */
|
|
||||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
|
||||||
} FATFS;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File object structure (FIL) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
|
|
||||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
|
||||||
BYTE flag; /* Status flags */
|
|
||||||
BYTE err; /* Abort flag (error code) */
|
|
||||||
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
|
|
||||||
DWORD fsize; /* File size */
|
|
||||||
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
|
|
||||||
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
|
|
||||||
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
|
|
||||||
#if !_FS_READONLY
|
|
||||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
|
||||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
|
||||||
#endif
|
|
||||||
#if _USE_FASTSEEK
|
|
||||||
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
|
|
||||||
#endif
|
|
||||||
#if _FS_LOCK
|
|
||||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
|
||||||
#endif
|
|
||||||
#if !_FS_TINY
|
|
||||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
|
||||||
#endif
|
|
||||||
} FIL;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Directory object structure (DIR) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
|
|
||||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
|
||||||
WORD index; /* Current read/write index number */
|
|
||||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
|
||||||
DWORD clust; /* Current cluster */
|
|
||||||
DWORD sect; /* Current sector */
|
|
||||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
|
||||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
|
||||||
#if _FS_LOCK
|
|
||||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
|
||||||
#endif
|
|
||||||
#if _USE_LFN
|
|
||||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
|
||||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
|
||||||
#endif
|
|
||||||
#if _USE_FIND
|
|
||||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
|
||||||
#endif
|
|
||||||
} DIR;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File information structure (FILINFO) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DWORD fsize; /* File size */
|
|
||||||
WORD fdate; /* Last modified date */
|
|
||||||
WORD ftime; /* Last modified time */
|
|
||||||
BYTE fattrib; /* Attribute */
|
|
||||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
|
||||||
#if _USE_LFN
|
|
||||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
|
||||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
|
||||||
#endif
|
|
||||||
} FILINFO;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File function return code (FRESULT) */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FR_OK = 0, /* (0) Succeeded */
|
|
||||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
|
||||||
FR_INT_ERR, /* (2) Assertion failed */
|
|
||||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
|
||||||
FR_NO_FILE, /* (4) Could not find the file */
|
|
||||||
FR_NO_PATH, /* (5) Could not find the path */
|
|
||||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
|
||||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
|
||||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
|
||||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
|
||||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
|
||||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
|
||||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
|
||||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
|
||||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
|
||||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
|
||||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
|
||||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
|
||||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
|
|
||||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
|
||||||
} FRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* FatFs module application interface */
|
|
||||||
|
|
||||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
|
||||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
|
||||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
|
|
||||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a 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, DWORD ofs); /* Move file pointer of a file object */
|
|
||||||
FRESULT f_truncate (FIL* fp); /* Truncate 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_closedir (DIR* dp); /* Close an open directory */
|
|
||||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
|
||||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
|
||||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
|
||||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
|
||||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
|
||||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
|
||||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
|
||||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */
|
|
||||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
|
|
||||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
|
||||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
|
||||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
|
||||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
|
||||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
|
||||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
|
||||||
FRESULT f_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_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */
|
|
||||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
|
||||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
|
||||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
|
||||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
|
||||||
|
|
||||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
|
|
||||||
#define f_error(fp) ((fp)->err)
|
|
||||||
#define f_tell(fp) ((fp)->fptr)
|
|
||||||
#define f_size(fp) ((fp)->fsize)
|
|
||||||
#define f_rewind(fp) f_lseek((fp), 0)
|
|
||||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
|
||||||
|
|
||||||
#ifndef EOF
|
|
||||||
#define EOF (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Additional user defined functions */
|
|
||||||
|
|
||||||
/* RTC function */
|
|
||||||
#if !_FS_READONLY && !_FS_NORTC
|
|
||||||
DWORD get_fattime (void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Unicode support functions */
|
|
||||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
|
||||||
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
|
||||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
|
||||||
#if _USE_LFN == 3 /* Memory functions */
|
|
||||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
|
||||||
void ff_memfree (void* mblock); /* Free memory block */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Sync functions */
|
|
||||||
#if _FS_REENTRANT
|
|
||||||
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
|
|
||||||
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
|
||||||
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
|
||||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// dpgeorge: added the following 3 declarations to support our volume names
|
|
||||||
|
|
||||||
// Current drive
|
|
||||||
extern BYTE ff_CurrVol;
|
|
||||||
|
|
||||||
// Returns logical drive number (-1:invalid drive)
|
|
||||||
int ff_get_ldnumber(const TCHAR** path);
|
|
||||||
|
|
||||||
// Store the volume name into dest, and advance the pointer
|
|
||||||
void ff_get_volname(BYTE vol, TCHAR **dest);
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Flags and offset address */
|
|
||||||
|
|
||||||
|
|
||||||
/* File access control and file status flags (FIL.flag) */
|
|
||||||
|
|
||||||
#define FA_READ 0x01
|
|
||||||
#define FA_OPEN_EXISTING 0x00
|
|
||||||
|
|
||||||
#if !_FS_READONLY
|
|
||||||
#define FA_WRITE 0x02
|
|
||||||
#define FA_CREATE_NEW 0x04
|
|
||||||
#define FA_CREATE_ALWAYS 0x08
|
|
||||||
#define FA_OPEN_ALWAYS 0x10
|
|
||||||
#define FA__WRITTEN 0x20
|
|
||||||
#define FA__DIRTY 0x40
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* FAT sub type (FATFS.fs_type) */
|
|
||||||
|
|
||||||
#define FS_FAT12 1
|
|
||||||
#define FS_FAT16 2
|
|
||||||
#define FS_FAT32 3
|
|
||||||
|
|
||||||
|
|
||||||
/* File attribute bits for directory entry */
|
|
||||||
|
|
||||||
#define AM_RDO 0x01 /* Read only */
|
|
||||||
#define AM_HID 0x02 /* Hidden */
|
|
||||||
#define AM_SYS 0x04 /* System */
|
|
||||||
#define AM_VOL 0x08 /* Volume label */
|
|
||||||
#define AM_LFN 0x0F /* LFN entry */
|
|
||||||
#define AM_DIR 0x10 /* Directory */
|
|
||||||
#define AM_ARC 0x20 /* Archive */
|
|
||||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
|
||||||
|
|
||||||
|
|
||||||
/* Fast seek feature */
|
|
||||||
#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
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _FATFS */
|
|
@ -1,180 +0,0 @@
|
|||||||
----------------------------------------------------------------------------
|
|
||||||
Revision history of FatFs module
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
R0.00 (February 26, 2006)
|
|
||||||
Prototype.
|
|
||||||
|
|
||||||
|
|
||||||
R0.01 (April 29, 2006)
|
|
||||||
First stable version.
|
|
||||||
|
|
||||||
|
|
||||||
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 error code.
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
@ -1,33 +0,0 @@
|
|||||||
/*-------------------------------------------*/
|
|
||||||
/* Integer type definitions for FatFs module */
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _FF_INTEGER
|
|
||||||
#define _FF_INTEGER
|
|
||||||
|
|
||||||
#ifdef _WIN32 /* FatFs development platform */
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
|
|
||||||
#else /* Embedded platform */
|
|
||||||
|
|
||||||
/* This type MUST be 8 bit */
|
|
||||||
typedef unsigned char BYTE;
|
|
||||||
|
|
||||||
/* These types MUST be 16 bit */
|
|
||||||
typedef short SHORT;
|
|
||||||
typedef unsigned short WORD;
|
|
||||||
typedef unsigned short WCHAR;
|
|
||||||
|
|
||||||
/* These types MUST be 16 bit or 32 bit */
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
|
|
||||||
/* These types MUST be 32 bit */
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
10973
lib/fatfs/option/cc936.c
10973
lib/fatfs/option/cc936.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,572 +0,0 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2012 */
|
|
||||||
/* (SBCS code pages) */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* 437 U.S. (OEM)
|
|
||||||
/ 720 Arabic (OEM)
|
|
||||||
/ 1256 Arabic (Windows)
|
|
||||||
/ 737 Greek (OEM)
|
|
||||||
/ 1253 Greek (Windows)
|
|
||||||
/ 1250 Central Europe (Windows)
|
|
||||||
/ 775 Baltic (OEM)
|
|
||||||
/ 1257 Baltic (Windows)
|
|
||||||
/ 850 Multilingual Latin 1 (OEM)
|
|
||||||
/ 852 Latin 2 (OEM)
|
|
||||||
/ 1252 Latin 1 (Windows)
|
|
||||||
/ 855 Cyrillic (OEM)
|
|
||||||
/ 1251 Cyrillic (Windows)
|
|
||||||
/ 866 Russian (OEM)
|
|
||||||
/ 857 Turkish (OEM)
|
|
||||||
/ 1254 Turkish (Windows)
|
|
||||||
/ 858 Multilingual Latin 1 + Euro (OEM)
|
|
||||||
/ 862 Hebrew (OEM)
|
|
||||||
/ 1255 Hebrew (Windows)
|
|
||||||
/ 874 Thai (OEM, Windows)
|
|
||||||
/ 1258 Vietnam (OEM, Windows)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../ff.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if _CODE_PAGE == 437
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
|
||||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
|
||||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
|
||||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
|
||||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
|
||||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
|
||||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
|
||||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 720
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
|
||||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
|
||||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
|
||||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
|
||||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
|
||||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
|
||||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
|
||||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
|
||||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
|
||||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248,
|
|
||||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 737
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
|
||||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
|
||||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
|
||||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
|
||||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
|
||||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
|
||||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
|
||||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
|
||||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
|
||||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
|
||||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 775
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
|
||||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
|
||||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
|
||||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
|
||||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
|
||||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
|
||||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
|
||||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
|
||||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
|
||||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
|
||||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 850
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
|
||||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
|
||||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
|
||||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
|
||||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
|
||||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
|
||||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
|
||||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
|
||||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 852
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
|
||||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
|
||||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
|
||||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
|
||||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
|
||||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
|
||||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
|
||||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
|
||||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
|
||||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 855
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
|
||||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
|
||||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
|
||||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
|
||||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
|
||||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
|
||||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
|
||||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
|
||||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
|
||||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
|
||||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
|
||||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 857
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
|
||||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
|
||||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
|
||||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
|
||||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
|
||||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
|
||||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
|
||||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
|
||||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 858
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
|
||||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
|
||||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
|
||||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
|
||||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
|
||||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 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 == 862
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
|
||||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
|
||||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
|
||||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
|
||||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
|
||||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
|
||||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
|
||||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
|
||||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 866
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
|
||||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
|
||||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
|
||||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
|
||||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
|
||||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
|
||||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
|
||||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
|
||||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
|
||||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
|
||||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
|
||||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 874
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
|
||||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
||||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
|
||||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
||||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
|
||||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
|
||||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
|
||||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
#if _TBLDEF && _USE_LFN
|
|
||||||
|
|
||||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
|
||||||
WCHAR chr, /* Character code to be converted */
|
|
||||||
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
WCHAR c;
|
|
||||||
|
|
||||||
|
|
||||||
if (chr < 0x80) { /* ASCII */
|
|
||||||
c = chr;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (dir) { /* OEMCP to Unicode */
|
|
||||||
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
|
||||||
|
|
||||||
} else { /* Unicode to OEMCP */
|
|
||||||
for (c = 0; c < 0x80; c++) {
|
|
||||||
if (chr == Tbl[c]) break;
|
|
||||||
}
|
|
||||||
c = (c + 0x80) & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WCHAR ff_wtoupper ( /* Upper converted character */
|
|
||||||
WCHAR chr /* Input character */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// dpgeorge: here we have a space optimised version of the original routine
|
|
||||||
|
|
||||||
static const WCHAR tbl_lower[] = {
|
|
||||||
0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF,
|
|
||||||
0xFF,
|
|
||||||
0x17A, 0x17C, 0x17E, 0x192,
|
|
||||||
0, // sentinel
|
|
||||||
};
|
|
||||||
|
|
||||||
static const WCHAR tbl_upper[] = {
|
|
||||||
0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3,
|
|
||||||
0x178,
|
|
||||||
0x179, 0x17B, 0x17D, 0x191,
|
|
||||||
};
|
|
||||||
|
|
||||||
if ((0x61 <= chr && chr <= 0x7a)
|
|
||||||
|| (0xe0 <= chr && chr <= 0xfe && chr != 0xf7)
|
|
||||||
|| (0x3b1 <= chr && chr <= 0x3ca && chr != 0x3c2)
|
|
||||||
|| (0x430 <= chr && chr <= 0x44f)
|
|
||||||
|| (0xff41 <= chr && chr <= 0xff5a)) {
|
|
||||||
return chr - 0x20;
|
|
||||||
}
|
|
||||||
if ((chr & 1) != 0
|
|
||||||
&& ((0x101 <= chr && chr <= 0x137)
|
|
||||||
|| (0x14b <= chr && chr <= 0x177))) {
|
|
||||||
return chr - 1;
|
|
||||||
}
|
|
||||||
if ((chr & 1) == 0 && 0x13a <= chr && chr <= 0x148) {
|
|
||||||
return chr - 1;
|
|
||||||
}
|
|
||||||
if (0x451 <= chr && chr <= 0x45f && chr != 0x45d) {
|
|
||||||
return chr - 0x50;
|
|
||||||
}
|
|
||||||
if (0x2170 <= chr && chr <= 0x217f) {
|
|
||||||
return chr - 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
|
||||||
|
|
||||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,151 +0,0 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Sample code of OS dependent controls for FatFs */
|
|
||||||
/* (C)ChaN, 2014 */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "../ff.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if _FS_REENTRANT
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Create a Synchronization Object
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called in f_mount() function to create a new
|
|
||||||
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
|
||||||
/ the f_mount() function fails with FR_INT_ERR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
|
|
||||||
BYTE vol, /* Corresponding logical drive being processed */
|
|
||||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
|
|
||||||
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
|
||||||
ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
|
|
||||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
|
||||||
|
|
||||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
|
||||||
// ret = (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
|
|
||||||
// ret = (int)(*sobj != NULL);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Delete a Synchronization Object */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called in f_mount() function to delete a synchronization
|
|
||||||
/ object that created with ff_cre_syncobj function. When a 0 is returned,
|
|
||||||
/ the f_mount() function fails with FR_INT_ERR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
|
|
||||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
|
|
||||||
ret = CloseHandle(sobj); /* Win32 */
|
|
||||||
|
|
||||||
// ret = 1; /* uITRON (nothing to do) */
|
|
||||||
|
|
||||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
|
||||||
// ret = (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
// vSemaphoreDelete(sobj); /* FreeRTOS */
|
|
||||||
// ret = 1;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Request Grant to Access the Volume */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called on entering file functions to lock the volume.
|
|
||||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
|
||||||
_SYNC_t sobj /* Sync object to wait */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
|
||||||
|
|
||||||
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
|
||||||
|
|
||||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
|
||||||
// ret = (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
// ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Release Grant to Access the Volume */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called on leaving file functions to unlock the volume.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ff_rel_grant (
|
|
||||||
_SYNC_t sobj /* Sync object to be signaled */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ReleaseMutex(sobj); /* Win32 */
|
|
||||||
|
|
||||||
// sig_sem(sobj); /* uITRON */
|
|
||||||
|
|
||||||
// OSMutexPost(sobj); /* uC/OS-II */
|
|
||||||
|
|
||||||
// xSemaphoreGive(sobj); /* FreeRTOS */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Allocate a memory block */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
|
||||||
UINT msize /* Number of bytes to allocate */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Free a memory block */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void ff_memfree (
|
|
||||||
void* mblock /* Pointer to the memory block to free */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
free(mblock); /* Discard the memory block with POSIX API */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,17 +0,0 @@
|
|||||||
#include "../ff.h"
|
|
||||||
|
|
||||||
#if _USE_LFN != 0
|
|
||||||
|
|
||||||
#if _CODE_PAGE == 932 /* Japanese Shift_JIS */
|
|
||||||
#include "cc932.c"
|
|
||||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
|
||||||
#include "cc936.c"
|
|
||||||
#elif _CODE_PAGE == 949 /* Korean */
|
|
||||||
#include "cc949.c"
|
|
||||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
|
||||||
#include "cc950.c"
|
|
||||||
#else /* Single Byte Character-Set */
|
|
||||||
#include "ccsbcs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
83
lib/oofatfs/diskio.h
Normal file
83
lib/oofatfs/diskio.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* This file is part of ooFatFs, a customised version of FatFs
|
||||||
|
* See https://github.com/micropython/oofatfs for details
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------/
|
||||||
|
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||||
|
/-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _DISKIO_DEFINED
|
||||||
|
#define _DISKIO_DEFINED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Status of Disk Functions */
|
||||||
|
typedef BYTE DSTATUS;
|
||||||
|
|
||||||
|
/* Results of Disk Functions */
|
||||||
|
typedef enum {
|
||||||
|
RES_OK = 0, /* 0: Successful */
|
||||||
|
RES_ERROR, /* 1: R/W Error */
|
||||||
|
RES_WRPRT, /* 2: Write Protected */
|
||||||
|
RES_NOTRDY, /* 3: Not Ready */
|
||||||
|
RES_PARERR /* 4: Invalid Parameter */
|
||||||
|
} DRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------*/
|
||||||
|
/* Prototypes for disk control functions */
|
||||||
|
|
||||||
|
|
||||||
|
DRESULT disk_read (void *drv, BYTE* buff, DWORD sector, UINT count);
|
||||||
|
DRESULT disk_write (void *drv, const BYTE* buff, DWORD sector, UINT count);
|
||||||
|
DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff);
|
||||||
|
|
||||||
|
|
||||||
|
/* Disk Status Bits (DSTATUS) */
|
||||||
|
|
||||||
|
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||||
|
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||||
|
#define STA_PROTECT 0x04 /* Write protected */
|
||||||
|
|
||||||
|
|
||||||
|
/* Command code for disk_ioctrl fucntion */
|
||||||
|
|
||||||
|
/* Generic command (Used by FatFs) */
|
||||||
|
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||||
|
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||||
|
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||||
|
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||||
|
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||||
|
#define IOCTL_INIT 5
|
||||||
|
#define IOCTL_STATUS 6
|
||||||
|
|
||||||
|
/* Generic command (Not used by FatFs) */
|
||||||
|
#define CTRL_POWER 5 /* Get/Set power status */
|
||||||
|
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||||
|
#define CTRL_EJECT 7 /* Eject media */
|
||||||
|
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||||
|
|
||||||
|
/* MMC/SDC specific ioctl command */
|
||||||
|
#define MMC_GET_TYPE 10 /* Get card type */
|
||||||
|
#define MMC_GET_CSD 11 /* Get CSD */
|
||||||
|
#define MMC_GET_CID 12 /* Get CID */
|
||||||
|
#define MMC_GET_OCR 13 /* Get OCR */
|
||||||
|
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||||
|
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||||
|
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||||
|
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||||
|
|
||||||
|
/* ATA/CF specific ioctl command */
|
||||||
|
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||||
|
#define ATA_GET_MODEL 21 /* Get model name */
|
||||||
|
#define ATA_GET_SN 22 /* Get serial number */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
5594
lib/oofatfs/ff.c
Normal file
5594
lib/oofatfs/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
380
lib/oofatfs/ff.h
Normal file
380
lib/oofatfs/ff.h
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
/* This file is part of ooFatFs, a customised version of FatFs
|
||||||
|
* See https://github.com/micropython/oofatfs for details
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------/
|
||||||
|
/ FatFs - Generic FAT file system module R0.12b /
|
||||||
|
/-----------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2016, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||||
|
/ source and binary forms, with or without modification, are permitted provided
|
||||||
|
/ that the following condition is met:
|
||||||
|
|
||||||
|
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
/ this condition and the following disclaimer.
|
||||||
|
/
|
||||||
|
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||||
|
/ and any warranties related to this software are DISCLAIMED.
|
||||||
|
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||||
|
/ by use of this software.
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _FATFS
|
||||||
|
#define _FATFS 68020 /* Revision ID */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* This type MUST be 8-bit */
|
||||||
|
typedef uint8_t BYTE;
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit */
|
||||||
|
typedef int16_t SHORT;
|
||||||
|
typedef uint16_t WORD;
|
||||||
|
typedef uint16_t WCHAR;
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit or 32-bit */
|
||||||
|
typedef int INT;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
|
||||||
|
/* These types MUST be 32-bit */
|
||||||
|
typedef int32_t LONG;
|
||||||
|
typedef uint32_t DWORD;
|
||||||
|
|
||||||
|
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
|
||||||
|
typedef uint64_t QWORD;
|
||||||
|
|
||||||
|
#include FFCONF_H /* FatFs configuration options */
|
||||||
|
|
||||||
|
#if _FATFS != _FFCONF
|
||||||
|
#error Wrong configuration file (ffconf.h).
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions of volume management */
|
||||||
|
|
||||||
|
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||||
|
#define LD2PT(fs) (fs->part) /* Get partition index */
|
||||||
|
#else /* Single partition configuration */
|
||||||
|
#define LD2PT(fs) 0 /* Find first valid partition or in SFD */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of path name strings on FatFs API */
|
||||||
|
|
||||||
|
#if _LFN_UNICODE /* Unicode (UTF-16) string */
|
||||||
|
#if _USE_LFN == 0
|
||||||
|
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||||
|
#endif
|
||||||
|
#ifndef _INC_TCHAR
|
||||||
|
typedef WCHAR TCHAR;
|
||||||
|
#define _T(x) L ## x
|
||||||
|
#define _TEXT(x) L ## x
|
||||||
|
#endif
|
||||||
|
#else /* ANSI/OEM string */
|
||||||
|
#ifndef _INC_TCHAR
|
||||||
|
typedef char TCHAR;
|
||||||
|
#define _T(x) x
|
||||||
|
#define _TEXT(x) x
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of file size variables */
|
||||||
|
|
||||||
|
#if _FS_EXFAT
|
||||||
|
#if _USE_LFN == 0
|
||||||
|
#error LFN must be enabled when enable exFAT
|
||||||
|
#endif
|
||||||
|
typedef QWORD FSIZE_t;
|
||||||
|
#else
|
||||||
|
typedef DWORD FSIZE_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File system object structure (FATFS) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *drv; // block device underlying this filesystem
|
||||||
|
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||||
|
BYTE part; // Partition: 0:Auto detect, 1-4:Forced partition
|
||||||
|
#endif
|
||||||
|
BYTE fs_type; /* File system type (0:N/A) */
|
||||||
|
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||||
|
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||||
|
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||||
|
WORD id; /* File system mount ID */
|
||||||
|
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||||
|
WORD csize; /* Cluster size [sectors] */
|
||||||
|
#if _MAX_SS != _MIN_SS
|
||||||
|
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||||
|
#endif
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
WCHAR* lfnbuf; /* LFN working buffer */
|
||||||
|
#endif
|
||||||
|
#if _FS_EXFAT
|
||||||
|
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
|
||||||
|
#endif
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
_SYNC_t sobj; /* Identifier of sync object */
|
||||||
|
#endif
|
||||||
|
#if !_FS_READONLY
|
||||||
|
DWORD last_clst; /* Last allocated cluster */
|
||||||
|
DWORD free_clst; /* Number of free clusters */
|
||||||
|
#endif
|
||||||
|
#if _FS_RPATH != 0
|
||||||
|
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||||
|
#if _FS_EXFAT
|
||||||
|
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||||
|
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||||
|
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||||
|
DWORD fsize; /* Size of an FAT [sectors] */
|
||||||
|
DWORD volbase; /* Volume base sector */
|
||||||
|
DWORD fatbase; /* FAT base sector */
|
||||||
|
DWORD dirbase; /* Root directory base sector/cluster */
|
||||||
|
DWORD database; /* Data base sector */
|
||||||
|
DWORD winsect; /* Current sector appearing in the win[] */
|
||||||
|
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Object ID and allocation information (_FDID) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FATFS* fs; /* Pointer to the owner file system object */
|
||||||
|
WORD id; /* Owner file system mount ID */
|
||||||
|
BYTE attr; /* Object attribute */
|
||||||
|
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */
|
||||||
|
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
|
||||||
|
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||||
|
#if _FS_EXFAT
|
||||||
|
DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */
|
||||||
|
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||||
|
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||||
|
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */
|
||||||
|
#endif
|
||||||
|
#if _FS_LOCK != 0
|
||||||
|
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||||
|
#endif
|
||||||
|
} _FDID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File object structure (FIL) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||||
|
BYTE flag; /* File status flags */
|
||||||
|
BYTE err; /* Abort flag (error code) */
|
||||||
|
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||||
|
DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */
|
||||||
|
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||||
|
#if !_FS_READONLY
|
||||||
|
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||||
|
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||||
|
#endif
|
||||||
|
#if _USE_FASTSEEK
|
||||||
|
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||||
|
#endif
|
||||||
|
#if !_FS_TINY
|
||||||
|
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||||
|
#endif
|
||||||
|
} FIL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Directory object structure (FF_DIR) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
_FDID obj; /* Object identifier */
|
||||||
|
DWORD dptr; /* Current read/write offset */
|
||||||
|
DWORD clust; /* Current cluster */
|
||||||
|
DWORD sect; /* Current sector */
|
||||||
|
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||||
|
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||||
|
#endif
|
||||||
|
#if _USE_FIND
|
||||||
|
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||||
|
#endif
|
||||||
|
} FF_DIR;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File information structure (FILINFO) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FSIZE_t fsize; /* File size */
|
||||||
|
WORD fdate; /* Modified date */
|
||||||
|
WORD ftime; /* Modified time */
|
||||||
|
BYTE fattrib; /* File attribute */
|
||||||
|
#if _USE_LFN != 0
|
||||||
|
TCHAR altname[13]; /* Altenative file name */
|
||||||
|
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
|
||||||
|
#else
|
||||||
|
TCHAR fname[13]; /* File name */
|
||||||
|
#endif
|
||||||
|
} FILINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File function return code (FRESULT) */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FR_OK = 0, /* (0) Succeeded */
|
||||||
|
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||||
|
FR_INT_ERR, /* (2) Assertion failed */
|
||||||
|
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||||
|
FR_NO_FILE, /* (4) Could not find the file */
|
||||||
|
FR_NO_PATH, /* (5) Could not find the path */
|
||||||
|
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||||
|
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||||
|
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||||
|
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||||
|
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||||
|
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||||
|
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||||
|
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||||
|
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||||
|
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||||
|
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||||
|
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||||
|
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
|
||||||
|
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||||
|
} FRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* FatFs module application interface */
|
||||||
|
|
||||||
|
FRESULT f_open (FATFS *fs, FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||||
|
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||||
|
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||||
|
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||||
|
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||||
|
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||||
|
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||||
|
FRESULT f_opendir (FATFS *fs, FF_DIR* dp, const TCHAR* path); /* Open a directory */
|
||||||
|
FRESULT f_closedir (FF_DIR* dp); /* Close an open directory */
|
||||||
|
FRESULT f_readdir (FF_DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||||
|
FRESULT f_findfirst (FF_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||||
|
FRESULT f_findnext (FF_DIR* dp, FILINFO* fno); /* Find next file */
|
||||||
|
FRESULT f_mkdir (FATFS *fs, const TCHAR* path); /* Create a sub directory */
|
||||||
|
FRESULT f_unlink (FATFS *fs, const TCHAR* path); /* Delete an existing file or directory */
|
||||||
|
FRESULT f_rename (FATFS *fs, const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||||
|
FRESULT f_stat (FATFS *fs, const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||||
|
FRESULT f_chmod (FATFS *fs, const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||||
|
FRESULT f_utime (FATFS *fs, const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||||
|
FRESULT f_chdir (FATFS *fs, const TCHAR* path); /* Change current directory */
|
||||||
|
FRESULT f_getcwd (FATFS *fs, TCHAR* buff, UINT len); /* Get current directory */
|
||||||
|
FRESULT f_getfree (FATFS *fs, DWORD* nclst); /* Get number of free clusters on the drive */
|
||||||
|
FRESULT f_getlabel (FATFS *fs, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||||
|
FRESULT f_setlabel (FATFS *fs, 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); /* Mount/Unmount a logical drive */
|
||||||
|
FRESULT f_umount (FATFS* fs); /* Unmount a logical drive */
|
||||||
|
FRESULT f_mkfs (FATFS *fs, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||||
|
FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||||
|
|
||||||
|
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||||
|
#define f_error(fp) ((fp)->err)
|
||||||
|
#define f_tell(fp) ((fp)->fptr)
|
||||||
|
#define f_size(fp) ((fp)->obj.objsize)
|
||||||
|
#define f_rewind(fp) f_lseek((fp), 0)
|
||||||
|
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||||
|
|
||||||
|
#ifndef EOF
|
||||||
|
#define EOF (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Additional user defined functions */
|
||||||
|
|
||||||
|
/* RTC function */
|
||||||
|
#if !_FS_READONLY && !_FS_NORTC
|
||||||
|
DWORD get_fattime (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Unicode support functions */
|
||||||
|
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
|
||||||
|
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||||
|
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||||
|
#if _USE_LFN == 3 /* Memory functions */
|
||||||
|
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||||
|
void ff_memfree (void* mblock); /* Free memory block */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sync functions */
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
int ff_cre_syncobj (FATFS *fatfs, _SYNC_t* sobj); /* Create a sync object */
|
||||||
|
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||||
|
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||||
|
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Flags and offset address */
|
||||||
|
|
||||||
|
|
||||||
|
/* File access mode and open method flags (3rd argument of f_open) */
|
||||||
|
#define FA_READ 0x01
|
||||||
|
#define FA_WRITE 0x02
|
||||||
|
#define FA_OPEN_EXISTING 0x00
|
||||||
|
#define FA_CREATE_NEW 0x04
|
||||||
|
#define FA_CREATE_ALWAYS 0x08
|
||||||
|
#define FA_OPEN_ALWAYS 0x10
|
||||||
|
#define FA_OPEN_APPEND 0x30
|
||||||
|
|
||||||
|
/* Fast seek controls (2nd argument of f_lseek) */
|
||||||
|
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||||
|
|
||||||
|
/* Format options (2nd argument of f_mkfs) */
|
||||||
|
#define FM_FAT 0x01
|
||||||
|
#define FM_FAT32 0x02
|
||||||
|
#define FM_EXFAT 0x04
|
||||||
|
#define FM_ANY 0x07
|
||||||
|
#define FM_SFD 0x08
|
||||||
|
|
||||||
|
/* Filesystem type (FATFS.fs_type) */
|
||||||
|
#define FS_FAT12 1
|
||||||
|
#define FS_FAT16 2
|
||||||
|
#define FS_FAT32 3
|
||||||
|
#define FS_EXFAT 4
|
||||||
|
|
||||||
|
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||||
|
#define AM_RDO 0x01 /* Read only */
|
||||||
|
#define AM_HID 0x02 /* Hidden */
|
||||||
|
#define AM_SYS 0x04 /* System */
|
||||||
|
#define AM_DIR 0x10 /* Directory */
|
||||||
|
#define AM_ARC 0x20 /* Archive */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FATFS */
|
@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of the Micro Python project, http://micropython.org/
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* Original file from:
|
* Original file from:
|
||||||
* FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
* FatFs - FAT file system module configuration file R0.12a (C)ChaN, 2016
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013, 2014 Damien P. George
|
* Copyright (c) 2013-2017 Damien P. George
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -27,44 +27,36 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _FFCONF
|
|
||||||
#define _FFCONF 32020 /* Revision ID */
|
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
/*---------------------------------------------------------------------------/
|
||||||
/ Functions and Buffer Configurations
|
/ FatFs - FAT file system module configuration file
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define _FS_TINY 1
|
#define _FFCONF 68020 /* Revision ID */
|
||||||
/* 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. */
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Function Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define _FS_READONLY 0
|
#define _FS_READONLY 0
|
||||||
/* 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 writing API functions, f_write(), f_sync(),
|
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||||
/ and optional writing functions as well. */
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
|
||||||
#define _FS_MINIMIZE 0
|
#define _FS_MINIMIZE 0
|
||||||
/* This option defines minimization level to remove some basic 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. */
|
||||||
|
|
||||||
|
|
||||||
#define _USE_STRFUNC 0
|
#define _USE_STRFUNC 0
|
||||||
/* 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().
|
||||||
/
|
/
|
||||||
@ -73,94 +65,112 @@
|
|||||||
/ 2: Enable with LF-CRLF conversion. */
|
/ 2: Enable with LF-CRLF conversion. */
|
||||||
|
|
||||||
|
|
||||||
#define _USE_FIND 0
|
#define _USE_FIND 0
|
||||||
/* This option switches filtered directory read feature and related functions,
|
/* This option switches filtered directory read functions, f_findfirst() and
|
||||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
/ 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) */
|
||||||
|
|
||||||
|
|
||||||
#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 1
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_USE_LABEL
|
#ifdef MICROPY_FATFS_USE_LABEL
|
||||||
#define _USE_LABEL (MICROPY_FATFS_USE_LABEL)
|
#define _USE_LABEL (MICROPY_FATFS_USE_LABEL)
|
||||||
#else
|
#else
|
||||||
#define _USE_LABEL 0
|
#define _USE_LABEL 0
|
||||||
#endif
|
#endif
|
||||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
/ (0:Disable or 1:Enable) */
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
#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
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_LFN_CODE_PAGE
|
#ifdef MICROPY_FATFS_LFN_CODE_PAGE
|
||||||
#define _CODE_PAGE (MICROPY_FATFS_LFN_CODE_PAGE)
|
#define _CODE_PAGE (MICROPY_FATFS_LFN_CODE_PAGE)
|
||||||
#else
|
#else
|
||||||
#define _CODE_PAGE 1
|
#define _CODE_PAGE 1
|
||||||
#endif
|
#endif
|
||||||
/* 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.
|
||||||
/
|
/
|
||||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||||
/ 437 - U.S.
|
/ 437 - U.S.
|
||||||
/ 720 - Arabic
|
/ 720 - Arabic
|
||||||
/ 737 - Greek
|
/ 737 - Greek
|
||||||
/ 775 - Baltic
|
/ 771 - KBL
|
||||||
/ 850 - Multilingual Latin 1
|
/ 775 - Baltic
|
||||||
/ 852 - Latin 2
|
/ 850 - Latin 1
|
||||||
/ 855 - Cyrillic
|
/ 852 - Latin 2
|
||||||
/ 857 - Turkish
|
/ 855 - Cyrillic
|
||||||
/ 858 - Multilingual Latin 1 + Euro
|
/ 857 - Turkish
|
||||||
/ 862 - Hebrew
|
/ 860 - Portuguese
|
||||||
/ 866 - Russian
|
/ 861 - Icelandic
|
||||||
/ 874 - Thai
|
/ 862 - Hebrew
|
||||||
/ 932 - Japanese Shift_JIS (DBCS)
|
/ 863 - Canadian French
|
||||||
/ 936 - Simplified Chinese GBK (DBCS)
|
/ 864 - Arabic
|
||||||
/ 949 - Korean (DBCS)
|
/ 865 - Nordic
|
||||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
/ 866 - Russian
|
||||||
|
/ 869 - Greek 2
|
||||||
|
/ 932 - Japanese (DBCS)
|
||||||
|
/ 936 - Simplified Chinese (DBCS)
|
||||||
|
/ 949 - Korean (DBCS)
|
||||||
|
/ 950 - Traditional Chinese (DBCS)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_ENABLE_LFN
|
#ifdef MICROPY_FATFS_ENABLE_LFN
|
||||||
#define _USE_LFN (MICROPY_FATFS_ENABLE_LFN)
|
#define _USE_LFN (MICROPY_FATFS_ENABLE_LFN)
|
||||||
#else
|
#else
|
||||||
#define _USE_LFN 0
|
#define _USE_LFN 0
|
||||||
#endif
|
#endif
|
||||||
#ifdef MICROPY_FATFS_MAX_LFN
|
#ifdef MICROPY_FATFS_MAX_LFN
|
||||||
#define _MAX_LFN (MICROPY_FATFS_MAX_LFN)
|
#define _MAX_LFN (MICROPY_FATFS_MAX_LFN)
|
||||||
#else
|
#else
|
||||||
#define _MAX_LFN 255
|
#define _MAX_LFN 255
|
||||||
#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
|
||||||
@ -168,59 +178,57 @@
|
|||||||
/ 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. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_RPATH
|
#ifdef MICROPY_FATFS_RPATH
|
||||||
#define _FS_RPATH (MICROPY_FATFS_RPATH)
|
#define _FS_RPATH (MICROPY_FATFS_RPATH)
|
||||||
#else
|
#else
|
||||||
#define _FS_RPATH 0
|
#define _FS_RPATH 0
|
||||||
#endif
|
#endif
|
||||||
/* 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. */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
/*---------------------------------------------------------------------------/
|
||||||
/ Drive/Volume Configurations
|
/ Drive/Volume Configurations
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_VOLUMES
|
#define _VOLUMES 1
|
||||||
#define _VOLUMES (MICROPY_FATFS_VOLUMES)
|
|
||||||
#else
|
|
||||||
#define _VOLUMES 1
|
|
||||||
#endif
|
|
||||||
/* Number of volumes (logical drives) to be used. */
|
/* Number of volumes (logical drives) to be used. */
|
||||||
|
|
||||||
|
|
||||||
#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
|
||||||
/ the drive ID strings are: A-Z and 0-9. */
|
/ the drive ID strings are: A-Z and 0-9. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_MULTI_PARTITION
|
#ifdef MICROPY_FATFS_MULTI_PARTITION
|
||||||
#define _MULTI_PARTITION (MICROPY_FATFS_MULTI_PARTITION)
|
#define _MULTI_PARTITION (MICROPY_FATFS_MULTI_PARTITION)
|
||||||
#else
|
#else
|
||||||
#define _MULTI_PARTITION 0
|
#define _MULTI_PARTITION 0
|
||||||
#endif
|
#endif
|
||||||
/* 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 available. */
|
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||||
|
/ funciton will be available. */
|
||||||
|
|
||||||
|
|
||||||
#define _MIN_SS 512
|
#define _MIN_SS 512
|
||||||
#ifdef MICROPY_FATFS_MAX_SS
|
#ifdef MICROPY_FATFS_MAX_SS
|
||||||
#define _MAX_SS (MICROPY_FATFS_MAX_SS)
|
#define _MAX_SS (MICROPY_FATFS_MAX_SS)
|
||||||
#else
|
#else
|
||||||
#define _MAX_SS 512
|
#define _MAX_SS 512
|
||||||
#endif
|
#endif
|
||||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||||
@ -230,13 +238,13 @@
|
|||||||
/ disk_ioctl() function. */
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
|
||||||
#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. */
|
||||||
|
|
||||||
|
|
||||||
#define _FS_NOFSINFO 0
|
#define _FS_NOFSINFO 0
|
||||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||||
/ option, and f_getfree() function at first time after volume mount will force
|
/ option, and f_getfree() function at first time after volume mount will force
|
||||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||||
@ -253,54 +261,76 @@
|
|||||||
/ System Configurations
|
/ System Configurations
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define _FS_NORTC 0
|
#define _FS_TINY 1
|
||||||
#define _NORTC_MON 2
|
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||||
#define _NORTC_MDAY 1
|
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
|
||||||
#define _NORTC_YEAR 2015
|
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
|
||||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
|
||||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
|
#ifdef MICROPY_FATFS_EXFAT
|
||||||
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
|
#define _FS_EXFAT (MICROPY_FATFS_EXFAT)
|
||||||
/ to be added to the project to read current time form RTC. _NORTC_MON,
|
#else
|
||||||
|
#define _FS_EXFAT 0
|
||||||
|
#endif
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MICROPY_FATFS_NORTC
|
||||||
|
#define _FS_NORTC (MICROPY_FATFS_NORTC)
|
||||||
|
#else
|
||||||
|
#define _FS_NORTC 0
|
||||||
|
#endif
|
||||||
|
#define _NORTC_MON 1
|
||||||
|
#define _NORTC_MDAY 1
|
||||||
|
#define _NORTC_YEAR 2016
|
||||||
|
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
||||||
|
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
||||||
|
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||||
|
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||||
|
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||||
|
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
/ _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. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_REENTRANT
|
#ifdef MICROPY_FATFS_REENTRANT
|
||||||
#define _FS_REENTRANT (MICROPY_FATFS_REENTRANT)
|
#define _FS_REENTRANT (MICROPY_FATFS_REENTRANT)
|
||||||
#else
|
#else
|
||||||
#define _FS_REENTRANT 0
|
#define _FS_REENTRANT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// milliseconds
|
// milliseconds
|
||||||
#ifdef MICROPY_FATFS_TIMEOUT
|
#ifdef MICROPY_FATFS_TIMEOUT
|
||||||
#define _FS_TIMEOUT (MICROPY_FATFS_TIMEOUT)
|
#define _FS_TIMEOUT (MICROPY_FATFS_TIMEOUT)
|
||||||
#else
|
#else
|
||||||
#define _FS_TIMEOUT 1000
|
#define _FS_TIMEOUT 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MICROPY_FATFS_SYNC_T
|
#ifdef MICROPY_FATFS_SYNC_T
|
||||||
#define _SYNC_t MICROPY_FATFS_SYNC_T
|
#define _SYNC_t MICROPY_FATFS_SYNC_T
|
||||||
#else
|
#else
|
||||||
#define _SYNC_t HANDLE
|
#define _SYNC_t HANDLE
|
||||||
#endif
|
#endif
|
||||||
/* 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,
|
||||||
@ -310,30 +340,10 @@
|
|||||||
/
|
/
|
||||||
/ 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. */
|
||||||
|
|
||||||
|
/* #include <windows.h> // O/S definitions */
|
||||||
|
|
||||||
|
|
||||||
#define _WORD_ACCESS 0
|
/*--- End of configuration options ---*/
|
||||||
/* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif // _FFCONF
|
|
388
lib/oofatfs/option/ccsbcs.c
Normal file
388
lib/oofatfs/option/ccsbcs.c
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */
|
||||||
|
/* (SBCS code pages) */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* 437 U.S.
|
||||||
|
/ 720 Arabic
|
||||||
|
/ 737 Greek
|
||||||
|
/ 771 KBL
|
||||||
|
/ 775 Baltic
|
||||||
|
/ 850 Latin 1
|
||||||
|
/ 852 Latin 2
|
||||||
|
/ 855 Cyrillic
|
||||||
|
/ 857 Turkish
|
||||||
|
/ 860 Portuguese
|
||||||
|
/ 861 Icelandic
|
||||||
|
/ 862 Hebrew
|
||||||
|
/ 863 Canadian French
|
||||||
|
/ 864 Arabic
|
||||||
|
/ 865 Nordic
|
||||||
|
/ 866 Russian
|
||||||
|
/ 869 Greek 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if _CODE_PAGE == 437
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 720
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||||
|
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||||
|
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 737
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||||
|
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||||
|
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||||
|
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 771
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||||
|
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||||
|
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
|
||||||
|
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||||
|
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 775
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||||
|
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||||
|
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||||
|
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 850
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||||
|
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 852
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||||
|
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||||
|
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 855
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||||
|
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||||
|
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||||
|
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||||
|
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 857
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||||
|
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||||
|
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||||
|
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 860
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
||||||
|
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 861
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
||||||
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 862
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||||
|
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 863
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
||||||
|
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
||||||
|
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 864
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
||||||
|
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
||||||
|
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
||||||
|
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
|
||||||
|
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
|
||||||
|
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
|
||||||
|
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
|
||||||
|
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 865
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||||
|
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||||
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||||
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 866
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||||
|
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||||
|
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||||
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||||
|
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||||
|
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 869
|
||||||
|
#define _TBLDEF 1
|
||||||
|
static
|
||||||
|
const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
|
||||||
|
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
||||||
|
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
||||||
|
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
||||||
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
|
||||||
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
|
||||||
|
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
|
||||||
|
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
|
||||||
|
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !_TBLDEF || !_USE_LFN
|
||||||
|
#error This file is not needed at current configuration. Remove from the project.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||||
|
WCHAR chr, /* Character code to be converted */
|
||||||
|
UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WCHAR c;
|
||||||
|
|
||||||
|
|
||||||
|
if (chr < 0x80) { /* ASCII */
|
||||||
|
c = chr;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (dir) { /* OEM code to Unicode */
|
||||||
|
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
||||||
|
|
||||||
|
} else { /* Unicode to OEM code */
|
||||||
|
for (c = 0; c < 0x80; c++) {
|
||||||
|
if (chr == Tbl[c]) break;
|
||||||
|
}
|
||||||
|
c = (c + 0x80) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WCHAR ff_wtoupper ( /* Returns upper converted character */
|
||||||
|
WCHAR chr /* Unicode character to be upper converted (BMP only) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Compressed upper conversion table */
|
||||||
|
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
|
||||||
|
/* Basic Latin */
|
||||||
|
0x0061,0x031A,
|
||||||
|
/* Latin-1 Supplement */
|
||||||
|
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
||||||
|
/* Latin Extended-A */
|
||||||
|
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
||||||
|
/* Latin Extended-B */
|
||||||
|
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
||||||
|
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
|
||||||
|
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
|
||||||
|
/* IPA Extensions */
|
||||||
|
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
||||||
|
/* Greek, Coptic */
|
||||||
|
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
|
||||||
|
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
|
||||||
|
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
||||||
|
/* Cyrillic */
|
||||||
|
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
|
||||||
|
/* Armenian */
|
||||||
|
0x0561,0x0426,
|
||||||
|
|
||||||
|
0x0000
|
||||||
|
};
|
||||||
|
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
|
||||||
|
/* Phonetic Extensions */
|
||||||
|
0x1D7D,0x0001,0x2C63,
|
||||||
|
/* Latin Extended Additional */
|
||||||
|
0x1E00,0x0196, 0x1EA0,0x015A,
|
||||||
|
/* Greek Extended */
|
||||||
|
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
|
||||||
|
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
|
||||||
|
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
||||||
|
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||||
|
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
|
||||||
|
/* Letterlike Symbols */
|
||||||
|
0x214E,0x0001,0x2132,
|
||||||
|
/* Number forms */
|
||||||
|
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
||||||
|
/* Enclosed Alphanumerics */
|
||||||
|
0x24D0,0x051A, 0x2C30,0x042F,
|
||||||
|
/* Latin Extended-C */
|
||||||
|
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
||||||
|
/* Coptic */
|
||||||
|
0x2C80,0x0164,
|
||||||
|
/* Georgian Supplement */
|
||||||
|
0x2D00,0x0826,
|
||||||
|
/* Full-width */
|
||||||
|
0xFF41,0x031A,
|
||||||
|
|
||||||
|
0x0000
|
||||||
|
};
|
||||||
|
const WCHAR *p;
|
||||||
|
WCHAR bc, nc, cmd;
|
||||||
|
|
||||||
|
|
||||||
|
p = chr < 0x1000 ? cvt1 : cvt2;
|
||||||
|
for (;;) {
|
||||||
|
bc = *p++; /* Get block base */
|
||||||
|
if (!bc || chr < bc) break;
|
||||||
|
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||||
|
if (chr < bc + nc) { /* In the block? */
|
||||||
|
switch (cmd) {
|
||||||
|
case 0: chr = p[chr - bc]; break; /* Table conversion */
|
||||||
|
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
|
||||||
|
case 2: chr -= 16; break; /* Shift -16 */
|
||||||
|
case 3: chr -= 32; break; /* Shift -32 */
|
||||||
|
case 4: chr -= 48; break; /* Shift -48 */
|
||||||
|
case 5: chr -= 26; break; /* Shift -26 */
|
||||||
|
case 6: chr += 8; break; /* Shift +8 */
|
||||||
|
case 7: chr -= 80; break; /* Shift -80 */
|
||||||
|
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cmd) p += nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chr;
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user