├── docs ├── images │ ├── EMPTY │ ├── m5stamp_c3dev_01.jpg │ ├── m5stamp_c3dev_02.png │ ├── m5stamp_c3dev_03.png │ ├── m5stamp_c3dev_04.jpg │ ├── m5stamp_c3dev_05.jpg │ ├── m5stamp_c3dev_05.png │ ├── m5stamp_c3dev_06.jpg │ └── circuit_diagram_01.png ├── asgps │ ├── gpsgsv.wasm │ ├── gpsgsv.0a16a138.wasm │ ├── index.html │ ├── index.2911557e.css │ └── index.2911557e.css.map └── asclock │ ├── clockenv.wasm │ ├── clockenv.a67d0fc1.wasm │ ├── index.html │ ├── index.2911557e.css │ └── index.2911557e.css.map ├── main ├── test_nvs_wifi.h ├── test_tinypng.h ├── test_wasm3_imu6886.h ├── test_wasm3_clockenv.h ├── test_wasm3_gpsgsv.h ├── test_freetype.h ├── test_uart_gpio1819.h ├── test_i2c_gpio1819.h ├── CMakeLists.txt ├── c3dev_board.h ├── Kconfig.projbuild ├── test_nvs_wifi.cpp ├── test_tinypng.cpp ├── test_uart_gpio1819.cpp ├── test_i2c_gpio1819.cpp ├── test_freetype.cpp ├── main.cpp ├── test_wasm3_imu6886.cpp ├── test_wasm3_clockenv.cpp └── test_wasm3_gpsgsv.cpp ├── wasm ├── clockenv │ ├── .gitignore │ ├── .parcelrc │ ├── tsconfig.json │ ├── README.md │ ├── web │ │ ├── index.html │ │ ├── style.css │ │ └── main.js │ ├── package.json │ └── src │ │ ├── c3dev.ts │ │ └── main.ts ├── gpsgsv │ ├── .gitignore │ ├── tsconfig.json │ ├── web │ │ ├── index.html │ │ ├── style.css │ │ └── main.js │ ├── src │ │ ├── c3dev.ts │ │ └── main.ts │ └── package.json └── imu6886 │ ├── .gitignore │ ├── .parcelrc │ ├── tsconfig.json │ ├── web │ ├── index.html │ ├── style.css │ └── main.js │ ├── package.json │ └── src │ ├── c3dev.ts │ └── main.ts ├── resources ├── spiffs_font.bin ├── spiffs_wasm.bin ├── font │ └── GENSHINM.TTF ├── wasm │ ├── gpsgsv.wasm │ ├── imu6886.wasm │ └── clockenv.wasm └── range.sh ├── nvs_partition.csv ├── pcb └── fg06-c3dev-revb │ ├── fg06-c3dev-revb-gerber.zip │ ├── fp-lib-table │ ├── sym-lib-table │ ├── gerber │ ├── fg06-c3dev-revb-B_Paste.gbp │ ├── fg06-c3dev-revb-F_Paste.gtp │ ├── fg06-c3dev-revb-B_Silkscreen.gbo │ ├── fg06-c3dev-revb-Edge_Cuts.gm1 │ ├── fg06-c3dev-revb.drl │ ├── fg06-c3dev-revb-job.gbrjob │ ├── fg06-c3dev-revb-B_Mask.gbs │ └── fg06-c3dev-revb-F_Mask.gts │ ├── fg06-c3dev-revb.kicad_prl │ ├── fg-series.pretty │ ├── AE-USB2.0-TYPE-C.kicad_mod │ ├── BNX016-01.kicad_mod │ ├── KMR-1.8SPI.kicad_mod │ ├── AJ-1780.kicad_mod │ ├── M5STAMP-C3.kicad_mod │ └── MBUS.kicad_mod │ └── fg06-c3dev-revb.kicad_pro ├── .vscode ├── extensions.json ├── settings.json ├── c_cpp_properties.json ├── tasks.json └── launch.json ├── components ├── wasm │ ├── linker.lf │ └── CMakeLists.txt ├── ultrasonic │ └── CMakeLists.txt ├── freetype │ ├── src │ │ ├── freetype_helper.h │ │ └── freetype_helper.c │ └── CMakeLists.txt ├── unitenv │ └── CMakeLists.txt ├── tinypng │ └── CMakeLists.txt ├── lwgps │ └── CMakeLists.txt └── lcd │ └── CMakeLists.txt ├── .gitignore ├── CMakeLists.txt ├── .editorconfig ├── partitions.csv ├── LICENSE ├── .gitmodules ├── .github └── workflows │ └── build.yml └── README.md /docs/images/EMPTY: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /main/test_nvs_wifi.h: -------------------------------------------------------------------------------- 1 | void sync_wifi_ntp(void); 2 | -------------------------------------------------------------------------------- /wasm/clockenv/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .parcel-cache/ 3 | -------------------------------------------------------------------------------- /wasm/gpsgsv/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .parcel-cache/ 3 | -------------------------------------------------------------------------------- /wasm/imu6886/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .parcel-cache/ 3 | -------------------------------------------------------------------------------- /docs/asgps/gpsgsv.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/asgps/gpsgsv.wasm -------------------------------------------------------------------------------- /resources/spiffs_font.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/resources/spiffs_font.bin -------------------------------------------------------------------------------- /resources/spiffs_wasm.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/resources/spiffs_wasm.bin -------------------------------------------------------------------------------- /docs/asclock/clockenv.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/asclock/clockenv.wasm -------------------------------------------------------------------------------- /resources/font/GENSHINM.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/resources/font/GENSHINM.TTF -------------------------------------------------------------------------------- /resources/wasm/gpsgsv.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/resources/wasm/gpsgsv.wasm -------------------------------------------------------------------------------- /resources/wasm/imu6886.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/resources/wasm/imu6886.wasm -------------------------------------------------------------------------------- /wasm/clockenv/.parcelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@parcel/config-default"], 3 | "reporters": ["..."] 4 | } 5 | -------------------------------------------------------------------------------- /wasm/imu6886/.parcelrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@parcel/config-default"], 3 | "reporters": ["..."] 4 | } 5 | -------------------------------------------------------------------------------- /resources/wasm/clockenv.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/resources/wasm/clockenv.wasm -------------------------------------------------------------------------------- /docs/asgps/gpsgsv.0a16a138.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/asgps/gpsgsv.0a16a138.wasm -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_01.jpg -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_02.png -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_03.png -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_04.jpg -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_05.jpg -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_05.png -------------------------------------------------------------------------------- /docs/images/m5stamp_c3dev_06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/m5stamp_c3dev_06.jpg -------------------------------------------------------------------------------- /docs/asclock/clockenv.a67d0fc1.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/asclock/clockenv.a67d0fc1.wasm -------------------------------------------------------------------------------- /docs/images/circuit_diagram_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/docs/images/circuit_diagram_01.png -------------------------------------------------------------------------------- /nvs_partition.csv: -------------------------------------------------------------------------------- 1 | key,type,encoding,value 2 | wifi,namespace,, 3 | ssid,data,string,[ssid] 4 | passwd,data,string,[password] 5 | -------------------------------------------------------------------------------- /main/test_tinypng.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void draw_sdcard_png(const char *filename, uint16_t base_x, uint16_t base_y); 4 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg06-c3dev-revb-gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/HEAD/pcb/fg06-c3dev-revb/fg06-c3dev-revb-gerber.zip -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name "fg-series")(type "KiCad")(uri "${KIPRJMOD}/fg-series.pretty")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name "fg-series")(type "KiCad")(uri "${KIPRJMOD}/fg-series.kicad_sym")(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-vscode.cpptools", 4 | "ms-vscode.cmake-tools", 5 | "EditorConfig.EditorConfig", 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /components/wasm/linker.lf: -------------------------------------------------------------------------------- 1 | [mapping:wasm] 2 | archive: libwasm.a 3 | entries: 4 | m3_core (noflash) 5 | m3_exec (noflash) 6 | m3_compile (default) # Not enough IRAM memory 7 | -------------------------------------------------------------------------------- /main/test_wasm3_imu6886.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void as_gc_unpin_ptr(uint32_t wasm_prt); 4 | void as_gc_collect(void); 5 | esp_err_t imu6886_init_wasm(void); 6 | esp_err_t imu6886_tick_wasm(void); 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | managed_components/ 4 | .cache/ 5 | pcb/fg06-c3dev-revb/fg06-c3dev-revb-backups 6 | fp-info-cache 7 | sdkconfig.old 8 | nvs_partition.bin 9 | dependencies.lock 10 | -------------------------------------------------------------------------------- /main/test_wasm3_clockenv.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void as_gc_unpin_ptr(uint32_t wasm_prt); 4 | void as_gc_collect(void); 5 | esp_err_t clockenv_init_wasm(void); 6 | esp_err_t clockenv_tick_wasm(void); 7 | -------------------------------------------------------------------------------- /main/test_wasm3_gpsgsv.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void as_gc_unpin_ptr(uint32_t wasm_prt); 4 | void as_gc_collect(void); 5 | esp_err_t gpsgsv_init_wasm(void); 6 | esp_err_t gpsgsv_tick_wasm(bool clear); 7 | -------------------------------------------------------------------------------- /wasm/gpsgsv/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./src/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "strictPropertyInitialization": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /wasm/clockenv/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./src/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "strictPropertyInitialization": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /wasm/imu6886/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./src/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "strictPropertyInitialization": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /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 | project(hello-world) 7 | -------------------------------------------------------------------------------- /components/ultrasonic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | M5Unit-Sonic/src 5 | ) 6 | 7 | set(SRCS 8 | M5Unit-Sonic/src/Unit_Sonic.cpp 9 | ) 10 | 11 | idf_component_register(INCLUDE_DIRS ${INCLUDEDIRS} SRCS ${SRCS} REQUIRES arduino-esp32) 12 | -------------------------------------------------------------------------------- /main/test_freetype.h: -------------------------------------------------------------------------------- 1 | #include "ffsupport.h" 2 | #include "font_render.h" 3 | 4 | void init_freetype(void); 5 | font_render_t create_freetype_render(uint32_t font_size, uint32_t font_cache_size); 6 | void draw_freetype_string(const char *string, int32_t poX, int32_t poY, uint16_t fg, font_render_t *render); 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.fs": "glsl", 4 | "font_render.h": "c", 5 | "ffsupport.h": "c", 6 | "sd.h": "c", 7 | "stdint.h": "c", 8 | "wasm3.h": "c", 9 | "m3_env.h": "c", 10 | "fib32.wasm.h": "c" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /main/test_uart_gpio1819.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct 4 | { 5 | uint8_t num; 6 | uint8_t elevation; 7 | uint16_t azimuth; 8 | uint8_t snr; 9 | } unitgpsgsv_t; 10 | 11 | void init_uart_gpio1819(void); 12 | void get_uart_gpsgsv_data(unitgpsgsv_t unitgpsgsv[], uint8_t *satellites); 13 | -------------------------------------------------------------------------------- /main/test_i2c_gpio1819.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | float tmp; 3 | float hum; 4 | float pressure; 5 | } unitenv_t; 6 | 7 | typedef struct { 8 | float distance; 9 | } unit_ultrasonic_t; 10 | 11 | void init_i2c_gpio1819(void); 12 | void get_i2c_unit_data(unitenv_t *unitenv, unit_ultrasonic_t *ultrasonic); 13 | -------------------------------------------------------------------------------- /components/freetype/src/freetype_helper.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif /* __cplusplus */ 6 | uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc); 7 | uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining); 8 | #ifdef __cplusplus 9 | } 10 | #endif /* __cplusplus */ 11 | -------------------------------------------------------------------------------- /components/unitenv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | UNIT_ENV/src 5 | ) 6 | 7 | set(SRCS 8 | UNIT_ENV/src/DHT12.cpp 9 | UNIT_ENV/src/QMP6988.cpp 10 | UNIT_ENV/src/SHT3X.cpp 11 | ) 12 | 13 | idf_component_register(INCLUDE_DIRS ${INCLUDEDIRS} SRCS ${SRCS} REQUIRES arduino-esp32) 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [package.json] 15 | indent_size = 2 16 | 17 | [*.yml] 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /partitions.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap 3 | nvs, data, nvs, 0x9000, 0x6000, 4 | phy_init, data, phy, 0xf000, 0x1000, 5 | app, app, factory, 0x10000, 0x200000, 6 | font, data, spiffs, 0x210000, 0x100000 7 | wasm, data, spiffs, 0x310000, 0x10000 8 | -------------------------------------------------------------------------------- /components/tinypng/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | tinyPNG 5 | ) 6 | 7 | set(SRCS 8 | tinyPNG/tinyPNG.cpp 9 | ) 10 | 11 | idf_component_register(INCLUDE_DIRS ${INCLUDEDIRS} SRCS ${SRCS}) 12 | 13 | target_compile_options(${COMPONENT_TARGET} PRIVATE 14 | -O3 15 | -fexceptions 16 | -std=c++17 17 | -Dtypeof=__typeof__ 18 | -DDEFLATE_ALLOCATION_DYNAMIC) 19 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(INCLUDEDIRS 2 | ./ 3 | ) 4 | 5 | set(SRCS 6 | main.cpp 7 | test_wasm3_clockenv.cpp 8 | test_wasm3_gpsgsv.cpp 9 | test_wasm3_imu6886.cpp 10 | test_freetype.cpp 11 | test_tinypng.cpp 12 | test_nvs_wifi.cpp 13 | test_i2c_gpio1819.cpp 14 | test_uart_gpio1819.cpp 15 | ) 16 | 17 | idf_component_register( 18 | INCLUDE_DIRS ${INCLUDEDIRS} 19 | SRCS ${SRCS} 20 | REQUIRES arduino-esp32 freetype lcd tinypng lwgps wasm unitenv ultrasonic) 21 | -------------------------------------------------------------------------------- /components/lwgps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | lwgps/lwgps/src/include 5 | ) 6 | 7 | set(SRCS 8 | lwgps/lwgps/src/lwgps/lwgps.c 9 | ) 10 | 11 | idf_component_register(INCLUDE_DIRS ${INCLUDEDIRS} SRCS ${SRCS}) 12 | 13 | target_compile_options(${COMPONENT_TARGET} PUBLIC 14 | -O3 15 | -DLWGPS_IGNORE_USER_OPTS=1 16 | -DLWGPS_CFG_STATEMENT_GPGGA=1 17 | -DLWGPS_CFG_STATEMENT_GPGSA=1 18 | -DLWGPS_CFG_STATEMENT_GPGSV_SAT_DET=1 19 | ) 20 | -------------------------------------------------------------------------------- /main/c3dev_board.h: -------------------------------------------------------------------------------- 1 | #include "Adafruit_GFX.h" 2 | #include "Adafruit_ST7735.h" 3 | 4 | #define C3DEV_GPIO_0 0 5 | 6 | #define C3DEV_SPI_CLOCK 25000000 7 | #define C3DEV_SPI_SCLK 4 8 | #define C3DEV_SPI_MOSI 5 9 | #define C3DEV_SPI_MISO 6 10 | 11 | #define C3DEV_SD_CS 1 12 | 13 | #define C3DEV_LCD_CS 7 14 | #define C3DEV_LCD_DC 10 15 | #define C3DEV_LCD_RST 8 16 | 17 | #define C3DEV_SW1 9 18 | #define M5STAMP_C3_SW 3 19 | #define M5STAMP_C3_LED 2 20 | 21 | extern Adafruit_ST7735 tft; 22 | extern SPIClass *spi; 23 | -------------------------------------------------------------------------------- /wasm/clockenv/README.md: -------------------------------------------------------------------------------- 1 | # AssemblyScript Analog Clock 2 | 3 | ## Build 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | ### for Web 10 | 11 | ``` 12 | npm run start 13 | # http://localhost:1234 14 | ``` 15 | 16 | ### for FG06-C3DEV/Wasm3 17 | 18 | ``` 19 | npm run asbuild 20 | # and flash .wasm 21 | cd ../../ 22 | python ${IDF_PATH}/components/spiffs/spiffsgen.py 0x10000 resources/wasm resources/spiffs_wasm.bin 23 | parttool.py --port write_partition --partition-name=wasm --partition-subtype=spiffs --input resources/spiffs_wasm.bin 24 | ``` 25 | -------------------------------------------------------------------------------- /wasm/imu6886/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C3DEV Simulator 8 | 9 | 10 |
11 | 12 |
13 |

AssemblyScript IMU
Sensor values are dummy.

14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/asgps/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C3DEV Simulator 8 | 9 | 10 |
11 | 12 |
13 |

AssemblyScript GPS GSV view
Sensor values are dummy.

14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /wasm/gpsgsv/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C3DEV Simulator 8 | 9 | 10 |
11 | 12 |
13 |

AssemblyScript GPS GSV view
Sensor values are dummy.

14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/asclock/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C3DEV Simulator 8 | 9 | 10 |
11 | 12 |
13 |

AssemblyScript Analog Clock
Sensor values are dummy.

14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /wasm/clockenv/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | C3DEV Simulator 8 | 9 | 10 |
11 | 12 |
13 |

AssemblyScript Analog Clock
Sensor values are dummy.

