├── src ├── rp2040 │ ├── .gitignore │ ├── pico_tn20k.png │ ├── sdc_direct.h │ ├── ws2812.pio.h │ ├── freertos_callbacks.c │ ├── FreeRTOS_Kernel_import.cmake │ └── usb_descriptors.c ├── bl616 │ ├── m0s_dock_tn20k.png │ ├── friend_20k │ │ ├── friend_20k_bl616.bin │ │ ├── friend_20k_encrypted_bl616.bin │ │ ├── friend_20k_cfg.ini │ │ ├── friend_20k_encrypted_cfg.ini │ │ └── README.md │ ├── bl616_fpga_partner │ │ ├── bl616_fpga_partner_20kNano.bin │ │ ├── bl616_fpga_partner_25kDock.bin │ │ ├── bl616_fpga_partner_Console.bin │ │ ├── bl616_fpga_partner_NeoDock.bin │ │ ├── bl616_fpga_partner_138kproDock.bin │ │ ├── bl616_fpga_partner_20kNano_cfg.ini │ │ └── README.md │ ├── flash_m0sdock_cfg.ini │ ├── flash.ini │ ├── flash_prog_cfg.ini │ ├── Makefile │ ├── buildall.bat │ └── CMakeLists.txt ├── esp32 │ ├── esp32s2_tn20k.png │ ├── main │ │ ├── idf_component.yml │ │ └── CMakeLists.txt │ ├── CMakeLists.txt │ └── README.md ├── fatfs │ ├── documents │ │ ├── res │ │ │ ├── f1.png │ │ │ ├── f2.png │ │ │ ├── f3.png │ │ │ ├── f4.png │ │ │ ├── f5.png │ │ │ ├── f6.png │ │ │ ├── f7.png │ │ │ ├── funcs.png │ │ │ ├── mkfs.xlsx │ │ │ ├── layers.png │ │ │ ├── layers1.png │ │ │ ├── layers2.png │ │ │ ├── layers3.png │ │ │ ├── mkfatimg.zip │ │ │ ├── modules.png │ │ │ ├── rwtest1.png │ │ │ ├── rwtest2.png │ │ │ ├── rwtest3.png │ │ │ ├── uniconv.zip │ │ │ ├── app1.c │ │ │ ├── app5.c │ │ │ ├── app6.c │ │ │ ├── app2.c │ │ │ └── app3.c │ │ ├── doc │ │ │ ├── error.html │ │ │ ├── size.html │ │ │ ├── tell.html │ │ │ ├── eof.html │ │ │ ├── dinit.html │ │ │ ├── sdir.html │ │ │ ├── truncate.html │ │ │ ├── closedir.html │ │ │ ├── close.html │ │ │ ├── dstat.html │ │ │ ├── chdrive.html │ │ │ ├── fattime.html │ │ │ ├── mkdir.html │ │ │ ├── opendir.html │ │ │ ├── findnext.html │ │ │ ├── sfile.html │ │ │ ├── putc.html │ │ │ ├── unlink.html │ │ │ ├── getcwd.html │ │ │ ├── puts.html │ │ │ ├── setcp.html │ │ │ ├── read.html │ │ │ ├── gets.html │ │ │ ├── chmod.html │ │ │ ├── utime.html │ │ │ ├── getlabel.html │ │ │ ├── chdir.html │ │ │ ├── write.html │ │ │ ├── rename.html │ │ │ ├── sync.html │ │ │ ├── sfileinfo.html │ │ │ ├── setlabel.html │ │ │ ├── getfree.html │ │ │ ├── dwrite.html │ │ │ ├── sfatfs.html │ │ │ ├── dread.html │ │ │ └── stat.html │ │ └── css_e.css │ ├── source │ │ ├── 00readme.txt │ │ └── diskio.h │ ├── README.asc │ └── LICENSE.txt ├── xml.h ├── osd.h ├── at_wifi.h ├── inifile.h ├── menu.h ├── sdc.h ├── sysctrl.h ├── hid.h ├── hidparser.h ├── puff.h ├── mcu_hw.h ├── debug.h ├── spi.h ├── jtag.h ├── osd_u8g2.c ├── config.h ├── main.c └── xml.c ├── debug.png ├── .gitmodules ├── .gitignore ├── DEBUGGING.md └── README.md /src/rp2040/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .vscode -------------------------------------------------------------------------------- /debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/debug.png -------------------------------------------------------------------------------- /src/rp2040/pico_tn20k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/rp2040/pico_tn20k.png -------------------------------------------------------------------------------- /src/bl616/m0s_dock_tn20k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/m0s_dock_tn20k.png -------------------------------------------------------------------------------- /src/esp32/esp32s2_tn20k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/esp32/esp32s2_tn20k.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f1.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f2.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f3.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f4.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f5.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f6.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/f7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/f7.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/funcs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/funcs.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/mkfs.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/mkfs.xlsx -------------------------------------------------------------------------------- /src/fatfs/documents/res/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/layers.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/layers1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/layers1.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/layers2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/layers2.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/layers3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/layers3.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/mkfatimg.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/mkfatimg.zip -------------------------------------------------------------------------------- /src/fatfs/documents/res/modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/modules.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/rwtest1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/rwtest1.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/rwtest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/rwtest2.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/rwtest3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/rwtest3.png -------------------------------------------------------------------------------- /src/fatfs/documents/res/uniconv.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/fatfs/documents/res/uniconv.zip -------------------------------------------------------------------------------- /src/bl616/friend_20k/friend_20k_bl616.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/friend_20k/friend_20k_bl616.bin -------------------------------------------------------------------------------- /src/esp32/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | ## IDF Component Manager Manifest File 2 | dependencies: 3 | idf: ">=4.4" 4 | usb_host_hid: "1.0.0" 5 | -------------------------------------------------------------------------------- /src/bl616/friend_20k/friend_20k_encrypted_bl616.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/friend_20k/friend_20k_encrypted_bl616.bin -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/bl616_fpga_partner_20kNano.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/bl616_fpga_partner/bl616_fpga_partner_20kNano.bin -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/bl616_fpga_partner_25kDock.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/bl616_fpga_partner/bl616_fpga_partner_25kDock.bin -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/bl616_fpga_partner_Console.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/bl616_fpga_partner/bl616_fpga_partner_Console.bin -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/bl616_fpga_partner_NeoDock.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/bl616_fpga_partner/bl616_fpga_partner_NeoDock.bin -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/bl616_fpga_partner_138kproDock.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiSTle-Dev/FPGA-Companion/HEAD/src/bl616/bl616_fpga_partner/bl616_fpga_partner_138kproDock.bin -------------------------------------------------------------------------------- /src/xml.h: -------------------------------------------------------------------------------- 1 | #ifndef XML_H 2 | #define XML_H 3 | 4 | // callbacks 5 | extern int xml_element_start_cb(char *name); 6 | extern void xml_element_end_cb(void); 7 | extern void xml_attribute_cb(char *name, char *value); 8 | 9 | void xml_init(void); 10 | int xml_parse(char); 11 | 12 | 13 | #endif // XML_H 14 | -------------------------------------------------------------------------------- /src/osd.h: -------------------------------------------------------------------------------- 1 | #ifndef OSD_H 2 | #define OSD_H 3 | 4 | #include "spi.h" 5 | #include "u8g2.h" 6 | 7 | #define OSD_INVISIBLE 0 8 | #define OSD_VISIBLE (!OSD_INVISIBLE) 9 | 10 | extern u8g2_t u8g2; 11 | 12 | void osd_init(void); 13 | void osd_enable(char); 14 | int osd_is_visible(void); 15 | 16 | #endif // OSD_H 17 | -------------------------------------------------------------------------------- /src/at_wifi.h: -------------------------------------------------------------------------------- 1 | /* 2 | at_wifi.h 3 | */ 4 | 5 | #ifndef AT_WIFI_H 6 | #define AT_WIFI_H 7 | 8 | void at_wifi_init(void); 9 | void at_wifi_port_byte(unsigned char); 10 | void at_wifi_puts(char *); 11 | void at_wifi_puts_n(char *, int); 12 | uint8_t pet2asc(uint8_t c); 13 | uint8_t asc2pet(uint8_t c); 14 | 15 | #endif // AT_WIFI_H 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/u8g2"] 2 | path = src/u8g2 3 | url = https://github.com/olikraus/u8g2 4 | [submodule "src/FreeRTOS-Kernel"] 5 | path = src/FreeRTOS-Kernel 6 | url = https://github.com/FreeRTOS/FreeRTOS-Kernel 7 | [submodule "src/tusb_xinput"] 8 | path = src/tusb_xinput 9 | url = https://github.com/Ryzee119/tusb_xinput.git 10 | -------------------------------------------------------------------------------- /src/inifile.h: -------------------------------------------------------------------------------- 1 | /* 2 | inifile.h 3 | */ 4 | 5 | #ifndef INIFILE_H 6 | #define INIFILE_H 7 | 8 | #define INIFILE_OPTION_HOTKEY 0 // HID key code 9 | #define INIFILE_OPTION_LED 1 // 0 = blink, 1 = on, 0 = off 10 | 11 | int inifile_read(char *); 12 | void inifile_write(char *); 13 | int inifile_option_get(int id); 14 | 15 | #endif // INIFILE_H 16 | -------------------------------------------------------------------------------- /src/esp32/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | 7 | set(PROJECT fpga_companion) 8 | project(${PROJECT}) 9 | 10 | # target_link_options(${PROJECT} PRIVATE --print-memory-usage) 11 | -------------------------------------------------------------------------------- /src/bl616/friend_20k/friend_20k_cfg.ini: -------------------------------------------------------------------------------- 1 | [cfg] 2 | # 0: no erase, 1:programmed section erase, 2: chip erase 3 | erase = 1 4 | # skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated 5 | skip_mode = 0x0, 0x0 6 | # 0: not use isp mode, #1: isp mode 7 | boot2_isp_mode = 0 8 | 9 | [FW] 10 | filedir = ./friend_20k_bl616.bin 11 | address = 0x000000 12 | 13 | -------------------------------------------------------------------------------- /src/bl616/friend_20k/friend_20k_encrypted_cfg.ini: -------------------------------------------------------------------------------- 1 | [cfg] 2 | # 0: no erase, 1:programmed section erase, 2: chip erase 3 | erase = 2 4 | # skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated 5 | skip_mode = 0x0, 0x0 6 | # 0: not use isp mode, #1: isp mode 7 | boot2_isp_mode = 0 8 | 9 | [FW] 10 | filedir = ./friend_20k_encrypted_bl616.bin 11 | address = 0x000000 12 | 13 | -------------------------------------------------------------------------------- /src/rp2040/sdc_direct.h: -------------------------------------------------------------------------------- 1 | #ifndef SDC_DIRECT_H 2 | #define SDC_DIRECT_H 3 | 4 | bool sdc_direct_init(void); 5 | void sdc_direct_release(void); 6 | 7 | // these are called by sdc.c 8 | bool sdc_direct_write(uint32_t lba, const uint8_t *buffer); 9 | bool sdc_direct_read(uint32_t lba, uint8_t *buffer); 10 | 11 | // called by main if accessing the FPGA times out 12 | void sdc_boot(void); 13 | 14 | #endif // SDC_DIRECT_H 15 | -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/bl616_fpga_partner_20kNano_cfg.ini: -------------------------------------------------------------------------------- 1 | [cfg] 2 | # 0: no erase, 1:programmed section erase, 2: chip erase 3 | erase = 1 4 | # skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated 5 | skip_mode = 0x0, 0x0 6 | # 0: not use isp mode, #1: isp mode 7 | boot2_isp_mode = 0 8 | 9 | [FW] 10 | filedir = ./bl616_fpga_partner_20kNano.bin 11 | address = 0x000000 12 | -------------------------------------------------------------------------------- /src/bl616/flash_m0sdock_cfg.ini: -------------------------------------------------------------------------------- 1 | [cfg] 2 | # 0: no erase, 1:programmed section erase, 2: chip erase 3 | erase = 1 4 | # skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated 5 | skip_mode = 0x0, 0x0 6 | # 0: not use isp mode, #1: isp mode 7 | boot2_isp_mode = 0 8 | pre_program = 9 | pre_program_args = 10 | 11 | [FW] 12 | filedir = ./fpga_companion_m0sdock.bin 13 | address = 0x0 14 | 15 | -------------------------------------------------------------------------------- /src/bl616/flash.ini: -------------------------------------------------------------------------------- 1 | [cfg] 2 | # 0: no erase, 1:programmed section erase, 2: chip erase 3 | erase = 1 4 | # skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated 5 | skip_mode = 0x0, 0x0 6 | # 0: not use isp mode, #1: isp mode 7 | boot2_isp_mode = 0 8 | pre_program = 9 | pre_program_args = 10 | 11 | [official] 12 | filedir = ./bl616_fpga_partner.bin 13 | address = 0x0 14 | 15 | [custom] 16 | filedir = ./fpga_companion.bin 17 | address = 0x40000 18 | -------------------------------------------------------------------------------- /src/esp32/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB U8G2_SRC ../../u8g2/csrc/*.c) 2 | 3 | idf_component_register(SRCS 4 | "../../main.c" 5 | "../../hid.c" 6 | "../../hidparser.c" 7 | "../../sysctrl.c" 8 | "../../sdc.c" 9 | "../../menu.c" 10 | "../../osd_u8g2.c" 11 | "../../inifile.c" 12 | "../../config.c" 13 | "../../at_wifi.c" 14 | "../../xml.c" 15 | "../mcu_hw.c" 16 | "../../puff.c" 17 | ${U8G2_SRC} 18 | ../../u8g2/sys/bitmap/common/u8x8_d_bitmap.c 19 | 20 | INCLUDE_DIRS 21 | "." 22 | ".." 23 | "../../u8g2/csrc" 24 | ) 25 | -------------------------------------------------------------------------------- /src/bl616/flash_prog_cfg.ini: -------------------------------------------------------------------------------- 1 | [cfg] 2 | # 0: no erase, 1:programmed section erase, 2: chip erase 3 | erase = 1 4 | # skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated 5 | skip_mode = 0x0, 0x0 6 | # 0: not use isp mode, #1: isp mode 7 | boot2_isp_mode = 0 8 | 9 | # for onboard BL616 configuration only 10 | #[official] 11 | #filedir = ./bl616_fpga_partner_20kNano.bin 12 | #filedir = ./bl616_fpga_partner_Console.bin 13 | #address = 0x0 14 | 15 | # activate [offical] section and change address below to 0x40000 for onboard BL616 configuration 16 | [FW] 17 | filedir = ./build/build_out/fpga_companion*_$(CHIPNAME).bin 18 | #address = 0x40000 19 | address = 0x0 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | build/ 55 | buildall/ 56 | managed_components/ 57 | dependencies.lock -------------------------------------------------------------------------------- /src/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef MENU_H 2 | #define MENU_H 3 | 4 | #include "osd.h" 5 | #include "sdc.h" 6 | 7 | #define MENU_EVENT_NONE 0 8 | #define MENU_EVENT_UP 1 9 | #define MENU_EVENT_DOWN 2 10 | #define MENU_EVENT_LEFT 3 11 | #define MENU_EVENT_RIGHT 4 12 | #define MENU_EVENT_SELECT 5 13 | #define MENU_EVENT_SHOW 6 14 | #define MENU_EVENT_HIDE 7 15 | #define MENU_EVENT_PGUP 8 16 | #define MENU_EVENT_PGDOWN 9 17 | #define MENU_EVENT_BACK 10 18 | #define MENU_EVENT_KEY_RELEASE 11 19 | 20 | typedef struct { 21 | char id; 22 | int value; 23 | } menu_variable_t; 24 | 25 | void menu_init(void); 26 | menu_variable_t **menu_get_variables(void); 27 | void menu_set_value(unsigned char id, unsigned char value); 28 | void menu_do(int); 29 | void menu_notify(unsigned long msg); 30 | 31 | #endif // MENU_H 32 | -------------------------------------------------------------------------------- /src/sdc.h: -------------------------------------------------------------------------------- 1 | #ifndef SDC_H 2 | #define SDC_H 3 | 4 | #include "config.h" 5 | #include 6 | #include // for DEV_SD 7 | 8 | // fatfs mounts the card under /sd 9 | #ifdef DEV_SD 10 | #define CARD_MOUNTPOINT "/sd" 11 | #else 12 | #define CARD_MOUNTPOINT "" 13 | #endif 14 | 15 | typedef struct { 16 | char *name; 17 | unsigned long len; 18 | int is_dir; 19 | } sdc_dir_entry_t; 20 | 21 | typedef struct { 22 | int len; 23 | sdc_dir_entry_t *files; 24 | } sdc_dir_t; 25 | 26 | int sdc_init(void); 27 | int sdc_image_open(int drive, char *name); 28 | sdc_dir_t *sdc_readdir(int drive, char *name, const char *exts); 29 | int sdc_handle_event(void); 30 | void sdc_lock(void); 31 | void sdc_unlock(void); 32 | char *sdc_get_image_name(int drive); 33 | char *sdc_get_cwd(int drive); 34 | void sdc_set_default(int drive, const char *name); 35 | void sdc_mount_defaults(void); 36 | 37 | #endif // SDC_H 38 | -------------------------------------------------------------------------------- /src/fatfs/source/00readme.txt: -------------------------------------------------------------------------------- 1 | FatFs Module Source Files R0.15 2 | 3 | 4 | FILES 5 | 6 | 00readme.txt This file. 7 | 00history.txt Revision history. 8 | ff.c FatFs module. 9 | ffconf.h Configuration file of FatFs module. 10 | ff.h Common include file for FatFs and application module. 11 | diskio.h Common include file for FatFs and disk I/O module. 12 | diskio.c An example of glue function to attach existing disk I/O module to FatFs. 13 | ffunicode.c Optional Unicode utility functions. 14 | ffsystem.c An example of optional O/S related functions. 15 | 16 | 17 | Low level disk I/O module is not included in this archive because the FatFs 18 | module is only a generic file system layer and it does not depend on any specific 19 | storage device. You need to provide a low level disk I/O module written to 20 | control the storage device that attached to the target system. 21 | 22 | -------------------------------------------------------------------------------- /src/fatfs/README.asc: -------------------------------------------------------------------------------- 1 | = FatFs 2 | 3 | This is a copy of FatFs, a "generic FAT file system module for small embedded 4 | systems", by ChaN. See http://elm-chan.org/fsw/ff/00index_e.html. 5 | 6 | Please submit bug reports to the http://elm-chan.org/fsw/ff/bd/[FatFs 7 | User Forum], not to this repo. 8 | 9 | == License 10 | 11 | Copyright (C) 2022, ChaN, all right reserved. 12 | 13 | FatFs module is an open source software. Redistribution and use of FatFs in 14 | source and binary forms, with or without modification, are permitted provided 15 | that the following condition is met: 16 | 17 | 1. Redistributions of source code must retain the above copyright notice, 18 | this condition and the following disclaimer. 19 | 20 | This software is provided by the copyright holder and contributors "AS IS" 21 | and any warranties related to this software are DISCLAIMED. 22 | The copyright owner or contributors be NOT LIABLE for any damages caused 23 | by use of this software. 24 | -------------------------------------------------------------------------------- /src/sysctrl.h: -------------------------------------------------------------------------------- 1 | /* 2 | sysctrl.h 3 | 4 | MiSTeryNano system control interface 5 | */ 6 | 7 | #ifndef SYS_CTRL_H 8 | #define SYS_CTRL_H 9 | 10 | #include 11 | #include 12 | #include "config.h" 13 | #include "spi.h" 14 | 15 | struct port_serial_status { 16 | uint32_t bitrate :24; 17 | uint8_t stopbits:2; 18 | uint8_t parity:2; 19 | uint8_t databits:4; 20 | } __attribute__((packed)); 21 | 22 | int sys_status_is_valid(void); 23 | void sys_set_leds(char); 24 | void sys_set_rgb(unsigned long); 25 | unsigned char sys_get_buttons(void); 26 | void sys_set_val(char, uint8_t); 27 | unsigned char sys_irq_ctrl(unsigned char); 28 | void sys_handle_interrupts(unsigned char, bool); 29 | bool sys_wait4fpga(void); 30 | char *sys_get_config(void); 31 | 32 | void sys_run_action(config_action_t *); 33 | void sys_run_action_by_name(char *); 34 | const char *sys_get_config_name(void); 35 | 36 | void sys_port_write(unsigned char, const unsigned char*, int); 37 | bool sys_port_get_status(unsigned char); 38 | 39 | #endif // SYS_CTRL_H 40 | -------------------------------------------------------------------------------- /src/hid.h: -------------------------------------------------------------------------------- 1 | /* hid.h */ 2 | 3 | #ifndef HID_H 4 | #define HID_H 5 | 6 | #include 7 | #include "hidparser.h" 8 | 9 | struct hid_kbd_state_S { 10 | unsigned char last_report[8]; 11 | }; 12 | 13 | struct hid_mouse_state_S { 14 | }; 15 | 16 | struct hid_joystick_state_S { 17 | unsigned char last_state; 18 | unsigned char js_index; 19 | int last_state_x; 20 | int last_state_y; 21 | unsigned char last_state_btn_extra; 22 | }; 23 | 24 | typedef union { 25 | struct hid_kbd_state_S kbd; 26 | struct hid_mouse_state_S mouse; 27 | struct hid_joystick_state_S joystick; 28 | } hid_state_t; 29 | 30 | void hid_parse(const hid_report_t *report, hid_state_t *state, uint8_t const* data, uint16_t len); 31 | 32 | void kbd_parse(const hid_report_t *report, struct hid_kbd_state_S *state, const unsigned char *buffer, int nbytes); 33 | void mouse_parse(const hid_report_t *report, struct hid_mouse_state_S *state, const unsigned char *buffer, int nbytes); 34 | void joystick_parse(const hid_report_t *report, struct hid_joystick_state_S *state, const unsigned char *buffer, int nbytes); 35 | 36 | void hid_handle_event(void); 37 | 38 | uint8_t hid_allocate_joystick(void); 39 | void hid_release_joystick(uint8_t idx); 40 | 41 | #endif // HID_H 42 | -------------------------------------------------------------------------------- /src/bl616/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for the MiSTeryNano firmware 2 | 3 | COMX?=/dev/m0s_debugger 4 | BAUDRATE?=2000000 5 | 6 | SDK_DEMO_PATH ?= . 7 | BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../.. 8 | 9 | CHIP ?= bl616 10 | BOARD ?= bl616dk 11 | TANG_BOARD ?= m0sdock 12 | CROSS_COMPILE ?= riscv64-unknown-elf- 13 | cmake_definition+=-DTANG_BOARD=$(TANG_BOARD) 14 | 15 | include $(BL_SDK_BASE)/project.build 16 | 17 | term: 18 | term.sh $(COMX) $(BAUDRATE) 19 | 20 | FATFS_SRC=$(BL_SDK_BASE)/components/fs/fatfs 21 | FATFS_FILES=$(FATFS_SRC)/ff.c $(FATFS_SRC)/diskio.c $(FATFS_SRC)/ffunicode.c 22 | 23 | MXML_SRC=mxml 24 | MXML_FILES=$(MXML_SRC)/mxml-attr.c $(MXML_SRC)/mxml-file.c $(MXML_SRC)/mxml-get.c $(MXML_SRC)/mxml-index.c $(MXML_SRC)/mxml-node.c $(MXML_SRC)/mxml-options.c $(MXML_SRC)/mxml-private.c $(MXML_SRC)/mxml-search.c $(MXML_SRC)/mxml-set.c 25 | 26 | SDL_TEST_CFLAGS=-I. -I$(FATFS_SRC) -I$(MXML_SRC) -Iu8g2/csrc `sdl2-config --cflags` -DSDL 27 | SDL_TEST_SRC=u8g2/csrc/*.c u8g2/sys/bitmap/common/*.c u8g2/sys/sdl/common/*.c 28 | 29 | sdl_menu_test: sdl_menu_test.c menu.c menu.h fatfs_conf_user.h $(FATFS_FILES) $(MXML_FILES) 30 | gcc $(SDL_TEST_CFLAGS) -o sdl_menu_test sdl_menu_test.c menu.c $(SDL_TEST_SRC) $(FATFS_FILES) $(MXML_FILES) `sdl2-config --libs` 31 | 32 | test: sdl_menu_test 33 | ./sdl_menu_test 34 | -------------------------------------------------------------------------------- /src/fatfs/documents/res/app1.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------/ 2 | / Open or create a file in append mode 3 | / (This function was sperseded by FA_OPEN_APPEND flag at FatFs R0.12a) 4 | /------------------------------------------------------------*/ 5 | 6 | FRESULT open_append ( 7 | FIL* fp, /* [OUT] File object to create */ 8 | const char* path /* [IN] File name to be opened */ 9 | ) 10 | { 11 | FRESULT fr; 12 | 13 | /* Opens an existing file. If not exist, creates a new file. */ 14 | fr = f_open(fp, path, FA_WRITE | FA_OPEN_ALWAYS); 15 | if (fr == FR_OK) { 16 | /* Seek to end of the file to append data */ 17 | fr = f_lseek(fp, f_size(fp)); 18 | if (fr != FR_OK) 19 | f_close(fp); 20 | } 21 | return fr; 22 | } 23 | 24 | 25 | int main (void) 26 | { 27 | FRESULT fr; 28 | FATFS fs; 29 | FIL fil; 30 | 31 | /* Open or create a log file and ready to append */ 32 | f_mount(&fs, "", 0); 33 | fr = open_append(&fil, "logfile.txt"); 34 | if (fr != FR_OK) return 1; 35 | 36 | /* Append a line */ 37 | f_printf(&fil, "%02u/%02u/%u, %2u:%02u\n", Mday, Mon, Year, Hour, Min); 38 | 39 | /* Close the file */ 40 | f_close(&fil); 41 | 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/hidparser.h: -------------------------------------------------------------------------------- 1 | #ifndef HIDPARSER_H 2 | #define HIDPARSER_H 3 | 4 | #include 5 | 6 | #define REPORT_TYPE_NONE 0 7 | #define REPORT_TYPE_MOUSE 1 8 | #define REPORT_TYPE_KEYBOARD 2 9 | #define REPORT_TYPE_JOYSTICK 3 10 | 11 | #define MAX_AXES 4 12 | 13 | // currently only joysticks are supported 14 | typedef struct { 15 | uint8_t type: 2; // REPORT_TYPE_... 16 | uint8_t report_id_present: 1; // REPORT_TYPE_... 17 | uint8_t report_id; 18 | uint8_t report_size; 19 | 20 | union { 21 | struct { 22 | struct { 23 | uint16_t offset; 24 | uint8_t size; 25 | struct { 26 | uint16_t min; 27 | uint16_t max; 28 | } logical; 29 | } axis[MAX_AXES]; // x and y axis + wheel or right hat 30 | 31 | struct { 32 | uint8_t byte_offset; 33 | uint8_t bitmask; 34 | } button[12]; // 12 buttons max 35 | 36 | struct { 37 | uint16_t offset; 38 | uint8_t size; 39 | struct { 40 | uint16_t min; 41 | uint16_t max; 42 | } logical; 43 | struct { 44 | uint16_t min; 45 | uint16_t max; 46 | } physical; 47 | } hat; // 1 hat (joystick only) 48 | } joystick_mouse; 49 | }; 50 | } hid_report_t; 51 | 52 | bool parse_report_descriptor(const uint8_t *rep, uint16_t rep_size, hid_report_t *conf, uint16_t *rbytes); 53 | 54 | #endif // HIDPARSER_H 55 | -------------------------------------------------------------------------------- /src/puff.h: -------------------------------------------------------------------------------- 1 | /* puff.h 2 | Copyright (C) 2002-2013 Mark Adler, all rights reserved 3 | version 2.3, 21 Jan 2013 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the author be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | 21 | Mark Adler madler@alumni.caltech.edu 22 | */ 23 | 24 | 25 | /* 26 | * See puff.c for purpose and usage. 27 | */ 28 | #ifndef NIL 29 | # define NIL ((unsigned char *)0) /* for no output option */ 30 | #endif 31 | 32 | int puff(unsigned char *dest, /* pointer to destination pointer */ 33 | unsigned long *destlen, /* amount of output space */ 34 | unsigned char (*source)(void), /* function to read input */ 35 | unsigned long *sourcelen); /* amount of input available */ 36 | -------------------------------------------------------------------------------- /src/fatfs/documents/res/app5.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------/ 2 | / Test if the file is contiguous / 3 | /----------------------------------------------------------------------*/ 4 | 5 | FRESULT test_contiguous_file ( 6 | FIL* fp, /* [IN] Open file object to be checked */ 7 | int* cont /* [OUT] 1:Contiguous, 0:Fragmented or zero-length */ 8 | ) 9 | { 10 | DWORD clst, clsz, step; 11 | FSIZE_t fsz; 12 | FRESULT fr; 13 | 14 | 15 | *cont = 0; 16 | fr = f_rewind(fp); /* Validates and prepares the file */ 17 | if (fr != FR_OK) return fr; 18 | 19 | #if FF_MAX_SS == FF_MIN_SS 20 | clsz = (DWORD)fp->obj.fs->csize * FF_MAX_SS; /* Cluster size */ 21 | #else 22 | clsz = (DWORD)fp->obj.fs->csize * fp->obj.fs->ssize; 23 | #endif 24 | fsz = f_size(fp); 25 | if (fsz > 0) { 26 | clst = fp->obj.sclust - 1; /* A cluster leading the first cluster for first test */ 27 | while (fsz) { 28 | step = (fsz >= clsz) ? clsz : (DWORD)fsz; 29 | fr = f_lseek(fp, f_tell(fp) + step); /* Advances file pointer a cluster */ 30 | if (fr != FR_OK) return fr; 31 | if (clst + 1 != fp->clust) break; /* Is not the cluster next to previous one? */ 32 | clst = fp->clust; fsz -= step; /* Get current cluster for next test */ 33 | } 34 | if (fsz == 0) *cont = 1; /* All done without fail? */ 35 | } 36 | 37 | return FR_OK; 38 | } 39 | -------------------------------------------------------------------------------- /src/mcu_hw.h: -------------------------------------------------------------------------------- 1 | #ifndef MCU_HW_H 2 | #define MCU_HW_H 3 | 4 | #include 5 | #include 6 | 7 | #define LOGO "\r\n\r\n\033[1;33m"\ 8 | " __ __ _ ____ _____ _\r\n"\ 9 | " | \\/ (_) ___|_ _| | ___\r\n"\ 10 | " | |\\/| | \\___ \\ | | | |/ o_)\r\n"\ 11 | " |_| |_|_|____/ |_| |_|\\___|\033[0m\r\n"\ 12 | " \033[1;36mhttp://github.com/MiSTle-Dev\033[0m\r\n" 13 | 14 | void mcu_hw_init(void); 15 | void mcu_hw_main_loop(void); 16 | 17 | void mcu_hw_irq_ack(void); 18 | void mcu_hw_reset(void); 19 | 20 | // HW SPI interface 21 | void mcu_hw_spi_begin(void); 22 | unsigned char mcu_hw_spi_tx_u08(unsigned char b); 23 | void mcu_hw_spi_end(void); 24 | 25 | // received a byte via the io port (e.g. rs232 from core) 26 | void mcu_hw_port_byte(unsigned char); 27 | 28 | void mcu_hw_wifi_scan(void); 29 | void mcu_hw_wifi_connect(char *ssid, char *key); 30 | void mcu_hw_tcp_connect(char *ip, int port); 31 | void mcu_hw_tcp_disconnect(void); 32 | bool mcu_hw_tcp_data(unsigned char byte); 33 | 34 | // some boards provide a connection to the FPGAs JTAG interface 35 | // currently only the Dev20k 36 | #if MISTLE_BOARD == 4 37 | void mcu_hw_jtag_set_pins(uint8_t dir, uint8_t data); 38 | uint8_t mcu_hw_jtag_tms(uint8_t tdi, uint8_t data, int len); 39 | void mcu_hw_jtag_data(uint8_t *txd, uint8_t *rxd, int len); 40 | void mcu_hw_fpga_reconfig(bool state); 41 | 42 | // this board also has the ability to boot the FPGA from SD card 43 | #include "sdc_direct.h" 44 | #define FPGA_BOOT_TIMEOUT 5000 // give FPGA 5 seconds to boot 45 | #define BOOT_FROM_SDC sdc_boot // afterwards this will be called 46 | 47 | // give file system driver in sdc.c access to the local sd card 48 | #define SDC_DIRECT_READ sdc_direct_read 49 | #define SDC_DIRECT_WRITE sdc_direct_write 50 | 51 | #endif 52 | 53 | #endif // MCU_HW_H 54 | -------------------------------------------------------------------------------- /src/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | 4 | #include 5 | 6 | #define debugf(x, ...) printf(x "\r\n", ##__VA_ARGS__) 7 | 8 | #define ini_debugf(a, ...) debugf("\033[0;31mINI: " a "\033[0m", ##__VA_ARGS__) // red 9 | #define sys_debugf(a, ...) debugf("\033[0;32mSYS: " a "\033[0m", ##__VA_ARGS__) // green 10 | #define sdc_debugf(a, ...) debugf("\033[0;33mSDC: " a "\033[0m", ##__VA_ARGS__) // yellow 11 | // #define usb_debugf(a, ...) debugf("\033[0;34mUSB: " a "\033[0m", ##__VA_ARGS__) // blue -> too dark to read 12 | #define usb_debugf(a, ...) debugf("\033[0;36mUSB: " a "\033[0m", ##__VA_ARGS__) // cyan 13 | #define hidp_debugf(a, ...) debugf("\033[0;35mHDP: " a "\033[0m", ##__VA_ARGS__) // magenta 14 | #define osd_debugf(a, ...) debugf("\033[0;36mOSD: " a "\033[0m", ##__VA_ARGS__) // cyan 15 | #define menu_debugf(a, ...) debugf("\033[1;33mMNU: " a "\033[0m", ##__VA_ARGS__) // bold yellow 16 | #define jtag_debugf(a, ...) debugf("\033[0;32mJTAG: " a "\033[0m", ##__VA_ARGS__) // green 17 | #define jtag_highlight_debugf(a, ...) debugf("\033[1;32mJTAG: " a "\033[0m", ##__VA_ARGS__) // bold green 18 | #define fatal_debugf(a, ...) debugf("\033[1;31mFATAL: " a "\033[0m", ##__VA_ARGS__) // bold red 19 | 20 | #include 21 | static inline void hexdump(const void *data, int size) { 22 | int i, b2c; 23 | int n=0; 24 | char *ptr = (char*)data; 25 | 26 | if(!size) return; 27 | 28 | while(size>0) { 29 | printf("%04x: ", n); 30 | 31 | b2c = (size>16)?16:size; 32 | for(i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_error 10 | 11 | 12 | 13 | 14 |
15 |

