Upgrade fatfs and sdmmc driver
This commit is contained in:
parent
f718297591
commit
710ad11819
@ -300,3 +300,31 @@ R0.13 (May 21, 2017)
|
||||
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
|
||||
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
|
||||
|
||||
|
||||
|
||||
R0.13a (October 14, 2017)
|
||||
|
||||
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
|
||||
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
|
||||
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
|
||||
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
|
||||
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
|
||||
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.13b (April 07, 2018)
|
||||
|
||||
Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
|
||||
Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
|
||||
Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
|
||||
Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
|
||||
|
||||
|
||||
|
||||
R0.13c (October 14, 2018)
|
||||
Supported stdint.h for C99 and later. (integer.h was included in ff.h)
|
||||
Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
|
||||
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
|
||||
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
FatFs Module Source Files R0.13
|
||||
FatFs Module Source Files R0.13c
|
||||
|
||||
|
||||
FILES
|
||||
@ -10,7 +10,6 @@ FILES
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related functions.
|
||||
|
||||
|
1802
source/fatfs/ff.c
1802
source/fatfs/ff.c
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13 /
|
||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/ Copyright (C) 2018, 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
|
||||
@ -20,13 +20,12 @@
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 87030 /* Revision ID */
|
||||
#define FF_DEFINED 86604 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
@ -34,6 +33,30 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
|
||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
@ -45,24 +68,39 @@ typedef struct {
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if FF_LFN_UNICODE && FF_USE_LFN /* Unicode (UTF-16) string */
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#define _INC_TCHAR
|
||||
#endif
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#define _INC_TCHAR
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -70,8 +108,8 @@ typedef char TCHAR;
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if !FF_USE_LFN
|
||||
#error LFN must be enabled when enable exFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
@ -83,8 +121,8 @@ typedef DWORD FSIZE_t;
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:N/A) */
|
||||
BYTE pdrv; /* Physical drive number */
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
@ -121,6 +159,9 @@ typedef struct {
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
@ -133,7 +174,7 @@ typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
@ -200,10 +241,10 @@ typedef struct {
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[13]; /* Altenative file name */
|
||||
TCHAR fname[FF_MAX_LFN + 1]; /* Primary file name */
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[13]; /* File name */
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
@ -299,10 +340,10 @@ DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN /* Code conversion (defined in unicode.c) */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (WCHAR uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
WCHAR ff_wtoupper (WCHAR uni); /* Unicode upper-case conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - Configuration file
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 87030 /* Revision ID */
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
@ -18,7 +18,7 @@
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
@ -106,32 +106,47 @@
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
||||
/ to the project. The working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional 608 bytes at exFAT enabled. FF_MAX_LFN can be in range from 12 to 255.
|
||||
/ It should be set 255 to support full featured LFN operations.
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree(), must be added to the project. */
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches character encoding on the API, 0:ANSI/OEM or 1:UTF-16,
|
||||
/ when LFN is enabled. Also behavior of string I/O functions will be affected by
|
||||
/ this option. When LFN is not enabled, this option has no effect.
|
||||
*/
|
||||
#define FF_LFN_UNICODE 2
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE = 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM
|
||||
/ 1: UTF-16LE
|
||||
/ 2: UTF-16BE
|
||||
/ 3: UTF-8
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
@ -154,11 +169,16 @@
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches string support for volume ID.
|
||||
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
@ -212,17 +232,17 @@
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled.
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 5
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2017
|
||||
#define FF_NORTC_YEAR 2019
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
@ -242,6 +262,7 @@
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
@ -262,8 +283,6 @@
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
@ -1,20 +1,19 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs */
|
||||
/* (C)ChaN, 2017 */
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C)ChaN, 2018 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
@ -27,7 +26,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on no
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
@ -47,7 +46,7 @@ void ff_memfree (
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
|
||||
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
@ -74,7 +73,7 @@ int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(Mutex + vol);
|
||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
||||
// return (int)(*sobj != NULL);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode handling functions for FatFs R0.13+ */
|
||||
/* Unicode handling functions for FatFs R0.13c */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This module will occupy a huge memory in the .const section when the /
|
||||
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
|
||||
@ -7,7 +7,7 @@
|
||||
/ that function to avoid silly memory consumption. /
|
||||
/-------------------------------------------------------------------------*/
|
||||
/*
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/ Copyright (C) 2018, 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
|
||||
@ -25,7 +25,11 @@
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#if FF_USE_LFN
|
||||
#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */
|
||||
|
||||
#if FF_DEFINED != 86604 /* Revision ID */
|
||||
#error Wrong include file (ff.h).
|
||||
#endif
|
||||
|
||||
#define MERGE2(a, b) a ## b
|
||||
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
|
||||
@ -36,8 +40,7 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE == 932 || FF_CODE_PAGE == 0 /* Japanese */
|
||||
static
|
||||
const WCHAR uni2oem932[] = { /* Unicode --> Shift_JIS pairs */
|
||||
static const WCHAR uni2oem932[] = { /* Unicode --> Shift_JIS pairs */
|
||||
0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D, 0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180,
|
||||
0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2, 0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6,
|
||||
0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA, 0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE,
|
||||
@ -964,8 +967,7 @@ const WCHAR uni2oem932[] = { /* Unicode --> Shift_JIS pairs */
|
||||
0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150, 0xFFE4, 0xFA55, 0xFFE5, 0x818F, 0, 0
|
||||
};
|
||||
|
||||
static
|
||||
const WCHAR oem2uni932[] = { /* Shift_JIS --> Unicode pairs */
|
||||
static const WCHAR oem2uni932[] = { /* Shift_JIS --> Unicode pairs */
|
||||
0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64, 0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68,
|
||||
0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C, 0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70,
|
||||
0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74, 0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78,
|
||||
@ -1894,8 +1896,7 @@ const WCHAR oem2uni932[] = { /* Shift_JIS --> Unicode pairs */
|
||||
#endif
|
||||
|
||||
#if FF_CODE_PAGE == 936 || FF_CODE_PAGE == 0 /* Simplified Chinese */
|
||||
static
|
||||
const WCHAR uni2oem936[] = { /* Unicode --> GBK pairs */
|
||||
static const WCHAR uni2oem936[] = { /* Unicode --> GBK pairs */
|
||||
0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3, 0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4,
|
||||
0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA, 0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE,
|
||||
0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9, 0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9,
|
||||
@ -4623,8 +4624,7 @@ const WCHAR uni2oem936[] = { /* Unicode --> GBK pairs */
|
||||
0, 0
|
||||
};
|
||||
|
||||
static
|
||||
const WCHAR oem2uni936[] = { /* GBK --> Unicode pairs */
|
||||
static const WCHAR oem2uni936[] = { /* GBK --> Unicode pairs */
|
||||
0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05, 0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17,
|
||||
0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23, 0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F,
|
||||
0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37, 0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42,
|
||||
@ -7354,8 +7354,7 @@ const WCHAR oem2uni936[] = { /* GBK --> Unicode pairs */
|
||||
#endif
|
||||
|
||||
#if FF_CODE_PAGE == 949 || FF_CODE_PAGE == 0 /* Korean */
|
||||
static
|
||||
const WCHAR uni2oem949[] = { /* Unicode --> Korean pairs */
|
||||
static const WCHAR uni2oem949[] = { /* Unicode --> Korean pairs */
|
||||
0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7, 0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6,
|
||||
0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5, 0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6,
|
||||
0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA, 0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF,
|
||||
@ -9490,8 +9489,7 @@ const WCHAR uni2oem949[] = { /* Unicode --> Korean pairs */
|
||||
0, 0
|
||||
};
|
||||
|
||||
static
|
||||
const WCHAR oem2uni949[] = { /* Korean --> Unicode pairs */
|
||||
static const WCHAR oem2uni949[] = { /* Korean --> Unicode pairs */
|
||||
0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06, 0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E,
|
||||
0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F, 0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25,
|
||||
0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29, 0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32,
|
||||
@ -11628,8 +11626,7 @@ const WCHAR oem2uni949[] = { /* Korean --> Unicode pairs */
|
||||
#endif
|
||||
|
||||
#if FF_CODE_PAGE == 950 || FF_CODE_PAGE == 0 /* Traditional Chinese */
|
||||
static
|
||||
const WCHAR uni2oem950[] = { /* Unicode --> Big5 pairs */
|
||||
static const WCHAR uni2oem950[] = { /* Unicode --> Big5 pairs */
|
||||
0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3, 0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE,
|
||||
0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5, 0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346,
|
||||
0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A, 0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E,
|
||||
@ -13320,8 +13317,7 @@ const WCHAR uni2oem950[] = { /* Unicode --> Big5 pairs */
|
||||
0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246, 0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0
|
||||
};
|
||||
|
||||
static
|
||||
const WCHAR oem2uni950[] = { /* Big5 --> Unicode pairs */
|
||||
static const WCHAR oem2uni950[] = { /* Big5 --> Unicode pairs */
|
||||
0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002, 0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A,
|
||||
0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026, 0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52,
|
||||
0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56, 0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31,
|
||||
@ -15014,8 +15010,7 @@ const WCHAR oem2uni950[] = { /* Big5 --> Unicode pairs */
|
||||
#endif
|
||||
|
||||
#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
static const WCHAR uc437[] = { /* CP437(U.S.) 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,
|
||||
@ -15027,8 +15022,7 @@ const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
static const WCHAR uc720[] = { /* CP720(Arabic) 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,
|
||||
@ -15040,8 +15034,7 @@ const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
static const WCHAR uc737[] = { /* CP737(Greek) 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,
|
||||
@ -15053,8 +15046,7 @@ const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
static const WCHAR uc771[] = { /* CP771(KBL) 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,
|
||||
@ -15066,8 +15058,7 @@ const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
static const WCHAR uc775[] = { /* CP775(Baltic) 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,
|
||||
@ -15079,8 +15070,7 @@ const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
static const WCHAR uc850[] = { /* CP850(Latin 1) 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,
|
||||
@ -15092,8 +15082,7 @@ const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
static const WCHAR uc852[] = { /* CP852(Latin 2) 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,
|
||||
@ -15105,8 +15094,7 @@ const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
|
||||
static const WCHAR uc855[] = { /* CP855(Cyrillic) 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,
|
||||
@ -15118,8 +15106,7 @@ const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
static const WCHAR uc857[] = { /* CP857(Turkish) 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,
|
||||
@ -15131,8 +15118,7 @@ const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
|
||||
static const WCHAR uc860[] = { /* CP860(Portuguese) 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,
|
||||
@ -15144,8 +15130,7 @@ const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
|
||||
static const WCHAR uc861[] = { /* CP861(Icelandic) 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,
|
||||
@ -15157,8 +15142,7 @@ const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
static const WCHAR uc862[] = { /* CP862(Hebrew) 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,
|
||||
@ -15170,8 +15154,7 @@ const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
|
||||
static const WCHAR uc863[] = { /* CP863(Canadian French) 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,
|
||||
@ -15183,8 +15166,7 @@ const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table *
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
static const WCHAR uc864[] = { /* CP864(Arabic) 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,
|
||||
@ -15196,8 +15178,7 @@ const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
static const WCHAR uc865[] = { /* CP865(Nordic) 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,
|
||||
@ -15209,8 +15190,7 @@ const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
static const WCHAR uc866[] = { /* CP866(Russian) 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,
|
||||
@ -15222,8 +15202,7 @@ const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
};
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
|
||||
static
|
||||
const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
|
||||
static const WCHAR uc869[] = { /* CP869(Greek 2) 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,
|
||||
@ -15245,7 +15224,7 @@ const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
|
||||
|
||||
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
WCHAR uni, /* Unicode character to be converted */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
@ -15253,15 +15232,16 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII char */
|
||||
c = uni;
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
for (c = 0; c < 0x80 && uni != p[c]; c++) ;
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -15274,7 +15254,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII char */
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
@ -15282,6 +15262,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
if (oem < 0x100) c = p[oem - 0x80];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -15294,29 +15275,30 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
/* DBCS fixed code page */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE >= 900
|
||||
#if FF_CODE_PAGE >= 900
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
WCHAR uni, /* Unicode character to be converted */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i, n, li, hi;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i = 0, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII char */
|
||||
c = uni;
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
uc = (WCHAR)uni;
|
||||
p = CVTBL(uni2oem, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (uni == p[i * 2]) break;
|
||||
if (uni > p[i * 2]) {
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
@ -15325,6 +15307,7 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -15336,14 +15319,14 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i, n, li, hi;
|
||||
UINT i = 0, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII char */
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it valid code page? */
|
||||
p = CVTBL(oem2uni, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
@ -15359,6 +15342,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
@ -15376,40 +15360,42 @@ static const WCHAR *const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850
|
||||
|
||||
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
WCHAR uni, /* Unicode character to be converted */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII char */
|
||||
c = uni;
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII char */
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WCHAR)uni;
|
||||
p = 0;
|
||||
if (cp < 900) { /* SBCS */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */
|
||||
p = cp_table[i];
|
||||
if (p) { /* Is it a valid CP ? */
|
||||
for (c = 0; c < 0x80 && uni != p[c]; c++) ; /* Find OEM code in the table */
|
||||
if (p) { /* Is it valid code page ? */
|
||||
for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
} else { /* DBCS */
|
||||
switch (cp) {
|
||||
switch (cp) { /* Get conversion table */
|
||||
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
|
||||
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
|
||||
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
|
||||
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
|
||||
}
|
||||
if (p) { /* Is it a valid code page? */
|
||||
if (p) { /* Is it valid code page? */
|
||||
li = 0;
|
||||
for (n = 16; n; n--) { /* Find OEM code */
|
||||
i = li + (hi - li) / 2;
|
||||
if (uni == p[i * 2]) break;
|
||||
if (uni > p[i * 2]) {
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
@ -15419,12 +15405,14 @@ WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted */
|
||||
WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
@ -15433,7 +15421,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII char */
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
@ -15466,6 +15454,7 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
@ -15476,54 +15465,94 @@ WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
/* Unicode up-case conversion */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
WCHAR ff_wtoupper ( /* Returns up-converted character */
|
||||
WCHAR uni /* Unicode character to be upper converted (BMP only) */
|
||||
DWORD ff_wtoupper ( /* Returns up-converted code point */
|
||||
DWORD uni /* Unicode code point to be up-converted */
|
||||
)
|
||||
{
|
||||
/* Compressed upper conversion table */
|
||||
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
|
||||
const WORD *p;
|
||||
WORD uc, bc, nc, cmd;
|
||||
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
|
||||
/* Basic Latin */
|
||||
0x0061,0x031A,
|
||||
/* Latin-1 Supplement */
|
||||
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
||||
0x00E0,0x0317,
|
||||
0x00F8,0x0307,
|
||||
0x00FF,0x0001,0x0178,
|
||||
/* Latin Extended-A */
|
||||
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
0x0430,0x0320,
|
||||
0x0450,0x0710,
|
||||
0x0460,0x0122,
|
||||
0x048A,0x0136,
|
||||
0x04C1,0x010E,
|
||||
0x04CF,0x0001,0x04C0,
|
||||
0x04D0,0x0144,
|
||||
/* Armenian */
|
||||
0x0561,0x0426,
|
||||
|
||||
0x0000
|
||||
0x0000 /* EOT */
|
||||
};
|
||||
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
|
||||
static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */
|
||||
/* Phonetic Extensions */
|
||||
0x1D7D,0x0001,0x2C63,
|
||||
/* Latin Extended Additional */
|
||||
0x1E00,0x0196, 0x1EA0,0x015A,
|
||||
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,
|
||||
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, 0x1FF3,0x0001,0x1FFC,
|
||||
0x1F80,0x0608,
|
||||
0x1F90,0x0608,
|
||||
0x1FA0,0x0608,
|
||||
0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3,
|
||||
0x1FD0,0x0602,
|
||||
0x1FE0,0x0602,
|
||||
0x1FE5,0x0001,0x1FEC,
|
||||
0x1FF3,0x0001,0x1FFC,
|
||||
/* Letterlike Symbols */
|
||||
0x214E,0x0001,0x2132,
|
||||
/* Number forms */
|
||||
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
||||
0x2170,0x0210,
|
||||
0x2184,0x0001,0x2183,
|
||||
/* Enclosed Alphanumerics */
|
||||
0x24D0,0x051A, 0x2C30,0x042F,
|
||||
0x24D0,0x051A,
|
||||
0x2C30,0x042F,
|
||||
/* Latin Extended-C */
|
||||
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
||||
0x2C60,0x0102,
|
||||
0x2C67,0x0106, 0x2C75,0x0102,
|
||||
/* Coptic */
|
||||
0x2C80,0x0164,
|
||||
/* Georgian Supplement */
|
||||
@ -15531,36 +15560,38 @@ WCHAR ff_wtoupper ( /* Returns up-converted character */
|
||||
/* Full-width */
|
||||
0xFF41,0x031A,
|
||||
|
||||
0x0000
|
||||
0x0000 /* EOT */
|
||||
};
|
||||
const WCHAR *p;
|
||||
WCHAR bc, nc, cmd;
|
||||
|
||||
|
||||
p = uni < 0x1000 ? cvt1 : cvt2;
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WORD)uni;
|
||||
p = uc < 0x1000 ? cvt1 : cvt2;
|
||||
for (;;) {
|
||||
bc = *p++; /* Get block base */
|
||||
if (!bc || uni < bc) break;
|
||||
bc = *p++; /* Get the block base */
|
||||
if (bc == 0 || uc < bc) break; /* Not matched? */
|
||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||
if (uni < bc + nc) { /* In the block? */
|
||||
if (uc < bc + nc) { /* In the block? */
|
||||
switch (cmd) {
|
||||
case 0: uni = p[uni - bc]; break; /* Table conversion */
|
||||
case 1: uni -= (uni - bc) & 1; break; /* Case pairs */
|
||||
case 2: uni -= 16; break; /* Shift -16 */
|
||||
case 3: uni -= 32; break; /* Shift -32 */
|
||||
case 4: uni -= 48; break; /* Shift -48 */
|
||||
case 5: uni -= 26; break; /* Shift -26 */
|
||||
case 6: uni += 8; break; /* Shift +8 */
|
||||
case 7: uni -= 80; break; /* Shift -80 */
|
||||
case 8: uni -= 0x1C60; break; /* Shift -0x1C60 */
|
||||
case 0: uc = p[uc - bc]; break; /* Table conversion */
|
||||
case 1: uc -= (uc - bc) & 1; break; /* Case pairs */
|
||||
case 2: uc -= 16; break; /* Shift -16 */
|
||||
case 3: uc -= 32; break; /* Shift -32 */
|
||||
case 4: uc -= 48; break; /* Shift -48 */
|
||||
case 5: uc -= 26; break; /* Shift -26 */
|
||||
case 6: uc += 8; break; /* Shift +8 */
|
||||
case 7: uc -= 80; break; /* Shift -80 */
|
||||
case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!cmd) p += nc;
|
||||
if (cmd == 0) p += nc; /* Skip table if needed */
|
||||
}
|
||||
uni = uc;
|
||||
}
|
||||
|
||||
return uni;
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if _USE_LFN */
|
||||
#endif /* #if FF_USE_LFN */
|
||||
|
@ -1,16 +0,0 @@
|
||||
.text
|
||||
.arm
|
||||
.align 4
|
||||
|
||||
.global waitcycles
|
||||
.type waitcycles, %function
|
||||
waitcycles:
|
||||
push {r0-r2, lr}
|
||||
str r0, [sp, #4]
|
||||
waitcycles_loop:
|
||||
ldr r3, [sp, #4]
|
||||
subs r2, r3, #1
|
||||
str r2, [sp, #4]
|
||||
cmp r3, #0
|
||||
bne waitcycles_loop
|
||||
pop {r0-r2, pc}
|
@ -22,46 +22,16 @@
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "wait_cycles.h"
|
||||
#include "sdmmc.h"
|
||||
#include "delay.h"
|
||||
|
||||
static struct mmcdevice handleNAND;
|
||||
static struct mmcdevice handleSD;
|
||||
#define DATA32_SUPPORT
|
||||
|
||||
static inline u16 sdmmc_read16(u16 reg)
|
||||
{
|
||||
return *(vu16 *)(SDMMC_BASE + reg);
|
||||
}
|
||||
|
||||
static inline void sdmmc_write16(u16 reg, u16 val)
|
||||
{
|
||||
*(vu16 *)(SDMMC_BASE + reg) = val;
|
||||
}
|
||||
|
||||
static inline u32 sdmmc_read32(u16 reg)
|
||||
{
|
||||
return *(vu32 *)(SDMMC_BASE + reg);
|
||||
}
|
||||
|
||||
static inline void sdmmc_write32(u16 reg, u32 val)
|
||||
{
|
||||
*(vu32 *)(SDMMC_BASE + reg) = val;
|
||||
}
|
||||
|
||||
static inline void sdmmc_mask16(u16 reg, const u16 clear, const u16 set)
|
||||
{
|
||||
u16 val = sdmmc_read16(reg);
|
||||
val &= ~clear;
|
||||
val |= set;
|
||||
sdmmc_write16(reg, val);
|
||||
}
|
||||
|
||||
static inline void setckl(u32 data)
|
||||
{
|
||||
sdmmc_mask16(REG_SDCLKCTL, 0x100, 0);
|
||||
sdmmc_mask16(REG_SDCLKCTL, 0x2FF, data & 0x2FF);
|
||||
sdmmc_mask16(REG_SDCLKCTL, 0x0, 0x100);
|
||||
}
|
||||
struct mmcdevice handleNAND;
|
||||
struct mmcdevice handleSD;
|
||||
|
||||
mmcdevice *getMMCDevice(int drive)
|
||||
{
|
||||
@ -69,28 +39,37 @@ mmcdevice *getMMCDevice(int drive)
|
||||
return &handleSD;
|
||||
}
|
||||
|
||||
static int geterror(struct mmcdevice *ctx)
|
||||
static int get_error(struct mmcdevice *ctx)
|
||||
{
|
||||
return (int)((ctx->error << 29) >> 31);
|
||||
}
|
||||
|
||||
static void inittarget(struct mmcdevice *ctx)
|
||||
|
||||
static void set_target(struct mmcdevice *ctx)
|
||||
{
|
||||
sdmmc_mask16(REG_SDPORTSEL,0x3,(u16)ctx->devicenumber);
|
||||
setckl(ctx->clk);
|
||||
if(ctx->SDOPT == 0) sdmmc_mask16(REG_SDOPT, 0, 0x8000);
|
||||
else sdmmc_mask16(REG_SDOPT, 0x8000, 0);
|
||||
if(ctx->SDOPT == 0)
|
||||
{
|
||||
sdmmc_mask16(REG_SDOPT,0,0x8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
sdmmc_mask16(REG_SDOPT,0x8000,0);
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
|
||||
static void sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
|
||||
{
|
||||
u32 getSDRESP = (cmd << 15) >> 31;
|
||||
const bool getSDRESP = (cmd << 15) >> 31;
|
||||
u16 flags = (cmd << 15) >> 31;
|
||||
const int readdata = cmd & 0x20000;
|
||||
const int writedata = cmd & 0x40000;
|
||||
const bool readdata = cmd & 0x20000;
|
||||
const bool writedata = cmd & 0x40000;
|
||||
|
||||
if(readdata || writedata)
|
||||
{
|
||||
flags |= TMIO_STAT0_DATAEND;
|
||||
}
|
||||
|
||||
ctx->error = 0;
|
||||
while((sdmmc_read16(REG_SDSTATUS1) & TMIO_STAT1_CMD_BUSY)); //mmc working?
|
||||
@ -98,67 +77,134 @@ static void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx,
|
||||
sdmmc_write16(REG_SDIRMASK1,0);
|
||||
sdmmc_write16(REG_SDSTATUS0,0);
|
||||
sdmmc_write16(REG_SDSTATUS1,0);
|
||||
sdmmc_mask16(REG_DATACTL32, 0x1800, 0);
|
||||
sdmmc_mask16(REG_DATACTL32,0x1800,0x400); // Disable TX32RQ and RX32RDY IRQ. Clear fifo.
|
||||
sdmmc_write16(REG_SDCMDARG0,args &0xFFFF);
|
||||
sdmmc_write16(REG_SDCMDARG1,args >> 16);
|
||||
sdmmc_write16(REG_SDCMD,cmd &0xFFFF);
|
||||
|
||||
u32 size = ctx->size;
|
||||
u8 *rDataPtr = ctx->rData;
|
||||
const u8 *tDataPtr = ctx->tData;
|
||||
const u16 blkSize = sdmmc_read16(REG_SDBLKLEN32);
|
||||
u32 *rDataPtr32 = (u32*)(void*)ctx->rData;
|
||||
u8 *rDataPtr8 = ctx->rData;
|
||||
const u32 *tDataPtr32 = (u32*)(void*)ctx->tData;
|
||||
const u8 *tDataPtr8 = ctx->tData;
|
||||
|
||||
bool rUseBuf = rDataPtr != NULL;
|
||||
bool tUseBuf = tDataPtr != NULL;
|
||||
bool rUseBuf = ( NULL != rDataPtr32 );
|
||||
bool tUseBuf = ( NULL != tDataPtr32 );
|
||||
|
||||
u16 status0 = 0;
|
||||
while(true)
|
||||
while(1)
|
||||
{
|
||||
vu16 status1 = sdmmc_read16(REG_SDSTATUS1);
|
||||
vu16 ctl32 = sdmmc_read16(REG_DATACTL32);
|
||||
volatile u16 status1 = sdmmc_read16(REG_SDSTATUS1);
|
||||
#ifdef DATA32_SUPPORT
|
||||
volatile u16 ctl32 = sdmmc_read16(REG_DATACTL32);
|
||||
if((ctl32 & 0x100))
|
||||
#else
|
||||
if((status1 & TMIO_STAT1_RXRDY))
|
||||
#endif
|
||||
{
|
||||
if(readdata)
|
||||
{
|
||||
if(rUseBuf)
|
||||
{
|
||||
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0);
|
||||
if(size > 0x1FF)
|
||||
if(size >= blkSize)
|
||||
{
|
||||
//Gabriel Marcano: This implementation doesn't assume alignment.
|
||||
//I've removed the alignment check doen with former rUseBuf32 as a result
|
||||
for(int i = 0; i < 0x200; i += 4)
|
||||
#ifdef DATA32_SUPPORT
|
||||
if(!((u32)rDataPtr32 & 3))
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 4)
|
||||
{
|
||||
*rDataPtr32++ = sdmmc_read32(REG_SDFIFO32);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 4)
|
||||
{
|
||||
u32 data = sdmmc_read32(REG_SDFIFO32);
|
||||
*rDataPtr++ = data;
|
||||
*rDataPtr++ = data >> 8;
|
||||
*rDataPtr++ = data >> 16;
|
||||
*rDataPtr++ = data >> 24;
|
||||
*rDataPtr8++ = data;
|
||||
*rDataPtr8++ = data >> 8;
|
||||
*rDataPtr8++ = data >> 16;
|
||||
*rDataPtr8++ = data >> 24;
|
||||
}
|
||||
size -= 0x200;
|
||||
}
|
||||
#else
|
||||
if(!((u32)rDataPtr16 & 1))
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 4)
|
||||
{
|
||||
*rDataPtr16++ = sdmmc_read16(REG_SDFIFO);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 4)
|
||||
{
|
||||
u16 data = sdmmc_read16(REG_SDFIFO);
|
||||
*rDataPtr8++ = data;
|
||||
*rDataPtr8++ = data >> 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
size -= blkSize;
|
||||
}
|
||||
}
|
||||
|
||||
sdmmc_mask16(REG_DATACTL32, 0x800, 0);
|
||||
}
|
||||
}
|
||||
#ifdef DATA32_SUPPORT
|
||||
if(!(ctl32 & 0x200))
|
||||
#else
|
||||
if((status1 & TMIO_STAT1_TXRQ))
|
||||
#endif
|
||||
{
|
||||
if(writedata)
|
||||
{
|
||||
if(tUseBuf)
|
||||
{
|
||||
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0);
|
||||
if(size > 0x1FF)
|
||||
if(size >= blkSize)
|
||||
{
|
||||
for(int i = 0; i < 0x200; i += 4)
|
||||
#ifdef DATA32_SUPPORT
|
||||
if(!((u32)tDataPtr32 & 3))
|
||||
{
|
||||
u32 data = *tDataPtr++;
|
||||
data |= (u32)*tDataPtr++ << 8;
|
||||
data |= (u32)*tDataPtr++ << 16;
|
||||
data |= (u32)*tDataPtr++ << 24;
|
||||
for(u32 i = 0; i < blkSize; i += 4)
|
||||
{
|
||||
sdmmc_write32(REG_SDFIFO32, *tDataPtr32++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 4)
|
||||
{
|
||||
u32 data = *tDataPtr8++;
|
||||
data |= (u32)*tDataPtr8++ << 8;
|
||||
data |= (u32)*tDataPtr8++ << 16;
|
||||
data |= (u32)*tDataPtr8++ << 24;
|
||||
sdmmc_write32(REG_SDFIFO32, data);
|
||||
}
|
||||
size -= 0x200;
|
||||
}
|
||||
#else
|
||||
if(!((u32)tDataPtr16 & 1))
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 2)
|
||||
{
|
||||
sdmmc_write16(REG_SDFIFO, *tDataPtr16++);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u32 i = 0; i < blkSize; i += 2)
|
||||
{
|
||||
u16 data = *tDataPtr8++;
|
||||
data |= (u16)(*tDataPtr8++ << 8);
|
||||
sdmmc_write16(REG_SDFIFO, data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
size -= blkSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,65 +247,73 @@ static void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in)
|
||||
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in)
|
||||
{
|
||||
if(handleSD.isSDHC == 0) sector_no <<= 9;
|
||||
inittarget(&handleSD);
|
||||
set_target(&handleSD);
|
||||
sdmmc_write16(REG_SDSTOP,0x100);
|
||||
#ifdef DATA32_SUPPORT
|
||||
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
|
||||
sdmmc_write16(REG_SDBLKLEN32,0x200);
|
||||
#endif
|
||||
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
|
||||
handleSD.tData = in;
|
||||
handleSD.size = numsectors << 9;
|
||||
sdmmc_send_command(&handleSD,0x52C19,sector_no);
|
||||
return geterror(&handleSD);
|
||||
return get_error(&handleSD);
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out)
|
||||
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out)
|
||||
{
|
||||
if(handleSD.isSDHC == 0) sector_no <<= 9;
|
||||
inittarget(&handleSD);
|
||||
set_target(&handleSD);
|
||||
sdmmc_write16(REG_SDSTOP,0x100);
|
||||
#ifdef DATA32_SUPPORT
|
||||
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
|
||||
sdmmc_write16(REG_SDBLKLEN32,0x200);
|
||||
#endif
|
||||
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
|
||||
handleSD.rData = out;
|
||||
handleSD.size = numsectors << 9;
|
||||
sdmmc_send_command(&handleSD,0x33C12,sector_no);
|
||||
return geterror(&handleSD);
|
||||
return get_error(&handleSD);
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out)
|
||||
|
||||
|
||||
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out)
|
||||
{
|
||||
if(handleNAND.isSDHC == 0) sector_no <<= 9;
|
||||
inittarget(&handleNAND);
|
||||
set_target(&handleNAND);
|
||||
sdmmc_write16(REG_SDSTOP,0x100);
|
||||
#ifdef DATA32_SUPPORT
|
||||
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
|
||||
sdmmc_write16(REG_SDBLKLEN32,0x200);
|
||||
#endif
|
||||
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
|
||||
handleNAND.rData = out;
|
||||
handleNAND.size = numsectors << 9;
|
||||
sdmmc_send_command(&handleNAND,0x33C12,sector_no);
|
||||
inittarget(&handleSD);
|
||||
return geterror(&handleNAND);
|
||||
return get_error(&handleNAND);
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in) //experimental
|
||||
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in) //experimental
|
||||
{
|
||||
if(handleNAND.isSDHC == 0) sector_no <<= 9;
|
||||
inittarget(&handleNAND);
|
||||
set_target(&handleNAND);
|
||||
sdmmc_write16(REG_SDSTOP,0x100);
|
||||
#ifdef DATA32_SUPPORT
|
||||
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
|
||||
sdmmc_write16(REG_SDBLKLEN32,0x200);
|
||||
#endif
|
||||
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
|
||||
handleNAND.tData = in;
|
||||
handleNAND.size = numsectors << 9;
|
||||
sdmmc_send_command(&handleNAND,0x52C19,sector_no);
|
||||
inittarget(&handleSD);
|
||||
return geterror(&handleNAND);
|
||||
return get_error(&handleNAND);
|
||||
}
|
||||
|
||||
static u32 calcSDSize(u8 *csd, int type)
|
||||
static u32 sdmmc_calc_size(u8* csd, int type)
|
||||
{
|
||||
u32 result = 0;
|
||||
if(type == -1) type = csd[14] >> 6;
|
||||
@ -267,7 +321,7 @@ static u32 calcSDSize(u8 *csd, int type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
u32 block_len = csd[9] & 0xF;
|
||||
u32 block_len=csd[9]&0xf;
|
||||
block_len=1u<<block_len;
|
||||
u32 mult=( u32)((csd[4]>>7)|((csd[5]&3)<<1));
|
||||
mult=1u<<(mult+2);
|
||||
@ -275,10 +329,10 @@ static u32 calcSDSize(u8 *csd, int type)
|
||||
result=(result<<8)|csd[7];
|
||||
result=(result<<2)|(csd[6]>>6);
|
||||
result=(result+1)*mult*block_len/512;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
result = csd[7] & 0x3F;
|
||||
result=csd[7]&0x3f;
|
||||
result=(result<<8)|csd[6];
|
||||
result=(result<<8)|csd[5];
|
||||
result=(result+1)*1024;
|
||||
@ -289,17 +343,41 @@ static u32 calcSDSize(u8 *csd, int type)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void InitSD()
|
||||
void sdmmc_init()
|
||||
{
|
||||
*(vu32 *)0x10000020 = 0; //InitFS stuff
|
||||
*(vu32 *)0x10000020 = 0x200; //InitFS stuff
|
||||
//NAND
|
||||
handleNAND.isSDHC = 0;
|
||||
handleNAND.SDOPT = 0;
|
||||
handleNAND.res = 0;
|
||||
handleNAND.initarg = 1;
|
||||
handleNAND.clk = 0x20; // 523.655968 KHz
|
||||
handleNAND.devicenumber = 1;
|
||||
|
||||
//SD
|
||||
handleSD.isSDHC = 0;
|
||||
handleSD.SDOPT = 0;
|
||||
handleSD.res = 0;
|
||||
handleSD.initarg = 0;
|
||||
handleSD.clk = 0x20; // 523.655968 KHz
|
||||
handleSD.devicenumber = 0;
|
||||
|
||||
*(vu16*)0x10006100 &= 0xF7FFu; //SDDATACTL32
|
||||
*(vu16*)0x10006100 &= 0xEFFFu; //SDDATACTL32
|
||||
#ifdef DATA32_SUPPORT
|
||||
*(vu16*)0x10006100 |= 0x402u; //SDDATACTL32
|
||||
#else
|
||||
*(vu16*)0x10006100 |= 0x402u; //SDDATACTL32
|
||||
#endif
|
||||
*(vu16*)0x100060D8 = (*(vu16*)0x100060D8 & 0xFFDD) | 2;
|
||||
#ifdef DATA32_SUPPORT
|
||||
*(vu16*)0x10006100 &= 0xFFFFu; //SDDATACTL32
|
||||
*(vu16*)0x100060D8 &= 0xFFDFu; //SDDATACTL
|
||||
*(vu16*)0x10006104 = 512; //SDBLKLEN32
|
||||
#else
|
||||
*(vu16*)0x10006100 &= 0xFFFDu; //SDDATACTL32
|
||||
*(vu16*)0x100060D8 &= 0xFFDDu; //SDDATACTL
|
||||
*(vu16*)0x10006104 = 0; //SDBLKLEN32
|
||||
#endif
|
||||
*(vu16*)0x10006108 = 1; //SDBLKCOUNT32
|
||||
*(vu16*)0x100060E0 &= 0xFFFEu; //SDRESET
|
||||
*(vu16*)0x100060E0 |= 1u; //SDRESET
|
||||
@ -308,25 +386,30 @@ static void InitSD()
|
||||
*(vu16*)0x100060FC |= 0xDBu; //SDCTL_RESERVED7
|
||||
*(vu16*)0x100060FE |= 0xDBu; //SDCTL_RESERVED8
|
||||
*(vu16*)0x10006002 &= 0xFFFCu; //SDPORTSEL
|
||||
#ifdef DATA32_SUPPORT
|
||||
*(vu16*)0x10006024 = 0x20;
|
||||
*(vu16 *)0x10006028 = 0x40EE;
|
||||
*(vu16*)0x10006028 = 0x40E9;
|
||||
#else
|
||||
*(vu16*)0x10006024 = 0x40; //Nintendo sets this to 0x20
|
||||
*(vu16*)0x10006028 = 0x40E9; //Nintendo sets this to 0x40EE
|
||||
#endif
|
||||
*(vu16*)0x10006002 &= 0xFFFCu; ////SDPORTSEL
|
||||
*(vu16*)0x10006026 = 512; //SDBLKLEN
|
||||
*(vu16*)0x10006008 = 0; //SDSTOP
|
||||
}
|
||||
|
||||
static int Nand_Init()
|
||||
int Nand_Init()
|
||||
{
|
||||
//NAND
|
||||
// init the handle
|
||||
handleNAND.isSDHC = 0;
|
||||
handleNAND.SDOPT = 0;
|
||||
handleNAND.res = 0;
|
||||
handleNAND.initarg = 1;
|
||||
handleNAND.clk = 0x80;
|
||||
handleNAND.clk = 0x20; // 523.655968 KHz
|
||||
handleNAND.devicenumber = 1;
|
||||
|
||||
inittarget(&handleNAND);
|
||||
waitcycles(0xF000);
|
||||
// The eMMC is always on. Nothing special to do.
|
||||
set_target(&handleNAND);
|
||||
|
||||
sdmmc_send_command(&handleNAND,0,0);
|
||||
|
||||
@ -335,8 +418,7 @@ static int Nand_Init()
|
||||
do
|
||||
{
|
||||
sdmmc_send_command(&handleNAND,0x10701,0x100000);
|
||||
}
|
||||
while(!(handleNAND.error & 1));
|
||||
} while ( !(handleNAND.error & 1) );
|
||||
}
|
||||
while((handleNAND.ret[0] & 0x80000000) == 0);
|
||||
|
||||
@ -349,20 +431,21 @@ static int Nand_Init()
|
||||
sdmmc_send_command(&handleNAND,0x10609,handleNAND.initarg << 0x10);
|
||||
if((handleNAND.error & 0x4))return -1;
|
||||
|
||||
handleNAND.total_size = calcSDSize((u8*)&handleNAND.ret[0], 0);
|
||||
handleNAND.clk = 1;
|
||||
setckl(1);
|
||||
handleNAND.total_size = sdmmc_calc_size((u8*)&handleNAND.ret[0],0);
|
||||
setckl(0x201); // 16.756991 MHz
|
||||
|
||||
sdmmc_send_command(&handleNAND,0x10407,handleNAND.initarg << 0x10);
|
||||
if((handleNAND.error & 0x4))return -1;
|
||||
|
||||
handleNAND.SDOPT = 1;
|
||||
|
||||
sdmmc_send_command(&handleNAND, 0x10506, 0x3B70100);
|
||||
sdmmc_send_command(&handleNAND,0x10506,0x3B70100); // Set 4 bit bus width.
|
||||
if((handleNAND.error & 0x4))return -1;
|
||||
sdmmc_mask16(REG_SDOPT, 0x8000, 0); // Switch to 4 bit mode.
|
||||
|
||||
sdmmc_send_command(&handleNAND, 0x10506, 0x3B90100);
|
||||
sdmmc_send_command(&handleNAND,0x10506,0x3B90100); // Switch to high speed timing.
|
||||
if((handleNAND.error & 0x4))return -1;
|
||||
handleNAND.clk = 0x200; // 33.513982 MHz
|
||||
setckl(0x200);
|
||||
|
||||
sdmmc_send_command(&handleNAND,0x1040D,handleNAND.initarg << 0x10);
|
||||
if((handleNAND.error & 0x4))return -1;
|
||||
@ -370,44 +453,37 @@ static int Nand_Init()
|
||||
sdmmc_send_command(&handleNAND,0x10410,0x200);
|
||||
if((handleNAND.error & 0x4))return -1;
|
||||
|
||||
handleNAND.clk |= 0x200;
|
||||
|
||||
inittarget(&handleSD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SD_Init()
|
||||
int SD_Init()
|
||||
{
|
||||
//SD
|
||||
// init the handle
|
||||
handleSD.isSDHC = 0;
|
||||
handleSD.SDOPT = 0;
|
||||
handleSD.res = 0;
|
||||
handleSD.initarg = 0;
|
||||
handleSD.clk = 0x80;
|
||||
handleSD.clk = 0x20; // 523.655968 KHz
|
||||
handleSD.devicenumber = 0;
|
||||
|
||||
inittarget(&handleSD);
|
||||
|
||||
waitcycles(1u << 22); //Card needs a little bit of time to be detected, it seems FIXME test again to see what a good number is for the delay
|
||||
|
||||
//If not inserted
|
||||
if(!(*((vu16 *)(SDMMC_BASE + REG_SDSTATUS0)) & TMIO_STAT0_SIGSTATE)) return 5;
|
||||
// We need to send at least 74 clock pulses.
|
||||
set_target(&handleSD);
|
||||
wait_cycles(0x1980); // ~75-76 clocks
|
||||
|
||||
sdmmc_send_command(&handleSD,0,0);
|
||||
sdmmc_send_command(&handleSD,0x10408,0x1AA);
|
||||
u32 temp = (handleSD.error & 0x1) << 0x1E;
|
||||
|
||||
u32 temp2 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
|
||||
sdmmc_send_command(&handleSD, 0x10769, 0x00FF8000 | temp);
|
||||
sdmmc_send_command(&handleSD,0x10769,0x10100000 | temp); // Allow 150mA, 3.2-3.3V (from Process9)
|
||||
temp2 = 1;
|
||||
}
|
||||
while(!(handleSD.error & 1));
|
||||
} while ( !(handleSD.error & 1) );
|
||||
}
|
||||
while((handleSD.ret[0] & 0x80000000) == 0);
|
||||
|
||||
@ -426,57 +502,117 @@ static int SD_Init()
|
||||
sdmmc_send_command(&handleSD,0x10609,handleSD.initarg << 0x10);
|
||||
if((handleSD.error & 0x4)) return -3;
|
||||
|
||||
handleSD.total_size = calcSDSize((u8*)&handleSD.ret[0], -1);
|
||||
handleSD.clk = 1;
|
||||
setckl(1);
|
||||
// Command Class 10 support
|
||||
const bool cmd6Supported = ((u8*)handleSD.ret)[10] & 0x40;
|
||||
handleSD.total_size = sdmmc_calc_size((u8*)&handleSD.ret[0],-1);
|
||||
setckl(0x201); // 16.756991 MHz
|
||||
|
||||
sdmmc_send_command(&handleSD,0x10507,handleSD.initarg << 0x10);
|
||||
if((handleSD.error & 0x4)) return -4;
|
||||
|
||||
// CMD55
|
||||
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
|
||||
if((handleSD.error & 0x4)) return -5;
|
||||
if(handleSD.error & 0x4) return -5;
|
||||
|
||||
// ACMD42 SET_CLR_CARD_DETECT
|
||||
sdmmc_send_command(&handleSD,0x1076A,0x0);
|
||||
if(handleSD.error & 0x4) return -6;
|
||||
|
||||
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
|
||||
if((handleSD.error & 0x4)) return -7;
|
||||
|
||||
handleSD.SDOPT = 1;
|
||||
sdmmc_send_command(&handleSD,0x10446,0x2);
|
||||
if((handleSD.error & 0x4)) return -6;
|
||||
if((handleSD.error & 0x4)) return -8;
|
||||
sdmmc_mask16(REG_SDOPT, 0x8000, 0); // Switch to 4 bit mode.
|
||||
|
||||
// TODO: CMD6 to switch to high speed mode.
|
||||
if(cmd6Supported)
|
||||
{
|
||||
sdmmc_write16(REG_SDSTOP,0);
|
||||
sdmmc_write16(REG_SDBLKLEN32,64);
|
||||
sdmmc_write16(REG_SDBLKLEN,64);
|
||||
handleSD.rData = NULL;
|
||||
handleSD.size = 64;
|
||||
sdmmc_send_command(&handleSD,0x31C06,0x80FFFFF1);
|
||||
sdmmc_write16(REG_SDBLKLEN,512);
|
||||
if(handleSD.error & 0x4) return -9;
|
||||
|
||||
handleSD.clk = 0x200; // 33.513982 MHz
|
||||
setckl(0x200);
|
||||
}
|
||||
else handleSD.clk = 0x201; // 16.756991 MHz
|
||||
|
||||
sdmmc_send_command(&handleSD,0x1040D,handleSD.initarg << 0x10);
|
||||
if((handleSD.error & 0x4)) return -7;
|
||||
if((handleSD.error & 0x4)) return -9;
|
||||
|
||||
sdmmc_send_command(&handleSD,0x10410,0x200);
|
||||
if((handleSD.error & 0x4)) return -8;
|
||||
handleSD.clk |= 0x200;
|
||||
if((handleSD.error & 0x4)) return -10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sdmmc_get_cid(bool isNand, u32 *info)
|
||||
int sdmmc_get_cid(bool isNand, u32 *info)
|
||||
{
|
||||
struct mmcdevice *device = isNand ? &handleNAND : &handleSD;
|
||||
|
||||
inittarget(device);
|
||||
struct mmcdevice *device;
|
||||
if(isNand)
|
||||
device = &handleNAND;
|
||||
else
|
||||
device = &handleSD;
|
||||
|
||||
set_target(device);
|
||||
// use cmd7 to put sd card in standby mode
|
||||
// CMD7
|
||||
{
|
||||
sdmmc_send_command(device,0x10507,0);
|
||||
//if((device->error & 0x4)) return -1;
|
||||
}
|
||||
|
||||
// get sd card info
|
||||
// use cmd10 to read CID
|
||||
{
|
||||
sdmmc_send_command(device,0x1060A,device->initarg << 0x10);
|
||||
//if((device->error & 0x4)) return -2;
|
||||
|
||||
for(int i = 0; i < 4; ++i)
|
||||
for( int i = 0; i < 4; ++i ) {
|
||||
info[i] = device->ret[i];
|
||||
}
|
||||
}
|
||||
|
||||
// put sd card back to transfer mode
|
||||
// CMD7
|
||||
{
|
||||
sdmmc_send_command(device,0x10507,device->initarg << 0x10);
|
||||
//if((device->error & 0x4)) return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 sdmmc_sdcard_init()
|
||||
{
|
||||
u32 ret = 0;
|
||||
InitSD();
|
||||
|
||||
// SD mount fix
|
||||
*((vu16*)0x10000020) = 0x340;
|
||||
|
||||
// init SDMMC / NAND
|
||||
sdmmc_init();
|
||||
if(Nand_Init() != 0) ret &= 1;
|
||||
if(SD_Init() != 0) ret &= 2;
|
||||
|
||||
// init SDMMC / SDCARD
|
||||
u32 timeout = 20; // number of tries (2ms per try)
|
||||
|
||||
do {
|
||||
// if sd card is ready, stop polling
|
||||
if(sdmmc_read16(REG_SDSTATUS0) & TMIO_STAT0_SIGSTATE)
|
||||
break;
|
||||
|
||||
wait_cycles(268000000); // approx 2ms
|
||||
timeout--;
|
||||
} while(timeout);
|
||||
|
||||
if(!timeout || SD_Init() != 0) ret &= 2;
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,72 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright (c) 2014-2015, Normmatt
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms
|
||||
* of the GNU General Public License Version 2, as described below:
|
||||
*
|
||||
* This file is free software: you may copy, redistribute and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#include "../../types.h"
|
||||
|
||||
#define SDMMC_BASE 0x10006000
|
||||
#define SDMMC_BASE (0x10006000)
|
||||
|
||||
#define REG_SDCMD 0x00
|
||||
#define REG_SDPORTSEL 0x02
|
||||
#define REG_SDCMDARG 0x04
|
||||
#define REG_SDCMDARG0 0x04
|
||||
#define REG_SDCMDARG1 0x06
|
||||
#define REG_SDSTOP 0x08
|
||||
#define REG_SDBLKCOUNT 0x0A
|
||||
#define REG_SDCMD (0x00)
|
||||
#define REG_SDPORTSEL (0x02)
|
||||
#define REG_SDCMDARG (0x04)
|
||||
#define REG_SDCMDARG0 (0x04)
|
||||
#define REG_SDCMDARG1 (0x06)
|
||||
#define REG_SDSTOP (0x08)
|
||||
#define REG_SDBLKCOUNT (0x0a)
|
||||
|
||||
#define REG_SDRESP0 0x0C
|
||||
#define REG_SDRESP1 0x0E
|
||||
#define REG_SDRESP2 0x10
|
||||
#define REG_SDRESP3 0x12
|
||||
#define REG_SDRESP4 0x14
|
||||
#define REG_SDRESP5 0x16
|
||||
#define REG_SDRESP6 0x18
|
||||
#define REG_SDRESP7 0x1A
|
||||
#define REG_SDRESP0 (0x0c)
|
||||
#define REG_SDRESP1 (0x0e)
|
||||
#define REG_SDRESP2 (0x10)
|
||||
#define REG_SDRESP3 (0x12)
|
||||
#define REG_SDRESP4 (0x14)
|
||||
#define REG_SDRESP5 (0x16)
|
||||
#define REG_SDRESP6 (0x18)
|
||||
#define REG_SDRESP7 (0x1a)
|
||||
|
||||
#define REG_SDSTATUS0 0x1C
|
||||
#define REG_SDSTATUS1 0x1E
|
||||
#define REG_SDSTATUS0 (0x1c)
|
||||
#define REG_SDSTATUS1 (0x1e)
|
||||
|
||||
#define REG_SDIRMASK0 0x20
|
||||
#define REG_SDIRMASK1 0x22
|
||||
#define REG_SDCLKCTL 0x24
|
||||
#define REG_SDIRMASK0 (0x20)
|
||||
#define REG_SDIRMASK1 (0x22)
|
||||
#define REG_SDCLKCTL (0x24)
|
||||
|
||||
#define REG_SDBLKLEN 0x26
|
||||
#define REG_SDOPT 0x28
|
||||
#define REG_SDFIFO 0x30
|
||||
#define REG_SDBLKLEN (0x26)
|
||||
#define REG_SDOPT (0x28)
|
||||
#define REG_SDFIFO (0x30)
|
||||
|
||||
#define REG_DATACTL 0xD8
|
||||
#define REG_SDRESET 0xE0
|
||||
#define REG_SDPROTECTED 0xF6 //bit 0 determines if sd is protected or not?
|
||||
#define REG_DATACTL (0xd8)
|
||||
#define REG_SDRESET (0xe0)
|
||||
#define REG_SDPROTECTED (0xf6) //bit 0 determines if sd is protected or not?
|
||||
|
||||
#define REG_DATACTL32 0x100
|
||||
#define REG_SDBLKLEN32 0x104
|
||||
#define REG_SDBLKCOUNT32 0x108
|
||||
#define REG_SDFIFO32 0x10C
|
||||
#define REG_DATACTL32 (0x100)
|
||||
#define REG_SDBLKLEN32 (0x104)
|
||||
#define REG_SDBLKCOUNT32 (0x108)
|
||||
#define REG_SDFIFO32 (0x10C)
|
||||
|
||||
#define REG_CLK_AND_WAIT_CTL 0x138
|
||||
#define REG_RESET_SDIO 0x1E0
|
||||
#define REG_CLK_AND_WAIT_CTL (0x138)
|
||||
#define REG_RESET_SDIO (0x1e0)
|
||||
|
||||
#define TMIO_STAT0_CMDRESPEND 0x0001
|
||||
#define TMIO_STAT0_DATAEND 0x0004
|
||||
#define TMIO_STAT0_CARD_REMOVE 0x0008
|
||||
#define TMIO_STAT0_CARD_INSERT 0x0010
|
||||
#define TMIO_STAT0_SIGSTATE 0x0020
|
||||
#define TMIO_STAT0_WRPROTECT 0x0080
|
||||
#define TMIO_STAT0_CARD_REMOVE_A 0x0100
|
||||
#define TMIO_STAT0_CARD_INSERT_A 0x0200
|
||||
#define TMIO_STAT0_SIGSTATE_A 0x0400
|
||||
#define TMIO_STAT1_CMD_IDX_ERR 0x0001
|
||||
#define TMIO_STAT1_CRCFAIL 0x0002
|
||||
#define TMIO_STAT1_STOPBIT_ERR 0x0004
|
||||
#define TMIO_STAT1_DATATIMEOUT 0x0008
|
||||
#define TMIO_STAT1_RXOVERFLOW 0x0010
|
||||
#define TMIO_STAT1_TXUNDERRUN 0x0020
|
||||
#define TMIO_STAT1_CMDTIMEOUT 0x0040
|
||||
#define TMIO_STAT1_RXRDY 0x0100
|
||||
#define TMIO_STAT1_TXRQ 0x0200
|
||||
#define TMIO_STAT1_ILL_FUNC 0x2000
|
||||
#define TMIO_STAT1_CMD_BUSY 0x4000
|
||||
#define TMIO_STAT1_ILL_ACCESS 0x8000
|
||||
#define TMIO_STAT0_CMDRESPEND (0x0001)
|
||||
#define TMIO_STAT0_DATAEND (0x0004)
|
||||
#define TMIO_STAT0_CARD_REMOVE (0x0008)
|
||||
#define TMIO_STAT0_CARD_INSERT (0x0010)
|
||||
#define TMIO_STAT0_SIGSTATE (0x0020)
|
||||
#define TMIO_STAT0_WRPROTECT (0x0080)
|
||||
#define TMIO_STAT0_CARD_REMOVE_A (0x0100)
|
||||
#define TMIO_STAT0_CARD_INSERT_A (0x0200)
|
||||
#define TMIO_STAT0_SIGSTATE_A (0x0400)
|
||||
#define TMIO_STAT1_CMD_IDX_ERR (0x0001)
|
||||
#define TMIO_STAT1_CRCFAIL (0x0002)
|
||||
#define TMIO_STAT1_STOPBIT_ERR (0x0004)
|
||||
#define TMIO_STAT1_DATATIMEOUT (0x0008)
|
||||
#define TMIO_STAT1_RXOVERFLOW (0x0010)
|
||||
#define TMIO_STAT1_TXUNDERRUN (0x0020)
|
||||
#define TMIO_STAT1_CMDTIMEOUT (0x0040)
|
||||
#define TMIO_STAT1_RXRDY (0x0100)
|
||||
#define TMIO_STAT1_TXRQ (0x0200)
|
||||
#define TMIO_STAT1_ILL_FUNC (0x2000)
|
||||
#define TMIO_STAT1_CMD_BUSY (0x4000)
|
||||
#define TMIO_STAT1_ILL_ACCESS (0x8000)
|
||||
|
||||
#define TMIO_MASK_ALL 0x837F031D
|
||||
#define TMIO_MASK_ALL (0x837F031D)
|
||||
|
||||
#define TMIO_MASK_GW (TMIO_STAT1_ILL_ACCESS | TMIO_STAT1_CMDTIMEOUT | TMIO_STAT1_TXUNDERRUN | TMIO_STAT1_RXOVERFLOW | \
|
||||
TMIO_STAT1_DATATIMEOUT | TMIO_STAT1_STOPBIT_ERR | TMIO_STAT1_CRCFAIL | TMIO_STAT1_CMD_IDX_ERR)
|
||||
@ -74,6 +98,12 @@
|
||||
#define TMIO_MASK_READOP (TMIO_STAT1_RXRDY | TMIO_STAT1_DATAEND)
|
||||
#define TMIO_MASK_WRITEOP (TMIO_STAT1_TXRQ | TMIO_STAT1_DATAEND)
|
||||
|
||||
#define SD_WRITE_PROTECTED (((*((vu16*)(SDMMC_BASE + REG_SDSTATUS0))) & (1 << 7 | 1 << 5)) == (1 << 5))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct mmcdevice {
|
||||
u8* rData;
|
||||
const u8* tData;
|
||||
@ -91,10 +121,62 @@ typedef struct mmcdevice {
|
||||
u32 res;
|
||||
} mmcdevice;
|
||||
|
||||
u32 sdmmc_sdcard_init();
|
||||
void sdmmc_init();
|
||||
int sdmmc_sdcard_readsector(u32 sector_no, u8 *out);
|
||||
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
||||
int sdmmc_sdcard_writesector(u32 sector_no, const u8 *in);
|
||||
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
|
||||
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
||||
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
void sdmmc_get_cid(bool isNand, u32 *info);
|
||||
|
||||
int sdmmc_get_cid(bool isNand, u32 *info);
|
||||
|
||||
mmcdevice *getMMCDevice(int drive);
|
||||
|
||||
int Nand_Init();
|
||||
int SD_Init();
|
||||
u32 sdmmc_sdcard_init();
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static inline u16 sdmmc_read16(u16 reg) {
|
||||
//---------------------------------------------------------------------------------
|
||||
return *(volatile u16*)(SDMMC_BASE + reg);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static inline void sdmmc_write16(u16 reg, u16 val) {
|
||||
//---------------------------------------------------------------------------------
|
||||
*(volatile u16*)(SDMMC_BASE + reg) = val;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static inline u32 sdmmc_read32(u16 reg) {
|
||||
//---------------------------------------------------------------------------------
|
||||
return *(volatile u32*)(SDMMC_BASE + reg);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static inline void sdmmc_write32(u16 reg, u32 val) {
|
||||
//---------------------------------------------------------------------------------
|
||||
*(volatile u32*)(SDMMC_BASE + reg) = val;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
static inline void sdmmc_mask16(u16 reg, const u16 clear, const u16 set) {
|
||||
//---------------------------------------------------------------------------------
|
||||
u16 val = sdmmc_read16(reg);
|
||||
val &= ~clear;
|
||||
val |= set;
|
||||
sdmmc_write16(reg, val);
|
||||
}
|
||||
|
||||
static inline void setckl(u32 data)
|
||||
{
|
||||
sdmmc_write16(REG_SDCLKCTL, data & 0xFF);
|
||||
sdmmc_write16(REG_SDCLKCTL, 1u<<8 | (data & 0x2FF));
|
||||
}
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
#include "../../types.h"
|
||||
|
||||
void waitcycles(u32 us);
|
||||
void wait_cycles(u32 us);
|
11
source/fatfs/sdmmc/wait_cycles.s
Normal file
11
source/fatfs/sdmmc/wait_cycles.s
Normal file
@ -0,0 +1,11 @@
|
||||
.arm
|
||||
|
||||
.section .text.wait_cycles, "ax", %progbits
|
||||
.align 2
|
||||
.global wait_cycles
|
||||
.type wait_cycles, %function
|
||||
wait_cycles:
|
||||
subs r0, #2
|
||||
nop
|
||||
bgt wait_cycles
|
||||
bx lr
|
Reference in New Issue
Block a user