14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /components/lcd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | adfruitbus 5 | agfxlib 6 | st7735 7 | ) 8 | 9 | set(SRCS 10 | adfruitbus/Adafruit_BusIO_Register.cpp 11 | adfruitbus/Adafruit_I2CDevice.cpp 12 | adfruitbus/Adafruit_SPIDevice.cpp 13 | agfxlib/Adafruit_GFX.cpp 14 | agfxlib/Adafruit_SPITFT.cpp 15 | agfxlib/glcdfont.c 16 | st7735/Adafruit_ST7735.cpp 17 | st7735/Adafruit_ST77xx.cpp 18 | ) 19 | 20 | idf_component_register(INCLUDE_DIRS ${INCLUDEDIRS} SRCS ${SRCS} REQUIRES arduino-esp32) 21 | 22 | target_compile_options(${COMPONENT_TARGET} PRIVATE 23 | -O3 24 | ) 25 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-B_Paste.gbp: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1* 2 | G04 #@! TF.CreationDate,2022-03-24T13:24:43+09:00* 3 | G04 #@! TF.ProjectId,fg06-c3dev-revb,66673036-2d63-4336-9465-762d72657662,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Paste,Bot* 6 | G04 #@! TF.FilePolarity,Positive* 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.3-a3aad9c10e~116~ubuntu20.04.1) date 2022-03-24 13:24:43* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 APERTURE END LIST* 15 | M02* 16 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-F_Paste.gtp: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1* 2 | G04 #@! TF.CreationDate,2022-03-24T13:24:43+09:00* 3 | G04 #@! TF.ProjectId,fg06-c3dev-revb,66673036-2d63-4336-9465-762d72657662,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Paste,Top* 6 | G04 #@! TF.FilePolarity,Positive* 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.3-a3aad9c10e~116~ubuntu20.04.1) date 2022-03-24 13:24:43* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 APERTURE END LIST* 15 | M02* 16 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-B_Silkscreen.gbo: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1* 2 | G04 #@! TF.CreationDate,2022-03-24T13:24:43+09:00* 3 | G04 #@! TF.ProjectId,fg06-c3dev-revb,66673036-2d63-4336-9465-762d72657662,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Legend,Bot* 6 | G04 #@! TF.FilePolarity,Positive* 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.3-a3aad9c10e~116~ubuntu20.04.1) date 2022-03-24 13:24:43* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 APERTURE END LIST* 15 | M02* 16 | -------------------------------------------------------------------------------- /wasm/clockenv/web/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | body { 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | overflow: hidden; 11 | margin: 0; 12 | padding: 0; 13 | background-color: black; 14 | } 15 | 16 | p { 17 | color: #fff; 18 | text-align: center; 19 | } 20 | 21 | .lcd { 22 | border: 6px solid white; 23 | } 24 | 25 | .lcd #screen { 26 | display: block; 27 | background-color: black; 28 | border: 8px solid black; 29 | image-rendering: pixelated; 30 | image-rendering: crisp-edges; 31 | } 32 | 33 | #link { 34 | text-align: right; 35 | margin-bottom: 8px; 36 | } 37 | 38 | #link a { 39 | color:#00a040; 40 | text-decoration: overline; 41 | } 42 | -------------------------------------------------------------------------------- /wasm/gpsgsv/web/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | body { 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | overflow: hidden; 11 | margin: 0; 12 | padding: 0; 13 | background-color: black; 14 | } 15 | 16 | p { 17 | color: #fff; 18 | text-align: center; 19 | } 20 | 21 | .lcd { 22 | border: 6px solid white; 23 | } 24 | 25 | .lcd #screen { 26 | display: block; 27 | background-color: black; 28 | border: 8px solid black; 29 | image-rendering: pixelated; 30 | image-rendering: crisp-edges; 31 | } 32 | 33 | #link { 34 | text-align: right; 35 | margin-bottom: 8px; 36 | } 37 | 38 | #link a { 39 | color:#00a040; 40 | text-decoration: overline; 41 | } 42 | -------------------------------------------------------------------------------- /wasm/imu6886/web/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | body { 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | overflow: hidden; 11 | margin: 0; 12 | padding: 0; 13 | background-color: black; 14 | } 15 | 16 | p { 17 | color: #fff; 18 | text-align: center; 19 | } 20 | 21 | .lcd { 22 | border: 6px solid white; 23 | } 24 | 25 | .lcd #screen { 26 | display: block; 27 | background-color: black; 28 | border: 8px solid black; 29 | image-rendering: pixelated; 30 | image-rendering: crisp-edges; 31 | } 32 | 33 | #link { 34 | text-align: right; 35 | margin-bottom: 8px; 36 | } 37 | 38 | #link a { 39 | color:#00a040; 40 | text-decoration: overline; 41 | } 42 | -------------------------------------------------------------------------------- /docs/asgps/index.2911557e.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | body { 7 | background-color: #000; 8 | justify-content: center; 9 | align-items: center; 10 | margin: 0; 11 | padding: 0; 12 | display: flex; 13 | overflow: hidden; 14 | } 15 | 16 | p { 17 | color: #fff; 18 | text-align: center; 19 | } 20 | 21 | .lcd { 22 | border: 6px solid #fff; 23 | } 24 | 25 | .lcd #screen { 26 | image-rendering: pixelated; 27 | image-rendering: crisp-edges; 28 | background-color: #000; 29 | border: 8px solid #000; 30 | display: block; 31 | } 32 | 33 | #link { 34 | text-align: right; 35 | margin-bottom: 8px; 36 | } 37 | 38 | #link a { 39 | color: #00a040; 40 | text-decoration: overline; 41 | } 42 | 43 | /*# sourceMappingURL=index.2911557e.css.map */ 44 | -------------------------------------------------------------------------------- /docs/asclock/index.2911557e.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | body { 7 | background-color: #000; 8 | justify-content: center; 9 | align-items: center; 10 | margin: 0; 11 | padding: 0; 12 | display: flex; 13 | overflow: hidden; 14 | } 15 | 16 | p { 17 | color: #fff; 18 | text-align: center; 19 | } 20 | 21 | .lcd { 22 | border: 6px solid #fff; 23 | } 24 | 25 | .lcd #screen { 26 | image-rendering: pixelated; 27 | image-rendering: crisp-edges; 28 | background-color: #000; 29 | border: 8px solid #000; 30 | display: block; 31 | } 32 | 33 | #link { 34 | text-align: right; 35 | margin-bottom: 8px; 36 | } 37 | 38 | #link a { 39 | color: #00a040; 40 | text-decoration: overline; 41 | } 42 | 43 | /*# sourceMappingURL=index.2911557e.css.map */ 44 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "esp32c3", 5 | "forcedInclude": [ 6 | "${workspaceRoot}/build/config/sdkconfig.h" 7 | ], 8 | "defines": [ 9 | "CONFIG_IDF_TARGET_ESP32C3", 10 | "ESP_PLATFORM", 11 | "ARDUINO=101", 12 | "M3_COMPILER_GCC", 13 | "ESP32", 14 | "__riscv", 15 | "__riscv_xlen" 16 | ], 17 | "compilerPath": "/usr/bin/gcc", 18 | "cStandard": "c11", 19 | "cppStandard": "c++14", 20 | "intelliSenseMode": "linux-gcc-x86", 21 | "configurationProvider": "ms-vscode.cmake-tools" 22 | } 23 | ], 24 | "version": 4 25 | } 26 | -------------------------------------------------------------------------------- /docs/asgps/index.2911557e.css.map: -------------------------------------------------------------------------------- 1 | {"mappings":"AAAA;;;;;AAKA;;;;;;;;;;AAUA;;;;;AAKA;;;;AAIA;;;;;;;;AAQA;;;;;AAKA","sources":["web/style.css"],"sourcesContent":["html, body {\n width: 100%;\n height: 100%;\n}\n\nbody {\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: hidden;\n margin: 0;\n padding: 0;\n background-color: black;\n}\n\np {\n color: #fff;\n text-align: center;\n}\n\n.lcd {\n border: 6px solid white;\n}\n\n.lcd #screen {\n display: block;\n background-color: black;\n border: 8px solid black;\n image-rendering: pixelated;\n image-rendering: crisp-edges;\n}\n\n#link {\n text-align: right;\n margin-bottom: 8px;\n}\n\n#link a {\n color:#00a040;\n text-decoration: overline;\n}\n"],"names":[],"version":3,"file":"index.2911557e.css.map","sourceRoot":"/__parcel_source_root/"} -------------------------------------------------------------------------------- /docs/asclock/index.2911557e.css.map: -------------------------------------------------------------------------------- 1 | {"mappings":"AAAA;;;;;AAKA;;;;;;;;;;AAUA;;;;;AAKA;;;;AAIA;;;;;;;;AAQA;;;;;AAKA","sources":["web/style.css"],"sourcesContent":["html, body {\n width: 100%;\n height: 100%;\n}\n\nbody {\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: hidden;\n margin: 0;\n padding: 0;\n background-color: black;\n}\n\np {\n color: #fff;\n text-align: center;\n}\n\n.lcd {\n border: 6px solid white;\n}\n\n.lcd #screen {\n display: block;\n background-color: black;\n border: 8px solid black;\n image-rendering: pixelated;\n image-rendering: crisp-edges;\n}\n\n#link {\n text-align: right;\n margin-bottom: 8px;\n}\n\n#link a {\n color:#00a040;\n text-decoration: overline;\n}\n"],"names":[],"version":3,"file":"index.2911557e.css.map","sourceRoot":"/__parcel_source_root/"} -------------------------------------------------------------------------------- /wasm/gpsgsv/src/c3dev.ts: -------------------------------------------------------------------------------- 1 | export declare function now(): i64; 2 | export declare function delay(wait: i32): void; 3 | export declare function draw_pixel(x: i32, y: i32, color: i32): void; 4 | export declare function draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: i32): void; 5 | export declare function draw_string(x: i32, y: i32, color: i32, string: ArrayBuffer): void; 6 | 7 | export declare function log(string: ArrayBuffer): void; 8 | 9 | export const enum COLOR { 10 | BLACK = 0x0000, 11 | WHITE = 0xFFFF, 12 | RED = 0xF800, 13 | GREEN = 0x07E0, 14 | BLUE = 0x001F, 15 | CYAN = 0x07FF, 16 | MAGENTA = 0xF81F, 17 | YELLOW = 0xFFE0, 18 | ORANGE = 0xFC00, 19 | } 20 | 21 | export function consoleLog(string: string): void { 22 | log(String.UTF8.encode(string, true)); 23 | } 24 | 25 | export function drawString(x: i32, y: i32, color: i32, string: string): void { 26 | draw_string(x, y, color, String.UTF8.encode(string, true)); 27 | } 28 | -------------------------------------------------------------------------------- /main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "C3DEV Configuration" 2 | menu "NTP Server Configuration" 3 | config C3DEV_NTP_SERVER1 4 | string "NTP Server1" 5 | default "ntp1.jst.mfeed.ad.jp" 6 | config C3DEV_NTP_SERVER2 7 | string "NTP Server2" 8 | default "ntp2.jst.mfeed.ad.jp" 9 | config C3DEV_NTP_SERVER3 10 | string "NTP Server3" 11 | default "ntp3.jst.mfeed.ad.jp" 12 | endmenu 13 | 14 | choice 15 | prompt "Select GPIO 18/19" 16 | default GPIO1819_NONE 17 | config GPIO1819_NONE 18 | bool "None" 19 | config GPIO1819_I2C 20 | bool "Connect I2C (UNIT ENV III, UltraSonic)" 21 | config GPIO1819_UART_UNITGPS 22 | bool "Connect UART (UNIT GPS)" 23 | config GPIO1819_DIGIT_UNITIR 24 | bool "Connect DIGITAL (UNIT IR)" 25 | config GPIO1819_IMU6886 26 | bool "3D Cube Demo (not yet impliments UNIT MPU6886)" 27 | endchoice 28 | endmenu 29 | -------------------------------------------------------------------------------- /wasm/imu6886/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xtensa-wasm", 3 | "version": "1.0.0", 4 | "description": "RISC-V wasm3 example", 5 | "devDependencies": { 6 | "@babel/core": "^7.24.7", 7 | "@babel/eslint-parser": "^7.24.7", 8 | "@babel/plugin-transform-runtime": "^7.24.7", 9 | "@babel/preset-env": "^7.24.7", 10 | "parcel": "^2.12.0", 11 | "@parcel/source-map": "^2.1.1", 12 | "assemblyscript": "^0.27.29" 13 | }, 14 | "scripts": { 15 | "asbuild:web": "asc src/main.ts -o ./dist/imu6886.wasm -t build/imu6886.wat -b build/imu6886.d.ts --runtime minimal --exportRuntime --lowMemoryLimit 32767 --use Math=NativeMathf -O3 --optimize", 16 | "asbuild": "asc src/main.ts -o ../../resources/wasm/imu6886.wasm -t build/imu6886.wat -b build/imu6886.d.ts --runtime minimal --exportRuntime --lowMemoryLimit 32767 --use Math=NativeMathf -O3 --optimize", 17 | "start": "npm run asbuild:web && parcel web/index.html", 18 | "deploy": "npm run asbuild:web && parcel build --public-url '.' web/index.html" 19 | }, 20 | "author": "h1romas4", 21 | "license": "MIT" 22 | } 23 | -------------------------------------------------------------------------------- /wasm/gpsgsv/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "riscv-wasm", 3 | "version": "1.0.0", 4 | "description": "RISC-V wasm3 example", 5 | "devDependencies": { 6 | "@babel/core": "^7.24.7", 7 | "@babel/eslint-parser": "^7.24.7", 8 | "@babel/plugin-transform-runtime": "^7.24.7", 9 | "@babel/preset-env": "^7.24.7", 10 | "parcel": "^2.12.0", 11 | "@parcel/source-map": "^2.1.1", 12 | "assemblyscript": "^0.27.29" 13 | }, 14 | "scripts": { 15 | "asbuild:web": "asc src/main.ts -o ./dist/gpsgsv.wasm -t build/gpsgsv.wat -b build/gpsgsv.d.ts --runtime minimal --exportRuntime --lowMemoryLimit 32767 --use Math=NativeMathf -O3 --optimize", 16 | "asbuild:wasm3": "asc src/main.ts -o ../../resources/wasm/gpsgsv.wasm -t build/gpsgsv.wat -b build/gpsgsv.d.ts --runtime minimal --exportRuntime --lowMemoryLimit 32767 --use Math=NativeMathf -O3 --optimize", 17 | "asbuild": "npm run asbuild:wasm3", 18 | "start": "npm run asbuild:web && parcel web/index.html", 19 | "deploy": "npm run asbuild:web && parcel --public-url '.' web/index.html" 20 | }, 21 | "author": "h1romas4", 22 | "license": "MIT" 23 | } 24 | -------------------------------------------------------------------------------- /wasm/clockenv/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "riscv-wasm", 3 | "version": "1.0.0", 4 | "description": "RISC-V wasm3 example", 5 | "devDependencies": { 6 | "@babel/core": "^7.24.7", 7 | "@babel/eslint-parser": "^7.24.7", 8 | "@babel/plugin-transform-runtime": "^7.24.7", 9 | "@babel/preset-env": "^7.24.7", 10 | "parcel": "^2.12.0", 11 | "@parcel/source-map": "^2.1.1", 12 | "assemblyscript": "^0.27.29" 13 | }, 14 | "scripts": { 15 | "asbuild:web": "asc src/main.ts -o ./dist/clockenv.wasm -t build/clockenv.wat -b build/clockenv.d.ts --runtime minimal --exportRuntime --lowMemoryLimit 32767 --use Math=NativeMathf -O3 --optimize", 16 | "asbuild:wasm3": "asc src/main.ts -o ../../resources/wasm/clockenv.wasm -t build/clockenv.wat -b build/clockenv.d.ts --runtime minimal --exportRuntime --lowMemoryLimit 32767 --use Math=NativeMathf -O3 --optimize", 17 | "asbuild": "npm run asbuild:wasm3", 18 | "start": "npm run asbuild:web && parcel web/index.html", 19 | "deploy": "npm run asbuild:web && parcel --public-url '.' web/index.html" 20 | }, 21 | "author": "h1romas4", 22 | "license": "MIT" 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 h1romas4 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /wasm/imu6886/src/c3dev.ts: -------------------------------------------------------------------------------- 1 | export declare function now(): i64; 2 | export declare function delay(wait: i32): void; 3 | export declare function start_write(): void; 4 | export declare function draw_pixel(x: i32, y: i32, color: i32): void; 5 | export declare function draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: i32): void; 6 | export declare function fill_rect(x0: i32, y0: i32, x1: i32, y1: u32, color: i32): void; 7 | export declare function end_write(): void; 8 | export declare function draw_string(x: i32, y: i32, color: i32, string: ArrayBuffer): void; 9 | 10 | export declare function log(string: ArrayBuffer): void; 11 | 12 | export const enum COLOR { 13 | BLACK = 0x0000, 14 | WHITE = 0xFFFF, 15 | RED = 0xF800, 16 | GREEN = 0x07E0, 17 | BLUE = 0x001F, 18 | CYAN = 0x07FF, 19 | MAGENTA = 0xF81F, 20 | YELLOW = 0xFFE0, 21 | ORANGE = 0xFC00, 22 | } 23 | 24 | export function consoleLog(string: string): void { 25 | log(String.UTF8.encode(string, true)); 26 | } 27 | 28 | export function drawString(x: i32, y: i32, color: i32, string: string): void { 29 | draw_string(x, y, color, String.UTF8.encode(string, true)); 30 | } 31 | -------------------------------------------------------------------------------- /components/wasm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | wasm3/source 5 | wasm3/source/extensions 6 | wasm3/source/extra 7 | ) 8 | 9 | set(SRCS 10 | wasm3/source/m3_api_libc.c 11 | wasm3/source/m3_api_wasi.c 12 | wasm3/source/m3_api_uvwasi.c 13 | wasm3/source/m3_api_meta_wasi.c 14 | wasm3/source/m3_api_tracer.c 15 | wasm3/source/m3_bind.c 16 | wasm3/source/m3_code.c 17 | wasm3/source/m3_compile.c 18 | wasm3/source/m3_core.c 19 | wasm3/source/m3_env.c 20 | wasm3/source/m3_exec.c 21 | wasm3/source/m3_function.c 22 | wasm3/source/m3_info.c 23 | wasm3/source/m3_module.c 24 | wasm3/source/m3_parse.c 25 | ) 26 | 27 | idf_component_register( 28 | INCLUDE_DIRS ${INCLUDEDIRS} 29 | SRCS ${SRCS} 30 | LDFRAGMENTS linker.lf 31 | ) 32 | 33 | target_compile_options(${COMPONENT_TARGET} PRIVATE 34 | -DESP32 35 | -DM3_IN_IRAM 36 | -O3 37 | -freorder-blocks 38 | # -g0 39 | # -s 40 | # -Dd_m3FixedHeap=32768 41 | # -DDEBUG 42 | # -Dd_m3LogNativeStack 43 | # -Dd_m3LogHeapOps 44 | # -Dd_m3SkipStackCheck 45 | # -Dd_m3SkipMemoryBoundsCheck 46 | ) 47 | -------------------------------------------------------------------------------- /main/test_nvs_wifi.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "esp_log.h" 3 | #include "WiFi.h" 4 | #include "Preferences.h" 5 | 6 | static const char *TAG = "test_nvs_wifi.cpp"; 7 | 8 | #define NTP_SERVER1 CONFIG_C3DEV_NTP_SERVER1 9 | #define NTP_SERVER2 CONFIG_C3DEV_NTP_SERVER2 10 | #define NTP_SERVER3 CONFIG_C3DEV_NTP_SERVER3 11 | 12 | void sync_wifi_ntp(void) 13 | { 14 | Preferences preferences; 15 | 16 | if(!preferences.begin("wifi", true)) return; 17 | 18 | String ssid = preferences.getString("ssid"); 19 | String passwd = preferences.getString("passwd"); 20 | 21 | ESP_LOGI(TAG, "Connect to %s", ssid.c_str()); 22 | WiFi.begin(ssid.c_str(), passwd.c_str()); 23 | while (WiFi.status() != WL_CONNECTED) { 24 | delay(200); 25 | } 26 | ESP_LOGI(TAG, "Connected!"); 27 | configTime(9 * 3600L, 0, NTP_SERVER1, NTP_SERVER2, NTP_SERVER3); 28 | // Wait Time Sync 29 | struct tm timeInfo; 30 | while(true) { 31 | getLocalTime(&timeInfo); 32 | if(timeInfo.tm_year > 70) { 33 | break; 34 | } 35 | delay(500); 36 | ESP_LOGI(TAG, "waiting time sync..(%d:%d:%d %d)", timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec, timeInfo.tm_year); 37 | } 38 | ESP_LOGI(TAG, "Configured time from NTP"); 39 | WiFi.disconnect(); 40 | } 41 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/m5stack/M5EPD"] 2 | path = components/freetype/M5EPD 3 | url = https://github.com/m5stack/M5EPD 4 | [submodule "components/arduino-esp32"] 5 | path = components/arduino-esp32 6 | url = https://github.com/espressif/arduino-esp32 7 | [submodule "components/c3dev/st7735"] 8 | path = components/lcd/st7735 9 | url = https://github.com/adafruit/Adafruit-ST7735-Library 10 | [submodule "components/c3dev/agfxlib"] 11 | path = components/lcd/agfxlib 12 | url = https://github.com/adafruit/Adafruit-GFX-Library 13 | [submodule "components/tinypng/tinyPNG"] 14 | path = components/tinypng/tinyPNG 15 | url = https://github.com/olliiiver/tinyPNG 16 | [submodule "components/wasm/wasm3"] 17 | path = components/wasm/wasm3 18 | url = https://github.com/wasm3/wasm3 19 | [submodule "components/unitenv/UNIT_ENV"] 20 | path = components/unitenv/UNIT_ENV 21 | url = https://github.com/m5stack/UNIT_ENV 22 | [submodule "components/lcd/adfruitbus"] 23 | path = components/lcd/adfruitbus 24 | url = https://github.com/adafruit/Adafruit_BusIO 25 | [submodule "components/lwgps/lwgps"] 26 | path = components/lwgps/lwgps 27 | url = https://github.com/MaJerle/lwgps 28 | [submodule "components/ultrasonic/M5Unit-Sonic"] 29 | path = components/ultrasonic/M5Unit-Sonic 30 | url = https://github.com/m5stack/M5Unit-Sonic 31 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-Edge_Cuts.gm1: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1* 2 | G04 #@! TF.CreationDate,2022-03-24T13:24:43+09:00* 3 | G04 #@! TF.ProjectId,fg06-c3dev-revb,66673036-2d63-4336-9465-762d72657662,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Profile,NP* 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW 6.0.3-a3aad9c10e~116~ubuntu20.04.1) date 2022-03-24 13:24:43* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | G04 #@! TA.AperFunction,Profile* 14 | %ADD10C,0.050000*% 15 | G04 #@! TD* 16 | G04 APERTURE END LIST* 17 | D10* 18 | X130000000Y-40000000D02* 19 | X130000000Y-91180000D01* 20 | X41910000Y-93090000D02* 21 | X128090000Y-93090000D01* 22 | X40000000Y-40000000D02* 23 | X40000000Y-91180000D01* 24 | X128090000Y-93090000D02* 25 | G75* 26 | G03* 27 | X130000000Y-91180000I0J1910000D01* 28 | G01* 29 | X40000000Y-91180000D02* 30 | G75* 31 | G03* 32 | X41910000Y-93090000I1910000J0D01* 33 | G01* 34 | X41910000Y-38090000D02* 35 | X128090000Y-38090000D01* 36 | X41910000Y-38090000D02* 37 | G75* 38 | G03* 39 | X40000000Y-40000000I0J-1910000D01* 40 | G01* 41 | X130000000Y-40000000D02* 42 | G75* 43 | G03* 44 | X128090000Y-38090000I-1910000J0D01* 45 | G01* 46 | M02* 47 | -------------------------------------------------------------------------------- /wasm/clockenv/src/c3dev.ts: -------------------------------------------------------------------------------- 1 | export declare function now(): i64; 2 | export declare function delay(wait: i32): void; 3 | export declare function start_write(): void; 4 | export declare function draw_pixel(x: i32, y: i32, color: i32): void; 5 | export declare function draw_line(x0: i32, y0: i32, x1: i32, y1: i32, color: i32): void; 6 | export declare function write_pixel(x: i32, y: i32, color: i32): void; 7 | export declare function draw_string(x: i32, y: i32, color: i32, string: ArrayBuffer): void; 8 | export declare function end_write(): void; 9 | export declare function get_env_tmp(): f32; 10 | export declare function get_env_hum(): f32; 11 | export declare function get_env_pressure(): f32; 12 | export declare function get_ultrasonic_distance(): f32; 13 | 14 | export declare function log(string: ArrayBuffer): void; 15 | 16 | export const enum COLOR { 17 | BLACK = 0x0000, 18 | WHITE = 0xFFFF, 19 | RED = 0xF800, 20 | GREEN = 0x07E0, 21 | BLUE = 0x001F, 22 | CYAN = 0x07FF, 23 | MAGENTA = 0xF81F, 24 | YELLOW = 0xFFE0, 25 | ORANGE = 0xFC00, 26 | } 27 | 28 | export function consoleLog(string: string): void { 29 | log(String.UTF8.encode(string, true)); 30 | } 31 | 32 | export function drawString(x: i32, y: i32, color: i32, string: string): void { 33 | draw_string(x, y, color, String.UTF8.encode(string, true)); 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - uses: actions/checkout@v1 13 | with: 14 | submodules: recursive 15 | 16 | - uses: actions/cache@v3 17 | id: cache-toolchaine 18 | with: 19 | path: | 20 | ~/esp 21 | ~/.espressif/ 22 | key: ${{ runner.os }}-espidf-and-compiler-v51-u2204 23 | 24 | - name: esp-idf Dependencies Setup 25 | run: | 26 | sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 27 | 28 | - name: esp-idf Toolchain Setup 29 | if: steps.cache-toolchaine.outputs.cache-hit != 'true' 30 | run: | 31 | mkdir -p ~/esp 32 | cd ~/esp 33 | git clone -b release/v5.1 --recursive https://github.com/espressif/esp-idf.git 34 | cd ~/esp/esp-idf 35 | ./install.sh esp32c3 36 | 37 | - name: Build 38 | run: | 39 | . ~/esp/esp-idf/export.sh 40 | idf.py build 41 | cd wasm/clockenv 42 | npm install 43 | npm run asbuild 44 | cd ../gpsgsv 45 | npm install 46 | npm run asbuild 47 | cd ../imu6886 48 | npm install 49 | npm run asbuild 50 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg06-c3dev-revb.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 0, 4 | "active_layer_preset": "All Copper Layers", 5 | "auto_track_width": true, 6 | "hidden_nets": [], 7 | "high_contrast_mode": 0, 8 | "net_color_mode": 1, 9 | "opacity": { 10 | "pads": 1.0, 11 | "tracks": 1.0, 12 | "vias": 1.0, 13 | "zones": 0.6 14 | }, 15 | "ratsnest_display_mode": 0, 16 | "selection_filter": { 17 | "dimensions": true, 18 | "footprints": true, 19 | "graphics": true, 20 | "keepouts": true, 21 | "lockedItems": true, 22 | "otherItems": true, 23 | "pads": true, 24 | "text": true, 25 | "tracks": true, 26 | "vias": true, 27 | "zones": true 28 | }, 29 | "visible_items": [ 30 | 0, 31 | 1, 32 | 2, 33 | 3, 34 | 4, 35 | 5, 36 | 8, 37 | 9, 38 | 10, 39 | 11, 40 | 12, 41 | 13, 42 | 14, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36 64 | ], 65 | "visible_layers": "fffffff_ffffffff", 66 | "zone_display_mode": 0 67 | }, 68 | "meta": { 69 | "filename": "fg06-c3dev-revb.kicad_prl", 70 | "version": 3 71 | }, 72 | "project": { 73 | "files": [] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "shell", 8 | "label": "openocd (debug)", 9 | "command": "openocd", 10 | "args": [ 11 | "-f", 12 | "board/esp32c3-builtin.cfg" 13 | ], 14 | }, 15 | { 16 | "type": "shell", 17 | "label": "openocd flash", 18 | "command": "openocd", 19 | "args": [ 20 | "-f", 21 | "board/esp32c3-builtin.cfg", 22 | "-c", 23 | "program_esp build/hello-world.bin 0x10000 verify reset exit" 24 | ], 25 | }, 26 | { 27 | "type": "shell", 28 | "label": "idf.py build flash monitor", 29 | "command": "idf.py", 30 | "args": [ 31 | "build", 32 | "flash", 33 | "monitor" 34 | ], 35 | }, 36 | { 37 | "type": "shell", 38 | "label": "Flash partision (Wasm)", 39 | "linux": { 40 | "command": "(cd wasm/clockenv && npm run asbuild) && python ${IDF_PATH}/components/spiffs/spiffsgen.py 0x10000 resources/wasm resources/spiffs_wasm.bin && parttool.py write_partition --partition-name=wasm --partition-subtype=spiffs --input resources/spiffs_wasm.bin && idf.py monitor" 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug Launch (GDB)", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "filterStderr": true, 12 | "miDebuggerPath": "${env:ESP32_TOOLCHAIN_HOME}/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin/riscv32-esp-elf-gdb", 13 | "MIMode": "gdb", 14 | "targetArchitecture": "x64", // dummy 15 | "program": "${workspaceRoot}/build/hello-world.elf", 16 | "launchCompleteCommand": "exec-continue", 17 | "setupCommands": [ 18 | { 19 | "description": "enable pretty printing for gdb", 20 | "text": "-enable-pretty-printing", 21 | "ignoreFailures": true 22 | }, 23 | { 24 | "text": "file '${workspaceFolder}/build/hello-world.elf'" 25 | }, 26 | { 27 | "text": "target remote :3333" 28 | }, 29 | { 30 | "text": "set remote hardware-watchpoint-limit 2", 31 | }, 32 | { 33 | "text": "flushregs" 34 | }, 35 | { 36 | "text": "monitor reset halt" 37 | }, 38 | { 39 | "text": "thb app_main" 40 | } 41 | ], 42 | "args": [], 43 | "stopAtEntry": true, 44 | "cwd": "${workspaceRoot}", 45 | "externalConsole": false, 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /main/test_tinypng.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "SD.h" 3 | #include "esp_log.h" 4 | #include "tinyPNG.h" 5 | 6 | #include "c3dev_board.h" 7 | 8 | static const char *TAG = "test_tinypng.cpp"; 9 | 10 | /** 11 | * PNG render member 12 | */ 13 | tinyPNG png; 14 | uint16_t png_y = 0; 15 | uint16_t png_base_x = 0; 16 | uint16_t png_base_y = 0; 17 | 18 | /** 19 | * Example Draw PNG image in SD card 20 | */ 21 | void draw_sdcard_png(const char *filename, uint16_t base_x, uint16_t base_y) 22 | { 23 | // Read PNG image binary 24 | uint8_t *image; 25 | 26 | SD.begin(C3DEV_SD_CS, *spi, C3DEV_SPI_CLOCK, "/sdcard", 1, false); 27 | 28 | File file = SD.open(filename, "rb"); 29 | size_t file_size = file.size(); 30 | image = (uint8_t *)malloc(sizeof(uint8_t) * file.size()); 31 | if(image == nullptr) { 32 | ESP_LOGE(TAG, "Memory alloc error"); 33 | return; 34 | } 35 | if(file.read(image, file_size) != file.size()) { 36 | ESP_LOGE(TAG, "SD read error"); 37 | return; 38 | } 39 | file.close(); 40 | 41 | SD.end(); 42 | 43 | // Draw PNG image 44 | png_y = 0; 45 | png_base_x = base_x; 46 | png_base_y = base_y; 47 | png.setPNG((unsigned char *)image, file_size); 48 | png.process([](unsigned char *line) { 49 | int x; 50 | uint16_t color; 51 | tft.startWrite(); 52 | for (x = 0; x < png.getWidth(); x++) { 53 | // https://stackoverflow.com/questions/22937080/32bit-rgba-to-16bit-bgr565-conversion 54 | color = line[(x * 3) + 2] >> 3; // blue 55 | color |= (line[(x * 3) + 1] & 0xFC) << 3; // green 56 | color |= (line[(x * 3) + 0] & 0xF8) << 8; // red 57 | tft.writePixel(x + png_base_x, png_y + png_base_y, color); 58 | } 59 | png_y++; 60 | tft.endWrite(); 61 | }); 62 | 63 | free(image); 64 | } 65 | -------------------------------------------------------------------------------- /components/freetype/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(INCLUDEDIRS 4 | M5EPD/src 5 | M5EPD/src/base 6 | M5EPD/src/freetype 7 | M5EPD/src/sfnt 8 | M5EPD/src/smooth 9 | M5EPD/src/truetype 10 | src/ 11 | ) 12 | 13 | set(SRCS 14 | M5EPD/src/font_render.c 15 | M5EPD/src/ffsupport.cpp 16 | M5EPD/src/truetype/ttinterp.c 17 | M5EPD/src/truetype/ttobjs.c 18 | M5EPD/src/truetype/ttgload.c 19 | M5EPD/src/truetype/truetype.c 20 | M5EPD/src/truetype/ttsubpix.c 21 | M5EPD/src/truetype/ttdriver.c 22 | M5EPD/src/truetype/ttpload.c 23 | M5EPD/src/truetype/ttpic.c 24 | M5EPD/src/base/ftoutln.c 25 | M5EPD/src/base/ftbbox.c 26 | M5EPD/src/base/ftsnames.c 27 | M5EPD/src/base/ftsystem.cpp 28 | M5EPD/src/base/ftpic.c 29 | M5EPD/src/base/ftgxval.c 30 | M5EPD/src/base/ftfstype.c 31 | M5EPD/src/base/ftobjs.c 32 | M5EPD/src/base/ftgasp.c 33 | M5EPD/src/base/fttrigon.c 34 | M5EPD/src/base/basepic.c 35 | M5EPD/src/base/ftbase.c 36 | M5EPD/src/base/ftcalc.c 37 | M5EPD/src/base/ftgloadr.c 38 | M5EPD/src/base/ftstream.c 39 | M5EPD/src/base/ftapi.c 40 | M5EPD/src/base/ftinit.c 41 | M5EPD/src/base/ftadvanc.c 42 | M5EPD/src/base/ftbitmap.c 43 | M5EPD/src/base/ftglyph.c 44 | M5EPD/src/base/md5.c 45 | M5EPD/src/base/ftrfork.c 46 | M5EPD/src/base/ftutil.c 47 | M5EPD/src/base/ftdebug.c 48 | M5EPD/src/base/ftdbgmem.c 49 | M5EPD/src/sfnt/ttsbit0.c 50 | M5EPD/src/sfnt/sfnt.c 51 | M5EPD/src/sfnt/ttkern.c 52 | M5EPD/src/sfnt/ttpost.c 53 | M5EPD/src/sfnt/ttcmap.c 54 | M5EPD/src/sfnt/ttbdf.c 55 | M5EPD/src/sfnt/sfntpic.c 56 | M5EPD/src/sfnt/sfobjs.c 57 | M5EPD/src/sfnt/ttsbit.c 58 | M5EPD/src/sfnt/ttmtx.c 59 | M5EPD/src/sfnt/ttload.c 60 | M5EPD/src/sfnt/sfdriver.c 61 | M5EPD/src/smooth/ftgrays.c 62 | M5EPD/src/smooth/smooth.c 63 | M5EPD/src/smooth/ftsmooth.c 64 | M5EPD/src/smooth/ftspic.c 65 | src/freetype_helper.c 66 | ) 67 | 68 | idf_component_register(INCLUDE_DIRS ${INCLUDEDIRS} SRCS ${SRCS} REQUIRES arduino-esp32) 69 | 70 | target_compile_options(${COMPONENT_TARGET} PRIVATE 71 | -O3 72 | ) 73 | -------------------------------------------------------------------------------- /components/freetype/src/freetype_helper.c: -------------------------------------------------------------------------------- 1 | #include "freetype_helper.h" 2 | 3 | /** 4 | * alphaBlend 5 | * 6 | * from: M5Stack In_eSPI.cpp 7 | * https://github.com/m5stack/M5Stack/blob/master/src/utility/In_eSPI.cpp#L5884-L5908 8 | */ 9 | uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc) 10 | { 11 | if (alpha == 255) 12 | { 13 | return fgc; 14 | } 15 | else if (alpha == 0) 16 | { 17 | return bgc; 18 | } 19 | if (fgc == bgc) 20 | { 21 | return fgc; 22 | } 23 | // For speed use fixed point maths and rounding to permit a power of 2 division 24 | uint16_t fgR = ((fgc >> 10) & 0x3E) + 1; 25 | uint16_t fgG = ((fgc >> 4) & 0x7E) + 1; 26 | uint16_t fgB = ((fgc << 1) & 0x3E) + 1; 27 | 28 | uint16_t bgR = ((bgc >> 10) & 0x3E) + 1; 29 | uint16_t bgG = ((bgc >> 4) & 0x7E) + 1; 30 | uint16_t bgB = ((bgc << 1) & 0x3E) + 1; 31 | 32 | // Shift right 1 to drop rounding bit and shift right 8 to divide by 256 33 | uint16_t r = (((fgR * alpha) + (bgR * (255 - alpha))) >> 9); 34 | uint16_t g = (((fgG * alpha) + (bgG * (255 - alpha))) >> 9); 35 | uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9); 36 | 37 | // Combine RGB565 colours into 16 bits 38 | // return ((r&0x18) << 11) | ((g&0x30) << 5) | ((b&0x18) << 0); // 2 bit greyscale 39 | // return ((r&0x1E) << 11) | ((g&0x3C) << 5) | ((b&0x1E) << 0); // 4 bit greyscale 40 | return (r << 11) | (g << 5) | (b << 0); 41 | } 42 | 43 | /** 44 | * decodeUTF8 45 | * 46 | */ 47 | uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining) 48 | { 49 | uint16_t c = buf[(*index)++]; 50 | // 51 | // 7 bit Unicode 52 | if ((c & 0x80) == 0x00) 53 | return c; 54 | 55 | // 11 bit Unicode 56 | if (((c & 0xE0) == 0xC0) && (remaining > 1)) 57 | return ((c & 0x1F) << 6) | (buf[(*index)++] & 0x3F); 58 | 59 | // 16 bit Unicode 60 | if (((c & 0xF0) == 0xE0) && (remaining > 2)) 61 | { 62 | c = ((c & 0x0F) << 12) | ((buf[(*index)++] & 0x3F) << 6); 63 | return c | ((buf[(*index)++] & 0x3F)); 64 | } 65 | 66 | // 21 bit Unicode not supported so fall-back to extended ASCII 67 | // if ((c & 0xF8) == 0xF0) return c; 68 | 69 | return c; // fall-back to extended ASCII 70 | } 71 | -------------------------------------------------------------------------------- /main/test_uart_gpio1819.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "esp_log.h" 3 | #include "lwgps/lwgps.h" 4 | 5 | #include "test_uart_gpio1819.h" 6 | 7 | static const char *TAG = "test_uart_gpio1819.cpp"; 8 | 9 | // UART Sensor 10 | // M5STACK UNIT GPS 11 | // https://docs.m5stack.com/en/unit/gps 12 | HardwareSerial GPSRaw(1); 13 | 14 | /* GPS handle */ 15 | lwgps_t hgps; 16 | 17 | void init_uart_gpio1819(void) 18 | { 19 | GPSRaw.begin(9600); 20 | // Set pin (connected reverse) 21 | GPSRaw.setPins(/* GPS TXD (yellow) */ 19, /* GPS RXD (write) */ 18); 22 | // Init GPS 23 | lwgps_init(&hgps); 24 | 25 | ESP_LOGI(TAG, "Hardware serial and lwgps initialized."); 26 | } 27 | 28 | void get_uart_gpsgsv_data(unitgpsgsv_t unitgpsgsv[], uint8_t *satellites) 29 | { 30 | uint8_t buffer[255]; 31 | 32 | while(GPSRaw.available() > 0) { 33 | size_t size = GPSRaw.read(buffer, sizeof(buffer)); 34 | if(size > 0) { 35 | // ESP_LOGI(TAG, "GPS: %s", buffer); 36 | lwgps_process(&hgps, buffer, size); 37 | } 38 | if(hgps.is_valid == 1) { 39 | // ESP_LOGI(TAG, "Latitude: %f degrees", hgps.latitude); 40 | // ESP_LOGI(TAG, "Longitude: %f degrees", hgps.longitude); 41 | // ESP_LOGI(TAG, "Altitude: %f meters", hgps.altitude); 42 | for(uint8_t i = 0; i < 12; i++) { 43 | satellites[i] = hgps.satellites_ids[i]; 44 | // if(satellites[i] != 0) { 45 | // ESP_LOGI(TAG, "GSA satellites_ids[%d]=%d", i, satellites[i]); 46 | // } 47 | } 48 | } 49 | for(uint8_t i = 0; i < 12; i++) { 50 | uint8_t num = hgps.sats_in_view_desc[i].num; 51 | if(num != 0) { 52 | unitgpsgsv[i].num = num; 53 | unitgpsgsv[i].elevation = hgps.sats_in_view_desc[i].elevation; 54 | unitgpsgsv[i].azimuth = hgps.sats_in_view_desc[i].azimuth; 55 | unitgpsgsv[i].snr = hgps.sats_in_view_desc[i].snr; 56 | // ESP_LOGI(TAG, "GSV %d, elevation %d, azimuth %d, snr %d", 57 | // num, 58 | // unitgpsgsv[i].elevation, 59 | // unitgpsgsv[i].azimuth, 60 | // unitgpsgsv[i].snr 61 | // ); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad 6.0.3-a3aad9c10e~116~ubuntu20.04.1} date 2022年03月24日 13時26分21秒 3 | ; FORMAT={-:-/ absolute / inch / decimal} 4 | ; #@! TF.CreationDate,2022-03-24T13:26:21+09:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1 6 | ; #@! TF.FileFunction,MixedPlating,1,2 7 | FMAT,2 8 | INCH 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.0157 11 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 12 | T2C0.0300 13 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 14 | T3C0.0315 15 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 16 | T4C0.0394 17 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 18 | T5C0.0433 19 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 20 | T6C0.0866 21 | % 22 | G90 23 | G05 24 | T1 25 | X3.64Y-3.3 26 | X4.34Y-3.3 27 | T2 28 | X1.8692Y-3.1395 29 | X1.8692Y-3.4395 30 | X1.8692Y-3.5395 31 | X1.9692Y-3.1395 32 | X2.0692Y-3.1395 33 | X2.1692Y-3.1395 34 | X2.2692Y-3.1395 35 | X2.3692Y-3.1395 36 | X2.4692Y-3.1395 37 | X2.4692Y-3.4395 38 | X2.4692Y-3.5395 39 | T3 40 | X1.83Y-2.93 41 | X2.13Y-2.93 42 | X2.23Y-2.93 43 | X2.53Y-2.93 44 | X2.7Y-1.71 45 | X2.7Y-1.86 46 | X2.7Y-2.01 47 | X2.7Y-2.16 48 | X2.7Y-2.31 49 | X3.0Y-1.71 50 | X3.0Y-1.86 51 | X3.0Y-2.01 52 | X3.0Y-2.16 53 | X3.0Y-2.31 54 | T4 55 | X1.83Y-1.61 56 | X1.83Y-1.71 57 | X1.83Y-1.81 58 | X1.83Y-1.91 59 | X1.83Y-2.01 60 | X1.83Y-2.11 61 | X1.83Y-2.21 62 | X1.83Y-2.31 63 | X1.83Y-2.41 64 | X1.83Y-2.51 65 | X1.83Y-2.61 66 | X1.83Y-2.71 67 | X2.53Y-1.61 68 | X2.53Y-1.71 69 | X2.53Y-1.81 70 | X2.53Y-1.91 71 | X2.53Y-2.01 72 | X2.53Y-2.11 73 | X2.53Y-2.21 74 | X2.53Y-2.31 75 | X2.53Y-2.41 76 | X2.53Y-2.51 77 | X2.53Y-2.61 78 | X2.53Y-2.71 79 | X2.7798Y-3.13 80 | X2.8798Y-3.13 81 | X3.1646Y-1.8 82 | X3.1646Y-1.9 83 | X3.1646Y-2.0 84 | X3.1646Y-2.1 85 | X3.1646Y-2.2 86 | X3.1646Y-2.3 87 | X3.1646Y-2.4 88 | X3.1646Y-2.5 89 | X3.1646Y-2.6 90 | X3.1646Y-2.7 91 | X3.1646Y-2.8 92 | X3.1646Y-2.9 93 | X3.1646Y-3.0 94 | X3.1646Y-3.1 95 | X3.1646Y-3.2 96 | X3.1646Y-3.3 97 | X3.54Y-3.54 98 | X3.64Y-3.54 99 | X3.74Y-3.54 100 | X3.84Y-3.54 101 | X3.94Y-3.54 102 | X4.04Y-3.54 103 | X4.14Y-3.54 104 | X4.24Y-3.54 105 | X4.34Y-3.54 106 | X4.44Y-3.54 107 | X4.54Y-3.54 108 | X4.64Y-3.54 109 | T5 110 | X2.71Y-3.3514 111 | X2.71Y-3.5286 112 | X2.9659Y-3.3514 113 | X2.9659Y-3.5286 114 | T6 115 | X1.6929Y-1.6177 116 | X1.6929Y-3.5469 117 | X4.8819Y-1.7594 118 | X5.0Y-3.5469 119 | T0 120 | M30 121 | -------------------------------------------------------------------------------- /main/test_i2c_gpio1819.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "driver/i2c.h" 3 | #include "esp_log.h" 4 | #include "hal/gpio_hal.h" 5 | 6 | #include "M5_ENV.h" 7 | #include "Unit_Sonic.h" 8 | 9 | #include "test_i2c_gpio1819.h" 10 | 11 | static const char *TAG = "test_i2c_gpio1819.cpp"; 12 | 13 | // I2C Sensor 14 | // M5STACK ENV III Unit 15 | // https://docs.m5stack.com/en/unit/envIII 16 | SHT3X sht30; 17 | QMP6988 qmp6988; 18 | bool unitenviii_connected; 19 | 20 | // I2C UltraSonic Sensor 21 | // M5STACK UNIT SONIC I2C 22 | // https://docs.m5stack.com/en/unit/sonic.i2c 23 | SONIC_I2C rcwl9620; 24 | bool rcwl9620_connected; 25 | 26 | #define I2C_SDA 18 27 | #define I2C_SCL 19 28 | 29 | void init_i2c_gpio1819(void) 30 | { 31 | // components/unitenv/UNIT_ENV/src/SHT3X.cpp 32 | // SHT3X::SHT3X(uint8_t address) 33 | // { 34 | // Wire.begin(); 35 | // _address=address; 36 | // } 37 | // 38 | // Force i2c reassignment because Wire is initialized in the SHT3X constructor. 39 | Wire.end(); 40 | // or i2c_set_pin(0, I2C_SDA, I2C_SCL, true, true, I2C_MODE_MASTER); 41 | Wire.begin(I2C_SDA, I2C_SCL); 42 | 43 | // Unit ENV III 44 | unitenviii_connected = false; 45 | if(qmp6988.init()) { 46 | ESP_LOGI(TAG, "I2C: Found Unit ENV III"); 47 | unitenviii_connected = true; 48 | } else { 49 | ESP_LOGI(TAG, "I2C: Not found Unit ENV III"); 50 | } 51 | 52 | // Unit UltraSonic 53 | rcwl9620_connected = false; 54 | Wire.beginTransmission(0x57); 55 | if(Wire.endTransmission() == 0) { 56 | ESP_LOGI(TAG, "I2C: Found Unit UltraSonic"); 57 | rcwl9620.begin(&Wire); 58 | rcwl9620_connected = true; 59 | } else { 60 | ESP_LOGI(TAG, "I2C: Not found Unit UltraSonic"); 61 | } 62 | } 63 | 64 | void get_i2c_unit_data(unitenv_t *unitenv, unit_ultrasonic_t *ultrasonic) 65 | { 66 | // Unit ENV III 67 | if(unitenviii_connected) { 68 | unitenv->pressure = qmp6988.calcPressure() / 100; 69 | if(sht30.get() == 0) { 70 | unitenv->tmp = sht30.cTemp; 71 | unitenv->hum = sht30.humidity; 72 | } else { 73 | unitenv->tmp = 0; 74 | unitenv->hum = 0; 75 | } 76 | } else { 77 | unitenv->pressure = 0; 78 | unitenv->tmp = 0; 79 | unitenv->hum = 0; 80 | } 81 | 82 | // Unit UltraSonic 83 | if(rcwl9620_connected) { 84 | ultrasonic->distance = rcwl9620.getDistance(); 85 | } else { 86 | ultrasonic->distance = 0; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /main/test_freetype.cpp: -------------------------------------------------------------------------------- 1 | #include "SPIFFS.h" 2 | #include "ffsupport.h" 3 | #include "font_render.h" 4 | #include "freetype_helper.h" 5 | 6 | #include "test_freetype.h" 7 | #include "c3dev_board.h" 8 | 9 | static const char *TAG = "test_freetype.cpp"; 10 | 11 | /** 12 | * SPIFFS member 13 | */ 14 | fs::SPIFFSFS SPIFFS_FONT; 15 | 16 | /** 17 | * FreeType member 18 | */ 19 | font_face_t font_face; 20 | const uint8_t alphamap[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}; 21 | 22 | /** 23 | * Utility draw_freetype_pixel 24 | */ 25 | void draw_freetype_pixel(int32_t cx, int32_t cy, uint16_t bw, uint16_t bh, uint16_t fg, uint8_t *bitmap) 26 | { 27 | uint32_t pos = 0; 28 | uint16_t bg = 0; 29 | 30 | tft.startWrite(); 31 | for (int y = 0; y < bh; y++) { 32 | for (int x = 0; x < bw; x++) { 33 | if (pos & 0x1) { 34 | tft.writePixel(cx + x, cy + y, alphaBlend(alphamap[bitmap[pos >> 1] & 0x0F], fg, bg)); 35 | } else { 36 | tft.writePixel(cx + x, cy + y, alphaBlend(alphamap[bitmap[pos >> 1] >> 4], fg, bg)); 37 | } 38 | pos++; 39 | } 40 | } 41 | tft.endWrite(); 42 | } 43 | 44 | /** 45 | * Utility drawString 46 | */ 47 | void draw_freetype_string(const char *string, int32_t poX, int32_t poY, uint16_t fg, font_render_t *render) 48 | { 49 | int16_t sumX = 0; 50 | uint16_t len = strlen(string); 51 | uint16_t n = 0; 52 | uint16_t base_y = poY; 53 | 54 | while (n < len) { 55 | uint16_t uniCode = decodeUTF8((uint8_t *)string, &n, len - n); 56 | if (font_render_glyph(render, uniCode) != ESP_OK) { 57 | ESP_LOGE(TAG, "Font render faild."); 58 | } 59 | draw_freetype_pixel(poX + render->bitmap_left, 60 | base_y - render->bitmap_top, 61 | render->bitmap_width, 62 | render->bitmap_height, 63 | fg, 64 | render->bitmap 65 | ); 66 | poX += render->advance; 67 | sumX += render->advance; 68 | } 69 | } 70 | 71 | void init_freetype(void) 72 | { 73 | // FreeType initialize 74 | SPIFFS_FONT.begin(false, "/font", 4, "font"); 75 | ffsupport_setffs(SPIFFS_FONT); 76 | if (font_face_init_fs(&font_face, "/GENSHINM.TTF") != ESP_OK) { 77 | ESP_LOGE(TAG, "Font load faild."); 78 | } 79 | } 80 | 81 | font_render_t create_freetype_render(uint32_t font_size, uint32_t font_cache_size) 82 | { 83 | font_render_t font_render; 84 | 85 | // Font render initialize 86 | if (font_render_init(&font_render, &font_face, font_size, font_cache_size) != ESP_OK) { 87 | ESP_LOGE(TAG, "Render creation failed."); 88 | } 89 | 90 | return font_render; 91 | } 92 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg-series.pretty/AE-USB2.0-TYPE-C.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "AE-USB2.0-TYPE-C" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 61CE948B) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 -7.62) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp b06ce446-c27e-47df-a4e3-d10b64552c26) 8 | ) 9 | (fp_text value "AE-USB2.0-TYPE-C" (at -0.02 9.26) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp c9a0dd18-d945-4bfe-8921-ced29a4068d2) 12 | ) 13 | (fp_line (start -5.11 -0.34) (end -5.11 -6.69) (layer "F.SilkS") (width 0.12) (tstamp 24cb67fc-f0c9-4f6e-88c1-7636ab854c5e)) 14 | (fp_line (start -10.02 -6.75) (end 9.98 -6.75) (layer "F.SilkS") (width 0.12) (tstamp 81c041f3-483e-477d-9475-d108280de2a9)) 15 | (fp_line (start 9.98 8.25) (end -10.02 8.25) (layer "F.SilkS") (width 0.12) (tstamp 92e8f8c3-0985-4c0d-8e38-92cbbf365409)) 16 | (fp_line (start 5.05 -6.69) (end 5.05 -0.34) (layer "F.SilkS") (width 0.12) (tstamp b0f642eb-e44e-4747-9d08-48aa7b02d88d)) 17 | (fp_line (start 5.05 -0.34) (end -5.11 -0.34) (layer "F.SilkS") (width 0.12) (tstamp b89754be-9738-4e5f-8e95-e260ee696903)) 18 | (fp_line (start -10.02 8.25) (end -10.02 -6.75) (layer "F.SilkS") (width 0.12) (tstamp e149e0b1-47fa-4b20-b36e-2d51ee1e85c3)) 19 | (fp_line (start 9.98 -6.75) (end 9.98 8.25) (layer "F.SilkS") (width 0.12) (tstamp e68c5170-03c3-4a20-abd0-ad610c43d035)) 20 | (pad "" thru_hole rect (at 7.62 -3.81) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 563c12e4-8f8c-446c-a11f-94f5aa93b994)) 21 | (pad "" thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 681bd495-c396-44ce-92bd-4b397cd48c04)) 22 | (pad "" thru_hole rect (at 7.62 -1.27) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp a3668681-09b1-48f0-a7b1-f6b24183a469)) 23 | (pad "" thru_hole circle (at -7.62 -3.81) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp be0953c0-632d-4dd2-85e9-4d41239f22d2)) 24 | (pad "1" thru_hole rect (at -7.62 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 5994a946-119f-4db4-aafe-00ae73b5b800)) 25 | (pad "2" thru_hole circle (at -5.08 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp f6ee98b5-4773-4eeb-a825-33c1705abace)) 26 | (pad "3" thru_hole circle (at -2.54 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp eaef1172-3351-417c-bfc4-74a598f141cb)) 27 | (pad "4" thru_hole circle (at 0 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 08e2d62f-f99a-4268-8b33-617dfcc63e75)) 28 | (pad "5" thru_hole circle (at 2.54 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp b680b4a7-6cb0-40b5-a7ec-a02910a0daa4)) 29 | (pad "6" thru_hole circle (at 5.08 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp c5a1761e-3391-4e74-90c9-947fd66e1fc6)) 30 | (pad "7" thru_hole circle (at 7.62 6.35) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp a1c7b1f5-f895-4192-9484-2357882c73e0)) 31 | ) 32 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg-series.pretty/BNX016-01.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "BNX016-01" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 5F69D20F) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 -6.35) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 37e8181c-a81e-498b-b2e2-0aef0c391059) 8 | ) 9 | (fp_text value "BNX016-01" (at 0 6.35) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 676efd2f-1c48-4786-9e4b-2444f1e8f6ff) 12 | ) 13 | (fp_line (start -5.969 -5.08) (end -5.969 5.08) (layer "F.SilkS") (width 0.12) (tstamp 0351df45-d042-41d4-ba35-88092c7be2fc)) 14 | (fp_line (start -5.969 -5.461) (end -5.08 -5.461) (layer "F.SilkS") (width 0.12) (tstamp 097edb1b-8998-4e70-b670-bba125982348)) 15 | (fp_line (start 5.969 5.08) (end 5.969 5.461) (layer "F.SilkS") (width 0.12) (tstamp 0e1ed1c5-7428-4dc7-b76e-49b2d5f8177d)) 16 | (fp_line (start 5.969 5.461) (end 5.08 5.461) (layer "F.SilkS") (width 0.12) (tstamp 14c51520-6d91-4098-a59a-5121f2a898f7)) 17 | (fp_line (start 5.969 -5.08) (end 5.969 5.08) (layer "F.SilkS") (width 0.12) (tstamp 240e5dac-6242-47a5-bbef-f76d11c715c0)) 18 | (fp_line (start -5.08 5.461) (end -5.969 5.461) (layer "F.SilkS") (width 0.12) (tstamp 2d67a417-188f-4014-9282-000265d80009)) 19 | (fp_line (start -5.969 -5.08) (end -5.969 -5.461) (layer "F.SilkS") (width 0.12) (tstamp 477311b9-8f81-40c8-9c55-fd87e287247a)) 20 | (fp_line (start -5.969 5.461) (end -5.969 5.08) (layer "F.SilkS") (width 0.12) (tstamp 84e5506c-143e-495f-9aa4-d3a71622f213)) 21 | (fp_line (start 5.08 5.461) (end -5.08 5.461) (layer "F.SilkS") (width 0.12) (tstamp 8d9a3ecc-539f-41da-8099-d37cea9c28e7)) 22 | (fp_line (start 5.08 -5.461) (end 5.969 -5.461) (layer "F.SilkS") (width 0.12) (tstamp aa2ea573-3f20-43c1-aa99-1f9c6031a9aa)) 23 | (fp_line (start -5.08 -5.461) (end 5.08 -5.461) (layer "F.SilkS") (width 0.12) (tstamp e472dac4-5b65-4920-b8b2-6065d140a69d)) 24 | (fp_line (start 5.969 -5.461) (end 5.969 -5.08) (layer "F.SilkS") (width 0.12) (tstamp f40d350f-0d3e-4f8a-b004-d950f2f8f1ba)) 25 | (pad "1" thru_hole circle (at 2.54 -2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 67763d19-f622-4e1e-81e5-5b24da7c3f99)) 26 | (pad "2" thru_hole circle (at 2.54 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 099096e4-8c2a-4d84-a16f-06b4b6330e7a)) 27 | (pad "3" thru_hole circle (at -2.54 -2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp ca5a4651-0d1d-441b-b17d-01518ef3b656)) 28 | (pad "4" thru_hole circle (at -2.54 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp a13ab237-8f8d-4e16-8c47-4440653b8534)) 29 | (pad "5" thru_hole circle (at 0 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 994b6220-4755-4d84-91b3-6122ac1c2c5e)) 30 | (pad "6" thru_hole circle (at 5.08 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 6284122b-79c3-4e04-925e-3d32cc3ec077)) 31 | (model "./fg-series.vrml2/BNX016-01.x3d" 32 | (offset (xyz 0 0 0)) 33 | (scale (xyz 4 4 4)) 34 | (rotate (xyz -90 0 180)) 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-job.gbrjob: -------------------------------------------------------------------------------- 1 | { 2 | "Header": { 3 | "GenerationSoftware": { 4 | "Vendor": "KiCad", 5 | "Application": "Pcbnew", 6 | "Version": "6.0.3-a3aad9c10e~116~ubuntu20.04.1" 7 | }, 8 | "CreationDate": "2022-03-24T13:24:43+09:00" 9 | }, 10 | "GeneralSpecs": { 11 | "ProjectId": { 12 | "Name": "fg06-c3dev-revb", 13 | "GUID": "66673036-2d63-4336-9465-762d72657662", 14 | "Revision": "rev?" 15 | }, 16 | "Size": { 17 | "X": 90.05, 18 | "Y": 55.05 19 | }, 20 | "LayerNumber": 2, 21 | "BoardThickness": 1.6, 22 | "Finish": "None" 23 | }, 24 | "DesignRules": [ 25 | { 26 | "Layers": "Outer", 27 | "PadToPad": 0.0, 28 | "PadToTrack": 0.0, 29 | "TrackToTrack": 0.2, 30 | "MinLineWidth": 0.25, 31 | "TrackToRegion": 0.508, 32 | "RegionToRegion": 0.508 33 | } 34 | ], 35 | "FilesAttributes": [ 36 | { 37 | "Path": "fg06-c3dev-revb-F_Cu.gtl", 38 | "FileFunction": "Copper,L1,Top", 39 | "FilePolarity": "Positive" 40 | }, 41 | { 42 | "Path": "fg06-c3dev-revb-B_Cu.gbl", 43 | "FileFunction": "Copper,L2,Bot", 44 | "FilePolarity": "Positive" 45 | }, 46 | { 47 | "Path": "fg06-c3dev-revb-F_Paste.gtp", 48 | "FileFunction": "SolderPaste,Top", 49 | "FilePolarity": "Positive" 50 | }, 51 | { 52 | "Path": "fg06-c3dev-revb-B_Paste.gbp", 53 | "FileFunction": "SolderPaste,Bot", 54 | "FilePolarity": "Positive" 55 | }, 56 | { 57 | "Path": "fg06-c3dev-revb-F_Silkscreen.gto", 58 | "FileFunction": "Legend,Top", 59 | "FilePolarity": "Positive" 60 | }, 61 | { 62 | "Path": "fg06-c3dev-revb-B_Silkscreen.gbo", 63 | "FileFunction": "Legend,Bot", 64 | "FilePolarity": "Positive" 65 | }, 66 | { 67 | "Path": "fg06-c3dev-revb-F_Mask.gts", 68 | "FileFunction": "SolderMask,Top", 69 | "FilePolarity": "Negative" 70 | }, 71 | { 72 | "Path": "fg06-c3dev-revb-B_Mask.gbs", 73 | "FileFunction": "SolderMask,Bot", 74 | "FilePolarity": "Negative" 75 | }, 76 | { 77 | "Path": "fg06-c3dev-revb-Edge_Cuts.gm1", 78 | "FileFunction": "Profile", 79 | "FilePolarity": "Positive" 80 | } 81 | ], 82 | "MaterialStackup": [ 83 | { 84 | "Type": "Legend", 85 | "Name": "Top Silk Screen" 86 | }, 87 | { 88 | "Type": "SolderPaste", 89 | "Name": "Top Solder Paste" 90 | }, 91 | { 92 | "Type": "SolderMask", 93 | "Thickness": 0.01, 94 | "Name": "Top Solder Mask" 95 | }, 96 | { 97 | "Type": "Copper", 98 | "Thickness": 0.035, 99 | "Name": "F.Cu" 100 | }, 101 | { 102 | "Type": "Dielectric", 103 | "Thickness": 1.51, 104 | "Material": "FR4", 105 | "Name": "F.Cu/B.Cu", 106 | "Notes": "Type: dielectric layer 1 (from F.Cu to B.Cu)" 107 | }, 108 | { 109 | "Type": "Copper", 110 | "Thickness": 0.035, 111 | "Name": "B.Cu" 112 | }, 113 | { 114 | "Type": "SolderMask", 115 | "Thickness": 0.01, 116 | "Name": "Bottom Solder Mask" 117 | }, 118 | { 119 | "Type": "SolderPaste", 120 | "Name": "Bottom Solder Paste" 121 | }, 122 | { 123 | "Type": "Legend", 124 | "Name": "Bottom Silk Screen" 125 | } 126 | ] 127 | } 128 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-B_Mask.gbs: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1* 2 | G04 #@! TF.CreationDate,2022-03-24T13:24:43+09:00* 3 | G04 #@! TF.ProjectId,fg06-c3dev-revb,66673036-2d63-4336-9465-762d72657662,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Soldermask,Bot* 6 | G04 #@! TF.FilePolarity,Negative* 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.3-a3aad9c10e~116~ubuntu20.04.1) date 2022-03-24 13:24:43* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %ADD10C,1.600000*% 15 | %ADD11O,1.600000X1.600000*% 16 | %ADD12C,2.000000*% 17 | %ADD13R,1.700000X1.700000*% 18 | %ADD14O,1.700000X1.700000*% 19 | %ADD15C,3.500000*% 20 | %ADD16C,1.700000*% 21 | %ADD17R,1.524000X1.524000*% 22 | %ADD18C,1.524000*% 23 | G04 APERTURE END LIST* 24 | D10* 25 | G04 #@! TO.C,R5* 26 | X68580000Y-51054000D03* 27 | D11* 28 | X76200000Y-51054000D03* 29 | G04 #@! TD* 30 | D12* 31 | G04 #@! TO.C,SW1* 32 | X75334000Y-85126000D03* 33 | X68834000Y-85126000D03* 34 | X75334000Y-89626000D03* 35 | X68834000Y-89626000D03* 36 | G04 #@! TD* 37 | D13* 38 | G04 #@! TO.C,J1* 39 | X117856000Y-89916000D03* 40 | D14* 41 | X115316000Y-89916000D03* 42 | X112776000Y-89916000D03* 43 | X110236000Y-89916000D03* 44 | X107696000Y-89916000D03* 45 | X105156000Y-89916000D03* 46 | X102616000Y-89916000D03* 47 | X100076000Y-89916000D03* 48 | X97536000Y-89916000D03* 49 | X94996000Y-89916000D03* 50 | X92456000Y-89916000D03* 51 | X89916000Y-89916000D03* 52 | G04 #@! TD* 53 | D13* 54 | G04 #@! TO.C,JP1* 55 | X70607000Y-79502000D03* 56 | D14* 57 | X73147000Y-79502000D03* 58 | G04 #@! TD* 59 | D10* 60 | G04 #@! TO.C,R4* 61 | X68580000Y-47244000D03* 62 | D11* 63 | X76200000Y-47244000D03* 64 | G04 #@! TD* 65 | D15* 66 | G04 #@! TO.C,REF4* 67 | X127000000Y-90090000D03* 68 | G04 #@! TD* 69 | D10* 70 | G04 #@! TO.C,R7* 71 | X68580000Y-58674000D03* 72 | D11* 73 | X76200000Y-58674000D03* 74 | G04 #@! TD* 75 | D10* 76 | G04 #@! TO.C,R6* 77 | X68580000Y-54864000D03* 78 | D11* 79 | X76200000Y-54864000D03* 80 | G04 #@! TD* 81 | D15* 82 | G04 #@! TO.C,REF2* 83 | X43000000Y-90090000D03* 84 | G04 #@! TD* 85 | G04 #@! TO.C,REF1* 86 | X43000000Y-41090000D03* 87 | G04 #@! TD* 88 | D16* 89 | G04 #@! TO.C,U2* 90 | X64262000Y-68834000D03* 91 | X64262000Y-66294000D03* 92 | X64262000Y-63754000D03* 93 | X64262000Y-61214000D03* 94 | X64262000Y-58674000D03* 95 | X64262000Y-56134000D03* 96 | X64262000Y-53594000D03* 97 | X64262000Y-51054000D03* 98 | X64262000Y-48514000D03* 99 | X64262000Y-45974000D03* 100 | X64262000Y-43434000D03* 101 | X64262000Y-40894000D03* 102 | X46482000Y-40894000D03* 103 | X46482000Y-43434000D03* 104 | X46482000Y-45974000D03* 105 | X46482000Y-48514000D03* 106 | X46482000Y-51054000D03* 107 | X46482000Y-53594000D03* 108 | X46482000Y-56134000D03* 109 | X46482000Y-58674000D03* 110 | X46482000Y-61214000D03* 111 | X46482000Y-63754000D03* 112 | X46482000Y-66294000D03* 113 | X46482000Y-68834000D03* 114 | G04 #@! TD* 115 | D15* 116 | G04 #@! TO.C,REF3* 117 | X124000000Y-44690000D03* 118 | G04 #@! TD* 119 | D10* 120 | G04 #@! TO.C,R1* 121 | X46482000Y-74422000D03* 122 | D11* 123 | X54102000Y-74422000D03* 124 | G04 #@! TD* 125 | D10* 126 | G04 #@! TO.C,R2* 127 | X56642000Y-74422000D03* 128 | D11* 129 | X64262000Y-74422000D03* 130 | G04 #@! TD* 131 | D17* 132 | G04 #@! TO.C,U1* 133 | X47478000Y-87364000D03* 134 | D18* 135 | X62718000Y-87364000D03* 136 | X62718000Y-89904000D03* 137 | D17* 138 | X47478000Y-89904000D03* 139 | X62718000Y-79744000D03* 140 | D18* 141 | X60178000Y-79744000D03* 142 | X57638000Y-79744000D03* 143 | X55098000Y-79744000D03* 144 | X52558000Y-79744000D03* 145 | X50018000Y-79744000D03* 146 | X47478000Y-79744000D03* 147 | G04 #@! TD* 148 | D16* 149 | G04 #@! TO.C,U3* 150 | X80380000Y-45720000D03* 151 | X80380000Y-48260000D03* 152 | X80380000Y-50800000D03* 153 | X80380000Y-53340000D03* 154 | X80380000Y-55880000D03* 155 | X80380000Y-58420000D03* 156 | X80380000Y-60960000D03* 157 | X80380000Y-63500000D03* 158 | X80380000Y-66040000D03* 159 | X80380000Y-68580000D03* 160 | X80380000Y-71120000D03* 161 | X80380000Y-73660000D03* 162 | X80380000Y-76200000D03* 163 | X80380000Y-78740000D03* 164 | X80380000Y-81280000D03* 165 | X80380000Y-83820000D03* 166 | G04 #@! TD* 167 | D10* 168 | G04 #@! TO.C,R3* 169 | X68580000Y-43434000D03* 170 | D11* 171 | X76200000Y-43434000D03* 172 | G04 #@! TD* 173 | M02* 174 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/gerber/fg06-c3dev-revb-F_Mask.gts: -------------------------------------------------------------------------------- 1 | G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,6.0.3-a3aad9c10e~116~ubuntu20.04.1* 2 | G04 #@! TF.CreationDate,2022-03-24T13:24:43+09:00* 3 | G04 #@! TF.ProjectId,fg06-c3dev-revb,66673036-2d63-4336-9465-762d72657662,rev?* 4 | G04 #@! TF.SameCoordinates,Original* 5 | G04 #@! TF.FileFunction,Soldermask,Top* 6 | G04 #@! TF.FilePolarity,Negative* 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.3-a3aad9c10e~116~ubuntu20.04.1) date 2022-03-24 13:24:43* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %ADD10C,1.600000*% 15 | %ADD11O,1.600000X1.600000*% 16 | %ADD12C,2.000000*% 17 | %ADD13R,1.700000X1.700000*% 18 | %ADD14O,1.700000X1.700000*% 19 | %ADD15C,3.500000*% 20 | %ADD16C,1.700000*% 21 | %ADD17R,1.524000X1.524000*% 22 | %ADD18C,1.524000*% 23 | G04 APERTURE END LIST* 24 | D10* 25 | G04 #@! TO.C,R5* 26 | X68580000Y-51054000D03* 27 | D11* 28 | X76200000Y-51054000D03* 29 | G04 #@! TD* 30 | D12* 31 | G04 #@! TO.C,SW1* 32 | X75334000Y-85126000D03* 33 | X68834000Y-85126000D03* 34 | X75334000Y-89626000D03* 35 | X68834000Y-89626000D03* 36 | G04 #@! TD* 37 | D13* 38 | G04 #@! TO.C,J1* 39 | X117856000Y-89916000D03* 40 | D14* 41 | X115316000Y-89916000D03* 42 | X112776000Y-89916000D03* 43 | X110236000Y-89916000D03* 44 | X107696000Y-89916000D03* 45 | X105156000Y-89916000D03* 46 | X102616000Y-89916000D03* 47 | X100076000Y-89916000D03* 48 | X97536000Y-89916000D03* 49 | X94996000Y-89916000D03* 50 | X92456000Y-89916000D03* 51 | X89916000Y-89916000D03* 52 | G04 #@! TD* 53 | D13* 54 | G04 #@! TO.C,JP1* 55 | X70607000Y-79502000D03* 56 | D14* 57 | X73147000Y-79502000D03* 58 | G04 #@! TD* 59 | D10* 60 | G04 #@! TO.C,R4* 61 | X68580000Y-47244000D03* 62 | D11* 63 | X76200000Y-47244000D03* 64 | G04 #@! TD* 65 | D15* 66 | G04 #@! TO.C,REF4* 67 | X127000000Y-90090000D03* 68 | G04 #@! TD* 69 | D10* 70 | G04 #@! TO.C,R7* 71 | X68580000Y-58674000D03* 72 | D11* 73 | X76200000Y-58674000D03* 74 | G04 #@! TD* 75 | D10* 76 | G04 #@! TO.C,R6* 77 | X68580000Y-54864000D03* 78 | D11* 79 | X76200000Y-54864000D03* 80 | G04 #@! TD* 81 | D15* 82 | G04 #@! TO.C,REF2* 83 | X43000000Y-90090000D03* 84 | G04 #@! TD* 85 | G04 #@! TO.C,REF1* 86 | X43000000Y-41090000D03* 87 | G04 #@! TD* 88 | D16* 89 | G04 #@! TO.C,U2* 90 | X64262000Y-68834000D03* 91 | X64262000Y-66294000D03* 92 | X64262000Y-63754000D03* 93 | X64262000Y-61214000D03* 94 | X64262000Y-58674000D03* 95 | X64262000Y-56134000D03* 96 | X64262000Y-53594000D03* 97 | X64262000Y-51054000D03* 98 | X64262000Y-48514000D03* 99 | X64262000Y-45974000D03* 100 | X64262000Y-43434000D03* 101 | X64262000Y-40894000D03* 102 | X46482000Y-40894000D03* 103 | X46482000Y-43434000D03* 104 | X46482000Y-45974000D03* 105 | X46482000Y-48514000D03* 106 | X46482000Y-51054000D03* 107 | X46482000Y-53594000D03* 108 | X46482000Y-56134000D03* 109 | X46482000Y-58674000D03* 110 | X46482000Y-61214000D03* 111 | X46482000Y-63754000D03* 112 | X46482000Y-66294000D03* 113 | X46482000Y-68834000D03* 114 | G04 #@! TD* 115 | D15* 116 | G04 #@! TO.C,REF3* 117 | X124000000Y-44690000D03* 118 | G04 #@! TD* 119 | D10* 120 | G04 #@! TO.C,R1* 121 | X46482000Y-74422000D03* 122 | D11* 123 | X54102000Y-74422000D03* 124 | G04 #@! TD* 125 | D10* 126 | G04 #@! TO.C,R2* 127 | X56642000Y-74422000D03* 128 | D11* 129 | X64262000Y-74422000D03* 130 | G04 #@! TD* 131 | D17* 132 | G04 #@! TO.C,U1* 133 | X47478000Y-87364000D03* 134 | D18* 135 | X62718000Y-87364000D03* 136 | X62718000Y-89904000D03* 137 | D17* 138 | X47478000Y-89904000D03* 139 | X62718000Y-79744000D03* 140 | D18* 141 | X60178000Y-79744000D03* 142 | X57638000Y-79744000D03* 143 | X55098000Y-79744000D03* 144 | X52558000Y-79744000D03* 145 | X50018000Y-79744000D03* 146 | X47478000Y-79744000D03* 147 | G04 #@! TD* 148 | D16* 149 | G04 #@! TO.C,U3* 150 | X80380000Y-45720000D03* 151 | X80380000Y-48260000D03* 152 | X80380000Y-50800000D03* 153 | X80380000Y-53340000D03* 154 | X80380000Y-55880000D03* 155 | X80380000Y-58420000D03* 156 | X80380000Y-60960000D03* 157 | X80380000Y-63500000D03* 158 | X80380000Y-66040000D03* 159 | X80380000Y-68580000D03* 160 | X80380000Y-71120000D03* 161 | X80380000Y-73660000D03* 162 | X80380000Y-76200000D03* 163 | X80380000Y-78740000D03* 164 | X80380000Y-81280000D03* 165 | X80380000Y-83820000D03* 166 | G04 #@! TD* 167 | D10* 168 | G04 #@! TO.C,R3* 169 | X68580000Y-43434000D03* 170 | D11* 171 | X76200000Y-43434000D03* 172 | G04 #@! TD* 173 | M02* 174 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg-series.pretty/KMR-1.8SPI.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "KMR-1.8SPI" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 620F00DA) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 -24.13) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp fef37e8b-0ff0-4da2-8a57-acaf19551d1a) 8 | ) 9 | (fp_text value "KMR-1.8SPI" (at 0 24.13) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp d21cc5e4-177a-4e1d-a8d5-060ed33e5b8e) 12 | ) 13 | (fp_line (start 22.86 22.86) (end -22.86 22.86) (layer "F.SilkS") (width 0.12) (tstamp 88d2c4b8-79f2-4e8b-9f70-b7e0ed9c70f8)) 14 | (fp_line (start -22.86 -22.86) (end 22.86 -22.86) (layer "F.SilkS") (width 0.12) (tstamp 89c0bc4d-eee5-4a77-ac35-d30b35db5cbe)) 15 | (fp_line (start -25.4 20.32) (end -25.4 -20.32) (layer "F.SilkS") (width 0.12) (tstamp a7531a95-7ca1-4f34-955e-18120cec99e6)) 16 | (fp_line (start 25.4 -20.32) (end 25.4 20.32) (layer "F.SilkS") (width 0.12) (tstamp e1c30a32-820e-4b17-aec9-5cb8b76f0ccc)) 17 | (fp_arc (start 22.86 -22.86) (mid 24.656051 -22.116051) (end 25.4 -20.32) (layer "F.SilkS") (width 0.12) (tstamp 34d03349-6d78-4165-a683-2d8b76f2bae8)) 18 | (fp_arc (start -22.86 22.86) (mid -24.656051 22.116051) (end -25.4 20.32) (layer "F.SilkS") (width 0.12) (tstamp 37b6c6d6-3e12-4736-912a-ea6e2bf06721)) 19 | (fp_arc (start 25.4 20.32) (mid 24.656051 22.116051) (end 22.86 22.86) (layer "F.SilkS") (width 0.12) (tstamp bb4b1afc-c46e-451d-8dad-36b7dec82f26)) 20 | (fp_arc (start -25.4 -20.32) (mid -24.656051 -22.116051) (end -22.86 -22.86) (layer "F.SilkS") (width 0.12) (tstamp f8fc38ec-0b98-40bc-ae2f-e5cc29973bca)) 21 | (fp_circle (center -21.5 19.86) (end -21.5 21.26) (layer "F.SilkS") (width 0.12) (fill none) (tstamp 0bcafe80-ffba-4f1e-ae51-95a595b006db)) 22 | (fp_circle (center -21.5 -20.06) (end -21.5 -18.66) (layer "F.SilkS") (width 0.12) (fill none) (tstamp 86dc7a78-7d51-4111-9eea-8a8f7977eb16)) 23 | (fp_circle (center 19.4 -20.06) (end 19.4 -18.66) (layer "F.SilkS") (width 0.12) (fill none) (tstamp e32ee344-1030-4498-9cac-bfbf7540faf4)) 24 | (pad "1" thru_hole circle (at -24.13 -19.05) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 026ac84e-b8b2-4dd2-b675-8323c24fd778)) 25 | (pad "2" thru_hole circle (at -24.13 -16.51) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp da25bf79-0abb-4fac-a221-ca5c574dfc29)) 26 | (pad "3" thru_hole circle (at -24.13 -13.97) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 34cdc1c9-c9e2-44c4-9677-c1c7d7efd83d)) 27 | (pad "4" thru_hole circle (at -24.13 -11.43) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp c49d23ab-146d-4089-864f-2d22b5b414b9)) 28 | (pad "5" thru_hole circle (at -24.13 -8.89) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp c7af8405-da2e-4a34-b9b8-518f342f8995)) 29 | (pad "6" thru_hole circle (at -24.13 -6.35) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp aa79024d-ca7e-4c24-b127-7df08bbd0c75)) 30 | (pad "7" thru_hole circle (at -24.13 -3.81) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 26801cfb-b53b-4a6a-a2f4-5f4986565765)) 31 | (pad "8" thru_hole circle (at -24.13 -1.27) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp f78e02cd-9600-4173-be8d-67e530b5d19f)) 32 | (pad "9" thru_hole circle (at -24.13 1.27) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 6f80f798-dc24-438f-a1eb-4ee2936267c8)) 33 | (pad "10" thru_hole circle (at -24.13 3.81) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp f66398f1-1ae7-4d4d-939f-958c174c6bce)) 34 | (pad "11" thru_hole circle (at -24.13 6.35) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 088f77ba-fca9-42b3-876e-a6937267f957)) 35 | (pad "12" thru_hole circle (at -24.13 8.89) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 71989e06-8659-4605-b2da-4f729cc41263)) 36 | (pad "13" thru_hole circle (at -24.13 11.43) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 9a0b74a5-4879-4b51-8e8e-6d85a0107422)) 37 | (pad "14" thru_hole circle (at -24.13 13.97) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp eae14f5f-515c-4a6f-ad0e-e8ef233d14bf)) 38 | (pad "15" thru_hole circle (at -24.13 16.51) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 6e435cd4-da2b-4602-a0aa-5dd988834dff)) 39 | (pad "16" thru_hole circle (at -24.13 19.05) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 6f675e5f-8fe6-4148-baf1-da97afc770f8)) 40 | (model "$KIPRJMOD/fg-series.vrml2/KMR-18.x3d" 41 | (offset (xyz 0 0 5)) 42 | (scale (xyz 4 4 4)) 43 | (rotate (xyz -90 0 -90)) 44 | ) 45 | ) 46 | -------------------------------------------------------------------------------- /wasm/imu6886/src/main.ts: -------------------------------------------------------------------------------- 1 | import * as c3dev from "./c3dev"; 2 | 3 | let imu: Imu | null; 4 | 5 | const DEG_TO_RAD: f32 = Math.PI / 180; 6 | const CUBE_POINTS: f32[][] = [ 7 | [-1, -1, 1], 8 | [ 1, -1, 1], 9 | [ 1, 1, 1], 10 | [-1, 1, 1], 11 | [-1, -1, -1], 12 | [ 1, -1, -1], 13 | [ 1, 1, -1], 14 | [-1, 1, -1] 15 | ]; 16 | const CUBE_LENGTH = 8; 17 | 18 | const DISTANCE: f32 = 4; 19 | const SCALE: f32 = 120; 20 | 21 | /** 22 | * IMU sensor 23 | */ 24 | class Imu { 25 | private centerX: f32 = 0; 26 | private centerY: f32 = 0; 27 | private angle: f32 = 0; 28 | private prevProj2dPoints: u32[][] = []; 29 | 30 | constructor( 31 | private width: u32, 32 | private height: u32 33 | ) { 34 | this.init(); 35 | } 36 | 37 | init(): void { 38 | this.centerX = this.width as f32 / 2.0; 39 | this.centerY = this.height as f32 / 2.0; 40 | for(let i = 0; i < CUBE_LENGTH; i++) { 41 | this.prevProj2dPoints[i] = [0, 0]; 42 | } 43 | } 44 | 45 | tick(): void { 46 | const angle: f32 = this.angle; 47 | 48 | const cos: f32 = Mathf.cos(angle); 49 | const sin: f32 = Mathf.sin(angle); 50 | 51 | const rotX: f32[][] = [ 52 | [ 1, 0, 0], 53 | [ 0, cos, -sin], 54 | [ 0, sin, cos] 55 | ]; 56 | const rotY: f32[][] = [ 57 | [ cos, 0, -sin], 58 | [ 0, 1, 0], 59 | [ sin, 0, cos] 60 | ]; 61 | const rotZ: f32[][] = [ 62 | [ cos, -sin, 0], 63 | [ sin, cos, 0], 64 | [ 0, 0, 1] 65 | ]; 66 | 67 | let proj2dPoints: u32[][] = []; 68 | let rot2d: f32[]; 69 | for(let i = 0; i < CUBE_LENGTH; i++) { 70 | rot2d = matrixMultiple(rotY, CUBE_POINTS[i]); 71 | rot2d = matrixMultiple(rotX, rot2d); 72 | rot2d = matrixMultiple(rotZ, rot2d); 73 | let z: f32 = 1 / (DISTANCE - rot2d[2]); 74 | const proj2d: f32[] = matrixMultiple( 75 | [ 76 | [z, 0, 0], 77 | [0, z, 0] 78 | ], 79 | rot2d 80 | ); 81 | const x = ((proj2d[0] * SCALE) + this.centerX) as u32; 82 | const y = ((proj2d[1] * SCALE) + this.centerY) as u32; 83 | proj2dPoints[i] = [x, y]; 84 | } 85 | 86 | // Draw 87 | // c3dev.fill_rect(0, 0, this.width, this.height, c3dev.COLOR.BLACK); 88 | 89 | c3dev.start_write(); 90 | // clear prev lines 91 | for(let i = 0; i < CUBE_LENGTH / 2; i++) { 92 | this.connect(i, (i + 1) % 4, this.prevProj2dPoints, c3dev.COLOR.BLACK); 93 | this.connect(i + 4, (i + 1) % 4 + 4, this.prevProj2dPoints, c3dev.COLOR.BLACK); 94 | this.connect(i, i + 4, this.prevProj2dPoints, c3dev.COLOR.BLACK); 95 | } 96 | // draw lines 97 | for(let i = 0; i < CUBE_LENGTH / 2; i++) { 98 | this.connect(i, (i + 1) % 4, proj2dPoints, c3dev.COLOR.GREEN); 99 | this.connect(i + 4, (i + 1) % 4 + 4, proj2dPoints, c3dev.COLOR.GREEN); 100 | this.connect(i, i + 4, proj2dPoints, c3dev.COLOR.GREEN); 101 | } 102 | // draw points and save prev 103 | for(let i = 0; i < CUBE_LENGTH; i++) { 104 | const x = proj2dPoints[i][0]; 105 | const y = proj2dPoints[i][1]; 106 | c3dev.draw_pixel(x, y, c3dev.COLOR.RED); 107 | this.prevProj2dPoints[i] = [x, y]; 108 | } 109 | c3dev.end_write(); 110 | 111 | this.angle += 0.04; 112 | } 113 | 114 | connect(i: u32, j: u32, k: u32[][], color: c3dev.COLOR): void { 115 | const a = k[i]; 116 | const b = k[j]; 117 | c3dev.draw_line(a[0], a[1], b[0], b[1], color); 118 | } 119 | } 120 | 121 | export function init(width: u32, height: u32): void { 122 | imu = new Imu(width, height); 123 | } 124 | 125 | export function tick(): void { 126 | if(imu != null) { 127 | imu!.tick(); 128 | } 129 | } 130 | 131 | function matrixMultiple(a: f32[][], b: f32[]): f32[] { 132 | let result: f32[] = []; 133 | 134 | for(let i = 0; i < a.length; i++) { 135 | let sum: f32 = 0; 136 | for(let j = 0; j < 3; j++) { 137 | sum += a[i][j] * b[j]; 138 | } 139 | result[i] = sum; 140 | } 141 | 142 | return result; 143 | } 144 | -------------------------------------------------------------------------------- /wasm/imu6886/web/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Canvas settings 3 | */ 4 | const CANVAS_WIDTH = 160; 5 | const CANVAS_HEIGHT = 128; 6 | const CANVAS_FONT_SIZE = 14; 7 | 8 | /** 9 | * Canvas 10 | * @type {HTMLCanvasElement} 11 | */ 12 | let canvas; 13 | 14 | /** 15 | * CanvasContext 16 | * @type {CanvasRenderingContext2D} 17 | */ 18 | let canvasContext; 19 | 20 | /** 21 | * WebAssembly Exports 22 | * @type {WebAssembly.Instance.exports} 23 | */ 24 | let wasmExports; 25 | 26 | /** 27 | * Setting Canvas 28 | */ 29 | (function() { 30 | canvas = document.getElementById('screen'); 31 | canvas.setAttribute('width', CANVAS_WIDTH * 2); 32 | canvas.setAttribute('height', CANVAS_HEIGHT * 2); 33 | canvas.style.width = CANVAS_WIDTH * 2 + "px"; 34 | canvas.style.heigth = CANVAS_HEIGHT * 2 + "px"; 35 | canvasContext = canvas.getContext('2d'); 36 | canvasContext.scale(2, 2); 37 | canvasContext.font = `${CANVAS_FONT_SIZE}px sans-serif`; 38 | canvasContext.lineWidth = 1; 39 | canvasContext.imageSmoothingEnabled = true; 40 | })(); 41 | 42 | /** 43 | * Load WebAssembly 44 | */ 45 | async function loadWasm() { 46 | const response = await fetch(new URL('../dist/imu6886.wasm', import.meta.url)); 47 | const responseArrayBuffer = new Uint8Array(await response.arrayBuffer()); 48 | const wasm_bytes = new Uint8Array(responseArrayBuffer).buffer; 49 | let module = await WebAssembly.compile(wasm_bytes); 50 | const instance = await WebAssembly.instantiate(module, { 51 | ...createImports() 52 | }); 53 | wasmExports = instance.exports; 54 | }; 55 | 56 | /** 57 | * Create Imports C3DEV interface 58 | * @returns imports 59 | */ 60 | function createImports() { 61 | let imports = []; 62 | imports['env'] = { 63 | 'abort': (i0, i1, i2, i3) => { 64 | console.log(`env.abort: ${i0}, ${i1}, ${i2}, ${i3}`); 65 | }, 66 | 'seed': () => { 67 | return Math.random(); 68 | } 69 | }; 70 | imports['c3dev'] = { 71 | 'start_write': () => { 72 | // nothing to do 73 | }, 74 | 'draw_pixel': (x, y, color) => { 75 | canvasContext.fillStyle = convertRGB565toStyle(color); 76 | canvasContext.fillRect(x, y, 1, 1); 77 | }, 78 | 'draw_line': (x0, y0, x1, y1, color) => { 79 | canvasContext.strokeStyle = convertRGB565toStyle(color); 80 | canvasContext.lineWidth = 1; 81 | canvasContext.beginPath(); 82 | canvasContext.moveTo(x0, y0); 83 | canvasContext.lineTo(x1 + 1, y1 + 1); 84 | canvasContext.stroke(); 85 | }, 86 | 'fill_rect': (x0, y0, x1, y1, color) => { 87 | canvasContext.fillStyle = convertRGB565toStyle(color); 88 | canvasContext.fillRect(x0, y0, x1, y1); 89 | }, 90 | 'end_write': () => { 91 | // nothing to do 92 | }, 93 | 'draw_string': (x, y, color, string) => { 94 | canvasContext.fillStyle = convertRGB565toStyle(color); 95 | canvasContext.fillText(decodeUTF8(string), x, y + CANVAS_FONT_SIZE); 96 | }, 97 | 'log': (string) => { 98 | console.log(decodeUTF8(string)); 99 | } 100 | }; 101 | 102 | return imports; 103 | } 104 | 105 | /** 106 | * Convert RGB565 to Canvas style 107 | * @param {string} rgb565 108 | */ 109 | function convertRGB565toStyle(rgb565) { 110 | const r8 = (rgb565 & 0xF800) >> 8; 111 | const g8 = (rgb565 & 0x07E0) >> 3; 112 | const b8 = (rgb565 & 0x001F) << 3; 113 | 114 | return `#` + 115 | `${(Number(r8).toString(16)).padStart(2, '0')}` + 116 | `${(Number(g8).toString(16)).padStart(2, '0')}` + 117 | `${(Number(b8).toString(16)).padStart(2, '0')}`; 118 | } 119 | 120 | function decodeUTF8(wasmPtr) { 121 | const memory = wasmExports.memory.buffer; 122 | // https://www.assemblyscript.org/memory.html#internals 123 | // TODO: internal: #rtSize 124 | const rtSize = new Uint32Array(memory, wasmPtr - 4, 1) - /* null terminated */ 1; 125 | // ArrayBuffer 126 | const utf8 = new Uint8Array(memory, wasmPtr, rtSize); 127 | var decoder = new TextDecoder('utf-8'); 128 | 129 | return decoder.decode(utf8); 130 | } 131 | 132 | /** 133 | * Main 134 | */ 135 | (async function() { 136 | await loadWasm(); 137 | wasmExports.init(CANVAS_WIDTH, CANVAS_HEIGHT); 138 | setInterval(() => { 139 | wasmExports.tick(); 140 | wasmExports.__collect() // clean up all garbage 141 | }, 16); 142 | })(); 143 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg-series.pretty/AJ-1780.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "AJ-1780" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 61BDDE7A) 4 | (descr "https://www.reichelt.de/index.html?ACTION=7&LA=3&OPEN=0&INDEX=0&FILENAME=C160%252FKB3SPRS.pdf") 5 | (tags "jack stereo TRS") 6 | (attr through_hole) 7 | (fp_text reference "AJ-1780" (at 0 -7.62) (layer "F.SilkS") 8 | (effects (font (size 1 1) (thickness 0.15))) 9 | (tstamp 0dcdf1b8-13c6-48b4-bd94-5d26038ff231) 10 | ) 11 | (fp_text value "AJ-1780" (at 0 7.62) (layer "F.Fab") 12 | (effects (font (size 1 1) (thickness 0.15))) 13 | (tstamp dde3dba8-1b81-466c-93a3-c284ff4da1ef) 14 | ) 15 | (fp_line (start -5.28 5.61) (end -5.28 -6.19) (layer "F.SilkS") (width 0.15) (tstamp 120a7b0f-ddfd-4447-85c1-35665465acdb)) 16 | (fp_line (start -8.88 3.11) (end -5.28 3.11) (layer "F.SilkS") (width 0.15) (tstamp 13475e15-f37c-4de8-857e-1722b0c39513)) 17 | (fp_line (start 0.6 6.65) (end 0.1 6.1) (layer "F.SilkS") (width 0.12) (tstamp 15875808-74d5-4210-b8ca-aa8fbc04ae21)) 18 | (fp_line (start -8.88 -3.09) (end -8.88 3.11) (layer "F.SilkS") (width 0.15) (tstamp 2732632c-4768-42b6-bf7f-14643424019e)) 19 | (fp_line (start 6.52 5.61) (end 2.39 5.63) (layer "F.SilkS") (width 0.15) (tstamp 48f827a8-6e22-4a2e-abdc-c2a03098d883)) 20 | (fp_line (start -0.4 6.65) (end 0.6 6.65) (layer "F.SilkS") (width 0.12) (tstamp 81bbc3ff-3938-49ac-8297-ce2bcc9a42bd)) 21 | (fp_line (start -5.28 -3.09) (end -8.88 -3.09) (layer "F.SilkS") (width 0.15) (tstamp 854dd5d4-5fd2-4730-bd49-a9cd8299a065)) 22 | (fp_line (start -1.99 5.58) (end -5.28 5.61) (layer "F.SilkS") (width 0.15) (tstamp 8d55e186-3e11-40e8-a65e-b36a8a00069e)) 23 | (fp_line (start 7.37 -6.19) (end 9.22 -6.19) (layer "F.SilkS") (width 0.15) (tstamp 9c8ccb2a-b1e9-4f2c-94fe-301b5975277e)) 24 | (fp_line (start -5.28 -6.19) (end 3 -6.19) (layer "F.SilkS") (width 0.15) (tstamp a03e565f-d8cd-4032-aae3-b7327d4143dd)) 25 | (fp_line (start 0.1 6.1) (end -0.4 6.65) (layer "F.SilkS") (width 0.12) (tstamp b1169a2d-8998-4b50-a48d-c520bcc1b8e1)) 26 | (fp_line (start 9.22 -6.19) (end 9.22 5.61) (layer "F.SilkS") (width 0.15) (tstamp cef6f603-8a0b-4dd0-af99-ebfbef7d1b4b)) 27 | (fp_line (start 9.22 5.61) (end 9.12 5.61) (layer "F.SilkS") (width 0.15) (tstamp e877bf4a-4210-4bd3-b7b0-806eb4affc5b)) 28 | (fp_line (start 9.62 -6.79) (end -9.28 -6.79) (layer "F.CrtYd") (width 0.05) (tstamp 5b2b5c7d-f943-4634-9f0a-e9561705c49d)) 29 | (fp_line (start -9.28 -6.79) (end -9.28 6.61) (layer "F.CrtYd") (width 0.05) (tstamp b635b16e-60bb-4b3e-9fc3-47d34eef8381)) 30 | (fp_line (start -9.28 6.61) (end 9.62 6.61) (layer "F.CrtYd") (width 0.05) (tstamp c70d9ef3-bfeb-47e0-a1e1-9aeba3da7864)) 31 | (fp_line (start 9.62 6.61) (end 9.62 -6.79) (layer "F.CrtYd") (width 0.05) (tstamp f976e2cc-36f9-4479-a816-2c74d1d5da6f)) 32 | (fp_line (start -5.18 -6.09) (end -5.18 5.51) (layer "F.Fab") (width 0.1) (tstamp 0147f16a-c952-4891-8f53-a9fb8cddeb8d)) 33 | (fp_line (start -8.78 -2.99) (end -8.78 3.01) (layer "F.Fab") (width 0.1) (tstamp 0d0bb7b2-a6e5-46d2-9492-a1aa6e5a7b2f)) 34 | (fp_line (start 9.12 -6.09) (end -5.18 -6.09) (layer "F.Fab") (width 0.1) (tstamp 4e3d7c0d-12e3-42f2-b944-e4bcdbbcac2a)) 35 | (fp_line (start -5.18 5.51) (end 9.12 5.51) (layer "F.Fab") (width 0.1) (tstamp 6a44418c-7bb4-4e99-8836-57f153c19721)) 36 | (fp_line (start 9.12 5.51) (end 9.12 -6.09) (layer "F.Fab") (width 0.1) (tstamp aa02e544-13f5-4cf8-a5f4-3e6cda006090)) 37 | (fp_line (start -8.78 -2.99) (end -5.18 -2.99) (layer "F.Fab") (width 0.1) (tstamp d1262c4d-2245-4c4f-8f35-7bb32cd9e21e)) 38 | (fp_line (start -8.78 3.01) (end -5.18 3.01) (layer "F.Fab") (width 0.1) (tstamp d22e95aa-f3db-4fbc-a331-048a2523233e)) 39 | (fp_circle (center 0.62 2.86) (end 0.92 3.06) (layer "F.Fab") (width 0.12) (fill none) (tstamp 58dc14f9-c158-4824-a84e-24a6a482a7a4)) 40 | (pad "1" thru_hole rect (at 0.12 4.6) (size 3.5 2) (drill oval 1.8 1) (layers *.Cu *.Mask) (tstamp dd00c2e1-6027-4717-b312-4fab3ee52002)) 41 | (pad "2" thru_hole oval (at 5.12 -5.4) (size 3.5 2) (drill oval 1.8 1) (layers *.Cu *.Mask) (tstamp b6270a28-e0d9-4655-a18a-03dbf007b940)) 42 | (pad "3" thru_hole oval (at -3.38 0) (size 2 3.5) (drill oval 1 1.8) (layers *.Cu *.Mask) (tstamp f3490fa5-5a27-423b-af60-53609669542c)) 43 | (pad "4" thru_hole oval (at 7.92 4.6 90) (size 3.5 2) (drill oval 1.8 1) (layers *.Cu *.Mask) (tstamp 0a3cc030-c9dd-4d74-9d50-715ed2b361a2)) 44 | (pad "5" thru_hole oval (at 3.42 -2.9) (size 3.5 2) (drill oval 1.8 1) (layers *.Cu *.Mask) (tstamp 8322f275-268c-4e87-a69f-4cfbf05e747f)) 45 | (model "./vrml2/AJ-1780.x3d" 46 | (offset (xyz -0.2 0.2 0)) 47 | (scale (xyz 4 4 4)) 48 | (rotate (xyz 90 180 90)) 49 | ) 50 | ) 51 | -------------------------------------------------------------------------------- /main/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "esp_log.h" 3 | #include "SPI.h" 4 | #include "Adafruit_GFX.h" 5 | #include "Adafruit_ST7735.h" 6 | 7 | #include "c3dev_board.h" 8 | #include "test_freetype.h" 9 | #include "test_tinypng.h" 10 | #include "test_nvs_wifi.h" 11 | 12 | #ifdef CONFIG_GPIO1819_NONE 13 | #include "test_wasm3_clockenv.h" 14 | #endif 15 | #ifdef CONFIG_GPIO1819_I2C 16 | #include "test_i2c_gpio1819.h" 17 | #include "test_wasm3_clockenv.h" 18 | #endif 19 | #ifdef CONFIG_GPIO1819_DIGIT_UNITIR 20 | #include "test_digit_gpio1819.h" 21 | #include "test_wasm3_clockenv.h" 22 | #endif 23 | #ifdef CONFIG_GPIO1819_UART_UNITGPS 24 | #include "test_uart_gpio1819.h" 25 | #include "test_wasm3_gpsgsv.h" 26 | #endif 27 | #ifdef CONFIG_GPIO1819_IMU6886 28 | #include "test_wasm3_imu6886.h" 29 | #endif 30 | 31 | static const char *TAG = "main.cpp"; 32 | 33 | /** 34 | * SPI member 35 | */ 36 | SPIClass *spi = &SPI; 37 | 38 | /** 39 | * LCD member 40 | */ 41 | Adafruit_ST7735 tft = Adafruit_ST7735(spi, C3DEV_LCD_CS, C3DEV_LCD_DC, C3DEV_LCD_RST); 42 | 43 | /** 44 | * FreeType member 45 | */ 46 | font_render_t font_render; 47 | 48 | /** 49 | * Wasm3 member 50 | */ 51 | boolean enable_wasm = false; 52 | 53 | void setup(void) 54 | { 55 | // SW initialize 56 | pinMode(C3DEV_SW1, INPUT); // external pull up 57 | pinMode(M5STAMP_C3_SW, INPUT_PULLUP); 58 | 59 | // SPI initialize 60 | SPI.begin(C3DEV_SPI_SCLK, C3DEV_SPI_MISO, C3DEV_SPI_MOSI, C3DEV_SD_CS); 61 | SPI.setFrequency(C3DEV_SPI_CLOCK); 62 | 63 | // LCD initialize 64 | tft.initR(INITR_BLACKTAB); 65 | tft.setSPISpeed(C3DEV_SPI_CLOCK); 66 | tft.setRotation(1); 67 | tft.fillScreen(ST77XX_BLACK); 68 | // If the color is inverted, set to 1. 69 | tft.invertDisplay(0); 70 | // tft.invertDisplay(1); 71 | 72 | // Test FreeType 73 | init_freetype(); 74 | font_render = create_freetype_render(/* font size */ 20, /* font cache */ 64); 75 | draw_freetype_string("M5Stamp C3", 10, 28, ST77XX_RED, &font_render); 76 | draw_freetype_string("Development", 10, 28 * 2, ST77XX_WHITE, &font_render); 77 | draw_freetype_string("Board", 10, 28 * 3, ST77XX_WHITE, &font_render); 78 | draw_freetype_string("RISC-V", 10, 28 * 4, ST77XX_BLUE, &font_render); 79 | delay(1000); 80 | 81 | // Test SD card and PNG 82 | // draw_sdcard_png("/M5STACK/TEST10-0.PNG", 0, 0); 83 | // draw_sdcard_png("/M5STACK/TEST10-1.PNG", 80, 0); 84 | // draw_sdcard_png("/M5STACK/TEST10-2.PNG", 0, 60); 85 | // draw_sdcard_png("/M5STACK/TEST10-3.PNG", 80, 60); 86 | 87 | // Test NVS and Wifi (Push SW1) 88 | if(digitalRead(C3DEV_SW1) == 0) { 89 | sync_wifi_ntp(); 90 | // not enough memory.. 91 | ESP_LOGI(TAG, "Restart ESP32C3"); 92 | esp_restart(); 93 | } 94 | 95 | #ifdef CONFIG_GPIO1819_I2C 96 | init_i2c_gpio1819(); 97 | #endif 98 | #ifdef CONFIG_GPIO1819_UART_UNITGPS 99 | init_uart_gpio1819(); 100 | #endif 101 | #ifdef CONFIG_GPIO1819_DIGIT_UNITIR 102 | init_digit_gpio1819(); 103 | #endif 104 | 105 | // Test WebAssembly 106 | #ifdef CONFIG_GPIO1819_UART_UNITGPS 107 | if(gpsgsv_init_wasm() == ESP_OK) enable_wasm = true; 108 | #elif CONFIG_GPIO1819_IMU6886 109 | if(imu6886_init_wasm() == ESP_OK) enable_wasm = true; 110 | #else 111 | if(clockenv_init_wasm() == ESP_OK) enable_wasm = true; 112 | #endif 113 | } 114 | 115 | void loop(void) 116 | { 117 | // Test Switch 118 | #ifndef CONFIG_GPIO1819_IMU6886 119 | ESP_LOGI(TAG, "SW: %d, SW1: %d", digitalRead(M5STAMP_C3_SW), digitalRead(C3DEV_SW1)); 120 | #endif 121 | 122 | // Test GPIO0 ADC (UNIT Light) 123 | #ifndef CONFIG_GPIO1819_IMU6886 124 | float_t an = (float_t)analogRead(C3DEV_GPIO_0) / (float_t)4096; 125 | if(an > 1) an = 1; 126 | ESP_LOGI(TAG, "GPIO0 analog: %f", an); 127 | #endif 128 | 129 | // Test UNIT IR 130 | #ifdef CONFIG_GPIO1819_DIGIT_UNITIR 131 | get_digit_unitir_data(); 132 | #endif 133 | 134 | // Test WebAssembly 135 | if(enable_wasm) { 136 | #ifdef CONFIG_GPIO1819_UART_UNITGPS 137 | // GPS GSV View 138 | gpsgsv_tick_wasm(digitalRead(C3DEV_SW1) == 0 ? true: false); 139 | #elif CONFIG_GPIO1819_IMU6886 140 | // 3D Cube 141 | // uint32_t time = millis(); 142 | imu6886_tick_wasm(); 143 | // ESP_LOGI(TAG, "time: %d", (uint32_t)(millis() - time)); 144 | // When draw to LCD is suppressed. (calculations only) 145 | // I (4057) main.cpp: time: 16 146 | #else 147 | // Clock Env 148 | clockenv_tick_wasm(); 149 | #endif 150 | } 151 | 152 | #ifdef CONFIG_GPIO1819_IMU6886 153 | delay(1); 154 | #else 155 | delay(500); 156 | #endif 157 | } 158 | -------------------------------------------------------------------------------- /wasm/clockenv/web/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Canvas settings 3 | */ 4 | const CANVAS_WIDTH = 160; 5 | const CANVAS_HEIGHT = 128; 6 | const CANVAS_FONT_SIZE = 8; 7 | 8 | /** 9 | * Canvas 10 | * @type {HTMLCanvasElement} 11 | */ 12 | let canvas; 13 | 14 | /** 15 | * CanvasContext 16 | * @type {CanvasRenderingContext2D} 17 | */ 18 | let canvasContext; 19 | 20 | /** 21 | * WebAssembly Exports 22 | * @type {WebAssembly.Instance.exports} 23 | */ 24 | let wasmExports; 25 | 26 | /** 27 | * Setting Canvas 28 | */ 29 | (function() { 30 | canvas = document.getElementById('screen'); 31 | canvas.setAttribute('width', CANVAS_WIDTH * 2); 32 | canvas.setAttribute('height', CANVAS_HEIGHT * 2); 33 | canvas.style.width = CANVAS_WIDTH * 2 + "px"; 34 | canvas.style.heigth = CANVAS_HEIGHT * 2 + "px"; 35 | canvasContext = canvas.getContext('2d'); 36 | canvasContext.scale(2, 2); 37 | canvasContext.font = `${CANVAS_FONT_SIZE}px sans-serif`; 38 | canvasContext.lineWidth = 1; 39 | canvasContext.imageSmoothingEnabled = true; 40 | })(); 41 | 42 | /** 43 | * Load WebAssembly 44 | */ 45 | async function loadWasm() { 46 | const response = await fetch(new URL('../dist/clockenv.wasm', import.meta.url)); 47 | const responseArrayBuffer = new Uint8Array(await response.arrayBuffer()); 48 | const wasm_bytes = new Uint8Array(responseArrayBuffer).buffer; 49 | let module = await WebAssembly.compile(wasm_bytes); 50 | const instance = await WebAssembly.instantiate(module, { 51 | ...createImports() 52 | }); 53 | wasmExports = instance.exports; 54 | }; 55 | 56 | /** 57 | * Create Imports C3DEV interface 58 | * @returns imports 59 | */ 60 | function createImports() { 61 | let imports = []; 62 | imports['env'] = { 63 | 'abort': (i0, i1, i2, i3) => { 64 | console.log(`env.abort: ${i0}, ${i1}, ${i2}, ${i3}`); 65 | }, 66 | 'seed': () => { 67 | return Math.random(); 68 | } 69 | }; 70 | imports['c3dev'] = { 71 | 'start_write': () => { 72 | // nothing to do 73 | }, 74 | 'draw_pixel': (x, y, color) => { 75 | // c3dev SPI non transactional 76 | canvasContext.fillStyle = convertRGB565toStyle(color); 77 | canvasContext.fillRect(x, y, 1, 1); 78 | }, 79 | 'write_pixel': (x, y, color) => { 80 | // c3dev SPI transactional 81 | canvasContext.fillStyle = convertRGB565toStyle(color); 82 | canvasContext.fillRect(x, y, 1, 1); 83 | }, 84 | 'end_write': () => { 85 | // nothing to do 86 | }, 87 | 'draw_string': (x, y, color, string) => { 88 | canvasContext.fillStyle = convertRGB565toStyle(color); 89 | canvasContext.fillText(decodeUTF8(string), x, y + CANVAS_FONT_SIZE); 90 | }, 91 | 'draw_line': (x0, y0, x1, y1, color) => { 92 | canvasContext.strokeStyle = convertRGB565toStyle(color); 93 | canvasContext.beginPath(); 94 | canvasContext.moveTo(x0, y0); 95 | canvasContext.lineTo(x1, y1); 96 | canvasContext.stroke(); 97 | }, 98 | 'get_env_tmp': () => { 99 | return 19.771495819091798; 100 | }, 101 | 'get_env_hum': () => { 102 | return 45.947967529296878; 103 | }, 104 | 'get_env_pressure': () => { 105 | return 996.9368896484375; 106 | }, 107 | 'get_ultrasonic_distance': () => { 108 | return 4000.10; 109 | }, 110 | 'log': (string) => { 111 | console.log(decodeUTF8(string)); 112 | }, 113 | 'now': () => { 114 | let offset = new Date().getTimezoneOffset(); 115 | return BigInt(Date.now() - /* TODO: */ offset * 60 * 1000); 116 | } 117 | }; 118 | 119 | return imports; 120 | } 121 | 122 | /** 123 | * Convert RGB565 to Canvas style 124 | * @param {string} rgb565 125 | */ 126 | function convertRGB565toStyle(rgb565) { 127 | const r8 = (rgb565 & 0xF800) >> 8; 128 | const g8 = (rgb565 & 0x07E0) >> 3; 129 | const b8 = (rgb565 & 0x001F) << 3; 130 | 131 | return `#` + 132 | `${(Number(r8).toString(16)).padStart(2, '0')}` + 133 | `${(Number(g8).toString(16)).padStart(2, '0')}` + 134 | `${(Number(b8).toString(16)).padStart(2, '0')}`; 135 | } 136 | 137 | function decodeUTF8(wasmPtr) { 138 | const memory = wasmExports.memory.buffer; 139 | // https://www.assemblyscript.org/memory.html#internals 140 | // TODO: internal: #rtSize 141 | const rtSize = new Uint32Array(memory, wasmPtr - 4, 1) - /* null terminated */ 1; 142 | // ArrayBuffer 143 | const utf8 = new Uint8Array(memory, wasmPtr, rtSize); 144 | var decoder = new TextDecoder('utf-8'); 145 | 146 | return decoder.decode(utf8); 147 | } 148 | 149 | /** 150 | * Main 151 | */ 152 | (async function() { 153 | await loadWasm(); 154 | wasmExports.clock(80, 64, 63); 155 | setInterval(() => { 156 | wasmExports.tick(); 157 | wasmExports.__collect() // clean up all garbage 158 | }, 500); 159 | })(); 160 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg-series.pretty/M5STAMP-C3.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "M5STAMP-C3" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 61E2447D) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 -17.78) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp b12e5309-5d01-40ef-a9c3-8453e00a555e) 8 | ) 9 | (fp_text value "M5STAMP-C3" (at 0 17.78) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp be6b17f9-34f5-44e9-a4c7-725d2e274a9d) 12 | ) 13 | (fp_text user "NC" (at 11.43 -13.97) (layer "F.SilkS") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 5f6afe3e-3cb2-473a-819c-dc94ae52a6be) 16 | ) 17 | (fp_text user "NC" (at 11.43 -11.43) (layer "F.SilkS") 18 | (effects (font (size 1 1) (thickness 0.15))) 19 | (tstamp 98970bf0-1168-4b4e-a1c9-3b0c8d7eaacf) 20 | ) 21 | (fp_line (start 8.89 -16.51) (end 10.16 -15.24) (layer "F.SilkS") (width 0.12) (tstamp 02538207-54a8-4266-8d51-23871852b2ff)) 22 | (fp_line (start 10.16 15.24) (end 8.89 16.51) (layer "F.SilkS") (width 0.12) (tstamp 0f560957-a8c5-442f-b20c-c2d88613742c)) 23 | (fp_line (start -10.16 15.24) (end -8.89 16.51) (layer "F.SilkS") (width 0.12) (tstamp 17ed3508-fa2e-4593-a799-bfd39a6cc14d)) 24 | (fp_line (start 10.16 -15.24) (end 10.16 15.24) (layer "F.SilkS") (width 0.12) (tstamp 1c9f6fea-1796-4a2d-80b3-ae22ce51c8f5)) 25 | (fp_line (start 5.08 10.16) (end 5.08 16.51) (layer "F.SilkS") (width 0.12) (tstamp 2aabebab-10c6-4637-946b-cda31980f550)) 26 | (fp_line (start -10.16 15.24) (end -10.16 -15.24) (layer "F.SilkS") (width 0.12) (tstamp 73fbe87f-3928-49c2-bf87-839d907c6aef)) 27 | (fp_line (start 8.89 16.51) (end -8.89 16.51) (layer "F.SilkS") (width 0.12) (tstamp 86ad0555-08b3-4dde-9a3e-c1e5e29b6615)) 28 | (fp_line (start -5.08 16.51) (end -5.08 10.16) (layer "F.SilkS") (width 0.12) (tstamp b830f01d-0d9c-451a-9ac4-3e5744deb516)) 29 | (fp_line (start -10.16 -15.24) (end -8.89 -16.51) (layer "F.SilkS") (width 0.12) (tstamp dd334895-c8ff-4719-bac4-c0b289bb5899)) 30 | (fp_line (start -5.08 10.16) (end 5.08 10.16) (layer "F.SilkS") (width 0.12) (tstamp ec1c193f-86ec-48fc-a26b-de8201d681ac)) 31 | (fp_line (start -8.89 -16.51) (end 8.89 -16.51) (layer "F.SilkS") (width 0.12) (tstamp f56d244f-1fa4-4475-ac1d-f41eed31a48b)) 32 | (pad "1" thru_hole circle (at -8.89 -13.97) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp c67ad10d-2f75-4ec6-a139-47058f7f06b2)) 33 | (pad "2" thru_hole circle (at -8.89 -11.43) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 2a6075ae-c7fa-41db-86b8-3f996740bdc2)) 34 | (pad "3" thru_hole circle (at -8.89 -8.89) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 8f12311d-6f4c-4d28-a5bc-d6cb462bade7)) 35 | (pad "4" thru_hole circle (at -8.89 -6.35) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp db742b9e-1fed-4e0c-b783-f911ab5116aa)) 36 | (pad "5" thru_hole circle (at -8.89 -3.81) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 4344bc11-e822-474b-8d61-d12211e719b1)) 37 | (pad "6" thru_hole circle (at -8.89 -1.27) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 12c8f4c9-cb79-4390-b96c-a717c693de17)) 38 | (pad "7" thru_hole circle (at -8.89 1.27) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 12f8e43c-8f83-48d3-a9b5-5f3ebc0b6c43)) 39 | (pad "8" thru_hole circle (at -8.89 3.81) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp eaa0d51a-ee4e-4d3a-a801-bddb7027e94c)) 40 | (pad "9" thru_hole circle (at -8.89 6.35) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 5f38bdb2-3657-474e-8e86-d6bb0b298110)) 41 | (pad "10" thru_hole circle (at -8.89 8.89) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp d72c89a6-7578-4468-964e-2a845431195f)) 42 | (pad "11" thru_hole circle (at -8.89 11.43) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 282c8e53-3acc-42f0-a92a-6aa976b97a93)) 43 | (pad "12" thru_hole circle (at -8.89 13.97) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 83c5181e-f5ee-453c-ae5c-d7256ba8837d)) 44 | (pad "13" thru_hole circle (at 8.89 13.97) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 0b4c0f05-c855-4742-bad2-dbf645d5842b)) 45 | (pad "14" thru_hole circle (at 8.89 11.43) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp ca5b6af8-ca05-4338-b852-b51f2b49b1db)) 46 | (pad "15" thru_hole circle (at 8.89 8.89) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp ea2ea877-1ce1-4cd6-ad19-1da87f51601d)) 47 | (pad "16" thru_hole circle (at 8.89 6.35) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp f699494a-77d6-4c73-bd50-29c1c1c5b879)) 48 | (pad "17" thru_hole circle (at 8.89 3.81) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 05d3e08e-e1f9-46cf-93d0-836d1306d03a)) 49 | (pad "18" thru_hole circle (at 8.89 1.27) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 6bd46644-7209-4d4d-acd8-f4c0d045bc61)) 50 | (pad "19" thru_hole circle (at 8.89 -1.27) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp befdfbe5-f3e5-423b-a34e-7bba3f218536)) 51 | (pad "20" thru_hole circle (at 8.89 -3.81) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 1c052668-6749-425a-9a77-35f046c8aa39)) 52 | (pad "21" thru_hole circle (at 8.89 -6.35) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 9db16341-dac0-4aab-9c62-7d88c111c1ce)) 53 | (pad "22" thru_hole circle (at 8.89 -8.89) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp b7d06af4-a5b1-447f-9b1a-8b44eb1cc204)) 54 | (pad "23" thru_hole circle (at 8.89 -11.43) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp ab8b0540-9c9f-4195-88f5-7bed0b0a8ed6)) 55 | (pad "24" thru_hole circle (at 8.89 -13.97) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp e79c8e11-ed47-4701-ae80-a54cdb6682a5)) 56 | ) 57 | -------------------------------------------------------------------------------- /wasm/gpsgsv/web/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Canvas settings 3 | */ 4 | const CANVAS_WIDTH = 160; 5 | const CANVAS_HEIGHT = 128; 6 | const CANVAS_FONT_SIZE = 8; 7 | 8 | /** 9 | * Canvas 10 | * @type {HTMLCanvasElement} 11 | */ 12 | let canvas; 13 | 14 | /** 15 | * CanvasContext 16 | * @type {CanvasRenderingContext2D} 17 | */ 18 | let canvasContext; 19 | 20 | /** 21 | * WebAssembly Exports 22 | * @type {WebAssembly.Instance.exports} 23 | */ 24 | let wasmExports; 25 | 26 | /** 27 | * Setting Canvas 28 | */ 29 | (function() { 30 | canvas = document.getElementById('screen'); 31 | canvas.setAttribute('width', CANVAS_WIDTH * 2); 32 | canvas.setAttribute('height', CANVAS_HEIGHT * 2); 33 | canvas.style.width = CANVAS_WIDTH * 2 + "px"; 34 | canvas.style.heigth = CANVAS_HEIGHT * 2 + "px"; 35 | canvasContext = canvas.getContext('2d'); 36 | canvasContext.scale(2, 2); 37 | canvasContext.font = `${CANVAS_FONT_SIZE}px sans-serif`; 38 | canvasContext.lineWidth = 1; 39 | canvasContext.imageSmoothingEnabled = true; 40 | })(); 41 | 42 | /** 43 | * Load WebAssembly 44 | */ 45 | async function loadWasm() { 46 | const response = await fetch(new URL('../dist/gpsgsv.wasm', import.meta.url)); 47 | const responseArrayBuffer = new Uint8Array(await response.arrayBuffer()); 48 | const wasm_bytes = new Uint8Array(responseArrayBuffer).buffer; 49 | let module = await WebAssembly.compile(wasm_bytes); 50 | const instance = await WebAssembly.instantiate(module, { 51 | ...createImports() 52 | }); 53 | wasmExports = instance.exports; 54 | }; 55 | 56 | /** 57 | * Create Imports C3DEV interface 58 | * @returns imports 59 | */ 60 | function createImports() { 61 | let imports = []; 62 | imports['env'] = { 63 | 'abort': (i0, i1, i2, i3) => { 64 | console.log(`env.abort: ${i0}, ${i1}, ${i2}, ${i3}`); 65 | }, 66 | 'seed': () => { 67 | return Math.random(); 68 | } 69 | }; 70 | imports['c3dev'] = { 71 | 'draw_pixel': (x, y, color) => { 72 | canvasContext.fillStyle = convertRGB565toStyle(color); 73 | canvasContext.fillRect(x, y, 1, 1); 74 | }, 75 | 'draw_string': (x, y, color, string) => { 76 | canvasContext.fillStyle = convertRGB565toStyle(color); 77 | canvasContext.fillText(decodeUTF8(string), x, y + CANVAS_FONT_SIZE); 78 | }, 79 | 'draw_line': (x0, y0, x1, y1, color) => { 80 | canvasContext.strokeStyle = convertRGB565toStyle(color); 81 | canvasContext.beginPath(); 82 | canvasContext.moveTo(x0, y0); 83 | canvasContext.lineTo(x1, y1); 84 | canvasContext.stroke(); 85 | }, 86 | 'log': (string) => { 87 | console.log(decodeUTF8(string)); 88 | }, 89 | 'now': () => { 90 | let offset = new Date().getTimezoneOffset(); 91 | return BigInt(Date.now() - /* TODO: */ offset * 60 * 1000); 92 | } 93 | }; 94 | 95 | return imports; 96 | } 97 | 98 | /** 99 | * Convert RGB565 to Canvas style 100 | * @param {string} rgb565 101 | */ 102 | function convertRGB565toStyle(rgb565) { 103 | const r8 = (rgb565 & 0xF800) >> 8; 104 | const g8 = (rgb565 & 0x07E0) >> 3; 105 | const b8 = (rgb565 & 0x001F) << 3; 106 | 107 | return `#` + 108 | `${(Number(r8).toString(16)).padStart(2, '0')}` + 109 | `${(Number(g8).toString(16)).padStart(2, '0')}` + 110 | `${(Number(b8).toString(16)).padStart(2, '0')}`; 111 | } 112 | 113 | function decodeUTF8(wasmPtr) { 114 | const memory = wasmExports.memory.buffer; 115 | // https://www.assemblyscript.org/memory.html#internals 116 | // TODO: internal: #rtSize 117 | const rtSize = new Uint32Array(memory, wasmPtr - 4, 1) - /* null terminated */ 1; 118 | // ArrayBuffer 119 | const utf8 = new Uint8Array(memory, wasmPtr, rtSize); 120 | var decoder = new TextDecoder('utf-8'); 121 | 122 | return decoder.decode(utf8); 123 | } 124 | 125 | function getUint8Array(wasmPtr) { 126 | const memory = wasmExports.memory.buffer; 127 | const layout = new Uint32Array(memory, wasmPtr, 3); 128 | return new Uint8Array(memory, layout[1], layout[2]); 129 | } 130 | 131 | /** 132 | * Main 133 | */ 134 | (async function() { 135 | await loadWasm(); 136 | 137 | // import AssemblyScript functions 138 | const { __pin, __unpin, __collect} = wasmExports; 139 | 140 | // initialize application 141 | wasmExports.gpsgsv(80, 64, 63); 142 | 143 | // create temporary array for array interface 144 | let satellitesArrayPrt = __pin(wasmExports.createSatellitesArray()) 145 | let satellites = getUint8Array(satellitesArrayPrt); 146 | 147 | // set test data 148 | wasmExports.setGsv(2 , 63, 201, 0); 149 | wasmExports.setGsv(5 , 67, 319, 0); 150 | wasmExports.setGsv(6 , 11, 152, 16); 151 | wasmExports.setGsv(7 , 28, 53 , 32); 152 | wasmExports.setGsv(11, 44, 162, 26); 153 | wasmExports.setGsv(13, 62, 228, 0); 154 | wasmExports.setGsv(15, 27, 244, 0); 155 | wasmExports.setGsv(18, 11, 319, 0); 156 | wasmExports.setGsv(20, 68, 84 , 33); 157 | wasmExports.setGsv(29, 25, 278, 0); 158 | wasmExports.setGsv(30, 44, 88 , 30); 159 | satellites[0] = 6; 160 | satellites[1] = 7; 161 | satellites[2] = 11; 162 | satellites[3] = 20; 163 | satellites[4] = 30; 164 | wasmExports.setSatellites(satellitesArrayPrt); 165 | 166 | // free temporary array 167 | __unpin(satellitesArrayPrt); 168 | 169 | // loop 170 | wasmExports.tick(true); 171 | setInterval(() => { 172 | wasmExports.tick(false); 173 | __collect() // clean up all garbage 174 | }, 500); 175 | })(); 176 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg-series.pretty/MBUS.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "MBUS" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 604E0DD8) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0 -3.81) (layer "F.SilkS") 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 4d2fd49e-2cb2-44d4-8935-68488970d97b) 8 | ) 9 | (fp_text value "MBUS" (at 0 6.604) (layer "F.Fab") 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 22c28634-55a5-4f76-9217-6b70ddd108b8) 12 | ) 13 | (fp_text user "MBUS" (at 0 6.604) (layer "F.SilkS") 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp ea77ba09-319a-49bd-ad5b-49f4c76f232c) 16 | ) 17 | (fp_line (start -22.86 -2.54) (end -22.86 -1.27) (layer "F.SilkS") (width 0.12) (tstamp 0c544a8c-9f45-4205-9bca-1d91c95d58ef)) 18 | (fp_line (start 22.86 -1.27) (end 22.86 3.81) (layer "F.SilkS") (width 0.12) (tstamp 74012f9c-57f0-452a-9ea1-1e3437e264b8)) 19 | (fp_line (start 22.86 3.81) (end 22.86 5.08) (layer "F.SilkS") (width 0.12) (tstamp bb5d2eae-a96e-45dd-89aa-125fe22cc2fa)) 20 | (fp_line (start -22.86 5.08) (end -22.86 3.81) (layer "F.SilkS") (width 0.12) (tstamp c37d3f0c-41ec-4928-8869-febc821c6326)) 21 | (fp_line (start 22.86 -2.54) (end -22.86 -2.54) (layer "F.SilkS") (width 0.12) (tstamp cd50b8dc-829d-4a1d-8f2a-6471f378ba87)) 22 | (fp_line (start -22.86 -1.27) (end -22.86 3.81) (layer "F.SilkS") (width 0.12) (tstamp cfdef906-c924-4492-999d-4de066c0bce1)) 23 | (fp_line (start 22.86 -1.27) (end 22.86 -2.54) (layer "F.SilkS") (width 0.12) (tstamp d1441985-7b63-4bf8-a06d-c70da2e3b78b)) 24 | (fp_line (start 22.86 5.08) (end -22.86 5.08) (layer "F.SilkS") (width 0.12) (tstamp facb0614-068b-4c9c-a466-d374df96a94c)) 25 | (pad "1" thru_hole circle (at -17.78 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 0a1d0cbe-85ab-4f0f-b3b1-fcef21dfb600)) 26 | (pad "2" thru_hole circle (at -15.24 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 60d26b83-9c3a-4edb-93ef-ab3d9d05e8cb)) 27 | (pad "3" thru_hole circle (at -12.7 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp ae158d42-76cc-4911-a621-4cc28931c98b)) 28 | (pad "4" thru_hole circle (at -10.16 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 1cb64bfe-d819-47e3-be11-515b04f2c451)) 29 | (pad "5" thru_hole circle (at -7.62 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 9f4abbc0-6ac3-48f0-b823-2c1c19349540)) 30 | (pad "6" thru_hole circle (at -5.08 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp d5f4d798-57d3-493b-b57c-3b6e89508879)) 31 | (pad "7" thru_hole circle (at -2.54 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 0a5610bb-d01a-4417-8271-dc424dd2c838)) 32 | (pad "8" thru_hole circle (at 0 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp e4504518-96e7-4c9e-8457-7273f5a490f1)) 33 | (pad "9" thru_hole circle (at 2.54 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 42ecdba3-f348-4384-8d4b-cd21e56f3613)) 34 | (pad "10" thru_hole circle (at 5.08 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp a22bec73-a69c-4ab7-8d8d-f6a6b09f925f)) 35 | (pad "11" thru_hole circle (at 7.62 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp bd29b6d3-a58c-4b1f-9c20-de4efb708ab2)) 36 | (pad "12" thru_hole circle (at 10.16 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp b44c0167-50fe-4c67-94fb-5ce2e6f52544)) 37 | (pad "13" thru_hole circle (at 12.7 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp dd2d59b3-ddef-491f-bb57-eb3d3820bdeb)) 38 | (pad "14" thru_hole circle (at 15.24 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 765684c2-53b3-4ef7-bd1b-7a4a73d87b76)) 39 | (pad "15" thru_hole circle (at 17.78 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 5a390647-51ba-4684-b747-9001f749ff71)) 40 | (pad "16" thru_hole circle (at 17.78 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp c811ed5f-f509-4605-b7d3-da6f79935a1e)) 41 | (pad "17" thru_hole circle (at 15.24 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 2681e64d-bedc-4e1f-87d2-754aaa485bbd)) 42 | (pad "18" thru_hole circle (at 12.7 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 6b8c153e-62fe-42fb-aa7f-caef740ef6fd)) 43 | (pad "19" thru_hole circle (at 10.16 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 6b6d35dc-fa1d-46c5-87c0-b0652011059d)) 44 | (pad "20" thru_hole circle (at 7.62 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp d035bb7a-e806-42f2-ba95-a390d279aef1)) 45 | (pad "21" thru_hole circle (at 5.08 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 4fb2577d-2e1c-480c-9060-124510b35053)) 46 | (pad "22" thru_hole circle (at 2.54 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 3b9c5ffd-e59b-402d-8c5e-052f7ca643a4)) 47 | (pad "23" thru_hole circle (at 0 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp f08895dc-4dcb-4aef-a39b-5a08864cdaaf)) 48 | (pad "24" thru_hole circle (at -2.54 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 6133fb54-5524-482e-9ae2-adbf29aced9e)) 49 | (pad "25" thru_hole circle (at -5.08 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 5a33f5a4-a470-4c04-9e2d-532b5f01a5d6)) 50 | (pad "26" thru_hole circle (at -7.62 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp acb6c3f3-e677-4f35-9fc2-138ba10f33af)) 51 | (pad "27" thru_hole circle (at -10.16 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 2ba25c40-ea42-478e-9150-1d94fa1c8ae9)) 52 | (pad "28" thru_hole circle (at -12.7 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp b7ac5cea-ed28-4028-87d0-45e58c709cf1)) 53 | (pad "29" thru_hole circle (at -15.24 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp bf8d857b-70bf-41ee-a068-5771461e04e9)) 54 | (pad "30" thru_hole circle (at -17.78 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (tstamp 232ccf4f-3322-4e62-990b-290e6ff36fcd)) 55 | (model "./vrml2/MBUS.x3d" 56 | (offset (xyz 0 -1.27 0)) 57 | (scale (xyz 4 4 4)) 58 | (rotate (xyz -90 0 0)) 59 | ) 60 | ) 61 | -------------------------------------------------------------------------------- /wasm/gpsgsv/src/main.ts: -------------------------------------------------------------------------------- 1 | import * as c3dev from "./c3dev"; 2 | 3 | let gpsView: GpsView | null; 4 | 5 | const MAX_SATELLITE: u32 = 12; 6 | const DEG_TO_RAD: f32 = Math.PI / 180; 7 | const ELAPSED_MINUTE_10 = 10 * 60 * 1000; 8 | 9 | class Gsv { 10 | elevation: u32; 11 | azimuth: u32; 12 | snr: u32; 13 | lastUpdate: i64; 14 | } 15 | 16 | class Pos { 17 | sx: u32; 18 | sy: u32; 19 | color: c3dev.COLOR; 20 | } 21 | 22 | class GpsView { 23 | private satellites: Set; 24 | private gsv: Map; 25 | 26 | constructor( 27 | private cx: u32, 28 | private cy: u32, 29 | private cr: u32 30 | ) { 31 | this.satellites = new Set(); 32 | this.gsv = new Map(); 33 | } 34 | 35 | public tick(clear: bool): void { 36 | const cx = this.cx; 37 | const cy = this.cy; 38 | const cr = this.cr; 39 | 40 | const gsv = this.gsv; 41 | const now = c3dev.now(); 42 | const ids = gsv.keys(); 43 | 44 | if(clear) this.initView(); 45 | 46 | let pos = new Map(); 47 | for(let index = 0; index < ids.length; index++) { 48 | const id = ids[index]; 49 | const stl = gsv.get(id); 50 | // last update 51 | if(stl.lastUpdate == 0 || now - stl.lastUpdate > ELAPSED_MINUTE_10) { 52 | // clear 53 | stl.lastUpdate = 0; 54 | continue; 55 | } 56 | // calc satellite pos 57 | const ev = ((90 - stl.elevation) / 90 * cr); 58 | const sx = (cx + Mathf.sin(stl.azimuth) * ev); 59 | const sy = (cy + Mathf.cos(stl.azimuth) * ev); 60 | const color = this.satellites.has(id)? c3dev.COLOR.RED : c3dev.COLOR.GREEN; 61 | pos.set(id, { sx: sx, sy: sy, color: color}); 62 | // background 63 | line(cx, cy, sx, sy, c3dev.COLOR.BLUE); 64 | } 65 | const keys = pos.keys(); 66 | for(let index = 0; index < keys.length; index++) { 67 | const stl = pos.get(keys[index]); 68 | // foregraund 69 | circle(stl.sx, stl.sy, 2, stl.color); 70 | if(clear) { 71 | c3dev.drawString(stl.sx, stl.sy, c3dev.COLOR.WHITE, `${keys[index]}`) 72 | } 73 | } 74 | } 75 | 76 | public setSatellites(satellites: Int8Array): void { 77 | this.satellites.clear(); 78 | for(let i: u32 = 0; i < MAX_SATELLITE; i++) { 79 | this.satellites.add(satellites[i]); 80 | } 81 | } 82 | 83 | public setGsv(id: u32, elevation: u32, azimuth: u32, snr: u32): void { 84 | this.gsv.set(id, { 85 | elevation: elevation, 86 | azimuth: azimuth, 87 | snr: snr, 88 | lastUpdate: c3dev.now(), 89 | }); 90 | } 91 | 92 | private initView(): void { 93 | const cx = this.cx; 94 | const cy = this.cy; 95 | const cr = this.cr; 96 | 97 | this.clearView(); 98 | circle(cx, cy, this.cr, c3dev.COLOR.BLUE); 99 | circle(cx, cy, 2, c3dev.COLOR.BLUE); 100 | 101 | for(let angle: u32 = 0; angle < 360; angle += 6) { 102 | const rad = angle * DEG_TO_RAD; 103 | const cos = Mathf.cos(rad); 104 | const sin = Mathf.sin(rad); 105 | const sx = cx + (cos * (cr - 6)); 106 | const sy = cy + (sin * (cr - 6)); 107 | const tx = cx + (cos * (cr - 1)); 108 | const ty = cy + (sin * (cr - 1)); 109 | const color = angle % 30 == 0 110 | ? c3dev.COLOR.BLUE 111 | : 0x0015; 112 | line(sx, sy, tx, ty, color); 113 | } 114 | 115 | c3dev.drawString(cx - 2, 0, c3dev.COLOR.WHITE, "N"); 116 | } 117 | 118 | private clearView(): void { 119 | const width = this.cr * 2; 120 | const left = this.cx - this.cr; 121 | const right = left + width + 1; 122 | 123 | for(let y: u32 = 0; y < width; y++) { 124 | c3dev.draw_line(left, y, right, y, c3dev.COLOR.BLACK); 125 | } 126 | } 127 | } 128 | 129 | export function gpsgsv(x: u32, y: u32, r: u32): void { 130 | gpsView = new GpsView(x, y, r); 131 | } 132 | 133 | export function tick(clear: bool): void { 134 | if(gpsView != null) { 135 | gpsView!.tick(clear); 136 | } 137 | } 138 | 139 | export function createSatellitesArray(): Int8Array { 140 | return new Int8Array(MAX_SATELLITE); 141 | } 142 | 143 | export function setSatellites(satellites: Int8Array) : void { 144 | if(gpsView != null) { 145 | gpsView!.setSatellites(satellites); 146 | } 147 | } 148 | 149 | export function setGsv(id: u32, elevation: u32, azimuth: u32, snr: u32): void { 150 | if(gpsView != null) { 151 | gpsView!.setGsv(id, elevation, azimuth, snr); 152 | } 153 | } 154 | 155 | function circle(x: u32, y: u32, r: u32, color: c3dev.COLOR): void { 156 | let xx: u32 = r; 157 | let yy: u32 = 0; 158 | let err = 0; 159 | 160 | while(xx >= yy) { 161 | c3dev.draw_pixel(x + xx, y + yy, color); 162 | c3dev.draw_pixel(x + yy, y + xx, color); 163 | c3dev.draw_pixel(x - yy, y + xx, color); 164 | c3dev.draw_pixel(x - xx, y + yy, color); 165 | c3dev.draw_pixel(x - xx, y - yy, color); 166 | c3dev.draw_pixel(x - yy, y - xx, color); 167 | c3dev.draw_pixel(x + yy, y - xx, color); 168 | c3dev.draw_pixel(x + xx, y - yy, color); 169 | if(err <= 0) { 170 | yy++; 171 | err += 2 * yy + 1; 172 | } else { 173 | xx--; 174 | err -= 2 * xx + 1; 175 | } 176 | } 177 | } 178 | 179 | function line(x0: u32, y0: u32, x1: u32, y1: u32, color: c3dev.COLOR): void { 180 | let dx = abs(x1 - x0); 181 | let dy = abs(y1 - y0); 182 | let sx = x0 < x1 ? 1: -1; 183 | let sy = y0 < y1 ? 1: -1; 184 | 185 | let x: i32 = x0; 186 | let y: i32 = y0; 187 | let err = dx - dy; 188 | 189 | while(true) { 190 | c3dev.draw_pixel(x, y, color); 191 | if(x == x1 && y == y1) { 192 | break; 193 | } 194 | let e2 = 2 * err; 195 | if(e2 > -dy) { 196 | err -= dy; 197 | x += sx; 198 | } 199 | if(e2 < dx) { 200 | err += dx; 201 | y += sy; 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /wasm/clockenv/src/main.ts: -------------------------------------------------------------------------------- 1 | import * as c3dev from "./c3dev"; 2 | 3 | let analogClock: AnalogClock | null; 4 | 5 | const DEG_TO_RAD: f32 = Math.PI / 180; 6 | const HAND_LENGTH_HOUR: f32 = 0.55; 7 | const HAND_LENGTH_MINUTE: f32 = 0.85; 8 | const HAND_LENGTH_SECOND: f32 = 0.9; 9 | 10 | class Hands { 11 | seconds: f32; 12 | minutes: f32; 13 | hours: f32; 14 | } 15 | 16 | /** 17 | * Analog Clock 18 | */ 19 | class AnalogClock { 20 | private rhour: f32; 21 | private rminute: f32; 22 | private rsecond: f32; 23 | 24 | private envTmpRaito: i32; 25 | private envHumRaito: i32; 26 | private envPressureRaito: i32; 27 | private envDistance: i32; 28 | 29 | constructor( 30 | private cx: u32, 31 | private cy: u32, 32 | private cr: u32 33 | ) { 34 | this.init(); 35 | } 36 | 37 | init(): void { 38 | const cx = this.cx; 39 | const cy = this.cy; 40 | const cr = this.cr; 41 | 42 | circle(cx, cy, this.cr, c3dev.COLOR.BLUE); 43 | circle(cx, cy, 2, c3dev.COLOR.BLUE); 44 | 45 | for(let angle: u32 = 0; angle < 360; angle += 6) { 46 | const rad = angle * DEG_TO_RAD; 47 | const cos = Mathf.cos(rad); 48 | const sin = Mathf.sin(rad); 49 | const sx = cx + (cos * (cr - 6)); 50 | const sy = cy + (sin * (cr - 6)); 51 | const tx = cx + (cos * (cr - 1)); 52 | const ty = cy + (sin * (cr - 1)); 53 | const color = angle % 30 == 0 54 | ? c3dev.COLOR.BLUE 55 | : 0x0015; 56 | line(sx, sy, tx, ty, color); 57 | } 58 | } 59 | 60 | tick(): void { 61 | const cr = this.cr; 62 | const now = new Date(c3dev.now()); 63 | 64 | const hands = this.calcHands(now); 65 | const hs = hands.seconds; 66 | const hm = hands.minutes; 67 | const hh = hands.hours; 68 | 69 | if(hs != this.rsecond) { 70 | this.drawHand(this.rsecond, cr * HAND_LENGTH_SECOND, c3dev.COLOR.BLACK); 71 | this.drawHand(hs, cr * HAND_LENGTH_SECOND, 0x0015); 72 | this.rsecond = hs; 73 | } 74 | if(hm != this.rminute) { 75 | this.drawHand(this.rminute, cr * HAND_LENGTH_MINUTE, c3dev.COLOR.BLACK); 76 | this.rminute = hm; 77 | } 78 | this.drawHand(hm, cr * HAND_LENGTH_MINUTE, c3dev.COLOR.ORANGE); 79 | if(hh != this.rhour) { 80 | this.drawHand(this.rhour, cr * HAND_LENGTH_HOUR, c3dev.COLOR.BLACK); 81 | this.rhour = hh; 82 | } 83 | this.drawHand(hh, cr * HAND_LENGTH_HOUR, c3dev.COLOR.ORANGE); 84 | 85 | const tmp = c3dev.get_env_tmp(); 86 | const tmpRaito = Mathf.round((tmp + 20) * 1.2); 87 | if(tmpRaito != this.envTmpRaito) { 88 | this.drawArcMeter(60, -60, tmpRaito, c3dev.COLOR.RED, c3dev.COLOR.BLUE); 89 | this.envTmpRaito = tmpRaito; 90 | c3dev.drawString(136, 116, c3dev.COLOR.RED, `${tmp}`.slice(0, 4) + "C"); 91 | } 92 | const hum = c3dev.get_env_hum(); 93 | const humRaito = Mathf.round(hum); 94 | if(humRaito != this.envHumRaito) { 95 | this.drawArcMeter(120, 180, humRaito, c3dev.COLOR.MAGENTA, c3dev.COLOR.BLUE); 96 | this.envHumRaito = humRaito; 97 | c3dev.drawString(0, 116, c3dev.COLOR.MAGENTA, `${hum}`.slice(0, 4) + "%"); 98 | } 99 | const pressure = c3dev.get_env_pressure(); 100 | const pressureRaito = Mathf.round(pressure / 20); 101 | if(pressureRaito != this.envPressureRaito) { 102 | const intpressure = Math.floor(pressure); 103 | this.drawArcMeter(180, 240, pressureRaito, c3dev.COLOR.GREEN, c3dev.COLOR.BLUE); 104 | this.envPressureRaito = pressureRaito; 105 | c3dev.drawString(0, 0, c3dev.COLOR.GREEN, `${intpressure}`.slice(0, 4) + "hP"); 106 | } 107 | const distance = Mathf.floor(c3dev.get_ultrasonic_distance() / 10); 108 | if(distance !=0 && distance / 10 != this.envDistance) { 109 | this.envDistance = (distance / 10); 110 | c3dev.drawString(128, 0, c3dev.COLOR.CYAN, `000${distance}cm`.slice(-5)); 111 | } 112 | } 113 | 114 | drawHand(rad: f32, length: f32, color: c3dev.COLOR): void { 115 | const cx = this.cx; 116 | const cy = this.cy; 117 | const cos = Mathf.cos(rad); 118 | const sin = Mathf.sin(rad); 119 | 120 | line( 121 | cx + (cos * 4.0), 122 | cy + (sin * 4.0), 123 | cx + (cos * length), 124 | cy + (sin * length), 125 | color 126 | ); 127 | } 128 | 129 | drawArcMeter(sangle: f32, eangle: f32, ratio: f32, fc: c3dev.COLOR, bc: c3dev.COLOR): void { 130 | if(ratio > 100) { 131 | ratio = 100; 132 | } 133 | let start = sangle; 134 | let stop = eangle; 135 | 136 | if(sangle < eangle) { 137 | start = eangle; 138 | stop = sangle; 139 | } 140 | const step: f32 = (100.0 / (start - stop)) / 10; 141 | 142 | const cx = this.cx; 143 | const cy = this.cy; 144 | const cr = this.cr; 145 | 146 | c3dev.start_write(); 147 | 148 | let sraito: f32 = 0; 149 | for(let angle: f32 = start; angle > stop; angle -= 0.1) { 150 | const rad = angle * DEG_TO_RAD; 151 | const cos = Mathf.cos(rad); 152 | const sin = Mathf.sin(rad); 153 | 154 | const sx = cx + (cos * (cr + 10)); 155 | const sy = cy + (sin * (cr + 10)); 156 | const tx = cx + (cos * (cr + 8)); 157 | const ty = cy + (sin * (cr + 8)); 158 | 159 | const color = sraito > ratio ? bc : fc; 160 | line(sx, sy, tx, ty, color, false); 161 | sraito += step; 162 | } 163 | 164 | c3dev.end_write(); 165 | } 166 | 167 | calcHands(date: Date): Hands { 168 | return { 169 | seconds: (date.getUTCSeconds() * 6 - 90) * DEG_TO_RAD, 170 | minutes: (date.getUTCMinutes() * 6 - 90) * DEG_TO_RAD, 171 | hours: (date.getUTCHours() * 30 + date.getUTCMinutes() * 0.5 - 90) * DEG_TO_RAD 172 | }; 173 | } 174 | } 175 | 176 | export function clock(x: u32, y: u32, r: u32): void { 177 | analogClock = new AnalogClock(x, y, r); 178 | } 179 | 180 | export function tick(): void { 181 | if(analogClock != null) { 182 | analogClock!.tick(); 183 | } 184 | } 185 | 186 | function circle(x: u32, y: u32, r: u32, color: c3dev.COLOR, tranctl: bool = true): void { 187 | let xx: u32 = r; 188 | let yy: u32 = 0; 189 | let err = 0; 190 | 191 | if(tranctl) c3dev.start_write(); 192 | 193 | while(xx >= yy) { 194 | c3dev.write_pixel(x + xx, y + yy, color); 195 | c3dev.write_pixel(x + yy, y + xx, color); 196 | c3dev.write_pixel(x - yy, y + xx, color); 197 | c3dev.write_pixel(x - xx, y + yy, color); 198 | c3dev.write_pixel(x - xx, y - yy, color); 199 | c3dev.write_pixel(x - yy, y - xx, color); 200 | c3dev.write_pixel(x + yy, y - xx, color); 201 | c3dev.write_pixel(x + xx, y - yy, color); 202 | if(err <= 0) { 203 | yy++; 204 | err += 2 * yy + 1; 205 | } else { 206 | xx--; 207 | err -= 2 * xx + 1; 208 | } 209 | } 210 | 211 | if(tranctl) c3dev.end_write(); 212 | } 213 | 214 | function line(x0: u32, y0: u32, x1: u32, y1: u32, color: c3dev.COLOR, tranctl: bool = true): void { 215 | let dx = abs(x1 - x0); 216 | let dy = abs(y1 - y0); 217 | let sx = x0 < x1 ? 1: -1; 218 | let sy = y0 < y1 ? 1: -1; 219 | 220 | let x: i32 = x0; 221 | let y: i32 = y0; 222 | let err = dx - dy; 223 | 224 | if(tranctl) c3dev.start_write(); 225 | 226 | while(true) { 227 | c3dev.write_pixel(x, y, color); 228 | if(x == x1 && y == y1) { 229 | break; 230 | } 231 | let e2 = 2 * err; 232 | if(e2 > -dy) { 233 | err -= dy; 234 | x += sx; 235 | } 236 | if(e2 < dx) { 237 | err += dx; 238 | y += sy; 239 | } 240 | } 241 | 242 | if(tranctl) c3dev.end_write(); 243 | } 244 | -------------------------------------------------------------------------------- /main/test_wasm3_imu6886.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "SPIFFS.h" 3 | #include "esp_log.h" 4 | #include "esp_err.h" 5 | #include "esp_heap_caps.h" 6 | #include 7 | 8 | #include "wasm3.h" 9 | #include "m3_env.h" 10 | #include "m3_api_libc.h" 11 | 12 | #include "c3dev_board.h" 13 | #include "test_freetype.h" 14 | 15 | static const char *TAG = "test_wasm3_imu6886.cpp"; 16 | 17 | /** 18 | * Wasm3 member 19 | */ 20 | IM3Environment wasm3_env; 21 | IM3Runtime wasm3_runtime; 22 | IM3Module wasm3_module; 23 | IM3Function wasm3_func_tick; 24 | IM3Function wasm3_func_collect; 25 | 26 | #define WASM3_STACK_SIZE 16384 27 | #define FREETYPE_FONT_SIZE 14 28 | 29 | /** 30 | * SPIFFS member 31 | */ 32 | fs::SPIFFSFS SPIFFS_WASM; 33 | 34 | /** 35 | * FreeType member 36 | */ 37 | font_render_t wasm_font_render; 38 | 39 | /** 40 | * as_gc_collect. 41 | */ 42 | void as_gc_collect(void) 43 | { 44 | M3Result result = m3Err_none; 45 | 46 | result = m3_Call(wasm3_func_collect, 0, nullptr); 47 | if (result) { 48 | ESP_LOGE(TAG, "m3_Call:as_gc_collect: %s", result); 49 | } 50 | } 51 | 52 | // (import "env" "seed" (func $env.seed (type $t3))) 53 | // (type $t3 (func (result f64))) 54 | m3ApiRawFunction(c3dev_random) { 55 | m3ApiReturnType(float_t) // 32bit 56 | m3ApiReturn(esp_random()); // uint32_t */ 57 | } 58 | 59 | // (import "env" "abort" (func $env.abort (type $t0))) 60 | // (type $t0 (func (param i32 i32 i32 i32))) 61 | m3ApiRawFunction(c3dev_abort) 62 | { 63 | m3ApiGetArgMem(char16_t *, message) 64 | m3ApiGetArgMem(char16_t *, fileName) 65 | m3ApiGetArg(int32_t, lineNumber) 66 | m3ApiGetArg(int32_t, columnNumber) 67 | 68 | // ESP_LOGE(TAG, "c3dev_abort: %ls %ls %d %d", message, fileName, lineNumber, columnNumber); 69 | 70 | m3ApiSuccess(); 71 | } 72 | 73 | m3ApiRawFunction(c3dev_now) 74 | { 75 | m3ApiReturnType(int64_t) 76 | 77 | struct timeval tv_now; 78 | gettimeofday(&tv_now, NULL); 79 | int64_t time_ms = (int64_t)tv_now.tv_sec * 1000L + /* UTC+9 */ 3600000 * 9; 80 | // ESP_LOGI(TAG, "c3dev_now: %d", time_ms); 81 | 82 | m3ApiReturn(time_ms); 83 | } 84 | 85 | m3ApiRawFunction(c3dev_delay) { 86 | m3ApiGetArg(int32_t, wait) 87 | 88 | delay(wait); 89 | 90 | m3ApiSuccess(); 91 | } 92 | 93 | m3ApiRawFunction(c3dev_start_write) 94 | { 95 | // TODO: SPI transaction 96 | // tft.startWrite(); 97 | 98 | m3ApiSuccess(); 99 | } 100 | 101 | m3ApiRawFunction(c3dev_draw_pixel) 102 | { 103 | m3ApiGetArg(int32_t, x) 104 | m3ApiGetArg(int32_t, y) 105 | m3ApiGetArg(int32_t, color) 106 | 107 | tft.drawPixel(x, y, color); 108 | 109 | m3ApiSuccess(); 110 | } 111 | 112 | m3ApiRawFunction(c3dev_draw_line) 113 | { 114 | m3ApiGetArg(int32_t, x0) 115 | m3ApiGetArg(int32_t, y0) 116 | m3ApiGetArg(int32_t, x1) 117 | m3ApiGetArg(int32_t, y1) 118 | m3ApiGetArg(int32_t, color) 119 | 120 | tft.drawLine(x0, y0, x1, y1, color); 121 | 122 | m3ApiSuccess(); 123 | } 124 | 125 | m3ApiRawFunction(c3dev_fill_rect) 126 | { 127 | m3ApiGetArg(int32_t, x0) 128 | m3ApiGetArg(int32_t, y0) 129 | m3ApiGetArg(int32_t, x1) 130 | m3ApiGetArg(int32_t, y1) 131 | m3ApiGetArg(int32_t, color) 132 | 133 | tft.fillRect(x0, y0, x1, y1, color); 134 | 135 | m3ApiSuccess(); 136 | } 137 | 138 | m3ApiRawFunction(c3dev_end_write) 139 | { 140 | // TODO: SPI transaction 141 | // tft.endWrite(); 142 | 143 | m3ApiSuccess(); 144 | } 145 | 146 | m3ApiRawFunction(c3dev_log) 147 | { 148 | m3ApiGetArgMem(char *, utf8_null_terminated_string) 149 | 150 | ESP_LOGI(TAG, "c3dev_log: %s", utf8_null_terminated_string); 151 | 152 | m3ApiSuccess(); 153 | } 154 | 155 | m3ApiRawFunction(c3dev_draw_string) 156 | { 157 | m3ApiGetArg(int32_t, x) 158 | m3ApiGetArg(int32_t, y) 159 | m3ApiGetArg(int32_t, color) 160 | m3ApiGetArgMem(char *, utf8_null_terminated_string) 161 | 162 | draw_freetype_string(utf8_null_terminated_string, x, y + FREETYPE_FONT_SIZE, color, &wasm_font_render); 163 | // ESP_LOGI(TAG, "draw_freetype_string(%d, %d, %d, %s)", x, y, color, utf8_null_terminated_string); 164 | 165 | m3ApiSuccess(); 166 | } 167 | 168 | M3Result link_c3dev(IM3Runtime runtime) { 169 | IM3Module module = runtime->modules; 170 | 171 | m3_LinkRawFunction(module, "env", "seed", "F()", &c3dev_random); 172 | m3_LinkRawFunction(module, "env", "abort", "v(**ii)", &c3dev_abort); 173 | m3_LinkRawFunction(module, "c3dev", "now", "I()", &c3dev_now); 174 | m3_LinkRawFunction(module, "c3dev", "delay", "v(i)", &c3dev_delay); 175 | m3_LinkRawFunction(module, "c3dev", "start_write", "v()", &c3dev_start_write); 176 | m3_LinkRawFunction(module, "c3dev", "draw_pixel", "v(iii)", &c3dev_draw_pixel); 177 | m3_LinkRawFunction(module, "c3dev", "draw_line", "v(iiiii)", &c3dev_draw_line); 178 | m3_LinkRawFunction(module, "c3dev", "fill_rect", "v(iiiii)", &c3dev_fill_rect); 179 | m3_LinkRawFunction(module, "c3dev", "end_write", "v()", &c3dev_end_write); 180 | m3_LinkRawFunction(module, "c3dev", "draw_string", "v(iii*)", &c3dev_draw_string); 181 | m3_LinkRawFunction(module, "c3dev", "log", "v(*)", &c3dev_log); 182 | 183 | return m3Err_none; 184 | } 185 | 186 | esp_err_t load_wasm(uint8_t *wasm_binary, size_t wasm_size) 187 | { 188 | M3Result result = m3Err_none; 189 | 190 | ESP_LOGI(TAG, "heap_caps_get_free_size: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT)); 191 | 192 | ESP_LOGI(TAG, "Loading WebAssembly..."); 193 | wasm3_env = m3_NewEnvironment(); 194 | if (!wasm3_env) { 195 | ESP_LOGE(TAG, "m3_NewEnvironment failed"); 196 | return ESP_FAIL; 197 | } 198 | 199 | wasm3_runtime = m3_NewRuntime(wasm3_env, WASM3_STACK_SIZE, NULL); 200 | if (!wasm3_runtime) { 201 | ESP_LOGE(TAG, "m3_NewRuntime failed"); 202 | return ESP_FAIL; 203 | } 204 | 205 | result = m3_ParseModule(wasm3_env, &wasm3_module, wasm_binary, wasm_size); 206 | if (result) { 207 | ESP_LOGE(TAG, "m3_ParseModule: %s", result); 208 | return ESP_FAIL; 209 | } 210 | 211 | result = m3_LoadModule(wasm3_runtime, wasm3_module); 212 | if (result) { 213 | ESP_LOGE(TAG, "m3_LoadModule: %s", result); 214 | return ESP_FAIL; 215 | } 216 | 217 | // link c3dev function 218 | result = link_c3dev(wasm3_runtime); 219 | if (result) { 220 | ESP_LOGE(TAG, "link_c3dev: %s", result); 221 | return ESP_FAIL; 222 | } 223 | 224 | ESP_LOGI(TAG, "Running..."); 225 | 226 | // Get AssemblyScript GC interface 227 | result = m3_FindFunction(&wasm3_func_collect, wasm3_runtime, "__collect"); 228 | if (result) { 229 | ESP_LOGE(TAG, "m3_FindFunction:wasm3_func_collect: %s", result); 230 | return ESP_FAIL; 231 | } 232 | 233 | // Init IMU 234 | IM3Function init; 235 | result = m3_FindFunction(&init, wasm3_runtime, "init"); 236 | if (result) { 237 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 238 | return ESP_FAIL; 239 | } 240 | // export function init(width: u32, height: u32): void; 241 | const char* i_argv[4] = { "160", "128" }; 242 | result = m3_CallArgv(init, 2, i_argv); 243 | if (result) { 244 | ESP_LOGE(TAG, "m3_Call: %s", result); 245 | return ESP_FAIL; 246 | } 247 | 248 | // Get tick function 249 | result = m3_FindFunction(&wasm3_func_tick, wasm3_runtime, "tick"); 250 | if (result) { 251 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 252 | return ESP_FAIL; 253 | } 254 | 255 | ESP_LOGI(TAG, "Wasm3 Initialized"); 256 | ESP_LOGI(TAG, "heap_caps_get_free_size: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT)); 257 | 258 | return ESP_OK; 259 | } 260 | 261 | esp_err_t imu6886_init_wasm(void) 262 | { 263 | SPIFFS_WASM.begin(false, "/wasm", 4, "wasm"); 264 | 265 | File wasm_file = SPIFFS_WASM.open("/imu6886.wasm", "rb"); 266 | size_t wasm_size = wasm_file.size(); 267 | 268 | ESP_LOGI(TAG, "imu6886.wasm: %d", wasm_size); 269 | // Read .wasm to Internal RAM (or MALLOC_CAP_SPIRAM - slow) 270 | uint8_t *wasm_binary = (uint8_t *)malloc(sizeof(uint8_t) * wasm_size); 271 | if(wasm_binary == nullptr) { 272 | ESP_LOGE(TAG, "Memory alloc error"); 273 | return ESP_FAIL; 274 | } 275 | if(wasm_file.read(wasm_binary, wasm_size) != wasm_size) { 276 | ESP_LOGE(TAG, "SPIFFS read error"); 277 | return ESP_FAIL; 278 | } 279 | 280 | wasm_file.close(); 281 | SPIFFS_WASM.end(); 282 | 283 | // Setup Font render 284 | wasm_font_render = create_freetype_render(FREETYPE_FONT_SIZE, /* font cache */ 64); 285 | // Clear LCD 286 | tft.fillScreen(ST77XX_BLACK); 287 | 288 | // Load WebAssembly on Wasm3 289 | return load_wasm(wasm_binary, wasm_size); 290 | } 291 | 292 | esp_err_t imu6886_tick_wasm(void) 293 | { 294 | M3Result result = m3Err_none; 295 | 296 | result = m3_Call(wasm3_func_tick, 0, nullptr); 297 | if (result) { 298 | ESP_LOGE(TAG, "m3_Call: %s", result); 299 | return ESP_FAIL; 300 | } 301 | 302 | // GC by tick for AssemblyScript --runtime minimal 303 | as_gc_collect(); 304 | 305 | return ESP_OK; 306 | } 307 | -------------------------------------------------------------------------------- /main/test_wasm3_clockenv.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "SPIFFS.h" 3 | #include "esp_log.h" 4 | #include "esp_err.h" 5 | #include "esp_heap_caps.h" 6 | #include 7 | 8 | #include "wasm3.h" 9 | #include "m3_env.h" 10 | #include "m3_api_libc.h" 11 | 12 | #include "c3dev_board.h" 13 | #include "test_freetype.h" 14 | 15 | #ifdef CONFIG_GPIO1819_I2C 16 | #include "test_i2c_gpio1819.h" 17 | /** 18 | * Unit ENV III member 19 | */ 20 | unitenv_t unitenv; 21 | 22 | /** 23 | * Unit UltraSonic 24 | */ 25 | unit_ultrasonic_t ultrasonic; 26 | #endif 27 | 28 | static const char *TAG = "test_wasm3_clockenv.cpp"; 29 | 30 | /** 31 | * Wasm3 member 32 | */ 33 | IM3Environment wasm3_env; 34 | IM3Runtime wasm3_runtime; 35 | IM3Module wasm3_module; 36 | IM3Function wasm3_func_tick; 37 | IM3Function wasm3_func_collect; 38 | 39 | #define WASM3_STACK_SIZE 16384 40 | #define FREETYPE_FONT_SIZE 9 41 | 42 | /** 43 | * SPIFFS member 44 | */ 45 | fs::SPIFFSFS SPIFFS_WASM; 46 | 47 | /** 48 | * FreeType member 49 | */ 50 | font_render_t wasm_font_render; 51 | 52 | /** 53 | * as_gc_collect. 54 | */ 55 | void as_gc_collect(void) 56 | { 57 | M3Result result = m3Err_none; 58 | 59 | result = m3_Call(wasm3_func_collect, 0, nullptr); 60 | if (result) { 61 | ESP_LOGE(TAG, "m3_Call:as_gc_collect: %s", result); 62 | } 63 | } 64 | 65 | // (import "env" "seed" (func $env.seed (type $t3))) 66 | // (type $t3 (func (result f64))) 67 | m3ApiRawFunction(c3dev_random) { 68 | m3ApiReturnType(float_t) // 32bit 69 | m3ApiReturn(esp_random()); // uint32_t */ 70 | } 71 | 72 | // (import "env" "abort" (func $env.abort (type $t0))) 73 | // (type $t0 (func (param i32 i32 i32 i32))) 74 | m3ApiRawFunction(c3dev_abort) 75 | { 76 | m3ApiGetArgMem(char16_t *, message) 77 | m3ApiGetArgMem(char16_t *, fileName) 78 | m3ApiGetArg(int32_t, lineNumber) 79 | m3ApiGetArg(int32_t, columnNumber) 80 | 81 | // ESP_LOGE(TAG, "c3dev_abort: %ls %ls %d %d", message, fileName, lineNumber, columnNumber); 82 | 83 | m3ApiSuccess(); 84 | } 85 | 86 | m3ApiRawFunction(c3dev_now) 87 | { 88 | m3ApiReturnType(int64_t) 89 | 90 | struct timeval tv_now; 91 | gettimeofday(&tv_now, NULL); 92 | int64_t time_ms = (int64_t)tv_now.tv_sec * 1000L + /* UTC+9 */ 3600000 * 9; 93 | // ESP_LOGI(TAG, "c3dev_now: %d", time_ms); 94 | 95 | m3ApiReturn(time_ms); 96 | } 97 | 98 | m3ApiRawFunction(c3dev_delay) { 99 | m3ApiGetArg(int32_t, wait) 100 | 101 | delay(wait); 102 | 103 | m3ApiSuccess(); 104 | } 105 | 106 | m3ApiRawFunction(c3dev_start_write) 107 | { 108 | tft.startWrite(); 109 | 110 | m3ApiSuccess(); 111 | } 112 | 113 | m3ApiRawFunction(c3dev_draw_pixel) 114 | { 115 | m3ApiGetArg(int32_t, x) 116 | m3ApiGetArg(int32_t, y) 117 | m3ApiGetArg(int32_t, color) 118 | 119 | tft.drawPixel(x, y, color); 120 | 121 | m3ApiSuccess(); 122 | } 123 | 124 | m3ApiRawFunction(c3dev_write_pixel) 125 | { 126 | m3ApiGetArg(int32_t, x) 127 | m3ApiGetArg(int32_t, y) 128 | m3ApiGetArg(int32_t, color) 129 | 130 | tft.writePixel(x, y, color); 131 | 132 | m3ApiSuccess(); 133 | } 134 | 135 | m3ApiRawFunction(c3dev_draw_line) 136 | { 137 | m3ApiGetArg(int32_t, x0) 138 | m3ApiGetArg(int32_t, y0) 139 | m3ApiGetArg(int32_t, x1) 140 | m3ApiGetArg(int32_t, y1) 141 | m3ApiGetArg(int32_t, color) 142 | 143 | tft.drawLine(x0, y0, x1, y1, color); 144 | 145 | m3ApiSuccess(); 146 | } 147 | 148 | m3ApiRawFunction(c3dev_end_write) 149 | { 150 | tft.endWrite(); 151 | 152 | m3ApiSuccess(); 153 | } 154 | 155 | m3ApiRawFunction(c3dev_log) 156 | { 157 | m3ApiGetArgMem(char *, utf8_null_terminated_string) 158 | 159 | ESP_LOGI(TAG, "c3dev_log: %s", utf8_null_terminated_string); 160 | 161 | m3ApiSuccess(); 162 | } 163 | 164 | m3ApiRawFunction(c3dev_draw_string) 165 | { 166 | m3ApiGetArg(int32_t, x) 167 | m3ApiGetArg(int32_t, y) 168 | m3ApiGetArg(int32_t, color) 169 | m3ApiGetArgMem(char *, utf8_null_terminated_string) 170 | 171 | draw_freetype_string(utf8_null_terminated_string, x, y + FREETYPE_FONT_SIZE, color, &wasm_font_render); 172 | // ESP_LOGI(TAG, "draw_freetype_string(%d, %d, %d, %s)", x, y, color, utf8_null_terminated_string); 173 | 174 | m3ApiSuccess(); 175 | } 176 | 177 | m3ApiRawFunction(c3dev_get_env_tmp) { 178 | m3ApiReturnType(float_t) 179 | #ifdef CONFIG_GPIO1819_I2C 180 | m3ApiReturn(unitenv.tmp); 181 | #else 182 | m3ApiReturn(/* dummy */20.0); 183 | #endif 184 | } 185 | 186 | m3ApiRawFunction(c3dev_get_env_hum) { 187 | m3ApiReturnType(float_t) 188 | #ifdef CONFIG_GPIO1819_I2C 189 | m3ApiReturn(unitenv.hum); 190 | #else 191 | m3ApiReturn(/* dummy */40.0); 192 | #endif 193 | } 194 | 195 | m3ApiRawFunction(c3dev_get_env_pressure) { 196 | m3ApiReturnType(float_t) 197 | #ifdef CONFIG_GPIO1819_I2C 198 | m3ApiReturn(unitenv.pressure); 199 | #else 200 | m3ApiReturn(/* dummy */1000.0); 201 | #endif 202 | } 203 | 204 | m3ApiRawFunction(c3dev_get_ultrasonic_distance) { 205 | m3ApiReturnType(float_t) 206 | #ifdef CONFIG_GPIO1819_I2C 207 | m3ApiReturn(ultrasonic.distance); 208 | #else 209 | m3ApiReturn(/* dummy */20.0); 210 | #endif 211 | } 212 | 213 | M3Result link_c3dev(IM3Runtime runtime) { 214 | IM3Module module = runtime->modules; 215 | 216 | m3_LinkRawFunction(module, "env", "seed", "F()", &c3dev_random); 217 | m3_LinkRawFunction(module, "env", "abort", "v(**ii)", &c3dev_abort); 218 | m3_LinkRawFunction(module, "c3dev", "now", "I()", &c3dev_now); 219 | m3_LinkRawFunction(module, "c3dev", "delay", "v(i)", &c3dev_delay); 220 | m3_LinkRawFunction(module, "c3dev", "start_write", "v()", &c3dev_start_write); 221 | m3_LinkRawFunction(module, "c3dev", "draw_pixel", "v(iii)", &c3dev_draw_pixel); 222 | m3_LinkRawFunction(module, "c3dev", "draw_line", "v(iiiii)", &c3dev_draw_line); 223 | m3_LinkRawFunction(module, "c3dev", "write_pixel", "v(iii)", &c3dev_write_pixel); 224 | m3_LinkRawFunction(module, "c3dev", "end_write", "v()", &c3dev_end_write); 225 | m3_LinkRawFunction(module, "c3dev", "draw_string", "v(iii*)", &c3dev_draw_string); 226 | m3_LinkRawFunction(module, "c3dev", "get_env_tmp", "f()", &c3dev_get_env_tmp); 227 | m3_LinkRawFunction(module, "c3dev", "get_env_hum", "f()", &c3dev_get_env_hum); 228 | m3_LinkRawFunction(module, "c3dev", "get_env_pressure", "f()", &c3dev_get_env_pressure); 229 | m3_LinkRawFunction(module, "c3dev", "get_ultrasonic_distance", "f()", &c3dev_get_ultrasonic_distance); 230 | m3_LinkRawFunction(module, "c3dev", "log", "v(*)", &c3dev_log); 231 | 232 | return m3Err_none; 233 | } 234 | 235 | esp_err_t load_wasm(uint8_t *wasm_binary, size_t wasm_size) 236 | { 237 | M3Result result = m3Err_none; 238 | 239 | ESP_LOGI(TAG, "heap_caps_get_free_size: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT)); 240 | 241 | ESP_LOGI(TAG, "Loading WebAssembly..."); 242 | wasm3_env = m3_NewEnvironment(); 243 | if (!wasm3_env) { 244 | ESP_LOGE(TAG, "m3_NewEnvironment failed"); 245 | return ESP_FAIL; 246 | } 247 | 248 | wasm3_runtime = m3_NewRuntime(wasm3_env, WASM3_STACK_SIZE, NULL); 249 | if (!wasm3_runtime) { 250 | ESP_LOGE(TAG, "m3_NewRuntime failed"); 251 | return ESP_FAIL; 252 | } 253 | 254 | result = m3_ParseModule(wasm3_env, &wasm3_module, wasm_binary, wasm_size); 255 | if (result) { 256 | ESP_LOGE(TAG, "m3_ParseModule: %s", result); 257 | return ESP_FAIL; 258 | } 259 | 260 | result = m3_LoadModule(wasm3_runtime, wasm3_module); 261 | if (result) { 262 | ESP_LOGE(TAG, "m3_LoadModule: %s", result); 263 | return ESP_FAIL; 264 | } 265 | 266 | // link c3dev function 267 | result = link_c3dev(wasm3_runtime); 268 | if (result) { 269 | ESP_LOGE(TAG, "link_c3dev: %s", result); 270 | return ESP_FAIL; 271 | } 272 | 273 | ESP_LOGI(TAG, "Running..."); 274 | 275 | // Get AssemblyScript GC interface 276 | result = m3_FindFunction(&wasm3_func_collect, wasm3_runtime, "__collect"); 277 | if (result) { 278 | ESP_LOGE(TAG, "m3_FindFunction:wasm3_func_collect: %s", result); 279 | return ESP_FAIL; 280 | } 281 | 282 | // Draw Clock 283 | IM3Function clock; 284 | result = m3_FindFunction(&clock, wasm3_runtime, "clock"); 285 | if (result) { 286 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 287 | return ESP_FAIL; 288 | } 289 | // export function clock(x: u32, y: u32, r: u32): void; 290 | const char* i_argv[4] = { "80", "64", "63" }; 291 | result = m3_CallArgv(clock, 3, i_argv); 292 | if (result) { 293 | ESP_LOGE(TAG, "m3_Call: %s", result); 294 | return ESP_FAIL; 295 | } 296 | 297 | // Get tick function 298 | result = m3_FindFunction(&wasm3_func_tick, wasm3_runtime, "tick"); 299 | if (result) { 300 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 301 | return ESP_FAIL; 302 | } 303 | 304 | ESP_LOGI(TAG, "Wasm3 Initialized"); 305 | ESP_LOGI(TAG, "heap_caps_get_free_size: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT)); 306 | 307 | return ESP_OK; 308 | } 309 | 310 | esp_err_t clockenv_init_wasm(void) 311 | { 312 | SPIFFS_WASM.begin(false, "/wasm", 4, "wasm"); 313 | 314 | File wasm_file = SPIFFS_WASM.open("/clockenv.wasm", "rb"); 315 | size_t wasm_size = wasm_file.size(); 316 | 317 | ESP_LOGI(TAG, "clockenv.wasm: %d", wasm_size); 318 | // Read .wasm 319 | uint8_t *wasm_binary = (uint8_t *)malloc(sizeof(uint8_t) * wasm_size); 320 | if(wasm_binary == nullptr) { 321 | ESP_LOGE(TAG, "Memory alloc error"); 322 | return ESP_FAIL; 323 | } 324 | if(wasm_file.read(wasm_binary, wasm_size) != wasm_size) { 325 | ESP_LOGE(TAG, "SPIFFS read error"); 326 | return ESP_FAIL; 327 | } 328 | 329 | wasm_file.close(); 330 | SPIFFS_WASM.end(); 331 | 332 | // Setup Font render 333 | wasm_font_render = create_freetype_render(FREETYPE_FONT_SIZE, /* font cache */ 64); 334 | // Clear LCD 335 | tft.fillScreen(ST77XX_BLACK); 336 | 337 | // Load WebAssembly on Wasm3 338 | return load_wasm(wasm_binary, wasm_size); 339 | } 340 | 341 | esp_err_t clockenv_tick_wasm(void) 342 | { 343 | M3Result result = m3Err_none; 344 | 345 | #ifdef CONFIG_GPIO1819_I2C 346 | // Get Unit ENV III date 347 | get_i2c_unit_data(&unitenv, &ultrasonic); 348 | #endif 349 | 350 | result = m3_Call(wasm3_func_tick, 0, nullptr); 351 | if (result) { 352 | ESP_LOGE(TAG, "m3_Call: %s", result); 353 | return ESP_FAIL; 354 | } 355 | 356 | // GC by tick for AssemblyScript --runtime minimal 357 | as_gc_collect(); 358 | 359 | return ESP_OK; 360 | } 361 | -------------------------------------------------------------------------------- /pcb/fg06-c3dev-revb/fg06-c3dev-revb.kicad_pro: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "design_settings": { 4 | "defaults": { 5 | "board_outline_line_width": 0.09999999999999999, 6 | "copper_line_width": 0.19999999999999998, 7 | "copper_text_italic": false, 8 | "copper_text_size_h": 1.5, 9 | "copper_text_size_v": 1.5, 10 | "copper_text_thickness": 0.3, 11 | "copper_text_upright": false, 12 | "courtyard_line_width": 0.049999999999999996, 13 | "dimension_precision": 4, 14 | "dimension_units": 3, 15 | "dimensions": { 16 | "arrow_length": 1270000, 17 | "extension_offset": 500000, 18 | "keep_text_aligned": true, 19 | "suppress_zeroes": false, 20 | "text_position": 0, 21 | "units_format": 1 22 | }, 23 | "fab_line_width": 0.09999999999999999, 24 | "fab_text_italic": false, 25 | "fab_text_size_h": 1.0, 26 | "fab_text_size_v": 1.0, 27 | "fab_text_thickness": 0.15, 28 | "fab_text_upright": false, 29 | "other_line_width": 0.15, 30 | "other_text_italic": false, 31 | "other_text_size_h": 1.0, 32 | "other_text_size_v": 1.0, 33 | "other_text_thickness": 0.15, 34 | "other_text_upright": false, 35 | "pads": { 36 | "drill": 0.762, 37 | "height": 1.524, 38 | "width": 1.524 39 | }, 40 | "silk_line_width": 0.15, 41 | "silk_text_italic": false, 42 | "silk_text_size_h": 1.0, 43 | "silk_text_size_v": 1.0, 44 | "silk_text_thickness": 0.15, 45 | "silk_text_upright": false, 46 | "zones": { 47 | "45_degree_only": true, 48 | "min_clearance": 0.508 49 | } 50 | }, 51 | "diff_pair_dimensions": [ 52 | { 53 | "gap": 0.0, 54 | "via_gap": 0.0, 55 | "width": 0.0 56 | } 57 | ], 58 | "drc_exclusions": [], 59 | "meta": { 60 | "version": 2 61 | }, 62 | "rule_severities": { 63 | "annular_width": "error", 64 | "clearance": "error", 65 | "copper_edge_clearance": "error", 66 | "courtyards_overlap": "error", 67 | "diff_pair_gap_out_of_range": "error", 68 | "diff_pair_uncoupled_length_too_long": "error", 69 | "drill_out_of_range": "error", 70 | "duplicate_footprints": "warning", 71 | "extra_footprint": "warning", 72 | "footprint_type_mismatch": "error", 73 | "hole_clearance": "error", 74 | "hole_near_hole": "error", 75 | "invalid_outline": "error", 76 | "item_on_disabled_layer": "error", 77 | "items_not_allowed": "error", 78 | "length_out_of_range": "error", 79 | "malformed_courtyard": "error", 80 | "microvia_drill_out_of_range": "error", 81 | "missing_courtyard": "ignore", 82 | "missing_footprint": "warning", 83 | "net_conflict": "warning", 84 | "npth_inside_courtyard": "ignore", 85 | "padstack": "error", 86 | "pth_inside_courtyard": "ignore", 87 | "shorting_items": "error", 88 | "silk_over_copper": "warning", 89 | "silk_overlap": "warning", 90 | "skew_out_of_range": "error", 91 | "through_hole_pad_without_hole": "error", 92 | "too_many_vias": "error", 93 | "track_dangling": "warning", 94 | "track_width": "error", 95 | "tracks_crossing": "error", 96 | "unconnected_items": "error", 97 | "unresolved_variable": "error", 98 | "via_dangling": "warning", 99 | "zone_has_empty_net": "error", 100 | "zones_intersect": "error" 101 | }, 102 | "rules": { 103 | "allow_blind_buried_vias": false, 104 | "allow_microvias": false, 105 | "max_error": 0.005, 106 | "min_clearance": 0.0, 107 | "min_copper_edge_clearance": 0.0, 108 | "min_hole_clearance": 0.25, 109 | "min_hole_to_hole": 0.25, 110 | "min_microvia_diameter": 0.19999999999999998, 111 | "min_microvia_drill": 0.09999999999999999, 112 | "min_silk_clearance": 0.0, 113 | "min_through_hole_diameter": 0.3, 114 | "min_track_width": 0.19999999999999998, 115 | "min_via_annular_width": 0.049999999999999996, 116 | "min_via_diameter": 0.39999999999999997, 117 | "solder_mask_clearance": 0.0, 118 | "solder_mask_min_width": 0.0, 119 | "use_height_for_length_calcs": true 120 | }, 121 | "track_widths": [ 122 | 0.0, 123 | 0.6 124 | ], 125 | "via_dimensions": [ 126 | { 127 | "diameter": 0.0, 128 | "drill": 0.0 129 | } 130 | ], 131 | "zones_allow_external_fillets": false, 132 | "zones_use_no_outline": true 133 | }, 134 | "layer_presets": [] 135 | }, 136 | "boards": [], 137 | "cvpcb": { 138 | "equivalence_files": [] 139 | }, 140 | "erc": { 141 | "erc_exclusions": [], 142 | "meta": { 143 | "version": 0 144 | }, 145 | "pin_map": [ 146 | [ 147 | 0, 148 | 0, 149 | 0, 150 | 0, 151 | 0, 152 | 0, 153 | 1, 154 | 0, 155 | 0, 156 | 0, 157 | 0, 158 | 2 159 | ], 160 | [ 161 | 0, 162 | 2, 163 | 0, 164 | 1, 165 | 0, 166 | 0, 167 | 1, 168 | 0, 169 | 2, 170 | 2, 171 | 2, 172 | 2 173 | ], 174 | [ 175 | 0, 176 | 0, 177 | 0, 178 | 0, 179 | 0, 180 | 0, 181 | 1, 182 | 0, 183 | 1, 184 | 0, 185 | 1, 186 | 2 187 | ], 188 | [ 189 | 0, 190 | 1, 191 | 0, 192 | 0, 193 | 0, 194 | 0, 195 | 1, 196 | 1, 197 | 2, 198 | 1, 199 | 1, 200 | 2 201 | ], 202 | [ 203 | 0, 204 | 0, 205 | 0, 206 | 0, 207 | 0, 208 | 0, 209 | 1, 210 | 0, 211 | 0, 212 | 0, 213 | 0, 214 | 2 215 | ], 216 | [ 217 | 0, 218 | 0, 219 | 0, 220 | 0, 221 | 0, 222 | 0, 223 | 0, 224 | 0, 225 | 0, 226 | 0, 227 | 0, 228 | 2 229 | ], 230 | [ 231 | 1, 232 | 1, 233 | 1, 234 | 1, 235 | 1, 236 | 0, 237 | 1, 238 | 1, 239 | 1, 240 | 1, 241 | 1, 242 | 2 243 | ], 244 | [ 245 | 0, 246 | 0, 247 | 0, 248 | 1, 249 | 0, 250 | 0, 251 | 1, 252 | 0, 253 | 0, 254 | 0, 255 | 0, 256 | 2 257 | ], 258 | [ 259 | 0, 260 | 2, 261 | 1, 262 | 2, 263 | 0, 264 | 0, 265 | 1, 266 | 0, 267 | 2, 268 | 2, 269 | 2, 270 | 2 271 | ], 272 | [ 273 | 0, 274 | 2, 275 | 0, 276 | 1, 277 | 0, 278 | 0, 279 | 1, 280 | 0, 281 | 2, 282 | 0, 283 | 0, 284 | 2 285 | ], 286 | [ 287 | 0, 288 | 2, 289 | 1, 290 | 1, 291 | 0, 292 | 0, 293 | 1, 294 | 0, 295 | 2, 296 | 0, 297 | 0, 298 | 2 299 | ], 300 | [ 301 | 2, 302 | 2, 303 | 2, 304 | 2, 305 | 2, 306 | 2, 307 | 2, 308 | 2, 309 | 2, 310 | 2, 311 | 2, 312 | 2 313 | ] 314 | ], 315 | "rule_severities": { 316 | "bus_definition_conflict": "error", 317 | "bus_entry_needed": "error", 318 | "bus_label_syntax": "error", 319 | "bus_to_bus_conflict": "error", 320 | "bus_to_net_conflict": "error", 321 | "different_unit_footprint": "error", 322 | "different_unit_net": "error", 323 | "duplicate_reference": "error", 324 | "duplicate_sheet_names": "error", 325 | "extra_units": "error", 326 | "global_label_dangling": "warning", 327 | "hier_label_mismatch": "error", 328 | "label_dangling": "error", 329 | "lib_symbol_issues": "warning", 330 | "multiple_net_names": "warning", 331 | "net_not_bus_member": "warning", 332 | "no_connect_connected": "warning", 333 | "no_connect_dangling": "warning", 334 | "pin_not_connected": "error", 335 | "pin_not_driven": "error", 336 | "pin_to_pin": "warning", 337 | "power_pin_not_driven": "error", 338 | "similar_labels": "warning", 339 | "unannotated": "error", 340 | "unit_value_mismatch": "error", 341 | "unresolved_variable": "error", 342 | "wire_dangling": "error" 343 | } 344 | }, 345 | "libraries": { 346 | "pinned_footprint_libs": [], 347 | "pinned_symbol_libs": [] 348 | }, 349 | "meta": { 350 | "filename": "fg06-c3dev-revb.kicad_pro", 351 | "version": 1 352 | }, 353 | "net_settings": { 354 | "classes": [ 355 | { 356 | "bus_width": 12.0, 357 | "clearance": 0.2, 358 | "diff_pair_gap": 0.25, 359 | "diff_pair_via_gap": 0.25, 360 | "diff_pair_width": 0.2, 361 | "line_style": 0, 362 | "microvia_diameter": 0.3, 363 | "microvia_drill": 0.1, 364 | "name": "Default", 365 | "pcb_color": "rgba(0, 0, 0, 0.000)", 366 | "schematic_color": "rgba(0, 0, 0, 0.000)", 367 | "track_width": 0.25, 368 | "via_diameter": 0.8, 369 | "via_drill": 0.4, 370 | "wire_width": 6.0 371 | } 372 | ], 373 | "meta": { 374 | "version": 2 375 | }, 376 | "net_colors": null 377 | }, 378 | "pcbnew": { 379 | "last_paths": { 380 | "gencad": "", 381 | "idf": "", 382 | "netlist": "", 383 | "specctra_dsn": "../../../../toolchain/freerouting/fg06-c3dev-revb.dsn", 384 | "step": "", 385 | "vrml": "" 386 | }, 387 | "page_layout_descr_file": "" 388 | }, 389 | "schematic": { 390 | "annotate_start_num": 0, 391 | "drawing": { 392 | "default_line_thickness": 6.0, 393 | "default_text_size": 50.0, 394 | "field_names": [], 395 | "intersheets_ref_own_page": false, 396 | "intersheets_ref_prefix": "", 397 | "intersheets_ref_short": false, 398 | "intersheets_ref_show": false, 399 | "intersheets_ref_suffix": "", 400 | "junction_size_choice": 3, 401 | "label_size_ratio": 0.375, 402 | "pin_symbol_size": 25.0, 403 | "text_offset_ratio": 0.15 404 | }, 405 | "legacy_lib_dir": "", 406 | "legacy_lib_list": [], 407 | "meta": { 408 | "version": 1 409 | }, 410 | "net_format_name": "", 411 | "ngspice": { 412 | "fix_include_paths": true, 413 | "fix_passive_vals": false, 414 | "meta": { 415 | "version": 0 416 | }, 417 | "model_mode": 0, 418 | "workbook_filename": "" 419 | }, 420 | "page_layout_descr_file": "", 421 | "plot_directory": "", 422 | "spice_adjust_passive_values": false, 423 | "spice_external_command": "spice \"%I\"", 424 | "subpart_first_id": 65, 425 | "subpart_id_separator": 0 426 | }, 427 | "sheets": [ 428 | [ 429 | "d4a2a404-6cd6-440d-9181-9193c7bace18", 430 | "" 431 | ] 432 | ], 433 | "text_variables": {} 434 | } 435 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # m5stamp-c3dev 2 | 3 | ![](https://github.com/h1romas4/m5stamp-c3dev/workflows/Build/badge.svg) 4 | 5 | ![Main Board](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_01.jpg) 6 | 7 | This is a development board for the [M5Stamp C3](https://shop.m5stack.com/products/m5stamp-c3-mate-with-pin-headers) (RISC-V/FreeRTOS). 8 | 9 | **Hardware** 10 | 11 | - External USB-C port for JTAG debugging 12 | - Support for LCD panel and SD card 13 | - Selecting a power supply 14 | - Switch(GPIO9) to enter loader mode 15 | - Pin headers to expose usable GPIOs to the outside 16 | - The size is just Japanese business card 17 | 18 | **Sample Sources Included** 19 | 20 | ![AssemblyScript and Wasm3](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_04.jpg) 21 | 22 | ![AssemblyScript and Wasm3](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_05.jpg) 23 | 24 | - TrueType font with Japanese output to LCD - [test_freetype.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_freetype.cpp) 25 | - Output PNG images in SD card to LCD - [test_tinypng.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_tinypng.cpp) 26 | - NTP synchronization via WiFi connection - [test_nvs_wifi.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_nvs_wifi.cpp) 27 | - Test ADC on GPIO0 28 | - UNIT Light - [main.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/main.cpp#L108-L111) 29 | - Test I2C on GPIO18, 19 30 | - UNIT ENV III - [test_i2c_gpio1819.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_i2c_gpio1819.cpp#L43-L50) 31 | - UNIT ULTRASONIC - [test_i2c_gpio1819.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_i2c_gpio1819.cpp#L52-L61) 32 | - Test UART on GPIO18, 19 33 | - UNIT GPS - [test_uart_gpio1819.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_uart_gpio1819.cpp) 34 | - WebAssembly execution with Wasm3 35 | - Analog clock using AssemblyScript - [test_wasm3_clockenv.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_wasm3_clockenv.cpp) 36 | - GPS GSV viewer using AssemblyScript - [test_wasm3_gpsgsv.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_wasm3_gpsgsv.cpp) 37 | - 3D Cube Demo using AssemblyScript - [test_wasm3_imu6886.cpp](https://github.com/h1romas4/m5stamp-c3dev/blob/main/main/test_wasm3_imu6886.cpp) 38 | - Usage of SPIFFS, which stores TrueType fonts and .wasm binaries (parttool.py and spiffsgen.py tools) 39 | - Use of NVS (cryptographically enabled key value store) that stores WiFi passwords (nvs_partition_gen.py tool) 40 | - Building libraries and managing dependencies using the esp-idf build system 41 | - Visual Studio Code C/C++ Extension configuration and JTAG debugging configuration in conjunction with openocd 42 | - AssembyScript sharing method between web browser and microcontroller - [wasm](https://github.com/h1romas4/m5stamp-c3dev/tree/main/wasm) 43 | 44 | This repository contains MIT Licensed PCB data and example programs. 45 | 46 | ## Demo 47 | 48 | ### Video 49 | 50 | - 📼 [Demo(LCD)](https://youtu.be/46I3Uo5Xivg) 51 | - 📼 [Demo(Wasm3)](https://youtu.be/TagQuPtwKCg) 52 | - 📼 [Demo(3D Cube)](https://twitter.com/h1romas4/status/1610228824607985664) 53 | 54 | ### Web Simulation 55 | 56 | - 🕸 [AssemblyScript Analog Clock](https://h1romas4.github.io/m5stamp-c3dev/asclock/) 57 | - 🕸 [AssemblyScript GPS GSV Viewer](https://h1romas4.github.io/m5stamp-c3dev/asgps/) 58 | 59 | ## Schematic 60 | 61 | ![Circuit Diagram](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/circuit_diagram_01.png) 62 | 63 | |#Unit|Name|Note|Where to get it| 64 | |----|----|----|----| 65 | |U1|AE-USB2.0-TYPE-C|USB 2.0 Type-C Break out board|[akizukidenshi.com (JP)](https://akizukidenshi.com/catalog/g/gK-13080/)| 66 | |U2|M5STAMP-C3|M5Stamp C3|+ [M5Stack](https://shop.m5stack.com/products/m5stamp-c3-mate-with-pin-headers?variant=40724631257260)
+ [SWITCH SCIENCE (JP)](https://www.switch-science.com/catalog/7474/)| 67 | |U3|KMR-1.8SPI|KMR-1.8 SPI marked LCD and SD card interface|+ [amazon.co.jp (1)](https://www.amazon.co.jp/gp/product/B07RG8SJVB/)
+ [ja.aliexpress.com](https://ja.aliexpress.com/item/4000511275898.html)| 68 | |R1 - R2|5.2K Resistor|Pull-down for USB Power supply|-| 69 | |R3 - R7|10K Resistor|SPI pull-up|-| 70 | |JP1|Jumper pin|Select external power supply|[akizukidenshi.com (JP)](https://akizukidenshi.com/catalog/g/gP-03687/)| 71 | |SW1|Tact switch|for loader mode and utility|[akizukidenshi.com (JP)](https://akizukidenshi.com/catalog/g/gP-03647/)| 72 | |J1|12 Pin header|You can use the one that comes with the M5Stamp C3 Mate|-| 73 | 74 | ## PCB and Gerber data 75 | 76 | - [KiCad 6 PCB](https://github.com/h1romas4/m5stamp-c3dev/tree/main/pcb/fg06-c3dev-revb) 77 | - [Gerber Data](https://github.com/h1romas4/m5stamp-c3dev/raw/main/pcb/fg06-c3dev-revb/fg06-c3dev-revb-gerber.zip) 78 | - [FG06-C3DEV REV.B (2枚) - M5Stamp C3 向けの開発用基板 - 部品なし基板のみ - 130円](https://h1romas4.booth.pm/items/3688492) 79 | 80 | ## Example Source 81 | 82 | ### Require 83 | 84 | - [Setup ESF-IDF **release/v5.1**](https://docs.espressif.com/projects/esp-idf/en/release-v5.1/esp32c3/get-started/linux-macos-setup.html) 85 | 86 | get_idf or (Windows) ESP-IDF command prompt 87 | 88 | ``` 89 | # Linux or macOS -> 90 | $ alias get_idf='. $HOME/esp/esp-idf/export.sh' 91 | $ get_idf 92 | # <- 93 | 94 | Detecting the Python interpreter 95 | ... snip ... 96 | Done! You can now compile ESP-IDF projects. 97 | Go to the project directory and run: 98 | 99 | idf.py build 100 | 101 | $ echo ${IDF_PATH} 102 | /home/hiromasa/devel/toolchain/esp/esp-idf 103 | 104 | $ riscv32-esp-elf-gcc -v 105 | Using built-in specs. 106 | COLLECT_GCC=riscv32-esp-elf-gcc 107 | ... snip ... 108 | gcc version 12.2.0 (crosstool-NG esp-12.2.0_20230208) 109 | ``` 110 | 111 | openocd (Optional) 112 | 113 | ``` 114 | $ openocd -v 115 | Open On-Chip Debugger v0.12.0-esp32-20240318 (2024-03-18-18:25) 116 | Licensed under GNU GPL v2 117 | For bug reports, read 118 | http://openocd.org/doc/doxygen/bugs.html 119 | ``` 120 | 121 | ### Build and Execute 122 | 123 | 1. git clone and build (Please add `--recursive`) 124 | 125 | ``` 126 | git clone --recursive https://github.com/h1romas4/m5stamp-c3dev 127 | cd m5stamp-c3dev 128 | idf.py build 129 | ``` 130 | 131 | **Note**: If you get a compile error, change the `sdkconfig` back to the Git one. In some cases, the target of `sdkconfig` is changed to `esp32` instead of `eps32c3`. 132 | 133 | 2. Write Partition table 134 | 135 | ``` 136 | idf.py partition-table-flash 137 | ``` 138 | 139 | 3. Write TypeType font to SPIFFS 140 | 141 | ``` 142 | parttool.py write_partition --partition-name=font --partition-subtype=spiffs --input resources/spiffs_font.bin 143 | ``` 144 | 145 | 4. Write WebAssembly(.wasm) to SPIFFS 146 | 147 | ``` 148 | parttool.py write_partition --partition-name=wasm --partition-subtype=spiffs --input resources/spiffs_wasm.bin 149 | ``` 150 | 151 | 5. Write main program to go! 152 | 153 | ``` 154 | idf.py flash monitor 155 | ``` 156 | 157 | ### Setup WiFi (Optional) 158 | 159 | 1. Change WiFi Setting 160 | 161 | `nvs_partition.csv`: Set own `[ssid]`, `[password]` 162 | 163 | ``` 164 | key,type,encoding,value 165 | wifi,namespace,, 166 | ssid,data,string,[ssid] 167 | passwd,data,string,[password] 168 | ``` 169 | 170 | 2. Create NVS Partition file 171 | 172 | ``` 173 | python ${IDF_PATH}/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py generate nvs_partition.csv nvs_partition.bin 0x6000 174 | ``` 175 | 176 | 3. Write NVS Partition 177 | 178 | ``` 179 | esptool.py write_flash 0x9000 nvs_partition.bin 180 | ``` 181 | 182 | 4. Run 183 | 184 | NTP synchronization is performed by pressing the SW1 after the startup logo. 185 | 186 | ``` 187 | idf.py monitor 188 | ``` 189 | 190 | ### Select connected GPIO18 and GPIO19 device (Optional) 191 | 192 | ``` 193 | idf.py menuconfig 194 | ``` 195 | 196 | C3DEV Configuration → Select GPIO 18/19 197 | 198 | ![](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_05.png) 199 | 200 | `3D Cube Demo` 201 | 202 | ![3D Cube](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_06.jpg) 203 | 204 | ### JTAG debug with Visual Studio Code 205 | 206 | Require setup ESP32_TOOLCHAIN_HOME 207 | 208 | ``` 209 | $ echo ${ESP32_TOOLCHAIN_HOME} 210 | /home/hiromasa/.espressif/tools/riscv32-esp-elf 211 | ``` 212 | 213 | 1. Connect the PC to the USB Type-C of the U1 214 | 2. Open the source file in Visual Studio Code. 215 | 3. Run Task "openocd (debug)" @see [.vscode/tasks.json](https://github.com/h1romas4/m5stamp-c3dev/blob/main/.vscode/tasks.json#L7-L13) 216 | 4. Set a breakpoint in the source code. 217 | 5. Debug Launch (GDB) @see [.vscode/launch.json](https://github.com/h1romas4/m5stamp-c3dev/blob/main/.vscode/launch.json#L8-L23) 218 | The first time you start the program, it will often fail, so if you get an error, retry. 219 | 220 | ![vscode](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_02.png) 221 | 222 | ### Note 223 | 224 | #### If the LCD color is inverted. 225 | 226 | `main/main.cpp` 227 | 228 | ```c 229 | // If the color is inverted, set to 1. 230 | tft.invertDisplay(0); 231 | // tft.invertDisplay(1); 232 | ``` 233 | 234 | #### Create SPIFFS partition file from file system 235 | 236 | ``` 237 | python ${IDF_PATH}/components/spiffs/spiffsgen.py 0x100000 resources/font resources/spiffs_font.bin 238 | python ${IDF_PATH}/components/spiffs/spiffsgen.py 0x10000 resources/wasm resources/spiffs_wasm.bin 239 | ``` 240 | 241 | #### Change the output destination of the log to U1 Serial/JTAG.(Don't forget to put it back) 242 | 243 | Component config → ESP System Settings → Channel for console output 244 | 245 | ``` 246 | idf.py menuconfig 247 | ``` 248 | 249 | ![vscode](https://raw.githubusercontent.com/h1romas4/m5stamp-c3dev/main/docs/images/m5stamp_c3dev_03.png) 250 | 251 | ## AssemblyScript and Wasm3 252 | 253 | ## Build AssemblyScript 254 | 255 | ``` 256 | cd wasm/clockenv # or wasm/gpsgsv or wasm/imu6886 257 | npm install 258 | ``` 259 | 260 | **Web Browser Development** 261 | 262 | ``` 263 | npm run asbuild:web 264 | npm run start 265 | # http://localhost:1234/ 266 | ``` 267 | 268 | **SPIFFS Build and Flash** 269 | 270 | ``` 271 | npm run asbuild 272 | cd ../../ 273 | python ${IDF_PATH}/components/spiffs/spiffsgen.py 0x10000 resources/wasm resources/spiffs_wasm.bin 274 | parttool.py write_partition --partition-name=wasm --partition-subtype=spiffs --input resources/spiffs_wasm.bin 275 | ``` 276 | 277 | ## Dependencies 278 | 279 | Thanks for all the open source. 280 | 281 | |Name|Version|License| 282 | |-|-|--| 283 | |[esp-idf](https://docs.espressif.com/projects/esp-idf/en/release-v5.1/esp32c3/get-started/index.html)|`release/v5.1`|BSD License| 284 | |[arduino-esp32](https://github.com/espressif/arduino-esp32/releases/tag/3.0.2)|`3.0.2`|LGPL-2.1 License| 285 | |[M5EPD](https://github.com/m5stack/M5EPD)|`0.1.5`|MIT License| 286 | |[UNIT_ENV](https://github.com/m5stack/UNIT_ENV)|`0.0.7`|MIT License| 287 | |[M5Unit-Sonic](https://github.com/m5stack/M5Unit-Sonic)|`0.0.2`|MIT License| 288 | |[Adafruit_GFX](https://github.com/adafruit/Adafruit-GFX-Library)|`1.11.9`|BSD License| 289 | |[Adafruit_BusIO](https://github.com/adafruit/Adafruit_BusIO)|`1.16.1`|MIT License| 290 | |[Adafruit-ST7735-Library](https://github.com/adafruit/Adafruit-ST7735-Library)|`1.10.4`|MIT License| 291 | |[tinyPNG](https://github.com/olliiiver/tinyPNG)|`0.11`|MIT License| 292 | |[lwgps](https://github.com/MaJerle/lwgps)|`v2.1.0`|MIT License| 293 | |[Wasm3](https://github.com/wasm3/wasm3)|master(`045040a9`)|MIT License| 294 | |[AssemblyScript](https://github.com/AssemblyScript/assemblyscript)|`0.27.29`|Apache-2.0 License| 295 | |[源真ゴシック](http://jikasei.me/font/genshin/)|-|SIL Open Font License 1.1| 296 | 297 | ## License 298 | 299 | MIT License (includes PCB data and example source) 300 | -------------------------------------------------------------------------------- /main/test_wasm3_gpsgsv.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "SPIFFS.h" 3 | #include "esp_log.h" 4 | #include "esp_err.h" 5 | #include "esp_heap_caps.h" 6 | #include 7 | 8 | #include "wasm3.h" 9 | #include "m3_env.h" 10 | #include "m3_api_libc.h" 11 | 12 | #include "c3dev_board.h" 13 | #include "test_freetype.h" 14 | #include "test_uart_gpio1819.h" 15 | 16 | static const char *TAG = "test_wasm3_gpsgsv.cpp"; 17 | 18 | /** 19 | * Wasm3 member 20 | */ 21 | IM3Environment wasm3_env; 22 | IM3Runtime wasm3_runtime; 23 | IM3Module wasm3_module; 24 | 25 | IM3Function wasm3_func_create_satellites_array; 26 | IM3Function wasm3_func_set_satellites; 27 | IM3Function wasm3_func_set_gsv; 28 | IM3Function wasm3_func_tick; 29 | IM3Function wasm3_func_pin; 30 | IM3Function wasm3_func_unpin; 31 | IM3Function wasm3_func_collect; 32 | 33 | uint8_t *wasm_mem; 34 | 35 | #define WASM3_STACK_SIZE 16384 36 | #define FREETYPE_FONT_SIZE 9 37 | 38 | /** 39 | * Unit GPS member 40 | */ 41 | #define MAX_SATELLITE 12 42 | unitgpsgsv_t unitgpsgsv[MAX_SATELLITE]; 43 | uint32_t wasm_satellites_ptr; 44 | uint32_t wasm_satellites_real; 45 | 46 | /** 47 | * SPIFFS member 48 | */ 49 | fs::SPIFFSFS SPIFFS_WASM; 50 | 51 | /** 52 | * FreeType member 53 | */ 54 | font_render_t wasm_font_render; 55 | 56 | /** 57 | * as_gc_unpin_ptr 58 | * 59 | * ex. as_gc_unpin_ptr(m3ApiPtrToOffset(string_ptr)); 60 | */ 61 | void as_gc_unpin_ptr(uint32_t wasm_prt) 62 | { 63 | M3Result result = m3Err_none; 64 | 65 | char str_32bit[11]; 66 | 67 | sprintf(str_32bit, "%ld", wasm_prt); 68 | ESP_LOGI(TAG, "as_gc_unpin_ptr: %s", str_32bit); 69 | 70 | const char* i_argv[1] = { str_32bit }; 71 | result = m3_CallArgv(wasm3_func_unpin, 1, i_argv); 72 | if (result) { 73 | ESP_LOGE(TAG, "m3_Call:as_gc_unpin_ptr: %s", result); 74 | } 75 | } 76 | 77 | /** 78 | * as_gc_collect. 79 | */ 80 | void as_gc_collect(void) 81 | { 82 | M3Result result = m3Err_none; 83 | 84 | result = m3_Call(wasm3_func_collect, 0, nullptr); 85 | if (result) { 86 | ESP_LOGE(TAG, "m3_Call:as_gc_collect: %s", result); 87 | } 88 | } 89 | 90 | // (import "env" "seed" (func $env.seed (type $t3))) 91 | // (type $t3 (func (result f64))) 92 | m3ApiRawFunction(c3dev_random) { 93 | m3ApiReturnType(float_t) // 32bit 94 | m3ApiReturn(esp_random()); // uint32_t */ 95 | } 96 | 97 | // (import "env" "abort" (func $env.abort (type $t0))) 98 | // (type $t0 (func (param i32 i32 i32 i32))) 99 | m3ApiRawFunction(c3dev_abort) 100 | { 101 | m3ApiGetArgMem(char16_t *, message) 102 | m3ApiGetArgMem(char16_t *, fileName) 103 | m3ApiGetArg(int32_t, lineNumber) 104 | m3ApiGetArg(int32_t, columnNumber) 105 | 106 | // ESP_LOGE(TAG, "c3dev_abort: %ls %ls %d %d", message, fileName, lineNumber, columnNumber); 107 | 108 | m3ApiSuccess(); 109 | } 110 | 111 | m3ApiRawFunction(c3dev_now) 112 | { 113 | m3ApiReturnType(int64_t) 114 | 115 | struct timeval tv_now; 116 | gettimeofday(&tv_now, NULL); 117 | int64_t time_ms = (int64_t)tv_now.tv_sec * 1000L + /* UTC+9 */ 3600000 * 9; 118 | // ESP_LOGI(TAG, "c3dev_now: %d", time_ms); 119 | 120 | m3ApiReturn(time_ms); 121 | } 122 | 123 | m3ApiRawFunction(c3dev_delay) { 124 | m3ApiGetArg(int32_t, wait) 125 | 126 | delay(wait); 127 | 128 | m3ApiSuccess(); 129 | } 130 | 131 | m3ApiRawFunction(c3dev_draw_pixel) 132 | { 133 | m3ApiGetArg(int32_t, x) 134 | m3ApiGetArg(int32_t, y) 135 | m3ApiGetArg(int32_t, color) 136 | 137 | tft.drawPixel(x, y, color); 138 | 139 | m3ApiSuccess(); 140 | } 141 | 142 | m3ApiRawFunction(c3dev_draw_line) 143 | { 144 | m3ApiGetArg(int32_t, x0) 145 | m3ApiGetArg(int32_t, y0) 146 | m3ApiGetArg(int32_t, x1) 147 | m3ApiGetArg(int32_t, y1) 148 | m3ApiGetArg(int32_t, color) 149 | 150 | tft.drawLine(x0, y0, x1, y1, color); 151 | 152 | m3ApiSuccess(); 153 | } 154 | 155 | m3ApiRawFunction(c3dev_log) 156 | { 157 | m3ApiGetArgMem(char *, utf8_null_terminated_string) 158 | 159 | ESP_LOGI(TAG, "c3dev_log: %s", utf8_null_terminated_string); 160 | 161 | m3ApiSuccess(); 162 | } 163 | 164 | m3ApiRawFunction(c3dev_draw_string) 165 | { 166 | m3ApiGetArg(int32_t, x) 167 | m3ApiGetArg(int32_t, y) 168 | m3ApiGetArg(int32_t, color) 169 | m3ApiGetArgMem(char *, utf8_null_terminated_string) 170 | 171 | draw_freetype_string(utf8_null_terminated_string, x, y + FREETYPE_FONT_SIZE, color, &wasm_font_render); 172 | // ESP_LOGI(TAG, "draw_freetype_string(%d, %d, %d, %s)", x, y, color, utf8_null_terminated_string); 173 | 174 | m3ApiSuccess(); 175 | } 176 | 177 | M3Result link_c3dev(IM3Runtime runtime) { 178 | IM3Module module = runtime->modules; 179 | 180 | m3_LinkRawFunction(module, "env", "seed", "F()", &c3dev_random); 181 | m3_LinkRawFunction(module, "env", "abort", "v(**ii)", &c3dev_abort); 182 | m3_LinkRawFunction(module, "c3dev", "now", "I()", &c3dev_now); 183 | m3_LinkRawFunction(module, "c3dev", "delay", "v(i)", &c3dev_delay); 184 | m3_LinkRawFunction(module, "c3dev", "draw_pixel", "v(iii)", &c3dev_draw_pixel); 185 | m3_LinkRawFunction(module, "c3dev", "draw_line", "v(iiiii)", &c3dev_draw_line); 186 | m3_LinkRawFunction(module, "c3dev", "draw_string", "v(iii*)", &c3dev_draw_string); 187 | m3_LinkRawFunction(module, "c3dev", "log", "v(*)", &c3dev_log); 188 | 189 | return m3Err_none; 190 | } 191 | 192 | esp_err_t load_wasm(uint8_t *wasm_binary, size_t wasm_size) 193 | { 194 | M3Result result = m3Err_none; 195 | 196 | ESP_LOGI(TAG, "heap_caps_get_free_size: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT)); 197 | 198 | ESP_LOGI(TAG, "Loading WebAssembly..."); 199 | wasm3_env = m3_NewEnvironment(); 200 | if (!wasm3_env) { 201 | ESP_LOGE(TAG, "m3_NewEnvironment failed"); 202 | return ESP_FAIL; 203 | } 204 | 205 | wasm3_runtime = m3_NewRuntime(wasm3_env, WASM3_STACK_SIZE, NULL); 206 | if (!wasm3_runtime) { 207 | ESP_LOGE(TAG, "m3_NewRuntime failed"); 208 | return ESP_FAIL; 209 | } 210 | 211 | result = m3_ParseModule(wasm3_env, &wasm3_module, wasm_binary, wasm_size); 212 | if (result) { 213 | ESP_LOGE(TAG, "m3_ParseModule: %s", result); 214 | return ESP_FAIL; 215 | } 216 | 217 | result = m3_LoadModule(wasm3_runtime, wasm3_module); 218 | if (result) { 219 | ESP_LOGE(TAG, "m3_LoadModule: %s", result); 220 | return ESP_FAIL; 221 | } 222 | 223 | // link c3dev function 224 | result = link_c3dev(wasm3_runtime); 225 | if (result) { 226 | ESP_LOGE(TAG, "link_c3dev: %s", result); 227 | return ESP_FAIL; 228 | } 229 | 230 | ESP_LOGI(TAG, "Running..."); 231 | 232 | // Get AssemblyScript GC interface 233 | result = m3_FindFunction(&wasm3_func_unpin, wasm3_runtime, "__unpin"); 234 | if (result) { 235 | ESP_LOGE(TAG, "m3_FindFunction:wasm3_func_unpin: %s", result); 236 | return ESP_FAIL; 237 | } 238 | result = m3_FindFunction(&wasm3_func_pin, wasm3_runtime, "__pin"); 239 | if (result) { 240 | ESP_LOGE(TAG, "m3_FindFunction:wasm3_func_pin: %s", result); 241 | return ESP_FAIL; 242 | } 243 | result = m3_FindFunction(&wasm3_func_collect, wasm3_runtime, "__collect"); 244 | if (result) { 245 | ESP_LOGE(TAG, "m3_FindFunction:wasm3_func_collect: %s", result); 246 | return ESP_FAIL; 247 | } 248 | 249 | // Draw Clock 250 | IM3Function gpsgsv; 251 | result = m3_FindFunction(&gpsgsv, wasm3_runtime, "gpsgsv"); 252 | if (result) { 253 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 254 | return ESP_FAIL; 255 | } 256 | // export function gpsgsv(x: u32, y: u32, r: u32): void; 257 | const char* i_argv[4] = { "80", "64", "63" }; 258 | result = m3_CallArgv(gpsgsv, 3, i_argv); 259 | if (result) { 260 | ESP_LOGE(TAG, "m3_Call: %s", result); 261 | return ESP_FAIL; 262 | } 263 | 264 | // Get AS function 265 | result = m3_FindFunction(&wasm3_func_tick, wasm3_runtime, "tick"); 266 | if (result) { 267 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 268 | return ESP_FAIL; 269 | } 270 | result = m3_FindFunction(&wasm3_func_create_satellites_array, wasm3_runtime, "createSatellitesArray"); 271 | if (result) { 272 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 273 | return ESP_FAIL; 274 | } 275 | result = m3_FindFunction(&wasm3_func_set_satellites, wasm3_runtime, "setSatellites"); 276 | if (result) { 277 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 278 | return ESP_FAIL; 279 | } 280 | result = m3_FindFunction(&wasm3_func_set_gsv, wasm3_runtime, "setGsv"); 281 | if (result) { 282 | ESP_LOGE(TAG, "m3_FindFunction: %s", result); 283 | return ESP_FAIL; 284 | } 285 | 286 | ESP_LOGI(TAG, "Wasm3 Initialized"); 287 | ESP_LOGI(TAG, "heap_caps_get_free_size: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT)); 288 | 289 | return ESP_OK; 290 | } 291 | 292 | esp_err_t gpsgsv_init_wasm(void) 293 | { 294 | SPIFFS_WASM.begin(false, "/wasm", 4, "wasm"); 295 | 296 | File wasm_file = SPIFFS_WASM.open("/gpsgsv.wasm", "rb"); 297 | size_t wasm_size = wasm_file.size(); 298 | 299 | ESP_LOGI(TAG, "gpsgsv.wasm: %d", wasm_size); 300 | // Read .wasm 301 | uint8_t *wasm_binary = (uint8_t *)malloc(sizeof(uint8_t) * wasm_size); 302 | if(wasm_binary == nullptr) { 303 | ESP_LOGE(TAG, "Memory alloc error"); 304 | return ESP_FAIL; 305 | } 306 | if(wasm_file.read(wasm_binary, wasm_size) != wasm_size) { 307 | ESP_LOGE(TAG, "SPIFFS read error"); 308 | return ESP_FAIL; 309 | } 310 | 311 | wasm_file.close(); 312 | SPIFFS_WASM.end(); 313 | 314 | // Setup Font render 315 | wasm_font_render = create_freetype_render(FREETYPE_FONT_SIZE, /* font cache */ 64); 316 | // Clear LCD 317 | tft.fillScreen(ST77XX_BLACK); 318 | 319 | // Load WebAssembly on Wasm3 320 | if(load_wasm(wasm_binary, wasm_size) != ESP_OK) { 321 | return ESP_FAIL; 322 | } 323 | 324 | // initialize GPS member 325 | memset(unitgpsgsv, 0, sizeof(unitgpsgsv_t) * 12); 326 | 327 | // Create Array memory 328 | M3Result result = m3Err_none; 329 | uint32_t p0 = 0; 330 | result = m3_Call(wasm3_func_create_satellites_array, 0, nullptr); 331 | if (result) { 332 | ESP_LOGE(TAG, "m3_Call: %s", result); 333 | return ESP_FAIL; 334 | } 335 | result = m3_GetResultsV(wasm3_func_create_satellites_array, &p0); 336 | if (result) { 337 | ESP_LOGE(TAG, "m3_GetResultsV: %s", result); 338 | return ESP_FAIL; 339 | } 340 | // Pined 341 | uint32_t *i_argv[2] = { &p0 }; 342 | wasm_satellites_ptr = 0; 343 | result = m3_Call(wasm3_func_pin, 1, (const void**)i_argv); 344 | if (result) { 345 | ESP_LOGE(TAG, "m3_Call: %s", result); 346 | return ESP_FAIL; 347 | } 348 | result = m3_GetResultsV(wasm3_func_pin, &wasm_satellites_ptr); 349 | if (result) { 350 | ESP_LOGE(TAG, "m3_GetResultsV: %s", result); 351 | return ESP_FAIL; 352 | } 353 | // Get memory pointer 354 | wasm_mem = m3_GetMemory(wasm3_runtime, 0, 0); 355 | wasm_satellites_real = wasm_mem[wasm_satellites_ptr + 0]; 356 | wasm_satellites_real += wasm_mem[wasm_satellites_ptr + 1] << 8; 357 | wasm_satellites_real += wasm_mem[wasm_satellites_ptr + 2] << 16; 358 | wasm_satellites_real += wasm_mem[wasm_satellites_ptr + 3] << 32; 359 | 360 | return ESP_OK; 361 | } 362 | 363 | esp_err_t gpsgsv_tick_wasm(bool clear) 364 | { 365 | // get GPS data 366 | get_uart_gpsgsv_data(unitgpsgsv, &wasm_mem[wasm_satellites_real]); 367 | 368 | M3Result result = m3Err_none; 369 | 370 | // set GSV 371 | for(uint32_t i = 0; i < MAX_SATELLITE; i++) { 372 | uint32_t num = unitgpsgsv[i].num; 373 | uint32_t elevation = unitgpsgsv[i].elevation; 374 | uint32_t azimuth = unitgpsgsv[i].azimuth; 375 | uint32_t snr = unitgpsgsv[i].snr; 376 | if(num == 0) continue; 377 | 378 | uint32_t *argv0[5] = { &num, &elevation, &azimuth, &snr }; 379 | result = m3_Call(wasm3_func_set_gsv, 4, (const void**)argv0); 380 | if (result) { 381 | ESP_LOGE(TAG, "m3_Call: %s", result); 382 | return ESP_FAIL; 383 | } 384 | } 385 | 386 | // set satellites 387 | uint32_t *argv1[2] = { &wasm_satellites_ptr }; 388 | result = m3_Call(wasm3_func_set_satellites, 1, (const void**)argv1); 389 | if (result) { 390 | ESP_LOGE(TAG, "m3_Call: %s", result); 391 | return ESP_FAIL; 392 | } 393 | 394 | // tick 395 | uint32_t boolean = 1; // clear ? 1: 0; 396 | uint32_t *argv2[2] = { &boolean }; 397 | result = m3_Call(wasm3_func_tick, 1, (const void**)argv2); 398 | if (result) { 399 | ESP_LOGE(TAG, "m3_Call: %s", result); 400 | return ESP_FAIL; 401 | } 402 | 403 | // GC by tick for AssemblyScript --runtime minimal 404 | as_gc_collect(); 405 | 406 | return ESP_OK; 407 | } 408 | -------------------------------------------------------------------------------- /resources/range.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | # Extracts and downsizes regular KANJI from Japanese fonts. 3 | # 漢字フォントから常用漢字を抽出してダウンサイズします。 4 | 5 | # Japanese Level1 Kanji(常用漢字の) UNICODE RANGE 6 | unicodes=U+0020,U+0041-005A,U+0020,U+0061-007A,U+0030-0039,U+002E,U+0020-002F,U+003A-0040,U+005B-0060,U+007B-007E,U+0020-002F,U+0030-0039,U+003A-0040,U+0041-005A,U+005B-0060,U+0061-007A,U+007B-007E,U+3000-303F,U+3041-309F,U+30A0-30FF,U+FF61-FF9F,U+00A7-00A8,U+00B0-00B1,U+00B4,U+00B6,U+00D7,U+00F7,U+2010,U+2015,U+2018-2019,U+201C-201D,U+2020-2021,U+2025-2026,U+2030,U+2032-2033,U+203B,U+2103,U+212B,U+2190-2193,U+21D2,U+21D4,U+2200,U+2202-2203,U+2207-2208,U+220B,U+221A,U+221D-221E,U+2220,U+2225,U+2227-222C,U+2234-2235,U+223D,U+2252,U+2260-2261,U+2266-2267,U+226A-226B,U+2282-2283,U+2286-2287,U+22A5,U+2312,U+25A0-25A1,U+25B2-25B3,U+25BC-25BD,U+25C6-25C7,U+25CB,U+25CE-25CF,U+25EF,U+2605-2606,U+2640,U+2642,U+266A,U+266D,U+266F,U+3000-3003,U+3005-3015,U+309B-309E,U+30FB-30FE,U+4E00-4E01,U+4E03,U+4E07-4E0B,U+4E0D-4E0E,U+4E11,U+4E14,U+4E16,U+4E18-4E19,U+4E1E,U+4E21,U+4E26,U+4E2D,U+4E32,U+4E38-4E39,U+4E3B,U+4E43,U+4E45,U+4E4B,U+4E4D-4E4F,U+4E57,U+4E59,U+4E5D-4E5F,U+4E71,U+4E73,U+4E7E,U+4E80,U+4E86,U+4E88-4E89,U+4E8B-4E8C,U+4E91-4E92,U+4E94-4E95,U+4E98-4E99,U+4E9B-4E9C,U+4EA1,U+4EA4-4EA6,U+4EA8,U+4EAB-4EAE,U+4EBA,U+4EC0-4EC1,U+4EC7,U+4ECA-4ECB,U+4ECF,U+4ED4-4ED6,U+4ED8-4ED9,U+4EDD,U+4EE3-4EE5,U+4EEE,U+4EF0,U+4EF2,U+4EF6,U+4EFB,U+4F01,U+4F0A,U+4F0D-4F11,U+4F1A,U+4F1D,U+4F2F,U+4F34,U+4F36,U+4F38,U+4F3A,U+4F3C-4F3D,U+4F43,U+4F46,U+4F4D-4F51,U+4F53,U+4F55,U+4F59,U+4F5C,U+4F73,U+4F75,U+4F7C,U+4F7F,U+4F83,U+4F8B,U+4F8D,U+4F9B,U+4F9D,U+4FA0-4FA1,U+4FAD-4FAF,U+4FB5-4FB6,U+4FBF,U+4FC2-4FC4,U+4FCA,U+4FD7,U+4FDD,U+4FE1,U+4FE3,U+4FEE,U+4FF3,U+4FF5,U+4FF8,U+4FFA,U+5009,U+500B,U+500D,U+5012,U+5016,U+5019,U+501F,U+5023-5024,U+5026,U+502B,U+502D,U+5036,U+5039,U+5049,U+504F,U+505C,U+5065,U+5072,U+5074-5076,U+507D,U+508D,U+5091,U+5098-5099,U+50AC-50AD,U+50B5,U+50B7,U+50BE,U+50C5,U+50CD,U+50CF,U+50D1,U+50D5,U+50DA,U+50E7,U+50FB,U+5100,U+5104,U+5112,U+511F,U+512A,U+5132,U+5141,U+5143-5149,U+514B,U+514D-514E,U+5150,U+515A,U+515C,U+5165,U+5168,U+516B-516D,U+5171,U+5175-5178,U+517C,U+5185-5186,U+518A,U+518D,U+5192,U+5197,U+5199,U+51A0,U+51A5,U+51A8,U+51AC,U+51B4,U+51B6-51B7,U+51C4,U+51C6,U+51CB-51CD,U+51DD,U+51E1,U+51E6-51E7,U+51EA,U+51F1,U+51F6,U+51F8-51FA,U+51FD,U+5200,U+5203,U+5206-5208,U+520A,U+5211,U+5217,U+521D,U+5224-5225,U+5229,U+5230,U+5236-5238,U+523A-523B,U+5243,U+5247,U+524A,U+524D,U+5256,U+525B,U+5263-5265,U+526F-5270,U+5272,U+5275,U+5283,U+5287,U+5289,U+529B,U+529F-52A0,U+52A3,U+52A9-52AB,U+52B1,U+52B4,U+52B9,U+52BE,U+52C3,U+52C5,U+52C7,U+52C9,U+52D5,U+52D8-52D9,U+52DD,U+52DF,U+52E2,U+52E4,U+52E7,U+52F2,U+52FA,U+52FE-52FF,U+5301-5302,U+5305,U+5316-5317,U+5319,U+531D,U+5320-5321,U+532A,U+5339-533B,U+533F,U+5341,U+5343,U+5347-5348,U+534A,U+5351-5354,U+5357-5358,U+535A,U+535C,U+5360,U+5366,U+536F-5371,U+5373-5375,U+5378,U+537F,U+5384,U+5398,U+539A,U+539F,U+53A8-53A9,U+53AD,U+53B3,U+53BB,U+53C2,U+53C8-53CE,U+53D4,U+53D6-53D7,U+53D9,U+53DB,U+53E1-53E5,U+53E9-53EC,U+53EF-53F3,U+53F6-53F8,U+5403-5404,U+5408-5411,U+541B,U+541F-5420,U+5426,U+542B,U+5438-5439,U+543B,U+543E,U+5442,U+5446,U+5448-544A,U+5451,U+5468,U+546A,U+5473,U+547C-547D,U+548B-548C,U+54B2-54B3,U+54BD,U+54C0-54C1,U+54C9,U+54E1,U+54E8-54E9,U+54F2,U+5504,U+5506-5507,U+5510,U+5516,U+552F,U+5531,U+553E,U+5544,U+5546,U+554F,U+5553,U+5584,U+5589,U+558B,U+559A,U+559C-559D,U+55A7,U+55AA-55AC,U+55B0,U+55B6,U+55E3,U+5606,U+5609,U+5617-5618,U+5629,U+5631,U+5642,U+564C,U+565B,U+5668,U+5674,U+5678,U+567A,U+5687,U+56A2,U+56DA-56DB,U+56DE,U+56E0,U+56E3,U+56F0,U+56F2-56F3,U+56FA,U+56FD,U+5703,U+570F,U+5712,U+571F,U+5727-5728,U+572D,U+5730,U+5742,U+5747,U+574A,U+5750-5751,U+5764,U+5766,U+576A,U+5782,U+578B,U+57A2-57A3,U+57CB,U+57CE,U+57DC,U+57DF-57E0,U+57F4,U+57F7,U+57F9-57FA,U+57FC,U+5800,U+5802,U+5805-5806,U+5815,U+5824,U+582A,U+5830-5831,U+5834-5835,U+583A,U+5840-5841,U+584A,U+5851,U+5854,U+5857-585A,U+585E,U+5869,U+586B,U+5875,U+587E,U+5883,U+5893,U+5897,U+589C,U+58A8,U+58B3,U+58BE,U+58C1,U+58C7,U+58CA,U+58CC,U+58D5,U+58EB-58EC,U+58EE,U+58F0-58F2,U+58F7,U+5909,U+590F,U+5915-5916,U+5919-591A,U+591C,U+5922,U+5927,U+5929-592B,U+592E,U+5931,U+5937,U+5944,U+5947-5949,U+594F,U+5951,U+5954,U+5957,U+5965,U+5968,U+596A,U+596E,U+5973-5974,U+597D,U+5982-5984,U+598A,U+5993,U+5996,U+5999,U+59A5,U+59A8,U+59AC,U+59B9,U+59BB,U+59BE,U+59C9,U+59CB,U+59D0-59D1,U+59D3-59D4,U+59E5-59E6,U+59EA-59EB,U+59F6,U+59FB,U+59FF,U+5A01,U+5A03,U+5A18,U+5A20,U+5A29,U+5A2F,U+5A3C,U+5A41,U+5A46,U+5A5A,U+5A66,U+5A7F,U+5A92,U+5A9B,U+5AC1,U+5AC9,U+5ACC,U+5AE1,U+5B09,U+5B22,U+5B2C,U+5B30,U+5B50,U+5B54,U+5B57-5B58,U+5B5C-5B5D,U+5B5F,U+5B63-5B64,U+5B66,U+5B6B,U+5B85,U+5B87-5B89,U+5B8B-5B8D,U+5B8F,U+5B95,U+5B97-5B9D,U+5B9F,U+5BA2-5BA5,U+5BAE,U+5BB0,U+5BB3-5BB6,U+5BB9,U+5BBF,U+5BC2,U+5BC4-5BC6,U+5BCC,U+5BD2-5BD3,U+5BDB,U+5BDD,U+5BDF,U+5BE1,U+5BE7,U+5BE9,U+5BEE,U+5BF5,U+5BF8,U+5BFA,U+5BFE-5BFF,U+5C01-5C02,U+5C04,U+5C06,U+5C09-5C0B,U+5C0E-5C0F,U+5C11,U+5C16,U+5C1A,U+5C24,U+5C2D,U+5C31,U+5C3A-5C40,U+5C45,U+5C48,U+5C4A-5C4B,U+5C4D,U+5C51,U+5C55,U+5C5E,U+5C60-5C61,U+5C64-5C65,U+5C6F,U+5C71,U+5C90,U+5CA1,U+5CA8-5CA9,U+5CAC,U+5CB1,U+5CB3,U+5CB8,U+5CE0-5CE1,U+5CE8,U+5CEF-5CF0,U+5CF6,U+5CFB,U+5D07,U+5D0E,U+5D16,U+5D29,U+5D50,U+5D69,U+5D6F,U+5D8B,U+5DBA,U+5DCC,U+5DDD-5DDE,U+5DE1,U+5DE3,U+5DE5-5DE8,U+5DEE,U+5DF1,U+5DF3-5DF4,U+5DF7,U+5DFB,U+5DFD-5DFE,U+5E02-5E03,U+5E06,U+5E0C,U+5E16,U+5E1D,U+5E25,U+5E2B,U+5E2D,U+5E2F-5E30,U+5E33,U+5E38,U+5E3D,U+5E45,U+5E4C,U+5E55,U+5E61,U+5E63,U+5E72-5E74,U+5E78-5E79,U+5E7B-5E7E,U+5E81,U+5E83-5E84,U+5E87,U+5E8A,U+5E8F,U+5E95-5E97,U+5E9A,U+5E9C,U+5EA6-5EA7,U+5EAB,U+5EAD,U+5EB5-5EB8,U+5EC3,U+5EC9-5ECA,U+5ED3,U+5EDF-5EE0,U+5EF6-5EF7,U+5EFA-5EFC,U+5EFF,U+5F01,U+5F04,U+5F0A,U+5F0F-5F10,U+5F13-5F15,U+5F17-5F18,U+5F1B,U+5F1F,U+5F25-5F27,U+5F31,U+5F35,U+5F37,U+5F3C,U+5F3E,U+5F4A,U+5F53,U+5F62,U+5F66,U+5F69-5F6C,U+5F70-5F71,U+5F79,U+5F7C,U+5F80-5F81,U+5F84-5F85,U+5F8B-5F8C,U+5F90,U+5F92-5F93,U+5F97,U+5FA1,U+5FA9-5FAA,U+5FAE,U+5FB3-5FB4,U+5FB9,U+5FBD,U+5FC3,U+5FC5,U+5FCC-5FCD,U+5FD7-5FD9,U+5FDC,U+5FE0,U+5FEB,U+5FF5,U+5FFD,U+6012,U+6016,U+601C-601D,U+6020,U+6025,U+6027-6028,U+602A,U+602F,U+604B,U+6050,U+6052,U+6055,U+6062,U+6065,U+6068-6069,U+606D,U+606F-6070,U+6075,U+6089,U+608C,U+6094,U+609F-60A0,U+60A3,U+60A6,U+60A9-60AA,U+60B2,U+60B6,U+60BC,U+60C5,U+60C7,U+60D1,U+60DA,U+60DC,U+60DF,U+60E3,U+60E8,U+60F0,U+60F3,U+60F9,U+6101,U+6108-6109,U+610F,U+611A-611B,U+611F,U+6148,U+614B-614C,U+614E,U+6155,U+6162-6163,U+6167-6168,U+616E,U+6170,U+6176,U+617E,U+6182,U+618E,U+6190,U+61A4,U+61A7,U+61A9,U+61B2,U+61B6,U+61BE,U+61C7,U+61D0,U+61F2,U+61F8,U+620A,U+620E,U+6210-6212,U+6216,U+621A,U+621F,U+6226,U+622F,U+6234,U+6238,U+623B,U+623F-6240,U+6247,U+6249,U+624B,U+624D,U+6253,U+6255,U+6258,U+626E,U+6271,U+6276,U+6279,U+627F-6280,U+6284,U+628A,U+6291,U+6295,U+6297-6298,U+629C,U+629E,U+62AB,U+62B1,U+62B5,U+62B9,U+62BC-62BD,U+62C5,U+62CD,U+62D0,U+62D2-62D3,U+62D8-62D9,U+62DB,U+62DD,U+62E0-62E1,U+62EC-62ED,U+62F3,U+62F6-62F7,U+62FE,U+6301,U+6307,U+6309,U+6311,U+6319,U+631F,U+6328,U+632B,U+632F,U+633A,U+633D,U+633F,U+6349,U+634C,U+6355,U+6357,U+635C,U+6367-6368,U+636E,U+6372,U+6377,U+637A-637B,U+6383,U+6388,U+638C,U+6392,U+6398,U+639B,U+63A0-63A2,U+63A5,U+63A7-63AA,U+63AC,U+63B2,U+63B4,U+63BB,U+63C3,U+63CF-63D0,U+63D6,U+63DA-63DB,U+63E1,U+63EE,U+63F4,U+63FA,U+640D,U+642C-642D,U+643A,U+643E,U+6442,U+6458,U+6469,U+6478,U+647A,U+6483,U+6492,U+649A,U+649E,U+64A4,U+64AB,U+64AD-64AE,U+64B0,U+64B2,U+64B9,U+64C1,U+64CD,U+64E2,U+64E6,U+64EC,U+64FE,U+652F,U+6539,U+653B,U+653E-653F,U+6545,U+654F,U+6551,U+6557,U+6559,U+6562-6563,U+6566,U+656C,U+6570,U+6574-6575,U+6577,U+6587,U+6589,U+658C,U+658E,U+6590-6591,U+6597,U+6599,U+659C,U+65A1,U+65A4-65A5,U+65A7,U+65AC-65AD,U+65AF-65B0,U+65B9,U+65BC-65BD,U+65C5,U+65CB,U+65CF,U+65D7,U+65E2,U+65E5-65E9,U+65EC-65ED,U+65FA,U+6602,U+6606-6607,U+660C,U+660E-660F,U+6613-6614,U+661F-6620,U+6625,U+6627-6628,U+662D,U+662F,U+663C,U+6642-6643,U+664B,U+6652,U+6666,U+6669,U+666E-666F,U+6674,U+6676,U+667A,U+6681,U+6687,U+6691,U+6696-6697,U+66A2,U+66A6,U+66AB,U+66AE,U+66B4,U+66C7,U+66D9,U+66DC-66DD,U+66F2-66F4,U+66F8-66F9,U+66FD-6700,U+6708-6709,U+670B,U+670D,U+6714-6715,U+6717,U+671B,U+671D,U+671F,U+6728,U+672A-672D,U+6731,U+6734,U+673A,U+673D,U+6749,U+674E-6751,U+6753,U+6756,U+675C,U+675F,U+6761-6762,U+6765,U+676D,U+676F,U+6771,U+6775,U+6777,U+677E-677F,U+6787,U+6790,U+6795,U+6797,U+679A,U+679C-679D,U+67A0,U+67A2,U+67AF,U+67B6,U+67C1,U+67C4,U+67CA,U+67CF-67D1,U+67D3-67D4,U+67D8,U+67DA,U+67F1,U+67F3-67F5,U+67FB,U+67FE-67FF,U+6802-6804,U+6813,U+6816-6817,U+6821-6822,U+682A,U+6834,U+6838-6839,U+683C-683D,U+6841-6843,U+6848,U+6850-6851,U+6853-6854,U+685C-685D,U+685F,U+6867,U+6876,U+6881,U+6885,U+6893,U+6897,U+68A2,U+68A7-68A8,U+68AF-68B1,U+68B6,U+68BC,U+68C4,U+68C9,U+68CB,U+68D2,U+68DA,U+68DF,U+68EE,U+68F2,U+68FA,U+6900,U+6905,U+690B,U+690D-690E,U+6919,U+691B-691C,U+6934,U+693F,U+694A,U+6953,U+6955,U+695A,U+6960,U+6962,U+696D,U+696F,U+6973,U+6975,U+697C-697D,U+6982,U+698A,U+698E,U+6994,U+699B,U+69CB-69CD,U+69D8-69D9,U+69FB,U+69FD,U+6A0B,U+6A17,U+6A19,U+6A1F,U+6A21,U+6A29-6A2B,U+6A35,U+6A39-6A3A,U+6A3D,U+6A4B,U+6A58,U+6A5F,U+6A61,U+6A7F-6A80,U+6A8E,U+6AD3,U+6ADB,U+6AE8,U+6B04,U+6B1D,U+6B20-6B21,U+6B23,U+6B27,U+6B32,U+6B3A,U+6B3D-6B3E,U+6B4C,U+6B4E,U+6B53,U+6B62-6B64,U+6B66,U+6B69-6B6A,U+6B6F,U+6B73-6B74,U+6B7B,U+6B86,U+6B89-6B8B,U+6B96,U+6BB4-6BB5,U+6BBA-6BBB,U+6BBF,U+6BC5,U+6BCD-6BCE,U+6BD2,U+6BD4,U+6BD8,U+6BDB,U+6C0F,U+6C11,U+6C17,U+6C34,U+6C37-6C38,U+6C3E,U+6C40-6C42,U+6C4E,U+6C50,U+6C57,U+6C5A,U+6C5D,U+6C5F-6C60,U+6C70,U+6C72,U+6C7A,U+6C7D,U+6C83,U+6C88,U+6C8C,U+6C93,U+6C96,U+6C99,U+6CA1-6CA2,U+6CAB,U+6CB3,U+6CB8-6CB9,U+6CBB-6CBC,U+6CBF,U+6CC1,U+6CC9-6CCA,U+6CCC,U+6CD5,U+6CE1-6CE3,U+6CE5,U+6CE8,U+6CF0,U+6CF3,U+6D0B,U+6D17,U+6D1B,U+6D1E,U+6D25,U+6D29-6D2A,U+6D32,U+6D3B,U+6D3E,U+6D41,U+6D44-6D45,U+6D5C,U+6D66,U+6D69-6D6A,U+6D6C,U+6D6E,U+6D74,U+6D77-6D78,U+6D88,U+6D8C,U+6D99,U+6D9B-6D9C,U+6DAF,U+6DB2,U+6DBC,U+6DC0,U+6DCB,U+6DD1,U+6DD8,U+6DE1,U+6DEB,U+6DF1,U+6DF3,U+6DF5,U+6DF7,U+6DFB,U+6E05,U+6E07-6E09,U+6E0B,U+6E13,U+6E1A-6E1B,U+6E20-6E21,U+6E25-6E26,U+6E29,U+6E2C,U+6E2F,U+6E4A,U+6E56,U+6E58,U+6E5B,U+6E67,U+6E6F,U+6E7E-6E80,U+6E8C,U+6E90,U+6E96,U+6E9C-6E9D,U+6EA2,U+6EB6,U+6EBA,U+6EC5,U+6ECB,U+6ED1,U+6EDD-6EDE,U+6EF4,U+6F01-6F02,U+6F06,U+6F09,U+6F0F,U+6F14-6F15,U+6F20,U+6F22-6F23,U+6F2B-6F2C,U+6F38,U+6F45,U+6F54,U+6F5C,U+6F5F,U+6F64,U+6F6E,U+6F70,U+6F84,U+6F97,U+6FB1,U+6FC0-6FC1,U+6FC3,U+6FE0-6FE1,U+6FEB,U+6FEF,U+7015,U+701E,U+7026-7027,U+702C,U+7058,U+706B,U+706F-7070,U+7078,U+707C-707D,U+7089-708A,U+708E,U+70AD,U+70B9-70BA,U+70C8,U+70CF,U+70F9,U+7114,U+711A,U+7121,U+7126,U+7136,U+713C,U+7149,U+714E,U+7159,U+7164,U+7167,U+7169,U+716E,U+717D,U+718A,U+7194,U+719F,U+71B1,U+71C3,U+71C8,U+71D0,U+71D5,U+71E5-71E6,U+71ED,U+7206,U+722A,U+7235-7236,U+723A,U+723D-723E,U+7247-7248,U+724C,U+7252,U+7259,U+725B,U+725D,U+725F,U+7261-7262,U+7267,U+7269,U+7272,U+7279,U+727D,U+7280,U+72A0,U+72AC,U+72AF,U+72B6,U+72C2,U+72D0,U+72D7,U+72D9,U+72DB,U+72E9,U+72EC-72ED,U+72F8,U+72FC-72FD,U+731B,U+731F,U+732A-732B,U+732E,U+7336-7337,U+733F,U+7344-7345,U+7363,U+7372,U+7384,U+7387,U+7389,U+738B,U+7396,U+73A9,U+73B2,U+73C2,U+73CA,U+73CD,U+73E0,U+73EA,U+73ED,U+73FE,U+7403,U+7406,U+7409,U+7422,U+7433-7436,U+745A-745B,U+745E,U+7460,U+7473,U+7483,U+74B0,U+74BD,U+74DC,U+74E2,U+74E6,U+74F6,U+7511,U+7518,U+751A,U+751C,U+751F,U+7523,U+7525,U+7528,U+752B,U+7530-7533,U+7537,U+753A-753B,U+754C,U+754F,U+7551,U+7554,U+7559,U+755C-755D,U+7560,U+7562,U+7565-7566,U+756A,U+7570,U+7573,U+7577,U+757F,U+758B,U+758E-758F,U+7591,U+75AB,U+75B2,U+75B9,U+75BE,U+75C5,U+75C7,U+75D4-75D5,U+75D8,U+75DB,U+75E2,U+75E9,U+75F4,U+7642,U+764C,U+7652,U+7656,U+767A-767B,U+767D-767E,U+7684,U+7686-7687,U+7690,U+76AE,U+76BF,U+76C3,U+76C6,U+76C8,U+76CA,U+76D7,U+76DB,U+76DF,U+76E3-76E4,U+76EE,U+76F2,U+76F4,U+76F8,U+76FE,U+7701,U+7709,U+770B-770C,U+771F-7720,U+773A,U+773C,U+7740,U+7761,U+7763,U+7766,U+77A5,U+77AC-77AD,U+77B3,U+77DB,U+77E2,U+77E5,U+77E7,U+77E9,U+77ED,U+77EF,U+77F3,U+7802,U+7814-7815,U+7825-7827,U+7832,U+7834,U+783A,U+783F,U+785D,U+786B-786C,U+786F,U+7872,U+7881,U+7887,U+788D,U+7891,U+7893,U+7895,U+7897,U+78A7,U+78A9,U+78BA,U+78C1,U+78D0,U+78E8,U+78EF,U+7901,U+790E,U+793A,U+793C,U+793E,U+7941,U+7947-7949,U+7950,U+7956,U+795D-795E,U+7962,U+7965,U+7968,U+796D,U+7977,U+7981,U+7984-7985,U+798D-798F,U+79A6,U+79B0,U+79BD-79C1,U+79CB,U+79D1-79D2,U+79D8,U+79DF,U+79E4,U+79E6,U+79E9,U+79F0,U+79FB,U+7A00,U+7A0B,U+7A0E,U+7A14,U+7A17,U+7A1A,U+7A1C,U+7A2E,U+7A32,U+7A3C-7A3D,U+7A3F-7A40,U+7A42,U+7A46,U+7A4D-7A50,U+7A63,U+7A6B,U+7A74,U+7A76,U+7A7A,U+7A7F,U+7A81,U+7A83-7A84,U+7A92-7A93,U+7A9F,U+7AAA,U+7AAE-7AAF,U+7ABA,U+7AC3,U+7ACB,U+7ADC,U+7AE0,U+7AE3,U+7AE5,U+7AEA,U+7AEF,U+7AF6,U+7AF9-7AFA,U+7AFF,U+7B08,U+7B11,U+7B1B,U+7B20,U+7B25-7B26,U+7B2C,U+7B39,U+7B46,U+7B48-7B49,U+7B4B,U+7B4F,U+7B51-7B52,U+7B54,U+7B56,U+7B86-7B87,U+7B94-7B95,U+7B97,U+7BA1,U+7BAA,U+7BAD,U+7BB1,U+7BB8,U+7BC0,U+7BC4,U+7BC7,U+7BC9,U+7BE0,U+7BE4,U+7BED,U+7C21,U+7C38,U+7C3E-7C3F,U+7C4D,U+7C73,U+7C7E,U+7C81-7C82,U+7C89,U+7C8B,U+7C8D,U+7C92,U+7C95,U+7C97-7C98,U+7C9B,U+7C9F,U+7CA5,U+7CA7,U+7CBE,U+7CCA,U+7CCE,U+7CD6,U+7CDE-7CE0,U+7CE7,U+7CF8,U+7CFB,U+7CFE,U+7D00,U+7D04-7D05,U+7D0B,U+7D0D,U+7D10,U+7D14,U+7D17-7D1B,U+7D20-7D22,U+7D2B-7D2C,U+7D2F-7D30,U+7D33,U+7D39-7D3A,U+7D42-7D44,U+7D4C,U+7D50,U+7D5E,U+7D61-7D62,U+7D66,U+7D71,U+7D75-7D76,U+7D79,U+7D99-7D9A,U+7D9C,U+7DAC-7DAD,U+7DB1-7DB2,U+7DB4,U+7DBB,U+7DBE-7DBF,U+7DCA-7DCB,U+7DCF,U+7DD1-7DD2,U+7DDA,U+7DE0,U+7DE8-7DE9,U+7DEC,U+7DEF,U+7DF4,U+7E01,U+7E04,U+7E1B,U+7E1E,U+7E26,U+7E2B,U+7E2E,U+7E3E,U+7E41,U+7E4A-7E4B,U+7E4D,U+7E54-7E55,U+7E6D,U+7E70,U+7E82,U+7E8F,U+7F36,U+7F6A-7F6B,U+7F6E,U+7F70,U+7F72,U+7F75,U+7F77,U+7F85,U+7F8A,U+7F8E,U+7FA4,U+7FA8-7FA9,U+7FBD,U+7FC1,U+7FCC,U+7FD2,U+7FE0,U+7FEB,U+7FF0,U+7FFB-7FFC,U+8000-8001,U+8003,U+8005,U+800C,U+8010,U+8015,U+8017,U+8033,U+8036,U+803D,U+8056,U+805E,U+8061,U+806F,U+8074,U+8077,U+807E,U+8087,U+8089,U+808B-808C,U+8096,U+8098,U+809D,U+80A1-80A2,U+80A5,U+80A9-80AA,U+80AF,U+80B1-80B2,U+80B4,U+80BA,U+80C3,U+80C6,U+80CC,U+80CE,U+80DE,U+80E1,U+80E4,U+80F4,U+80F8,U+80FD,U+8102,U+8105-8108,U+810A,U+811A,U+8131,U+8133,U+8139,U+814E,U+8150,U+8154-8155,U+816B,U+8170,U+8178-817A,U+817F,U+818F,U+819A,U+819C-819D,U+81A8,U+81B3,U+81BF,U+81C6,U+81D3,U+81E3,U+81E5,U+81E8,U+81EA,U+81ED,U+81F3-81F4,U+81FC,U+8208,U+820C,U+820E,U+8217-8218,U+821B-821C,U+821E-821F,U+822A,U+822C,U+8235-8237,U+8239,U+8247,U+8266,U+826E-826F,U+8272,U+8276,U+828B,U+8299,U+829D,U+82A5-82A6,U+82AD,U+82AF,U+82B1,U+82B3,U+82B8-82B9,U+82BD,U+82C5,U+82D1,U+82D3-82D4,U+82D7,U+82DB,U+82E5-82E7,U+82EB,U+82F1,U+8302,U+8304-8305,U+830E,U+831C,U+8328,U+8336,U+8338,U+8349-834A,U+834F,U+8352,U+8358,U+8377,U+837B,U+839E,U+83AB,U+83B1,U+83C5,U+83CA,U+83CC,U+83D3,U+83D6,U+83DC,U+83DF,U+83E9,U+83EF-83F1,U+8404,U+840C,U+840E,U+8429,U+8431,U+843D,U+8449,U+844E,U+8457,U+845B,U+8461,U+8463,U+8466,U+846C,U+8471,U+8475,U+847A,U+848B,U+8490,U+8494,U+8499,U+849C,U+84B2,U+84B8,U+84BC,U+84C4,U+84C9,U+84CB,U+84D1,U+84EC,U+84EE,U+8500,U+8511,U+8513,U+851A,U+8526,U+852D,U+8535,U+853D,U+8543,U+8549-854A,U+854E,U+8557,U+8568-856A,U+8584,U+8597,U+8599,U+85A6,U+85A9-85AC,U+85AE-85AF,U+85C1,U+85CD,U+85E4,U+85E9,U+85F7,U+85FB,U+8607,U+862D,U+864E,U+8650,U+865A,U+865C,U+865E,U+866B,U+8679,U+867B,U+868A,U+8695,U+86A4,U+86C7,U+86CB,U+86CD-86CE,U+86D9,U+86E4,U+86ED-86EE,U+86F8,U+86FE,U+8702,U+8718,U+871C,U+8749,U+874B,U+8755,U+8766,U+8776,U+877F,U+878D,U+87BA,U+87F9,U+87FB,U+8840,U+8846,U+884C,U+8853,U+8857,U+885B,U+885D,U+8861,U+8863,U+8868,U+8870,U+8877,U+887F,U+8888,U+888B,U+8896,U+88AB,U+88B4,U+88B7,U+88C1-88C2,U+88C5,U+88CF,U+88D5,U+88DC,U+88DF,U+88E1,U+88F3,U+88F8,U+88FD-88FE,U+8907,U+8910,U+8912,U+8956,U+895F,U+8972,U+897F,U+8981,U+8986-8987,U+898B,U+898F,U+8996-8997,U+899A,U+89A7,U+89AA,U+89B3,U+89D2,U+89E3,U+89E6,U+8A00,U+8A02,U+8A08,U+8A0A,U+8A0E,U+8A13,U+8A17-8A18,U+8A1F,U+8A23,U+8A2A,U+8A2D,U+8A31,U+8A33-8A34,U+8A3A-8A3C,U+8A50-8A51,U+8A54-8A55,U+8A5E,U+8A60,U+8A63,U+8A66,U+8A69,U+8A6B,U+8A6E,U+8A70-8A73,U+8A87,U+8A89,U+8A8C-8A8D,U+8A93,U+8A95,U+8A98,U+8A9E,U+8AA0,U+8AA4,U+8AAC-8AAD,U+8AB0,U+8AB2,U+8AB9,U+8ABC,U+8ABF,U+8AC7,U+8ACB-8ACC,U+8ACF,U+8AD2,U+8AD6,U+8ADC,U+8AE6,U+8AED-8AEE,U+8AF8,U+8AFA,U+8AFE,U+8B00-8B02,U+8B04,U+8B0E,U+8B19,U+8B1B,U+8B1D,U+8B21,U+8B2C,U+8B39,U+8B58,U+8B5C,U+8B66,U+8B70,U+8B72,U+8B77,U+8B83,U+8B90,U+8C37,U+8C46,U+8C4A,U+8C5A,U+8C61,U+8C6A,U+8C79,U+8C8C,U+8C9D-8C9E,U+8CA0-8CA2,U+8CA7-8CA9,U+8CAB-8CAC,U+8CAF-8CB0,U+8CB4,U+8CB7-8CB8,U+8CBB-8CBC,U+8CBF-8CC0,U+8CC2-8CC4,U+8CC7,U+8CCA,U+8CCE,U+8CD1,U+8CD3,U+8CDB-8CDC,U+8CDE,U+8CE0,U+8CE2,U+8CE6,U+8CEA,U+8CED,U+8CFC,U+8D08,U+8D0B,U+8D64,U+8D66,U+8D6B,U+8D70,U+8D74,U+8D77,U+8D85,U+8D8A,U+8DA3,U+8DA8,U+8DB3,U+8DDD,U+8DE1,U+8DE8,U+8DEF,U+8DF3,U+8DF5,U+8E0A,U+8E0F,U+8E44,U+8E5F,U+8E74,U+8E8D,U+8EAB,U+8EAF,U+8ECA,U+8ECC-8ECD,U+8ED2,U+8EDF,U+8EE2,U+8EF8,U+8EFD,U+8F03,U+8F09,U+8F14,U+8F1D,U+8F29-8F2A,U+8F2F,U+8F38,U+8F3F,U+8F44,U+8F4D,U+8F5F,U+8F61,U+8F9B,U+8F9E,U+8FB0-8FB2,U+8FBA-8FBC,U+8FBF,U+8FC2,U+8FC4-8FC5,U+8FCE,U+8FD1,U+8FD4,U+8FE6,U+8FE9,U+8FEB,U+8FED,U+8FF0,U+8FF7,U+8FFD,U+9000-9001,U+9003,U+9006,U+900F-9010,U+9013-9014,U+9017,U+9019-901A,U+901D,U+901F-9020,U+9022-9023,U+902E,U+9031-9032,U+9038,U+903C,U+9041-9042,U+9045,U+9047,U+904A-904B,U+904D-904E,U+9053-9055,U+905C,U+9060-9061,U+9063,U+9065,U+9069,U+906D-906E,U+9075,U+9077-9078,U+907A,U+907C,U+907F,U+9084,U+9091,U+90A3,U+90A6,U+90AA,U+90B8,U+90C1,U+90CA,U+90CE,U+90E1,U+90E8,U+90ED,U+90F5,U+90F7,U+90FD,U+912D,U+9149,U+914B-914E,U+9152,U+9154,U+9162,U+916A,U+916C,U+9175,U+9177-9178,U+9187,U+918D,U+9190,U+9192,U+9197,U+919C,U+91A4,U+91B8,U+91C6-91C8,U+91CC-91CF,U+91D1,U+91D8,U+91DC-91DD,U+91E3,U+91E6-91E7,U+920D-920E,U+9234,U+9237,U+9244,U+925B,U+9262,U+9266,U+9271,U+927E,U+9280,U+9283,U+9285,U+9291,U+9298,U+929A,U+92AD,U+92D2,U+92E4,U+92EA,U+92ED,U+92F2-92F3,U+92F8,U+92FC,U+9306,U+9310,U+9318,U+9320,U+9326,U+9328,U+932B-932C,U+932F,U+9332,U+934B,U+934D,U+9354,U+935B,U+936C,U+9375,U+937E,U+938C,U+9396-9397,U+939A,U+93A7,U+93AE,U+93D1,U+93E1,U+9418-9419,U+9438,U+9451,U+9453,U+9577,U+9580,U+9583,U+9589,U+958B,U+958F,U+9591,U+9593,U+95A2-95A5,U+95B2,U+95C7,U+95D8,U+961C,U+962A,U+9632,U+963B,U+963F-9640,U+9644,U+964D,U+9650,U+965B,U+9662-9665,U+966A,U+9670,U+9673,U+9675-9676,U+9678,U+967A,U+967D,U+9685-9686,U+9688,U+968A,U+968E-968F,U+9694,U+9699,U+969B-969C,U+96A0,U+96A3,U+96B7,U+96BB-96BC,U+96C0-96C1,U+96C4-96C7,U+96CC,U+96D1,U+96DB,U+96E2-96E3,U+96E8,U+96EA-96EB,U+96F0,U+96F2,U+96F6-96F7,U+96FB,U+9700,U+9707,U+970A,U+971C,U+971E,U+9727,U+9732,U+9752,U+9756,U+9759,U+975E,U+9762,U+9769,U+976D,U+9774,U+9784,U+978D,U+9798,U+97A0,U+97AD,U+97D3,U+97EE,U+97F3,U+97FB,U+97FF,U+9801-9803,U+9805-9806,U+9808,U+9810-9813,U+9817-9818,U+981A,U+982C-982D,U+9834,U+983B-983C,U+984C-984E,U+9854-9855,U+9858,U+985B,U+985E,U+9867,U+98A8,U+98DB,U+98DF,U+98E2,U+98EF,U+98F2,U+98F4,U+98FC-98FE,U+9905,U+990A,U+990C,U+9910,U+9913,U+9928,U+9957,U+9996,U+9999,U+99A8,U+99AC,U+99B3-99B4,U+99C1,U+99C4-99C6,U+99C8,U+99D0,U+99D2,U+99D5,U+99FF,U+9A0E,U+9A12-9A13,U+9A28,U+9A30,U+9A5A,U+9AA8,U+9AB8,U+9AC4,U+9AD8,U+9AEA,U+9AED,U+9B3C,U+9B41-9B42,U+9B45,U+9B54,U+9B5A,U+9B6F,U+9B8E,U+9B92,U+9BAA-9BAB,U+9BAD-9BAE,U+9BC9,U+9BD6,U+9BDB,U+9BE8,U+9BF5,U+9C0D,U+9C10,U+9C2D,U+9C2F,U+9C39,U+9C3B,U+9C48,U+9C52,U+9C57,U+9CE5,U+9CE9,U+9CF3-9CF4,U+9CF6,U+9D07,U+9D0E,U+9D1B,U+9D28,U+9D2B-9D2C,U+9D3B,U+9D5C,U+9D60-9D61,U+9D6C,U+9D8F,U+9DB4,U+9DF2,U+9DF9-9DFA,U+9E78,U+9E7F,U+9E93,U+9E97,U+9E9F,U+9EA6,U+9EB9-9EBB,U+9EBF,U+9EC4,U+9ECD,U+9ED2,U+9ED9,U+9EDB,U+9F0E,U+9F13,U+9F20,U+9F3B,U+9F62,U+9F8D,U+FF01,U+FF03-FF06,U+FF08-FF5E,U+FFE0-FFE3,U+FFE5 7 | 8 | pyftsubset $1 --output-file=${1}.min.ttf --unicodes=${unicodes} 9 | --------------------------------------------------------------------------------