f_error

16 |

The f_error tests for an error on a file.

17 |
18 | int f_error (
19 |   FIL* fp   /* [IN] File object */
20 | );
21 | 
22 |
23 | 24 | 25 |
26 |

Parameters

27 |
28 |
fp
29 |
Pointer to the open file object structure.
30 |
31 |
32 | 33 | 34 |
35 |

Return Values

36 |

Returns a non-zero value if a hard error has occured; otherwise it returns a zero.

37 |
38 | 39 | 40 |
41 |

Description

42 |

In this revision, this function is implemented as a macro. It does not have any validation and mutual exclusion.

43 |
44 | #define f_error(fp) ((fp)->err)
45 | 
46 |
47 | 48 | 49 |
50 |

QuickInfo

51 |

Always available.

52 |
53 | 54 | 55 |
56 |

See Also

57 |

f_open, FIL

58 |
59 | 60 |

Return

61 | 62 | 63 | -------------------------------------------------------------------------------- /DEBUGGING.md: -------------------------------------------------------------------------------- 1 | # Debugging the FPGA Companion 2 | 3 | The FPGA Companion may not act as expected and e.g. may not detect or 4 | accept USB devices. In this case the serial debug output of the 5 | FPGA Companion may be helpful. 6 | 7 | All currently supported MCUs do some debug output on one of the MCUs 8 | pins although with different serial speeds. The Raspberry Pi Pico or 9 | Pico-W use 921600 bit/s, the Waveshare RP2040 Zero uses 460800 bit/s, 10 | the ESP32 uses 115200 bit/s and the BL616 uses 2000000 bit/s. 11 | 12 | The output is similar in all cases: 13 | 14 | ``` 15 | __ __ _ ___ _____ _ _ 16 | | \/ (_) __|_ _|__ _ _ _ _| \| |__ _ _ _ ___ 17 | | |\/| | \__ \ | |/ -_) '_| || | .` / _` | ' \/ _ \ 18 | |_| |_|_|___/ |_|\___|_| \_, |_|\_\__,_|_||_\___/ 19 | |__/ 20 | FPGA Companion for RP2040/RP2350 21 | 22 | USB D+/D- on GP2 and GP3 23 | Initializing SPI 24 | MISO = 16 25 | SCK = 18 26 | MOSI = 19 27 | CSn = 17 28 | IRQn = 22 29 | LED MOUSE = GP4 30 | LED KEYBOARD = GP5 31 | LED JOYSTICK = GP6 32 | Total heap: 34272 33 | Free heap: 34208 34 | Starting main communication task 35 | SYS: Waiting for FPGA to become ready 36 | WiFi init task ... 37 | Detected Pico-W 38 | WiFi initialised 39 | STA mode enabled 40 | USB: [24ae:1001][1] HID Interface0, Protocol = Keyboard 41 | USB: Using HID entry 0 42 | HDP: USAGE_PAGE(1/0x1) 43 | HDP: -> Generic Desktop 44 | HDP: USAGE(6/0x6) 45 | HDP: -> Keyboard 46 | HDP: COLLECTION(1) 47 | ... 48 | ``` 49 | 50 | During usage further information may be printed. Some additional debug 51 | statements may be enabled in the code. Some debug output is suppressed 52 | to not slow the FPGA Companion down too much. 53 | 54 | The output actually uses ANSI color and should look like this on a 55 | terminal supporting that: 56 | 57 | ![Debug output in terminal](debug.png) 58 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/size.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_size 10 | 11 | 12 | 13 | 14 |
15 |

f_size

16 |

The f_size function gets the size of a file.

17 |
18 | FSIZE_t f_size (
19 |   FIL* fp   /* [IN] File object */
20 | );
21 | 
22 |
23 | 24 | 25 |
26 |

Parameters

27 |
28 |
fp
29 |
Pointer to the open file object structure.
30 |
31 |
32 | 33 | 34 |
35 |

Return Values

36 |

Returns the size of the file in unit of byte.

37 |
38 | 39 | 40 |
41 |

Description

42 |

In this revision, the f_size function is implemented as a macro. It does not have any validation and mutual exclusion.

43 |
44 | #define f_size(fp) ((fp)->obj.objsize)
45 | 
46 |
47 | 48 | 49 |
50 |

QuickInfo

51 |

Always available.

52 |
53 | 54 | 55 |
56 |

See Also

57 |

f_open, f_lseek, FIL

58 |
59 | 60 |

Return

61 | 62 | 63 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/tell.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_tell 10 | 11 | 12 | 13 | 14 |
15 |

f_tell

16 |

The f_tell function gets the current read/write pointer of a file.

17 |
18 | FSIZE_t f_tell (
19 |   FIL* fp   /* [IN] File object */
20 | );
21 | 
22 |
23 | 24 | 25 |
26 |

Parameters

27 |
28 |
fp
29 |
Pointer to the open file object structure.
30 |
31 |
32 | 33 | 34 |
35 |

Return Values

36 |

Returns current read/write pointer of the file.

37 |
38 | 39 | 40 |
41 |

Description

42 |

In this revision, the f_tell function is implemented as a macro. It does not have any validation and mutual exclusion.

43 |
44 | #define f_tell(fp) ((fp)->fptr)
45 | 
46 |
47 | 48 | 49 |
50 |

QuickInfo

51 |

Always available.

52 |
53 | 54 | 55 |
56 |

See Also

57 |

f_open, f_lseek, FIL

58 |
59 | 60 |

Return

61 | 62 | 63 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/eof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_eof 10 | 11 | 12 | 13 | 14 |
15 |

f_eof

16 |

The f_eof function tests for end-of-file on a file.

17 |
18 | int f_eof (
19 |   FIL* fp   /* [IN] File object */
20 | );
21 | 
22 |
23 | 24 | 25 |
26 |

Parameters

27 |
28 |
fp
29 |
Pointer to the open file object structure.
30 |
31 |
32 | 33 | 34 |
35 |

Return Values

36 |

The f_eof function returns a non-zero value if the read/write pointer has reached end of the file; otherwise it returns a zero.

37 |
38 | 39 | 40 |
41 |

Description

42 |

In this revision, this function is implemented as a macro. It does not have any validation and mutual exclusion.

43 |
44 | #define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
45 | 
46 |
47 | 48 | 49 |
50 |

QuickInfo

51 |

Always available.

52 |
53 | 54 | 55 |
56 |

See Also

57 |

f_open, f_lseek, FIL

58 |
59 | 60 |

Return

61 | 62 | 63 | -------------------------------------------------------------------------------- /src/fatfs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | FatFs License 2 | 3 | FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files. 4 | 5 | /*----------------------------------------------------------------------------/ 6 | / FatFs - Generic FAT Filesystem Module Rx.xx / 7 | /-----------------------------------------------------------------------------/ 8 | / 9 | / Copyright (C) 20xx, ChaN, all right reserved. 10 | / 11 | / FatFs module is an open source software. Redistribution and use of FatFs in 12 | / source and binary forms, with or without modification, are permitted provided 13 | / that the following condition is met: 14 | / 15 | / 1. Redistributions of source code must retain the above copyright notice, 16 | / this condition and the following disclaimer. 17 | / 18 | / This software is provided by the copyright holder and contributors "AS IS" 19 | / and any warranties related to this software are DISCLAIMED. 20 | / The copyright owner or contributors be NOT LIABLE for any damages caused 21 | / by use of this software. 22 | /----------------------------------------------------------------------------*/ 23 | 24 | Therefore FatFs license is one of the BSD-style licenses, but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, do not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses include GNU GPL. When you redistribute the FatFs source code with changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license. 25 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/dinit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - disk_initialize 10 | 11 | 12 | 13 | 14 |
15 |

disk_initialize

16 |

The disk_initialize function is called to initializes the storage device.

