diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f792d12..d86d2528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Change log +## 0.10.0 on 2024/11/17 + +Almost one year has passed since the last release. We have been working on improving the PRK Firmware! + +### Breaking Change 💣 +- No breaking change in this release + +### New Feature 🎉 +- On startup, if you connect a terminal emulator to com port, you can skip starting the keyboard task by pressing `s` according to the message on the terminal + - This feature is useful when your `keymap.rb` breaks and hangs up the keyboard + - Note that `s` key should be sent from the other keyboard that is working fine. This means you have to have multiple keyboards⌨⌨⌨⌨ + +### Improvement 🔈 +- Replace PicoRuby with a totally new one: + - The Ruby parser is now Prism! + - Many bugs are fixed in the virtual machine and libraries + - Stability should be improved a lot🤞 + +Please report if you find any bugs! + ## 0.9.23 on 2023/11/19 ### require diff --git a/CMakeLists.txt b/CMakeLists.txt index 168f1ff0..f4b4093d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.24) # initialize the SDK based on PICO_SDK_PATH # note: this must happen before project() include(pico_sdk_import.cmake) +include(pico_extras_import.cmake) ##################################################### # project specific configuration from here @@ -48,6 +49,14 @@ project("prk_firmware-${MSC_NAME}-${PRK_VERSION}-${PRK_BUILDDATE}-${PRK_REVISION # Initializing the Raspberry Pi Pico SDK should happen after project created pico_sdk_init() +add_compile_options(-Wall + # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int + -Wno-format + -Wno-unused-function + -Wno-maybe-uninitialized + -fshort-enums +) + file(GLOB SRCS src/*.c) add_executable(${PROJECT_NAME} ${SRCS} @@ -58,7 +67,13 @@ add_executable(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-i2c/ports/rp2040/i2c.c ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-spi/ports/rp2040/spi.c ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-adc/ports/rp2040/adc.c + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-uart/ports/rp2040/uart.c + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-pwm/ports/rp2040/pwm.c + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-machine/ports/rp2040/machine.c ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-io-console/ports/rp2040/io-console.c + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-watchdog/ports/rp2040/watchdog.c + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-rng/ports/rp2040/rng.c + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-env/ports/rp2040/env.c ) set(PICORBC ${CMAKE_SOURCE_DIR}/lib/picoruby/bin/picorbc) @@ -114,11 +129,11 @@ add_dependencies(${PROJECT_NAME} target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/tinyusb ${CMAKE_SOURCE_DIR}/lib/picoruby/include/hal_no_impl - ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-mrubyc/repos/mrubyc/src + ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-mrubyc/lib/mrubyc/src ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems/picoruby-filesystem-fat/lib/ff14b/source ${CMAKE_SOURCE_DIR}/lib/picoruby/build/$ENV{MRUBY_CONFIG}/mrbgems - ${CMAKE_SOURCE_DIR}/lib/picoruby/build/repos/$ENV{MRUBY_CONFIG}/mruby-pico-compiler/include ${CMAKE_SOURCE_DIR}/lib/picoruby/mrbgems + ${CMAKE_SOURCE_DIR}/lib/picoruby/build/repos/${BUILD_CONFIG}/mruby-compiler2/include ) target_link_directories(${PROJECT_NAME} PRIVATE @@ -131,15 +146,16 @@ target_link_libraries(${PROJECT_NAME} tinyusb_device tinyusb_board hardware_pio - hardware_pwm - pico_multicore + hardware_sleep hardware_flash hardware_adc + hardware_uart hardware_dma hardware_sync hardware_irq hardware_i2c hardware_spi + hardware_pwm mruby ) diff --git a/Gemfile b/Gemfile index 902191f2..61925919 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,3 @@ source 'https://rubygems.org' gem 'rake' -gem "mrubyc-test", ">= 0.9.1" diff --git a/Gemfile.lock b/Gemfile.lock index 1bf1e358..1f271f5d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,30 +1,12 @@ GEM remote: https://rubygems.org/ specs: - activesupport (7.0.4.2) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 1.6, < 2) - minitest (>= 5.1) - tzinfo (~> 2.0) - concurrent-ruby (1.2.2) - i18n (1.12.0) - concurrent-ruby (~> 1.0) - minitest (5.18.0) - mrubyc-test (0.9.2) - activesupport (~> 7.0) - rufo (~> 0.12) - thor (~> 1.2) rake (13.0.6) - rufo (0.15.1) - thor (1.2.1) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) PLATFORMS x86_64-linux DEPENDENCIES - mrubyc-test (>= 0.9.1) rake BUNDLED WITH diff --git a/Guardfile b/Guardfile deleted file mode 100644 index 4f2ceb14..00000000 --- a/Guardfile +++ /dev/null @@ -1,4 +0,0 @@ -guard :process, command: %w(bundle exec steep check) do - watch %r{lib/picoruby/mrbgems/[^/]+/(mrblib|task|sig)/.+\.(rb|rbs)} - watch %r{(mrblib|sig)/.+\.(rb|rbs)} -end diff --git a/Rakefile b/Rakefile index c5c67e58..21fc6ae0 100644 --- a/Rakefile +++ b/Rakefile @@ -1,30 +1,30 @@ require "fileutils" ENV['MRUBY_CONFIG'] = "prk_firmware-cortex-m0plus" -PICO_SDK_TAG = "1.5.1" +PICO_SDK_TAG = "2.0.0" task :default => :production task :setup do sh "bundle install" - sh "git submodule update --init" + sh "git submodule update --init --recursive" FileUtils.cd "lib/picoruby" do sh "bundle install" end end -task :all => [:libmruby, :test, :cmake, :build] - +task :all => [:libmruby, :cmake, :build] desc "build debug (you may need to rake clean before this)" task :debug do ENV['PICORUBY_DEBUG'] = '1' - ENV['-DCMAKE_BUILD_TYPE'] = 'Debug' + ENV['CMAKE_BUILD_TYPE'] = 'Debug' Rake::Task[:all].invoke end desc "build production" task :production do + ENV['CMAKE_BUILD_TYPE'] = 'Release' Rake::Task[:all].invoke end @@ -55,12 +55,12 @@ end task :libmruby => "lib/picoruby" do FileUtils.cd "lib/picoruby" do sh "MRUBY_CONFIG=default rake test" - sh "MRUBY_CONFIG=#{ENV['MRUBY_CONFIG']} rake" + sh "rake" end end task :cmake do - sh "cmake -B #{ENV['PRK_BUILD_DIR']}build" + sh "cmake -DCMAKE_BUILD_TYPE=#{ENV['CMAKE_BUILD_TYPE']} -B #{ENV['PRK_BUILD_DIR']}build" end task :check_pico_sdk => :check_pico_sdk_path do @@ -96,28 +96,6 @@ task :clean_with_keymap , ['keyboard_name'] do |_t, args| FileUtils.rm_r Dir.glob("keyboards/#{args.keyboard_name}/build/*") end - -desc "run :mrubyc_test" -task :test => %i(mrubyc_test) - -desc "run unit test for ruby program" -task :mrubyc_test => :setup_test do - sh %q(MRUBYCFILE=test/Mrubycfile bundle exec mrubyc-test) -end - -task :setup_test do - FileUtils.cd "test/models" do - Dir.glob("../../lib/picoruby/mrbgems/picoruby-prk-*").each do |dir| - Dir.glob("#{dir}/mrblib/*.rb").each do |model| - FileUtils.ln_sf model, File.basename(model) - end - end - FileUtils.ln_sf "../../lib/picoruby/mrbgems/picoruby-gpio/mrblib/gpio.rb", "gpio.rb" - FileUtils.ln_sf "../../lib/picoruby/mrbgems/picoruby-float-ext/mrblib/float.rb", "float.rb" - FileUtils.ln_sf "../../lib/picoruby/mrbgems/picoruby-music-macro-language/mrblib/mml.rb", "mml.rb" - end -end - desc "clean built" task :clean do FileUtils.cd "lib/picoruby" do @@ -150,13 +128,8 @@ task :symlinks do end end -desc "run guard-process" -task :guard do - sh "bundle exec guard start -i" -end - # Add a new tag then push it -task :release => :test do +task :release do git_status = `git status` branch = git_status.split("\n")[0].match(/\AOn branch (.+)\z/)[1] if branch != "master" diff --git a/lib/picoruby b/lib/picoruby index a5ffc54f..4c6a147c 160000 --- a/lib/picoruby +++ b/lib/picoruby @@ -1 +1 @@ -Subproject commit a5ffc54f57a67f3e006c86ef08ce4eb53dac4584 +Subproject commit 4c6a147c07599c807e1b0a6ade00517a5a63ae59 diff --git a/mrblib/object-ext.rb b/mrblib/object-ext.rb index 1e147ea2..b7de3dc5 100644 --- a/mrblib/object-ext.rb +++ b/mrblib/object-ext.rb @@ -1,7 +1,3 @@ -class LoadError < StandardError - # ScriptError is the super class in CRuby -end - class Object alias _puts puts diff --git a/mrblib/usb_task.rb b/mrblib/usb_task.rb index 9914ea3b..4c0fbaab 100644 --- a/mrblib/usb_task.rb +++ b/mrblib/usb_task.rb @@ -1,10 +1,20 @@ +require "machine" +require "watchdog" +Watchdog.disable +require 'env' + +ENV["HOME"] = "/" +ENV["PWD"] = "/" + +STDOUT = IO +STDIN = IO +STDIN.echo = false + if PICORUBY_MSC == "MSC_SD" require "spi" end require "keyboard" -ENV = {} - 200.times do USB.tud_task sleep_ms 2 @@ -17,6 +27,11 @@ while true USB.tud_task if Keyboard.autoreload_ready? && File.exist?("/keymap.rb") - Keyboard.restart + break unless Keyboard.restart end end + +puts "Restart microcontroller when you want to reload keymap.rb" +while true + USB.tud_task +end diff --git a/pico_extras_import.cmake b/pico_extras_import.cmake new file mode 100644 index 00000000..706add02 --- /dev/null +++ b/pico_extras_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_extras_import.cmake + +# This can be dropped into an external project to help locate pico-extras +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_EXTRAS_PATH} AND (NOT PICO_EXTRAS_PATH)) + set(PICO_EXTRAS_PATH $ENV{PICO_EXTRAS_PATH}) + message("Using PICO_EXTRAS_PATH from environment ('${PICO_EXTRAS_PATH}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT)) + set(PICO_EXTRAS_FETCH_FROM_GIT $ENV{PICO_EXTRAS_FETCH_FROM_GIT}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT from environment ('${PICO_EXTRAS_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT_PATH)) + set(PICO_EXTRAS_FETCH_FROM_GIT_PATH $ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT_PATH from environment ('${PICO_EXTRAS_FETCH_FROM_GIT_PATH}')") +endif () + +if (NOT PICO_EXTRAS_PATH) + if (PICO_EXTRAS_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_EXTRAS_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + PICO_EXTRAS + GIT_REPOSITORY https://github.com/raspberrypi/pico-extras + GIT_TAG master + ) + if (NOT PICO_EXTRAS) + message("Downloading PICO EXTRAS") + FetchContent_Populate(PICO_EXTRAS) + set(PICO_EXTRAS_PATH ${PICO_EXTRAS_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + if (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../pico-extras") + set(PICO_EXTRAS_PATH ${PICO_SDK_PATH}/../pico-extras) + message("Defaulting PICO_EXTRAS_PATH as sibling of PICO_SDK_PATH: ${PICO_EXTRAS_PATH}") + else() + message(FATAL_ERROR + "PICO EXTRAS location was not specified. Please set PICO_EXTRAS_PATH or set PICO_EXTRAS_FETCH_FROM_GIT to on to fetch from git." + ) + endif() + endif () +endif () + +set(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" CACHE PATH "Path to the PICO EXTRAS") +set(PICO_EXTRAS_FETCH_FROM_GIT "${PICO_EXTRAS_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO EXTRAS from git if not otherwise locatable") +set(PICO_EXTRAS_FETCH_FROM_GIT_PATH "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download EXTRAS") + +get_filename_component(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_EXTRAS_PATH}) + message(FATAL_ERROR "Directory '${PICO_EXTRAS_PATH}' not found") +endif () + +set(PICO_EXTRAS_PATH ${PICO_EXTRAS_PATH} CACHE PATH "Path to the PICO EXTRAS" FORCE) + +add_subdirectory(${PICO_EXTRAS_PATH} pico_extras) \ No newline at end of file diff --git a/src/main.c b/src/main.c index 21030b3b..1944377d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,4 @@ /* PicoRuby */ -#include #include /* Raspi SDK */ @@ -32,16 +31,13 @@ #endif #if defined(PICORUBY_SQLITE3) - #define MEMORY_SIZE (1024*203) + #define MEMORY_SIZE (1024*190) #else - #define MEMORY_SIZE (1024*207) + #define MEMORY_SIZE (1024*200) #endif static uint8_t memory_pool[MEMORY_SIZE]; -/* extern in mruby-pico-compiler/include/debug.h */ -int loglevel = LOGLEVEL_WARN; - int autoreload_state; /* from keyboard.h */ #ifndef PICORUBY_NO_MSC @@ -83,9 +79,8 @@ prk_init_picoruby(void) mrbc_raw_free(vm); /* class Object */ picoruby_load_model(object_ext); - picoruby_init_require(); + picoruby_init_require(vm); prk_init_Machine(); - prk_init_PicoRubyVM(); prk_init_USB(); } diff --git a/src/picorubyvm.c b/src/picorubyvm.c deleted file mode 100644 index 686d0c23..00000000 --- a/src/picorubyvm.c +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include "../include/picorubyvm.h" - -static void -c_print_alloc_stats(mrbc_vm *vm, mrbc_value *v, int argc) -{ - struct MRBC_ALLOC_STATISTICS mem; - mrbc_alloc_statistics(&mem); - console_printf("\nSTATS %d/%d\n", mem.used, mem.total); - SET_NIL_RETURN(); -} - -static void -c_alloc_stats(mrbc_vm *vm, mrbc_value *v, int argc) -{ - struct MRBC_ALLOC_STATISTICS mem; - mrbc_value ret = mrbc_hash_new(vm, 4); - mrbc_alloc_statistics(&mem); - mrbc_hash_set(&ret, &mrbc_symbol_value(mrbc_str_to_symid("TOTAL")), - &mrbc_integer_value(mem.total)); - mrbc_hash_set(&ret, &mrbc_symbol_value(mrbc_str_to_symid("USED")), - &mrbc_integer_value(mem.used)); - mrbc_hash_set(&ret, &mrbc_symbol_value(mrbc_str_to_symid("FREE")), - &mrbc_integer_value(mem.free)); - mrbc_hash_set(&ret, &mrbc_symbol_value(mrbc_str_to_symid("FRAGMENTATION")), - &mrbc_integer_value(mem.fragmentation)); - SET_RETURN(ret); -} - -void -prk_init_PicoRubyVM() -{ - mrbc_class *mrbc_class_PicoRubyVM = mrbc_define_class(0, "PicoRubyVM", mrbc_class_object); - mrbc_define_method(0, mrbc_class_PicoRubyVM, "alloc_stats", c_alloc_stats); - mrbc_define_method(0, mrbc_class_PicoRubyVM, "print_alloc_stats", c_print_alloc_stats); -} diff --git a/src/usb_cdc.c b/src/usb_cdc.c index cef2e2a7..158e99a5 100644 --- a/src/usb_cdc.c +++ b/src/usb_cdc.c @@ -28,9 +28,4 @@ void tud_cdc_rx_cb(uint8_t itf) { (void) itf; - - char buf[64]; - uint32_t count = tud_cdc_read(buf, sizeof(buf)); - tud_cdc_write(buf, count); - tud_cdc_write_flush(); } diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 3fbf3688..c6af20af 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -453,7 +453,6 @@ c_tud_task(mrbc_vm *vm, mrbc_value *v, int argc) static bool report_raw_hid(uint8_t* data, uint8_t len) { - bool ret; // Remote wakeup if (tud_suspended()) { // Wake up host if we are in suspend mode @@ -532,7 +531,7 @@ static void c_save_prk_conf(mrbc_vm *vm, mrbc_value *v, int argc) { uint8_t buff[SECTOR_SIZE] = {0}; - memcpy(buff, (const uint8_t *)GET_STRING_ARG(1), strlen((const uint8_t *)GET_STRING_ARG(1))); + memcpy(buff, (const uint8_t *)GET_STRING_ARG(1), strlen((const char *)GET_STRING_ARG(1))); if (strncmp((const char *)buff, (const char *)(FLASH_MMAP_ADDR - SECTOR_SIZE), PRK_CONF_SIZE) == 0)