Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25218795b4 | ||
|
|
a65ec67128 | ||
|
|
5d753f2384 | ||
|
|
1f2de35f94 | ||
|
|
5c140b4f35 | ||
|
|
362ee3cdb0 | ||
|
|
215f1bc8ee | ||
|
|
4d72c2b37a | ||
|
|
dc4dbe29ae | ||
|
|
72dd25a99e | ||
|
|
39d041466d | ||
|
|
442ebff829 | ||
|
|
7e169bc7df | ||
|
|
00f4e5158f | ||
|
|
0c688189f6 | ||
|
|
7cee36544c | ||
|
|
f9c1d5fc1b | ||
|
|
d95e20952c | ||
|
|
32a90334bb | ||
|
|
f534d3498e | ||
|
|
3ea9f444db | ||
|
|
5672c935ed | ||
|
|
4cc2b5c38a | ||
|
|
00e3d874e3 | ||
|
|
803e91a8c4 | ||
|
|
227a1d938d | ||
|
|
fc7f06dc78 | ||
|
|
6777dd9b38 | ||
|
|
4db212ea7b | ||
|
|
8177a27db9 | ||
|
|
27ff119ba6 | ||
|
|
c20774ff5d | ||
|
|
a9f5b7728b | ||
|
|
08ad48fbf3 | ||
|
|
2d0c881ffe | ||
|
|
c916a7db88 | ||
|
|
a5da286351 | ||
|
|
20a48c3a26 | ||
|
|
5bba0f47ff | ||
|
|
bfc987abcd | ||
|
|
85bf7c86e0 | ||
|
|
2225b86eea | ||
|
|
d09be18359 | ||
|
|
09ab3efddd | ||
|
|
382a0192f9 | ||
|
|
e3b968fa80 | ||
|
|
6f85b11fcc | ||
|
|
e561919a52 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "common/include/boost"]
|
||||
path = common/include/boost
|
||||
url = https://github.com/Atmosphere-NX/ext-boost.git
|
||||
[submodule "stratosphere/libstratosphere"]
|
||||
path = stratosphere/libstratosphere
|
||||
url = https://github.com/Atmosphere-NX/libstratosphere.git
|
||||
|
||||
1
Makefile
1
Makefile
@@ -57,6 +57,7 @@ dist: all
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000037
|
||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
|
||||
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
|
||||
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
|
||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
|
||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/sept/payload.bin
|
||||
cp sept/sept-primary/sept-primary.bin atmosphere-$(AMSVER)/sept/sept-primary.bin
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
BCT0
|
||||
[stage1]
|
||||
stage2_path = atmosphere/fusee-secondary.bin
|
||||
stage2_mtc_path = atmosphere/fusee-mtc.bin
|
||||
stage2_addr = 0xF0000000
|
||||
stage2_entrypoint = 0xF0000000
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ fatal_auto_reboot_interval = u64!0x0
|
||||
; Make the power menu's "reboot" button reboot to payload.
|
||||
; Set to "normal" for normal reboot, "rcm" for rcm reboot.
|
||||
power_menu_reboot_function = str!payload
|
||||
; Controls whether dmnt cheats should be toggled on or off by
|
||||
; Controls whether dmnt cheats should be toggled on or off by
|
||||
; default. 1 = toggled on by default, 0 = toggled off by default.
|
||||
dmnt_cheats_enabled_by_default = u8!0x1
|
||||
; Controls whether dmnt should always save cheat toggle state
|
||||
@@ -28,4 +28,13 @@ dmnt_always_save_cheat_toggles = u8!0x0
|
||||
; 0 = Do not redirect, 1 = Redirect.
|
||||
; NOTE: EXPERIMENTAL
|
||||
; If you do not know what you are doing, do not touch this yet.
|
||||
fsmitm_redirect_saves_to_sd = u8!0x0
|
||||
fsmitm_redirect_saves_to_sd = u8!0x0
|
||||
[hbloader]
|
||||
; Controls the size of the homebrew heap when running as applet.
|
||||
; If set to zero, all available applet memory is used as heap.
|
||||
; The default is zero.
|
||||
applet_heap_size = u64!0x0
|
||||
; Controls the amount of memory to reserve when running as applet
|
||||
; for usage by other applets. This setting has no effect if
|
||||
; applet_heap_size is non-zero. The default is zero.
|
||||
applet_heap_reservation_size = u64!0x8000000
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 0
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 9
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 2
|
||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 3
|
||||
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 8
|
||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
# Changelog
|
||||
## 0.9.3
|
||||
+ Thanks to hexkyz, fusee's boot sequence has been greatly optimized.
|
||||
+ Memory training is now managed by a separate binary (`fusee-mtc`, loaded by fusee-primary before fusee-secondary).
|
||||
+ Unnecessarily long splash screen display times were reduced.
|
||||
+ The end result is that Atmosphere now boots *significantly* faster. :)
|
||||
+ **Note:** This means fusee-primary must be updated for Atmosphere to boot successfully.
|
||||
+ The version string was adjusted, and now informs users whether or not they are using emummc.
|
||||
+ Atmosphere now automatically backs up the user's BIS keys on boot.
|
||||
+ This should prevent a user from corrupting nand without access to a copy of the keys needed to fix it.
|
||||
+ This is especially relevant on ipatched units, where the RCM vulnerability is not an option for addressing bricks.
|
||||
+ The `pm` system module was rewritten as part of Stratosphere's ongoing refactor.
|
||||
+ Support was added for forward-declaring a mitm'd service before a custom user sysmodule is launched.
|
||||
+ This should help resolve dependency issues with service registration times.
|
||||
+ SM is now informed of every process's title id, including built-in system modules.
|
||||
+ The `creport` system module was rewritten as part of Stratosphere's ongoing refactor.
|
||||
+ creport now dumps up to 0x100 of stack from each thread in the target process.
|
||||
+ A few bugs were fixed, including one that caused creport to incorrectly dump process dying messages.
|
||||
+ Defaults were added to `system_settings.ini` for controlling hbloader's memory usage in applet mode.
|
||||
+ These defaults reserve enough memory so that homebrew can launch swkbd while in applet mode.
|
||||
+ The `fatal` system module was rewritten as part of Stratosphere's ongoing refactor.
|
||||
+ Incorrect display output ("2000-0000") has been fixed. Fatal will now correctly show 2162-0002 when this occurs.
|
||||
+ A longstanding bug in how fatal manages the displays has been fixed, and official display init behavior is now matched precisely.
|
||||
+ General system stability improvements to enhance the user's experience.
|
||||
## 0.9.2
|
||||
+ A number of emummc bugfixes were added (all thanks to @m4xw's hard work). The following is a summary of emummc changes:
|
||||
+ Support for file-based emummc instances was fixed.
|
||||
|
||||
@@ -79,7 +79,7 @@ typedef enum {
|
||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
||||
CARDEVICE_UNK = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||
|
||||
@@ -215,7 +215,7 @@ void bootup_misc_mmio(void) {
|
||||
|
||||
if (!g_has_booted_up) {
|
||||
/* N doesn't do this, but we should for compatibility. */
|
||||
uart_select(UART_A);
|
||||
uart_config(UART_A);
|
||||
clkrst_reboot(CARDEVICE_UARTA);
|
||||
uart_init(UART_A, 115200);
|
||||
|
||||
|
||||
@@ -14,25 +14,56 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "i2c.h"
|
||||
#include "utils.h"
|
||||
#include "timers.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
/* Prototypes for internal commands. */
|
||||
volatile i2c_registers_t *i2c_get_registers_from_id(unsigned int id);
|
||||
void i2c_load_config(volatile i2c_registers_t *regs);
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
|
||||
void i2c_load_config(volatile tegra_i2c_t *regs);
|
||||
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t src_size);
|
||||
bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t dst_size);
|
||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
|
||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
|
||||
|
||||
/* Configure I2C pinmux. */
|
||||
void i2c_config(I2CDevice id) {
|
||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_2:
|
||||
pinmux->gen2_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen2_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_3:
|
||||
pinmux->gen3_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen3_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_4:
|
||||
pinmux->cam_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->cam_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_5:
|
||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_6:
|
||||
/* Unused. */
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize I2C based on registers. */
|
||||
void i2c_init(unsigned int id) {
|
||||
volatile i2c_registers_t *regs = i2c_get_registers_from_id(id);
|
||||
void i2c_init(I2CDevice id) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
|
||||
/* Setup divisor, and clear the bus. */
|
||||
regs->I2C_I2C_CLK_DIVISOR_REGISTER_0 = 0x50001;
|
||||
@@ -61,16 +92,16 @@ void i2c_init(unsigned int id) {
|
||||
void i2c_send_pmic_cpu_shutdown_cmd(void) {
|
||||
uint32_t val = 0;
|
||||
/* PMIC == Device 4:3C. */
|
||||
i2c_query(4, 0x3C, 0x41, &val, 1);
|
||||
i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
|
||||
val |= 4;
|
||||
i2c_send(4, 0x3C, 0x41, &val, 1);
|
||||
i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, 0x41, &val, 1);
|
||||
}
|
||||
|
||||
/* Queries the value of TI charger bit over I2C. */
|
||||
bool i2c_query_ti_charger_bit_7(void) {
|
||||
uint32_t val = 0;
|
||||
/* TI Charger = Device 0:6B. */
|
||||
i2c_query(0, 0x6B, 0, &val, 1);
|
||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
||||
return (val & 0x80) != 0;
|
||||
}
|
||||
|
||||
@@ -78,34 +109,34 @@ bool i2c_query_ti_charger_bit_7(void) {
|
||||
void i2c_clear_ti_charger_bit_7(void) {
|
||||
uint32_t val = 0;
|
||||
/* TI Charger = Device 0:6B. */
|
||||
i2c_query(0, 0x6B, 0, &val, 1);
|
||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
||||
val &= 0x7F;
|
||||
i2c_send(0, 0x6B, 0, &val, 1);
|
||||
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
||||
}
|
||||
|
||||
/* Sets TI charger bit over I2C. */
|
||||
void i2c_set_ti_charger_bit_7(void) {
|
||||
uint32_t val = 0;
|
||||
/* TI Charger = Device 0:6B. */
|
||||
i2c_query(0, 0x6B, 0, &val, 1);
|
||||
i2c_query(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
||||
val |= 0x80;
|
||||
i2c_send(0, 0x6B, 0, &val, 1);
|
||||
i2c_send(I2C_1, BQ24193_I2C_ADDR, 0, &val, 1);
|
||||
}
|
||||
|
||||
/* Get registers pointer based on I2C ID. */
|
||||
volatile i2c_registers_t *i2c_get_registers_from_id(unsigned int id) {
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
case I2C_1:
|
||||
return I2C1_REGS;
|
||||
case 1:
|
||||
case I2C_2:
|
||||
return I2C2_REGS;
|
||||
case 2:
|
||||
case I2C_3:
|
||||
return I2C3_REGS;
|
||||
case 3:
|
||||
case I2C_4:
|
||||
return I2C4_REGS;
|
||||
case 4:
|
||||
case I2C_5:
|
||||
return I2C5_REGS;
|
||||
case 5:
|
||||
case I2C_6:
|
||||
return I2C6_REGS;
|
||||
default:
|
||||
generic_panic();
|
||||
@@ -114,7 +145,7 @@ volatile i2c_registers_t *i2c_get_registers_from_id(unsigned int id) {
|
||||
}
|
||||
|
||||
/* Load hardware config for I2C4. */
|
||||
void i2c_load_config(volatile i2c_registers_t *regs) {
|
||||
void i2c_load_config(volatile tegra_i2c_t *regs) {
|
||||
/* Set MSTR_CONFIG_LOAD, TIMEOUT_CONFIG_LOAD, undocumented bit. */
|
||||
regs->I2C_I2C_CONFIG_LOAD_0 = 0x25;
|
||||
|
||||
@@ -128,8 +159,8 @@ void i2c_load_config(volatile i2c_registers_t *regs) {
|
||||
}
|
||||
|
||||
/* Reads a register from a device over I2C, writes result to output. */
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
volatile i2c_registers_t *regs = i2c_get_registers_from_id(id);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
uint32_t val = r;
|
||||
|
||||
/* Write single byte register ID to device. */
|
||||
@@ -145,7 +176,7 @@ bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst
|
||||
}
|
||||
|
||||
/* Writes a value to a register over I2C. */
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
uint32_t val = r;
|
||||
if (src_size == 0) {
|
||||
return true;
|
||||
@@ -158,7 +189,7 @@ bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_
|
||||
}
|
||||
|
||||
/* Writes bytes to device over I2C. */
|
||||
bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t src_size) {
|
||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size) {
|
||||
if (src_size > 4) {
|
||||
return false;
|
||||
} else if (src_size == 0) {
|
||||
@@ -177,8 +208,7 @@ bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t
|
||||
i2c_load_config(regs);
|
||||
|
||||
/* Config |= SEND; */
|
||||
regs->I2C_I2C_CNFG_0 |= 0x200;
|
||||
|
||||
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
|
||||
|
||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
||||
/* Wait until not busy. */
|
||||
@@ -189,7 +219,7 @@ bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t
|
||||
}
|
||||
|
||||
/* Reads bytes from device over I2C. */
|
||||
bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t dst_size) {
|
||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size) {
|
||||
if (dst_size > 4) {
|
||||
return false;
|
||||
} else if (dst_size == 0) {
|
||||
@@ -205,8 +235,7 @@ bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t
|
||||
i2c_load_config(regs);
|
||||
|
||||
/* Config |= SEND; */
|
||||
regs->I2C_I2C_CNFG_0 |= 0x200;
|
||||
|
||||
regs->I2C_I2C_CNFG_0 = ((regs->I2C_I2C_CNFG_0 & 0xFFFFFDFF) | 0x200);
|
||||
|
||||
while (regs->I2C_I2C_STATUS_0 & 0x100) {
|
||||
/* Wait until not busy. */
|
||||
|
||||
@@ -19,10 +19,27 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "memory_map.h"
|
||||
|
||||
/* Exosphere driver for the Tegra X1 I2C registers. */
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
#define MAX17050_I2C_ADDR 0x36
|
||||
#define MAX77620_PWR_I2C_ADDR 0x3C
|
||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
typedef enum {
|
||||
I2C_1 = 0,
|
||||
I2C_2 = 1,
|
||||
I2C_3 = 2,
|
||||
I2C_4 = 3,
|
||||
I2C_5 = 4,
|
||||
I2C_6 = 5,
|
||||
} I2CDevice;
|
||||
|
||||
typedef struct {
|
||||
uint32_t I2C_I2C_CNFG_0;
|
||||
uint32_t I2C_I2C_CMD_ADDR0_0;
|
||||
@@ -65,7 +82,7 @@ typedef struct {
|
||||
uint32_t I2C_I2C_INTERFACE_TIMING_1_0;
|
||||
uint32_t I2C_I2C_HS_INTERFACE_TIMING_0_0;
|
||||
uint32_t I2C_I2C_HS_INTERFACE_TIMING_1_0;
|
||||
} i2c_registers_t;
|
||||
} tegra_i2c_t;
|
||||
|
||||
static inline uintptr_t get_i2c_dtv_234_base(void) {
|
||||
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DTV_I2C234);
|
||||
@@ -75,17 +92,20 @@ static inline uintptr_t get_i2c56_spi2b_base(void) {
|
||||
return MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_I2C56_SPI2B);
|
||||
}
|
||||
|
||||
#define I2C1_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x000))
|
||||
#define I2C2_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x400))
|
||||
#define I2C3_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x500))
|
||||
#define I2C4_REGS ((volatile i2c_registers_t *)(get_i2c_dtv_234_base() + 0x700))
|
||||
#define I2C5_REGS ((volatile i2c_registers_t *)(get_i2c56_spi2b_base() + 0x000))
|
||||
#define I2C6_REGS ((volatile i2c_registers_t *)(get_i2c56_spi2b_base() + 0x100))
|
||||
#define I2C1_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x000))
|
||||
#define I2C2_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x400))
|
||||
#define I2C3_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x500))
|
||||
#define I2C4_REGS ((volatile tegra_i2c_t *)(get_i2c_dtv_234_base() + 0x700))
|
||||
#define I2C5_REGS ((volatile tegra_i2c_t *)(get_i2c56_spi2b_base() + 0x000))
|
||||
#define I2C6_REGS ((volatile tegra_i2c_t *)(get_i2c56_spi2b_base() + 0x100))
|
||||
|
||||
void i2c_init(unsigned int id);
|
||||
void i2c_config(I2CDevice id);
|
||||
|
||||
void i2c_init(I2CDevice id);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
void i2c_send_pmic_cpu_shutdown_cmd(void);
|
||||
|
||||
bool i2c_query_ti_charger_bit_7(void);
|
||||
void i2c_clear_ti_charger_bit_7(void);
|
||||
void i2c_set_ti_charger_bit_7(void);
|
||||
|
||||
@@ -18,26 +18,15 @@
|
||||
#define EXOSPHERE_MISC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "memory_map.h"
|
||||
|
||||
/* Exosphere driver for the Tegra X1 MISC Registers. */
|
||||
|
||||
#define MISC_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MISC))
|
||||
|
||||
#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n)
|
||||
|
||||
|
||||
#define APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 MAKE_MISC_REG(0x0C00)
|
||||
#define APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 MAKE_MISC_REG(0x0C04)
|
||||
#define APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 MAKE_MISC_REG(0x0C08)
|
||||
|
||||
#define PINMUX_AUX_GEN1_I2C_SCL_0 MAKE_MISC_REG(0x30BC)
|
||||
#define PINMUX_AUX_GEN1_I2C_SDA_0 MAKE_MISC_REG(0x30C0)
|
||||
|
||||
#define PINMUX_AUX_UARTn_TX_0(n) MAKE_MISC_REG(0x30E4 + 0x10 * (n))
|
||||
#define PINMUX_AUX_UARTn_RX_0(n) MAKE_MISC_REG(0x30E8 + 0x10 * (n))
|
||||
#define PINMUX_AUX_UARTn_RTS_0(n) MAKE_MISC_REG(0x30EC + 0x10 * (n))
|
||||
#define PINMUX_AUX_UARTn_CTS_0(n) MAKE_MISC_REG(0x30F0 + 0x10 * (n))
|
||||
|
||||
#endif
|
||||
|
||||
214
exosphere/src/pinmux.h
Normal file
214
exosphere/src/pinmux.h
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef EXOSPHERE_PINMUX_H
|
||||
#define EXOSPHERE_PINMUX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "memory_map.h"
|
||||
|
||||
#define PINMUX_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_MISC) + 0x3000)
|
||||
#define MAKE_PINMUX_REG(n) MAKE_REG32(PINMUX_BASE + n)
|
||||
|
||||
#define PINMUX_TRISTATE (1 << 4)
|
||||
#define PINMUX_PARKED (1 << 5)
|
||||
#define PINMUX_INPUT (1 << 6)
|
||||
#define PINMUX_PULL_NONE (0 << 2)
|
||||
#define PINMUX_PULL_DOWN (1 << 2)
|
||||
#define PINMUX_PULL_UP (2 << 2)
|
||||
#define PINMUX_SELECT_FUNCTION0 0
|
||||
#define PINMUX_SELECT_FUNCTION1 1
|
||||
#define PINMUX_SELECT_FUNCTION2 2
|
||||
#define PINMUX_SELECT_FUNCTION3 3
|
||||
#define PINMUX_DRIVE_1X (0 << 13)
|
||||
#define PINMUX_DRIVE_2X (1 << 13)
|
||||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
||||
typedef struct {
|
||||
uint32_t sdmmc1_clk;
|
||||
uint32_t sdmmc1_cmd;
|
||||
uint32_t sdmmc1_dat3;
|
||||
uint32_t sdmmc1_dat2;
|
||||
uint32_t sdmmc1_dat1;
|
||||
uint32_t sdmmc1_dat0;
|
||||
uint32_t _r18;
|
||||
uint32_t sdmmc3_clk;
|
||||
uint32_t sdmmc3_cmd;
|
||||
uint32_t sdmmc3_dat0;
|
||||
uint32_t sdmmc3_dat1;
|
||||
uint32_t sdmmc3_dat2;
|
||||
uint32_t sdmmc3_dat3;
|
||||
uint32_t _r34;
|
||||
uint32_t pex_l0_rst_n;
|
||||
uint32_t pex_l0_clkreq_n;
|
||||
uint32_t pex_wake_n;
|
||||
uint32_t pex_l1_rst_n;
|
||||
uint32_t pex_l1_clkreq_n;
|
||||
uint32_t sata_led_active;
|
||||
uint32_t spi1_mosi;
|
||||
uint32_t spi1_miso;
|
||||
uint32_t spi1_sck;
|
||||
uint32_t spi1_cs0;
|
||||
uint32_t spi1_cs1;
|
||||
uint32_t spi2_mosi;
|
||||
uint32_t spi2_miso;
|
||||
uint32_t spi2_sck;
|
||||
uint32_t spi2_cs0;
|
||||
uint32_t spi2_cs1;
|
||||
uint32_t spi4_mosi;
|
||||
uint32_t spi4_miso;
|
||||
uint32_t spi4_sck;
|
||||
uint32_t spi4_cs0;
|
||||
uint32_t qspi_sck;
|
||||
uint32_t qspi_cs_n;
|
||||
uint32_t qspi_io0;
|
||||
uint32_t qspi_io1;
|
||||
uint32_t qspi_io2;
|
||||
uint32_t qspi_io3;
|
||||
uint32_t _ra0;
|
||||
uint32_t dmic1_clk;
|
||||
uint32_t dmic1_dat;
|
||||
uint32_t dmic2_clk;
|
||||
uint32_t dmic2_dat;
|
||||
uint32_t dmic3_clk;
|
||||
uint32_t dmic3_dat;
|
||||
uint32_t gen1_i2c_scl;
|
||||
uint32_t gen1_i2c_sda;
|
||||
uint32_t gen2_i2c_scl;
|
||||
uint32_t gen2_i2c_sda;
|
||||
uint32_t gen3_i2c_scl;
|
||||
uint32_t gen3_i2c_sda;
|
||||
uint32_t cam_i2c_scl;
|
||||
uint32_t cam_i2c_sda;
|
||||
uint32_t pwr_i2c_scl;
|
||||
uint32_t pwr_i2c_sda;
|
||||
uint32_t uart1_tx;
|
||||
uint32_t uart1_rx;
|
||||
uint32_t uart1_rts;
|
||||
uint32_t uart1_cts;
|
||||
uint32_t uart2_tx;
|
||||
uint32_t uart2_rx;
|
||||
uint32_t uart2_rts;
|
||||
uint32_t uart2_cts;
|
||||
uint32_t uart3_tx;
|
||||
uint32_t uart3_rx;
|
||||
uint32_t uart3_rts;
|
||||
uint32_t uart3_cts;
|
||||
uint32_t uart4_tx;
|
||||
uint32_t uart4_rx;
|
||||
uint32_t uart4_rts;
|
||||
uint32_t uart4_cts;
|
||||
uint32_t dap1_fs;
|
||||
uint32_t dap1_din;
|
||||
uint32_t dap1_dout;
|
||||
uint32_t dap1_sclk;
|
||||
uint32_t dap2_fs;
|
||||
uint32_t dap2_din;
|
||||
uint32_t dap2_dout;
|
||||
uint32_t dap2_sclk;
|
||||
uint32_t dap4_fs;
|
||||
uint32_t dap4_din;
|
||||
uint32_t dap4_dout;
|
||||
uint32_t dap4_sclk;
|
||||
uint32_t cam1_mclk;
|
||||
uint32_t cam2_mclk;
|
||||
uint32_t jtag_rtck;
|
||||
uint32_t clk_32k_in;
|
||||
uint32_t clk_32k_out;
|
||||
uint32_t batt_bcl;
|
||||
uint32_t clk_req;
|
||||
uint32_t cpu_pwr_req;
|
||||
uint32_t pwr_int_n;
|
||||
uint32_t shutdown;
|
||||
uint32_t core_pwr_req;
|
||||
uint32_t aud_mclk;
|
||||
uint32_t dvfs_pwm;
|
||||
uint32_t dvfs_clk;
|
||||
uint32_t gpio_x1_aud;
|
||||
uint32_t gpio_x3_aud;
|
||||
uint32_t pcc7;
|
||||
uint32_t hdmi_cec;
|
||||
uint32_t hdmi_int_dp_hpd;
|
||||
uint32_t spdif_out;
|
||||
uint32_t spdif_in;
|
||||
uint32_t usb_vbus_en0;
|
||||
uint32_t usb_vbus_en1;
|
||||
uint32_t dp_hpd0;
|
||||
uint32_t wifi_en;
|
||||
uint32_t wifi_rst;
|
||||
uint32_t wifi_wake_ap;
|
||||
uint32_t ap_wake_bt;
|
||||
uint32_t bt_rst;
|
||||
uint32_t bt_wake_ap;
|
||||
uint32_t ap_wake_nfc;
|
||||
uint32_t nfc_en;
|
||||
uint32_t nfc_int;
|
||||
uint32_t gps_en;
|
||||
uint32_t gps_rst;
|
||||
uint32_t cam_rst;
|
||||
uint32_t cam_af_en;
|
||||
uint32_t cam_flash_en;
|
||||
uint32_t cam1_pwdn;
|
||||
uint32_t cam2_pwdn;
|
||||
uint32_t cam1_strobe;
|
||||
uint32_t lcd_te;
|
||||
uint32_t lcd_bl_pwm;
|
||||
uint32_t lcd_bl_en;
|
||||
uint32_t lcd_rst;
|
||||
uint32_t lcd_gpio1;
|
||||
uint32_t lcd_gpio2;
|
||||
uint32_t ap_ready;
|
||||
uint32_t touch_rst;
|
||||
uint32_t touch_clk;
|
||||
uint32_t modem_wake_ap;
|
||||
uint32_t touch_int;
|
||||
uint32_t motion_int;
|
||||
uint32_t als_prox_int;
|
||||
uint32_t temp_alert;
|
||||
uint32_t button_power_on;
|
||||
uint32_t button_vol_up;
|
||||
uint32_t button_vol_down;
|
||||
uint32_t button_slide_sw;
|
||||
uint32_t button_home;
|
||||
uint32_t pa6;
|
||||
uint32_t pe6;
|
||||
uint32_t pe7;
|
||||
uint32_t ph6;
|
||||
uint32_t pk0;
|
||||
uint32_t pk1;
|
||||
uint32_t pk2;
|
||||
uint32_t pk3;
|
||||
uint32_t pk4;
|
||||
uint32_t pk5;
|
||||
uint32_t pk6;
|
||||
uint32_t pk7;
|
||||
uint32_t pl0;
|
||||
uint32_t pl1;
|
||||
uint32_t pz0;
|
||||
uint32_t pz1;
|
||||
uint32_t pz2;
|
||||
uint32_t pz3;
|
||||
uint32_t pz4;
|
||||
uint32_t pz5;
|
||||
} tegra_pinmux_t;
|
||||
|
||||
static inline volatile tegra_pinmux_t *pinmux_get_regs(void)
|
||||
{
|
||||
return (volatile tegra_pinmux_t *)PINMUX_BASE;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,66 +15,120 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "timers.h"
|
||||
#include "uart.h"
|
||||
#include "misc.h"
|
||||
#include "timers.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
void uart_select(UartDevice dev) {
|
||||
unsigned int id = (unsigned int)dev;
|
||||
PINMUX_AUX_UARTn_TX_0(id) = 0; /* UART */
|
||||
PINMUX_AUX_UARTn_RX_0(id) = 0x48; /* UART, enable, pull up */
|
||||
PINMUX_AUX_UARTn_RTS_0(id) = 0; /* UART */
|
||||
PINMUX_AUX_UARTn_CTS_0(id) = 0x44; /* UART, enable, pull down */
|
||||
static inline void uart_wait_cycles(uint32_t baud, uint32_t num)
|
||||
{
|
||||
wait((num * 1000000 + 16 * baud - 1) / (16 * baud));
|
||||
}
|
||||
|
||||
static inline void uart_wait_syms(uint32_t baud, uint32_t num)
|
||||
{
|
||||
wait((num * 1000000 + baud - 1) / baud);
|
||||
}
|
||||
|
||||
void uart_config(UartDevice dev) {
|
||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||
|
||||
switch (dev) {
|
||||
case UART_A:
|
||||
pinmux->uart1_tx = 0;
|
||||
pinmux->uart1_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart1_rts = 0;
|
||||
pinmux->uart1_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_B:
|
||||
pinmux->uart2_tx = 0;
|
||||
pinmux->uart2_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart2_rts = 0;
|
||||
pinmux->uart2_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_C:
|
||||
pinmux->uart3_tx = 0;
|
||||
pinmux->uart3_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart3_rts = 0;
|
||||
pinmux->uart3_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_D:
|
||||
pinmux->uart4_tx = 0;
|
||||
pinmux->uart4_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart4_rts = 0;
|
||||
pinmux->uart4_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_E:
|
||||
/* Unused. */
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_init(UartDevice dev, uint32_t baud) {
|
||||
volatile uart_t *uart = get_uart_device(dev);
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
/* Set baud rate. */
|
||||
/* Wait for idle state. */
|
||||
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE);
|
||||
|
||||
/* Calculate baud rate, round to nearest. */
|
||||
uint32_t rate = (8 * baud + 408000000) / (16 * baud);
|
||||
uart->UART_LCR = UART_LCR_DLAB; /* Enable DLAB. */
|
||||
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
|
||||
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
|
||||
uart->UART_LCR = 0; /* Diable DLAB. */
|
||||
|
||||
/* Setup UART in fifo mode. */
|
||||
/* Setup UART in FIFO mode. */
|
||||
uart->UART_IER_DLAB = 0;
|
||||
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO | UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Enable and clear TX and RX FIFOs. */
|
||||
uart->UART_LSR;
|
||||
wait(3 * ((baud + 999999) / baud));
|
||||
uart->UART_LCR = UART_LCR_WD_LENGTH_8; /* Set word length 8. */
|
||||
uart->UART_MCR = 0;
|
||||
uart->UART_MSR = 0;
|
||||
uart->UART_IRDA_CSR = 0;
|
||||
uart->UART_RX_FIFO_CFG = 1; /* Set RX_FIFO trigger level */
|
||||
uart->UART_MIE = 0;
|
||||
uart->UART_ASR = 0;
|
||||
uart->UART_LCR = (UART_LCR_DLAB | UART_LCR_WD_LENGTH_8); /* Enable DLAB and set word length 8. */
|
||||
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
|
||||
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
|
||||
uart->UART_LCR &= ~(UART_LCR_DLAB); /* Disable DLAB. */
|
||||
uart->UART_SPR; /* Dummy read. */
|
||||
uart_wait_syms(baud, 3); /* Wait for 3 symbols at the new baudrate. */
|
||||
|
||||
/* Enable FIFO with default settings. */
|
||||
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO;
|
||||
uart->UART_SPR; /* Dummy read as mandated by TRM. */
|
||||
uart_wait_cycles(baud, 3); /* Wait for 3 baud cycles, as mandated by TRM (erratum). */
|
||||
|
||||
/* Flush FIFO. */
|
||||
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE); /* Make sure there's no data being written in TX FIFO (TRM). */
|
||||
uart->UART_IIR_FCR |= UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Clear TX and RX FIFOs. */
|
||||
uart_wait_cycles(baud, 32); /* Wait for 32 baud cycles (TRM, erratum). */
|
||||
/* Wait for idle state (TRM). */
|
||||
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE | UART_VENDOR_STATE_RX_IDLE);
|
||||
}
|
||||
|
||||
/* This function blocks until the UART device (dev) is in the desired state (status). Make sure the desired state can be reached! */
|
||||
/* This function blocks until the UART device is in the desired state. */
|
||||
void uart_wait_idle(UartDevice dev, UartVendorStatus status) {
|
||||
while (!(get_uart_device(dev)->UART_VENDOR_STATUS & status)) {
|
||||
/* Wait */
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
if (status & UART_VENDOR_STATE_TX_IDLE) {
|
||||
while (!(uart->UART_LSR & UART_LSR_TMTY)) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
if (status & UART_VENDOR_STATE_RX_IDLE) {
|
||||
while (uart->UART_LSR & UART_LSR_RDR) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uart_send(UartDevice dev, const void *buf, size_t len) {
|
||||
volatile uart_t *uart = get_uart_device(dev);
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (uart->UART_LSR & UART_LSR_TX_FIFO_FULL) {
|
||||
/* Wait until the TX FIFO isn't full */
|
||||
while (!(uart->UART_LSR & UART_LSR_THRE)) {
|
||||
/* Wait until it's possible to send data. */
|
||||
}
|
||||
uart->UART_THR_DLAB = *((const uint8_t *)buf + i);
|
||||
}
|
||||
}
|
||||
|
||||
void uart_recv(UartDevice dev, void *buf, size_t len) {
|
||||
volatile uart_t *uart = get_uart_device(dev);
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (uart->UART_LSR & UART_LSR_RX_FIFO_EMPTY) {
|
||||
/* Wait until the RX FIFO isn't empty */
|
||||
while (!(uart->UART_LSR & UART_LSR_RDR)) {
|
||||
/* Wait until it's possible to receive data. */
|
||||
}
|
||||
*((uint8_t *)buf + i) = uart->UART_THR_DLAB;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ static inline uintptr_t get_uart_base(void) {
|
||||
|
||||
#define BAUD_115200 115200
|
||||
|
||||
/* Exosphère: add the clkreset values for UART C,D,E */
|
||||
/* UART devices */
|
||||
typedef enum {
|
||||
UART_A = 0,
|
||||
UART_B = 1,
|
||||
@@ -148,31 +148,31 @@ typedef enum {
|
||||
} UartInterruptIdentification;
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ uint32_t UART_THR_DLAB;
|
||||
/* 0x04 */ uint32_t UART_IER_DLAB;
|
||||
/* 0x08 */ uint32_t UART_IIR_FCR;
|
||||
/* 0x0C */ uint32_t UART_LCR;
|
||||
/* 0x10 */ uint32_t UART_MCR;
|
||||
/* 0x14 */ uint32_t UART_LSR;
|
||||
/* 0x18 */ uint32_t UART_MSR;
|
||||
/* 0x1C */ uint32_t UART_SPR;
|
||||
/* 0x20 */ uint32_t UART_IRDA_CSR;
|
||||
/* 0x24 */ uint32_t UART_RX_FIFO_CFG;
|
||||
/* 0x28 */ uint32_t UART_MIE;
|
||||
/* 0x2C */ uint32_t UART_VENDOR_STATUS;
|
||||
/* 0x30 */ uint8_t _pad_30[0x0C];
|
||||
/* 0x3C */ uint32_t UART_ASR;
|
||||
} uart_t;
|
||||
uint32_t UART_THR_DLAB;
|
||||
uint32_t UART_IER_DLAB;
|
||||
uint32_t UART_IIR_FCR;
|
||||
uint32_t UART_LCR;
|
||||
uint32_t UART_MCR;
|
||||
uint32_t UART_LSR;
|
||||
uint32_t UART_MSR;
|
||||
uint32_t UART_SPR;
|
||||
uint32_t UART_IRDA_CSR;
|
||||
uint32_t UART_RX_FIFO_CFG;
|
||||
uint32_t UART_MIE;
|
||||
uint32_t UART_VENDOR_STATUS;
|
||||
uint8_t _0x30[0x0C];
|
||||
uint32_t UART_ASR;
|
||||
} tegra_uart_t;
|
||||
|
||||
void uart_select(UartDevice dev);
|
||||
void uart_config(UartDevice dev);
|
||||
void uart_init(UartDevice dev, uint32_t baud);
|
||||
void uart_wait_idle(UartDevice dev, UartVendorStatus status);
|
||||
void uart_send(UartDevice dev, const void *buf, size_t len);
|
||||
void uart_recv(UartDevice dev, void *buf, size_t len);
|
||||
|
||||
static inline volatile uart_t *get_uart_device(UartDevice dev) {
|
||||
static inline volatile tegra_uart_t *uart_get_regs(UartDevice dev) {
|
||||
static const size_t offsets[] = {0, 0x40, 0x200, 0x300, 0x400};
|
||||
return (volatile uart_t *)(UART_BASE + offsets[dev]);
|
||||
return (volatile tegra_uart_t *)(UART_BASE + offsets[dev]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "bootup.h"
|
||||
#include "smc_api.h"
|
||||
#include "exocfg.h"
|
||||
|
||||
#include "se.h"
|
||||
#include "mc.h"
|
||||
#include "car.h"
|
||||
@@ -32,7 +31,6 @@
|
||||
#include "misc.h"
|
||||
#include "uart.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
uintptr_t get_warmboot_main_stack_address(void) {
|
||||
@@ -41,8 +39,7 @@ uintptr_t get_warmboot_main_stack_address(void) {
|
||||
|
||||
static void warmboot_configure_hiz_mode(void) {
|
||||
/* Enable input to I2C1 */
|
||||
PINMUX_AUX_GEN1_I2C_SCL_0 = 0x40;
|
||||
PINMUX_AUX_GEN1_I2C_SDA_0 = 0x40;
|
||||
i2c_config(I2C_1);
|
||||
|
||||
clkrst_reboot(CARDEVICE_I2C1);
|
||||
i2c_init(0);
|
||||
@@ -69,7 +66,7 @@ void __attribute__((noreturn)) warmboot_main(void) {
|
||||
if (VIRT_MC_SECURITY_CFG3 == 0) {
|
||||
/* N only does this on dev units, but we will do it unconditionally. */
|
||||
{
|
||||
uart_select(UART_A);
|
||||
uart_config(UART_A);
|
||||
clkrst_reboot(CARDEVICE_UARTA);
|
||||
uart_init(UART_A, 115200);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SUBFOLDERS := fusee-primary fusee-secondary
|
||||
SUBFOLDERS := fusee-primary fusee-mtc fusee-secondary
|
||||
|
||||
TOPTARGETS := all clean
|
||||
|
||||
|
||||
163
fusee/fusee-mtc/Makefile
Normal file
163
fusee/fusee-mtc/Makefile
Normal file
@@ -0,0 +1,163 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
|
||||
AMS := $(TOPDIR)/../../
|
||||
include $(DEVKITARM)/base_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := src src/lib src/display
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
CFLAGS := \
|
||||
-g \
|
||||
-O2 \
|
||||
-fomit-frame-pointer \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-std=gnu11 \
|
||||
-Werror \
|
||||
-Wall \
|
||||
-fstrict-volatile-bitfields \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE)
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS :=
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT).bin
|
||||
|
||||
$(OUTPUT).bin : $(OUTPUT).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
%.elf: $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
@$(NM) -CSn $@ > $(notdir $*.lst)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h: %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
170
fusee/fusee-mtc/linker.ld
Normal file
170
fusee/fusee-mtc/linker.ld
Normal file
@@ -0,0 +1,170 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
crt0 PT_LOAD;
|
||||
main PT_LOAD;
|
||||
}
|
||||
|
||||
/* Mostly copied from https://github.com/devkitPro/buildscripts/blob/master/dkarm-eabi/crtls/3dsx.ld */
|
||||
MEMORY
|
||||
{
|
||||
NULL : ORIGIN = 0x00000000, LENGTH = 0x1000
|
||||
main : ORIGIN = 0xF0000000, LENGTH = 0x10000000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
PROVIDE(__start__ = 0xF0000000);
|
||||
PROVIDE(__stack_bottom__ = 0x90010000);
|
||||
PROVIDE(__stack_top__ = 0x90020000);
|
||||
PROVIDE(__heap_start__ = 0x90020000);
|
||||
PROVIDE(__heap_end__ = 0xA0020000);
|
||||
|
||||
. = __start__;
|
||||
|
||||
.crt0 :
|
||||
{
|
||||
KEEP( *(.text.start) )
|
||||
KEEP( *(.init) )
|
||||
. = ALIGN(32);
|
||||
} >main :crt0
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(32);
|
||||
/* .text */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.stub)
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
|
||||
/* .fini */
|
||||
KEEP( *(.fini) )
|
||||
. = ALIGN(8);
|
||||
} >main :main
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*all.rodata*(*)
|
||||
*(.gnu.linkonce.r*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(8);
|
||||
} >main
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} >main
|
||||
|
||||
.init_array ALIGN(4) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
} >main
|
||||
|
||||
.fini_array ALIGN(4) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} >main
|
||||
|
||||
.ctors ALIGN(4) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >main
|
||||
|
||||
.dtors ALIGN(4) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >main
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) __exidx_start = ABSOLUTE(.);} >main
|
||||
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = ABSOLUTE(.);} >main
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(32);
|
||||
} >main
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(32);
|
||||
PROVIDE (__bss_start__ = ABSOLUTE(.));
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
. = ALIGN(32);
|
||||
PROVIDE (__bss_end__ = ABSOLUTE(.));
|
||||
} >main :NONE
|
||||
__end__ = ABSOLUTE(.) ;
|
||||
|
||||
|
||||
/* ==================
|
||||
==== Metadata ====
|
||||
================== */
|
||||
|
||||
/* Discard sections that difficult post-processing */
|
||||
/DISCARD/ : { *(.group .comment .note) }
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
||||
7
fusee/fusee-mtc/linker.specs
Normal file
7
fusee/fusee-mtc/linker.specs
Normal file
@@ -0,0 +1,7 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
139
fusee/fusee-mtc/src/car.c
Normal file
139
fusee/fusee-mtc/src/car.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 "car.h"
|
||||
#include "timers.h"
|
||||
#include "utils.h"
|
||||
|
||||
static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||
switch (dev) {
|
||||
case CARDEVICE_UARTA: return 0x178;
|
||||
case CARDEVICE_UARTB: return 0x17C;
|
||||
case CARDEVICE_UARTC: return 0x1A0;
|
||||
case CARDEVICE_I2C1: return 0x124;
|
||||
case CARDEVICE_I2C5: return 0x128;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0x42C;
|
||||
case CARDEVICE_HOST1X: return 0x180;
|
||||
case CARDEVICE_TSEC: return 0x1F4;
|
||||
case CARDEVICE_SOR_SAFE: return 0;
|
||||
case CARDEVICE_SOR0: return 0;
|
||||
case CARDEVICE_SOR1: return 0x410;
|
||||
case CARDEVICE_KFUSE: return 0;
|
||||
case CARDEVICE_CL_DVFS: return 0;
|
||||
case CARDEVICE_CORESIGHT: return 0x1D4;
|
||||
case CARDEVICE_ACTMON: return 0x3E8;
|
||||
case CARDEVICE_BPMP: return 0;
|
||||
default: generic_panic();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t get_clk_source_val(CarDevice dev) {
|
||||
switch (dev) {
|
||||
case CARDEVICE_UARTA: return 0;
|
||||
case CARDEVICE_UARTB: return 0;
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 6;
|
||||
case CARDEVICE_I2C5: return 6;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 4;
|
||||
case CARDEVICE_TSEC: return 0;
|
||||
case CARDEVICE_SOR_SAFE: return 0;
|
||||
case CARDEVICE_SOR0: return 0;
|
||||
case CARDEVICE_SOR1: return 0;
|
||||
case CARDEVICE_KFUSE: return 0;
|
||||
case CARDEVICE_CL_DVFS: return 0;
|
||||
case CARDEVICE_CORESIGHT: return 0;
|
||||
case CARDEVICE_ACTMON: return 6;
|
||||
case CARDEVICE_BPMP: return 0;
|
||||
default: generic_panic();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t get_clk_source_div(CarDevice dev) {
|
||||
switch (dev) {
|
||||
case CARDEVICE_UARTA: return 0;
|
||||
case CARDEVICE_UARTB: return 0;
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 0;
|
||||
case CARDEVICE_I2C5: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 3;
|
||||
case CARDEVICE_TSEC: return 2;
|
||||
case CARDEVICE_SOR_SAFE: return 0;
|
||||
case CARDEVICE_SOR0: return 0;
|
||||
case CARDEVICE_SOR1: return 2;
|
||||
case CARDEVICE_KFUSE: return 0;
|
||||
case CARDEVICE_CL_DVFS: return 0;
|
||||
case CARDEVICE_CORESIGHT: return 4;
|
||||
case CARDEVICE_ACTMON: return 0;
|
||||
case CARDEVICE_BPMP: return 0;
|
||||
default: generic_panic();
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t g_clk_reg_offsets[NUM_CAR_BANKS] = {0x010, 0x014, 0x018, 0x360, 0x364, 0x280, 0x298};
|
||||
static uint32_t g_rst_reg_offsets[NUM_CAR_BANKS] = {0x004, 0x008, 0x00C, 0x358, 0x35C, 0x28C, 0x2A4};
|
||||
|
||||
void clk_enable(CarDevice dev) {
|
||||
uint32_t clk_source_reg;
|
||||
if ((clk_source_reg = get_clk_source_reg(dev))) {
|
||||
MAKE_CAR_REG(clk_source_reg) = (get_clk_source_val(dev) << 29) | get_clk_source_div(dev);
|
||||
}
|
||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
||||
}
|
||||
|
||||
void clk_disable(CarDevice dev) {
|
||||
MAKE_CAR_REG(g_clk_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
||||
}
|
||||
|
||||
void rst_enable(CarDevice dev) {
|
||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) |= BIT(dev & 0x1F);
|
||||
}
|
||||
|
||||
void rst_disable(CarDevice dev) {
|
||||
MAKE_CAR_REG(g_rst_reg_offsets[dev >> 5]) &= ~(BIT(dev & 0x1F));
|
||||
}
|
||||
|
||||
void clkrst_enable(CarDevice dev) {
|
||||
clk_enable(dev);
|
||||
rst_disable(dev);
|
||||
}
|
||||
|
||||
void clkrst_disable(CarDevice dev) {
|
||||
rst_enable(dev);
|
||||
clk_disable(dev);
|
||||
}
|
||||
|
||||
void clkrst_reboot(CarDevice dev) {
|
||||
clkrst_disable(dev);
|
||||
if (dev == CARDEVICE_KFUSE) {
|
||||
/* Workaround for KFUSE clock. */
|
||||
clk_enable(dev);
|
||||
udelay(100);
|
||||
rst_disable(dev);
|
||||
udelay(200);
|
||||
} else {
|
||||
clkrst_enable(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void clkrst_enable_fuse_regs(bool enable) {
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
car->misc_clk_enb = ((car->misc_clk_enb & 0xEFFFFFFF) | ((enable & 1) << 28));
|
||||
}
|
||||
505
fusee/fusee-mtc/src/car.h
Normal file
505
fusee/fusee-mtc/src/car.h
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_CAR_H
|
||||
#define FUSEE_CAR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define CAR_BASE 0x60006000
|
||||
#define MAKE_CAR_REG(n) MAKE_REG32(CAR_BASE + n)
|
||||
|
||||
#define CLK_L_SDMMC1 (1 << 14)
|
||||
#define CLK_L_SDMMC2 (1 << 9)
|
||||
#define CLK_U_SDMMC3 (1 << 5)
|
||||
#define CLK_L_SDMMC4 (1 << 15)
|
||||
|
||||
#define CLK_SOURCE_MASK (0b111 << 29)
|
||||
#define CLK_SOURCE_FIRST (0b000 << 29)
|
||||
#define CLK_DIVIDER_MASK (0xff << 0)
|
||||
#define CLK_DIVIDER_UNITY (0x00 << 0)
|
||||
|
||||
#define NUM_CAR_BANKS 7
|
||||
|
||||
/* Clock and reset devices. */
|
||||
typedef enum {
|
||||
CARDEVICE_UARTA = ((0 << 5) | 0x6),
|
||||
CARDEVICE_UARTB = ((0 << 5) | 0x7),
|
||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||
CARDEVICE_SOR_SAFE = ((6 << 5) | 0x1E),
|
||||
CARDEVICE_SOR0 = ((5 << 5) | 0x16),
|
||||
CARDEVICE_SOR1 = ((5 << 5) | 0x17),
|
||||
CARDEVICE_KFUSE = ((1 << 5) | 0x8),
|
||||
CARDEVICE_CL_DVFS = ((4 << 5) | 0x1B),
|
||||
CARDEVICE_CORESIGHT = ((2 << 5) | 0x9),
|
||||
CARDEVICE_ACTMON = ((3 << 5) | 0x17),
|
||||
CARDEVICE_BPMP = ((0 << 5) | 0x1)
|
||||
} CarDevice;
|
||||
|
||||
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
|
||||
typedef struct {
|
||||
uint32_t rst_src; /* _RST_SOURCE_0, 0x00 */
|
||||
|
||||
/* _RST_DEVICES_L/H/U_0 0x4-0xc */
|
||||
uint32_t rst_dev_l;
|
||||
uint32_t rst_dev_h;
|
||||
uint32_t rst_dev_u;
|
||||
|
||||
/* _CLK_OUT_ENB_L/H/U_0 0x10-0x18 */
|
||||
uint32_t clk_out_enb_l;
|
||||
uint32_t clk_out_enb_h;
|
||||
uint32_t clk_out_enb_u;
|
||||
|
||||
uint32_t _0x1C;
|
||||
uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
|
||||
uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0, 0x24 */
|
||||
uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
|
||||
uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0, 0x2c */
|
||||
uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
|
||||
uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
|
||||
uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0, 0x38 */
|
||||
uint32_t _0x3C;
|
||||
uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0, 0x40 */
|
||||
uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
|
||||
uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
|
||||
uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4c */
|
||||
uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
|
||||
uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
|
||||
uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
|
||||
uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0, 0x5c */
|
||||
uint32_t _0x60[2];
|
||||
uint32_t plle_ss_cntl; /* _PLLE_SS_CNTL_0, 0x68 */
|
||||
uint32_t plle_misc1; /* _PLLE_MISC1_0, 0x6c */
|
||||
uint32_t _0x70[4];
|
||||
|
||||
/* PLLC 0x80-0x8c */
|
||||
uint32_t pllc_base;
|
||||
uint32_t pllc_out;
|
||||
uint32_t pllc_misc0;
|
||||
uint32_t pllc_misc1;
|
||||
|
||||
/* PLLM 0x90-0x9c */
|
||||
uint32_t pllm_base;
|
||||
uint32_t pllm_out;
|
||||
uint32_t pllm_misc1;
|
||||
uint32_t pllm_misc2;
|
||||
|
||||
/* PLLP 0xa0-0xac */
|
||||
uint32_t pllp_base;
|
||||
uint32_t pllp_outa;
|
||||
uint32_t pllp_outb;
|
||||
uint32_t pllp_misc;
|
||||
|
||||
/* PLLA 0xb0-0xbc */
|
||||
uint32_t plla_base;
|
||||
uint32_t plla_out;
|
||||
uint32_t plla_misc0;
|
||||
uint32_t plla_misc1;
|
||||
|
||||
/* PLLU 0xc0-0xcc */
|
||||
uint32_t pllu_base;
|
||||
uint32_t pllu_out;
|
||||
uint32_t pllu_misc1;
|
||||
uint32_t pllu_misc2;
|
||||
|
||||
/* PLLD 0xd0-0xdc */
|
||||
uint32_t plld_base;
|
||||
uint32_t plld_out;
|
||||
uint32_t plld_misc1;
|
||||
uint32_t plld_misc2;
|
||||
|
||||
/* PLLX 0xe0-0xe4 */
|
||||
uint32_t pllx_base;
|
||||
uint32_t pllx_misc;
|
||||
|
||||
/* PLLE 0xe8-0xf4 */
|
||||
uint32_t plle_base;
|
||||
uint32_t plle_misc;
|
||||
uint32_t plle_ss_cntl1;
|
||||
uint32_t plle_ss_cntl2;
|
||||
|
||||
uint32_t lvl2_clk_gate_ovra; /* _LVL2_CLK_GATE_OVRA_0, 0xf8 */
|
||||
uint32_t lvl2_clk_gate_ovrb; /* _LVL2_CLK_GATE_OVRB_0, 0xfc */
|
||||
|
||||
uint32_t clk_source_i2s2; /* _CLK_SOURCE_I2S2_0, 0x100 */
|
||||
uint32_t clk_source_i2s3; /* _CLK_SOURCE_I2S3_0, 0x104 */
|
||||
uint32_t clk_source_spdif_out; /* _CLK_SOURCE_SPDIF_OUT_0, 0x108 */
|
||||
uint32_t clk_source_spdif_in; /* _CLK_SOURCE_SPDIF_IN_0, 0x10c */
|
||||
uint32_t clk_source_pwm; /* _CLK_SOURCE_PWM_0, 0x110 */
|
||||
uint32_t _0x114;
|
||||
uint32_t clk_source_spi2; /* _CLK_SOURCE_SPI2_0, 0x118 */
|
||||
uint32_t clk_source_spi3; /* _CLK_SOURCE_SPI3_0, 0x11c */
|
||||
uint32_t _0x120;
|
||||
uint32_t clk_source_i2c1; /* _CLK_SOURCE_I2C1_0, 0x124 */
|
||||
uint32_t clk_source_i2c5; /* _CLK_SOURCE_I2C5_0, 0x128 */
|
||||
uint32_t _0x12c[2];
|
||||
uint32_t clk_source_spi1; /* _CLK_SOURCE_SPI1_0, 0x134 */
|
||||
uint32_t clk_source_disp1; /* _CLK_SOURCE_DISP1_0, 0x138 */
|
||||
uint32_t clk_source_disp2; /* _CLK_SOURCE_DISP2_0, 0x13c */
|
||||
uint32_t _0x140;
|
||||
uint32_t clk_source_isp; /* _CLK_SOURCE_ISP_0, 0x144 */
|
||||
uint32_t clk_source_vi; /* _CLK_SOURCE_VI_0, 0x148 */
|
||||
uint32_t _0x14c;
|
||||
uint32_t clk_source_sdmmc1; /* _CLK_SOURCE_SDMMC1_0, 0x150 */
|
||||
uint32_t clk_source_sdmmc2; /* _CLK_SOURCE_SDMMC2_0, 0x154 */
|
||||
uint32_t _0x158[3];
|
||||
uint32_t clk_source_sdmmc4; /* _CLK_SOURCE_SDMMC4_0, 0x164 */
|
||||
uint32_t _0x168[4];
|
||||
uint32_t clk_source_uarta; /* _CLK_SOURCE_UARTA_0, 0x178 */
|
||||
uint32_t clk_source_uartb; /* _CLK_SOURCE_UARTB_0, 0x17c */
|
||||
uint32_t clk_source_host1x; /* _CLK_SOURCE_HOST1X_0, 0x180 */
|
||||
uint32_t _0x184[5];
|
||||
uint32_t clk_source_i2c2; /* _CLK_SOURCE_I2C2_0, 0x198 */
|
||||
uint32_t clk_source_emc; /* _CLK_SOURCE_EMC_0, 0x19c */
|
||||
uint32_t clk_source_uartc; /* _CLK_SOURCE_UARTC_0, 0x1a0 */
|
||||
uint32_t _0x1a4;
|
||||
uint32_t clk_source_vi_sensor; /* _CLK_SOURCE_VI_SENSOR_0, 0x1a8 */
|
||||
uint32_t _0x1ac[2];
|
||||
uint32_t clk_source_spi4; /* _CLK_SOURCE_SPI4_0, 0x1b4 */
|
||||
uint32_t clk_source_i2c3; /* _CLK_SOURCE_I2C3_0, 0x1b8 */
|
||||
uint32_t clk_source_sdmmc3; /* _CLK_SOURCE_SDMMC3_0, 0x1bc */
|
||||
uint32_t clk_source_uartd; /* _CLK_SOURCE_UARTD_0, 0x1c0 */
|
||||
uint32_t _0x1c4[2];
|
||||
uint32_t clk_source_owr; /* _CLK_SOURCE_OWR_0, 0x1cc */
|
||||
uint32_t _0x1d0;
|
||||
uint32_t clk_source_csite; /* _CLK_SOURCE_CSITE_0, 0x1d4 */
|
||||
uint32_t clk_source_i2s1; /* _CLK_SOURCE_I2S1_0, 0x1d8 */
|
||||
uint32_t clk_source_dtv; /* _CLK_SOURCE_DTV_0, 0x1dc */
|
||||
uint32_t _0x1e0[5];
|
||||
uint32_t clk_source_tsec; /* _CLK_SOURCE_TSEC_0, 0x1f4 */
|
||||
uint32_t _0x1f8;
|
||||
|
||||
uint32_t clk_spare2; /* _CLK_SPARE2_0, 0x1fc */
|
||||
uint32_t _0x200[32];
|
||||
|
||||
uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
|
||||
uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
|
||||
uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
|
||||
|
||||
uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
|
||||
uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
|
||||
uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
|
||||
|
||||
uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
|
||||
uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
|
||||
uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
|
||||
|
||||
uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
|
||||
uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
|
||||
uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
|
||||
|
||||
uint32_t _0x2b0[17];
|
||||
uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
|
||||
uint32_t _0x2f8[2];
|
||||
|
||||
/* _RST_DEV_L/H/U_SET_0 0x300-0x314 */
|
||||
uint32_t rst_dev_l_set;
|
||||
uint32_t rst_dev_l_clr;
|
||||
uint32_t rst_dev_h_set;
|
||||
uint32_t rst_dev_h_clr;
|
||||
uint32_t rst_dev_u_set;
|
||||
uint32_t rst_dev_u_clr;
|
||||
|
||||
uint32_t _0x318[2];
|
||||
|
||||
/* _CLK_ENB_L/H/U_CLR_0 0x320-0x334 */
|
||||
uint32_t clk_enb_l_set;
|
||||
uint32_t clk_enb_l_clr;
|
||||
uint32_t clk_enb_h_set;
|
||||
uint32_t clk_enb_h_clr;
|
||||
uint32_t clk_enb_u_set;
|
||||
uint32_t clk_enb_u_clr;
|
||||
|
||||
uint32_t _0x338;
|
||||
uint32_t ccplex_pg_sm_ovrd; /* _CCPLEX_PG_SM_OVRD_0, 0x33c */
|
||||
uint32_t rst_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
|
||||
uint32_t rst_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
|
||||
|
||||
/* Additional (T30) registers */
|
||||
uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
|
||||
uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
|
||||
|
||||
uint32_t _0x350[2];
|
||||
uint32_t rst_dev_v; /* _RST_DEVICES_V_0, 0x358 */
|
||||
uint32_t rst_dev_w; /* _RST_DEVICES_W_0, 0x35c */
|
||||
uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V_0, 0x360 */
|
||||
uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_W_0, 0x364 */
|
||||
uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
|
||||
uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36c */
|
||||
uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
|
||||
uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
|
||||
uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
|
||||
uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37c */
|
||||
uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
|
||||
uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
|
||||
uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
|
||||
uint32_t _0x38c[5];
|
||||
uint32_t lvl2_clk_gate_ovrc; /* _LVL2_CLK_GATE_OVRC, 0x3a0 */
|
||||
uint32_t lvl2_clk_gate_ovrd; /* _LVL2_CLK_GATE_OVRD, 0x3a4 */
|
||||
uint32_t _0x3a8[2];
|
||||
|
||||
uint32_t _0x3b0;
|
||||
uint32_t clk_source_mselect; /* _CLK_SOURCE_MSELECT_0, 0x3b4 */
|
||||
uint32_t clk_source_tsensor; /* _CLK_SOURCE_TSENSOR_0, 0x3b8 */
|
||||
uint32_t clk_source_i2s4; /* _CLK_SOURCE_I2S4_0, 0x3bc */
|
||||
uint32_t clk_source_i2s5; /* _CLK_SOURCE_I2S5_0, 0x3c0 */
|
||||
uint32_t clk_source_i2c4; /* _CLK_SOURCE_I2C4_0, 0x3c4 */
|
||||
uint32_t _0x3c8[2];
|
||||
uint32_t clk_source_ahub; /* _CLK_SOURCE_AHUB_0, 0x3d0 */
|
||||
uint32_t _0x3d4[4];
|
||||
uint32_t clk_source_hda2codec_2x; /* _CLK_SOURCE_HDA2CODEC_2X_0, 0x3e4 */
|
||||
uint32_t clk_source_actmon; /* _CLK_SOURCE_ACTMON_0, 0x3e8 */
|
||||
uint32_t clk_source_extperiph1; /* _CLK_SOURCE_EXTPERIPH1_0, 0x3ec */
|
||||
uint32_t clk_source_extperiph2; /* _CLK_SOURCE_EXTPERIPH2_0, 0x3f0 */
|
||||
uint32_t clk_source_extperiph3; /* _CLK_SOURCE_EXTPERIPH3_0, 0x3f4 */
|
||||
uint32_t _0x3f8;
|
||||
uint32_t clk_source_i2c_slow; /* _CLK_SOURCE_I2C_SLOW_0, 0x3fc */
|
||||
uint32_t clk_source_sys; /* _CLK_SOURCE_SYS_0, 0x400 */
|
||||
uint32_t clk_source_ispb; /* _CLK_SOURCE_ISPB_0, 0x404 */
|
||||
uint32_t _0x408[2];
|
||||
uint32_t clk_source_sor1; /* _CLK_SOURCE_SOR1_0, 0x410 */
|
||||
uint32_t clk_source_sor0; /* _CLK_SOURCE_SOR0_0, 0x414 */
|
||||
uint32_t _0x418[2];
|
||||
uint32_t clk_source_sata_oob; /* _CLK_SOURCE_SATA_OOB_0, 0x420 */
|
||||
uint32_t clk_source_sata; /* _CLK_SOURCE_SATA_0, 0x424 */
|
||||
uint32_t clk_source_hda; /* _CLK_SOURCE_HDA_0, 0x428 */
|
||||
uint32_t _0x42c;
|
||||
|
||||
/* _RST_DEV_V/W_SET_0 0x430-0x43c */
|
||||
uint32_t rst_dev_v_set;
|
||||
uint32_t rst_dev_v_clr;
|
||||
uint32_t rst_dev_w_set;
|
||||
uint32_t rst_dev_w_clr;
|
||||
|
||||
/* _CLK_ENB_V/W_CLR_0 0x440-0x44c */
|
||||
uint32_t clk_enb_v_set;
|
||||
uint32_t clk_enb_v_clr;
|
||||
uint32_t clk_enb_w_set;
|
||||
uint32_t clk_enb_w_clr;
|
||||
|
||||
/* Additional (T114+) registers */
|
||||
uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
|
||||
uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
|
||||
uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
|
||||
uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45c */
|
||||
uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
|
||||
uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
|
||||
uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
|
||||
uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46c */
|
||||
uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
|
||||
uint32_t _0x474;
|
||||
uint32_t intstatus; /* _INTSTATUS_0, 0x478 */
|
||||
uint32_t intmask; /* _INTMASK_0, 0x47c */
|
||||
uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
|
||||
uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
|
||||
uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
|
||||
|
||||
uint32_t plle_aux; /* _PLLE_AUX_0, 0x48c */
|
||||
uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
|
||||
uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
|
||||
uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
|
||||
|
||||
uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49c */
|
||||
uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4a0 */
|
||||
uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4a4 */
|
||||
uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4a8 */
|
||||
uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4ac */
|
||||
uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4b0 */
|
||||
uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4b4 */
|
||||
|
||||
uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4b8 */
|
||||
uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4bc */
|
||||
uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4c0 */
|
||||
uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4c4 */
|
||||
uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4c8 */
|
||||
uint32_t pllrefe_out; /* _PLLREFE_OUT_0, 0x4cc */
|
||||
uint32_t cpu_finetrim_byp; /* _CPU_FINETRIM_BYP_0, 0x4d0 */
|
||||
uint32_t cpu_finetrim_select; /* _CPU_FINETRIM_SELECT_0, 0x4d4 */
|
||||
uint32_t cpu_finetrim_dr; /* _CPU_FINETRIM_DR_0, 0x4d8 */
|
||||
uint32_t cpu_finetrim_df; /* _CPU_FINETRIM_DF_0, 0x4dc */
|
||||
uint32_t cpu_finetrim_f; /* _CPU_FINETRIM_F_0, 0x4e0 */
|
||||
uint32_t cpu_finetrim_r; /* _CPU_FINETRIM_R_0, 0x4e4 */
|
||||
uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4e8 */
|
||||
uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4ec */
|
||||
uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4f0 */
|
||||
uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4f4 */
|
||||
uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4f8 */
|
||||
uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4fc */
|
||||
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
|
||||
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
|
||||
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
|
||||
uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50c */
|
||||
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
|
||||
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
|
||||
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
|
||||
uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51c */
|
||||
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
|
||||
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
|
||||
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
|
||||
uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52c */
|
||||
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
|
||||
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
|
||||
uint32_t _0x538;
|
||||
uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53c */
|
||||
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
|
||||
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
|
||||
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
|
||||
uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54c */
|
||||
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
|
||||
uint32_t lvl2_clk_gate_ovre; /* _LVL2_CLK_GATE_OVRE, 0x554 */
|
||||
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
|
||||
uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55c */
|
||||
uint32_t audio_sync_clk_dmic1; /* _AUDIO_SYNC_CLK_DMIC1_0, 0x560 */
|
||||
uint32_t audio_sync_clk_dmic2; /* _AUDIO_SYNC_CLK_DMIC2_0, 0x564 */
|
||||
|
||||
uint32_t _0x568[2];
|
||||
uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG, 0x570 */
|
||||
uint32_t plld2_ss_ctrl1; /* _PLLD2_SS_CTRL1_0, 0x574 */
|
||||
uint32_t plld2_ss_ctrl2; /* _PLLD2_SS_CTRL2_0, 0x578 */
|
||||
uint32_t _0x57c[5];
|
||||
|
||||
uint32_t plldp_base; /* _PLLDP_BASE, 0x590*/
|
||||
uint32_t plldp_misc; /* _PLLDP_MISC, 0x594 */
|
||||
uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
|
||||
uint32_t plldp_ss_ctrl1; /* _PLLDP_SS_CTRL1_0, 0x59c */
|
||||
uint32_t plldp_ss_ctrl2; /* _PLLDP_SS_CTRL2_0, 0x5a0 */
|
||||
uint32_t pllc4_base; /* _PLLC4_BASE_0, 0x5a4 */
|
||||
uint32_t pllc4_misc; /* _PLLC4_MISC_0, 0x5a8 */
|
||||
uint32_t _0x5ac[6];
|
||||
uint32_t clk_spare0; /* _CLK_SPARE0_0, 0x5c4 */
|
||||
uint32_t clk_spare1; /* _CLK_SPARE1_0, 0x5c8 */
|
||||
uint32_t gpu_isob_ctrl; /* _GPU_ISOB_CTRL_0, 0x5cc */
|
||||
uint32_t pllc_misc2; /* _PLLC_MISC_2_0, 0x5d0 */
|
||||
uint32_t pllc_misc3; /* _PLLC_MISC_3_0, 0x5d4 */
|
||||
uint32_t plla_misc2; /* _PLLA_MISC2_0, 0x5d8 */
|
||||
uint32_t _0x5dc[2];
|
||||
uint32_t pllc4_out; /* _PLLC4_OUT_0, 0x5e4 */
|
||||
uint32_t pllmb_base; /* _PLLMB_BASE_0, 0x5e8 */
|
||||
uint32_t pllmb_misc1; /* _PLLMB_MISC1_0, 0x5ec */
|
||||
uint32_t pllx_misc4; /* _PLLX_MISC_4_0, 0x5f0 */
|
||||
uint32_t pllx_misc5; /* _PLLX_MISC_5_0, 0x5f4 */
|
||||
uint32_t _0x5f8[2];
|
||||
|
||||
uint32_t clk_source_xusb_core_host; /* _CLK_SOURCE_XUSB_CORE_HOST_0, 0x600 */
|
||||
uint32_t clk_source_xusb_falcon; /* _CLK_SOURCE_XUSB_FALCON_0, 0x604 */
|
||||
uint32_t clk_source_xusb_fs; /* _CLK_SOURCE_XUSB_FS_0, 0x608 */
|
||||
uint32_t clk_source_xusb_core_dev; /* _CLK_SOURCE_XUSB_CORE_DEV_0, 0x60c */
|
||||
uint32_t clk_source_xusb_ss; /* _CLK_SOURCE_XUSB_SS_0, 0x610 */
|
||||
uint32_t clk_source_cilab; /* _CLK_SOURCE_CILAB_0, 0x614 */
|
||||
uint32_t clk_source_cilcd; /* _CLK_SOURCE_CILCD_0, 0x618 */
|
||||
uint32_t clk_source_cilef; /* _CLK_SOURCE_CILEF_0, 0x61c */
|
||||
uint32_t clk_source_dsia_lp; /* _CLK_SOURCE_DSIA_LP_0, 0x620 */
|
||||
uint32_t clk_source_dsib_lp; /* _CLK_SOURCE_DSIB_LP_0, 0x624 */
|
||||
uint32_t clk_source_entropy; /* _CLK_SOURCE_ENTROPY_0, 0x628 */
|
||||
uint32_t clk_source_dvfs_ref; /* _CLK_SOURCE_DVFS_REF_0, 0x62c */
|
||||
uint32_t clk_source_dvfs_soc; /* _CLK_SOURCE_DVFS_SOC_0, 0x630 */
|
||||
uint32_t _0x634[3];
|
||||
uint32_t clk_source_emc_latency; /* _CLK_SOURCE_EMC_LATENCY_0, 0x640 */
|
||||
uint32_t clk_source_soc_therm; /* _CLK_SOURCE_SOC_THERM_0, 0x644 */
|
||||
uint32_t _0x648;
|
||||
uint32_t clk_source_dmic1; /* _CLK_SOURCE_DMIC1_0, 0x64c */
|
||||
uint32_t clk_source_dmic2; /* _CLK_SOURCE_DMIC2_0, 0x650 */
|
||||
uint32_t _0x654;
|
||||
uint32_t clk_source_vi_sensor2; /* _CLK_SOURCE_VI_SENSOR2_0, 0x658 */
|
||||
uint32_t clk_source_i2c6; /* _CLK_SOURCE_I2C6_0, 0x65c */
|
||||
uint32_t clk_source_mipibif; /* _CLK_SOURCE_MIPIBIF_0, 0x660 */
|
||||
uint32_t clk_source_emc_dll; /* _CLK_SOURCE_EMC_DLL_0, 0x664 */
|
||||
uint32_t _0x668;
|
||||
uint32_t clk_source_uart_fst_mipi_cal; /* _CLK_SOURCE_UART_FST_MIPI_CAL_0, 0x66c */
|
||||
uint32_t _0x670[2];
|
||||
uint32_t clk_source_vic; /* _CLK_SOURCE_VIC_0, 0x678 */
|
||||
|
||||
uint32_t pllp_outc; /* _PLLP_OUTC_0, 0x67c */
|
||||
uint32_t pllp_misc1; /* _PLLP_MISC1_0, 0x680 */
|
||||
uint32_t _0x684[2];
|
||||
uint32_t emc_div_clk_shaper_ctrl; /* _EMC_DIV_CLK_SHAPER_CTRL_0, 0x68c */
|
||||
uint32_t emc_pllc_shaper_ctrl; /* _EMC_PLLC_SHAPER_CTRL_0, 0x690 */
|
||||
|
||||
uint32_t clk_source_sdmmc_legacy_tm; /* _CLK_SOURCE_SDMMC_LEGACY_TM_0, 0x694 */
|
||||
uint32_t clk_source_nvdec; /* _CLK_SOURCE_NVDEC_0, 0x698 */
|
||||
uint32_t clk_source_nvjpg; /* _CLK_SOURCE_NVJPG_0, 0x69c */
|
||||
uint32_t clk_source_nvenc; /* _CLK_SOURCE_NVENC_0, 0x6a0 */
|
||||
|
||||
uint32_t plla1_base; /* _PLLA1_BASE_0, 0x6a4 */
|
||||
uint32_t plla1_misc0; /* _PLLA1_MISC_0_0, 0x6a8 */
|
||||
uint32_t plla1_misc1; /* _PLLA1_MISC_1_0, 0x6ac */
|
||||
uint32_t plla1_misc2; /* _PLLA1_MISC_2_0, 0x6b0 */
|
||||
uint32_t plla1_misc3; /* _PLLA1_MISC_3_0, 0x6b4 */
|
||||
uint32_t audio_sync_clk_dmic3; /* _AUDIO_SYNC_CLK_DMIC3_0, 0x6b8 */
|
||||
|
||||
uint32_t clk_source_dmic3; /* _CLK_SOURCE_DMIC3_0, 0x6bc */
|
||||
uint32_t clk_source_ape; /* _CLK_SOURCE_APE_0, 0x6c0 */
|
||||
uint32_t clk_source_qspi; /* _CLK_SOURCE_QSPI_0, 0x6c4 */
|
||||
uint32_t clk_source_vi_i2c; /* _CLK_SOURCE_VI_I2C_0, 0x6c8 */
|
||||
uint32_t clk_source_usb2_hsic_trk; /* _CLK_SOURCE_USB2_HSIC_TRK_0, 0x6cc */
|
||||
uint32_t clk_source_pex_sata_usb_rx_byp; /* _CLK_SOURCE_PEX_SATA_USB_RX_BYP_0, 0x6d0 */
|
||||
uint32_t clk_source_maud; /* _CLK_SOURCE_MAUD_0, 0x6d4 */
|
||||
uint32_t clk_source_tsecb; /* _CLK_SOURCE_TSECB_0, 0x6d8 */
|
||||
|
||||
uint32_t clk_cpug_misc1; /* _CLK_CPUG_MISC1_0, 0x6dc */
|
||||
uint32_t aclk_burst_policy; /* _ACLK_BURST_POLICY_0, 0x6e0 */
|
||||
uint32_t super_aclk_divider; /* _SUPER_ACLK_DIVIDER_0, 0x6e4 */
|
||||
|
||||
uint32_t nvenc_super_clk_divider; /* _NVENC_SUPER_CLK_DIVIDER_0, 0x6e8 */
|
||||
uint32_t vi_super_clk_divider; /* _VI_SUPER_CLK_DIVIDER_0, 0x6ec */
|
||||
uint32_t vic_super_clk_divider; /* _VIC_SUPER_CLK_DIVIDER_0, 0x6f0 */
|
||||
uint32_t nvdec_super_clk_divider; /* _NVDEC_SUPER_CLK_DIVIDER_0, 0x6f4 */
|
||||
uint32_t isp_super_clk_divider; /* _ISP_SUPER_CLK_DIVIDER_0, 0x6f8 */
|
||||
uint32_t ispb_super_clk_divider; /* _ISPB_SUPER_CLK_DIVIDER_0, 0x6fc */
|
||||
uint32_t nvjpg_super_clk_divider; /* _NVJPG_SUPER_CLK_DIVIDER_0, 0x700 */
|
||||
uint32_t se_super_clk_divider; /* _SE_SUPER_CLK_DIVIDER_0, 0x704 */
|
||||
uint32_t tsec_super_clk_divider; /* _TSEC_SUPER_CLK_DIVIDER_0, 0x708 */
|
||||
uint32_t tsecb_super_clk_divider; /* _TSECB_SUPER_CLK_DIVIDER_0, 0x70c */
|
||||
|
||||
uint32_t clk_source_uartape; /* _CLK_SOURCE_UARTAPE_0, 0x710 */
|
||||
uint32_t clk_cpug_misc2; /* _CLK_CPUG_MISC2_0, 0x714 */
|
||||
uint32_t clk_source_dbgapb; /* _CLK_SOURCE_DBGAPB_0, 0x718 */
|
||||
uint32_t clk_ccplex_cc4_ret_clk_enb; /* _CLK_CCPLEX_CC4_RET_CLK_ENB_0, 0x71c */
|
||||
uint32_t actmon_cpu_clk; /* _ACTMON_CPU_CLK_0, 0x720 */
|
||||
uint32_t clk_source_emc_safe; /* _CLK_SOURCE_EMC_SAFE_0, 0x724 */
|
||||
uint32_t sdmmc2_pllc4_out0_shaper_ctrl; /* _SDMMC2_PLLC4_OUT0_SHAPER_CTRL_0, 0x728 */
|
||||
uint32_t sdmmc2_pllc4_out1_shaper_ctrl; /* _SDMMC2_PLLC4_OUT1_SHAPER_CTRL_0, 0x72c */
|
||||
uint32_t sdmmc2_pllc4_out2_shaper_ctrl; /* _SDMMC2_PLLC4_OUT2_SHAPER_CTRL_0, 0x730 */
|
||||
uint32_t sdmmc2_div_clk_shaper_ctrl; /* _SDMMC2_DIV_CLK_SHAPER_CTRL_0, 0x734 */
|
||||
uint32_t sdmmc4_pllc4_out0_shaper_ctrl; /* _SDMMC4_PLLC4_OUT0_SHAPER_CTRL_0, 0x738 */
|
||||
uint32_t sdmmc4_pllc4_out1_shaper_ctrl; /* _SDMMC4_PLLC4_OUT1_SHAPER_CTRL_0, 0x73c */
|
||||
uint32_t sdmmc4_pllc4_out2_shaper_ctrl; /* _SDMMC4_PLLC4_OUT2_SHAPER_CTRL_0, 0x740 */
|
||||
uint32_t sdmmc4_div_clk_shaper_ctrl; /* _SDMMC4_DIV_CLK_SHAPER_CTRL_0, 0x744 */
|
||||
} tegra_car_t;
|
||||
|
||||
static inline volatile tegra_car_t *car_get_regs(void) {
|
||||
return (volatile tegra_car_t *)CAR_BASE;
|
||||
}
|
||||
|
||||
void clk_enable(CarDevice dev);
|
||||
void clk_disable(CarDevice dev);
|
||||
void rst_enable(CarDevice dev);
|
||||
void rst_disable(CarDevice dev);
|
||||
|
||||
void clkrst_enable(CarDevice dev);
|
||||
void clkrst_disable(CarDevice dev);
|
||||
void clkrst_reboot(CarDevice dev);
|
||||
|
||||
void clkrst_enable_fuse_regs(bool enable);
|
||||
|
||||
#endif
|
||||
1619
fusee/fusee-mtc/src/display/cfb_console.c
Normal file
1619
fusee/fusee-mtc/src/display/cfb_console.c
Normal file
File diff suppressed because it is too large
Load Diff
57
fusee/fusee-mtc/src/display/video_fb.h
Normal file
57
fusee/fusee-mtc/src/display/video_fb.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* (C) Copyright 1997-2002 ELTEC Elektronik AG
|
||||
* Frank Gottschling <fgottschling@eltec.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _VIDEO_FB_H_
|
||||
#define _VIDEO_FB_H_
|
||||
|
||||
#define CONSOLE_BG_COL 0x00
|
||||
#define CONSOLE_FG_COL 0xa0
|
||||
|
||||
/* Try using the small font */
|
||||
#define CONFIG_VIDEO_FONT_SMALL
|
||||
|
||||
/*
|
||||
* Graphic Data Format (GDF) bits for VIDEO_DATA_FORMAT
|
||||
*/
|
||||
#define GDF__8BIT_INDEX 0
|
||||
#define GDF_15BIT_555RGB 1
|
||||
#define GDF_16BIT_565RGB 2
|
||||
#define GDF_32BIT_X888RGB 3
|
||||
#define GDF_24BIT_888RGB 4
|
||||
#define GDF__8BIT_332RGB 5
|
||||
|
||||
#define CONFIG_VIDEO_FB_LITTLE_ENDIAN
|
||||
#define CONFIG_VIDEO_VISIBLE_COLS 720
|
||||
#define CONFIG_VIDEO_VISIBLE_ROWS 1280
|
||||
#define CONFIG_VIDEO_COLS 768
|
||||
#define CONFIG_VIDEO_PIXEL_SIZE 4
|
||||
#define CONFIG_VIDEO_DATA_FORMAT GDF_32BIT_X888RGB /* BGR actually, but w/e */
|
||||
|
||||
int video_get_col(void);
|
||||
int video_get_row(void);
|
||||
|
||||
int video_init(void *fb);
|
||||
int video_resume(void *fb, int row, int col);
|
||||
void video_puts(const char *s);
|
||||
|
||||
#endif /*_VIDEO_FB_H_ */
|
||||
6181
fusee/fusee-mtc/src/display/video_font_large.h
Normal file
6181
fusee/fusee-mtc/src/display/video_font_large.h
Normal file
File diff suppressed because it is too large
Load Diff
4630
fusee/fusee-mtc/src/display/video_font_small.h
Normal file
4630
fusee/fusee-mtc/src/display/video_font_small.h
Normal file
File diff suppressed because it is too large
Load Diff
1089
fusee/fusee-mtc/src/emc.h
Normal file
1089
fusee/fusee-mtc/src/emc.h
Normal file
File diff suppressed because it is too large
Load Diff
260
fusee/fusee-mtc/src/fuse.c
Normal file
260
fusee/fusee-mtc/src/fuse.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "car.h"
|
||||
#include "fuse.h"
|
||||
#include "timers.h"
|
||||
|
||||
/* Prototypes for internal commands. */
|
||||
void fuse_make_regs_visible(void);
|
||||
|
||||
void fuse_enable_power(void);
|
||||
void fuse_disable_power(void);
|
||||
void fuse_wait_idle(void);
|
||||
|
||||
/* Initialize the fuse driver */
|
||||
void fuse_init(void) {
|
||||
fuse_make_regs_visible();
|
||||
fuse_secondary_private_key_disable();
|
||||
fuse_disable_programming();
|
||||
|
||||
/* TODO: Overrides (iROM patches) and various reads happen here */
|
||||
}
|
||||
|
||||
/* Make all fuse registers visible */
|
||||
void fuse_make_regs_visible(void) {
|
||||
clkrst_enable_fuse_regs(true);
|
||||
}
|
||||
|
||||
/* Enable power to the fuse hardware array */
|
||||
void fuse_enable_power(void) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse->FUSE_PWR_GOOD_SW = 1;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/* Disable power to the fuse hardware array */
|
||||
void fuse_disable_power(void) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse->FUSE_PWR_GOOD_SW = 0;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
/* Wait for the fuse driver to go idle */
|
||||
void fuse_wait_idle(void) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
uint32_t ctrl_val = 0;
|
||||
|
||||
/* Wait for STATE_IDLE */
|
||||
while ((ctrl_val & (0xF0000)) != 0x40000)
|
||||
{
|
||||
udelay(1);
|
||||
ctrl_val = fuse->FUSE_CTRL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a fuse from the hardware array */
|
||||
uint32_t fuse_hw_read(uint32_t addr) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse_wait_idle();
|
||||
|
||||
/* Program the target address */
|
||||
fuse->FUSE_REG_ADDR = addr;
|
||||
|
||||
/* Enable read operation in control register */
|
||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
||||
ctrl_val &= ~0x3;
|
||||
ctrl_val |= 0x1; /* Set FUSE_READ command */
|
||||
fuse->FUSE_CTRL = ctrl_val;
|
||||
|
||||
fuse_wait_idle();
|
||||
|
||||
return fuse->FUSE_REG_READ;
|
||||
}
|
||||
|
||||
/* Write a fuse in the hardware array */
|
||||
void fuse_hw_write(uint32_t value, uint32_t addr) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse_wait_idle();
|
||||
|
||||
/* Program the target address and value */
|
||||
fuse->FUSE_REG_ADDR = addr;
|
||||
fuse->FUSE_REG_WRITE = value;
|
||||
|
||||
/* Enable write operation in control register */
|
||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
||||
ctrl_val &= ~0x3;
|
||||
ctrl_val |= 0x2; /* Set FUSE_WRITE command */
|
||||
fuse->FUSE_CTRL = ctrl_val;
|
||||
|
||||
fuse_wait_idle();
|
||||
}
|
||||
|
||||
/* Sense the fuse hardware array into the shadow cache */
|
||||
void fuse_hw_sense(void) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse_wait_idle();
|
||||
|
||||
/* Enable sense operation in control register */
|
||||
uint32_t ctrl_val = fuse->FUSE_CTRL;
|
||||
ctrl_val &= ~0x3;
|
||||
ctrl_val |= 0x3; /* Set FUSE_SENSE command */
|
||||
fuse->FUSE_CTRL = ctrl_val;
|
||||
|
||||
fuse_wait_idle();
|
||||
}
|
||||
|
||||
/* Disables all fuse programming. */
|
||||
void fuse_disable_programming(void) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse->FUSE_DIS_PGM = 1;
|
||||
}
|
||||
|
||||
/* Unknown exactly what this does, but it alters the contents read from the fuse cache. */
|
||||
void fuse_secondary_private_key_disable(void) {
|
||||
volatile tegra_fuse_t *fuse = fuse_get_regs();
|
||||
fuse->FUSE_PRIVATEKEYDISABLE = 0x10;
|
||||
}
|
||||
|
||||
|
||||
/* Read the SKU info register from the shadow cache */
|
||||
uint32_t fuse_get_sku_info(void) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
return fuse_chip->FUSE_SKU_INFO;
|
||||
}
|
||||
|
||||
/* Read the bootrom patch version from a register in the shadow cache */
|
||||
uint32_t fuse_get_bootrom_patch_version(void) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
return fuse_chip->FUSE_SOC_SPEEDO_1;
|
||||
}
|
||||
|
||||
/* Read a spare bit register from the shadow cache */
|
||||
uint32_t fuse_get_spare_bit(uint32_t idx) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
|
||||
if (idx >= 32) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fuse_chip->FUSE_SPARE_BIT[idx];
|
||||
}
|
||||
|
||||
/* Read a reserved ODM register from the shadow cache */
|
||||
uint32_t fuse_get_reserved_odm(uint32_t idx) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
|
||||
if (idx >= 8) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fuse_chip->FUSE_RESERVED_ODM[idx];
|
||||
}
|
||||
|
||||
/* Derive the Device ID using values in the shadow cache */
|
||||
uint64_t fuse_get_device_id(void) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
|
||||
uint64_t device_id = 0;
|
||||
uint64_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
||||
uint64_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
||||
uint64_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
||||
uint32_t lot_code = fuse_chip->FUSE_LOT_CODE_0;
|
||||
uint64_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
||||
uint64_t derived_lot_code = 0;
|
||||
for (unsigned int i = 0; i < 5; i++) {
|
||||
derived_lot_code = (derived_lot_code * 0x24) + ((lot_code >> (24 - 6*i)) & 0x3F);
|
||||
}
|
||||
derived_lot_code &= 0x03FFFFFF;
|
||||
|
||||
device_id |= y_coord << 0;
|
||||
device_id |= x_coord << 9;
|
||||
device_id |= wafer_id << 18;
|
||||
device_id |= derived_lot_code << 24;
|
||||
device_id |= fab_code << 50;
|
||||
return device_id;
|
||||
}
|
||||
|
||||
/* Get the DRAM ID using values in the shadow cache */
|
||||
uint32_t fuse_get_dram_id(void) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
return (fuse_chip->FUSE_RESERVED_ODM[4] >> 3) & 0x7;
|
||||
}
|
||||
|
||||
/* Derive the Hardware Type using values in the shadow cache */
|
||||
uint32_t fuse_get_hardware_type(void) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
|
||||
/* This function is very different between 4.x and < 4.x */
|
||||
uint32_t hardware_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 2) | ((fuse_chip->FUSE_RESERVED_ODM[4] >> 2) & 1);
|
||||
|
||||
/* TODO: choose; if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
|
||||
static const uint32_t types[] = {0,1,4,3};
|
||||
|
||||
hardware_type |= (fuse_chip->FUSE_RESERVED_ODM[4] >> 14) & 0x3C;
|
||||
hardware_type--;
|
||||
return hardware_type > 3 ? 4 : types[hardware_type];
|
||||
} else {*/
|
||||
if (hardware_type >= 1) {
|
||||
return hardware_type > 2 ? 3 : hardware_type - 1;
|
||||
} else if ((fuse_chip->FUSE_SPARE_BIT[9] & 1) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 3;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
/* Derive the Retail Type using values in the shadow cache */
|
||||
uint32_t fuse_get_retail_type(void) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
|
||||
/* Retail type = IS_RETAIL | UNIT_TYPE */
|
||||
uint32_t retail_type = ((fuse_chip->FUSE_RESERVED_ODM[4] >> 7) & 4) | (fuse_chip->FUSE_RESERVED_ODM[4] & 3);
|
||||
if (retail_type == 4) { /* Standard retail unit, IS_RETAIL | 0. */
|
||||
return 1;
|
||||
} else if (retail_type == 3) { /* Standard dev unit, 0 | DEV_UNIT. */
|
||||
return 0;
|
||||
}
|
||||
return 2; /* IS_RETAIL | DEV_UNIT */
|
||||
}
|
||||
|
||||
/* Derive the 16-byte Hardware Info using values in the shadow cache, and copy to output buffer. */
|
||||
void fuse_get_hardware_info(void *dst) {
|
||||
volatile tegra_fuse_chip_t *fuse_chip = fuse_chip_get_regs();
|
||||
uint32_t hw_info[0x4];
|
||||
|
||||
uint32_t unk_hw_fuse = fuse_chip->_0x120 & 0x3F;
|
||||
uint32_t y_coord = fuse_chip->FUSE_Y_COORDINATE & 0x1FF;
|
||||
uint32_t x_coord = fuse_chip->FUSE_X_COORDINATE & 0x1FF;
|
||||
uint32_t wafer_id = fuse_chip->FUSE_WAFER_ID & 0x3F;
|
||||
uint32_t lot_code_0 = fuse_chip->FUSE_LOT_CODE_0;
|
||||
uint32_t lot_code_1 = fuse_chip->FUSE_LOT_CODE_1 & 0x0FFFFFFF;
|
||||
uint32_t fab_code = fuse_chip->FUSE_FAB_CODE & 0x3F;
|
||||
uint32_t vendor_code = fuse_chip->FUSE_VENDOR_CODE & 0xF;
|
||||
|
||||
/* Hardware Info = unk_hw_fuse || Y_COORD || X_COORD || WAFER_ID || LOT_CODE || FAB_CODE || VENDOR_ID */
|
||||
hw_info[0] = (uint32_t)((lot_code_1 << 30) | (wafer_id << 24) | (x_coord << 15) | (y_coord << 6) | (unk_hw_fuse));
|
||||
hw_info[1] = (uint32_t)((lot_code_0 << 26) | (lot_code_1 >> 2));
|
||||
hw_info[2] = (uint32_t)((fab_code << 26) | (lot_code_0 >> 6));
|
||||
hw_info[3] = (uint32_t)(vendor_code);
|
||||
|
||||
memcpy(dst, hw_info, 0x10);
|
||||
}
|
||||
213
fusee/fusee-mtc/src/fuse.h
Normal file
213
fusee/fusee-mtc/src/fuse.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_FUSE_H
|
||||
#define FUSEE_FUSE_H
|
||||
|
||||
#define FUSE_BASE 0x7000F800
|
||||
#define FUSE_CHIP_BASE (FUSE_BASE + 0x100)
|
||||
#define MAKE_FUSE_REG(n) MAKE_REG32(FUSE_BASE + n)
|
||||
#define MAKE_FUSE_CHIP_REG(n) MAKE_REG32(FUSE_CHIP_BASE + n)
|
||||
|
||||
typedef struct {
|
||||
uint32_t FUSE_CTRL;
|
||||
uint32_t FUSE_REG_ADDR;
|
||||
uint32_t FUSE_REG_READ;
|
||||
uint32_t FUSE_REG_WRITE;
|
||||
uint32_t FUSE_TIME_RD1;
|
||||
uint32_t FUSE_TIME_RD2;
|
||||
uint32_t FUSE_TIME_PGM1;
|
||||
uint32_t FUSE_TIME_PGM2;
|
||||
uint32_t FUSE_PRIV2INTFC;
|
||||
uint32_t FUSE_FUSEBYPASS;
|
||||
uint32_t FUSE_PRIVATEKEYDISABLE;
|
||||
uint32_t FUSE_DIS_PGM;
|
||||
uint32_t FUSE_WRITE_ACCESS;
|
||||
uint32_t FUSE_PWR_GOOD_SW;
|
||||
uint32_t _0x38[0x32];
|
||||
} tegra_fuse_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t FUSE_PRODUCTION_MODE;
|
||||
uint32_t _0x4;
|
||||
uint32_t _0x8;
|
||||
uint32_t _0xC;
|
||||
uint32_t FUSE_SKU_INFO;
|
||||
uint32_t FUSE_CPU_SPEEDO_0;
|
||||
uint32_t FUSE_CPU_IDDQ;
|
||||
uint32_t _0x1C;
|
||||
uint32_t _0x20;
|
||||
uint32_t _0x24;
|
||||
uint32_t FUSE_FT_REV;
|
||||
uint32_t FUSE_CPU_SPEEDO_1;
|
||||
uint32_t FUSE_CPU_SPEEDO_2;
|
||||
uint32_t FUSE_SOC_SPEEDO_0;
|
||||
uint32_t FUSE_SOC_SPEEDO_1;
|
||||
uint32_t FUSE_SOC_SPEEDO_2;
|
||||
uint32_t FUSE_SOC_IDDQ;
|
||||
uint32_t _0x44;
|
||||
uint32_t FUSE_FA;
|
||||
uint32_t _0x4C;
|
||||
uint32_t _0x50;
|
||||
uint32_t _0x54;
|
||||
uint32_t _0x58;
|
||||
uint32_t _0x5C;
|
||||
uint32_t _0x60;
|
||||
uint32_t FUSE_PUBLIC_KEY[0x8];
|
||||
uint32_t FUSE_TSENSOR_1;
|
||||
uint32_t FUSE_TSENSOR_2;
|
||||
uint32_t _0x8C;
|
||||
uint32_t FUSE_CP_REV;
|
||||
uint32_t _0x94;
|
||||
uint32_t FUSE_TSENSOR_0;
|
||||
uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG;
|
||||
uint32_t FUSE_SECURITY_MODE;
|
||||
uint32_t FUSE_PRIVATE_KEY[0x4];
|
||||
uint32_t FUSE_DEVICE_KEY;
|
||||
uint32_t _0xB8;
|
||||
uint32_t _0xBC;
|
||||
uint32_t FUSE_RESERVED_SW;
|
||||
uint32_t FUSE_VP8_ENABLE;
|
||||
uint32_t FUSE_RESERVED_ODM[0x8];
|
||||
uint32_t _0xE8;
|
||||
uint32_t _0xEC;
|
||||
uint32_t FUSE_SKU_USB_CALIB;
|
||||
uint32_t FUSE_SKU_DIRECT_CONFIG;
|
||||
uint32_t _0xF8;
|
||||
uint32_t _0xFC;
|
||||
uint32_t FUSE_VENDOR_CODE;
|
||||
uint32_t FUSE_FAB_CODE;
|
||||
uint32_t FUSE_LOT_CODE_0;
|
||||
uint32_t FUSE_LOT_CODE_1;
|
||||
uint32_t FUSE_WAFER_ID;
|
||||
uint32_t FUSE_X_COORDINATE;
|
||||
uint32_t FUSE_Y_COORDINATE;
|
||||
uint32_t _0x11C;
|
||||
uint32_t _0x120;
|
||||
uint32_t FUSE_SATA_CALIB;
|
||||
uint32_t FUSE_GPU_IDDQ;
|
||||
uint32_t FUSE_TSENSOR_3;
|
||||
uint32_t _0x130;
|
||||
uint32_t _0x134;
|
||||
uint32_t _0x138;
|
||||
uint32_t _0x13C;
|
||||
uint32_t _0x140;
|
||||
uint32_t _0x144;
|
||||
uint32_t FUSE_OPT_SUBREVISION;
|
||||
uint32_t _0x14C;
|
||||
uint32_t _0x150;
|
||||
uint32_t FUSE_TSENSOR_4;
|
||||
uint32_t FUSE_TSENSOR_5;
|
||||
uint32_t FUSE_TSENSOR_6;
|
||||
uint32_t FUSE_TSENSOR_7;
|
||||
uint32_t FUSE_OPT_PRIV_SEC_DIS;
|
||||
uint32_t FUSE_PKC_DISABLE;
|
||||
uint32_t _0x16C;
|
||||
uint32_t _0x170;
|
||||
uint32_t _0x174;
|
||||
uint32_t _0x178;
|
||||
uint32_t _0x17C;
|
||||
uint32_t FUSE_TSENSOR_COMMON;
|
||||
uint32_t _0x184;
|
||||
uint32_t _0x188;
|
||||
uint32_t _0x18C;
|
||||
uint32_t _0x190;
|
||||
uint32_t _0x194;
|
||||
uint32_t _0x198;
|
||||
uint32_t FUSE_DEBUG_AUTH_OVERRIDE;
|
||||
uint32_t _0x1A0;
|
||||
uint32_t _0x1A4;
|
||||
uint32_t _0x1A8;
|
||||
uint32_t _0x1AC;
|
||||
uint32_t _0x1B0;
|
||||
uint32_t _0x1B4;
|
||||
uint32_t _0x1B8;
|
||||
uint32_t _0x1BC;
|
||||
uint32_t _0x1D0;
|
||||
uint32_t FUSE_TSENSOR_8;
|
||||
uint32_t _0x1D8;
|
||||
uint32_t _0x1DC;
|
||||
uint32_t _0x1E0;
|
||||
uint32_t _0x1E4;
|
||||
uint32_t _0x1E8;
|
||||
uint32_t _0x1EC;
|
||||
uint32_t _0x1F0;
|
||||
uint32_t _0x1F4;
|
||||
uint32_t _0x1F8;
|
||||
uint32_t _0x1FC;
|
||||
uint32_t _0x200;
|
||||
uint32_t FUSE_RESERVED_CALIB;
|
||||
uint32_t _0x208;
|
||||
uint32_t _0x20C;
|
||||
uint32_t _0x210;
|
||||
uint32_t _0x214;
|
||||
uint32_t _0x218;
|
||||
uint32_t FUSE_TSENSOR_9;
|
||||
uint32_t _0x220;
|
||||
uint32_t _0x224;
|
||||
uint32_t _0x228;
|
||||
uint32_t _0x22C;
|
||||
uint32_t _0x230;
|
||||
uint32_t _0x234;
|
||||
uint32_t _0x238;
|
||||
uint32_t _0x23C;
|
||||
uint32_t _0x240;
|
||||
uint32_t _0x244;
|
||||
uint32_t _0x248;
|
||||
uint32_t _0x24C;
|
||||
uint32_t FUSE_USB_CALIB_EXT;
|
||||
uint32_t _0x254;
|
||||
uint32_t _0x258;
|
||||
uint32_t _0x25C;
|
||||
uint32_t _0x260;
|
||||
uint32_t _0x264;
|
||||
uint32_t _0x268;
|
||||
uint32_t _0x26C;
|
||||
uint32_t _0x270;
|
||||
uint32_t _0x274;
|
||||
uint32_t _0x278;
|
||||
uint32_t _0x27C;
|
||||
uint32_t FUSE_SPARE_BIT[0x20];
|
||||
} tegra_fuse_chip_t;
|
||||
|
||||
static inline volatile tegra_fuse_t *fuse_get_regs(void) {
|
||||
return (volatile tegra_fuse_t *)FUSE_BASE;
|
||||
}
|
||||
|
||||
static inline volatile tegra_fuse_chip_t *fuse_chip_get_regs(void) {
|
||||
return (volatile tegra_fuse_chip_t *)FUSE_CHIP_BASE;
|
||||
}
|
||||
|
||||
void fuse_init(void);
|
||||
|
||||
uint32_t fuse_hw_read(uint32_t addr);
|
||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||
void fuse_hw_sense(void);
|
||||
void fuse_disable_programming(void);
|
||||
void fuse_secondary_private_key_disable(void);
|
||||
|
||||
uint32_t fuse_get_sku_info(void);
|
||||
uint32_t fuse_get_spare_bit(uint32_t idx);
|
||||
uint32_t fuse_get_reserved_odm(uint32_t idx);
|
||||
|
||||
uint32_t fuse_get_bootrom_patch_version(void);
|
||||
uint64_t fuse_get_device_id(void);
|
||||
uint32_t fuse_get_dram_id(void);
|
||||
uint32_t fuse_get_hardware_type(void);
|
||||
uint32_t fuse_get_retail_type(void);
|
||||
void fuse_get_hardware_info(void *dst);
|
||||
|
||||
#endif
|
||||
86
fusee/fusee-mtc/src/init.c
Normal file
86
fusee/fusee-mtc/src/init.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include "stage2.h"
|
||||
#include "utils.h"
|
||||
|
||||
void __libc_init_array(void);
|
||||
void __libc_fini_array(void);
|
||||
|
||||
extern uint8_t __bss_start__[], __bss_end__[];
|
||||
extern uint8_t __heap_start__[], __heap_end__[];
|
||||
|
||||
extern char *fake_heap_start;
|
||||
extern char *fake_heap_end;
|
||||
|
||||
int __program_argc;
|
||||
void **__program_argv;
|
||||
|
||||
void __program_exit(int rc);
|
||||
static void __program_parse_argc_argv(int argc, char *argdata);
|
||||
static void __program_cleanup_argv(void);
|
||||
|
||||
static void __program_init_heap(void) {
|
||||
fake_heap_start = (char*)__heap_start__;
|
||||
fake_heap_end = (char*)__heap_end__;
|
||||
}
|
||||
|
||||
static void __program_init_newlib_hooks(void) {
|
||||
__syscalls.exit = __program_exit; /* For exit, etc. */
|
||||
}
|
||||
|
||||
void __program_init(int argc, char *argdata) {
|
||||
/* Zero-fill the .bss section */
|
||||
memset(__bss_start__, 0, __bss_end__ - __bss_start__);
|
||||
|
||||
__program_init_heap();
|
||||
__program_init_newlib_hooks();
|
||||
__program_parse_argc_argv(argc, argdata);
|
||||
__libc_init_array();
|
||||
}
|
||||
|
||||
void __program_exit(int rc) {
|
||||
__libc_fini_array();
|
||||
__program_cleanup_argv();
|
||||
}
|
||||
|
||||
static void __program_parse_argc_argv(int argc, char *argdata) {
|
||||
__program_argc = argc;
|
||||
|
||||
__program_argv = malloc(argc * sizeof(void **));
|
||||
if (__program_argv == NULL) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
__program_argv[0] = malloc(sizeof(stage2_mtc_args_t));
|
||||
if (__program_argv[0] == NULL) {
|
||||
generic_panic();
|
||||
}
|
||||
memcpy(__program_argv[0], argdata, sizeof(stage2_mtc_args_t));
|
||||
}
|
||||
|
||||
static void __program_cleanup_argv(void) {
|
||||
for (int i = 0; i < __program_argc; i++) {
|
||||
free(__program_argv[i]);
|
||||
__program_argv[i] = NULL;
|
||||
}
|
||||
free(__program_argv);
|
||||
}
|
||||
127
fusee/fusee-mtc/src/lib/log.c
Normal file
127
fusee/fusee-mtc/src/lib/log.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 "log.h"
|
||||
|
||||
#include "../display/video_fb.h"
|
||||
#include "vsprintf.h"
|
||||
|
||||
/* default log level for screen output */
|
||||
ScreenLogLevel g_screen_log_level = SCREEN_LOG_LEVEL_NONE;
|
||||
|
||||
void log_set_log_level(ScreenLogLevel log_level) {
|
||||
g_screen_log_level = log_level;
|
||||
}
|
||||
|
||||
ScreenLogLevel log_get_log_level() {
|
||||
return g_screen_log_level;
|
||||
}
|
||||
|
||||
void log_to_uart(const char *message) {
|
||||
/* TODO: add UART logging */
|
||||
}
|
||||
|
||||
static void print_to_screen(ScreenLogLevel screen_log_level, char *message) {
|
||||
/* don't print to screen if below log level */
|
||||
if(screen_log_level > g_screen_log_level) return;
|
||||
|
||||
video_puts(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* vprintk - logs a message and prints it to screen based on its screen_log_level
|
||||
*
|
||||
* If the level is below g_screen_log_level it will not be shown but logged to UART
|
||||
* This text will not be colored or prefixed
|
||||
* UART is TODO
|
||||
*/
|
||||
void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args)
|
||||
{
|
||||
char buf[PRINT_MESSAGE_MAX_LENGTH];
|
||||
vsnprintf(buf, PRINT_MESSAGE_MAX_LENGTH, fmt, args);
|
||||
|
||||
/* we don't need that flag here, but if it gets used, strip it so we print correctly */
|
||||
screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX;
|
||||
|
||||
/* log to UART */
|
||||
log_to_uart(buf);
|
||||
|
||||
print_to_screen(screen_log_level, buf);
|
||||
}
|
||||
|
||||
static void add_prefix(ScreenLogLevel screen_log_level, const char *fmt, char *buf) {
|
||||
char typebuf[] = "[%s] %s";
|
||||
|
||||
/* apply prefix and append message format */
|
||||
/* TODO: add coloring to the output */
|
||||
switch(screen_log_level)
|
||||
{
|
||||
case SCREEN_LOG_LEVEL_ERROR:
|
||||
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "ERROR", fmt);
|
||||
break;
|
||||
case SCREEN_LOG_LEVEL_WARNING:
|
||||
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "WARNING", fmt);
|
||||
break;
|
||||
case SCREEN_LOG_LEVEL_MANDATORY:
|
||||
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt);
|
||||
break;
|
||||
case SCREEN_LOG_LEVEL_INFO:
|
||||
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "INFO", fmt);
|
||||
break;
|
||||
case SCREEN_LOG_LEVEL_DEBUG:
|
||||
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "DEBUG", fmt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* print - logs a message and prints it to screen based on its screen_log_level
|
||||
*
|
||||
* If the level is below g_screen_log_level it will not be shown but logged to UART
|
||||
* Use SCREEN_LOG_LEVEL_NO_PREFIX if you don't want a prefix to be added
|
||||
* UART is TODO
|
||||
*/
|
||||
void print(ScreenLogLevel screen_log_level, const char * fmt, ...)
|
||||
{
|
||||
char buf[PRINT_MESSAGE_MAX_LENGTH] = {};
|
||||
char message[PRINT_MESSAGE_MAX_LENGTH] = {};
|
||||
|
||||
/* TODO: make splash disappear if level > MANDATORY */
|
||||
|
||||
/* make prefix free messages with log_level possible */
|
||||
if(screen_log_level & SCREEN_LOG_LEVEL_NO_PREFIX) {
|
||||
/* remove the NO_PREFIX flag so the enum can be recognized later on */
|
||||
screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX;
|
||||
|
||||
snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt);
|
||||
}
|
||||
else {
|
||||
add_prefix(screen_log_level, fmt, buf);
|
||||
}
|
||||
|
||||
/* input arguments */
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(message, PRINT_MESSAGE_MAX_LENGTH, buf, args);
|
||||
va_end(args);
|
||||
|
||||
/* log to UART */
|
||||
log_to_uart(message);
|
||||
|
||||
print_to_screen(screen_log_level, message);
|
||||
}
|
||||
43
fusee/fusee-mtc/src/lib/log.h
Normal file
43
fusee/fusee-mtc/src/lib/log.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_LOG_H
|
||||
#define FUSEE_LOG_H
|
||||
|
||||
#define PRINT_MESSAGE_MAX_LENGTH 512
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef enum {
|
||||
SCREEN_LOG_LEVEL_NONE = 0,
|
||||
SCREEN_LOG_LEVEL_ERROR = 1,
|
||||
SCREEN_LOG_LEVEL_WARNING = 2,
|
||||
SCREEN_LOG_LEVEL_MANDATORY = 3, /* no log prefix */
|
||||
SCREEN_LOG_LEVEL_INFO = 4,
|
||||
SCREEN_LOG_LEVEL_DEBUG = 5,
|
||||
|
||||
SCREEN_LOG_LEVEL_NO_PREFIX = 0x100 /* OR this to your LOG_LEVEL to prevent prefix creation */
|
||||
} ScreenLogLevel;
|
||||
|
||||
extern ScreenLogLevel g_screen_log_level;
|
||||
|
||||
void log_set_log_level(ScreenLogLevel screen_log_level);
|
||||
ScreenLogLevel log_get_log_level();
|
||||
void log_to_uart(const char *message);
|
||||
void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args);
|
||||
void print(ScreenLogLevel screen_log_level, const char* fmt, ...);
|
||||
|
||||
#endif
|
||||
1676
fusee/fusee-mtc/src/lib/vsprintf.c
Normal file
1676
fusee/fusee-mtc/src/lib/vsprintf.c
Normal file
File diff suppressed because it is too large
Load Diff
28
fusee/fusee-mtc/src/lib/vsprintf.h
Normal file
28
fusee/fusee-mtc/src/lib/vsprintf.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrei Warkentin <andrey.warkentin@gmail.com>
|
||||
*
|
||||
* This program is free software ; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef VSPRINTF_H
|
||||
#define VSPRINTF_H
|
||||
|
||||
struct va_format {
|
||||
const char *fmt;
|
||||
va_list *va;
|
||||
};
|
||||
|
||||
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base);
|
||||
|
||||
int sprintf(char *buf, const char *fmt, ...);
|
||||
int scnprintf(char *buf, size_t size, const char *fmt, ...);
|
||||
int snprintf(char *buf, size_t size, const char *fmt, ...);
|
||||
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
|
||||
int sscanf(const char *buf, const char *fmt, ...);
|
||||
|
||||
#endif /* VSPRINTF_H */
|
||||
57
fusee/fusee-mtc/src/main.c
Normal file
57
fusee/fusee-mtc/src/main.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 <string.h>
|
||||
#include "mtc.h"
|
||||
#include "stage2.h"
|
||||
#include "display/video_fb.h"
|
||||
|
||||
static void *g_framebuffer;
|
||||
static __attribute__((__aligned__(0x200))) stage2_mtc_args_t g_mtc_args_store;
|
||||
static stage2_mtc_args_t *g_mtc_args;
|
||||
|
||||
/* Allow for main(int argc, void **argv) signature. */
|
||||
#pragma GCC diagnostic ignored "-Wmain"
|
||||
|
||||
int main(int argc, void **argv) {
|
||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
||||
|
||||
/* Check argc. */
|
||||
if (argc != MTC_ARGC) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract arguments from argv. */
|
||||
g_mtc_args = &g_mtc_args_store;
|
||||
memcpy(g_mtc_args, (stage2_mtc_args_t *)argv[MTC_ARGV_ARGUMENT_STRUCT], sizeof(*g_mtc_args));
|
||||
log_level = g_mtc_args->log_level;
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(log_level);
|
||||
|
||||
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Set framebuffer address. */
|
||||
g_framebuffer = (void *)0xC0000000;
|
||||
|
||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||
video_init(g_framebuffer);
|
||||
}
|
||||
|
||||
/* Train DRAM. */
|
||||
train_dram();
|
||||
|
||||
return 0;
|
||||
}
|
||||
167
fusee/fusee-mtc/src/mc.c
Normal file
167
fusee/fusee-mtc/src/mc.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 "mc.h"
|
||||
#include "car.h"
|
||||
#include "timers.h"
|
||||
|
||||
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock)
|
||||
{
|
||||
MAKE_MC_REG(MC_SEC_CARVEOUT_BOM) = bom;
|
||||
MAKE_MC_REG(MC_SEC_CARVEOUT_SIZE_MB) = size1mb;
|
||||
|
||||
if (lock)
|
||||
MAKE_MC_REG(MC_SEC_CARVEOUT_REG_CTRL) = 1;
|
||||
}
|
||||
|
||||
void mc_config_carveout()
|
||||
{
|
||||
*(volatile uint32_t *)0x8005FFFC = 0xC0EDBBCC;
|
||||
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = 1;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = 0;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_BOM) = 0;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_SIZE_MB) = 0;
|
||||
MAKE_MC_REG(MC_VIDEO_PROTECT_REG_CTRL) = 1;
|
||||
|
||||
mc_config_tsec_carveout(0, 0, true);
|
||||
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_BOM) = 0;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_SIZE_MB) = 0;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_ADR_HI) = 0;
|
||||
MAKE_MC_REG(MC_MTS_CARVEOUT_REG_CTRL) = 1;
|
||||
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_BOM_HI) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_SIZE_128KB) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT1_CFG0) = 0x4000006;
|
||||
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_BOM_HI) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_SIZE_128KB) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT3_CFG0) = 0x4401E7E;
|
||||
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_BOM_HI) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_SIZE_128KB) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT4_CFG0) = 0x8F;
|
||||
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_BOM_HI) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_SIZE_128KB) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT5_CFG0) = 0x8F;
|
||||
}
|
||||
|
||||
void mc_config_carveout_finalize()
|
||||
{
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM) = 0x80020000;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_BOM_HI) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_SIZE_128KB) = 2;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2) = (BIT(CSR_GPUSRD) | BIT(CSW_GPUSWR));
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4) = (BIT(CSR_GPUSRD2) | BIT(CSW_GPUSWR2));
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4) = 0;
|
||||
MAKE_MC_REG(MC_SECURITY_CARVEOUT2_CFG0) = 0x440167E;
|
||||
}
|
||||
|
||||
void mc_enable_ahb_redirect()
|
||||
{
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
car->lvl2_clk_gate_ovrd = ((car->lvl2_clk_gate_ovrd & 0xFFF7FFFF) | 0x80000);
|
||||
|
||||
MAKE_MC_REG(MC_IRAM_BOM) = 0x40000000;
|
||||
MAKE_MC_REG(MC_IRAM_TOM) = 0x4003F000;
|
||||
}
|
||||
|
||||
void mc_disable_ahb_redirect()
|
||||
{
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
|
||||
MAKE_MC_REG(MC_IRAM_BOM) = 0xFFFFF000;
|
||||
MAKE_MC_REG(MC_IRAM_TOM) = 0;
|
||||
|
||||
car->lvl2_clk_gate_ovrd &= 0xFFF7FFFF;
|
||||
}
|
||||
|
||||
void mc_enable()
|
||||
{
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
|
||||
/* Set EMC clock source. */
|
||||
car->clk_source_emc = ((car->clk_source_emc & 0x1FFFFFFF) | 0x40000000);
|
||||
|
||||
/* Enable MIPI CAL clock. */
|
||||
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFDFFFFFF) | 0x2000000);
|
||||
|
||||
/* Enable MC clock. */
|
||||
car->clk_enb_h_set = ((car->clk_enb_h_set & 0xFFFFFFFE) | 1);
|
||||
|
||||
/* Enable EMC DLL clock. */
|
||||
car->clk_enb_x_set = ((car->clk_enb_x_set & 0xFFFFBFFF) | 0x4000);
|
||||
|
||||
/* Clear EMC and MC reset. */
|
||||
car->rst_dev_h_set = 0x2000001;
|
||||
udelay(5);
|
||||
|
||||
mc_disable_ahb_redirect();
|
||||
}
|
||||
598
fusee/fusee-mtc/src/mc.h
Normal file
598
fusee/fusee-mtc/src/mc.h
Normal file
@@ -0,0 +1,598 @@
|
||||
/*
|
||||
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_MC_H_
|
||||
#define FUSEE_MC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MC_BASE 0x70019000
|
||||
#define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n)
|
||||
|
||||
#define MC_INTSTATUS 0x0
|
||||
#define MC_INTMASK 0x4
|
||||
#define MC_ERR_STATUS 0x8
|
||||
#define MC_ERR_ADR 0xc
|
||||
#define MC_SMMU_CONFIG 0x10
|
||||
#define MC_SMMU_TLB_CONFIG 0x14
|
||||
#define MC_SMMU_PTC_CONFIG 0x18
|
||||
#define MC_SMMU_PTB_ASID 0x1c
|
||||
#define MC_SMMU_PTB_DATA 0x20
|
||||
#define MC_SMMU_TLB_FLUSH 0x30
|
||||
#define MC_SMMU_PTC_FLUSH 0x34
|
||||
#define MC_SMMU_ASID_SECURITY 0x38
|
||||
#define MC_SMMU_AFI_ASID 0x238
|
||||
#define MC_SMMU_AVPC_ASID 0x23c
|
||||
#define MC_SMMU_TSEC_ASID 0x294
|
||||
#define MC_SMMU_PPCS1_ASID 0x298
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_0 0x228
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_1 0x22c
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_2 0x230
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_3 0x234
|
||||
#define MC_SMMU_TRANSLATION_ENABLE_4 0xb98
|
||||
#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0
|
||||
#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4
|
||||
#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8
|
||||
#define MC_PCFIFO_CLIENT_CONFIG3 0xddc
|
||||
#define MC_PCFIFO_CLIENT_CONFIG4 0xde0
|
||||
#define MC_EMEM_CFG 0x50
|
||||
#define MC_EMEM_ADR_CFG 0x54
|
||||
#define MC_EMEM_ADR_CFG_DEV0 0x58
|
||||
#define MC_EMEM_ADR_CFG_DEV1 0x5c
|
||||
#define MC_EMEM_ADR_CFG_CHANNEL_MASK 0x60
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_0 0x64
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_1 0x68
|
||||
#define MC_EMEM_ADR_CFG_BANK_MASK_2 0x6c
|
||||
#define MC_SECURITY_CFG0 0x70
|
||||
#define MC_SECURITY_CFG1 0x74
|
||||
#define MC_SECURITY_CFG3 0x9bc
|
||||
#define MC_SECURITY_RSV 0x7c
|
||||
#define MC_EMEM_ARB_CFG 0x90
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
|
||||
#define MC_EMEM_ARB_TIMING_RCD 0x98
|
||||
#define MC_EMEM_ARB_TIMING_RP 0x9c
|
||||
#define MC_EMEM_ARB_TIMING_RC 0xa0
|
||||
#define MC_EMEM_ARB_TIMING_RAS 0xa4
|
||||
#define MC_EMEM_ARB_TIMING_FAW 0xa8
|
||||
#define MC_EMEM_ARB_TIMING_RRD 0xac
|
||||
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
|
||||
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
|
||||
#define MC_EMEM_ARB_TIMING_R2R 0xb8
|
||||
#define MC_EMEM_ARB_TIMING_W2W 0xbc
|
||||
#define MC_EMEM_ARB_TIMING_R2W 0xc0
|
||||
#define MC_EMEM_ARB_TIMING_W2R 0xc4
|
||||
#define MC_EMEM_ARB_TIMING_RFCPB 0x6c0
|
||||
#define MC_EMEM_ARB_TIMING_CCDMW 0x6c4
|
||||
#define MC_EMEM_ARB_REFPB_HP_CTRL 0x6f0
|
||||
#define MC_EMEM_ARB_REFPB_BANK_CTRL 0x6f4
|
||||
#define MC_EMEM_ARB_DA_TURNS 0xd0
|
||||
#define MC_EMEM_ARB_DA_COVERS 0xd4
|
||||
#define MC_EMEM_ARB_MISC0 0xd8
|
||||
#define MC_EMEM_ARB_MISC1 0xdc
|
||||
#define MC_EMEM_ARB_MISC2 0xc8
|
||||
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
|
||||
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE 0x6b0
|
||||
#define MC_EMEM_ARB_OVERRIDE 0xe8
|
||||
#define MC_EMEM_ARB_RSV 0xec
|
||||
#define MC_CLKEN_OVERRIDE 0xf4
|
||||
#define MC_TIMING_CONTROL_DBG 0xf8
|
||||
#define MC_TIMING_CONTROL 0xfc
|
||||
#define MC_STAT_CONTROL 0x100
|
||||
#define MC_STAT_STATUS 0x104
|
||||
#define MC_STAT_EMC_CLOCK_LIMIT 0x108
|
||||
#define MC_STAT_EMC_CLOCK_LIMIT_MSBS 0x10c
|
||||
#define MC_STAT_EMC_CLOCKS 0x110
|
||||
#define MC_STAT_EMC_CLOCKS_MSBS 0x114
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_LO 0x118
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_LO 0x158
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_HI 0x11c
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_HI 0x15c
|
||||
#define MC_STAT_EMC_FILTER_SET0_ADR_LIMIT_UPPER 0xa20
|
||||
#define MC_STAT_EMC_FILTER_SET1_ADR_LIMIT_UPPER 0xa24
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_LO 0x198
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_LO 0x1a8
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_HI 0x19c
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_HI 0x1ac
|
||||
#define MC_STAT_EMC_FILTER_SET0_VIRTUAL_ADR_LIMIT_UPPER 0xa28
|
||||
#define MC_STAT_EMC_FILTER_SET1_VIRTUAL_ADR_LIMIT_UPPER 0xa2c
|
||||
#define MC_STAT_EMC_FILTER_SET0_ASID 0x1a0
|
||||
#define MC_STAT_EMC_FILTER_SET1_ASID 0x1b0
|
||||
#define MC_STAT_EMC_FILTER_SET0_SLACK_LIMIT 0x120
|
||||
#define MC_STAT_EMC_FILTER_SET1_SLACK_LIMIT 0x160
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_0 0x128
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_0 0x168
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_1 0x12c
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_1 0x16c
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_2 0x130
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_2 0x170
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_3 0x134
|
||||
#define MC_STAT_EMC_FILTER_SET0_CLIENT_4 0xb88
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_3 0x174
|
||||
#define MC_STAT_EMC_FILTER_SET1_CLIENT_4 0xb8c
|
||||
#define MC_STAT_EMC_SET0_COUNT 0x138
|
||||
#define MC_STAT_EMC_SET0_COUNT_MSBS 0x13c
|
||||
#define MC_STAT_EMC_SET1_COUNT 0x178
|
||||
#define MC_STAT_EMC_SET1_COUNT_MSBS 0x17c
|
||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM 0x140
|
||||
#define MC_STAT_EMC_SET0_SLACK_ACCUM_MSBS 0x144
|
||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM 0x180
|
||||
#define MC_STAT_EMC_SET1_SLACK_ACCUM_MSBS 0x184
|
||||
#define MC_STAT_EMC_SET0_HISTO_COUNT 0x148
|
||||
#define MC_STAT_EMC_SET0_HISTO_COUNT_MSBS 0x14c
|
||||
#define MC_STAT_EMC_SET1_HISTO_COUNT 0x188
|
||||
#define MC_STAT_EMC_SET1_HISTO_COUNT_MSBS 0x18c
|
||||
#define MC_STAT_EMC_SET0_MINIMUM_SLACK_OBSERVED 0x150
|
||||
#define MC_STAT_EMC_SET1_MINIMUM_SLACK_OBSERVED 0x190
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_COUNT 0x1b8
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCL_COUNT_MSBS 0x1bc
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_COUNT 0x1c8
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCL_COUNT_MSBS 0x1cc
|
||||
#define MC_STAT_EMC_SET0_IDLE_CYCLE_PARTITION_SELECT 0x1c0
|
||||
#define MC_STAT_EMC_SET1_IDLE_CYCLE_PARTITION_SELECT 0x1d0
|
||||
#define MC_CLIENT_HOTRESET_CTRL 0x200
|
||||
#define MC_CLIENT_HOTRESET_CTRL_1 0x970
|
||||
#define MC_CLIENT_HOTRESET_STATUS 0x204
|
||||
#define MC_CLIENT_HOTRESET_STATUS_1 0x974
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_0 0x208
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_1 0x20c
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_2 0x210
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_3 0x214
|
||||
#define MC_EMEM_ARB_ISOCHRONOUS_4 0xb94
|
||||
#define MC_EMEM_ARB_HYSTERESIS_0 0x218
|
||||
#define MC_EMEM_ARB_HYSTERESIS_1 0x21c
|
||||
#define MC_EMEM_ARB_HYSTERESIS_2 0x220
|
||||
#define MC_EMEM_ARB_HYSTERESIS_3 0x224
|
||||
#define MC_EMEM_ARB_HYSTERESIS_4 0xb84
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_0 0xbb0
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_1 0xbb4
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_2 0xbb8
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_3 0xbbc
|
||||
#define MC_EMEM_ARB_DHYSTERESIS_4 0xbc0
|
||||
#define MC_EMEM_ARB_DHYST_CTRL 0xbcc
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0 0xbd0
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1 0xbd4
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2 0xbd8
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3 0xbdc
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4 0xbe0
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5 0xbe4
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6 0xbe8
|
||||
#define MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7 0xbec
|
||||
#define MC_RESERVED_RSV 0x3fc
|
||||
#define MC_DISB_EXTRA_SNAP_LEVELS 0x408
|
||||
#define MC_APB_EXTRA_SNAP_LEVELS 0x2a4
|
||||
#define MC_AHB_EXTRA_SNAP_LEVELS 0x2a0
|
||||
#define MC_USBD_EXTRA_SNAP_LEVELS 0xa18
|
||||
#define MC_ISP_EXTRA_SNAP_LEVELS 0xa08
|
||||
#define MC_AUD_EXTRA_SNAP_LEVELS 0xa10
|
||||
#define MC_MSE_EXTRA_SNAP_LEVELS 0x40c
|
||||
#define MC_GK2_EXTRA_SNAP_LEVELS 0xa40
|
||||
#define MC_A9AVPPC_EXTRA_SNAP_LEVELS 0x414
|
||||
#define MC_FTOP_EXTRA_SNAP_LEVELS 0x2bc
|
||||
#define MC_JPG_EXTRA_SNAP_LEVELS 0xa3c
|
||||
#define MC_HOST_EXTRA_SNAP_LEVELS 0xa14
|
||||
#define MC_SAX_EXTRA_SNAP_LEVELS 0x2c0
|
||||
#define MC_DIS_EXTRA_SNAP_LEVELS 0x2ac
|
||||
#define MC_VICPC_EXTRA_SNAP_LEVELS 0xa1c
|
||||
#define MC_HDAPC_EXTRA_SNAP_LEVELS 0xa48
|
||||
#define MC_AVP_EXTRA_SNAP_LEVELS 0x2a8
|
||||
#define MC_USBX_EXTRA_SNAP_LEVELS 0x404
|
||||
#define MC_PCX_EXTRA_SNAP_LEVELS 0x2b8
|
||||
#define MC_SD_EXTRA_SNAP_LEVELS 0xa04
|
||||
#define MC_DFD_EXTRA_SNAP_LEVELS 0xa4c
|
||||
#define MC_VE_EXTRA_SNAP_LEVELS 0x2d8
|
||||
#define MC_GK_EXTRA_SNAP_LEVELS 0xa00
|
||||
#define MC_VE2_EXTRA_SNAP_LEVELS 0x410
|
||||
#define MC_SDM_EXTRA_SNAP_LEVELS 0xa44
|
||||
#define MC_VIDEO_PROTECT_BOM 0x648
|
||||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
||||
#define MC_VIDEO_PROTECT_BOM_ADR_HI 0x978
|
||||
#define MC_VIDEO_PROTECT_REG_CTRL 0x650
|
||||
#define MC_ERR_VPR_STATUS 0x654
|
||||
#define MC_ERR_VPR_ADR 0x658
|
||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE 0x418
|
||||
#define MC_VIDEO_PROTECT_VPR_OVERRIDE1 0x590
|
||||
#define MC_IRAM_BOM 0x65c
|
||||
#define MC_IRAM_TOM 0x660
|
||||
#define MC_IRAM_ADR_HI 0x980
|
||||
#define MC_IRAM_REG_CTRL 0x964
|
||||
#define MC_EMEM_CFG_ACCESS_CTRL 0x664
|
||||
#define MC_TZ_SECURITY_CTRL 0x668
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_RING3 0x66c
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ_NISO 0x6b4
|
||||
#define MC_EMEM_ARB_RING0_THROTTLE_MASK 0x6bc
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK 0x6b8
|
||||
#define MC_EMEM_ARB_NISO_THROTTLE_MASK_1 0xb80
|
||||
#define MC_SEC_CARVEOUT_BOM 0x670
|
||||
#define MC_SEC_CARVEOUT_SIZE_MB 0x674
|
||||
#define MC_SEC_CARVEOUT_ADR_HI 0x9d4
|
||||
#define MC_SEC_CARVEOUT_REG_CTRL 0x678
|
||||
#define MC_ERR_SEC_STATUS 0x67c
|
||||
#define MC_ERR_SEC_ADR 0x680
|
||||
#define MC_PC_IDLE_CLOCK_GATE_CONFIG 0x684
|
||||
#define MC_STUTTER_CONTROL 0x688
|
||||
#define MC_RESERVED_RSV_1 0x958
|
||||
#define MC_DVFS_PIPE_SELECT 0x95c
|
||||
#define MC_AHB_PTSA_MIN 0x4e0
|
||||
#define MC_AUD_PTSA_MIN 0x54c
|
||||
#define MC_MLL_MPCORER_PTSA_RATE 0x44c
|
||||
#define MC_RING2_PTSA_RATE 0x440
|
||||
#define MC_USBD_PTSA_RATE 0x530
|
||||
#define MC_USBX_PTSA_MIN 0x528
|
||||
#define MC_USBD_PTSA_MIN 0x534
|
||||
#define MC_APB_PTSA_MAX 0x4f0
|
||||
#define MC_JPG_PTSA_RATE 0x584
|
||||
#define MC_DIS_PTSA_MIN 0x420
|
||||
#define MC_AVP_PTSA_MAX 0x4fc
|
||||
#define MC_AVP_PTSA_RATE 0x4f4
|
||||
#define MC_RING1_PTSA_MIN 0x480
|
||||
#define MC_DIS_PTSA_MAX 0x424
|
||||
#define MC_SD_PTSA_MAX 0x4d8
|
||||
#define MC_MSE_PTSA_RATE 0x4c4
|
||||
#define MC_VICPC_PTSA_MIN 0x558
|
||||
#define MC_PCX_PTSA_MAX 0x4b4
|
||||
#define MC_ISP_PTSA_RATE 0x4a0
|
||||
#define MC_A9AVPPC_PTSA_MIN 0x48c
|
||||
#define MC_RING2_PTSA_MAX 0x448
|
||||
#define MC_AUD_PTSA_RATE 0x548
|
||||
#define MC_HOST_PTSA_MIN 0x51c
|
||||
#define MC_MLL_MPCORER_PTSA_MAX 0x454
|
||||
#define MC_SD_PTSA_MIN 0x4d4
|
||||
#define MC_RING1_PTSA_RATE 0x47c
|
||||
#define MC_JPG_PTSA_MIN 0x588
|
||||
#define MC_HDAPC_PTSA_MIN 0x62c
|
||||
#define MC_AVP_PTSA_MIN 0x4f8
|
||||
#define MC_JPG_PTSA_MAX 0x58c
|
||||
#define MC_VE_PTSA_MAX 0x43c
|
||||
#define MC_DFD_PTSA_MAX 0x63c
|
||||
#define MC_VICPC_PTSA_RATE 0x554
|
||||
#define MC_GK_PTSA_MAX 0x544
|
||||
#define MC_VICPC_PTSA_MAX 0x55c
|
||||
#define MC_SDM_PTSA_MAX 0x624
|
||||
#define MC_SAX_PTSA_RATE 0x4b8
|
||||
#define MC_PCX_PTSA_MIN 0x4b0
|
||||
#define MC_APB_PTSA_MIN 0x4ec
|
||||
#define MC_GK2_PTSA_MIN 0x614
|
||||
#define MC_PCX_PTSA_RATE 0x4ac
|
||||
#define MC_RING1_PTSA_MAX 0x484
|
||||
#define MC_HDAPC_PTSA_RATE 0x628
|
||||
#define MC_MLL_MPCORER_PTSA_MIN 0x450
|
||||
#define MC_GK2_PTSA_MAX 0x618
|
||||
#define MC_AUD_PTSA_MAX 0x550
|
||||
#define MC_GK2_PTSA_RATE 0x610
|
||||
#define MC_ISP_PTSA_MAX 0x4a8
|
||||
#define MC_DISB_PTSA_RATE 0x428
|
||||
#define MC_VE2_PTSA_MAX 0x49c
|
||||
#define MC_DFD_PTSA_MIN 0x638
|
||||
#define MC_FTOP_PTSA_RATE 0x50c
|
||||
#define MC_A9AVPPC_PTSA_RATE 0x488
|
||||
#define MC_VE2_PTSA_MIN 0x498
|
||||
#define MC_USBX_PTSA_MAX 0x52c
|
||||
#define MC_DIS_PTSA_RATE 0x41c
|
||||
#define MC_USBD_PTSA_MAX 0x538
|
||||
#define MC_A9AVPPC_PTSA_MAX 0x490
|
||||
#define MC_USBX_PTSA_RATE 0x524
|
||||
#define MC_FTOP_PTSA_MAX 0x514
|
||||
#define MC_HDAPC_PTSA_MAX 0x630
|
||||
#define MC_SD_PTSA_RATE 0x4d0
|
||||
#define MC_DFD_PTSA_RATE 0x634
|
||||
#define MC_FTOP_PTSA_MIN 0x510
|
||||
#define MC_SDM_PTSA_RATE 0x61c
|
||||
#define MC_AHB_PTSA_RATE 0x4dc
|
||||
#define MC_SMMU_SMMU_PTSA_MAX 0x460
|
||||
#define MC_RING2_PTSA_MIN 0x444
|
||||
#define MC_SDM_PTSA_MIN 0x620
|
||||
#define MC_APB_PTSA_RATE 0x4e8
|
||||
#define MC_MSE_PTSA_MIN 0x4c8
|
||||
#define MC_HOST_PTSA_RATE 0x518
|
||||
#define MC_VE_PTSA_RATE 0x434
|
||||
#define MC_AHB_PTSA_MAX 0x4e4
|
||||
#define MC_SAX_PTSA_MIN 0x4bc
|
||||
#define MC_SMMU_SMMU_PTSA_MIN 0x45c
|
||||
#define MC_ISP_PTSA_MIN 0x4a4
|
||||
#define MC_HOST_PTSA_MAX 0x520
|
||||
#define MC_SAX_PTSA_MAX 0x4c0
|
||||
#define MC_VE_PTSA_MIN 0x438
|
||||
#define MC_GK_PTSA_MIN 0x540
|
||||
#define MC_MSE_PTSA_MAX 0x4cc
|
||||
#define MC_DISB_PTSA_MAX 0x430
|
||||
#define MC_DISB_PTSA_MIN 0x42c
|
||||
#define MC_SMMU_SMMU_PTSA_RATE 0x458
|
||||
#define MC_VE2_PTSA_RATE 0x494
|
||||
#define MC_GK_PTSA_RATE 0x53c
|
||||
#define MC_PTSA_GRANT_DECREMENT 0x960
|
||||
#define MC_LATENCY_ALLOWANCE_AVPC_0 0x2e4
|
||||
#define MC_LATENCY_ALLOWANCE_AXIAP_0 0x3a0
|
||||
#define MC_LATENCY_ALLOWANCE_XUSB_1 0x380
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2B_0 0x384
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCAA_0 0x3bc
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCA_0 0x3b8
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2_0 0x370
|
||||
#define MC_LATENCY_ALLOWANCE_SE_0 0x3e0
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2_1 0x374
|
||||
#define MC_LATENCY_ALLOWANCE_DC_0 0x2e8
|
||||
#define MC_LATENCY_ALLOWANCE_VIC_0 0x394
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_1 0x2f8
|
||||
#define MC_LATENCY_ALLOWANCE_NVDEC_0 0x3d8
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_2 0x2fc
|
||||
#define MC_LATENCY_ALLOWANCE_TSEC_0 0x390
|
||||
#define MC_LATENCY_ALLOWANCE_DC_2 0x2f0
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0AB 0x694
|
||||
#define MC_LATENCY_ALLOWANCE_PPCS_1 0x348
|
||||
#define MC_LATENCY_ALLOWANCE_XUSB_0 0x37c
|
||||
#define MC_LATENCY_ALLOWANCE_PPCS_0 0x344
|
||||
#define MC_LATENCY_ALLOWANCE_TSECB_0 0x3f0
|
||||
#define MC_LATENCY_ALLOWANCE_AFI_0 0x2e0
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0B 0x698
|
||||
#define MC_LATENCY_ALLOWANCE_DC_1 0x2ec
|
||||
#define MC_LATENCY_ALLOWANCE_APE_0 0x3dc
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0C 0x6a0
|
||||
#define MC_LATENCY_ALLOWANCE_A9AVP_0 0x3a4
|
||||
#define MC_LATENCY_ALLOWANCE_GPU2_0 0x3e8
|
||||
#define MC_LATENCY_ALLOWANCE_DCB_0 0x2f4
|
||||
#define MC_LATENCY_ALLOWANCE_HC_1 0x314
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMC_0 0x3c0
|
||||
#define MC_LATENCY_ALLOWANCE_NVJPG_0 0x3e4
|
||||
#define MC_LATENCY_ALLOWANCE_PTC_0 0x34c
|
||||
#define MC_LATENCY_ALLOWANCE_ETR_0 0x3ec
|
||||
#define MC_LATENCY_ALLOWANCE_MPCORE_0 0x320
|
||||
#define MC_LATENCY_ALLOWANCE_VI2_0 0x398
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0BB 0x69c
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0CB 0x6a4
|
||||
#define MC_LATENCY_ALLOWANCE_SATA_0 0x350
|
||||
#define MC_SCALED_LATENCY_ALLOWANCE_DISPLAY0A 0x690
|
||||
#define MC_LATENCY_ALLOWANCE_HC_0 0x310
|
||||
#define MC_LATENCY_ALLOWANCE_DC_3 0x3c8
|
||||
#define MC_LATENCY_ALLOWANCE_GPU_0 0x3ac
|
||||
#define MC_LATENCY_ALLOWANCE_SDMMCAB_0 0x3c4
|
||||
#define MC_LATENCY_ALLOWANCE_ISP2B_1 0x388
|
||||
#define MC_LATENCY_ALLOWANCE_NVENC_0 0x328
|
||||
#define MC_LATENCY_ALLOWANCE_HDA_0 0x318
|
||||
#define MC_MIN_LENGTH_APE_0 0xb34
|
||||
#define MC_MIN_LENGTH_DCB_2 0x8a8
|
||||
#define MC_MIN_LENGTH_A9AVP_0 0x950
|
||||
#define MC_MIN_LENGTH_TSEC_0 0x93c
|
||||
#define MC_MIN_LENGTH_DC_1 0x898
|
||||
#define MC_MIN_LENGTH_AXIAP_0 0x94c
|
||||
#define MC_MIN_LENGTH_ISP2B_0 0x930
|
||||
#define MC_MIN_LENGTH_VI2_0 0x944
|
||||
#define MC_MIN_LENGTH_DCB_0 0x8a0
|
||||
#define MC_MIN_LENGTH_DCB_1 0x8a4
|
||||
#define MC_MIN_LENGTH_PPCS_1 0x8f4
|
||||
#define MC_MIN_LENGTH_NVJPG_0 0xb3c
|
||||
#define MC_MIN_LENGTH_HDA_0 0x8c4
|
||||
#define MC_MIN_LENGTH_NVENC_0 0x8d4
|
||||
#define MC_MIN_LENGTH_SDMMC_0 0xb18
|
||||
#define MC_MIN_LENGTH_ISP2B_1 0x934
|
||||
#define MC_MIN_LENGTH_HC_1 0x8c0
|
||||
#define MC_MIN_LENGTH_DC_3 0xb20
|
||||
#define MC_MIN_LENGTH_AVPC_0 0x890
|
||||
#define MC_MIN_LENGTH_VIC_0 0x940
|
||||
#define MC_MIN_LENGTH_ISP2_0 0x91c
|
||||
#define MC_MIN_LENGTH_HC_0 0x8bc
|
||||
#define MC_MIN_LENGTH_SE_0 0xb38
|
||||
#define MC_MIN_LENGTH_NVDEC_0 0xb30
|
||||
#define MC_MIN_LENGTH_SATA_0 0x8fc
|
||||
#define MC_MIN_LENGTH_DC_0 0x894
|
||||
#define MC_MIN_LENGTH_XUSB_1 0x92c
|
||||
#define MC_MIN_LENGTH_DC_2 0x89c
|
||||
#define MC_MIN_LENGTH_SDMMCAA_0 0xb14
|
||||
#define MC_MIN_LENGTH_GPU_0 0xb04
|
||||
#define MC_MIN_LENGTH_ETR_0 0xb44
|
||||
#define MC_MIN_LENGTH_AFI_0 0x88c
|
||||
#define MC_MIN_LENGTH_PPCS_0 0x8f0
|
||||
#define MC_MIN_LENGTH_ISP2_1 0x920
|
||||
#define MC_MIN_LENGTH_XUSB_0 0x928
|
||||
#define MC_MIN_LENGTH_MPCORE_0 0x8cc
|
||||
#define MC_MIN_LENGTH_TSECB_0 0xb48
|
||||
#define MC_MIN_LENGTH_SDMMCA_0 0xb10
|
||||
#define MC_MIN_LENGTH_GPU2_0 0xb40
|
||||
#define MC_MIN_LENGTH_SDMMCAB_0 0xb1c
|
||||
#define MC_MIN_LENGTH_PTC_0 0x8f8
|
||||
#define MC_EMEM_ARB_OVERRIDE_1 0x968
|
||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_0 0x984
|
||||
#define MC_VIDEO_PROTECT_GPU_OVERRIDE_1 0x988
|
||||
#define MC_EMEM_ARB_STATS_0 0x990
|
||||
#define MC_EMEM_ARB_STATS_1 0x994
|
||||
#define MC_MTS_CARVEOUT_BOM 0x9a0
|
||||
#define MC_MTS_CARVEOUT_SIZE_MB 0x9a4
|
||||
#define MC_MTS_CARVEOUT_ADR_HI 0x9a8
|
||||
#define MC_MTS_CARVEOUT_REG_CTRL 0x9ac
|
||||
#define MC_ERR_MTS_STATUS 0x9b0
|
||||
#define MC_ERR_MTS_ADR 0x9b4
|
||||
#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
|
||||
#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS2 0xd74
|
||||
#define MC_SECURITY_CARVEOUT4_CFG0 0xcf8
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS2 0xd10
|
||||
#define MC_SECURITY_CARVEOUT4_SIZE_128KB 0xd04
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS4 0xc28
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS1 0xc30
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS4 0xc8c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS0 0xd1c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS1 0xd70
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS0 0xc2c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS4 0xd7c
|
||||
#define MC_SECURITY_CARVEOUT3_SIZE_128KB 0xcb4
|
||||
#define MC_SECURITY_CARVEOUT2_CFG0 0xc58
|
||||
#define MC_SECURITY_CARVEOUT1_CFG0 0xc08
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS2 0xc84
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS0 0xc68
|
||||
#define MC_SECURITY_CARVEOUT3_BOM 0xcac
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS2 0xc70
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS3 0xd78
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS0 0xc7c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS4 0xd18
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS1 0xcbc
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS3 0xc38
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS2 0xc34
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS2 0xcc0
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS2 0xd60
|
||||
#define MC_SECURITY_CARVEOUT3_CFG0 0xca8
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS0 0xcb8
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS3 0xc88
|
||||
#define MC_SECURITY_CARVEOUT2_SIZE_128KB 0xc64
|
||||
#define MC_SECURITY_CARVEOUT5_BOM_HI 0xd50
|
||||
#define MC_SECURITY_CARVEOUT1_SIZE_128KB 0xc14
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS3 0xd14
|
||||
#define MC_SECURITY_CARVEOUT1_BOM 0xc0c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS4 0xd2c
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS4 0xd68
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS4 0xcc8
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS0 0xd58
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS2 0xd24
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_ACCESS3 0xcc4
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS4 0xc78
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS1 0xc1c
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS0 0xc18
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS3 0xd28
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS1 0xd5c
|
||||
#define MC_SECURITY_CARVEOUT3_BOM_HI 0xcb0
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS3 0xcd8
|
||||
#define MC_SECURITY_CARVEOUT2_BOM_HI 0xc60
|
||||
#define MC_SECURITY_CARVEOUT4_BOM_HI 0xd00
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_ACCESS3 0xd64
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS4 0xcdc
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_FORCE_INTERNAL_ACCESS1 0xc80
|
||||
#define MC_SECURITY_CARVEOUT5_SIZE_128KB 0xd54
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_FORCE_INTERNAL_ACCESS1 0xd20
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS2 0xcd4
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS1 0xd0c
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS3 0xc74
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS0 0xccc
|
||||
#define MC_SECURITY_CARVEOUT4_BOM 0xcfc
|
||||
#define MC_SECURITY_CARVEOUT5_CFG0 0xd48
|
||||
#define MC_SECURITY_CARVEOUT2_BOM 0xc5c
|
||||
#define MC_SECURITY_CARVEOUT5_BOM 0xd4c
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS3 0xc24
|
||||
#define MC_SECURITY_CARVEOUT5_CLIENT_FORCE_INTERNAL_ACCESS0 0xd6c
|
||||
#define MC_SECURITY_CARVEOUT3_CLIENT_FORCE_INTERNAL_ACCESS1 0xcd0
|
||||
#define MC_SECURITY_CARVEOUT1_BOM_HI 0xc10
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_ACCESS2 0xc20
|
||||
#define MC_SECURITY_CARVEOUT1_CLIENT_FORCE_INTERNAL_ACCESS4 0xc3c
|
||||
#define MC_SECURITY_CARVEOUT2_CLIENT_ACCESS1 0xc6c
|
||||
#define MC_SECURITY_CARVEOUT4_CLIENT_ACCESS0 0xd08
|
||||
#define MC_ERR_APB_ASID_UPDATE_STATUS 0x9d0
|
||||
#define MC_DA_CONFIG0 0x9dc
|
||||
|
||||
/* Memory Controller clients */
|
||||
#define CLIENT_ACCESS_NUM_CLIENTS 32
|
||||
typedef enum {
|
||||
/* _ACCESS0 */
|
||||
CSR_PTCR = (0 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0A = (1 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0AB = (2 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0B = (3 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0BB = (4 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0C = (5 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAY0CB = (6 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_AFIR = (14 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_AVPCARM7R = (15 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAYHC = (16 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_DISPLAYHCB = (17 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HDAR = (21 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HOST1XDMAR = (22 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_HOST1XR = (23 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_NVENCSRD = (28 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_PPCSAHBDMAR = (29 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_PPCSAHBSLVR = (30 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
CSR_SATAR = (31 - (CLIENT_ACCESS_NUM_CLIENTS * 0)),
|
||||
|
||||
/* _ACCESS1 */
|
||||
CSR_VDEBSEVR = (34 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDEMBER = (35 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDEMCER = (36 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_VDETPER = (37 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_MPCORELPR = (38 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSR_MPCORER = (39 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_NVENCSWR = (43 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_AFIW = (49 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_AVPCARM7W = (50 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_HDAW = (53 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_HOST1XW = (54 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_MPCORELPW = (56 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_MPCOREW = (57 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_PPCSAHBDMAW = (59 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_PPCSAHBSLVW = (60 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_SATAW = (61 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_VDEBSEVW = (62 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
CSW_VDEDBGW = (63 - (CLIENT_ACCESS_NUM_CLIENTS * 1)),
|
||||
|
||||
/* _ACCESS2 */
|
||||
CSW_VDEMBEW = (64 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_VDETPMW = (65 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_ISPRA = (68 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWA = (70 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWB = (71 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_XUSB_HOSTR = (74 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_XUSB_HOSTW = (75 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_XUSB_DEVR = (76 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_XUSB_DEVW = (77 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_ISPRAB = (78 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWAB = (80 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_ISPWBB = (81 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_TSECSRD = (84 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_TSECSWR = (85 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_A9AVPSCR = (86 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_A9AVPSCW = (87 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_GPUSRD = (88 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSW_GPUSWR = (89 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
CSR_DISPLAYT = (90 - (CLIENT_ACCESS_NUM_CLIENTS * 2)),
|
||||
|
||||
/* _ACCESS3 */
|
||||
CSR_SDMMCRA = (96 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCRAA = (97 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCR = (98 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_SDMMCRAB = (99 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWA = (100 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWAA = (101 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCW = (102 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_SDMMCWAB = (103 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_VICSRD = (108 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_VICSWR = (109 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_VIW = (114 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_DISPLAYD = (115 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_NVDECSRD = (120 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_NVDECSWR = (121 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_APER = (122 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_APEW = (123 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSR_NVJPGSRD = (126 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
CSW_NVJPGSWR = (127 - (CLIENT_ACCESS_NUM_CLIENTS * 3)),
|
||||
|
||||
/* _ACCESS4 */
|
||||
CSR_SESRD = (128 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_SESWR = (129 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_AXIAPR = (130 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_AXIAPW = (131 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_ETRR = (132 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_ETRW = (133 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_TSECSRDB = (134 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_TSECSWRB = (135 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSR_GPUSRD2 = (136 - (CLIENT_ACCESS_NUM_CLIENTS * 4)),
|
||||
CSW_GPUSWR2 = (137 - (CLIENT_ACCESS_NUM_CLIENTS * 4))
|
||||
} McClient;
|
||||
|
||||
void mc_config_tsec_carveout(uint32_t bom, uint32_t size1mb, bool lock);
|
||||
void mc_config_carveout();
|
||||
void mc_config_carveout_finalize();
|
||||
void mc_enable_ahb_redirect();
|
||||
void mc_disable_ahb_redirect();
|
||||
void mc_enable();
|
||||
|
||||
#endif
|
||||
@@ -3706,7 +3706,7 @@ static int train_one(int z_val, uint32_t next_rate, uint32_t current_rate, tegra
|
||||
return 0;
|
||||
}
|
||||
|
||||
void train_dram() {
|
||||
void train_dram(void) {
|
||||
volatile tegra_car_t *car = car_get_regs();
|
||||
|
||||
tegra_emc_timing_t *timing_tables;
|
||||
@@ -754,6 +754,6 @@ enum {
|
||||
};
|
||||
|
||||
/* Train all possible DRAM sequences. */
|
||||
void train_dram();
|
||||
void train_dram(void);
|
||||
|
||||
#endif
|
||||
29
fusee/fusee-mtc/src/stage2.h
Normal file
29
fusee/fusee-mtc/src/stage2.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_STAGE2_H
|
||||
#define FUSEE_STAGE2_H
|
||||
|
||||
#include "lib/log.h"
|
||||
|
||||
#define MTC_ARGV_ARGUMENT_STRUCT 0
|
||||
#define MTC_ARGC 1
|
||||
|
||||
typedef struct {
|
||||
ScreenLogLevel log_level;
|
||||
} stage2_mtc_args_t;
|
||||
|
||||
#endif
|
||||
70
fusee/fusee-mtc/src/start.s
Normal file
70
fusee/fusee-mtc/src/start.s
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
.macro CLEAR_GPR_REG_ITER
|
||||
mov r\@, #0
|
||||
.endm
|
||||
|
||||
.section .text.start, "ax", %progbits
|
||||
.arm
|
||||
.align 5
|
||||
.global _start
|
||||
.type _start, %function
|
||||
_start:
|
||||
/* Switch to system mode, mask all interrupts, clear all flags */
|
||||
msr cpsr_cxsf, #0xDF
|
||||
|
||||
/* Backup current stack pointer. */
|
||||
mov r12, sp
|
||||
|
||||
/* Set the stack pointer */
|
||||
ldr sp, =__stack_top__
|
||||
mov fp, #0
|
||||
|
||||
/* Save context */
|
||||
push {r12, lr}
|
||||
|
||||
/* Call init. */
|
||||
bl __program_init
|
||||
|
||||
/* Set r0 to r12 to 0 (for debugging) & call main */
|
||||
.rept 13
|
||||
CLEAR_GPR_REG_ITER
|
||||
.endr
|
||||
ldr r0, =__program_argc
|
||||
ldr r1, =__program_argv
|
||||
ldr r0, [r0]
|
||||
ldr r1, [r1]
|
||||
bl main
|
||||
|
||||
/* Save result. */
|
||||
push {r0}
|
||||
|
||||
/* Exit manually. */
|
||||
bl __program_exit
|
||||
|
||||
/* Restore result. */
|
||||
pop {r0}
|
||||
|
||||
/* Restore context */
|
||||
pop {r12}
|
||||
pop {lr}
|
||||
|
||||
/* Restore previous stack pointer. */
|
||||
mov sp, r12
|
||||
|
||||
/* Return */
|
||||
bx lr
|
||||
94
fusee/fusee-mtc/src/timers.h
Normal file
94
fusee/fusee-mtc/src/timers.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_TIMERS_H
|
||||
#define FUSEE_TIMERS_H
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define TIMERS_BASE 0x60005000
|
||||
#define MAKE_TIMERS_REG(n) MAKE_REG32(TIMERS_BASE + n)
|
||||
|
||||
#define TIMERUS_CNTR_1US_0 MAKE_TIMERS_REG(0x10)
|
||||
#define TIMERUS_USEC_CFG_0 MAKE_TIMERS_REG(0x14)
|
||||
#define SHARED_INTR_STATUS_0 MAKE_TIMERS_REG(0x1A0)
|
||||
#define SHARED_TIMER_SECURE_CFG_0 MAKE_TIMERS_REG(0x1A4)
|
||||
|
||||
#define RTC_BASE 0x7000E000
|
||||
#define MAKE_RTC_REG(n) MAKE_REG32(RTC_BASE + n)
|
||||
|
||||
#define RTC_SECONDS MAKE_RTC_REG(0x08)
|
||||
#define RTC_SHADOW_SECONDS MAKE_RTC_REG(0x0C)
|
||||
#define RTC_MILLI_SECONDS MAKE_RTC_REG(0x10)
|
||||
|
||||
typedef struct {
|
||||
uint32_t CONFIG;
|
||||
uint32_t STATUS;
|
||||
uint32_t COMMAND;
|
||||
uint32_t PATTERN;
|
||||
} watchdog_timers_t;
|
||||
|
||||
#define GET_WDT(n) ((volatile watchdog_timers_t *)(TIMERS_BASE + 0x100 + 0x20 * n))
|
||||
#define WDT_REBOOT_PATTERN 0xC45A
|
||||
#define GET_WDT_REBOOT_CFG_REG(n) MAKE_REG32(TIMERS_BASE + 0x60 + 0x8 * n)
|
||||
|
||||
void wait(uint32_t microseconds);
|
||||
|
||||
static inline uint32_t get_time_s(void) {
|
||||
return RTC_SECONDS;
|
||||
}
|
||||
|
||||
static inline uint32_t get_time_ms(void) {
|
||||
return (RTC_MILLI_SECONDS | (RTC_SHADOW_SECONDS << 10));
|
||||
}
|
||||
|
||||
static inline uint32_t get_time_us(void) {
|
||||
return TIMERUS_CNTR_1US_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds.
|
||||
*/
|
||||
static inline uint32_t get_time(void) {
|
||||
return get_time_us();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of microseconds that have passed since a given get_time().
|
||||
*/
|
||||
static inline uint32_t get_time_since(uint32_t base) {
|
||||
return get_time_us() - base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays for a given number of microseconds.
|
||||
*/
|
||||
static inline void udelay(uint32_t usecs) {
|
||||
uint32_t start = get_time_us();
|
||||
while (get_time_us() - start < usecs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays for a given number of milliseconds.
|
||||
*/
|
||||
static inline void mdelay(uint32_t msecs) {
|
||||
uint32_t start = get_time_ms();
|
||||
while (get_time_ms() - start < msecs);
|
||||
}
|
||||
|
||||
__attribute__ ((noreturn)) void watchdog_reboot(void);
|
||||
|
||||
#endif
|
||||
40
fusee/fusee-mtc/src/utils.c
Normal file
40
fusee/fusee-mtc/src/utils.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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 <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include "utils.h"
|
||||
#include "lib/log.h"
|
||||
|
||||
__attribute__ ((noreturn)) void generic_panic(void) {
|
||||
print(SCREEN_LOG_LEVEL_ERROR, "Panic raised!");
|
||||
|
||||
while (true) {
|
||||
/* Lock. */
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void fatal_error(const char *fmt, ...) {
|
||||
va_list args;
|
||||
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
|
||||
va_start(args, fmt);
|
||||
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
while (true) {
|
||||
/* Lock. */
|
||||
}
|
||||
}
|
||||
43
fusee/fusee-mtc/src/utils.h
Normal file
43
fusee/fusee-mtc/src/utils.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_UTILS_H
|
||||
#define FUSEE_UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define BIT(n) (1u << (n))
|
||||
#define BITL(n) (1ull << (n))
|
||||
#define MASK(n) (BIT(n) - 1)
|
||||
#define MASKL(n) (BITL(n) - 1)
|
||||
#define MASK2(a,b) (MASK(a) & ~MASK(b))
|
||||
#define MASK2L(a,b) (MASKL(a) & ~MASKL(b))
|
||||
|
||||
#define MAKE_REG32(a) (*(volatile uint32_t *)(a))
|
||||
|
||||
#define ALIGN(m) __attribute__((aligned(m)))
|
||||
#define PACKED __attribute__((packed))
|
||||
|
||||
#define ALINLINE __attribute__((always_inline))
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
|
||||
__attribute__((noreturn)) void generic_panic(void);
|
||||
__attribute__((noreturn)) void fatal_error(const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0x1A0;
|
||||
case CARDEVICE_I2C1: return 0x124;
|
||||
case CARDEVICE_I2C5: return 0x128;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0x42C;
|
||||
case CARDEVICE_HOST1X: return 0x180;
|
||||
case CARDEVICE_TSEC: return 0x1F4;
|
||||
@@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 6;
|
||||
case CARDEVICE_I2C5: return 6;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 4;
|
||||
case CARDEVICE_TSEC: return 0;
|
||||
@@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 0;
|
||||
case CARDEVICE_I2C5: return 0;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 3;
|
||||
case CARDEVICE_TSEC: return 2;
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef enum {
|
||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
||||
CARDEVICE_UNK = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||
|
||||
@@ -21,125 +21,66 @@
|
||||
#include "gpio.h"
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* Returns a GPIO bank object that corresponds to the given GPIO pin,
|
||||
* which can be created using the TEGRA_GPIO macro or passed from the name macro.
|
||||
*
|
||||
* @param pin The GPIO to get the bank for.
|
||||
* @return The GPIO bank object to use for working with the given bank.
|
||||
*/
|
||||
static volatile tegra_gpio_bank_t *gpio_get_bank(uint32_t pin)
|
||||
{
|
||||
static volatile tegra_gpio_bank_t *gpio_get_bank(uint32_t pin) {
|
||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
||||
uint32_t bank_number = pin >> GPIO_BANK_SHIFT;
|
||||
uint32_t bank_number = (pin >> GPIO_BANK_SHIFT);
|
||||
|
||||
return &gpio->bank[bank_number];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the port number for working with the given GPIO.
|
||||
*/
|
||||
static volatile uint32_t gpio_get_port(uint32_t pin)
|
||||
{
|
||||
return (pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK;
|
||||
static volatile uint32_t gpio_get_port(uint32_t pin) {
|
||||
return ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a mask to be used to work with the given GPIO
|
||||
*/
|
||||
static volatile uint32_t gpio_get_mask(uint32_t pin)
|
||||
{
|
||||
uint32_t pin_number = pin & GPIO_PIN_MASK;
|
||||
static volatile uint32_t gpio_get_mask(uint32_t pin) {
|
||||
uint32_t pin_number = (pin & GPIO_PIN_MASK);
|
||||
return (1 << pin_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple GPIO configuration operation.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param should_be_set True iff the relevant bit should be set; or false if it should be cleared.
|
||||
* @param offset The offset into a gpio_bank structure
|
||||
*/
|
||||
static void gpio_simple_register_set(uint32_t pin, bool should_be_set, uint32_t offset)
|
||||
{
|
||||
// Retrieve the register set that corresponds to the given pin and offset.
|
||||
static void gpio_simple_register_set(uint32_t pin, bool should_be_set, uint32_t offset) {
|
||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
||||
uintptr_t cluster_addr = (uintptr_t)gpio_get_bank(pin) + offset;
|
||||
uint32_t *cluster = (uint32_t *)cluster_addr;
|
||||
|
||||
// Figure out the offset into the cluster,
|
||||
// and the mask to be used.
|
||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
||||
uint32_t port = gpio_get_port(pin);
|
||||
uint32_t mask = gpio_get_mask(pin);
|
||||
|
||||
// Set or clear the bit, as appropriate.
|
||||
/* Set or clear the bit, as appropriate. */
|
||||
if (should_be_set)
|
||||
cluster[port] |= mask;
|
||||
cluster[port] |= mask;
|
||||
else
|
||||
cluster[port] &= ~mask;
|
||||
|
||||
/* Dummy read. */
|
||||
(void)cluster[port];
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple GPIO configuration operation.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param should_be_set True iff the relevant bit should be set; or false if it should be cleared.
|
||||
* @param offset The offset into a gpio_bank structure
|
||||
*/
|
||||
static bool gpio_simple_register_get(uint32_t pin, uint32_t offset)
|
||||
{
|
||||
// Retrieve the register set that corresponds to the given pin and offset.
|
||||
static bool gpio_simple_register_get(uint32_t pin, uint32_t offset) {
|
||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
||||
uintptr_t cluster_addr = (uintptr_t)gpio_get_bank(pin) + offset;
|
||||
uint32_t *cluster = (uint32_t *)cluster_addr;
|
||||
|
||||
// Figure out the offset into the cluster,
|
||||
// and the mask to be used.
|
||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
||||
uint32_t port = gpio_get_port(pin);
|
||||
uint32_t mask = gpio_get_mask(pin);
|
||||
|
||||
// Convert the given value to a boolean.
|
||||
/* Convert the given value to a boolean. */
|
||||
return !!(cluster[port] & mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a given pin as either GPIO or SFIO.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
void gpio_configure_mode(uint32_t pin, uint32_t mode)
|
||||
{
|
||||
void gpio_configure_mode(uint32_t pin, uint32_t mode) {
|
||||
gpio_simple_register_set(pin, mode == GPIO_MODE_GPIO, offsetof(tegra_gpio_bank_t, config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a given pin as either INPUT or OUPUT.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param direction The relevant direction.
|
||||
*/
|
||||
void gpio_configure_direction(uint32_t pin, uint32_t dir)
|
||||
{
|
||||
void gpio_configure_direction(uint32_t pin, uint32_t dir) {
|
||||
gpio_simple_register_set(pin, dir == GPIO_DIRECTION_OUTPUT, offsetof(tegra_gpio_bank_t, direction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives a relevant GPIO pin as either HIGH or LOW.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
void gpio_write(uint32_t pin, uint32_t value)
|
||||
{
|
||||
void gpio_write(uint32_t pin, uint32_t value) {
|
||||
gpio_simple_register_set(pin, value == GPIO_LEVEL_HIGH, offsetof(tegra_gpio_bank_t, out));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives a relevant GPIO pin as either HIGH or LOW.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
uint32_t gpio_read(uint32_t pin)
|
||||
{
|
||||
uint32_t gpio_read(uint32_t pin) {
|
||||
return gpio_simple_register_get(pin, offsetof(tegra_gpio_bank_t, in));
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ static inline volatile tegra_gpio_t *gpio_get_regs(void)
|
||||
((TEGRA_GPIO_PORT_##port * 8) + offset)
|
||||
|
||||
/* Mode select */
|
||||
#define GPIO_MODE_GPIO 0
|
||||
#define GPIO_MODE_SFIO 1
|
||||
#define GPIO_MODE_SFIO 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
|
||||
/* Direction */
|
||||
#define GPIO_DIRECTION_INPUT 0
|
||||
|
||||
@@ -75,14 +75,9 @@ void config_gpios()
|
||||
gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT);
|
||||
gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT);
|
||||
|
||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
||||
pinmux->uart1_rx = 0;
|
||||
pinmux->uart1_tx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart1_rts = 0;
|
||||
pinmux->uart1_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
i2c_config(I2C_1);
|
||||
i2c_config(I2C_5);
|
||||
uart_config(UART_A);
|
||||
|
||||
/* Configure volume up/down as inputs. */
|
||||
gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO);
|
||||
@@ -236,8 +231,8 @@ void nx_hwinit()
|
||||
/* NOTE: [4.0.0+] This was removed. */
|
||||
/* clkrst_reboot(CARDEVICE_SE); */
|
||||
|
||||
/* Reboot unknown device. */
|
||||
clkrst_reboot(CARDEVICE_UNK);
|
||||
/* Reboot TZRAM. */
|
||||
clkrst_reboot(CARDEVICE_TZRAM);
|
||||
|
||||
/* Initialize I2C1. */
|
||||
/* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */
|
||||
|
||||
@@ -17,19 +17,52 @@
|
||||
#include "i2c.h"
|
||||
#include "utils.h"
|
||||
#include "timers.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
/* Prototypes for internal commands. */
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id);
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
|
||||
void i2c_load_config(volatile tegra_i2c_t *regs);
|
||||
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
|
||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
|
||||
|
||||
/* Configure I2C pinmux. */
|
||||
void i2c_config(I2CDevice id) {
|
||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_2:
|
||||
pinmux->gen2_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen2_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_3:
|
||||
pinmux->gen3_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen3_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_4:
|
||||
pinmux->cam_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->cam_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_5:
|
||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_6:
|
||||
/* Unused. */
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize I2C based on registers. */
|
||||
void i2c_init(unsigned int id) {
|
||||
void i2c_init(I2CDevice id) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
|
||||
/* Setup divisor, and clear the bus. */
|
||||
@@ -91,7 +124,7 @@ void i2c_set_ti_charger_bit_7(void) {
|
||||
}
|
||||
|
||||
/* Get registers pointer based on I2C ID. */
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id) {
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
return I2C1_REGS;
|
||||
@@ -126,7 +159,7 @@ void i2c_load_config(volatile tegra_i2c_t *regs) {
|
||||
}
|
||||
|
||||
/* Reads a register from a device over I2C, writes result to output. */
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
uint32_t val = r;
|
||||
|
||||
@@ -143,7 +176,7 @@ bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst
|
||||
}
|
||||
|
||||
/* Writes a value to a register over I2C. */
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
uint32_t val = r;
|
||||
if (src_size == 0) {
|
||||
return true;
|
||||
|
||||
@@ -24,13 +24,6 @@
|
||||
#define I2C1234_BASE 0x7000C000
|
||||
#define I2C56_BASE 0x7000D000
|
||||
|
||||
#define I2C_1 0
|
||||
#define I2C_2 1
|
||||
#define I2C_3 2
|
||||
#define I2C_4 3
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
#define MAX17050_I2C_ADDR 0x36
|
||||
@@ -38,6 +31,15 @@
|
||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
typedef enum {
|
||||
I2C_1 = 0,
|
||||
I2C_2 = 1,
|
||||
I2C_3 = 2,
|
||||
I2C_4 = 3,
|
||||
I2C_5 = 4,
|
||||
I2C_6 = 5,
|
||||
} I2CDevice;
|
||||
|
||||
typedef struct {
|
||||
uint32_t I2C_I2C_CNFG_0;
|
||||
uint32_t I2C_I2C_CMD_ADDR0_0;
|
||||
@@ -89,9 +91,11 @@ typedef struct {
|
||||
#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
|
||||
#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
|
||||
|
||||
void i2c_init(unsigned int id);
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
void i2c_config(I2CDevice id);
|
||||
|
||||
void i2c_init(I2CDevice id);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
void i2c_send_pmic_cpu_shutdown_cmd(void);
|
||||
bool i2c_query_ti_charger_bit_7(void);
|
||||
|
||||
@@ -1,324 +1,330 @@
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.13 (May 21, 2017)
|
||||
|
||||
Changed heading character of configuration keywords "_" to "FF_".
|
||||
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.13 (May 21, 2017)
|
||||
|
||||
Changed heading character of configuration keywords "_" to "FF_".
|
||||
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||
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,22 +1,21 @@
|
||||
FatFs Module Source Files R0.13b
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related 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 it does not depend on any specific
|
||||
storage device. You need to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
||||
FatFs Module Source Files R0.13c
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related 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 it does not depend on any specific
|
||||
storage device. You need to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
||||
|
||||
@@ -1,95 +1,100 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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 <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "../../fs_utils.h"
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case 0:
|
||||
return sdmmc_device_read(&g_sd_device, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case 0:
|
||||
return sdmmc_device_write(&g_sd_device, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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 <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "ff.h" /* Obtains integer types */
|
||||
#include "diskio.h" /* Declarations of disk functions */
|
||||
#include "../../fs_utils.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case 0:
|
||||
return sdmmc_device_read(&g_sd_device, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if FF_FS_READONLY == 0
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case 0:
|
||||
return sdmmc_device_write(&g_sd_device, sector, count, (void *)buff) ? RES_OK : RES_ERROR;
|
||||
default:
|
||||
return RES_PARERR;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,80 +1,77 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ 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 */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,376 +1,405 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13b /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ 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
|
||||
/ 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 FF_DEFINED
|
||||
#define FF_DEFINED 63463 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#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 */
|
||||
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:N/A) */
|
||||
BYTE pdrv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_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[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
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) */
|
||||
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
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID 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 fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* 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 > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#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 (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 */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_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 /* FF_DEFINED */
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ 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
|
||||
/ 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 FF_DEFINED
|
||||
#define FF_DEFINED 86604 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#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 */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#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 */
|
||||
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
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) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_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 */
|
||||
#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;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
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: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
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID 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 fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* 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 > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#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 (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 */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_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 /* FF_DEFINED */
|
||||
|
||||
@@ -1,289 +1,288 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - Configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 63463 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 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.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 1
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, 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() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#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(),
|
||||
/ 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 in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "sdmc"
|
||||
/* 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
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled.
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* 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. 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,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 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.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 1
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, 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() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#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(),
|
||||
/ 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 in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "sdmc"
|
||||
/* 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
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ 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 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* 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. 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,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
||||
@@ -1,171 +1,170 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C)ChaN, 2017 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#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) */
|
||||
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 (nothing to do for null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */
|
||||
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(Mutex + vol);
|
||||
// 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. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 if not enough core) */
|
||||
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 (nothing to do if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//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 */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
||||
// 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. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef FF_INTEGER
|
||||
#define FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -508,7 +508,7 @@ char *uuid_string(char *buf, char *end, const uint8_t *addr,
|
||||
if (uc) {
|
||||
p = uuid;
|
||||
do {
|
||||
*p = toupper(*p);
|
||||
*p = toupper((unsigned char)*p);
|
||||
} while (*(++p));
|
||||
}
|
||||
|
||||
@@ -1177,7 +1177,7 @@ do { \
|
||||
case FORMAT_TYPE_PTR:
|
||||
save_arg(void *);
|
||||
/* skip all alphanumeric pointer suffixes */
|
||||
while (isalnum(*fmt))
|
||||
while (isalnum((unsigned char)*fmt))
|
||||
fmt++;
|
||||
break;
|
||||
|
||||
@@ -1340,7 +1340,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const uint32_t *bin_buf
|
||||
|
||||
case FORMAT_TYPE_PTR:
|
||||
str = pointer(fmt+1, str, end, get_arg(void *), spec);
|
||||
while (isalnum(*fmt))
|
||||
while (isalnum((unsigned char)*fmt))
|
||||
fmt++;
|
||||
break;
|
||||
|
||||
@@ -1577,10 +1577,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
|
||||
digit = *(str + 1);
|
||||
|
||||
if (!digit
|
||||
|| (base == 16 && !isxdigit(digit))
|
||||
|| (base == 10 && !isdigit(digit))
|
||||
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|
||||
|| (base == 0 && !isdigit(digit)))
|
||||
|| (base == 16 && !isxdigit((unsigned char)digit))
|
||||
|| (base == 10 && !isdigit((unsigned char)digit))
|
||||
|| (base == 8 && (!isdigit((unsigned char)digit) || digit > '7'))
|
||||
|| (base == 0 && !isdigit((unsigned char)digit)))
|
||||
break;
|
||||
|
||||
switch (qualifier) {
|
||||
|
||||
@@ -41,6 +41,7 @@ static char g_bct0_buffer[BCTO_MAX_SIZE];
|
||||
"BCT0\n"\
|
||||
"[stage1]\n"\
|
||||
"stage2_path = atmosphere/fusee-secondary.bin\n"\
|
||||
"stage2_mtc_path = atmosphere/fusee-mtc.bin\n"\
|
||||
"stage2_addr = 0xF0000000\n"\
|
||||
"stage2_entrypoint = 0xF0000000\n"
|
||||
|
||||
@@ -84,12 +85,9 @@ static int config_ini_handler(void *user, const char *section, const char *name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void setup_env(void) {
|
||||
static void setup_display(void) {
|
||||
g_framebuffer = (void *)0xC0000000;
|
||||
|
||||
/* Initialize hardware. */
|
||||
nx_hwinit();
|
||||
|
||||
|
||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||
video_init(g_framebuffer);
|
||||
|
||||
@@ -102,6 +100,19 @@ static void setup_env(void) {
|
||||
/* Turn on the backlight after initializing the lfb */
|
||||
/* to avoid flickering. */
|
||||
display_backlight(true);
|
||||
}
|
||||
|
||||
static void cleanup_display(void) {
|
||||
/* Turn off the backlight. */
|
||||
display_backlight(false);
|
||||
|
||||
/* Terminate the display. */
|
||||
display_end();
|
||||
}
|
||||
|
||||
static void setup_env(void) {
|
||||
/* Initialize hardware. */
|
||||
nx_hwinit();
|
||||
|
||||
/* Set up the exception handlers. */
|
||||
setup_exception_handlers();
|
||||
@@ -113,9 +124,6 @@ static void setup_env(void) {
|
||||
static void cleanup_env(void) {
|
||||
/* Unmount the SD card. */
|
||||
unmount_sd();
|
||||
|
||||
display_backlight(false);
|
||||
display_end();
|
||||
}
|
||||
|
||||
static void exit_callback(int rc) {
|
||||
@@ -128,12 +136,9 @@ int main(void) {
|
||||
const char *stage2_path;
|
||||
stage2_args_t *stage2_args;
|
||||
uint32_t stage2_version = 0;
|
||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_MANDATORY;
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(log_level);
|
||||
|
||||
/* Initialize the display, console, etc. */
|
||||
ScreenLogLevel log_level = SCREEN_LOG_LEVEL_NONE;
|
||||
|
||||
/* Initialize the boot environment. */
|
||||
setup_env();
|
||||
|
||||
/* Check for panics. */
|
||||
@@ -147,8 +152,16 @@ int main(void) {
|
||||
fatal_error("Failed to parse BCT.ini!\n");
|
||||
}
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(log_level);
|
||||
|
||||
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Initialize the display for debugging. */
|
||||
setup_display();
|
||||
}
|
||||
|
||||
/* Say hello. */
|
||||
print(SCREEN_LOG_LEVEL_MANDATORY, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer);
|
||||
|
||||
/* Load the loader payload into DRAM. */
|
||||
@@ -160,15 +173,19 @@ int main(void) {
|
||||
stage2_args = (stage2_args_t *)(g_chainloader_arg_data + strlen(stage2_path) + 1); /* May be unaligned. */
|
||||
memcpy(&stage2_args->version, &stage2_version, 4);
|
||||
memcpy(&stage2_args->log_level, &log_level, sizeof(log_level));
|
||||
stage2_args->display_initialized = false;
|
||||
strcpy(stage2_args->bct0, bct0);
|
||||
g_chainloader_argc = 2;
|
||||
|
||||
/* Wait a while. */
|
||||
mdelay(1000);
|
||||
|
||||
/* Deinitialize the display, console, etc. */
|
||||
/* Terminate the boot environment. */
|
||||
cleanup_env();
|
||||
|
||||
if (log_level != SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Wait a while for debugging. */
|
||||
mdelay(1000);
|
||||
|
||||
/* Terminate the display for debugging. */
|
||||
cleanup_display();
|
||||
}
|
||||
|
||||
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, jump to Stage2. */
|
||||
__program_exit_callback = exit_callback;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "utils.h"
|
||||
#include "fs_utils.h"
|
||||
#include "lib/log.h"
|
||||
#include "display/video_fb.h"
|
||||
|
||||
static uint32_t g_panic_code = 0;
|
||||
|
||||
@@ -56,6 +57,22 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
||||
}
|
||||
|
||||
{
|
||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||
video_init((void *)0xC0000000);
|
||||
|
||||
/* Initialize the display. */
|
||||
display_init();
|
||||
|
||||
/* Set the framebuffer. */
|
||||
display_init_framebuffer((void *)0xC0000000);
|
||||
|
||||
/* Turn on the backlight after initializing the lfb */
|
||||
/* to avoid flickering. */
|
||||
display_backlight(true);
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
|
||||
|
||||
/* Copy fatal error context to the stack. */
|
||||
atmosphere_fatal_error_ctx ctx = *(ATMOSPHERE_FATAL_ERROR_CONTEXT);
|
||||
|
||||
@@ -79,6 +96,7 @@ static void _check_and_display_atmosphere_fatal_error(void) {
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
|
||||
}
|
||||
|
||||
/* Wait for button and reboot. */
|
||||
wait_for_button_and_reboot();
|
||||
}
|
||||
|
||||
@@ -87,11 +105,9 @@ void check_and_display_panic(void) {
|
||||
_check_and_display_atmosphere_fatal_error();
|
||||
|
||||
/* We also handle our own panics. */
|
||||
/* In the case of our own panics, we assume that the display has already been initialized. */
|
||||
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
||||
uint32_t code = g_panic_code == 0 ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
|
||||
|
||||
has_panic = has_panic && !(APBDEV_PMC_RST_STATUS_0 != 1 && code == PANIC_CODE_SAFEMODE);
|
||||
bool has_panic = ((APBDEV_PMC_RST_STATUS_0 != 0) || (g_panic_code != 0));
|
||||
uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
|
||||
has_panic = has_panic && !((APBDEV_PMC_RST_STATUS_0 != 1) && (code == PANIC_CODE_SAFEMODE));
|
||||
|
||||
if (has_panic) {
|
||||
uint32_t color;
|
||||
@@ -134,11 +150,13 @@ void check_and_display_panic(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_panic_code == 0) {
|
||||
display_init();
|
||||
}
|
||||
|
||||
/* Initialize the display. */
|
||||
display_init();
|
||||
|
||||
/* Fill the screen. */
|
||||
display_color_screen(color);
|
||||
|
||||
/* Wait for button and reboot. */
|
||||
wait_for_button_and_reboot();
|
||||
} else {
|
||||
g_panic_code = 0;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#define PANIC_CODE_SAFEMODE 0x00000020
|
||||
|
||||
|
||||
#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20
|
||||
#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ static int stage2_ini_handler(void *user, const char *section, const char *name,
|
||||
if (strcmp(name, STAGE2_NAME_KEY) == 0) {
|
||||
strncpy(config->path, value, sizeof(config->path) - 1);
|
||||
config->path[sizeof(config->path) - 1] = '\0';
|
||||
} else if (strcmp(name, STAGE2_MTC_NAME_KEY) == 0) {
|
||||
strncpy(config->mtc_path, value, sizeof(config->mtc_path) - 1);
|
||||
config->mtc_path[sizeof(config->mtc_path) - 1] = '\0';
|
||||
} else if (strcmp(name, STAGE2_ADDRESS_KEY) == 0) {
|
||||
/* Read in load address as a hex string. */
|
||||
sscanf(value, "%x", &x);
|
||||
@@ -52,6 +55,42 @@ static int stage2_ini_handler(void *user, const char *section, const char *name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool run_mtc(const char *mtc_path, uintptr_t mtc_address) {
|
||||
FILINFO info;
|
||||
size_t size;
|
||||
|
||||
/* Check if the MTC binary is present. */
|
||||
if (f_stat(mtc_path, &info) != FR_OK) {
|
||||
print(SCREEN_LOG_LEVEL_WARNING, "Stage2's MTC binary not found!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
size = (size_t)info.fsize;
|
||||
|
||||
/* Try to read the MTC binary. */
|
||||
if (read_from_file((void *)mtc_address, size, mtc_path) != size) {
|
||||
print(SCREEN_LOG_LEVEL_WARNING, "Failed to read stage2's MTC binary (%s)!\n", mtc_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
ScreenLogLevel mtc_log_level = log_get_log_level();
|
||||
bool mtc_res = false;
|
||||
int mtc_argc = 1;
|
||||
char mtc_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0};
|
||||
stage2_mtc_args_t *mtc_args = (stage2_mtc_args_t *)mtc_arg_data;
|
||||
|
||||
/* Setup argument data. */
|
||||
memcpy(&mtc_args->log_level, &mtc_log_level, sizeof(mtc_log_level));
|
||||
|
||||
/* Run the MTC binary. */
|
||||
mtc_res = (((int (*)(int, void *))mtc_address)(mtc_argc, mtc_arg_data) == 0);
|
||||
|
||||
/* Cleanup right away. */
|
||||
memset((void *)mtc_address, 0, size);
|
||||
|
||||
return mtc_res;
|
||||
}
|
||||
|
||||
void load_stage2(const char *bct0) {
|
||||
stage2_config_t config = {0};
|
||||
FILINFO info;
|
||||
@@ -77,12 +116,18 @@ void load_stage2(const char *bct0) {
|
||||
if (!check_32bit_address_loadable(config.load_address)) {
|
||||
fatal_error("Stage2's load address is invalid!\n");
|
||||
}
|
||||
|
||||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 Config:\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " File Path: %s\n", config.path);
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " MTC File Path: %s\n", config.mtc_path);
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Load Address: 0x%08x\n", config.load_address);
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Entrypoint: 0x%p\n", config.entrypoint);
|
||||
|
||||
/* Run the MTC binary. */
|
||||
if (!run_mtc(config.mtc_path, config.load_address)) {
|
||||
print(SCREEN_LOG_LEVEL_WARNING, "DRAM training failed! Continuing with untrained DRAM.\n");
|
||||
}
|
||||
|
||||
if (f_stat(config.path, &info) != FR_OK) {
|
||||
fatal_error("Failed to stat stage2 (%s)!\n", config.path);
|
||||
}
|
||||
@@ -108,6 +153,7 @@ void load_stage2(const char *bct0) {
|
||||
tmp_addr = config.load_address;
|
||||
}
|
||||
|
||||
/* Try to read stage2. */
|
||||
if (read_from_file((void *)tmp_addr, size, config.path) != size) {
|
||||
fatal_error("Failed to read stage2 (%s)!\n", config.path);
|
||||
}
|
||||
|
||||
@@ -32,12 +32,15 @@
|
||||
#define STAGE2_ARGC 2
|
||||
|
||||
#define STAGE2_NAME_KEY "stage2_path"
|
||||
#define STAGE2_MTC_NAME_KEY "stage2_mtc_path"
|
||||
#define STAGE2_ADDRESS_KEY "stage2_addr"
|
||||
#define STAGE2_ENTRYPOINT_KEY "stage2_entrypoint"
|
||||
|
||||
#define BCTO_MAX_SIZE 0x5800
|
||||
|
||||
typedef struct {
|
||||
char path[0x100];
|
||||
char mtc_path[0x100];
|
||||
uintptr_t load_address;
|
||||
uintptr_t entrypoint;
|
||||
} stage2_config_t;
|
||||
@@ -45,10 +48,13 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
ScreenLogLevel log_level;
|
||||
bool display_initialized;
|
||||
char bct0[BCTO_MAX_SIZE];
|
||||
} stage2_args_t;
|
||||
|
||||
typedef struct {
|
||||
ScreenLogLevel log_level;
|
||||
} stage2_mtc_args_t;
|
||||
|
||||
const char *stage2_get_program_path(void);
|
||||
void load_stage2(const char *bct0);
|
||||
|
||||
|
||||
@@ -17,35 +17,98 @@
|
||||
|
||||
#include "uart.h"
|
||||
#include "timers.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
static inline void uart_wait_cycles(uint32_t baud, uint32_t num)
|
||||
{
|
||||
udelay((num * 1000000 + 16 * baud - 1) / (16 * baud));
|
||||
}
|
||||
|
||||
static inline void uart_wait_syms(uint32_t baud, uint32_t num)
|
||||
{
|
||||
udelay((num * 1000000 + baud - 1) / baud);
|
||||
}
|
||||
|
||||
void uart_config(UartDevice dev) {
|
||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||
|
||||
switch (dev) {
|
||||
case UART_A:
|
||||
pinmux->uart1_tx = 0;
|
||||
pinmux->uart1_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart1_rts = 0;
|
||||
pinmux->uart1_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_B:
|
||||
pinmux->uart2_tx = 0;
|
||||
pinmux->uart2_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart2_rts = 0;
|
||||
pinmux->uart2_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_C:
|
||||
pinmux->uart3_tx = 0;
|
||||
pinmux->uart3_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart3_rts = 0;
|
||||
pinmux->uart3_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_D:
|
||||
pinmux->uart4_tx = 0;
|
||||
pinmux->uart4_rx = (PINMUX_INPUT | PINMUX_PULL_UP);
|
||||
pinmux->uart4_rts = 0;
|
||||
pinmux->uart4_cts = (PINMUX_INPUT | PINMUX_PULL_DOWN);
|
||||
break;
|
||||
case UART_E:
|
||||
/* Unused. */
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_init(UartDevice dev, uint32_t baud) {
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
/* Set baud rate. */
|
||||
uint32_t rate = (8 * baud + 408000000) / (16 * baud);
|
||||
uart->UART_LCR = UART_LCR_DLAB; /* Enable DLAB. */
|
||||
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
|
||||
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
|
||||
uart->UART_LCR = 0; /* Diable DLAB. */
|
||||
/* Wait for idle state. */
|
||||
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE);
|
||||
|
||||
/* Setup UART in fifo mode. */
|
||||
/* Calculate baud rate, round to nearest. */
|
||||
uint32_t rate = (8 * baud + 408000000) / (16 * baud);
|
||||
|
||||
/* Setup UART in FIFO mode. */
|
||||
uart->UART_IER_DLAB = 0;
|
||||
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO | UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Enable and clear TX and RX FIFOs. */
|
||||
(void)uart->UART_LSR;
|
||||
udelay(3 * ((baud + 999999) / baud));
|
||||
uart->UART_LCR = UART_LCR_WD_LENGTH_8; /* Set word length 8. */
|
||||
uart->UART_MCR = 0;
|
||||
uart->UART_MSR = 0;
|
||||
uart->UART_IRDA_CSR = 0;
|
||||
uart->UART_RX_FIFO_CFG = 1; /* Set RX_FIFO trigger level */
|
||||
uart->UART_MIE = 0;
|
||||
uart->UART_ASR = 0;
|
||||
uart->UART_LCR = (UART_LCR_DLAB | UART_LCR_WD_LENGTH_8); /* Enable DLAB and set word length 8. */
|
||||
uart->UART_THR_DLAB = (uint8_t)rate; /* Divisor latch LSB. */
|
||||
uart->UART_IER_DLAB = (uint8_t)(rate >> 8); /* Divisor latch MSB. */
|
||||
uart->UART_LCR &= ~(UART_LCR_DLAB); /* Disable DLAB. */
|
||||
uart->UART_SPR; /* Dummy read. */
|
||||
uart_wait_syms(baud, 3); /* Wait for 3 symbols at the new baudrate. */
|
||||
|
||||
/* Enable FIFO with default settings. */
|
||||
uart->UART_IIR_FCR = UART_FCR_FCR_EN_FIFO;
|
||||
uart->UART_SPR; /* Dummy read as mandated by TRM. */
|
||||
uart_wait_cycles(baud, 3); /* Wait for 3 baud cycles, as mandated by TRM (erratum). */
|
||||
|
||||
/* Flush FIFO. */
|
||||
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE); /* Make sure there's no data being written in TX FIFO (TRM). */
|
||||
uart->UART_IIR_FCR |= UART_FCR_RX_CLR | UART_FCR_TX_CLR; /* Clear TX and RX FIFOs. */
|
||||
uart_wait_cycles(baud, 32); /* Wait for 32 baud cycles (TRM, erratum). */
|
||||
/* Wait for idle state (TRM). */
|
||||
uart_wait_idle(dev, UART_VENDOR_STATE_TX_IDLE | UART_VENDOR_STATE_RX_IDLE);
|
||||
}
|
||||
|
||||
/* This function blocks until the UART device (dev) is in the desired state (status). Make sure the desired state can be reached! */
|
||||
/* This function blocks until the UART device is in the desired state. */
|
||||
void uart_wait_idle(UartDevice dev, UartVendorStatus status) {
|
||||
while (!(uart_get_regs(dev)->UART_VENDOR_STATUS & status)) {
|
||||
/* Wait */
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
if (status & UART_VENDOR_STATE_TX_IDLE) {
|
||||
while (!(uart->UART_LSR & UART_LSR_TMTY)) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
if (status & UART_VENDOR_STATE_RX_IDLE) {
|
||||
while (uart->UART_LSR & UART_LSR_RDR) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +116,8 @@ void uart_send(UartDevice dev, const void *buf, size_t len) {
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (uart->UART_LSR & UART_LSR_TX_FIFO_FULL) {
|
||||
/* Wait until the TX FIFO isn't full */
|
||||
while (!(uart->UART_LSR & UART_LSR_THRE)) {
|
||||
/* Wait until it's possible to send data. */
|
||||
}
|
||||
uart->UART_THR_DLAB = *((const uint8_t *)buf + i);
|
||||
}
|
||||
@@ -64,8 +127,8 @@ void uart_recv(UartDevice dev, void *buf, size_t len) {
|
||||
volatile tegra_uart_t *uart = uart_get_regs(dev);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (uart->UART_LSR & UART_LSR_RX_FIFO_EMPTY) {
|
||||
/* Wait until the RX FIFO isn't empty */
|
||||
while (!(uart->UART_LSR & UART_LSR_RDR)) {
|
||||
/* Wait until it's possible to receive data. */
|
||||
}
|
||||
*((uint8_t *)buf + i) = uart->UART_THR_DLAB;
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ typedef struct {
|
||||
uint32_t UART_ASR;
|
||||
} tegra_uart_t;
|
||||
|
||||
void uart_config(UartDevice dev);
|
||||
void uart_init(UartDevice dev, uint32_t baud);
|
||||
void uart_wait_idle(UartDevice dev, UartVendorStatus status);
|
||||
void uart_send(UartDevice dev, const void *buf, size_t len);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include "utils.h"
|
||||
#include "di.h"
|
||||
#include "se.h"
|
||||
#include "fuse.h"
|
||||
#include "pmc.h"
|
||||
@@ -24,8 +25,8 @@
|
||||
#include "panic.h"
|
||||
#include "car.h"
|
||||
#include "btn.h"
|
||||
|
||||
#include "lib/log.h"
|
||||
#include "display/video_fb.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -97,12 +98,34 @@ __attribute__ ((noreturn)) void generic_panic(void) {
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void fatal_error(const char *fmt, ...) {
|
||||
/* Forcefully initialize the screen if logging is disabled. */
|
||||
if (log_get_log_level() == SCREEN_LOG_LEVEL_NONE) {
|
||||
/* Zero-fill the framebuffer and register it as printk provider. */
|
||||
video_init((void *)0xC0000000);
|
||||
|
||||
/* Initialize the display. */
|
||||
display_init();
|
||||
|
||||
/* Set the framebuffer. */
|
||||
display_init_framebuffer((void *)0xC0000000);
|
||||
|
||||
/* Turn on the backlight after initializing the lfb */
|
||||
/* to avoid flickering. */
|
||||
display_backlight(true);
|
||||
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(SCREEN_LOG_LEVEL_ERROR);
|
||||
}
|
||||
|
||||
/* Display fatal error. */
|
||||
va_list args;
|
||||
print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: ");
|
||||
va_start(args, fmt);
|
||||
vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args);
|
||||
va_end(args);
|
||||
print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n");
|
||||
|
||||
/* Wait for button and reboot. */
|
||||
wait_for_button_and_reboot();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0x1A0;
|
||||
case CARDEVICE_I2C1: return 0x124;
|
||||
case CARDEVICE_I2C5: return 0x128;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0x42C;
|
||||
case CARDEVICE_HOST1X: return 0x180;
|
||||
case CARDEVICE_TSEC: return 0x1F4;
|
||||
@@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 6;
|
||||
case CARDEVICE_I2C5: return 6;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 4;
|
||||
case CARDEVICE_TSEC: return 0;
|
||||
@@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 0;
|
||||
case CARDEVICE_I2C5: return 0;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 3;
|
||||
case CARDEVICE_TSEC: return 2;
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef enum {
|
||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
||||
CARDEVICE_UNK = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||
|
||||
@@ -97,26 +97,23 @@ static ssize_t decode_utf8(uint32_t *out, const uint8_t *in) {
|
||||
}
|
||||
|
||||
static void console_init_display(void) {
|
||||
if (!g_display_initialized) {
|
||||
/* Initialize the display. */
|
||||
display_init();
|
||||
}
|
||||
/* Initialize the display. */
|
||||
display_init();
|
||||
|
||||
/* Set the framebuffer. */
|
||||
display_init_framebuffer(g_framebuffer);
|
||||
|
||||
/* Turn on the backlight after initializing the lfb */
|
||||
/* to avoid flickering. */
|
||||
if (!g_display_initialized) {
|
||||
display_backlight(true);
|
||||
}
|
||||
display_backlight(true);
|
||||
|
||||
/* Display is initialized. */
|
||||
g_display_initialized = true;
|
||||
}
|
||||
|
||||
static ssize_t console_write(struct _reent *r, void *fd, const char *ptr, size_t len) {
|
||||
size_t i = 0;
|
||||
if (!g_display_initialized) {
|
||||
if (!g_display_initialized && (g_framebuffer != NULL)) {
|
||||
console_init_display();
|
||||
}
|
||||
while (i < len) {
|
||||
@@ -138,6 +135,8 @@ static int console_create(void) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate memory for the framebuffer. */
|
||||
g_framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE);
|
||||
|
||||
if (g_framebuffer == NULL) {
|
||||
@@ -154,9 +153,7 @@ static int console_create(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int console_init(bool display_initialized) {
|
||||
g_display_initialized = display_initialized;
|
||||
|
||||
int console_init(void) {
|
||||
if (console_create() == -1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -171,15 +168,15 @@ int console_init(bool display_initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *console_get_framebuffer(bool enable_display) {
|
||||
if (g_framebuffer != NULL && enable_display) {
|
||||
void *console_get_framebuffer(void) {
|
||||
if (!g_display_initialized && (g_framebuffer != NULL)) {
|
||||
console_init_display();
|
||||
}
|
||||
return g_framebuffer;
|
||||
}
|
||||
|
||||
int console_display(const void *framebuffer) {
|
||||
if (!g_display_initialized) {
|
||||
if (!g_display_initialized && (g_framebuffer != NULL)) {
|
||||
console_init_display();
|
||||
}
|
||||
display_init_framebuffer((void *)framebuffer);
|
||||
@@ -187,7 +184,7 @@ int console_display(const void *framebuffer) {
|
||||
}
|
||||
|
||||
int console_resume(void) {
|
||||
if (!g_display_initialized) {
|
||||
if (!g_display_initialized && (g_framebuffer != NULL)) {
|
||||
console_init_display();
|
||||
} else {
|
||||
display_init_framebuffer(g_framebuffer);
|
||||
@@ -196,10 +193,15 @@ int console_resume(void) {
|
||||
}
|
||||
|
||||
int console_end(void) {
|
||||
/* Deinitialize the framebuffer and display */
|
||||
if (g_display_initialized) {
|
||||
if (g_display_initialized) {
|
||||
/* Turn off the backlight. */
|
||||
display_backlight(false);
|
||||
|
||||
/* Terminate the display. */
|
||||
display_end();
|
||||
|
||||
/* Display is terminated. */
|
||||
g_display_initialized = false;
|
||||
}
|
||||
free(g_framebuffer);
|
||||
g_framebuffer = NULL;
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include <malloc.h>
|
||||
#include <sys/iosupport.h>
|
||||
|
||||
int console_init(bool display_initialized);
|
||||
void *console_get_framebuffer(bool enable_display);
|
||||
int console_init(void);
|
||||
void *console_get_framebuffer(void);
|
||||
int console_display(const void *framebuffer); /* Must be page-aligned */
|
||||
int console_resume(void);
|
||||
int console_end(void);
|
||||
|
||||
@@ -21,125 +21,66 @@
|
||||
#include "gpio.h"
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* Returns a GPIO bank object that corresponds to the given GPIO pin,
|
||||
* which can be created using the TEGRA_GPIO macro or passed from the name macro.
|
||||
*
|
||||
* @param pin The GPIO to get the bank for.
|
||||
* @return The GPIO bank object to use for working with the given bank.
|
||||
*/
|
||||
static volatile tegra_gpio_bank_t *gpio_get_bank(uint32_t pin)
|
||||
{
|
||||
static volatile tegra_gpio_bank_t *gpio_get_bank(uint32_t pin) {
|
||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
||||
uint32_t bank_number = pin >> GPIO_BANK_SHIFT;
|
||||
uint32_t bank_number = (pin >> GPIO_BANK_SHIFT);
|
||||
|
||||
return &gpio->bank[bank_number];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the port number for working with the given GPIO.
|
||||
*/
|
||||
static volatile uint32_t gpio_get_port(uint32_t pin)
|
||||
{
|
||||
return (pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK;
|
||||
static volatile uint32_t gpio_get_port(uint32_t pin) {
|
||||
return ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a mask to be used to work with the given GPIO
|
||||
*/
|
||||
static volatile uint32_t gpio_get_mask(uint32_t pin)
|
||||
{
|
||||
uint32_t pin_number = pin & GPIO_PIN_MASK;
|
||||
static volatile uint32_t gpio_get_mask(uint32_t pin) {
|
||||
uint32_t pin_number = (pin & GPIO_PIN_MASK);
|
||||
return (1 << pin_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple GPIO configuration operation.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param should_be_set True iff the relevant bit should be set; or false if it should be cleared.
|
||||
* @param offset The offset into a gpio_bank structure
|
||||
*/
|
||||
static void gpio_simple_register_set(uint32_t pin, bool should_be_set, uint32_t offset)
|
||||
{
|
||||
// Retrieve the register set that corresponds to the given pin and offset.
|
||||
static void gpio_simple_register_set(uint32_t pin, bool should_be_set, uint32_t offset) {
|
||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
||||
uintptr_t cluster_addr = (uintptr_t)gpio_get_bank(pin) + offset;
|
||||
uint32_t *cluster = (uint32_t *)cluster_addr;
|
||||
|
||||
// Figure out the offset into the cluster,
|
||||
// and the mask to be used.
|
||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
||||
uint32_t port = gpio_get_port(pin);
|
||||
uint32_t mask = gpio_get_mask(pin);
|
||||
|
||||
// Set or clear the bit, as appropriate.
|
||||
/* Set or clear the bit, as appropriate. */
|
||||
if (should_be_set)
|
||||
cluster[port] |= mask;
|
||||
cluster[port] |= mask;
|
||||
else
|
||||
cluster[port] &= ~mask;
|
||||
|
||||
/* Dummy read. */
|
||||
(void)cluster[port];
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple GPIO configuration operation.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param should_be_set True iff the relevant bit should be set; or false if it should be cleared.
|
||||
* @param offset The offset into a gpio_bank structure
|
||||
*/
|
||||
static bool gpio_simple_register_get(uint32_t pin, uint32_t offset)
|
||||
{
|
||||
// Retrieve the register set that corresponds to the given pin and offset.
|
||||
static bool gpio_simple_register_get(uint32_t pin, uint32_t offset) {
|
||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
||||
uintptr_t cluster_addr = (uintptr_t)gpio_get_bank(pin) + offset;
|
||||
uint32_t *cluster = (uint32_t *)cluster_addr;
|
||||
|
||||
// Figure out the offset into the cluster,
|
||||
// and the mask to be used.
|
||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
||||
uint32_t port = gpio_get_port(pin);
|
||||
uint32_t mask = gpio_get_mask(pin);
|
||||
|
||||
// Convert the given value to a boolean.
|
||||
/* Convert the given value to a boolean. */
|
||||
return !!(cluster[port] & mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a given pin as either GPIO or SFIO.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
void gpio_configure_mode(uint32_t pin, uint32_t mode)
|
||||
{
|
||||
void gpio_configure_mode(uint32_t pin, uint32_t mode) {
|
||||
gpio_simple_register_set(pin, mode == GPIO_MODE_GPIO, offsetof(tegra_gpio_bank_t, config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a given pin as either INPUT or OUPUT.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param direction The relevant direction.
|
||||
*/
|
||||
void gpio_configure_direction(uint32_t pin, uint32_t dir)
|
||||
{
|
||||
void gpio_configure_direction(uint32_t pin, uint32_t dir) {
|
||||
gpio_simple_register_set(pin, dir == GPIO_DIRECTION_OUTPUT, offsetof(tegra_gpio_bank_t, direction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives a relevant GPIO pin as either HIGH or LOW.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
void gpio_write(uint32_t pin, uint32_t value)
|
||||
{
|
||||
void gpio_write(uint32_t pin, uint32_t value) {
|
||||
gpio_simple_register_set(pin, value == GPIO_LEVEL_HIGH, offsetof(tegra_gpio_bank_t, out));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives a relevant GPIO pin as either HIGH or LOW.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
uint32_t gpio_read(uint32_t pin)
|
||||
{
|
||||
uint32_t gpio_read(uint32_t pin) {
|
||||
return gpio_simple_register_get(pin, offsetof(tegra_gpio_bank_t, in));
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ static inline volatile tegra_gpio_t *gpio_get_regs(void)
|
||||
((TEGRA_GPIO_PORT_##port * 8) + offset)
|
||||
|
||||
/* Mode select */
|
||||
#define GPIO_MODE_GPIO 0
|
||||
#define GPIO_MODE_SFIO 1
|
||||
#define GPIO_MODE_SFIO 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
|
||||
/* Direction */
|
||||
#define GPIO_DIRECTION_INPUT 0
|
||||
|
||||
@@ -17,19 +17,52 @@
|
||||
#include "i2c.h"
|
||||
#include "utils.h"
|
||||
#include "timers.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
/* Prototypes for internal commands. */
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id);
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
|
||||
void i2c_load_config(volatile tegra_i2c_t *regs);
|
||||
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
|
||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
|
||||
|
||||
/* Configure I2C pinmux. */
|
||||
void i2c_config(I2CDevice id) {
|
||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_2:
|
||||
pinmux->gen2_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen2_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_3:
|
||||
pinmux->gen3_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen3_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_4:
|
||||
pinmux->cam_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->cam_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_5:
|
||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_6:
|
||||
/* Unused. */
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize I2C based on registers. */
|
||||
void i2c_init(unsigned int id) {
|
||||
void i2c_init(I2CDevice id) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
|
||||
/* Setup divisor, and clear the bus. */
|
||||
@@ -91,7 +124,7 @@ void i2c_set_ti_charger_bit_7(void) {
|
||||
}
|
||||
|
||||
/* Get registers pointer based on I2C ID. */
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id) {
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
return I2C1_REGS;
|
||||
@@ -126,7 +159,7 @@ void i2c_load_config(volatile tegra_i2c_t *regs) {
|
||||
}
|
||||
|
||||
/* Reads a register from a device over I2C, writes result to output. */
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
uint32_t val = r;
|
||||
|
||||
@@ -143,7 +176,7 @@ bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst
|
||||
}
|
||||
|
||||
/* Writes a value to a register over I2C. */
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
uint32_t val = r;
|
||||
if (src_size == 0) {
|
||||
return true;
|
||||
|
||||
@@ -24,13 +24,6 @@
|
||||
#define I2C1234_BASE 0x7000C000
|
||||
#define I2C56_BASE 0x7000D000
|
||||
|
||||
#define I2C_1 0
|
||||
#define I2C_2 1
|
||||
#define I2C_3 2
|
||||
#define I2C_4 3
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
#define MAX17050_I2C_ADDR 0x36
|
||||
@@ -38,6 +31,15 @@
|
||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
typedef enum {
|
||||
I2C_1 = 0,
|
||||
I2C_2 = 1,
|
||||
I2C_3 = 2,
|
||||
I2C_4 = 3,
|
||||
I2C_5 = 4,
|
||||
I2C_6 = 5,
|
||||
} I2CDevice;
|
||||
|
||||
typedef struct {
|
||||
uint32_t I2C_I2C_CNFG_0;
|
||||
uint32_t I2C_I2C_CMD_ADDR0_0;
|
||||
@@ -89,9 +91,11 @@ typedef struct {
|
||||
#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
|
||||
#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
|
||||
|
||||
void i2c_init(unsigned int id);
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
void i2c_config(I2CDevice id);
|
||||
|
||||
void i2c_init(I2CDevice id);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
void i2c_send_pmic_cpu_shutdown_cmd(void);
|
||||
bool i2c_query_ti_charger_bit_7(void);
|
||||
|
||||
@@ -176,7 +176,7 @@ static inline uint8_t hex_nybble_to_u8(const char nybble) {
|
||||
static bool name_matches_hash(const char *name, size_t name_len, const void *hash, size_t hash_size) {
|
||||
/* Validate name is hex build id. */
|
||||
for (unsigned int i = 0; i < name_len - 4; i++) {
|
||||
if (isxdigit(name[i]) == 0) {
|
||||
if (isxdigit((unsigned char)name[i]) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,324 +1,330 @@
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.13 (May 21, 2017)
|
||||
|
||||
Changed heading character of configuration keywords "_" to "FF_".
|
||||
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.13 (May 21, 2017)
|
||||
|
||||
Changed heading character of configuration keywords "_" to "FF_".
|
||||
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||
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,22 +1,21 @@
|
||||
FatFs Module Source Files R0.13b
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related 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 it does not depend on any specific
|
||||
storage device. You need to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
||||
FatFs Module Source Files R0.13c
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related 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 it does not depend on any specific
|
||||
storage device. You need to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
||||
|
||||
@@ -1,121 +1,125 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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 <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "ffconf.h"
|
||||
#include "../../device_partition.h"
|
||||
|
||||
/* fs_dev.c */
|
||||
extern device_partition_t *g_volume_to_devparts[FF_VOLUMES];
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (devpart)
|
||||
return devpart->initialized ? RES_OK : STA_NOINIT;
|
||||
else
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
/* We aren't using FF_MULTI_PARTITION, so pdrv = volume id. */
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (!devpart)
|
||||
return STA_NODISK;
|
||||
else if (devpart->initializer)
|
||||
return devpart->initializer(devpart) ? STA_NOINIT : RES_OK;
|
||||
else
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
/* We aren't using FF_MULTI_PARTITION, so pdrv = volume id. */
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (!devpart)
|
||||
return RES_PARERR;
|
||||
else if (devpart->reader)
|
||||
return device_partition_read_data(devpart, buff, sector, count) ? RES_ERROR : RES_OK;
|
||||
else
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
/* We aren't using FF_MULTI_PARTITION, so pdrv = volume id. */
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (!devpart)
|
||||
return RES_PARERR;
|
||||
else if (devpart->writer)
|
||||
return device_partition_write_data(devpart, buff, sector, count) ? RES_ERROR : RES_OK;
|
||||
else
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
switch (cmd) {
|
||||
case GET_SECTOR_SIZE:
|
||||
*(WORD *)buff = devpart ? (WORD)devpart->sector_size : 512;
|
||||
return RES_OK;
|
||||
default:
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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 <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "ff.h" /* Obtains integer types */
|
||||
#include "diskio.h" /* Declarations of disk functions */
|
||||
#include "ffconf.h"
|
||||
#include "../../device_partition.h"
|
||||
|
||||
/* fs_dev.c */
|
||||
extern device_partition_t *g_volume_to_devparts[FF_VOLUMES];
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Drive Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (devpart)
|
||||
return devpart->initialized ? RES_OK : STA_NOINIT;
|
||||
else
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
/* We aren't using FF_MULTI_PARTITION, so pdrv = volume id. */
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (!devpart)
|
||||
return STA_NODISK;
|
||||
else if (devpart->initializer)
|
||||
return devpart->initializer(devpart) ? STA_NOINIT : RES_OK;
|
||||
else
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* 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, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
/* We aren't using FF_MULTI_PARTITION, so pdrv = volume id. */
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (!devpart)
|
||||
return RES_PARERR;
|
||||
else if (devpart->reader)
|
||||
return device_partition_read_data(devpart, buff, sector, count) ? RES_ERROR : RES_OK;
|
||||
else
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if FF_FS_READONLY == 0
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Start sector in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
/* We aren't using FF_MULTI_PARTITION, so pdrv = volume id. */
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
if (!devpart)
|
||||
return RES_PARERR;
|
||||
else if (devpart->writer)
|
||||
return device_partition_write_data(devpart, buff, sector, count) ? RES_ERROR : RES_OK;
|
||||
else
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
device_partition_t *devpart = g_volume_to_devparts[pdrv];
|
||||
switch (cmd) {
|
||||
case GET_SECTOR_SIZE:
|
||||
*(WORD *)buff = devpart ? (WORD)devpart->sector_size : 512;
|
||||
return RES_OK;
|
||||
default:
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,80 +1,77 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ 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 */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,376 +1,405 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13b /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ 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
|
||||
/ 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 FF_DEFINED
|
||||
#define FF_DEFINED 63463 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#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 */
|
||||
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:N/A) */
|
||||
BYTE pdrv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_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[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
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) */
|
||||
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
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID 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 fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* 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 > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#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 (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 */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_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 /* FF_DEFINED */
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ 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
|
||||
/ 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 FF_DEFINED
|
||||
#define FF_DEFINED 86604 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#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 */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#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 */
|
||||
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
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) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_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 */
|
||||
#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;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
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: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
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID 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 fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* 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 > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#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 (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 */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_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 /* FF_DEFINED */
|
||||
|
||||
@@ -1,289 +1,288 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - Configuration file
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 63463 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 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.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 1
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 1
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, 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() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#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(),
|
||||
/ 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 in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 2
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 10
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 1
|
||||
//#define FF_VOLUME_STRS "sdmc"
|
||||
/* 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
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 4096
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled.
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* 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. 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,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 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.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 1
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 1
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, 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() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#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(),
|
||||
/ 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 in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 2
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 10
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 1
|
||||
//#define FF_VOLUME_STRS "sdmc"
|
||||
/* 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
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 4096
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ 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 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* 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. 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,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
||||
@@ -1,171 +1,170 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C)ChaN, 2017 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#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) */
|
||||
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 (nothing to do for null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */
|
||||
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(Mutex + vol);
|
||||
// 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. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 if not enough core) */
|
||||
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 (nothing to do if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//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 */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
||||
// 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. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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 */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef FF_INTEGER
|
||||
#define FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -26,13 +26,11 @@
|
||||
#include "loader.h"
|
||||
#include "chainloader.h"
|
||||
#include "stage2.h"
|
||||
#include "mtc.h"
|
||||
#include "nxboot.h"
|
||||
#include "console.h"
|
||||
#include "fs_utils.h"
|
||||
#include "nxfs.h"
|
||||
#include "gpt.h"
|
||||
#include "splash_screen.h"
|
||||
#include "display/video_fb.h"
|
||||
#include "sdmmc/sdmmc.h"
|
||||
#include "lib/log.h"
|
||||
@@ -44,11 +42,11 @@ static stage2_args_t *g_stage2_args;
|
||||
static bool g_do_nxboot;
|
||||
|
||||
static void setup_env(void) {
|
||||
/* Set the console up. */
|
||||
if (console_init(g_stage2_args->display_initialized) == -1) {
|
||||
/* Initialize the display and console. */
|
||||
if (console_init() < 0) {
|
||||
generic_panic();
|
||||
}
|
||||
|
||||
|
||||
/* Set up exception handlers. */
|
||||
setup_exception_handlers();
|
||||
|
||||
@@ -56,16 +54,11 @@ static void setup_env(void) {
|
||||
if (nxfs_init() < 0) {
|
||||
fatal_error("Failed to initialize the file system: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
/* Train DRAM. */
|
||||
train_dram();
|
||||
}
|
||||
|
||||
|
||||
static void cleanup_env(void) {
|
||||
/* Unmount everything (this causes all open files to be flushed and closed) */
|
||||
/* Terminate the file system. */
|
||||
nxfs_end();
|
||||
//console_end();
|
||||
}
|
||||
|
||||
static void exit_callback(int rc) {
|
||||
@@ -83,6 +76,7 @@ static void exit_callback(int rc) {
|
||||
int main(int argc, void **argv) {
|
||||
loader_ctx_t *loader_ctx = get_loader_ctx();
|
||||
|
||||
/* Check argc. */
|
||||
if (argc != STAGE2_ARGC) {
|
||||
generic_panic();
|
||||
}
|
||||
@@ -90,6 +84,7 @@ int main(int argc, void **argv) {
|
||||
g_stage2_args = &g_stage2_args_store;
|
||||
memcpy(g_stage2_args, (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT], sizeof(*g_stage2_args));
|
||||
|
||||
/* Check stage2 version field. */
|
||||
if (g_stage2_args->version != 0) {
|
||||
generic_panic();
|
||||
}
|
||||
@@ -97,9 +92,9 @@ int main(int argc, void **argv) {
|
||||
/* Override the global logging level. */
|
||||
log_set_log_level(g_stage2_args->log_level);
|
||||
|
||||
/* Initialize the display, console, FS, etc. */
|
||||
/* Initialize the boot environment. */
|
||||
setup_env();
|
||||
|
||||
|
||||
print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, u8"Welcome to Atmosphère Fusée Stage 2!\n");
|
||||
print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]);
|
||||
|
||||
@@ -114,30 +109,31 @@ int main(int argc, void **argv) {
|
||||
|
||||
/* This will load all remaining binaries off of the SD. */
|
||||
load_payload(g_stage2_args->bct0);
|
||||
|
||||
print(SCREEN_LOG_LEVEL_INFO, "Loaded payloads!\n");
|
||||
|
||||
g_do_nxboot = loader_ctx->chainload_entrypoint == 0;
|
||||
|
||||
g_do_nxboot = (loader_ctx->chainload_entrypoint == 0);
|
||||
if (g_do_nxboot) {
|
||||
print(SCREEN_LOG_LEVEL_INFO, "Now performing nxboot.\n");
|
||||
|
||||
/* Start boot. */
|
||||
uint32_t boot_memaddr = nxboot_main();
|
||||
/* Wait for the splash screen to have been displayed as long as it should be. */
|
||||
splash_screen_wait_delay();
|
||||
/* Cleanup environment. */
|
||||
|
||||
/* Terminate the boot environment. */
|
||||
cleanup_env();
|
||||
|
||||
/* Finish boot. */
|
||||
nxboot_finish(boot_memaddr);
|
||||
} else {
|
||||
/* TODO: What else do we want to do in terms of argc/argv? */
|
||||
const char *path = get_loader_ctx()->file_paths_to_load[get_loader_ctx()->file_id_of_entrypoint];
|
||||
print(SCREEN_LOG_LEVEL_MANDATORY, "Now chainloading.\n");
|
||||
print(SCREEN_LOG_LEVEL_INFO, "Now chainloading.\n");
|
||||
g_chainloader_argc = 1;
|
||||
strcpy(g_chainloader_arg_data, path);
|
||||
|
||||
/* Terminate the boot environment. */
|
||||
cleanup_env();
|
||||
}
|
||||
|
||||
/* Deinitialize the display, console, FS, etc. */
|
||||
cleanup_env();
|
||||
|
||||
/* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, chainload or halt ourselves. */
|
||||
__program_exit_callback = exit_callback;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "exocfg.h"
|
||||
#include "display/video_fb.h"
|
||||
#include "lib/ini.h"
|
||||
#include "lib/log.h"
|
||||
#include "splash_screen.h"
|
||||
|
||||
#define u8 uint8_t
|
||||
@@ -57,7 +58,6 @@
|
||||
#include "sept_secondary_01_enc.h"
|
||||
#include "lp0fw_bin.h"
|
||||
#include "emummc_kip.h"
|
||||
#include "lib/log.h"
|
||||
#undef u8
|
||||
#undef u32
|
||||
|
||||
@@ -484,7 +484,7 @@ uint32_t nxboot_main(void) {
|
||||
FILE *boot0, *pk2file;
|
||||
void *exosphere_memaddr;
|
||||
exo_emummc_config_t exo_emummc_cfg;
|
||||
|
||||
|
||||
/* Configure emummc or mount the real NAND. */
|
||||
if (!nxboot_configure_emummc(&exo_emummc_cfg)) {
|
||||
emummc = NULL;
|
||||
@@ -649,8 +649,7 @@ uint32_t nxboot_main(void) {
|
||||
fatal_error("[NXBOOT] Failed to get TSEC key!\n");
|
||||
}
|
||||
}
|
||||
|
||||
//fatal_error("Ran sept!");
|
||||
|
||||
/* Display splash screen. */
|
||||
display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000);
|
||||
|
||||
@@ -716,7 +715,6 @@ uint32_t nxboot_main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Select the right address for the warmboot firmware. */
|
||||
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_400) {
|
||||
warmboot_memaddr = (void *)0x8000D000;
|
||||
@@ -801,9 +799,9 @@ uint32_t nxboot_main(void) {
|
||||
|
||||
print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Powering on the CCPLEX...\n");
|
||||
|
||||
/* Unmount everything. */
|
||||
nxfs_end();
|
||||
|
||||
/* Wait for the splash screen to have been displayed for as long as it should be. */
|
||||
splash_screen_wait_delay();
|
||||
|
||||
/* Return the memory address for booting CPU0. */
|
||||
return (uint32_t)exosphere_memaddr;
|
||||
}
|
||||
|
||||
@@ -24,11 +24,9 @@ static uint32_t g_panic_code = 0;
|
||||
|
||||
void check_and_display_panic(void) {
|
||||
/* We also handle our own panics. */
|
||||
/* In the case of our own panics, we assume that the display has already been initialized. */
|
||||
bool has_panic = APBDEV_PMC_RST_STATUS_0 != 0 || g_panic_code != 0;
|
||||
uint32_t code = g_panic_code == 0 ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
|
||||
|
||||
has_panic = has_panic && !(APBDEV_PMC_RST_STATUS_0 != 1 && code == PANIC_CODE_SAFEMODE);
|
||||
bool has_panic = ((APBDEV_PMC_RST_STATUS_0 != 0) || (g_panic_code != 0));
|
||||
uint32_t code = (g_panic_code == 0) ? APBDEV_PMC_SCRATCH200_0 : g_panic_code;
|
||||
has_panic = has_panic && !((APBDEV_PMC_RST_STATUS_0 != 1) && (code == PANIC_CODE_SAFEMODE));
|
||||
|
||||
if (has_panic) {
|
||||
uint32_t color;
|
||||
@@ -71,11 +69,13 @@ void check_and_display_panic(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_panic_code == 0) {
|
||||
display_init();
|
||||
}
|
||||
|
||||
/* Initialize the display. */
|
||||
display_init();
|
||||
|
||||
/* Fill the screen. */
|
||||
display_color_screen(color);
|
||||
|
||||
/* Wait for button and reboot. */
|
||||
wait_for_button_and_reboot();
|
||||
} else {
|
||||
g_panic_code = 0;
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
ScreenLogLevel log_level;
|
||||
bool display_initialized;
|
||||
char bct0[BCTO_MAX_SIZE];
|
||||
} stage2_args_t;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ static inline uint32_t get_clk_source_reg(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0x1A0;
|
||||
case CARDEVICE_I2C1: return 0x124;
|
||||
case CARDEVICE_I2C5: return 0x128;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0x42C;
|
||||
case CARDEVICE_HOST1X: return 0x180;
|
||||
case CARDEVICE_TSEC: return 0x1F4;
|
||||
@@ -48,7 +48,7 @@ static inline uint32_t get_clk_source_val(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 6;
|
||||
case CARDEVICE_I2C5: return 6;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 4;
|
||||
case CARDEVICE_TSEC: return 0;
|
||||
@@ -71,7 +71,7 @@ static inline uint32_t get_clk_source_div(CarDevice dev) {
|
||||
case CARDEVICE_UARTC: return 0;
|
||||
case CARDEVICE_I2C1: return 0;
|
||||
case CARDEVICE_I2C5: return 0;
|
||||
case CARDEVICE_UNK: return 0;
|
||||
case CARDEVICE_TZRAM: return 0;
|
||||
case CARDEVICE_SE: return 0;
|
||||
case CARDEVICE_HOST1X: return 3;
|
||||
case CARDEVICE_TSEC: return 2;
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef enum {
|
||||
CARDEVICE_UARTC = ((1 << 5) | 0x17),
|
||||
CARDEVICE_I2C1 = ((0 << 5) | 0xC),
|
||||
CARDEVICE_I2C5 = ((1 << 5) | 0xF),
|
||||
CARDEVICE_UNK = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_TZRAM = ((3 << 5) | 0x1E),
|
||||
CARDEVICE_SE = ((3 << 5) | 0x1F),
|
||||
CARDEVICE_HOST1X = ((0 << 5) | 0x1C),
|
||||
CARDEVICE_TSEC = ((2 << 5) | 0x13),
|
||||
|
||||
@@ -21,125 +21,66 @@
|
||||
#include "gpio.h"
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* Returns a GPIO bank object that corresponds to the given GPIO pin,
|
||||
* which can be created using the TEGRA_GPIO macro or passed from the name macro.
|
||||
*
|
||||
* @param pin The GPIO to get the bank for.
|
||||
* @return The GPIO bank object to use for working with the given bank.
|
||||
*/
|
||||
static volatile tegra_gpio_bank_t *gpio_get_bank(uint32_t pin)
|
||||
{
|
||||
static volatile tegra_gpio_bank_t *gpio_get_bank(uint32_t pin) {
|
||||
volatile tegra_gpio_t *gpio = gpio_get_regs();
|
||||
uint32_t bank_number = pin >> GPIO_BANK_SHIFT;
|
||||
uint32_t bank_number = (pin >> GPIO_BANK_SHIFT);
|
||||
|
||||
return &gpio->bank[bank_number];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the port number for working with the given GPIO.
|
||||
*/
|
||||
static volatile uint32_t gpio_get_port(uint32_t pin)
|
||||
{
|
||||
return (pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK;
|
||||
static volatile uint32_t gpio_get_port(uint32_t pin) {
|
||||
return ((pin >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a mask to be used to work with the given GPIO
|
||||
*/
|
||||
static volatile uint32_t gpio_get_mask(uint32_t pin)
|
||||
{
|
||||
uint32_t pin_number = pin & GPIO_PIN_MASK;
|
||||
static volatile uint32_t gpio_get_mask(uint32_t pin) {
|
||||
uint32_t pin_number = (pin & GPIO_PIN_MASK);
|
||||
return (1 << pin_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple GPIO configuration operation.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param should_be_set True iff the relevant bit should be set; or false if it should be cleared.
|
||||
* @param offset The offset into a gpio_bank structure
|
||||
*/
|
||||
static void gpio_simple_register_set(uint32_t pin, bool should_be_set, uint32_t offset)
|
||||
{
|
||||
// Retrieve the register set that corresponds to the given pin and offset.
|
||||
static void gpio_simple_register_set(uint32_t pin, bool should_be_set, uint32_t offset) {
|
||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
||||
uintptr_t cluster_addr = (uintptr_t)gpio_get_bank(pin) + offset;
|
||||
uint32_t *cluster = (uint32_t *)cluster_addr;
|
||||
|
||||
// Figure out the offset into the cluster,
|
||||
// and the mask to be used.
|
||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
||||
uint32_t port = gpio_get_port(pin);
|
||||
uint32_t mask = gpio_get_mask(pin);
|
||||
|
||||
// Set or clear the bit, as appropriate.
|
||||
/* Set or clear the bit, as appropriate. */
|
||||
if (should_be_set)
|
||||
cluster[port] |= mask;
|
||||
cluster[port] |= mask;
|
||||
else
|
||||
cluster[port] &= ~mask;
|
||||
|
||||
/* Dummy read. */
|
||||
(void)cluster[port];
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a simple GPIO configuration operation.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param should_be_set True iff the relevant bit should be set; or false if it should be cleared.
|
||||
* @param offset The offset into a gpio_bank structure
|
||||
*/
|
||||
static bool gpio_simple_register_get(uint32_t pin, uint32_t offset)
|
||||
{
|
||||
// Retrieve the register set that corresponds to the given pin and offset.
|
||||
static bool gpio_simple_register_get(uint32_t pin, uint32_t offset) {
|
||||
/* Retrieve the register set that corresponds to the given pin and offset. */
|
||||
uintptr_t cluster_addr = (uintptr_t)gpio_get_bank(pin) + offset;
|
||||
uint32_t *cluster = (uint32_t *)cluster_addr;
|
||||
|
||||
// Figure out the offset into the cluster,
|
||||
// and the mask to be used.
|
||||
/* Figure out the offset into the cluster, and the mask to be used. */
|
||||
uint32_t port = gpio_get_port(pin);
|
||||
uint32_t mask = gpio_get_mask(pin);
|
||||
|
||||
// Convert the given value to a boolean.
|
||||
/* Convert the given value to a boolean. */
|
||||
return !!(cluster[port] & mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a given pin as either GPIO or SFIO.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
void gpio_configure_mode(uint32_t pin, uint32_t mode)
|
||||
{
|
||||
void gpio_configure_mode(uint32_t pin, uint32_t mode) {
|
||||
gpio_simple_register_set(pin, mode == GPIO_MODE_GPIO, offsetof(tegra_gpio_bank_t, config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a given pin as either INPUT or OUPUT.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param direction The relevant direction.
|
||||
*/
|
||||
void gpio_configure_direction(uint32_t pin, uint32_t dir)
|
||||
{
|
||||
void gpio_configure_direction(uint32_t pin, uint32_t dir) {
|
||||
gpio_simple_register_set(pin, dir == GPIO_DIRECTION_OUTPUT, offsetof(tegra_gpio_bank_t, direction));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives a relevant GPIO pin as either HIGH or LOW.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
void gpio_write(uint32_t pin, uint32_t value)
|
||||
{
|
||||
void gpio_write(uint32_t pin, uint32_t value) {
|
||||
gpio_simple_register_set(pin, value == GPIO_LEVEL_HIGH, offsetof(tegra_gpio_bank_t, out));
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives a relevant GPIO pin as either HIGH or LOW.
|
||||
*
|
||||
* @param pin The GPIO pin to work with, as created with TEGRA_GPIO, or a named GPIO.
|
||||
* @param mode The relevant mode.
|
||||
*/
|
||||
uint32_t gpio_read(uint32_t pin)
|
||||
{
|
||||
uint32_t gpio_read(uint32_t pin) {
|
||||
return gpio_simple_register_get(pin, offsetof(tegra_gpio_bank_t, in));
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ static inline volatile tegra_gpio_t *gpio_get_regs(void)
|
||||
((TEGRA_GPIO_PORT_##port * 8) + offset)
|
||||
|
||||
/* Mode select */
|
||||
#define GPIO_MODE_GPIO 0
|
||||
#define GPIO_MODE_SFIO 1
|
||||
#define GPIO_MODE_SFIO 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
|
||||
/* Direction */
|
||||
#define GPIO_DIRECTION_INPUT 0
|
||||
|
||||
@@ -17,19 +17,52 @@
|
||||
#include "i2c.h"
|
||||
#include "utils.h"
|
||||
#include "timers.h"
|
||||
#include "pinmux.h"
|
||||
|
||||
/* Prototypes for internal commands. */
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id);
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id);
|
||||
void i2c_load_config(volatile tegra_i2c_t *regs);
|
||||
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
bool i2c_write(volatile tegra_i2c_t *regs, uint8_t device, void *src, size_t src_size);
|
||||
bool i2c_read(volatile tegra_i2c_t *regs, uint8_t device, void *dst, size_t dst_size);
|
||||
|
||||
/* Configure I2C pinmux. */
|
||||
void i2c_config(I2CDevice id) {
|
||||
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
|
||||
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
pinmux->gen1_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen1_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_2:
|
||||
pinmux->gen2_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen2_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_3:
|
||||
pinmux->gen3_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->gen3_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_4:
|
||||
pinmux->cam_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->cam_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_5:
|
||||
pinmux->pwr_i2c_scl = PINMUX_INPUT;
|
||||
pinmux->pwr_i2c_sda = PINMUX_INPUT;
|
||||
break;
|
||||
case I2C_6:
|
||||
/* Unused. */
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize I2C based on registers. */
|
||||
void i2c_init(unsigned int id) {
|
||||
void i2c_init(I2CDevice id) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
|
||||
/* Setup divisor, and clear the bus. */
|
||||
@@ -91,7 +124,7 @@ void i2c_set_ti_charger_bit_7(void) {
|
||||
}
|
||||
|
||||
/* Get registers pointer based on I2C ID. */
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(unsigned int id) {
|
||||
volatile tegra_i2c_t *i2c_get_registers_from_id(I2CDevice id) {
|
||||
switch (id) {
|
||||
case I2C_1:
|
||||
return I2C1_REGS;
|
||||
@@ -126,7 +159,7 @@ void i2c_load_config(volatile tegra_i2c_t *regs) {
|
||||
}
|
||||
|
||||
/* Reads a register from a device over I2C, writes result to output. */
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size) {
|
||||
volatile tegra_i2c_t *regs = i2c_get_registers_from_id(id);
|
||||
uint32_t val = r;
|
||||
|
||||
@@ -143,7 +176,7 @@ bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst
|
||||
}
|
||||
|
||||
/* Writes a value to a register over I2C. */
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size) {
|
||||
uint32_t val = r;
|
||||
if (src_size == 0) {
|
||||
return true;
|
||||
|
||||
@@ -24,13 +24,6 @@
|
||||
#define I2C1234_BASE 0x7000C000
|
||||
#define I2C56_BASE 0x7000D000
|
||||
|
||||
#define I2C_1 0
|
||||
#define I2C_2 1
|
||||
#define I2C_3 2
|
||||
#define I2C_4 3
|
||||
#define I2C_5 4
|
||||
#define I2C_6 5
|
||||
|
||||
#define MAX77621_CPU_I2C_ADDR 0x1B
|
||||
#define MAX77621_GPU_I2C_ADDR 0x1C
|
||||
#define MAX17050_I2C_ADDR 0x36
|
||||
@@ -38,6 +31,15 @@
|
||||
#define MAX77620_RTC_I2C_ADDR 0x68
|
||||
#define BQ24193_I2C_ADDR 0x6B
|
||||
|
||||
typedef enum {
|
||||
I2C_1 = 0,
|
||||
I2C_2 = 1,
|
||||
I2C_3 = 2,
|
||||
I2C_4 = 3,
|
||||
I2C_5 = 4,
|
||||
I2C_6 = 5,
|
||||
} I2CDevice;
|
||||
|
||||
typedef struct {
|
||||
uint32_t I2C_I2C_CNFG_0;
|
||||
uint32_t I2C_I2C_CMD_ADDR0_0;
|
||||
@@ -89,9 +91,11 @@ typedef struct {
|
||||
#define I2C5_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x000))
|
||||
#define I2C6_REGS ((volatile tegra_i2c_t *)(I2C56_BASE + 0x100))
|
||||
|
||||
void i2c_init(unsigned int id);
|
||||
bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
void i2c_config(I2CDevice id);
|
||||
|
||||
void i2c_init(I2CDevice id);
|
||||
bool i2c_query(I2CDevice id, uint8_t device, uint8_t r, void *dst, size_t dst_size);
|
||||
bool i2c_send(I2CDevice id, uint8_t device, uint8_t r, void *src, size_t src_size);
|
||||
|
||||
void i2c_send_pmic_cpu_shutdown_cmd(void);
|
||||
bool i2c_query_ti_charger_bit_7(void);
|
||||
|
||||
211
sept/sept-primary/src/pinmux.h
Normal file
211
sept/sept-primary/src/pinmux.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FUSEE_PINMUX_H
|
||||
#define FUSEE_PINMUX_H
|
||||
|
||||
#define PINMUX_BASE 0x70003000
|
||||
#define MAKE_PINMUX_REG(n) MAKE_REG32(PINMUX_BASE + n)
|
||||
|
||||
#define PINMUX_TRISTATE (1 << 4)
|
||||
#define PINMUX_PARKED (1 << 5)
|
||||
#define PINMUX_INPUT (1 << 6)
|
||||
#define PINMUX_PULL_NONE (0 << 2)
|
||||
#define PINMUX_PULL_DOWN (1 << 2)
|
||||
#define PINMUX_PULL_UP (2 << 2)
|
||||
#define PINMUX_SELECT_FUNCTION0 0
|
||||
#define PINMUX_SELECT_FUNCTION1 1
|
||||
#define PINMUX_SELECT_FUNCTION2 2
|
||||
#define PINMUX_SELECT_FUNCTION3 3
|
||||
#define PINMUX_DRIVE_1X (0 << 13)
|
||||
#define PINMUX_DRIVE_2X (1 << 13)
|
||||
#define PINMUX_DRIVE_3X (2 << 13)
|
||||
#define PINMUX_DRIVE_4X (3 << 13)
|
||||
|
||||
typedef struct {
|
||||
uint32_t sdmmc1_clk;
|
||||
uint32_t sdmmc1_cmd;
|
||||
uint32_t sdmmc1_dat3;
|
||||
uint32_t sdmmc1_dat2;
|
||||
uint32_t sdmmc1_dat1;
|
||||
uint32_t sdmmc1_dat0;
|
||||
uint32_t _r18;
|
||||
uint32_t sdmmc3_clk;
|
||||
uint32_t sdmmc3_cmd;
|
||||
uint32_t sdmmc3_dat0;
|
||||
uint32_t sdmmc3_dat1;
|
||||
uint32_t sdmmc3_dat2;
|
||||
uint32_t sdmmc3_dat3;
|
||||
uint32_t _r34;
|
||||
uint32_t pex_l0_rst_n;
|
||||
uint32_t pex_l0_clkreq_n;
|
||||
uint32_t pex_wake_n;
|
||||
uint32_t pex_l1_rst_n;
|
||||
uint32_t pex_l1_clkreq_n;
|
||||
uint32_t sata_led_active;
|
||||
uint32_t spi1_mosi;
|
||||
uint32_t spi1_miso;
|
||||
uint32_t spi1_sck;
|
||||
uint32_t spi1_cs0;
|
||||
uint32_t spi1_cs1;
|
||||
uint32_t spi2_mosi;
|
||||
uint32_t spi2_miso;
|
||||
uint32_t spi2_sck;
|
||||
uint32_t spi2_cs0;
|
||||
uint32_t spi2_cs1;
|
||||
uint32_t spi4_mosi;
|
||||
uint32_t spi4_miso;
|
||||
uint32_t spi4_sck;
|
||||
uint32_t spi4_cs0;
|
||||
uint32_t qspi_sck;
|
||||
uint32_t qspi_cs_n;
|
||||
uint32_t qspi_io0;
|
||||
uint32_t qspi_io1;
|
||||
uint32_t qspi_io2;
|
||||
uint32_t qspi_io3;
|
||||
uint32_t _ra0;
|
||||
uint32_t dmic1_clk;
|
||||
uint32_t dmic1_dat;
|
||||
uint32_t dmic2_clk;
|
||||
uint32_t dmic2_dat;
|
||||
uint32_t dmic3_clk;
|
||||
uint32_t dmic3_dat;
|
||||
uint32_t gen1_i2c_scl;
|
||||
uint32_t gen1_i2c_sda;
|
||||
uint32_t gen2_i2c_scl;
|
||||
uint32_t gen2_i2c_sda;
|
||||
uint32_t gen3_i2c_scl;
|
||||
uint32_t gen3_i2c_sda;
|
||||
uint32_t cam_i2c_scl;
|
||||
uint32_t cam_i2c_sda;
|
||||
uint32_t pwr_i2c_scl;
|
||||
uint32_t pwr_i2c_sda;
|
||||
uint32_t uart1_tx;
|
||||
uint32_t uart1_rx;
|
||||
uint32_t uart1_rts;
|
||||
uint32_t uart1_cts;
|
||||
uint32_t uart2_tx;
|
||||
uint32_t uart2_rx;
|
||||
uint32_t uart2_rts;
|
||||
uint32_t uart2_cts;
|
||||
uint32_t uart3_tx;
|
||||
uint32_t uart3_rx;
|
||||
uint32_t uart3_rts;
|
||||
uint32_t uart3_cts;
|
||||
uint32_t uart4_tx;
|
||||
uint32_t uart4_rx;
|
||||
uint32_t uart4_rts;
|
||||
uint32_t uart4_cts;
|
||||
uint32_t dap1_fs;
|
||||
uint32_t dap1_din;
|
||||
uint32_t dap1_dout;
|
||||
uint32_t dap1_sclk;
|
||||
uint32_t dap2_fs;
|
||||
uint32_t dap2_din;
|
||||
uint32_t dap2_dout;
|
||||
uint32_t dap2_sclk;
|
||||
uint32_t dap4_fs;
|
||||
uint32_t dap4_din;
|
||||
uint32_t dap4_dout;
|
||||
uint32_t dap4_sclk;
|
||||
uint32_t cam1_mclk;
|
||||
uint32_t cam2_mclk;
|
||||
uint32_t jtag_rtck;
|
||||
uint32_t clk_32k_in;
|
||||
uint32_t clk_32k_out;
|
||||
uint32_t batt_bcl;
|
||||
uint32_t clk_req;
|
||||
uint32_t cpu_pwr_req;
|
||||
uint32_t pwr_int_n;
|
||||
uint32_t shutdown;
|
||||
uint32_t core_pwr_req;
|
||||
uint32_t aud_mclk;
|
||||
uint32_t dvfs_pwm;
|
||||
uint32_t dvfs_clk;
|
||||
uint32_t gpio_x1_aud;
|
||||
uint32_t gpio_x3_aud;
|
||||
uint32_t pcc7;
|
||||
uint32_t hdmi_cec;
|
||||
uint32_t hdmi_int_dp_hpd;
|
||||
uint32_t spdif_out;
|
||||
uint32_t spdif_in;
|
||||
uint32_t usb_vbus_en0;
|
||||
uint32_t usb_vbus_en1;
|
||||
uint32_t dp_hpd0;
|
||||
uint32_t wifi_en;
|
||||
uint32_t wifi_rst;
|
||||
uint32_t wifi_wake_ap;
|
||||
uint32_t ap_wake_bt;
|
||||
uint32_t bt_rst;
|
||||
uint32_t bt_wake_ap;
|
||||
uint32_t ap_wake_nfc;
|
||||
uint32_t nfc_en;
|
||||
uint32_t nfc_int;
|
||||
uint32_t gps_en;
|
||||
uint32_t gps_rst;
|
||||
uint32_t cam_rst;
|
||||
uint32_t cam_af_en;
|
||||
uint32_t cam_flash_en;
|
||||
uint32_t cam1_pwdn;
|
||||
uint32_t cam2_pwdn;
|
||||
uint32_t cam1_strobe;
|
||||
uint32_t lcd_te;
|
||||
uint32_t lcd_bl_pwm;
|
||||
uint32_t lcd_bl_en;
|
||||
uint32_t lcd_rst;
|
||||
uint32_t lcd_gpio1;
|
||||
uint32_t lcd_gpio2;
|
||||
uint32_t ap_ready;
|
||||
uint32_t touch_rst;
|
||||
uint32_t touch_clk;
|
||||
uint32_t modem_wake_ap;
|
||||
uint32_t touch_int;
|
||||
uint32_t motion_int;
|
||||
uint32_t als_prox_int;
|
||||
uint32_t temp_alert;
|
||||
uint32_t button_power_on;
|
||||
uint32_t button_vol_up;
|
||||
uint32_t button_vol_down;
|
||||
uint32_t button_slide_sw;
|
||||
uint32_t button_home;
|
||||
uint32_t pa6;
|
||||
uint32_t pe6;
|
||||
uint32_t pe7;
|
||||
uint32_t ph6;
|
||||
uint32_t pk0;
|
||||
uint32_t pk1;
|
||||
uint32_t pk2;
|
||||
uint32_t pk3;
|
||||
uint32_t pk4;
|
||||
uint32_t pk5;
|
||||
uint32_t pk6;
|
||||
uint32_t pk7;
|
||||
uint32_t pl0;
|
||||
uint32_t pl1;
|
||||
uint32_t pz0;
|
||||
uint32_t pz1;
|
||||
uint32_t pz2;
|
||||
uint32_t pz3;
|
||||
uint32_t pz4;
|
||||
uint32_t pz5;
|
||||
} tegra_pinmux_t;
|
||||
|
||||
static inline volatile tegra_pinmux_t *pinmux_get_regs(void)
|
||||
{
|
||||
return (volatile tegra_pinmux_t *)PINMUX_BASE;
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user