17 |
18 | DSTATUS disk_initialize (
19 |   BYTE pdrv           /* [IN] Physical drive number */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
pdrv
28 |
Physical drive number to identify the target device. Always zero at single drive system.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

This function returns the current drive status flags as the result. For details of the drive status, refer to the disk_status function.

36 |
37 | 38 |
39 |

Description

40 |

This function initializes the storage device and put it ready to generic read/write. When the function succeeded, STA_NOINIT flag in the return value is cleared.

41 |

Remarks: This function needs to be under control of FatFs module. Application program MUST NOT call this function while FatFs is in use, or FAT structure on the volume can be broken. To re-initialize the filesystem, use f_mount function instead.

42 |
43 | 44 |

Return

45 | 46 | 47 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/sdir.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - DIR 10 | 11 | 12 | 13 | 14 |
15 |

DIR

16 |

The DIR structure is used for the work area to read a directory by f_oepndir, f_readdir, f_findfirst and f_findnext function. Application program must not modify any member in this structure, or f_readdir function will not work properly.

17 |
18 | typedef struct {
19 |     FFOBJID obj;        /* Object identifier */
20 |     DWORD   dptr;       /* Current read/write offset */
21 |     DWORD   clust;      /* Current cluster */
22 |     LBA_t   sect;       /* Current sector */
23 |     BYTE*   dir;        /* Pointer to the current SFN entry in the win[] */
24 |     BYTE*   fn;         /* Pointer to the SFN buffer (in/out) {file[8],ext[3],status[1]} */
25 | #if FF_USE_LFN
26 |     DWORD   blk_ofs;    /* Offset of the entry block (0xFFFFFFFF:Invalid) */
27 |     WCHAR*  lfn;        /* Pointer to the LFN working buffer (in/out) */
28 | #endif
29 | #if FF_USE_FIND
30 |     const TCHAR*  pat;  /* Ponter to the matching pattern */
31 | #endif
32 | } DIR;
33 | 
34 |
35 | 36 |

Return

37 | 38 | 39 | -------------------------------------------------------------------------------- /src/spi.h: -------------------------------------------------------------------------------- 1 | #ifndef SPI_H 2 | #define SPI_H 3 | 4 | #ifndef ESP_PLATFORM 5 | #include 6 | #include 7 | #include 8 | #include 9 | #endif 10 | 11 | #define SPI_TARGET_SYS 0 // system control target 12 | #define SPI_SYS_STATUS 0 13 | #define SPI_SYS_LEDS 1 14 | #define SPI_SYS_RGB 2 15 | #define SPI_SYS_BUTTONS 3 16 | #define SPI_SYS_SETVAL 4 17 | #define SPI_SYS_IRQ_CTRL 5 18 | #define SPI_SYS_IRQ_SRC 6 19 | #define SPI_SYS_PORT 7 20 | #define SPI_SYS_READ_CFG 8 21 | 22 | // port subcommands 23 | #define SPI_SYS_PORT_STATUS 0 24 | #define SPI_SYS_PORT_GET 1 25 | #define SPI_SYS_PORT_PUT 2 26 | 27 | #define SPI_TARGET_HID 1 // human interface devices 28 | #define SPI_HID_STATUS 0 29 | #define SPI_HID_KEYBOARD 1 30 | #define SPI_HID_MOUSE 2 31 | #define SPI_HID_JOYSTICK 3 32 | #define SPI_HID_GET_DB9 4 33 | 34 | #define SPI_TARGET_OSD 2 // on-screen-display 35 | #define SPI_OSD_ENABLE 1 36 | #define SPI_OSD_WRITE 2 37 | 38 | #define SPI_TARGET_SDC 3 // sd card 39 | #define SPI_SDC_STATUS 1 // get sd card status 40 | #define SPI_SDC_CORE_RW 2 // trigger core read/write 41 | #define SPI_SDC_MCU_READ 3 // read sector into MCU (e.g. for dir listing) 42 | #define SPI_SDC_INSERTED 4 // inform core that some disk image has been insered 43 | #define SPI_SDC_MCU_WRITE 5 // write sector from MCU 44 | #define SPI_SDC_DIRECT 6 // inform core that disk image may direclty be accessed 45 | #define SPI_SDC_INS_LARGE 7 // inform core that some large disk image > 4GB has been insered 46 | #define SPI_SDC_IMAGE 8 // read rom image command 47 | 48 | // image subcommands 49 | #define SPI_SDC_IMAGE_STATUS 0 50 | #define SPI_SDC_IMAGE_SELECT 1 51 | #define SPI_SDC_IMAGE_WRITE 2 52 | 53 | #define SPI_TARGET_AUDIO 4 // audio (e.g. to play fake floppy sounds) 54 | #define SPI_AUDIO_ENABLE 1 55 | #define SPI_AUDIO_BUFFER 2 // return audio buffer usage 56 | #define SPI_AUDIO_WRITE 3 57 | 58 | // this is still on usb_host.c but should eventially go 59 | // into a separate hid.c 60 | extern void hid_handle_event(void); 61 | 62 | #endif // SPI_H 63 | -------------------------------------------------------------------------------- /src/fatfs/documents/res/app6.c: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------*/ 2 | /* Raw Read/Write Throughput Checker */ 3 | /*---------------------------------------------------------------------*/ 4 | 5 | #include 6 | #include 7 | #include "diskio.h" 8 | #include "ff.h" 9 | 10 | 11 | int test_raw_speed ( 12 | BYTE pdrv, /* Physical drive number */ 13 | DWORD lba, /* Start LBA for read/write test */ 14 | DWORD len, /* Number of bytes to read/write (must be multiple of sz_buff) */ 15 | void* buff, /* Read/write buffer */ 16 | UINT sz_buff /* Size of read/write buffer (must be multiple of FF_MAX_SS) */ 17 | ) 18 | { 19 | WORD ss; 20 | DWORD ofs, tmr; 21 | 22 | 23 | #if FF_MIN_SS != FF_MAX_SS 24 | if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) { 25 | printf("\ndisk_ioctl() failed.\n"); 26 | return 0; 27 | } 28 | #else 29 | ss = FF_MAX_SS; 30 | #endif 31 | 32 | printf("Starting raw write test at sector %lu in %u bytes of data chunks...", lba, sz_buff); 33 | tmr = systimer(); 34 | for (ofs = 0; ofs < len / ss; ofs += sz_buff / ss) { 35 | if (disk_write(pdrv, buff, lba + ofs, sz_buff / ss) != RES_OK) { 36 | printf("\ndisk_write() failed.\n"); 37 | return 0; 38 | } 39 | } 40 | if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) { 41 | printf("\ndisk_ioctl() failed.\n"); 42 | return 0; 43 | } 44 | tmr = systimer() - tmr; 45 | printf("\n%lu bytes written and it took %lu timer ticks.\n", len, tmr); 46 | 47 | printf("Starting raw read test at sector %lu in %u bytes of data chunks...", lba, sz_buff); 48 | tmr = systimer(); 49 | for (ofs = 0; ofs < len / ss; ofs += sz_buff / ss) { 50 | if (disk_read(pdrv, buff, lba + ofs, sz_buff / ss) != RES_OK) { 51 | printf("\ndisk_read() failed.\n"); 52 | return 0; 53 | } 54 | } 55 | tmr = systimer() - tmr; 56 | printf("\n%lu bytes read and it took %lu timer ticks.\n", len, tmr); 57 | 58 | printf("Test completed.\n"); 59 | return 1; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/truncate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_truncate 10 | 11 | 12 | 13 | 14 |
15 |

f_truncate

16 |

The f_truncate function truncates the file size.

17 |
18 | FRESULT f_truncate (
19 |   FIL* fp     /* [IN] File object */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
fp
28 |
Pointer to the open file object to be truncated.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_DENIED, 40 | FR_INVALID_OBJECT, 41 | FR_TIMEOUT 42 |

43 |
44 | 45 | 46 |
47 |

Description

48 |

The f_truncate function truncates the file size to the current file read/write pointer. This function has no effect if the file read/write pointer is already pointing end of the file.

49 |
50 | 51 | 52 |
53 |

QuickInfo

54 |

Available when FF_FS_READONLY == 0 and FF_FS_MINIMIZE == 0.

55 |
56 | 57 | 58 |
59 |

See Also

60 |

f_open, f_lseek, FIL

61 |
62 | 63 | 64 |

Return

65 | 66 | 67 | -------------------------------------------------------------------------------- /src/rp2040/ws2812.pio.h: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------- // 2 | // This file is autogenerated by pioasm; do not edit! // 3 | // -------------------------------------------------- // 4 | 5 | #pragma once 6 | 7 | #if !PICO_NO_HARDWARE 8 | #include "hardware/pio.h" 9 | #endif 10 | 11 | // ------ // 12 | // ws2812 // 13 | // ------ // 14 | 15 | #define ws2812_wrap_target 0 16 | #define ws2812_wrap 3 17 | #define ws2812_pio_version 0 18 | 19 | #define ws2812_T1 2 20 | #define ws2812_T2 5 21 | #define ws2812_T3 3 22 | 23 | static const uint16_t ws2812_program_instructions[] = { 24 | // .wrap_target 25 | 0x6221, // 0: out x, 1 side 0 [2] 26 | 0x1123, // 1: jmp !x, 3 side 1 [1] 27 | 0x1400, // 2: jmp 0 side 1 [4] 28 | 0xa442, // 3: nop side 0 [4] 29 | // .wrap 30 | }; 31 | 32 | #if !PICO_NO_HARDWARE 33 | static const struct pio_program ws2812_program = { 34 | .instructions = ws2812_program_instructions, 35 | .length = 4, 36 | .origin = -1, 37 | // .pio_version = 0, 38 | #if PICO_PIO_VERSION > 0 39 | .used_gpio_ranges = 0x0 40 | #endif 41 | }; 42 | 43 | static inline pio_sm_config ws2812_program_get_default_config(uint offset) { 44 | pio_sm_config c = pio_get_default_sm_config(); 45 | sm_config_set_wrap(&c, offset + ws2812_wrap_target, offset + ws2812_wrap); 46 | sm_config_set_sideset(&c, 1, false, false); 47 | return c; 48 | } 49 | 50 | #include "hardware/clocks.h" 51 | static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) { 52 | pio_gpio_init(pio, pin); 53 | pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true); 54 | pio_sm_config c = ws2812_program_get_default_config(offset); 55 | sm_config_set_sideset_pins(&c, pin); 56 | sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24); 57 | sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); 58 | int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3; 59 | float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit); 60 | sm_config_set_clkdiv(&c, div); 61 | pio_sm_init(pio, sm, offset, &c); 62 | pio_sm_set_enabled(pio, sm, true); 63 | } 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/closedir.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_closedir 10 | 11 | 12 | 13 | 14 |
15 |

f_closedir

16 |

The f_closedir function closes an open directory.

17 |
18 | FRESULT f_closedir (
19 |   DIR* dp     /* [IN] Pointer to the directory object */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
dp
28 |
Pointer to the open directory object structure to be closed.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_INT_ERR, 38 | FR_INVALID_OBJECT, 39 | FR_TIMEOUT 40 |

41 |
42 | 43 | 44 |
45 |

Description

46 |

The f_closedir function closes an open directory object. After the function succeeded, the directory object is no longer valid and it can be discarded.

47 |

Note that the directory object can also be discarded without this procedure when option FF_FS_LOCK is not enabled. However this is not recommended for future compatibility.

48 |
49 | 50 | 51 |
52 |

QuickInfo

53 |

Available when FF_FS_MINIMIZE <= 1.

54 |
55 | 56 | 57 |
58 |

See Also

59 |

f_opendir, f_readdir, DIR

60 |
61 | 62 |

Return

63 | 64 | 65 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/close.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_close 10 | 11 | 12 | 13 | 14 |
15 |

f_close

16 |

The f_close function closes an open file.

17 |
18 | FRESULT f_close (
19 |   FIL* fp     /* [IN] Pointer to the file object */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
fp
28 |
Pointer to the open file object structure to be closed.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_INVALID_OBJECT, 40 | FR_TIMEOUT 41 |

42 |
43 | 44 | 45 |
46 |

Description

47 |

The f_close function closes an open file object. If the file has been changed, the cached information of the file is written back to the volume. After the function succeeded, the file object is no longer valid and it can be discarded.

48 |

Note that if the file object is in read-only mode and FF_FS_LOCK is not enabled, the file object can also be discarded without this procedure. However this is not recommended for future compatibility.

49 |
50 | 51 | 52 |
53 |

QuickInfo

54 |

Always available.

55 |
56 | 57 | 58 |
59 |

See Also

60 |

f_open, f_read, f_write, f_sync, FIL, FATFS

61 |
62 | 63 |

Return

64 | 65 | 66 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/dstat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - disk_status 10 | 11 | 12 | 13 | 14 |
15 |

disk_status

16 |

The disk_status function is called to inquire the current drive status.

17 |
18 | DSTATUS disk_status (
19 |   BYTE pdrv     /* [IN] Physical drive number */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
pdrv
28 |
Physical drive number to identify the target device. Always zero in single drive system.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

The current drive status is returned in combination of status flags described below. FatFs refers only STA_NOINIT and STA_PROTECT.

36 |
37 |
STA_NOINIT
38 |
Indicates that the device has not been initialized and not ready to work. This flag is set on system reset, media removal or failure of disk_initialize function. It is cleared on disk_initialize function succeeded. Any media change that occurs asynchronously must be captured and reflect it to the status flags, or auto-mount function will not work correctly. If the system does not support media change detection, application program needs to explicitly re-mount the volume with f_mount function after each media change.
39 |
STA_NODISK
40 |
Indicates that no medium in the drive. This is always cleared when the drive is non-removable class. Note that FatFs does not refer this flag.
41 |
STA_PROTECT
42 |
Indicates that the medium is write protected. This is always cleared when the drive has no write protect function. Not valid if STA_NODISK is set.
43 |
44 |
45 | 46 |

Return

47 | 48 | 49 | -------------------------------------------------------------------------------- /src/bl616/buildall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enabledelayedexpansion 3 | 4 | REM Create buildall directory if it doesn't exist 5 | if not exist buildall mkdir buildall 6 | del /Q buildall\* 7 | 8 | REM List of boards to build 9 | set "boards=m0sdock nano20k console60k primer25k mega138kpro mega60k" 10 | @REM set "boards=m0sdock nano20k console60k mega60k mega138kpro primer25k" 11 | 12 | for %%b in (%boards%) do ( 13 | echo Building for board: %%b 14 | 15 | REM Clean previous build 16 | make clean 17 | 18 | REM Set board environment variable and build 19 | set "TANG_BOARD=%%b" 20 | make ninja 21 | 22 | if !errorlevel! equ 0 ( 23 | echo Build successful for %%b 24 | 25 | REM Copy and rename the binary files 26 | copy /Y build\build_out\fpga_companion_bl616.bin buildall\fpga_companion_%%b.bin 27 | if "%%b"=="console60k" ( 28 | copy /Y bl616_fpga_partner\bl616_fpga_partner_Console.bin buildall\bl616_fpga_partner_%%b.bin 29 | ) else if "%%b"=="mega60k" ( 30 | copy /Y bl616_fpga_partner\bl616_fpga_partner_NeoDock.bin buildall\bl616_fpga_partner_%%b.bin 31 | ) else if "%%b"=="mega138kpro" ( 32 | copy /Y bl616_fpga_partner\bl616_fpga_partner_138kproDock.bin buildall\bl616_fpga_partner_%%b.bin 33 | ) else if "%%b"=="primer25k" ( 34 | copy /Y bl616_fpga_partner\bl616_fpga_partner_25kDock.bin buildall\bl616_fpga_partner_%%b.bin 35 | ) else if "%%b"=="nano20k" ( 36 | copy /Y bl616_fpga_partner\bl616_fpga_partner_20kNano.bin buildall\bl616_fpga_partner_%%b.bin 37 | REM Copy unfused files 38 | copy /Y bl616_fpga_partner\friend_20k_bl616.bin buildall\friend_20k_bl616.bin 39 | copy /Y bl616_fpga_partner\friend_20k_cfg.ini buildall\friend_20k_cfg.ini 40 | copy /Y bl616_fpga_partner\flash_nano20k_unfused_cfg.ini buildall\flash_nano20k_unfused_cfg.ini 41 | ) 42 | if "%%b"=="m0sdock" ( 43 | copy /Y flash_m0sdock_cfg.ini buildall\flash_m0sdock_cfg.ini 44 | ) else ( 45 | powershell -Command "(Get-Content flash.ini) -replace 'bl616_fpga_partner.bin', 'bl616_fpga_partner_%%b.bin' -replace 'fpga_companion.bin', 'fpga_companion_%%b.bin' | Set-Content buildall\flash_%%b.ini" 46 | ) 47 | ) else ( 48 | echo Build failed for %%b 49 | ) 50 | ) 51 | 52 | REM List contents of buildall directory 53 | echo. 54 | echo Contents of buildall directory: 55 | dir /B buildall\ 56 | 57 | endlocal 58 | 59 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/chdrive.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_chdrive 10 | 11 | 12 | 13 | 14 |
15 |

f_chdrive

16 |

The f_chdrive function changes the current drive.

17 |
18 | FRESULT f_chdrive (
19 |   const TCHAR* path  /* [IN] Logical drive number */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameters

26 |
27 |
path
28 |
Specifies the logical drive number to be set as the current drive.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_INVALID_DRIVE 38 |

39 |
40 | 41 | 42 |
43 |

Description

44 |

The f_chdrive function changes only the current drive. The initial value of the current drive number is 0. In Unix style drive prefix configuration, this function will not be needed because f_chdir function changes also the current drive. Note that the current drive is retained in a static variable, so that it also affects other tasks that using the file functions.

45 |
46 | 47 |
48 |

QuickInfo

49 |

Available when FF_FS_RPATH >= 1.

50 |
51 | 52 | 53 |
54 |

Example

55 |
56 |     f_chdrive("2:");  /* Set drive 2 as current drive */
57 | 
58 |     f_chdrive("");    /* No effect (set current drive as current drive) */
59 | 
60 |
61 | 62 | 63 |
64 |

See Also

65 |

f_chdir, f_getcwd

66 |
67 | 68 |

Return

69 | 70 | 71 | -------------------------------------------------------------------------------- /src/fatfs/documents/res/app2.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------/ 2 | / Delete a sub-directory even if it contains any file 3 | /-------------------------------------------------------------/ 4 | / The delete_node() function is for R0.12+. 5 | / It works regardless of FF_FS_RPATH. 6 | */ 7 | 8 | 9 | FRESULT delete_node ( 10 | TCHAR* path, /* Path name buffer with the sub-directory to delete */ 11 | UINT sz_buff, /* Size of path name buffer (items) */ 12 | FILINFO* fno /* Name read buffer */ 13 | ) 14 | { 15 | UINT i, j; 16 | FRESULT fr; 17 | DIR dir; 18 | 19 | 20 | fr = f_opendir(&dir, path); /* Open the sub-directory to make it empty */ 21 | if (fr != FR_OK) return fr; 22 | 23 | for (i = 0; path[i]; i++) ; /* Get current path length */ 24 | path[i++] = _T('/'); 25 | 26 | for (;;) { 27 | fr = f_readdir(&dir, fno); /* Get a directory item */ 28 | if (fr != FR_OK || !fno->fname[0]) break; /* End of directory? */ 29 | j = 0; 30 | do { /* Make a path name */ 31 | if (i + j >= sz_buff) { /* Buffer over flow? */ 32 | fr = 100; break; /* Fails with 100 when buffer overflow */ 33 | } 34 | path[i + j] = fno->fname[j]; 35 | } while (fno->fname[j++]); 36 | if (fno->fattrib & AM_DIR) { /* Item is a sub-directory */ 37 | fr = delete_node(path, sz_buff, fno); 38 | } else { /* Item is a file */ 39 | fr = f_unlink(path); 40 | } 41 | if (fr != FR_OK) break; 42 | } 43 | 44 | path[--i] = 0; /* Restore the path name */ 45 | f_closedir(&dir); 46 | 47 | if (fr == FR_OK) fr = f_unlink(path); /* Delete the empty sub-directory */ 48 | return fr; 49 | } 50 | 51 | 52 | 53 | 54 | int main (void) /* How to use */ 55 | { 56 | FRESULT fr; 57 | FATFS fs; 58 | TCHAR buff[256]; 59 | FILINFO fno; 60 | 61 | 62 | f_mount(&fs, _T("5:"), 0); 63 | 64 | /* Directory to be deleted */ 65 | _tcscpy(buff, _T("5:dir")); 66 | 67 | /* Delete the directory */ 68 | fr = delete_node(buff, sizeof buff / sizeof buff[0], &fno); 69 | 70 | /* Check the result */ 71 | if (fr) { 72 | _tprintf(_T("Failed to delete the directory. (%u)\n"), fr); 73 | return fr; 74 | } else { 75 | _tprintf(_T("The directory and the contents have successfully been deleted.\n"), buff); 76 | return 0; 77 | } 78 | } 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/bl616/friend_20k/README.md: -------------------------------------------------------------------------------- 1 | # Friend 20K firmware 2 | 3 | This is the original firmware that came pre-installed with the BL616 4 | on the Tang Nano 20K. These files should allow you to return the board 5 | to factory state in case the firmware has been overwritten. 6 | 7 | There are two variants, the regular one and an encrypted one. Both 8 | provide a similar functionality. Sipeed decided to encrypt the 9 | firmware on boards sold about the beginning of 2024. These newer 10 | boards will not accept or run any non-encrypted firmware and replacing 11 | its default firmware will essentially brick the Tang Nano 20K. This 12 | encrypted firmware will allow restoring the newer boards to factory 13 | state as well and thus unbrick the device. 14 | 15 | It's currently unknown if the firmware versions can be identified 16 | beforehand. So you might have to try both of them and to check which 17 | one's the one working for your board. 18 | 19 | ## How to flash 20 | 21 | > [!IMPORTANT] 22 | > If your Tang Nano 20k shows up on USB as the FTDI FT2232 compatible 23 | > ```20k friend``` there is no need to flash it again. This is only 24 | > required if you replaced the firmware and now want to go back to 25 | > the factory state. 26 | 27 | You can flash either of these with the command line tool. To get the 28 | BL616 into firmware update mode, power the Tang Nano 20k up with the 29 | ```UPDATE``` (next to the HDMI connector) pressed. The BL616 will then 30 | identify itself as ```Bouffalo CDC DEMO``` and a virtual COM port 31 | will be created. Use the following commands to flash using the 32 | command line tool: 33 | 34 | ``` 35 | $ BLFlashCommand --interface=uart --baudrate=2000000 --port=/dev/ttyACM0 --chipname=bl616 --cpu_id= --config=friend_20k_cfg.ini 36 | ``` 37 | 38 | or 39 | 40 | ``` 41 | $ BLFlashCommand --interface=uart --baudrate=2000000 --port=/dev/ttyACM0 --chipname=bl616 --cpu_id= --config=friend_20k_encrypted_cfg.ini 42 | ``` 43 | 44 | Afterward power cycle the device, and it should show up as the ```20K's FRIEND``` friend 45 | again and work as normal. If it still shows up as the ```Bouffalo CDC DEMO``` then you 46 | most probably flashed the wrong version (encrypted onto an unencrypted device or 47 | vice versa). In that case you can simply flash the correct version. 48 | 49 | ## More information 50 | 51 | - [Information about the Tang Nano 20k variants](https://github.com/MiSTle-Dev/.github/wiki/Versions_TangNano20k) 52 | - [More details on how to flash the BL616](https://github.com/MiSTle-Dev/.github/wiki/Firmware-Installation-BL616-%C2%B5C). 53 | - [BL616 FPGA PARTNER firmware](../bl616_fpga_partner) 54 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/fattime.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - get_fattime 10 | 11 | 12 | 13 | 14 |
15 |

get_fattime

16 |

The get_fattime function is called to get the current time.

17 |
18 | DWORD get_fattime (void);
19 | 
20 |
21 | 22 | 23 |
24 |

Return Value

25 |

Currnet local time shall be returned as bit-fields packed into a DWORD value. The bit fields are as follows:

26 |
27 |
bit31:25
28 |
Year origin from the 1980 (0..127, e.g. 37 for 2017)
29 |
bit24:21
30 |
Month (1..12)
31 |
bit20:16
32 |
Day of the month (1..31)
33 |
bit15:11
34 |
Hour (0..23)
35 |
bit10:5
36 |
Minute (0..59)
37 |
bit4:0
38 |
Second / 2 (0..29, e.g. 25 for 50)
39 |
40 |
41 | 42 | 43 |
44 |

Description

45 |

The get_fattime function shall return any valid time even if the system does not support a real time clock. If a zero is returned, the file will not have a valid timestamp.

46 |
47 | 48 | 49 |
50 |

QuickInfo

51 |

This function is not needed when FF_FS_READONLY == 1 or FF_FS_NORTC == 1.

52 |
53 | 54 | 55 |
56 |

Example

57 |
58 | DWORD get_fattime (void)
59 | {
60 |     time_t t;
61 |     struct tm *stm;
62 | 
63 | 
64 |     t = time(0);
65 |     stm = localtime(&t);
66 | 
67 |     return (DWORD)(stm->tm_year - 80) << 25 |
68 |            (DWORD)(stm->tm_mon + 1) << 21 |
69 |            (DWORD)stm->tm_mday << 16 |
70 |            (DWORD)stm->tm_hour << 11 |
71 |            (DWORD)stm->tm_min << 5 |
72 |            (DWORD)stm->tm_sec >> 1;
73 | }
74 | 
75 |
76 | 77 | 78 |

Return

79 | 80 | 81 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/mkdir.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_mkdir 10 | 11 | 12 | 13 | 14 |
15 |

f_mkdir

16 |

The f_mkdir function creates a new directory.

17 |
18 | FRESULT f_mkdir (
19 |   const TCHAR* path /* [IN] Directory name */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
path
28 |
Pointer to the null-terminated string that specifies the directory name to create.
29 |
30 |
31 | 32 | 33 |
34 |

Return Value

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_NOT_READY, 40 | FR_NO_PATH, 41 | FR_INVALID_NAME, 42 | FR_DENIED, 43 | FR_EXIST, 44 | FR_WRITE_PROTECTED, 45 | FR_INVALID_DRIVE, 46 | FR_NOT_ENABLED, 47 | FR_NO_FILESYSTEM, 48 | FR_TIMEOUT, 49 | FR_NOT_ENOUGH_CORE 50 |

51 |
52 | 53 | 54 |
55 |

Description

56 |

This function creates a new directory. To remove a directory, use f_unlink function.

57 |
58 | 59 | 60 |
61 |

QuickInfo

62 |

Available when FF_FS_READONLY == 0 and FF_FS_MINIMIZE == 0.

63 |
64 | 65 | 66 |
67 |

Example

68 |
69 |     res = f_mkdir("sub1");
70 |     if (res) die(res);
71 |     res = f_mkdir("sub1/sub2");
72 |     if (res) die(res);
73 |     res = f_mkdir("sub1/sub2/sub3");
74 |     if (res) die(res);
75 | 
76 |
77 | 78 |

Return

79 | 80 | 81 | -------------------------------------------------------------------------------- /src/bl616/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | # Set C++ standard 4 | set(CMAKE_CXX_STANDARD 17) 5 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 6 | 7 | # Components 8 | set(CONFIG_FREERTOS 1) 9 | set(CONFIG_CHERRYUSB 1) 10 | set(CONFIG_CHERRYUSB_HOST 1) 11 | set(CONFIG_CHERRYUSB_DEVICE 1) 12 | set(CONFIG_CHERRYUSB_DEVICE_HID 1) 13 | set(CONFIG_PSRAM 0) 14 | set(CONFIG_FATFS 1) 15 | set(CONFIG_BFLOG 0) 16 | set(CONFIG_SHELL 1) 17 | set(CONFIG_CHERRYUSB_OSAL "freertos") 18 | set(CONFIG_CHERRYUSB_HOST_HCD "ehci_bouffalo") 19 | set(CONFIG_CHERRYUSB_HOST_HID 1) 20 | set(CONFIG_CHERRYMP 1) 21 | set(CONFIG_CHERRYRB 1) 22 | set(CONFIG_VSNPRINTF_FLOAT 1) 23 | set(CONFIG_VSNPRINTF_FLOAT_EX 1) 24 | set(CONFIG_VSNPRINTF_LONG_LONG 1) 25 | set(CONFIG_CLI_CMD_ENABLE 1) 26 | #set(CONFIG_CHERRYMP 1) 27 | #set(CONFIG_CHERRYRB 1) 28 | 29 | # wifi support 30 | set(CONFIG_LWIP 1) 31 | set(CONFIG_WIFI6 1) 32 | set(CONFIG_RF 1) 33 | set(CONFIG_MBEDTLS 1) 34 | set(CONFIG_DHCPD 1) 35 | set(CONFIG_POSIX 1) 36 | set(CONFIG_TLSF 1) 37 | set(CONFIG_PING 1) 38 | # mbedtls 39 | set(CONFIG_MBEDTLS_AES_USE_HW 1) 40 | set(CONFIG_MBEDTLS_BIGNUM_USE_HW 1) 41 | set(CONFIG_MBEDTLS_ECC_USE_HW 1) 42 | set(CONFIG_MBEDTLS_SHA1_USE_HW 1) 43 | set(CONFIG_MBEDTLS_SHA256_USE_HW 1) 44 | set(CONFIG_MBEDTLS_SHA512_USE_HW 1) 45 | # wifi 46 | set(CONFIG_VIF_MAX 2) 47 | set(CONFIG_STA_MAX 4) 48 | set(CONFIG_MAC_TXQ_DEPTH 32) 49 | set(CONFIG_MAC_RXQ_DEPTH 12) 50 | #set(CONFIG_WIFI_IPERF 1) 51 | 52 | if(TANG_BOARD STREQUAL "mega60k") 53 | add_definitions(-DTANG_MEGA60K) 54 | elseif(TANG_BOARD STREQUAL "mega138kpro") 55 | add_definitions(-DTANG_MEGA138KPRO) 56 | elseif(TANG_BOARD STREQUAL "console60k") 57 | add_definitions(-DTANG_CONSOLE60K) 58 | elseif(TANG_BOARD STREQUAL "console138k") 59 | add_definitions(-DTANG_CONSOLE138K) 60 | elseif(TANG_BOARD STREQUAL "primer25k") 61 | add_definitions(-DTANG_PRIMER25K) 62 | elseif(TANG_BOARD STREQUAL "nano20k") 63 | add_definitions(-DTANG_NANO20K) 64 | elseif(TANG_BOARD STREQUAL "m0sdock") 65 | add_definitions(-DM0S_DOCK) 66 | endif() 67 | 68 | find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) 69 | 70 | sdk_add_include_directories(. ../u8g2/csrc) 71 | 72 | target_sources(app PRIVATE 73 | mcu_hw.c 74 | ../hidparser.c 75 | ../hid.c 76 | ../inifile.c 77 | ../menu.c 78 | ../sdc.c 79 | ../osd_u8g2.c 80 | ../sysctrl.c 81 | ../config.c 82 | ../xml.c 83 | ../at_wifi.c 84 | ../puff.c 85 | hid_keyboard_template.c 86 | ) 87 | 88 | file(GLOB COMPONENT_SRCS ../u8g2/csrc/*.c ../u8g2/sys/bitmap/common/*.c) 89 | target_sources(app PRIVATE ${COMPONENT_SRCS}) 90 | 91 | sdk_set_main_file(../main.c) 92 | 93 | project(fpga_companion) 94 | #project(fpga_companion CXX) 95 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/opendir.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_opendir 10 | 11 | 12 | 13 | 14 |
15 |

f_opendir

16 |

The f_opendir function opens a directory.

17 |
18 | FRESULT f_opendir (
19 |   DIR* dp,           /* [OUT] Pointer to the directory object structure */
20 |   const TCHAR* path  /* [IN] Directory name */
21 | );
22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
dp
29 |
Pointer to the blank directory object to create a new one.
30 |
path
31 |
Pointer to the null-terminated string that specifies the directory name to be opened.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

39 | FR_OK, 40 | FR_DISK_ERR, 41 | FR_INT_ERR, 42 | FR_NOT_READY, 43 | FR_NO_PATH, 44 | FR_INVALID_NAME, 45 | FR_INVALID_OBJECT, 46 | FR_INVALID_DRIVE, 47 | FR_NOT_ENABLED, 48 | FR_NO_FILESYSTEM, 49 | FR_TIMEOUT, 50 | FR_NOT_ENOUGH_CORE, 51 | FR_TOO_MANY_OPEN_FILES 52 |

53 |
54 | 55 | 56 |
57 |

Description

58 |

The f_opendir function opens an exsisting directory and creates a directory object for subsequent f_readdir function.

59 |
60 | 61 | 62 |
63 |

QuickInfo

64 |

Available when FF_FS_MINIMIZE <= 1.

65 |
66 | 67 | 68 |
69 |

See Also

70 |

f_readdir, f_closedir, DIR

71 |
72 | 73 |

Return

74 | 75 | 76 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/findnext.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_findnext 10 | 11 | 12 | 13 | 14 |
15 |

f_findnext

16 |

The f_findnext function searches for a next matched object

17 |
18 | FRESULT f_findnext (
19 |   DIR* dp,              /* [IN] Poninter to the directory object */
20 |   FILINFO* fno          /* [OUT] Pointer to the file information structure */
21 | );
22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
dp
29 |
Pointer to the valid directory object created by f_findfirst function.
30 |
fno
31 |
Pointer to the file information structure to store the information about the found directory item.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

39 | FR_OK, 40 | FR_DISK_ERR, 41 | FR_INT_ERR, 42 | FR_NOT_READY, 43 | FR_INVALID_OBJECT, 44 | FR_TIMEOUT, 45 | FR_NOT_ENOUGH_CORE 46 |

47 |
48 | 49 | 50 |
51 |

Description

52 |

It continues the search from a previous call to the f_findfirst or f_findnext function. If found, the information about the object is stored into the file information structure. If no item to be read, a null string will be returned into fno->fname[].

53 |
54 | 55 | 56 |
57 |

QuickInfo

58 |

This is a wrapper function of f_readdir function. Available when FF_USE_FIND == 1 and FF_FS_MINIMIZE <= 1.

59 |
60 | 61 | 62 |
63 |

See Also

64 |

f_findfirst, f_closedir, DIR, FILINFO

65 |
66 | 67 |

Return

68 | 69 | 70 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/sfile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - FIL 10 | 11 | 12 | 13 | 14 |
15 |

FIL

16 |

The FIL structure (file object) holds the state of an open file. It is created by f_open function and discarded by f_close function. Application program must not modify any member in this structure except for cltbl, or the FAT volume will be collapsed. Note that a sector buffer is defined in this structure at non-tiny configuration (FF_FS_TINY == 0), so that the FIL structures at that configuration should not be defined as auto variable.

17 | 18 |
19 | typedef struct {
20 |     FFOBJID obj;          /* Object identifier */
21 |     BYTE    flag;         /* File object status flags */
22 |     BYTE    err;          /* Abort flag (error code) */
23 |     FSIZE_t fptr;         /* File read/write pointer (Byte offset origin from top of the file) */
24 |     DWORD   clust;        /* Current cluster of fptr (One cluster behind if fptr is on the cluster boundary. Invalid if fptr == 0.) */
25 |     LBA_t   sect;         /* Current data sector (Can be invalid if fptr is on the cluster boundary.)*/
26 | #if !FF_FS_READONLY
27 |     LBA_t   dir_sect;     /* Sector number containing the directory entry */
28 |     BYTE*   dir_ptr;      /* Ponter to the directory entry in the window */
29 | #endif
30 | #if FF_USE_FASTSEEK
31 |     DWORD*  cltbl;        /* Pointer to the cluster link map table (Nulled on file open. Set by application.) */
32 | #endif
33 | #if !FF_FS_TINY
34 |     BYTE    buf[FF_MAX_SS]; /* File private data transfer buffer (Always valid if fptr is not on the sector boundary but can be invalid if fptr is on the sector boundary.) */
35 | #endif
36 | } FIL;
37 | 
38 | 39 |
40 | 41 |

Return

42 | 43 | 44 | -------------------------------------------------------------------------------- /src/bl616/bl616_fpga_partner/README.md: -------------------------------------------------------------------------------- 1 | # BL616 FPGA Partner firmware 2 | 3 | The BL616 FPGA Partner firmware is a replacement firmware for the 4 | factory installed firmware of the BL616 MCU on the Tang 5 | FPGA boards. The FPGA Partner adds the ability to later install and 6 | run a secondary firmware on the BL616 in parallel. This feature can be 7 | used to install the FPGA Companion on the on-board BL616 MCU. 8 | 9 | > [!IMPORTANT] 10 | > You don't need this if you have connected a separate MCU like the 11 | > [Raspberry Pi Pico](../../rp2040) or a [M0S Dock](..) to run the FPGA Companion. The 12 | > FPGA Partner is only needed if you want to use the on-board 13 | > BL616 of a Tang device to run the FPGA Companion. 14 | 15 | The FPGA Partner exists for many of the Tang devices including 16 | the Tang Nano 20k, the Tang Primer 25k Dock, the Tang Neo Dock 17 | or the Tang Mega 138k Dock. 18 | 19 | ## How to flash 20 | 21 | You can flash these with the command line tool. To get the 22 | BL616 into firmware update mode, power the Tang up with the 23 | ```UPDATE``` button pressed (see [here](https://github.com/MiSTle-Dev/.github/wiki/Firmware-Installation-BL616-%C2%B5C) for more details). The BL616 will then 24 | indentify itself as ```Bouffalo CDC DEMO``` and a virtual COM port 25 | will be created. 26 | 27 | Use the following commands to flash using the command line tool to e.g. flash 28 | the Tang Nano 20k: 29 | 30 | ``` 31 | $ BLFlashCommand --interface=uart --baudrate=2000000 --port=/dev/ttyACM0 --chipname=bl616 --cpu_id= --config=bl616_fpga_partner_20kNano_cfg.ini 32 | ``` 33 | 34 | Afterward power cycle the device, and it should show up as FT2232 device named ```SIPEED USB Debugger```. 35 | The device should still work normal and be able to update and flash the FPGA. 36 | 37 | > [!IMPORTANT] 38 | > Some early versions of the Tang Nano 20k don't have encryption enabled. 39 | > This is needed for the FPGA Partner to work. If you flash the FPGA Partner 40 | > to one of these early Tang Nano 20k's it will not work. Instead, it will 41 | > stay in ```Bouffalo CDC DEMO``` update mode. In this case you cannot 42 | > use the FPGA Partner. You need to follow [these instructions](../friend_20k) 43 | > to restore your device to factory state. 44 | 45 | ## Installing the FPGA Companion as secondary firmware 46 | 47 | Once the FPGA Partner is installed and the device still works as expected, then 48 | the FPGA Companion can be installed additionally. The necessary files are usuaally part 49 | of the [FPGA Companion Releases](https://github.com/MiSTle-Dev/FPGA-Companion/releases). 50 | 51 | ## More information 52 | 53 | - [Information about the Tang Nano 20k variants](https://github.com/MiSTle-Dev/.github/wiki/Versions_TangNano20k) 54 | - [More details on how to flash the BL616](https://github.com/MiSTle-Dev/.github/wiki/Firmware-Installation-BL616-%C2%B5C). 55 | - [Original 20k FRIEND firmware](../friend_20k) 56 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/putc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_putc 10 | 11 | 12 | 13 | 14 |
15 |

f_putc

16 |

The f_putc funciton puts a character to the file.

17 |
18 | int f_putc (
19 |   TCHAR chr,  /* [IN] A character to write */
20 |   FIL* fp     /* [IN] File object */
21 | );
22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
chr
29 |
A character to write.
30 |
fp
31 |
Pointer to the open file object structuer.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

When the character was written successfuly, it returns number of character encoding units written to the file. When the function failed due to disk full or any error, a negative value will be returned.

39 |
40 | 41 | 42 |
43 |

Description

44 |

When FatFs is configured for Unicode API (FF_LFN_UNICODE >= 1), character encoding on the string fuctions, f_putc, f_puts, f_printf and f_gets function, is also switched to Unicode. The character encoding on the file to be read/written via those functions is selected by FF_STRF_ENCODE. The Unicode characters in multiple encoding unit, such as surrogate pair and multi-byte sequence, cannot be written with this function.

45 |
46 | 47 |
48 |

QuickInfo

49 |

This is a wrapper function of f_write function. Available when FF_FS_READONLY == 0 and FF_USE_STRFUNC >= 1. When FF_USE_STRFUNC == 2, a '\n' is output as '\r'+'\n'.

50 |
51 | 52 | 53 |
54 |

See Also

55 |

f_open, f_puts, f_printf, f_gets, f_close, FIL

56 |
57 | 58 |

Return

59 | 60 | 61 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/unlink.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_unlink 10 | 11 | 12 | 13 | 14 |
15 |

f_unlink

16 |

The f_unlink function removes a file or sub-directory from the volume.

17 |
18 | FRESULT f_unlink (
19 |   const TCHAR* path  /* [IN] Object name */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
path
28 |
Pointer to a null-terminated string that specifies the file or sub-directory to be removed.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_NOT_READY, 40 | FR_NO_FILE, 41 | FR_NO_PATH, 42 | FR_INVALID_NAME, 43 | FR_DENIED, 44 | FR_WRITE_PROTECTED, 45 | FR_INVALID_DRIVE, 46 | FR_NOT_ENABLED, 47 | FR_NO_FILESYSTEM, 48 | FR_TIMEOUT, 49 | FR_LOCKED, 50 | FR_NOT_ENOUGH_CORE 51 |

52 |
53 | 54 | 55 |
56 |

Description

57 |

58 | If condition of the object to be removed is applicable to the following terms, the function will be rejected.

    59 |
  • The file/sub-directory must not have read-only attribute (AM_RDO), or the function will be rejected with FR_DENIED.
  • 60 |
  • The sub-directory must be empty and must not be current directory, or the function will be rejected with FR_DENIED.
  • 61 |
  • The file/sub-directory must not be opened, or the FAT volume can be collapsed. It will be rejected safely when file lock function is enabled.
  • 62 |
63 |
64 | 65 | 66 |
67 |

QuickInfo

68 |

Available when FF_FS_READONLY == 0 and FF_FS_MINIMIZE == 0.

69 |
70 | 71 | 72 |

Return

73 | 74 | 75 | -------------------------------------------------------------------------------- /src/fatfs/source/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2019 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* Status of Disk Functions */ 13 | typedef BYTE DSTATUS; 14 | 15 | /* Results of Disk Functions */ 16 | typedef enum { 17 | RES_OK = 0, /* 0: Successful */ 18 | RES_ERROR, /* 1: R/W Error */ 19 | RES_WRPRT, /* 2: Write Protected */ 20 | RES_NOTRDY, /* 3: Not Ready */ 21 | RES_PARERR /* 4: Invalid Parameter */ 22 | } DRESULT; 23 | 24 | 25 | /*---------------------------------------*/ 26 | /* Prototypes for disk control functions */ 27 | 28 | 29 | DSTATUS disk_initialize (BYTE pdrv); 30 | DSTATUS disk_status (BYTE pdrv); 31 | DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); 32 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); 33 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 34 | 35 | 36 | /* Disk Status Bits (DSTATUS) */ 37 | 38 | #define STA_NOINIT 0x01 /* Drive not initialized */ 39 | #define STA_NODISK 0x02 /* No medium in the drive */ 40 | #define STA_PROTECT 0x04 /* Write protected */ 41 | 42 | 43 | /* Command code for disk_ioctrl fucntion */ 44 | 45 | /* Generic command (Used by FatFs) */ 46 | #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ 47 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ 48 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ 49 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ 50 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ 51 | 52 | /* Generic command (Not used by FatFs) */ 53 | #define CTRL_POWER 5 /* Get/Set power status */ 54 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 55 | #define CTRL_EJECT 7 /* Eject media */ 56 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 57 | 58 | /* MMC/SDC specific ioctl command */ 59 | #define MMC_GET_TYPE 10 /* Get card type */ 60 | #define MMC_GET_CSD 11 /* Get CSD */ 61 | #define MMC_GET_CID 12 /* Get CID */ 62 | #define MMC_GET_OCR 13 /* Get OCR */ 63 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 64 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 65 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 66 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 67 | 68 | /* ATA/CF specific ioctl command */ 69 | #define ATA_GET_REV 20 /* Get F/W revision */ 70 | #define ATA_GET_MODEL 21 /* Get model name */ 71 | #define ATA_GET_SN 22 /* Get serial number */ 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/getcwd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_getcwd 10 | 11 | 12 | 13 | 14 |
15 |

f_getcwd

16 |

The f_getcwd function retrieves the current directory of the current drive.

17 |
18 | FRESULT f_getcwd (
19 |   TCHAR* buff, /* [OUT] Buffer to return path name */
20 |   UINT len     /* [IN] The length of the buffer */
21 | );
22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
buff
29 |
Pointer to the buffer to receive the current directory string.
30 |
len
31 |
Size of the buffer in unit of TCHAR.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

39 | FR_OK, 40 | FR_DISK_ERR, 41 | FR_INT_ERR, 42 | FR_NOT_READY, 43 | FR_NOT_ENABLED, 44 | FR_NO_FILESYSTEM, 45 | FR_TIMEOUT, 46 | FR_NOT_ENOUGH_CORE 47 |

48 |
49 | 50 | 51 |
52 |

Description

53 |

The f_getcwd function retrieves full path name of the current directory of the current drive. When FF_VOLUMES >= 2, a heading drive prefix is added to the path name. The style of drive prefix depends on FF_STR_VOLUME_ID.

54 |

Note: In this revision, this function cannot retrieve the current directory path on the exFAT volume. It always returns the root directory path.

55 |
56 | 57 | 58 |
59 |

QuickInfo

60 |

Available when FF_FS_RPATH == 2.

61 |
62 | 63 | 64 |
65 |

Example

66 |
67 |     FRESULT fr;
68 |     TCHAR str[SZ_STR];
69 | 
70 |     fr = f_getcwd(str, SZ_STR);  /* Get current directory path */
71 | 
72 | 
73 |
74 | 75 | 76 |
77 |

See Also

78 |

f_chdrive, f_chdir

79 |
80 | 81 |

Return

82 | 83 | 84 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/puts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_puts 10 | 11 | 12 | 13 | 14 |
15 |

f_puts

16 |

The f_puts function writes a string to the file.

17 |
18 | int f_puts (
19 |   const TCHAR* str, /* [IN] String */
20 |   FIL* fp           /* [IN] File object */
21 | );
22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
str
29 |
Pointer to the null terminated string to be written. The terminator character will not be written.
30 |
fp
31 |
Pointer to the open file object structure.
32 |
33 |
34 | 35 | 36 |
37 |

Return Value

38 |

When the string was written successfuly, it returns number of character encoding units written to the file. When the function failed due to disk full or any error, a negative value will be returned.

39 |
40 | 41 | 42 |
43 |

Description

44 |

When FatFs is configured for Unicode API (FF_LFN_UNICODE >= 1), character encoding on the string fuctions, f_putc, f_puts, f_printf and f_gets function, is also switched to Unicode. The input Unicode characters in multiple encoding unit, such as surrogate pair and multi-byte sequence, should not be divided into two function calls, or the character will be lost. The character encoding on the file to be written via this functions is selected by FF_STRF_ENCODE. The characters with wrong encoding or invalid for the output encoding will be lost.

45 |
46 | 47 | 48 |
49 |

QuickInfo

50 |

This is a wrapper function of f_write function. Available when FF_FS_READONLY == 0 and FF_USE_STRFUNC >= 1. When FF_USE_STRFUNC == 2, '\n's contained in the input string are output as '\r'+'\n' each.

51 |
52 | 53 | 54 |
55 |

See Also

56 |

f_open, f_putc, f_printf, f_gets, f_close, FIL

57 |
58 | 59 |

Return

60 | 61 | 62 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/setcp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_setcp 10 | 11 | 12 | 13 | 14 |
15 |

f_setcp

16 |

The f_setcp function sets the active code page.

17 |
18 | FRESULT f_setcp (
19 |   WORD cp     /* [IN] Code page to be set */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameters

26 |
27 |
cp
28 |
OEM code page to be used for the path name. Valid values are as follows.
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
ValueMeaning
0Initial value (any extended character cannot be used)
437U.S.
720Arabic
737Greek
771KBL
775Baltic
850Latin 1
852Latin 2
855Cyrillic
857Turkish
860Portuguese
861Icelandic
862Hebrew
863Canadian French
864Arabic
865Nordic
866Russian
869Greek 2
932Japanese (DBCS)
936Simplified Chinese (DBCS)
949Korean (DBCS)
950Traditional Chinese (DBCS)
54 |
55 |
56 |
57 | 58 | 59 |
60 |

Return Values

61 |

62 | FR_OK, 63 | FR_INVALID_PARAMETER 64 |

65 |
66 | 67 | 68 |
69 |

Description

70 |

The f_setcp function sets the active code page for the path name. Also code conversion of string functions will be affected by the setting of code page when FF_LFN_UNICODE >= 1 and FF_STRF_ENCODE == 0. Because the initial setting of the code page is 0 and API function with extended character will not work properly, a valid code page needs to be set on the system start-up and it should not be changed on the fly.

71 |
72 | 73 | 74 |
75 |

QuickInfo

76 |

Available when FF_CODE_PAGE == 0.

77 |
78 | 79 | 80 |

Return

81 | 82 | 83 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/read.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_read 10 | 11 | 12 | 13 | 14 |
15 |

f_read

16 |

The f_read function reads data from a file.

17 |
18 | FRESULT f_read (
19 |   FIL* fp,     /* [IN] File object */
20 |   void* buff,  /* [OUT] Buffer to store read data */
21 |   UINT btr,    /* [IN] Number of bytes to read */
22 |   UINT* br     /* [OUT] Number of bytes read */
23 | );
24 | 
25 |
26 | 27 |
28 |

Parameters

29 |
30 |
fp
31 |
Pointer to the open file object.
32 |
buff
33 |
Pointer to the buffer to store the read data.
34 |
btr
35 |
Number of bytes to read in range of UINT type. If the file needs to be read fast, it should be read in large chunk as possible.
36 |
br
37 |
Pointer to the UINT variable that receives number of bytes read. This value is always valid after the function call regardless of the function return code. If the return value is equal to btr, the function return code should be FR_OK.
38 |
39 |
40 | 41 | 42 |
43 |

Return Values

44 |

45 | FR_OK, 46 | FR_DISK_ERR, 47 | FR_INT_ERR, 48 | FR_DENIED, 49 | FR_INVALID_OBJECT, 50 | FR_TIMEOUT 51 |

52 |
53 | 54 | 55 |
56 |

Description

57 |

The function starts to read data from the file at the file offset pointed by read/write pointer. The read/write pointer advances as number of bytes read. After the function succeeded, *br should be checked to detect end of the file. In case of *br < btr, it means the read/write pointer hit end of the file during read operation.

58 |
59 | 60 | 61 |
62 |

QuickInfo

63 |

Always available.

64 |
65 | 66 | 67 |
68 |

Example

69 |

Refer to the example in f_open.

70 |
71 | 72 | 73 |
74 |

See Also

75 |

f_open, fgets, f_write, f_close, FIL

76 |
77 | 78 |

Return

79 | 80 | 81 | -------------------------------------------------------------------------------- /src/jtag.h: -------------------------------------------------------------------------------- 1 | /* 2 | jtag.h 3 | 4 | mainly gowin related JTAG 5 | */ 6 | 7 | #ifndef JTAG_H 8 | #define JTAG_H 9 | 10 | #include 11 | #include 12 | 13 | /* known GOWIN JTAG commands */ 14 | #define JTAG_COMMAND_GOWIN_BYPASS0 0x00 15 | #define JTAG_COMMAND_GOWIN_SAMPLE 0x01 16 | #define JTAG_COMMAND_GOWIN_NOOP 0x02 17 | #define JTAG_COMMAND_GOWIN_SRAM_READ 0x03 18 | #define JTAG_COMMAND_GOWIN_EXTEST 0x04 19 | #define JTAG_COMMAND_GOWIN_ERASE_SRAM 0x05 20 | #define JTAG_COMMAND_GOWIN_UNKNOWN1 0x08 // seems to be "DONE WRITING USERCODE" 21 | #define JTAG_COMMAND_GOWIN_XFER_DONE 0x09 22 | #define JTAG_COMMAND_GOWIN_UNKNOWN2 0x0a // seems to be "WRITE USERCODE" 23 | #define JTAG_COMMAND_GOWIN_IDCODE 0x11 24 | #define JTAG_COMMAND_GOWIN_INIT_ADDR 0x12 25 | #define JTAG_COMMAND_GOWIN_USERCODE 0x13 26 | #define JTAG_COMMAND_GOWIN_CONFIG_ENABLE 0x15 27 | #define JTAG_COMMAND_GOWIN_TRANSFER_SPI 0x16 28 | #define JTAG_COMMAND_GOWIN_XFER_WRITE 0x17 29 | #define JTAG_COMMAND_GOWIN_PROGRAM_KEY_1 0x21 30 | #define JTAG_COMMAND_GOWIN_SECURITY 0x23 31 | #define JTAG_COMMAND_GOWIN_PROGRAM_EFUSE 0x24 32 | #define JTAG_COMMAND_GOWIN_PROGRAM_KEY_2 0x29 // gowin doesn't explain why there are two "PROGRAM KEY" 33 | #define JTAG_COMMAND_GOWIN_READ_KEY 0x25 34 | #define JTAG_COMMAND_GOWIN_CONFIG_DISABLE 0x3a 35 | #define JTAG_COMMAND_GOWIN_RECONFIG 0x3c 36 | #define JTAG_COMMAND_GOWIN_STATUS 0x41 37 | #define JTAG_COMMAND_GOWIN_GAO_1 0x42 38 | #define JTAG_COMMAND_GOWIN_GAO_2 0x43 39 | #define JTAG_COMMAND_GOWIN_EFLASH_PROGRAM 0x71 40 | #define JTAG_COMMAND_GOWIN_EFLASH_ERASE 0x75 41 | #define JTAG_COMMAND_GOWIN_SWITCH_MCU_JTAG 0x7a 42 | #define JTAG_COMMAND_GOWIN_BYPASS 0xff 43 | 44 | #define JTAG_GOWIN_STATUS_CRC_ERROR (1 << 0) 45 | #define JTAG_GOWIN_STATUS_BAD_COMMAND (1 << 1) 46 | #define JTAG_GOWIN_STATUS_ID_VERIFY_FAILED (1 << 2) 47 | #define JTAG_GOWIN_STATUS_TIMEOUT (1 << 3) 48 | #define JTAG_GOWIN_STATUS_MEMORY_ERASE (1 << 5) 49 | #define JTAG_GOWIN_STATUS_PREAMBLE (1 << 6) 50 | #define JTAG_GOWIN_STATUS_SYSTEM_EDIT_MODE (1 << 7) 51 | #define JTAG_GOWIN_STATUS_PRG_SPIFLASH_DIRECT (1 << 8) 52 | #define JTAG_GOWIN_STATUS_NON_JTAG_CNF_ACTIVE (1 << 10) 53 | #define JTAG_GOWIN_STATUS_BYPASS (1 << 11) 54 | #define JTAG_GOWIN_STATUS_GOWIN_VLD (1 << 12) 55 | #define JTAG_GOWIN_STATUS_DONE_FINAL (1 << 13) 56 | #define JTAG_GOWIN_STATUS_SECURITY_FINAL (1 << 14) 57 | #define JTAG_GOWIN_STATUS_READY (1 << 15) 58 | #define JTAG_GOWIN_STATUS_POR (1 << 16) 59 | #define JTAG_GOWIN_STATUS_FLASH_LOCK (1 << 17) 60 | 61 | bool jtag_open(void); 62 | void jtag_close(void); 63 | 64 | // these are actually for 8 bit commands and thus somewhat gowin specific 65 | void jtag_command(uint8_t cmd); 66 | uint32_t jtag_command_read32(uint8_t cmd); 67 | 68 | // these are obviously gowin specific 69 | bool jtag_gowin_eraseSRAM(void); 70 | bool jtag_gowin_writeSRAM_prepare(void); 71 | bool jtag_gowin_writeSRAM_transfer(uint8_t *data, uint16_t len, bool first, bool last); 72 | bool jtag_gowin_writeSRAM_postproc(uint32_t checksum); 73 | 74 | #endif // JTAG_H 75 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/gets.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_gets 10 | 11 | 12 | 13 | 14 |
15 |

f_gets

16 |

The f_gets reads a string from the file.

17 |
18 | TCHAR* f_gets (
19 |   TCHAR* buff, /* [OUT] Read buffer */
20 |   int len,     /* [IN] Size of the read buffer */
21 |   FIL* fp      /* [IN] File object */
22 | );
23 | 
24 |
25 | 26 |
27 |

Parameters

28 |
29 |
buff
30 |
Pointer to read buffer to store the read string.
31 |
len
32 |
Size of the read buffer in unit of item.
33 |
fp
34 |
Pointer to the open file object structure.
35 |
36 |
37 | 38 | 39 |
40 |

Return Values

41 |

When the function succeeded, buff will be returuned.

42 |
43 | 44 | 45 |
46 |

Description

47 |

The read operation continues until a '\n' is stored, reached end of the file or the buffer is filled with len - 1 characters. The read string is terminated with a '\0'. When no character to read or any error occured during read operation, it returns a null pointer. The status of EOF and error can be examined with f_eof and f_error function.

48 |

When FatFs is configured to Unicode API (FF_LFN_UNICODE >= 1), data types on the srting fuctions, f_putc, f_puts, f_printf and f_gets, is also switched to Unicode. The character encoding on the file to be read via this function is assumed as FF_STRF_ENCODE. If the character encoding on the file differs from that on the API, it is converted in this function. In this case, input characters with wrong encoding will be lost.

49 |
50 | 51 | 52 |
53 |

QuickInfo

54 |

This is a wrapper function of f_read function. Available when FF_USE_STRFUNC >= 1. When it is set to 2, '\r's contained in the file are stripped out.

55 |
56 | 57 | 58 |
59 |

See Also

60 |

f_open, f_read, f_putc, f_puts, f_printf, f_close, FIL

61 |
62 | 63 |

Return

64 | 65 | 66 | -------------------------------------------------------------------------------- /src/osd_u8g2.c: -------------------------------------------------------------------------------- 1 | // 2 | // osd_u8g2.c 3 | // 4 | 5 | #include "spi.h" 6 | #include "osd.h" 7 | #include "menu.h" 8 | #include "sdc.h" 9 | #include "mcu_hw.h" 10 | 11 | #include "debug.h" 12 | 13 | u8g2_t u8g2; 14 | 15 | static char state; 16 | static uint8_t buf[128*8]; // screen buffer 17 | 18 | static const u8x8_display_info_t u8x8_mn_128x64_info = 19 | { 0, 1, 0, 0, 0, 0, 0, 0, 4000000UL, 1, 0, 0, 0, 16, 8, 0, 0, 128, 64 }; 20 | 21 | uint8_t u8x8_d_mn_128x64(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr) { 22 | uint8_t x, y, c; 23 | uint8_t *ptr; 24 | 25 | switch(msg) 26 | { 27 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 28 | u8x8_d_helper_display_setup_memory(u8g2, &u8x8_mn_128x64_info); 29 | break; 30 | case U8X8_MSG_DISPLAY_INIT: 31 | u8x8_d_helper_display_init(u8g2); 32 | break; 33 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 34 | break; 35 | case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 36 | break; 37 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 38 | break; 39 | case U8X8_MSG_DISPLAY_DRAW_TILE: 40 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 41 | x *= 8; 42 | x += u8g2->x_offset; 43 | 44 | y = ((u8x8_tile_t *)arg_ptr)->y_pos; 45 | y *= 8; 46 | 47 | do 48 | { 49 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 50 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 51 | 52 | mcu_hw_spi_begin(); 53 | 54 | /* send data */ 55 | mcu_hw_spi_tx_u08(SPI_TARGET_OSD); 56 | mcu_hw_spi_tx_u08(SPI_OSD_WRITE); // command byte data 57 | mcu_hw_spi_tx_u08(((y/8)<<4)+x/8); // tile address 58 | 59 | for(int i=0;i 0 ); 67 | 68 | break; 69 | 70 | default: 71 | return 0; 72 | } 73 | return 1; 74 | } 75 | 76 | static uint8_t u8x8_d_mn_gpio(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) { 77 | return 1; 78 | } 79 | 80 | void u8x8_Setup_mn_128x64(u8x8_t *u8x8) { 81 | /* setup defaults */ 82 | u8x8_SetupDefaults(u8x8); 83 | 84 | /* setup specific callbacks */ 85 | u8x8->display_cb = u8x8_d_mn_128x64; 86 | 87 | u8x8->gpio_and_delay_cb = u8x8_d_mn_gpio; 88 | 89 | /* setup display info */ 90 | u8x8_SetupMemory(u8x8); 91 | } 92 | 93 | void osd_enable(char en) { 94 | osd_debugf("%sable", en?"en":"dis"); 95 | 96 | state = en; 97 | 98 | // show/hide OSD 99 | mcu_hw_spi_begin(); 100 | mcu_hw_spi_tx_u08(SPI_TARGET_OSD); 101 | mcu_hw_spi_tx_u08(SPI_OSD_ENABLE); // enable/disable command 102 | mcu_hw_spi_tx_u08(en); // enable 103 | mcu_hw_spi_end(); 104 | } 105 | 106 | void osd_init(void) { 107 | // prepare u8g2 108 | // osd.spi->dev->user_data = osd.buf; 109 | u8x8_Setup_mn_128x64(u8g2_GetU8x8(&u8g2)); 110 | u8g2_SetupBuffer(&u8g2, buf, 8, u8g2_ll_hvline_vertical_top_lsb, &u8g2_cb_r0); 111 | 112 | u8x8_ConnectBitmapToU8x8(u8g2_GetU8x8(&u8g2)); 113 | u8g2_SetFontMode(&u8g2, 1); 114 | 115 | // make sure OSD is initially hidden 116 | state = OSD_INVISIBLE; 117 | osd_enable(state); 118 | } 119 | 120 | int osd_is_visible(void) { 121 | return state == OSD_VISIBLE; 122 | } 123 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/chmod.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_chmod 10 | 11 | 12 | 13 | 14 |
15 |

f_chmod

16 |

The f_chmod function changes the attribute of a file or sub-directory.

17 |
18 | FRESULT f_chmod (
19 |   const TCHAR* path, /* [IN] Object name */
20 |   BYTE attr,         /* [IN] Attribute flags */
21 |   BYTE mask          /* [IN] Attribute masks */
22 | );
23 | 
24 |
25 | 26 |
27 |

Parameters

28 |
29 |
path
30 |
Pointer to the null-terminated string that specifies an object to be changed
31 |
attr
32 |
Attribute flags to be set in one or more combination of the following flags. The specified flags are set and others are cleard.
33 | 34 | 35 | 36 | 37 | 38 | 39 |
AttributeDescription
AM_RDORead only
AM_ARCArchive
AM_SYSSystem
AM_HIDHidden
40 |
41 |
mask
42 |
Attribute mask that specifies which attribute is changed. The specified attributes are set or cleard and others are left unchanged.
43 |
44 |
45 | 46 | 47 |
48 |

Return Values

49 |

50 | FR_OK, 51 | FR_DISK_ERR, 52 | FR_INT_ERR, 53 | FR_NOT_READY, 54 | FR_NO_FILE, 55 | FR_NO_PATH, 56 | FR_INVALID_NAME, 57 | FR_WRITE_PROTECTED, 58 | FR_INVALID_DRIVE, 59 | FR_NOT_ENABLED, 60 | FR_NO_FILESYSTEM, 61 | FR_TIMEOUT, 62 | FR_NOT_ENOUGH_CORE 63 |

64 |
65 | 66 | 67 |
68 |

Description

69 |

The f_chmod function changes the attribute of a file or sub-directory.

70 |
71 | 72 | 73 |
74 |

QuickInfo

75 |

Available when FF_FS_READONLY == 0 and FF_USE_CHMOD == 1.

76 |
77 | 78 | 79 |
80 |

Example

81 |
82 |     /* Set Read-only, clear Archive and others are left unchanged. */
83 |     f_chmod("file.txt", AM_RDO, AM_RDO | AM_ARC);
84 | 
85 |
86 | 87 |

Return

88 | 89 | 90 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/utime.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_utime 10 | 11 | 12 | 13 | 14 |
15 |

f_utime

16 |

The f_utime function changes the timestamp of a file or sub-directory.

17 |
 18 | FRESULT f_utime (
 19 |   const TCHAR* path,  /* [IN] Object name */
 20 |   const FILINFO* fno  /* [IN] Time and data to be set */
 21 | );
 22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
path
29 |
Pointer to the null-terminated string that specifies an object to be changed.
30 |
fno
31 |
Pointer to the file information structure that has a timestamp to be set in member fdate and ftime. Do not care any other members.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

39 | FR_OK, 40 | FR_DISK_ERR, 41 | FR_INT_ERR, 42 | FR_NOT_READY, 43 | FR_NO_FILE, 44 | FR_NO_PATH, 45 | FR_INVALID_NAME, 46 | FR_WRITE_PROTECTED, 47 | FR_INVALID_DRIVE, 48 | FR_NOT_ENABLED, 49 | FR_NO_FILESYSTEM, 50 | FR_TIMEOUT, 51 | FR_NOT_ENOUGH_CORE 52 |

53 |
54 | 55 | 56 |
57 |

Description

58 |

The f_utime function changes the timestamp of a file or sub-directory

59 |
60 | 61 | 62 |
63 |

Example

64 |
 65 | FRESULT set_timestamp (
 66 |     char *obj,     /* Pointer to the file name */
 67 |     int year,
 68 |     int month,
 69 |     int mday,
 70 |     int hour,
 71 |     int min,
 72 |     int sec
 73 | )
 74 | {
 75 |     FILINFO fno;
 76 | 
 77 |     fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
 78 |     fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);
 79 | 
 80 |     return f_utime(obj, &fno);
 81 | }
 82 | 
83 |
84 | 85 | 86 |
87 |

QuickInfo

88 |

Available when FF_FS_READONLY == 0 and FF_USE_CHMOD == 1.

89 |
90 | 91 | 92 |
93 |

See Also

94 |

f_stat, FILINFO

95 |
96 | 97 |

Return

98 | 99 | 100 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/getlabel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_getlabel 10 | 11 | 12 | 13 | 14 |
15 |

f_getlabel

16 |

The f_getlabel function returns volume label and volume serial number of a volume.

17 |
18 | FRESULT f_getlabel (
19 |   const TCHAR* path,  /* [IN] Drive number */
20 |   TCHAR* label,       /* [OUT] Volume label */
21 |   DWORD* vsn          /* [OUT] Volume serial number */
22 | );
23 | 
24 |
25 | 26 |
27 |

Parameters

28 |
29 |
path
30 |
Pointer to the null-terminated string that specifies the logical drive. Null-string specifies the default drive.
31 |
label
32 |
Pointer to the buffer to store the volume label. If the volume has no label, a null-string will be returned. Set null pointer if this information is not needed. The buffer size should be shown below at least to avoid buffer overflow.
33 | 34 | 35 | 36 | 37 | 38 | 39 |
ConfigurationFF_FS_EXFAT == 0FF_FS_EXFAT == 1
FF_USE_LFN == 012 items-
FF_LFN_UNICODE == 012 items23 items
FF_LFN_UNICODE == 1,312 items12 items
FF_LFN_UNICODE == 234 items34 items
40 |
41 |
vsn
42 |
Pointer to the DWORD variable to store the volume serial number. Set null pointer if this information is not needed.
43 |
44 |
45 | 46 | 47 |
48 |

Return Values

49 |

50 | FR_OK, 51 | FR_DISK_ERR, 52 | FR_INT_ERR, 53 | FR_NOT_READY, 54 | FR_INVALID_DRIVE, 55 | FR_NOT_ENABLED, 56 | FR_NO_FILESYSTEM, 57 | FR_TIMEOUT 58 |

59 |
60 | 61 | 62 |
63 |

QuickInfo

64 |

Available when FF_USE_LABEL == 1.

65 |
66 | 67 | 68 |
69 |

Example

70 |
71 |     char str[12];
72 | 
73 |     /* Get volume label of the default drive */
74 |     f_getlabel("", str, 0);
75 | 
76 |     /* Get volume label of the drive 2 */
77 |     f_getlabel("2:", str, 0);
78 | 
79 |
80 | 81 | 82 |
83 |

See Also

84 | f_setlabel 85 |
86 | 87 | 88 |

Return

89 | 90 | 91 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/chdir.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_chdir 10 | 11 | 12 | 13 | 14 |
15 |

f_chdir

16 |

The f_chdir function changes the current directory of the logical drive.

17 |
18 | FRESULT f_chdir (
19 |   const TCHAR* path /* [IN] Path name */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameters

26 |
27 |
path
28 |
Pointer to the null-terminated string that specifies the directory to be set as current directory.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_NOT_READY, 40 | FR_NO_PATH, 41 | FR_INVALID_NAME, 42 | FR_INVALID_DRIVE, 43 | FR_NOT_ENABLED, 44 | FR_NO_FILESYSTEM, 45 | FR_TIMEOUT, 46 | FR_NOT_ENOUGH_CORE 47 |

48 |
49 | 50 | 51 |
52 |

Description

53 |

The f_chdir function changes the current directory of the logical drive. Also the current drive will be changed when in Unix style drive prefix, FF_STR_VOLUME_ID == 2. The current directory of each logical drive is initialized to the root directory on mount.

54 |

Note that the current directory is retained in the each file system object and the current drive is retained in a static variable, so that it also affects other tasks that use the file functions.

55 |
56 | 57 | 58 |
59 |

QuickInfo

60 |

Available when FF_FS_RPATH >= 1.

61 |
62 | 63 | 64 |
65 |

Example

66 |
67 |     /* Change current direcoty of the current drive ("dir1" under root directory) */
68 |     f_chdir("/dir1");
69 | 
70 |     /* Change current direcoty of current drive (parent directory of drive 2) */
71 |     f_chdir("2:..");
72 | 
73 |     /* Change current direcoty of the drive "sdcard" (at DOS/Windows style volume ID) */
74 |     f_chdir("sdcard:/dir1");
75 | 
76 |     /* Change current direcoty of the drive "flash" and set it as current drive (at Unix style volume ID) */
77 |     f_chdir("/flash/dir1");
78 | 
79 |
80 | 81 |
82 |

See Also

83 |

f_chdrive, f_getcwd

84 |
85 | 86 |

Return

87 | 88 | 89 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/write.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_write 10 | 11 | 12 | 13 | 14 |
15 |

f_write

16 |

The f_write writes data to a file.

17 |
18 | FRESULT f_write (
19 |   FIL* fp,          /* [IN] Pointer to the file object structure */
20 |   const void* buff, /* [IN] Pointer to the data to be written */
21 |   UINT btw,         /* [IN] Number of bytes to write */
22 |   UINT* bw          /* [OUT] Pointer to the variable to return number of bytes written */
23 | );
24 | 
25 |
26 | 27 |
28 |

Parameters

29 |
30 |
fp
31 |
Pointer to the open file object structure.
32 |
buff
33 |
Pointer to the data to be written.
34 |
btw
35 |
Specifies number of bytes to write in range of UINT type. If the data needs to be written fast, it should be written in large chunk as possible.
36 |
bw
37 |
Pointer to the UINT variable that receives the number of bytes written. This value is always valid after the function call regardless of the function return code. If the return value is equal to btw, the function return code should be FR_OK.
38 |
39 |
40 | 41 | 42 |
43 |

Return Values

44 |

45 | FR_OK, 46 | FR_DISK_ERR, 47 | FR_INT_ERR, 48 | FR_DENIED, 49 | FR_INVALID_OBJECT, 50 | FR_TIMEOUT 51 |

52 |
53 | 54 | 55 |
56 |

Description

57 |

The function starts to write data to the file at the file offset pointed by read/write pointer. The read/write pointer advances as number of bytes written. After the function succeeded, *bw should be checked to detect the disk full. In case of *bw < btw, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.

58 |
59 | 60 | 61 |
62 |

QuickInfo

63 |

Available when FF_FS_READONLY == 0.

64 |
65 | 66 | 67 |
68 |

Example

69 |

Refer to the example in f_open.

70 |
71 | 72 | 73 |
74 |

See Also

75 |

f_open, f_read, fputc, fputs, fprintf, f_close, FIL

76 |
77 | 78 |

Return

79 | 80 | 81 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | config.h - MiSTeryNano FPGA Companion 3 | 4 | */ 5 | 6 | #ifndef CONFIG_H 7 | #define CONFIG_H 8 | 9 | #include 10 | 11 | #ifndef ESP_PLATFORM 12 | #define CONFIG_MAX_PRIORITY (32) 13 | #else 14 | #define CONFIG_MAX_PRIORITY (25) 15 | #endif 16 | 17 | #define MAX_DRIVES (8) // max disk floppy/hdd drives supported 18 | #define MAX_IMAGES (8) // max rom/memory images supported 19 | #define MAX_HID_DEVICES (6) 20 | #define MAX_XBOX_DEVICES (2) 21 | 22 | 23 | /* ================== configuration as requested by the FPGA ================ */ 24 | 25 | #define CONFIG_ACTION_COMMAND_IDLE 0 26 | #define CONFIG_ACTION_COMMAND_SET 1 27 | #define CONFIG_ACTION_COMMAND_DELAY 2 28 | #define CONFIG_ACTION_COMMAND_SAVE 3 29 | #define CONFIG_ACTION_COMMAND_LOAD 4 30 | #define CONFIG_ACTION_COMMAND_HIDE 5 31 | #define CONFIG_ACTION_COMMAND_LINK 6 32 | 33 | typedef struct { 34 | unsigned char code; 35 | union { 36 | struct { 37 | unsigned char id; 38 | unsigned char value; 39 | } set; 40 | struct { 41 | unsigned short ms; 42 | } delay; 43 | char *filename; 44 | struct config_action_S *action; 45 | }; 46 | } config_action_command_t; 47 | 48 | typedef struct config_action_S { 49 | char *name; 50 | config_action_command_t *commands; 51 | } config_action_t; 52 | 53 | typedef struct { 54 | char index; 55 | char *label; 56 | char *def; 57 | char **ext; 58 | config_action_t *action; 59 | } config_fsel_t; 60 | 61 | typedef struct { 62 | char *label; 63 | unsigned char value; 64 | } config_listentry_t; 65 | 66 | typedef struct { 67 | unsigned char id; 68 | char *label; 69 | unsigned char def; 70 | config_listentry_t **listentries; 71 | config_action_t *action; 72 | } config_list_t; 73 | 74 | typedef struct { 75 | char *label; 76 | config_action_t *action; 77 | } config_button_t; 78 | 79 | typedef struct { 80 | char index; 81 | char *label; 82 | char **ext; 83 | char *def; 84 | char *none_str; 85 | unsigned char *none_icn; 86 | config_action_t *action; 87 | } config_image_t; 88 | 89 | typedef struct { 90 | unsigned char id; 91 | char *label; 92 | unsigned char def; 93 | config_action_t *action; 94 | } config_toggle_t; 95 | 96 | #define CONFIG_MENU_ENTRY_UNKNOWN 0 97 | #define CONFIG_MENU_ENTRY_MENU 1 98 | #define CONFIG_MENU_ENTRY_FILESELECTOR 2 99 | #define CONFIG_MENU_ENTRY_LIST 3 100 | #define CONFIG_MENU_ENTRY_BUTTON 4 101 | #define CONFIG_MENU_ENTRY_IMAGE 5 102 | #define CONFIG_MENU_ENTRY_TOGGLE 6 103 | 104 | typedef struct { 105 | unsigned char type; 106 | union { 107 | struct config_menu_S *menu; 108 | config_fsel_t *fsel; 109 | config_list_t *list; 110 | config_button_t *button; 111 | config_image_t *image; 112 | config_toggle_t *toggle; 113 | }; 114 | } config_menu_entry_t; 115 | 116 | typedef struct config_menu_S { 117 | char *label; 118 | config_menu_entry_t *entries; 119 | } config_menu_t; 120 | 121 | typedef struct { 122 | char *name; 123 | int version; 124 | config_action_t **actions; 125 | config_menu_t *menu; 126 | } config_t; 127 | 128 | // the global config 129 | extern config_t *cfg; 130 | 131 | void config_init(void); 132 | config_action_t *config_get_action(const char *); 133 | void config_dump(void); 134 | const char *config_menuentry_get_type_str(config_menu_entry_t *); 135 | 136 | #endif // CONFIG_H 137 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/rename.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_rename 10 | 11 | 12 | 13 | 14 |
15 |

f_rename

16 |

The f_rename function renames and/or moves a file or sub-directory.

17 |
18 | FRESULT f_rename (
19 |   const TCHAR* old_name, /* [IN] Old object name */
20 |   const TCHAR* new_name  /* [IN] New object name */
21 | );
22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
old_name
29 |
Pointer to a null-terminated string that specifies the existing file or sub-directory to be renamed.
30 |
new_name
31 |
Pointer to a null-terminated string that specifies the new object name. A drive number may be specified in this string but it is ignored and assumed as the same drive of the old_name. Any object with this path name except old_name must not be exist, or the function fails with FR_EXIST.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

39 | FR_OK, 40 | FR_DISK_ERR, 41 | FR_INT_ERR, 42 | FR_NOT_READY, 43 | FR_NO_FILE, 44 | FR_NO_PATH, 45 | FR_INVALID_NAME, 46 | FR_EXIST, 47 | FR_WRITE_PROTECTED, 48 | FR_INVALID_DRIVE, 49 | FR_NOT_ENABLED, 50 | FR_NO_FILESYSTEM, 51 | FR_TIMEOUT, 52 | FR_LOCKED, 53 | FR_NOT_ENOUGH_CORE 54 |

55 |
56 | 57 | 58 |
59 |

Description

60 |

Renames a file or sub-directory and can also move it to other directory in the same volume. The object to be renamed must not be an open object, or the FAT volume can be collapsed. Such the wrong operation is rejected safely when file lock function is enabled.

61 |
62 | 63 | 64 |
65 |

QuickInfo

66 |

Available when FF_FS_READONLY == 0 and FF_FS_MINIMIZE == 0.

67 |
68 | 69 | 70 |
71 |

Example

72 |
73 |     /* Rename an object in the default drive */
74 |     f_rename("oldname.txt", "newname.txt");
75 | 
76 |     /* Rename an object in the drive 2 */
77 |     f_rename("2:oldname.txt", "newname.txt");
78 | 
79 |     /* Rename an object and move it to another directory in the drive */
80 |     f_rename("log.txt", "old/log0001.txt");
81 | 
82 |
83 | 84 | 85 |

Return

86 | 87 | 88 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/sync.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_sync 10 | 11 | 12 | 13 | 14 |
15 |

f_sync

16 |

The f_sync function flushes the cached information of a writing file.

17 |
18 | FRESULT f_sync (
19 |   FIL* fp     /* [IN] File object */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameter

26 |
27 |
fp
28 |
Pointer to the open file object to be flushed.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_INVALID_OBJECT, 40 | FR_TIMEOUT 41 |

42 |
43 | 44 | 45 |
46 |

Description

47 |

The f_sync function performs the same process as f_close function but the file is left opened and can continue read/write/seek operations to the file. This is suitable for the applications that open files for a long time in write mode, such as data logger. Performing f_sync function in certain interval can minimize the risk of data loss due to a sudden blackout, wrong media removal or unrecoverable disk error. For more information, refer to application note.

48 |
49 | Case 1. Normal write sequence
50 | 
51 |                                 Time -->                                     ↓Normal shutdown
52 | OwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwC <Power off>
53 | 
54 | 
55 | Case 2. Without using f_sync()
56 | 
57 |                                 Time -->                             ↓System crush
58 | Owwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
59 |  |<--------------- All data written will be lost ------------------>|
60 | 
61 | 
62 | Case 3. Using f_sync()
63 |                                 Time -->                             ↓System crush
64 | OwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwww
65 |                             Data after last f_sync will be lost |<->| 
66 | O - f_open()
67 | C - f_close()
68 | w - f_write()
69 | S - f_sync()
70 | 
71 |

However there is no sense in f_sync function immediataly before f_close function because it performs f_sync function in it. In other words, the differnce between those functions is that the file object is invalidated or not.

72 |
73 | 74 | 75 |
76 |

QuickInfo

77 |

Available when FF_FS_READONLY == 0.

78 |
79 | 80 | 81 |
82 |

See Also

83 |

f_close, Critical section

84 |
85 | 86 |

Return

87 | 88 | 89 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/sfileinfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - FILINFO 10 | 11 | 12 | 13 | 14 |
15 |

FILINFO

16 |

The FILINFO structure holds information about the object retrieved by f_readdir, f_findfirst, f_findnext and f_stat function. Be careful in the size of structure when LFN is enabled.

17 |
18 | typedef struct {
19 |     FSIZE_t fsize;               /* File size */
20 |     WORD    fdate;               /* Last modified date */
21 |     WORD    ftime;               /* Last modified time */
22 |     BYTE    fattrib;             /* Attribute */
23 | #if FF_USE_LFN
24 |     TCHAR   altname[FF_SFN_BUF + 1]; /* Alternative object name */
25 |     TCHAR   fname[FF_LFN_BUF + 1];   /* Primary object name */
26 | #else
27 |     TCHAR   fname[12 + 1];       /* Object name */
28 | #endif
29 | } FILINFO;
30 | 
31 |
32 | 33 |

Members

34 |
35 |
fsize
36 |
Size of the file in unit of byte. FSIZE_t is an alias of integer type either DWORD(32-bit) or QWORD(64-bit) depends on the configuration option FF_FS_EXFAT. Do not care if the item is a sub-directory.
37 |
fdate
38 |
The date when the file was modified or the directory was created.
39 |
40 |
bit15:9
41 |
Year origin from 1980 (0..127)
42 |
bit8:5
43 |
Month (1..12)
44 |
bit4:0
45 |
Day (1..31)
46 |
47 |
48 |
ftime
49 |
The time when the file was modified or the directory was created.
50 |
51 |
bit15:11
52 |
Hour (0..23)
53 |
bit10:5
54 |
Minute (0..59)
55 |
bit4:0
56 |
Second / 2 (0..29)
57 |
58 |
59 |
fattrib
60 |
The attribute flags in combination of:
61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
FlagMeaning
AM_RDORead-only. Write mode open and deleting is rejected.
AM_HIDHidden. Should not be shown in normal directory listing.
AM_SYSSystem. Used by system and should not be accessed.
AM_ARCArchive. Set on new creation or any modification to the file.
AM_DIRDirectory. This is not a file but a sub-directory container.
69 |
70 |
fname[]
71 |
Null-terminated object name. A null string is stored when no item to read and it indicates this structure is invalid. The size of fname[] and altname[] each can be configured in LFN configuration.
72 |
altname[]
73 |
Alternative object name is stored if available. This member is not available in non-LFN configuration.
74 |
75 | 76 |

Return

77 | 78 | 79 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/setlabel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_setlabel 10 | 11 | 12 | 13 | 14 |
15 |

f_setlabel

16 |

The f_setlabel function sets/removes the label of a volume.

17 |
18 | FRESULT f_setlabel (
19 |   const TCHAR* label  /* [IN] Volume label to be set */
20 | );
21 | 
22 |
23 | 24 |
25 |

Parameters

26 |
27 |
label
28 |
Pointer to the null-terminated string that specifies the volume label to be set.
29 |
30 |
31 | 32 | 33 |
34 |

Return Values

35 |

36 | FR_OK, 37 | FR_DISK_ERR, 38 | FR_INT_ERR, 39 | FR_NOT_READY, 40 | FR_INVALID_NAME, 41 | FR_WRITE_PROTECTED, 42 | FR_INVALID_DRIVE, 43 | FR_NOT_ENABLED, 44 | FR_NO_FILESYSTEM, 45 | FR_TIMEOUT 46 |

47 |
48 | 49 | 50 |
51 |

Description

52 |

When the string has a drive prefix, the volume label will be set to the volume specified by the drive prefix. Unix style volume ID cannot be used to specify the volume. If drive number is not specified, the volume label will be set to the default drive. If length of the given volume label is zero, the volume label on the volume will be removed. The format of the volume label is as shown below:

53 |
    54 |
  • Up to 11 bytes long as conversion of OEM code page at FAT volume.
  • 55 |
  • Up to 11 characters long at exFAT volume.
  • 56 |
  • Allowable characters for FAT volume are: characters allowed for SFN excludes dot. Low-case characters are up converted.
  • 57 |
  • Allowable characters for exFAT volume are: characters allowed for LFN includes dot. Low-case characters are preserved.
  • 58 |
  • Spaces can be embedded anywhere in the volume label. Trailing spaces are truncated off at FAT volume.
  • 59 |
60 |

Remark: The standard system (Windows) has a problem at the volume label with a heading \xE5 on the FAT volume. To avoid this problem, this function rejects such volume label as invalid name.

61 |
62 | 63 |
64 |

QuickInfo

65 |

Available when FF_FS_READONLY == 0 and FF_USE_LABEL == 1.

66 |
67 | 68 | 69 |
70 |

Example

71 |
72 |     /* Set volume label to the default drive */
73 |     f_setlabel("DATA DISK");
74 | 
75 |     /* Set volume label to the drive 2 */
76 |     f_setlabel("2:DISK 3 OF 4");
77 | 
78 |     /* Remove volume label of the drive 2 */
79 |     f_setlabel("2:");
80 | 
81 |
82 | 83 | 84 |
85 |

See Also

86 | f_getlabel 87 |
88 | 89 | 90 |

Return

91 | 92 | 93 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/getfree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_getfree 10 | 11 | 12 | 13 | 14 |
15 |

f_getfree

16 |

The f_getfree function gets number of the free clusters on the volume.

17 |
18 | FRESULT f_getfree (
19 |   const TCHAR* path,  /* [IN] Logical drive number */
20 |   DWORD* nclst,       /* [OUT] Number of free clusters */
21 |   FATFS** fatfs       /* [OUT] Corresponding filesystem object */
22 | );
23 | 
24 |
25 | 26 |
27 |

Parameters

28 |
29 |
path
30 |
Pointer to the null-terminated string that specifies the logical drive. A null-string means the default drive.
31 |
nclst
32 |
Pointer to the DWORD variable to store number of free clusters.
33 |
fatfs
34 |
Pointer to pointer that to store a pointer to the corresponding filesystem object.
35 |
36 |
37 | 38 | 39 |
40 |

Return Values

41 |

42 | FR_OK, 43 | FR_DISK_ERR, 44 | FR_INT_ERR, 45 | FR_NOT_READY, 46 | FR_INVALID_DRIVE, 47 | FR_NOT_ENABLED, 48 | FR_NO_FILESYSTEM, 49 | FR_TIMEOUT 50 |

51 |
52 | 53 | 54 |
55 |

Descriptions

56 |

The f_getfree function gets number of free clusters on the volume. The member csize in the filesystem object indicates number of sectors per cluster, so that the free space in unit of sector can be calcurated with this information. In case of FSINFO structure on the FAT32 volume is not in sync, this function can return an incorrect free cluster count. To avoid this problem, FatFs can be forced full FAT scan by FF_FS_NOFSINFO option.

57 |
58 | 59 | 60 |
61 |

QuickInfo

62 |

Available when FF_FS_READONLY == 0 and FF_FS_MINIMIZE == 0.

63 |
64 | 65 | 66 |
67 |

Example

68 |
69 |     FATFS *fs;
70 |     DWORD fre_clust, fre_sect, tot_sect;
71 | 
72 | 
73 |     /* Get volume information and free clusters of drive 1 */
74 |     res = f_getfree("1:", &fre_clust, &fs);
75 |     if (res) die(res);
76 | 
77 |     /* Get total sectors and free sectors */
78 |     tot_sect = (fs->n_fatent - 2) * fs->csize;
79 |     fre_sect = fre_clust * fs->csize;
80 | 
81 |     /* Print the free space (assuming 512 bytes/sector) */
82 |     printf("%10lu KiB total drive space.\n%10lu KiB available.\n", tot_sect / 2, fre_sect / 2);
83 | 
84 |
85 | 86 | 87 |
88 |

See Also

89 |

FATFS

90 |
91 | 92 |

Return

93 | 94 | 95 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/dwrite.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - disk_write 10 | 11 | 12 | 13 | 14 |
15 |

disk_write

16 |

The disk_write function is called to write data to the storage device.

17 |
18 | DRESULT disk_write (
19 |   BYTE pdrv,        /* [IN] Physical drive number */
20 |   const BYTE* buff, /* [IN] Pointer to the data to be written */
21 |   LBA_t sector,     /* [IN] Sector number to write from */
22 |   UINT count        /* [IN] Number of sectors to write */
23 | );
24 | 
25 |
26 | 27 |
28 |

Parameters

29 |
30 |
pdrv
31 |
Physical drive number to identify the target device.
32 |
buff
33 |
Pointer to the first item of the byte array to be written. The size of data to be written is sector size * count bytes.
34 |
sector
35 |
Start sector number in LBA. The data type LBA_t is an alias of DWORD or QWORD depends on the configuration option.
36 |
count
37 |
Number of sectors to write.
38 |
39 |
40 | 41 | 42 |
43 |

Return Values

44 |
45 |
RES_OK (0)
46 |
The function succeeded.
47 |
RES_ERROR
48 |
An unrecoverable hard error occured during the write operation.
49 |
RES_WRPRT
50 |
The medium is write protected.
51 |
RES_PARERR
52 |
Invalid parameter.
53 |
RES_NOTRDY
54 |
The device has not been initialized.
55 |
56 |
57 | 58 | 59 |
60 |

Description

61 |

The specified memory address is not that always aligned to word boundary because the argument is defined as BYTE*. For more information, refer to the description of disk_read function.

62 |

Generally, a multiple sector write request (count > 1) must not be split into single sector transactions to the storage device, or the file write throughput will be drastically decreased.

63 |

FatFs expects delayed write function of the disk control layer. The write operation to the media does not need to be completed when return from this function by what write operation is in progress or data is only stored into the write-back cache. But write data on the buff is invalid after return from this function. The write completion request is done by CTRL_SYNC command of disk_ioctl function. Therefore, if a delayed write function is implemented, the write throughput of the filesystem will be improved.

64 |

Remarks: Application program MUST NOT call this function, or FAT structure on the volume can be collapsed.

65 |
66 | 67 | 68 |
69 |

QuickInfo

70 |

This function is not needed when FF_FS_READONLY == 1.

71 |
72 | 73 | 74 |

Return

75 | 76 | 77 | -------------------------------------------------------------------------------- /src/fatfs/documents/css_e.css: -------------------------------------------------------------------------------- 1 | * {margin: 0; padding: 0; border-width: 0;} 2 | body {margin: 8px; background-color: #e0ffff; font-color: black; font-family: serif; line-height: 133%; max-width: 1024px;} 3 | a:link {color: blue;} 4 | a:visited {color: darkmagenta;} 5 | a:hover {background-color: #a0ffff;} 6 | a:active {color: darkmagenta; overflow: hidden; outline:none; position: relative; top: 1px; left: 1px;} 7 | abbr {border-width: 1px;} 8 | 9 | p {margin: 0 0 0.3em 1em;} 10 | i {margin: 0 0.3em 0 0;} 11 | b {margin: 0 0.1em;} 12 | em {font-style: normal; font-weight: bold; margin: 0 0.1em;} 13 | strong {} 14 | pre {border: 1px dashed gray; margin: 0.5em 1em; padding: 0.5em; line-height: 1.2em; font-size: 85%; font-family: "Consolas", "Courier New", monospace; background-color: white;} 15 | pre span.c {color: green;} 16 | pre span.k {color: blue;} 17 | pre span.e {color: red;} 18 | pre span.b {font-weight: bold;} 19 | pre span.arg {font-style: italic;} 20 | tt {margin: 0 0.2em; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; } 21 | tt.arg {font-style: italic;} 22 | ol {margin: 0.5em 2.5em;} 23 | ul {margin: 0.5em 2em;} 24 | ul ul {margin: 0 2em 0.5em 1em;} 25 | dl {margin: 0.5em 1em;} 26 | dd {margin: 0 2em;} 27 | dt {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace;} 28 | dl.par dt {margin: 0.5em 0 0 0 ; font-style: italic; } 29 | dl.ret dt {margin: 0.5em 0 0 0 ; font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; font-weight: bold; } 30 | hr {border-width: 1px; margin: 1em;} 31 | div.abst {font-family: sans-serif;} 32 | div.para {clear: both; font-family: serif;} 33 | div.ret a {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; } 34 | .equ {text-indent: 0; margin: 1em 2em 1em;} 35 | .indent {margin-left: 2em;} 36 | .rset {float: right; margin: 0.3em 0 0.5em 0.5em;} 37 | .lset {float: left; margin: 0.3em 0.5em 0.5em 0.5em;} 38 | ul.flat li {list-style-type: none; margin: 0;} 39 | a.imglnk img {border: 1px solid;} 40 | .iequ {white-space: nowrap; font-weight: bold;} 41 | .clr {clear: both;} 42 | .it {font-style: italic;} 43 | .mfd {font-size: 0.7em; padding: 0 1px; border: 1px solid; white-space : nowrap} 44 | .ral {text-align: right; } 45 | .lal {text-align: left; } 46 | .cal {text-align: center; } 47 | 48 | h1 {line-height: 1em; font-size: 2em; font-family: sans-serif; padding: 0.3em 0 0.3em;} 49 | h2 {font-size: 2em; font-family: sans-serif; background-color: #d8d8FF; padding: 0.5em 0.5em; margin: 0 0 0.5em;} 50 | h3 {font-size: 1.5em; font-family: sans-serif; margin: 1.5em 0 0.5em;} 51 | div.doc h3 {border-color: #b0d8d8; border-style: solid; border-width: 0px 0px 4px 12px; padding: 4px; margin-top: 3em;} 52 | h4 {font-size: 1.2em; font-family: sans-serif; margin: 2em 0 0.2em;} 53 | h5 {font-size: 1em; font-family: sans-serif; margin: 1em 0 0em;} 54 | p.hdd {float: right; text-align: right; margin-top: 0.5em;} 55 | hr.hds {clear: both; margin-bottom: 1em;} 56 | kbd {letter-spacing: 0;} 57 | small {font-size: 80%;} 58 | .indent {margin-left: 2em;} 59 | 60 | /* Tables */ 61 | table {margin: 0.5em 1em; border-collapse: collapse; border: 2px solid gray; } 62 | table caption {font-family: sans-serif; font-weight: bold;} 63 | table th {background-color: white; border-style: solid; border-width: 1px 1px 2px; border-color: gray; padding: 0 3px; vertical-align: top; white-space: nowrap;} 64 | table td {background-color: white; border: 1px solid gray; padding: 0 3px; vertical-align: top; line-height: 1.3em;} 65 | table.lst td:first-child {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} 66 | table.lst2 td {font-size: 0.85em; font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} 67 | table.lst3 td {font-family: "Consolas", "Courier New", monospace; white-space: nowrap;} 68 | tr.lst3 td {border-width: 2px 1px 1px; } 69 | table.lst4 td {padding: 0.3em;} 70 | table.lst4 td:nth-child(2) {width: 45%;} 71 | table.lst4 td:nth-child(3) {width: 45%;} 72 | 73 | p.foot {clear: both; text-indent: 0; margin: 1em 0.5em 1em;} 74 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/sfatfs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - FATFS 10 | 11 | 12 | 13 | 14 |
15 |

FATFS

16 |

The FATFS structure (filesystem object) holds dynamic work area of individual logical drives. It is given by application program and registerd/unregisterd to the FatFs module with f_mount function. Initialization of the structure is done by volume mount process whenever necessary. Application program must not modify any member in this structure, or the FAT volume will be collapsed.

17 |
18 | typedef struct {
19 |     BYTE    fs_type;      /* FAT type (0, FS_FAT12, FS_FAT16, FS_FAT32 or FS_EXFAT) */
20 |     BYTE    pdrv;         /* Hosting physical drive of this volume */
21 |     BYTE    n_fats;       /* Number of FAT copies (1,2) */
22 |     BYTE    wflag;        /* win[] flag (b0:win[] is dirty) */
23 |     BYTE    fsi_flag;     /* FSINFO flags (b7:Disabled, b0:Dirty) */
24 |     WORD    id;           /* Volume mount ID */
25 |     WORD    n_rootdir;    /* Number of root directory entries (FAT12/16) */
26 |     WORD    csize;        /* Sectors per cluster */
27 | #if FF_MAX_SS != FF_MIN_SS
28 |     WORD    ssize;        /* Sector size (512,1024,2048 or 4096) */
29 | #endif
30 | #if FF_FS_EXFAT
31 |     BYTE*   dirbuf;       /* Directory entry block scratchpad buffer */
32 | #endif
33 | #if FF_FS_REENTRANT
34 |     FF_SYNC_t sobj;       /* Identifier of sync object */
35 | #endif
36 | #if !FF_FS_READONLY
37 |     DWORD   last_clust;   /* FSINFO: Last allocated cluster (0xFFFFFFFF if invalid) */
38 |     DWORD   free_clust;   /* FSINFO: Number of free clusters (0xFFFFFFFF if invalid) */
39 | #endif
40 | #if FF_FS_RPATH
41 |     DWORD   cdir;         /* Cluster number of current directory (0:root) */
42 | #if FF_FS_EXFAT
43 |     DWORD   cdc_scl;      /* Containing directory start cluster (invalid when cdir is 0) */
44 |     DWORD   cdc_size;     /* b31-b8:Size of containing directory, b7-b0: Chain status */
45 |     DWORD   cdc_ofs;      /* Offset in the containing directory (invalid when cdir is 0) */
46 | #endif
47 | #endif
48 |     DWORD   n_fatent;     /* Number of FAT entries (Number of clusters + 2) */
49 |     DWORD   fsize;        /* Sectors per FAT */
50 |     LBA_t   volbase;      /* Volume base LBA */
51 |     LBA_t   fatbase;      /* FAT base LBA */
52 |     LBA_t   dirbase;      /* Root directory base (LBA|Cluster) */
53 |     LBA_t   database;     /* Data base LBA */
54 |     LBA_t   winsect;      /* Sector LBA appearing in the win[] */
55 |     BYTE    win[FF_MAX_SS]; /* Disk access window for directory, FAT (and file data at tiny cfg) */
56 | } FATFS;
57 | 
58 |
59 | 60 |

Return

61 | 62 | 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MiSTeryNano FPGA Companion 2 | 3 | The MiSTeryNano FPGA Companion implements support functions for FPGA 4 | based retro computing projects like [MiSTeryNano 5 | project](https://github.com/MiSTle-Dev/MiSTeryNano). While the FPGA 6 | typically implements the hardware of the retro machine itself the 7 | Companion uses a microcontroller to add support for modern peripherals 8 | like USB keyboard, mice and SD cards. It also implements an 9 | on-screen-display menu to allow the user to configure the retro 10 | machine. 11 | 12 | The FPGA Companion replaces the MiSTeryNano firmware that was 13 | formerly part of the [MiSTeryNano 14 | project](https://github.com/MiSTle-Dev/MiSTeryNano). It is also 15 | used by the [NanoMig](https://github.com/MiSTle-Dev/nanomig), 16 | the [NanoMac](https://github.com/MiSTle-Dev/nanomac), the 17 | [C64Nano](https://github.com/MiSTle-Dev/C64Nano), the 18 | [VIC20Nano](https://github.com/MiSTle-Dev/VIC20Nano), the 19 | [A2600Nano](https://github.com/MiSTle-Dev/A2600Nano) and the 20 | [NanoApple2](https://github.com/MiSTle-Dev/NanoApple2). 21 | 22 | ## Supported MCUs 23 | 24 | While the MiSTeryNano was initially designed with a BL616 MCU as the 25 | support MCU the FPGA Companion introduces more flexibility and allows 26 | to choose from different MCUs to act as the support MCU. From the 27 | FPGAs perspective these behave identical although not all MCUs may 28 | support all functions to the same extent and e.g. the ESP32 is rather 29 | limited when it comes to USB support. The MCU is communicating via [SPI](SPI.md) interface to the FPGA. 30 | 31 | Currently the FPGA Companion can be used with the following MCUs: 32 | 33 | - [M0S/BL616](https://wiki.sipeed.com/hardware/en/maixzero/m0s/m0s.html) or TANG onboard [BL616](https://en.bouffalolab.com/product/), see the [build instuctions](src/bl616), and 34 | - [Raspberry Pi Pico/RP2040](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html), see the [build instructions](src/rp2040) 35 | - [ESP32 S2/S3](https://www.espressif.com/en/products/socs/esp32-s2), see the [build instructions](src/esp32) 36 | 37 | ## Features and disadvantages of the different MCUs 38 | 39 | The inital version of MiSTeryNano relied on the BL616 as a support 40 | MCU. Some shortcomings of that platform caused the code to be ported 41 | to other MCUs which then may have their own advantages and 42 | disadvantages. 43 | 44 | ### BL616 45 | 46 | - Pros 47 | - Very powerful Risc-V CPU 48 | - USB 2.0 highspeed host support 49 | - WiFi 6 support 50 | - Bluetooth BLE 5.2 support 51 | - Cons 52 | - Limited SDK support 53 | - USB needs manual update of the [CherryUSB](https://github.com/cherry-embedded/CherryUSB) stack 54 | - No classic Bluetooth support 55 | 56 | ### RP2040 57 | 58 | - Pros 59 | - Powerful and well-supported SDK 60 | - Widely available and cheap 61 | - Fullspeed USB host support 62 | - Cons 63 | - No built-in bluetooth and WiFi support 64 | - Only available via seperate modules (e.g. on Pico(W)) 65 | 66 | ### ESP32-S2/S3 67 | 68 | - Pros 69 | - Powerful and well-supported SDK 70 | - Widely available and cheap 71 | - Built-in Bluetooth and WiFi 72 | - Cons 73 | - Very limited USB host support 74 | - Only one device (no hub) 75 | - USB stack complex to use 76 | 77 | ## Related projects 78 | 79 | You might also want to check out the following related projects: 80 | 81 | - [MiSTeryNano](https://github.com/MiSTle-Dev/MiSTeryNano) HDL implementation of the Atari ST home computer 82 | - [NanoMig](https://github.com/MiSTle-Dev/NanoMIG) HDL implementation of the Commodore Amiga home computer 83 | - [NanoMac](https://github.com/MiSTle-Dev/NanoMac) HDL implementation of the Apple Macintosh Plus computer 84 | - [C64 Nano](https://github.com/MiSTle-Dev/C64Nano) HDL implementationm of the Commodore C64 home computer 85 | - [VIC20 Nano](https://github.com/MiSTle-Dev/VIC20Nano) HDL implementation of the Commodore VIC20 home computer 86 | - [A2600 Nano](https://github.com/MiSTle-Dev/A2600Nano) HDL implementation of the Atari 2600 game console 87 | - [NanoApple2](https://github.com/MiSTle-Dev/NanoApple2) HDL implementation of the Apple IIe home computer 88 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | main.c - MiSTeryNano FPGA Companion Pi Pico variant 3 | 4 | */ 5 | 6 | #include "../mcu_hw.h" 7 | 8 | #include "../config.h" 9 | #include "../sysctrl.h" 10 | #include "../sdc.h" 11 | #include "../osd.h" 12 | #include "../menu.h" 13 | #include "../inifile.h" 14 | #include "../debug.h" 15 | #include "../xml.h" 16 | #include "../at_wifi.h" 17 | 18 | /*-----------------------------------------------------------*/ 19 | /*--- main FPGA communication task ----*/ 20 | /*-----------------------------------------------------------*/ 21 | 22 | TaskHandle_t com_task_handle = NULL; 23 | 24 | static void com_task(__attribute__((unused)) void *p ) { 25 | debugf("Starting main communication task"); 26 | 27 | // startup FPGA, this will also put the core into reset 28 | if(sys_wait4fpga()) { 29 | // FPGA is ready and can be talked to 30 | 31 | // initialitze SD card 32 | sdc_init(); 33 | 34 | // try to load a config .xml from sd card. If the core has identified itself, 35 | // then e.g. atarist.xml will be read. otherwise config.xml 36 | FIL fil; 37 | if(f_open(&fil, sys_get_config_name(), FA_OPEN_EXISTING | FA_READ) == FR_OK) { 38 | config_init(); 39 | 40 | UINT br; char c; 41 | debugf("Loading XML config from file"); 42 | 43 | // read byte by byte. Slow but that doesn't hurt ... 44 | FRESULT r = f_read(&fil, &c, 1, &br); 45 | while(r == FR_OK && br) { 46 | xml_parse(c); 47 | r = f_read(&fil, &c, 1, &br); 48 | } 49 | f_close(&fil); 50 | 51 | config_dump(); 52 | } else { 53 | // no XML on SD card, try to load from core itself 54 | char *cfg_str = sys_get_config(); 55 | if(cfg_str) { 56 | debugf("Loading XML config from core"); 57 | config_init(); 58 | char *c = cfg_str; 59 | while(*c) xml_parse(*c++); 60 | config_dump(); 61 | } else 62 | debugf("No valid config found, neither on sd card nor in core"); 63 | } 64 | 65 | // process any pending interrupt. Filter out irq 1 which is the 66 | // FPGA cold boot event which we ignore since we just booted outselves 67 | sys_handle_interrupts(sys_irq_ctrl(0xff), true); 68 | 69 | // by default, DB9 interrupts are disabled. Reading 70 | // the DB9 state enables them. This is what hid_handle_event 71 | // does. 72 | hid_handle_event(); 73 | 74 | if(!cfg) { 75 | // finally release FPGA from reset 76 | sys_set_val('R', 0); 77 | } 78 | 79 | // initialize on-screen-display and menu system 80 | osd_init(); 81 | menu_init(); 82 | 83 | // open disk images, either defaults set in sdc_init or 84 | // user configure ones from the ini file 85 | sdc_mount_defaults(); 86 | 87 | // finally prepare for wifi communication 88 | at_wifi_init(); 89 | 90 | debugf("Entering main loop"); 91 | 92 | for(;;) { 93 | mcu_hw_irq_ack(); // (re-)enable interrupt 94 | ulTaskNotifyTake( pdTRUE, portMAX_DELAY); 95 | sys_handle_interrupts(sys_irq_ctrl(0xff), false); 96 | } 97 | } 98 | 99 | /* This will only be reached if the FPGA is not ready */ 100 | /* So loop foreever while e.g. USB is still being handled */ 101 | /* e.g. for debugging */ 102 | 103 | #ifdef BOOT_FROM_SDC 104 | BOOT_FROM_SDC(); 105 | #endif 106 | 107 | for(;;) { 108 | // frequently check for an FPGA to show up and reboot to 109 | // startup normally if one is detected 110 | if(sys_status_is_valid()) { 111 | debugf("FPGA detected!"); 112 | // This may be due to a USB download. So give USB 113 | // some time to finish. The same happens in sysconfig.c 114 | vTaskDelay(pdMS_TO_TICKS(2000)); 115 | mcu_hw_reset(); 116 | } 117 | 118 | vTaskDelay(pdMS_TO_TICKS(250)); 119 | } 120 | } 121 | 122 | #ifdef ESP_PLATFORM 123 | void app_main( void ) 124 | #else 125 | int main( void ) 126 | #endif 127 | { 128 | mcu_hw_init(); 129 | 130 | // run FPGA com thread 131 | xTaskCreate( com_task, "FPGA Com", 4096, NULL, CONFIG_MAX_PRIORITY-1, &com_task_handle ); 132 | 133 | mcu_hw_main_loop(); 134 | 135 | #ifndef ESP_PLATFORM 136 | return 0; 137 | #endif 138 | } 139 | /*-----------------------------------------------------------*/ 140 | 141 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/dread.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - disk_read 10 | 11 | 12 | 13 | 14 |
15 |

disk_read

16 |

The disk_read function is called to read data from the storage device.

17 |
18 | DRESULT disk_read (
19 |   BYTE pdrv,     /* [IN] Physical drive number */
20 |   BYTE* buff,    /* [OUT] Pointer to the read data buffer */
21 |   LBA_t sector,  /* [IN] Start sector number */
22 |   UINT count     /* [IN] Number of sectros to read */
23 | );
24 | 
25 |
26 | 27 |
28 |

Parameters

29 |
30 |
pdrv
31 |
Physical drive number to identify the target device.
32 |
buff
33 |
Pointer to the first item of the byte array to store read data. Size of read data will be the sector size * count bytes.
34 |
sector
35 |
Start sector number in LBA. The data type LBA_t is an alias of DWORD or QWORD depends on the configuration option.
36 |
count
37 |
Number of sectors to read.
38 |
39 |
40 | 41 | 42 |
43 |

Return Value

44 |
45 |
RES_OK (0)
46 |
The function succeeded.
47 |
RES_ERROR
48 |
An unrecoverable hard error occured during the read operation.
49 |
RES_PARERR
50 |
Invalid parameter.
51 |
RES_NOTRDY
52 |
The device has not been initialized.
53 |
54 |
55 | 56 | 57 |
58 |

Description

59 |

Read/write operation to the generic storage devices, such as memory card, hadddisk and optical disk, is done in unit of block of data bytes called sector. FatFs supports the sector size in range of 512 to 4096 bytes. When FatFs is configured for fixed sector size (FF_MIN_SS == FF_MAX_SS, this is the most case), the generic read/write function must work at this sector size only. When FatFs is configured for variable sector size (FF_MIN_SS < FF_MAX_SS), the sector size of medium is inquired with disk_ioctl function after disk_initialize function succeeds.

60 |

There are some considerations about the memory addres passed via buff. It is not that always aligned with the word boundary, because the argument is defined as BYTE*. The unaligned transfer request can occure at direct transfer. If the bus architecture, especially DMA controller, does not allow unaligned memory access, it should be solved in this function. If it is the case, there are some workarounds described below to avoid this issue.

61 |
    62 |
  • Convert word transfer to byte transfer with some trick in this function. - Recommended.
  • 63 |
  • On the f_read() calls, avoid long read request that includes a whole of sector. - Any direct transfer never occures.
  • 64 |
  • On the f_read(fp, data, btw, bw) calls, make sure that (((UINT)data & 3) == (f_tell(fp) & 3)) is true. - Word alignment of buff is guaranteed.
  • 65 |
66 |

Also the memory area may be out of reach in DMA. This is the case if it is located on the tightly coupled memory which is usually used for stack. Use double buffered transfer, or avoid to define file I/O buffer, FATFS and FIL structure as local variables where on the stack.

67 |

Generally, a multiple sector read request must not be split into single sector transactions to the storage device, or read throughput gets worse.

68 |
69 | 70 | 71 |

Return

72 | 73 | 74 | -------------------------------------------------------------------------------- /src/esp32/README.md: -------------------------------------------------------------------------------- 1 | # MiSTeryNano FPGA companion ESP32 variant 2 | 3 | This is the variant of the 4 | [MiSTeryNano](https://github.com/MiSTle-Dev/MiSTeryNano) FPGA companion 5 | firmware for the ESP32-S2 and ESP32-S3. 6 | 7 | ## USB Support 8 | 9 | You need an ESP32 variant with native USB support, preferrably through 10 | a second USB connector. Such a board has two USB-C connectors, one 11 | usually being labeled COM and servicing a USB UART (COM port) as 12 | typical for ESP32 boards and the second one giving access to the 13 | ESP32's native USB port which can be operated in USB host mode to 14 | connect a device like a keyboard or a mouse. 15 | 16 | Currently the ESP32-S2 and ESP32-S3 are supported. Still, USB support 17 | on these devices is rather limited and only one directly connected USB 18 | device is supported. Hubs are not supported and thus the use of a 19 | (wireless) keyboard/mouse combo device like the [Rii 20 | R8](http://www.riitek.eu/DE/Produkte/RT-MWK08RF_DE.html) makes the 21 | most sense for a retro home computer setup. This does not leave a port 22 | for a USB joystick which will instead have to be e.g. a retro joystick 23 | connected directly to the FPGA. 24 | 25 | ### Hardware modifications 26 | 27 | Most ESP32 boards that come with two USB ports are designed to 28 | be powered from one of three power sources: The COM USB, the 29 | native USB or an external 5V power source, but no to provide power 30 | _to_ any of these. 31 | 32 | For this project it's preferred if the whole setup can be pwoered from 33 | the COM USB port providing power to other USB devices connected to the 34 | native USB. Furthermore the FPGA may also be powered from this source. 35 | Some boards have solder jumpers e.g. labeled ```USB OTG``` and 36 | ```IN-OUT``` which can provide this. On other boards it may be 37 | necessary to remove/bridge diodes. 38 | 39 | ## Features and limitations 40 | 41 | - Requires an ESP32 variante with USB host support (ESP32-S2 or S3) 42 | - Only one USB device possible (no hubs) 43 | - Can provide wireless network connectivity (not yet implemented) 44 | - Can provide support for Bluetooth peripherials (not yet implemented) 45 | 46 | ## Building 47 | 48 | Get the esp-idf as explained [here](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/linux-macos-setup.html) and install the toolchain: 49 | 50 | ``` 51 | git clone -b v5.4.1 --recursive https://github.com/espressif/esp-idf.git 52 | cd esp-idf 53 | ./install.sh esp32s2,esp32s3 54 | . ./export.sh 55 | ```` 56 | 57 | You'll then need to make a few adjustments: 58 | 59 | First specify which CPU you are using. Either 60 | 61 | ``` 62 | idf.py set-target esp32s2 63 | ``` 64 | 65 | or 66 | 67 | ``` 68 | idf.py set-target esp32s3 69 | ``` 70 | 71 | Then in ```esp-idf/components/fatfs/src/ffconf.h``` you need to 72 | manually set 73 | ``` 74 | #define FF_FS_EXFAT 1 75 | ``` 76 | 77 | Then enter the menu by 78 | 79 | ``` 80 | idf.py menuconfig 81 | ``` 82 | 83 | and change a few settings: 84 | 85 | - Navigate into ```Component Config``` and then into ```FAT Filesystem Support```. 86 | - Activate the ```Enable fast seek algorithm ...``` option 87 | - Set the ```Sector Size``` to 512 88 | - Set ```Long filename support``` to ```Long filename buffer in heap``` 89 | - Set ```Enable String functions``` to ```1: Enable without LR-CRLF conversion``` 90 | - Enable ```Use FATFS volume label``` 91 | - Navigate to ```Component Config``` and then to ```Wear Leveling``` 92 | - Set ```Wear Levelling library sector size``` to 512 93 | - Navigate to ```Component Config``` and then to ```FreeRTOS``` and ```Kernel``` 94 | - Set ```configTICK_RATE_HZ``` to 1000 95 | 96 | Finally start the build with 97 | 98 | ``` 99 | idf.py build 100 | ``` 101 | 102 | If successful the resulting binary can be flashed: 103 | 104 | ``` 105 | idf.py -p /dev/ttyUSB0 flash 106 | ``` 107 | 108 | Additional debug output is sent via UART at 115200 bit/s 109 | 110 | # Pin usage 111 | 112 | | Pin | Signal | Description | 113 | |---|---|---| 114 | | TX | UART_TX | Serial debug output | 115 | | GPIO20 | USB D+ | USB host D+ | 116 | | GPIO19 | USB D- | USB host D- | 117 | | GPIO14 | IRQn | SPI interrupt from FPGA | 118 | | GPIO13 | MISO | SPI data from FPGA | 119 | | GPIO12 | SCK | SPI clock to FPGA | 120 | | GPIO11 | MOSI | SPI data to FPGA | 121 | | GPIO10 | CSn | SPI chip select to FPGA | 122 | 123 | # Example wiring 124 | 125 | ![Tang Nano 20k with ESP32s2](esp32s2_tn20k.png) 126 | -------------------------------------------------------------------------------- /src/rp2040/freertos_callbacks.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "FreeRTOS.h" 4 | #include "task.h" 5 | 6 | void *pvPortRealloc( void *pv, size_t size ){ 7 | vPortFree ( pv ); 8 | return pvPortMalloc( size ); 9 | } 10 | 11 | /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide 12 | an implementation of vApplicationGetIdleTaskMemory() to provide the memory that 13 | is used by the Idle task. */ 14 | void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 15 | StackType_t **ppxIdleTaskStackBuffer, 16 | uint32_t *pulIdleTaskStackSize) { 17 | /* If the buffers to be provided to the Idle task are declared inside this 18 | function then they must be declared static – otherwise they will be 19 | allocated on the stack and so not exists after this function exits. */ 20 | static StaticTask_t xIdleTaskTCB; 21 | static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE] 22 | __attribute__((aligned)); 23 | 24 | /* Pass out a pointer to the StaticTask_t structure in which the Idle task’s 25 | state will be stored. */ 26 | *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; 27 | 28 | /* Pass out the array that will be used as the Idle task’s stack. */ 29 | *ppxIdleTaskStackBuffer = uxIdleTaskStack; 30 | 31 | /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. 32 | Note that, as the array is necessarily of type StackType_t, 33 | configMINIMAL_STACK_SIZE is specified in words, not bytes. */ 34 | *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; 35 | } 36 | void vApplicationGetPassiveIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 37 | StackType_t **ppxIdleTaskStackBuffer, 38 | uint32_t *pulIdleTaskStackSize, 39 | BaseType_t xCoreID) { 40 | /* If the buffers to be provided to the Idle task are declared inside this 41 | function then they must be declared static – otherwise they will be 42 | allocated on the stack and so not exists after this function exits. */ 43 | static StaticTask_t xIdleTaskTCB[configNUMBER_OF_CORES]; 44 | static StackType_t uxIdleTaskStack[configNUMBER_OF_CORES][configMINIMAL_STACK_SIZE] 45 | __attribute__((aligned)); 46 | 47 | configASSERT(xCoreID < configNUMBER_OF_CORES); 48 | 49 | /* Pass out a pointer to the StaticTask_t structure in which the Idle task’s 50 | state will be stored. */ 51 | *ppxIdleTaskTCBBuffer = &xIdleTaskTCB[xCoreID]; 52 | 53 | /* Pass out the array that will be used as the Idle task’s stack. */ 54 | *ppxIdleTaskStackBuffer = uxIdleTaskStack[xCoreID]; 55 | 56 | /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. 57 | Note that, as the array is necessarily of type StackType_t, 58 | configMINIMAL_STACK_SIZE is specified in words, not bytes. */ 59 | *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; 60 | } 61 | 62 | /* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so 63 | the application must provide an implementation of 64 | vApplicationGetTimerTaskMemory() 65 | to provide the memory that is used by the Timer service task. */ 66 | void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 67 | StackType_t **ppxTimerTaskStackBuffer, 68 | uint32_t *pulTimerTaskStackSize) { 69 | /* If the buffers to be provided to the Timer task are declared inside this 70 | function then they must be declared static – otherwise they will be 71 | allocated on the stack and so not exists after this function exits. */ 72 | static StaticTask_t xTimerTaskTCB; 73 | static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH] 74 | __attribute__((aligned)); 75 | 76 | /* Pass out a pointer to the StaticTask_t structure in which the Timer 77 | task’s state will be stored. */ 78 | *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; 79 | 80 | /* Pass out the array that will be used as the Timer task’s stack. */ 81 | *ppxTimerTaskStackBuffer = uxTimerTaskStack; 82 | 83 | /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. 84 | Note that, as the array is necessarily of type StackType_t, 85 | configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ 86 | *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; 87 | } 88 | -------------------------------------------------------------------------------- /src/fatfs/documents/doc/stat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | FatFs - f_stat 10 | 11 | 12 | 13 | 14 |
15 |

f_stat

16 |

The f_stat function checks the existence of a file or sub-directory.

17 |
 18 | FRESULT f_stat (
 19 |   const TCHAR* path,  /* [IN] Object name */
 20 |   FILINFO* fno        /* [OUT] FILINFO structure */
 21 | );
 22 | 
23 |
24 | 25 |
26 |

Parameters

27 |
28 |
path
29 |
Pointer to the null-terminated string that specifies the object to get its information. The object must not be the root direcotry.
30 |
fno
31 |
Pointer to the blank FILINFO structure to store the information of the object. Set null pointer if this information is not needed.
32 |
33 |
34 | 35 | 36 |
37 |

Return Values

38 |

39 | FR_OK, 40 | FR_DISK_ERR, 41 | FR_INT_ERR, 42 | FR_NOT_READY, 43 | FR_NO_FILE, 44 | FR_NO_PATH, 45 | FR_INVALID_NAME, 46 | FR_INVALID_DRIVE, 47 | FR_NOT_ENABLED, 48 | FR_NO_FILESYSTEM, 49 | FR_TIMEOUT, 50 | FR_NOT_ENOUGH_CORE 51 |

52 |
53 | 54 | 55 |
56 |

Description

57 |

The f_stat function checks the existence of a file or sub-directory in the directory. If it is not exist, the function returns with FR_NO_FILE. If it is exist, the function returns with FR_OK and the informations about the object, size, timestamp and attribute, is stored to the file information structure. For details of the file information, refer to the FILINFO structure and f_readdir function.

58 |

Note that the file information comes from the meta data in the directory. If the file has been opend and modified, the file will need to be synched or closed in order to obtain the latest file information.

59 |
60 | 61 | 62 |
63 |

QuickInfo

64 |

Available when FF_FS_MINIMIZE == 0.

65 |
66 | 67 | 68 |
69 |

Example

70 |
 71 |     FRESULT fr;
 72 |     FILINFO fno;
 73 |     const char *fname = "file.txt";
 74 | 
 75 | 
 76 |     printf("Test for \"%s\"...\n", fname);
 77 | 
 78 |     fr = f_stat(fname, &fno);
 79 |     switch (fr) {
 80 | 
 81 |     case FR_OK:
 82 |         printf("Size: %lu\n", fno.fsize);
 83 |         printf("Timestamp: %u-%02u-%02u, %02u:%02u\n",
 84 |                (fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,
 85 |                fno.ftime >> 11, fno.ftime >> 5 & 63);
 86 |         printf("Attributes: %c%c%c%c%c\n",
 87 |                (fno.fattrib & AM_DIR) ? 'D' : '-',
 88 |                (fno.fattrib & AM_RDO) ? 'R' : '-',
 89 |                (fno.fattrib & AM_HID) ? 'H' : '-',
 90 |                (fno.fattrib & AM_SYS) ? 'S' : '-',
 91 |                (fno.fattrib & AM_ARC) ? 'A' : '-');
 92 |         break;
 93 | 
 94 |     case FR_NO_FILE:
 95 |         printf("\"%s\" is not exist.\n", fname);
 96 |         break;
 97 | 
 98 |     default:
 99 |         printf("An error occured. (%d)\n", fr);
100 |     }
101 | 
102 |
103 | 104 | 105 |
106 |

References

107 |

f_opendir, f_readdir, FILINFO

108 |
109 | 110 |

Return

111 | 112 | 113 | -------------------------------------------------------------------------------- /src/xml.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "xml.h" 5 | #include "debug.h" 6 | 7 | /* ======================== very simple xml stream parser ======================== */ 8 | 9 | static int state = 0; 10 | static int depth = 0; 11 | 12 | void xml_init(void) { 13 | state = 0; // wait for open tag 14 | depth = 0; // start in root level 15 | } 16 | 17 | static int xml_iswhite(unsigned char c) { 18 | return (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'); 19 | } 20 | 21 | // append char to string 22 | static char *xml_str_expand(char *s, char c) { 23 | int len = 0; 24 | 25 | if(!s) s = malloc(2); 26 | else { 27 | len = strlen(s); 28 | // reallocate with space for term char and new char 29 | s = realloc(s, len+2); 30 | } 31 | 32 | s[len] = c; 33 | s[len+1] = '\0'; 34 | return s; 35 | } 36 | 37 | int xml_parse(char c) { 38 | static char *name = NULL; 39 | static char *value = NULL; 40 | static int skip = 0; 41 | 42 | // debugf("S%d: %d (%c)", state, c, (c>=32)?c:'.'); 43 | 44 | switch(state) { 45 | case 0: // waiting for element start 46 | if(c == '<') state = 1; 47 | break; 48 | 49 | case 1: // first char after element start 50 | if(c == '?' || c == '!') state = 2; 51 | else if(c == '/') state = 10; 52 | else { 53 | // first char of element name, start buffering 54 | name = xml_str_expand(NULL, c); 55 | state = 3; 56 | } 57 | break; 58 | 59 | case 2: // in or , bot are ignored 60 | if(c == '>') state = 0; 61 | break; 62 | 63 | case 3: // reading element name 64 | if(c == '/') { 65 | if(!skip) { 66 | if(xml_element_start_cb(name) != 0) skip = 1; 67 | } else skip++; 68 | if(name) free(name); 69 | name = NULL; 70 | if(!skip) xml_element_end_cb(); 71 | else skip--; 72 | state = 2; 73 | } else if(!xml_iswhite(c) && c != '>') name = xml_str_expand(name, c); 74 | else { 75 | if(!skip) { 76 | if(xml_element_start_cb(name) != 0) skip = 1; 77 | } else skip++; 78 | 79 | if(c == '>') state = 0; 80 | else state = 4; 81 | } 82 | break; 83 | 84 | case 4: // search for attributes (if present) 85 | if(c == '>') state = 0; 86 | else if(c == '/') { 87 | if(!skip) xml_element_end_cb(); 88 | else skip--; 89 | if(name) free(name); 90 | name = NULL; 91 | state = 0; 92 | } else if(!xml_iswhite(c)) { 93 | name = xml_str_expand(NULL, c); 94 | state = 5; 95 | } 96 | break; 97 | 98 | case 5: // reading attribute name 99 | if(c == '>') { 100 | debugf("unexpected '>' after attribute name"); 101 | state = -1; 102 | } else if(!xml_iswhite(c) && c != '=') name = xml_str_expand(name, c); 103 | else if(c == '=') state = 7; 104 | else state = 6; 105 | break; 106 | 107 | case 6: // search for equal sign 108 | if(c == '=') state = 7; 109 | else if(!xml_iswhite(c)) { 110 | debugf("expected '='"); 111 | state = -1; 112 | } 113 | break; 114 | 115 | case 7: // search for attribute value 116 | if(c == '\"') state = 8; 117 | else if(c == '\'') state = 9; 118 | else if(!xml_iswhite(c)) { 119 | debugf("attribute value does not start with ' or \""); 120 | state = -1; 121 | } 122 | break; 123 | 124 | case 8: // attribute value started with " 125 | case 9: // attribute value started with ' 126 | if((state == 8 && c == '\"') || 127 | (state == 9 && c == '\'')) { 128 | if(!skip) xml_attribute_cb(name, value); 129 | if(name) free(name); 130 | name = NULL; 131 | if(value) free(value); 132 | value = NULL; 133 | state = 4; // -> search for next attribute 134 | } else { 135 | value = xml_str_expand(value, c); 136 | 137 | // check if string now ends with escaped char 138 | if(strlen(value)>=5 && !strcasecmp("&", value+strlen(value)-5)) 139 | strcpy(value+strlen(value)-5, "&"); 140 | else if(strlen(value)>=4 && !strcasecmp("<", value+strlen(value)-4)) 141 | strcpy(value+strlen(value)-4, "<"); 142 | else if(strlen(value)>=4 && !strcasecmp(">", value+strlen(value)-4)) 143 | strcpy(value+strlen(value)-4, ">"); 144 | } 145 | break; 146 | 147 | case 10: // closing element 148 | if(c == '>') { 149 | if(!skip) xml_element_end_cb(); 150 | else skip--; 151 | state = 0; 152 | } 153 | break; 154 | } 155 | 156 | return 0; 157 | } 158 | 159 | -------------------------------------------------------------------------------- /src/fatfs/documents/res/app3.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------/ 2 | / Allocate a contiguous area to the file 3 | /-----------------------------------------------------------------------/ 4 | / This function checks if the file is contiguous with desired size. 5 | / If not, a block of contiguous sectors is allocated to the file. 6 | / If the file has been opened without FA_WRITE flag, it only checks if 7 | / the file is contiguous and returns the resulut. 8 | /-----------------------------------------------------------------------/ 9 | / This function can work with FatFs R0.09 - R0.11a. 10 | / It is incompatible with R0.12+. Use f_expand function instead. 11 | /----------------------------------------------------------------------*/ 12 | 13 | /* Declarations of FatFs internal functions accessible from applications. 14 | / This is intended to be used for disk checking/fixing or dirty hacks :-) */ 15 | DWORD clust2sect (FATFS* fs, DWORD clst); 16 | DWORD get_fat (FATFS* fs, DWORD clst); 17 | FRESULT put_fat (FATFS* fs, DWORD clst, DWORD val); 18 | 19 | 20 | DWORD allocate_contiguous_clusters ( /* Returns the first sector in LBA (0:error or not contiguous) */ 21 | FIL* fp, /* Pointer to the open file object */ 22 | DWORD len /* Number of bytes to allocate */ 23 | ) 24 | { 25 | DWORD csz, tcl, ncl, ccl, cl; 26 | 27 | 28 | if (f_lseek(fp, 0) || !len) /* Check if the given parameters are valid */ 29 | return 0; 30 | csz = 512UL * fp->fs->csize; /* Cluster size in unit of byte (assuming 512 bytes/sector) */ 31 | tcl = (len + csz - 1) / csz; /* Total number of clusters required */ 32 | len = tcl * csz; /* Round-up file size to the cluster boundary */ 33 | 34 | /* Check if the existing cluster chain is contiguous */ 35 | if (len == fp->fsize) { 36 | ncl = 0; ccl = fp->sclust; 37 | do { 38 | cl = get_fat(fp->fs, ccl); /* Get the cluster status */ 39 | if (cl + 1 < 3) return 0; /* Hard error? */ 40 | if (cl != ccl + 1 && cl < fp->fs->n_fatent) break; /* Not contiguous? */ 41 | ccl = cl; 42 | } while (++ncl < tcl); 43 | if (ncl == tcl) /* Is the file contiguous? */ 44 | return clust2sect(fp->fs, fp->sclust); /* File is contiguous. Return the start sector */ 45 | } 46 | 47 | /* File is not contiguous */ 48 | #if _FS_READONLY 49 | return 0; /* Exit if in read-only cfg. */ 50 | #else 51 | if (!(fp->flag & FA_WRITE)) return 0; /* Exit if the file object is for read-only */ 52 | 53 | if (f_truncate(fp)) return 0; /* Remove the non-contiguous chain */ 54 | 55 | /* Find a free contiguous area */ 56 | ccl = cl = 2; ncl = 0; 57 | do { 58 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */ 59 | if (get_fat(fp->fs, cl)) { /* Encounterd a cluster in use */ 60 | do { /* Skip the block of used clusters */ 61 | cl++; 62 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */ 63 | } while (get_fat(fp->fs, cl)); 64 | ccl = cl; ncl = 0; 65 | } 66 | cl++; ncl++; 67 | } while (ncl < tcl); 68 | 69 | /* Create a contiguous cluster chain */ 70 | fp->fs->last_clust = ccl - 1; 71 | if (f_lseek(fp, len)) return 0; 72 | 73 | return clust2sect(fp->fs, fp->sclust); /* Return file start sector */ 74 | #endif 75 | } 76 | 77 | 78 | int main (void) 79 | { 80 | FRESULT fr; 81 | DRESULT dr; 82 | FATFS fs; 83 | FIL fil; 84 | DWORD org; 85 | 86 | 87 | /* Open or create a file to write */ 88 | f_mount(&fs, "", 0); 89 | fr = f_open(&fil, "fastrec.log", FA_READ | FA_WRITE | FA_OPEN_ALWAYS); 90 | if (fr) return 1; 91 | 92 | /* Check if the file is 256MB in size and occupies a contiguous area. 93 | / If not, a contiguous area will be re-allocated to the file. */ 94 | org = allocate_contiguous_clusters(&fil, 0x10000000); 95 | if (!org) { 96 | printf("Function failed due to any error or insufficient contiguous area.\n"); 97 | f_close(&fil); 98 | return 1; 99 | } 100 | 101 | /* Now you can read/write the file without filesystem layer. */ 102 | ... 103 | dr = disk_write(fil.fs->drv, Buff, org, 1024); /* Write 512KiB from top of the file */ 104 | ... 105 | 106 | f_close(&fil); 107 | return 0; 108 | } 109 | 110 | -------------------------------------------------------------------------------- /src/rp2040/FreeRTOS_Kernel_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /portable/ThirdParty/GCC/RP2040/FREERTOS_KERNEL_import.cmake 2 | 3 | # This can be dropped into an external project to help locate the FreeRTOS kernel 4 | # It should be include()ed prior to project(). Alternatively this file may 5 | # or the CMakeLists.txt in this directory may be included or added via add_subdirectory 6 | # respectively. 7 | 8 | if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH)) 9 | set(FREERTOS_KERNEL_PATH $ENV{FREERTOS_KERNEL_PATH}) 10 | message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')") 11 | endif () 12 | 13 | # first pass we look in old tree; second pass we look in new tree 14 | foreach(SEARCH_PASS RANGE 0 1) 15 | if (SEARCH_PASS) 16 | # ports may be moving to submodule in the future 17 | set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/Community-Supported-Ports/GCC") 18 | set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../../..") 19 | else() 20 | set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC") 21 | set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") 22 | endif() 23 | 24 | if(PICO_PLATFORM STREQUAL "rp2040") 25 | set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2040") 26 | else() 27 | if (PICO_PLATFORM STREQUAL "rp2350-riscv") 28 | set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_RISC-V") 29 | else() 30 | set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_ARM_NTZ") 31 | endif() 32 | endif() 33 | 34 | if (NOT FREERTOS_KERNEL_PATH) 35 | # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) 36 | get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) 37 | get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) 38 | if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) 39 | get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) 40 | endif() 41 | if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) 42 | get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) 43 | message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") 44 | break() 45 | elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") 46 | set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) 47 | message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") 48 | break() 49 | endif() 50 | endif () 51 | 52 | if (NOT FREERTOS_KERNEL_PATH) 53 | foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel ../FreeRTOS-Kernel FreeRTOS/Source) 54 | # check if FreeRTOS-Kernel exists under directory that included us 55 | set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) 56 | get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) 57 | if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) 58 | get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) 59 | message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") 60 | break() 61 | endif() 62 | endforeach() 63 | if (FREERTOS_KERNEL_PATH) 64 | break() 65 | endif() 66 | endif() 67 | 68 | # user must have specified 69 | if (FREERTOS_KERNEL_PATH) 70 | if (EXISTS "${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") 71 | break() 72 | endif() 73 | endif() 74 | endforeach () 75 | 76 | if (NOT FREERTOS_KERNEL_PATH) 77 | message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.") 78 | endif() 79 | 80 | set(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" CACHE PATH "Path to the FreeRTOS Kernel") 81 | 82 | get_filename_component(FREERTOS_KERNEL_PATH "${FREERTOS_KERNEL_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 83 | if (NOT EXISTS ${FREERTOS_KERNEL_PATH}) 84 | message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found") 85 | endif() 86 | if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) 87 | message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain a '${PICO_PLATFORM}' port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") 88 | endif() 89 | set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE) 90 | 91 | add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) 92 | 93 | message("FreeRTOS available at ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") 94 | -------------------------------------------------------------------------------- /src/rp2040/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | #include "bsp/board_api.h" 2 | #include "tusb.h" 3 | 4 | //--------------------------------------------------------------------+ 5 | // Device Descriptors 6 | //--------------------------------------------------------------------+ 7 | static tusb_desc_device_t const desc_device = { 8 | .bLength = sizeof(tusb_desc_device_t), 9 | .bDescriptorType = TUSB_DESC_DEVICE, 10 | .bcdUSB = 0x0200, 11 | 12 | .bDeviceClass = 0x00, 13 | .bDeviceSubClass = 0x00, 14 | .bDeviceProtocol = 0x00, 15 | 16 | .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, 17 | 18 | .idVendor = 0x0403, 19 | #if JTAG_CHANNELS == 2 20 | .idProduct = 0x6010, 21 | .bcdDevice = 0x0500, 22 | #else 23 | .idProduct = 0x6014, 24 | .bcdDevice = 0x0900, 25 | #endif 26 | 27 | .iManufacturer = 0x01, 28 | .iProduct = 0x02, 29 | .iSerialNumber = 0x03, 30 | 31 | .bNumConfigurations = 0x01 32 | }; 33 | 34 | // Invoked when received GET DEVICE DESCRIPTOR 35 | // Application return pointer to descriptor 36 | uint8_t const* tud_descriptor_device_cb(void) { 37 | return (uint8_t const*) &desc_device; 38 | } 39 | 40 | //--------------------------------------------------------------------+ 41 | // Configuration Descriptor 42 | //--------------------------------------------------------------------+ 43 | 44 | #define TUD_MPSSE_IF_DESCRIPTOR(_itfnum) \ 45 | 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, 2, 0xff, 0xff, 0xff, 2 46 | 47 | #define TUD_MPSSE_IF_DESCRIPTOR_LEN 9u 48 | 49 | #define TUD_MPSSE_BULK_DESCRIPTORS(_epin, _epout) \ 50 | 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(64), 0u, \ 51 | 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(64), 0u 52 | 53 | #define TUD_MPSSE_BULK_DESCRIPTORS_LEN (7u+7u) 54 | 55 | #if JTAG_CHANNELS == 2 56 | #define TUD_MPSSE_DESC \ 57 | TUD_MPSSE_IF_DESCRIPTOR(0), TUD_MPSSE_BULK_DESCRIPTORS(0x81, 0x02), \ 58 | TUD_MPSSE_IF_DESCRIPTOR(1), TUD_MPSSE_BULK_DESCRIPTORS(0x83, 0x04) 59 | 60 | #define TUD_MPSSE_DESC_LEN (2*(TUD_MPSSE_IF_DESCRIPTOR_LEN + TUD_MPSSE_BULK_DESCRIPTORS_LEN)) 61 | #else 62 | #define TUD_MPSSE_DESC \ 63 | TUD_MPSSE_IF_DESCRIPTOR(0), TUD_MPSSE_BULK_DESCRIPTORS(0x81, 0x02) 64 | 65 | #define TUD_MPSSE_DESC_LEN (TUD_MPSSE_IF_DESCRIPTOR_LEN + TUD_MPSSE_BULK_DESCRIPTORS_LEN) 66 | #endif 67 | 68 | // full speed configuration 69 | static uint8_t const desc_fs_configuration[] = { 70 | // Config number, interface count, string index, total length, attribute, power in mA 71 | TUD_CONFIG_DESCRIPTOR(1, 2, 0, TUD_CONFIG_DESC_LEN + TUD_MPSSE_DESC_LEN, 0x00, 100), 72 | TUD_MPSSE_DESC 73 | }; 74 | 75 | // Invoked when received GET CONFIGURATION DESCRIPTOR 76 | // Application return pointer to descriptor 77 | // Descriptor contents must exist long enough for transfer to complete 78 | uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { 79 | // (void) index; // for multiple configurations 80 | return desc_fs_configuration; 81 | } 82 | 83 | //--------------------------------------------------------------------+ 84 | // String Descriptors 85 | //--------------------------------------------------------------------+ 86 | 87 | // String Descriptor Index 88 | enum { 89 | STRID_LANGID = 0, 90 | STRID_MANUFACTURER, 91 | STRID_PRODUCT, 92 | STRID_SERIAL 93 | }; 94 | 95 | // array of pointer to string descriptors 96 | char const* string_desc_arr[] = { 97 | (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409) 98 | "MiSTle Project", // 1: Manufacturer 99 | "FPGA Companion", // 2: Product 100 | NULL // 3: Serials will use unique ID if possible 101 | }; 102 | 103 | static uint16_t _desc_str[32 + 1]; 104 | 105 | // Invoked when received GET STRING DESCRIPTOR request 106 | // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete 107 | uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { 108 | (void) langid; 109 | size_t chr_count; 110 | 111 | switch (index) { 112 | case STRID_LANGID: 113 | memcpy(&_desc_str[1], string_desc_arr[0], 2); 114 | chr_count = 1; 115 | break; 116 | 117 | case STRID_SERIAL: 118 | chr_count = board_usb_get_serial(_desc_str + 1, 32); 119 | break; 120 | 121 | default: 122 | // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. 123 | // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors 124 | 125 | if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL; 126 | 127 | const char* str = string_desc_arr[index]; 128 | 129 | // Cap at max char 130 | chr_count = strlen(str); 131 | size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type 132 | if (chr_count > max_count) chr_count = max_count; 133 | 134 | // Convert ASCII string into UTF-16 135 | for (size_t i = 0; i < chr_count; i++) { 136 | _desc_str[1 + i] = str[i]; 137 | } 138 | break; 139 | } 140 | 141 | // first byte is length (including header), second byte is string type 142 | _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); 143 | 144 | return _desc_str; 145 | } 146 | --------------------------------------------------------------------------------