diff --git a/.gitmodules b/.gitmodules
index 6d08115..2e5ee50 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -43,3 +43,6 @@
[submodule "plasma"]
path = plasma
url = https://github.com/grblHAL/Plugin_plasma/
+[submodule "flexgpio"]
+ path = flexgpio
+ url = https://github.com/Expatria-Technologies/plugin_FlexGPIO.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e65d80..67d3971 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,7 +17,7 @@ cmake_minimum_required(VERSION 3.13)
option(ADD_HPGL "Add HPGL plugin" OFF)
# Note: WiFi and Ethernet cannot be enabled at the same time!
option(ADD_WIFI "Add WiFi networking" OFF)
-option(ADD_ETHERNET "Add Ethernet networking" OFF)
+option(ADD_ETHERNET "Add Ethernet networking" ON)
option(ADD_BLUETOOTH "Add Bluetooth" OFF)
# Set LWIP_DIR below to the root path of lwIP sources when the following is set ON!
option(ADD_mDNS "Add mDNS service" OFF)
@@ -26,7 +26,7 @@ option(ADD_MQTT "Add MQTT client API" OFF)
option(AddMyPlugin "Add my_plugin.c to build" OFF)
# Select the correct board in VSCode, the following line will be updated accordingly
-set(PICO_BOARD pico CACHE STRING "Board type")
+set(PICO_BOARD pimoroni_pga2350 CACHE STRING "Board type")
include(pico_sdk_import.cmake)
@@ -57,6 +57,8 @@ if(ADD_HPGL)
include(hpgl/CMakeLists.txt)
endif()
+include(flexgpio/CMakeLists.txt)
+
project(grblHAL)
pico_sdk_init()
@@ -77,6 +79,7 @@ if(AddMyPlugin)
my_plugin.c
boards/pico_cnc.c
boards/btt_skr_pico_10.c
+ boards/flexihal2350.c
littlefs/lfs.c
littlefs/lfs_util.c
littlefs_hal.c
@@ -97,6 +100,7 @@ else()
tmc_uart.c
boards/pico_cnc.c
boards/btt_skr_pico_10.c
+ boards/flexihal2350.c
littlefs/lfs.c
littlefs/lfs_util.c
littlefs_hal.c
@@ -105,6 +109,8 @@ endif()
pico_generate_pio_header(grblHAL ${CMAKE_CURRENT_LIST_DIR}/driverPIO.pio)
+add_compile_definitions(N_AXIS=6)
+
if(PICO_BOARD STREQUAL "pico" OR PICO_BOARD STREQUAL "pico_w")
target_compile_definitions(grblHAL PUBLIC RP_MCU=2040)
if(PICO_SDK_VERSION_STRING VERSION_GREATER_EQUAL "2.1.1")
@@ -231,6 +237,7 @@ target_link_libraries(grblHAL PRIVATE
plasma
misc_plugins
embroidery
+ flexgpio
tinyusb_device_unmarked
pico_stdlib
pico_unique_id
diff --git a/boards/flexihal2350.c b/boards/flexihal2350.c
new file mode 100644
index 0000000..bf47cc6
--- /dev/null
+++ b/boards/flexihal2350.c
@@ -0,0 +1,501 @@
+/*
+ flexihal2350.c - init code for flexihal2350
+
+ Part of grblHAL
+
+ Copyright (c) 2021-2025 Terje Io
+
+ grblHAL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ grblHAL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with grblHAL. If not, see .
+*/
+
+#include "driver.h"
+
+#if defined(BOARD_FLEXIHAL2350)
+
+#include
+#include
+#include
+
+#include "grbl/hal.h"
+#include "grbl/protocol.h"
+#include "grbl/settings.h"
+#include "grbl/nvs_buffer.h"
+#include "grbl/system.h"
+
+#include "flexgpio/flexgpio.h"
+#include "boards/flexihal2350_map.h"
+
+#define AUXOUTPUT0_PIN 23 //RP2040 pin
+#define AUXOUTPUT1_PIN 22 //RP2040 pin
+#define AUXOUTPUT2_PIN 21 //RP2040 pin
+#define AUXOUTPUT3_PIN 20 //RP2040 pin
+#define AUXOUTPUT4_PIN 19 //RP2040 pin
+#define AUXOUTPUT5_PIN 18 //RP2040 pin
+#define AUXOUTPUT6_PIN 17 //RP2040 pin
+#define AUXOUTPUT7_PIN 16 //RP2040 pin
+
+static on_settings_changed_ptr on_settings_changed;
+static on_state_change_ptr on_state_change;
+static on_reset_ptr on_reset;
+
+#define N_MOTOR_ALARMS 6
+
+static int8_t val[N_MOTOR_ALARMS] = {0};
+static bool motor_alarm_active = false;
+
+static axes_signals_t motor_alarm_pins;
+
+static void alarm_reset (void)
+{
+ if(on_reset)
+ on_reset();
+
+ motor_alarm_active = false;
+}
+
+static void execute_alarm (sys_state_t state)
+{
+
+ if(!motor_alarm_active){
+
+ uint32_t pins = flexgpio_read_inputs();
+
+ motor_alarm_pins.x = (pins >> X_ALARM_PIN) & 1U;
+ motor_alarm_pins.y = (pins >> Y_ALARM_PIN) & 1U;
+ motor_alarm_pins.z = (pins >> Z_ALARM_PIN) & 1U;
+ motor_alarm_pins.a = (pins >> M3_ALARM_PIN) & 1U;
+ motor_alarm_pins.b = (pins >> M4_ALARM_PIN) & 1U;
+ motor_alarm_pins.c = (pins >> M5_ALARM_PIN) & 1U;
+
+ if(motor_alarm_pins.x){
+ report_message("Motor Error on X Motor!", Message_Warning);
+ }
+
+ if(motor_alarm_pins.y){
+ report_message("Motor Error on Y Motor!", Message_Warning);
+ }
+
+ if(motor_alarm_pins.z){
+ report_message("Motor Error on Z Motor!", Message_Warning);
+ }
+
+ if(motor_alarm_pins.a){
+ report_message("Motor Error on A Motor!", Message_Warning);
+ }
+
+ if(motor_alarm_pins.b){
+ report_message("Motor Error on B Motor!", Message_Warning);
+ }
+
+ if(motor_alarm_pins.c){
+ report_message("Motor Error on C Motor!", Message_Warning);
+ }
+ motor_alarm_active = true;
+ }
+
+}
+
+static void check_alarm_state (sys_state_t state)
+{
+ if(on_state_change)
+ on_state_change(state);
+
+ if (state == STATE_ALARM){
+ if (sys.alarm == Alarm_MotorFault)
+ execute_alarm (state);
+ }
+}
+
+static inline uint32_t set_bit_cond(uint32_t mask, bool cond, uint8_t pin) {
+ return cond ? (mask | (1 << pin)) : (mask & ~(1 << pin));
+}
+
+static void flexgpio_update_pins (void){
+
+ // Initialize the FlexGPIO ports for the board
+ uint_fast8_t idx;
+ uint_fast8_t n_ports = sizeof(flexgpio_aux_out) / sizeof(xbar_t);
+ pin_function_t aux_out_base = Output_Aux0;
+
+ flexgpio_direction_mask = 0;
+ flexgpio_polarity_mask = 0;
+ flexgpio_enable_mask = 0;
+
+#if MOTOR_FAULT_ENABLE
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, settings.motor_fault_enable.x, X_ALARM_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.motor_fault_invert.x, X_ALARM_PIN);
+
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, settings.motor_fault_enable.y, Y_ALARM_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.motor_fault_invert.y, Y_ALARM_PIN);
+
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, settings.motor_fault_enable.z, Z_ALARM_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.motor_fault_invert.z, Z_ALARM_PIN);
+
+ #if N_ABC_MOTORS > 0
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, settings.motor_fault_enable.a, M3_ALARM_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.motor_fault_invert.a, M3_ALARM_PIN);
+ #endif
+
+ #if N_ABC_MOTORS >= 2
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, settings.motor_fault_enable.b, M4_ALARM_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.motor_fault_invert.b, M4_ALARM_PIN);
+ #endif
+
+ #if N_ABC_MOTORS >= 2
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, settings.motor_fault_enable.b, M5_ALARM_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.motor_fault_invert.b, M5_ALARM_PIN);
+ #endif
+#endif
+
+#if PROBE_ENABLE
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, 1, PROBE_EXPANDER_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.probe.invert_probe_pin, PROBE_EXPANDER_PIN);
+
+ //need to make the inversion match the GRBLHAL setting. I think this is just the easiest way to handle this.
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.probe.invert_probe_pin, MCU_PROBE_PIN);
+
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, 1, TOOL_EXPANDER_PIN);
+ flexgpio_polarity_mask = set_bit_cond(flexgpio_polarity_mask, settings.probe.invert_toolsetter_input, TOOL_EXPANDER_PIN);
+#else
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, 0, PROBE_EXPANDER_PIN);
+
+ flexgpio_enable_mask = set_bit_cond(flexgpio_enable_mask, 0, TOOL_EXPANDER_PIN);
+#endif
+
+ for (idx = 0; idx < n_ports; idx++) {
+ flexgpio_aux_out[idx].id = idx;
+ flexgpio_aux_out[idx].port = &flexgpio_outpins;
+
+ //need to explicitly assign pin functions for the board as pins are not sequential
+ switch (idx) {
+ case 0:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT0_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 0;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT0_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT0_PIN);
+ break;
+ case 1:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT1_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 1;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT1_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT1_PIN);
+ break;
+ case 2:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT2_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 2;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT2_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT2_PIN);
+ break;
+ case 3:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT3_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 3;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT3_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT3_PIN);
+ break;
+ case 4:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT4_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 4;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT4_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT4_PIN);
+ break;
+ case 5:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT5_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 5;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT5_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT5_PIN);
+ break;
+ case 6:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT6_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 6;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT6_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT6_PIN);
+ break;
+ case 7:
+ flexgpio_aux_out[idx].pin = AUXOUTPUT7_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 7;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_direction_mask |= (1U << AUXOUTPUT7_PIN);
+ flexgpio_enable_mask |= (1U << AUXOUTPUT7_PIN);
+ break;
+ case 8:
+ flexgpio_aux_out[idx].pin = SPINDLE_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 8;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "Spindle Enable";
+ flexgpio_direction_mask |= (1U << SPINDLE_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << SPINDLE_ENABLE_PIN);
+ break;
+ case 9:
+ flexgpio_aux_out[idx].pin = SPINDLE_DIRECTION_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 9;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "Spindle Direction";
+ flexgpio_direction_mask |= (1U << SPINDLE_DIRECTION_PIN);
+ flexgpio_enable_mask |= (1U << SPINDLE_DIRECTION_PIN);
+ break;
+ case 10:
+ flexgpio_aux_out[idx].pin = COOLANT_FLOOD_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 10;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "Flood Coolant";
+ flexgpio_direction_mask |= (1U << COOLANT_FLOOD_PIN);
+ flexgpio_enable_mask |= (1U << COOLANT_FLOOD_PIN);
+ break;
+ case 11:
+ flexgpio_aux_out[idx].pin = COOLANT_MIST_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 11;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "Mist Coolant";
+ flexgpio_direction_mask |= (1U << COOLANT_MIST_PIN);
+ flexgpio_enable_mask |= (1U << COOLANT_MIST_PIN);
+ break;
+ case 12:
+ flexgpio_aux_out[idx].pin = X_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 12;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "X Stepper Enable";
+ flexgpio_direction_mask |= (1U << X_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << X_ENABLE_PIN);
+ break;
+ case 13:
+ flexgpio_aux_out[idx].pin = Y_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 13;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "Y Stepper Enable";
+ flexgpio_direction_mask |= (1U << Y_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << Y_ENABLE_PIN);
+ break;
+ case 14:
+ flexgpio_aux_out[idx].pin = Z_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 14;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "Z Stepper Enable";
+ flexgpio_direction_mask |= (1U << Z_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << Z_ENABLE_PIN);
+ break;
+#ifdef M3_ENABLE_PIN
+ case 15:
+ flexgpio_aux_out[idx].pin = M3_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 15;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "A Stepper Enable";
+ flexgpio_direction_mask |= (1U << M3_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << M3_ENABLE_PIN);
+ break;
+#endif
+#ifdef M4_ENABLE_PIN
+ case 16:
+ flexgpio_aux_out[idx].pin = M4_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 16;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "B Stepper Enable";
+ flexgpio_direction_mask |= (1U << M4_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << M4_ENABLE_PIN);
+ break;
+#endif
+#ifdef M5_ENABLE_PIN
+ case 17:
+ flexgpio_aux_out[idx].pin = M5_ENABLE_PIN;
+ flexgpio_aux_out[idx].function = aux_out_base + 17;
+ flexgpio_aux_out[idx].group = PinGroup_AuxOutput;
+ flexgpio_aux_out[idx].cap.output = On;
+ flexgpio_aux_out[idx].cap.external = On;
+ flexgpio_aux_out[idx].cap.claimable = On;
+ flexgpio_aux_out[idx].mode.output = On;
+ flexgpio_aux_out[idx].description = "C Stepper Enable";
+ flexgpio_direction_mask |= (1U << M5_ENABLE_PIN);
+ flexgpio_enable_mask |= (1U << M5_ENABLE_PIN);
+ break;
+#endif
+ default:
+ flexgpio_aux_out[idx].function = Input_Unassigned;
+ flexgpio_aux_out[idx].group = PinGroup_Virtual;
+ flexgpio_aux_out[idx].cap.output = Off;
+ flexgpio_aux_out[idx].cap.external = Off;
+ flexgpio_aux_out[idx].cap.claimable = Off;
+ flexgpio_aux_out[idx].mode.output = Off;
+ break;
+ }//close switch statement
+ }//close for statement
+
+}
+
+static void onSettingsChanged (settings_t *settings, settings_changed_flags_t changed)
+{
+ if(on_settings_changed)
+ on_settings_changed(settings, changed);
+
+ flexgpio_update_pins();
+ flexgpio_write_config();
+}
+
+void board_ports_init(void) {
+ flexgpio_update_pins();
+
+#if 1
+
+
+#if MOTOR_FAULT_ENABLE
+ on_reset = grbl.on_reset;
+ grbl.on_reset = alarm_reset;
+
+ on_state_change = grbl.on_state_change;
+ grbl.on_state_change = check_alarm_state;
+
+#endif
+
+ on_settings_changed = grbl.on_settings_changed;
+ grbl.on_settings_changed = onSettingsChanged;
+
+#endif
+}
+
+void board_init (void)
+{
+
+ #if 1
+
+ gpio_set_function(SPI_MOSI_PIN, GPIO_FUNC_SIO);
+ gpio_set_dir(SPI_MOSI_PIN, 1);
+ gpio_put(SPI_MOSI_PIN,1);
+ gpio_set_function(SPI_MOSI_PIN, GPIO_FUNC_SIO);
+ gpio_set_dir(SPI_MISO_PIN, 1);
+ gpio_put(SPI_MISO_PIN,1);
+ gpio_set_function(SPI_SCK_PIN, GPIO_FUNC_SIO);
+ gpio_set_dir(SPI_SCK_PIN, 1);
+ gpio_put(SPI_SCK_PIN,1);
+ gpio_set_function(SD_CS_PIN, GPIO_FUNC_SIO);
+ gpio_set_dir(SD_CS_PIN, 1);
+ gpio_put(SD_CS_PIN,1);
+ gpio_set_function(33, GPIO_FUNC_SIO);
+ gpio_set_dir(33, 1);
+ gpio_put(33,1);
+
+
+ volatile uint32_t dly = 1000;
+ volatile uint32_t count = 100;
+
+ while(--dly)
+ tight_loop_contents();
+
+ while(--count) {
+ gpio_put(SPI_SCK_PIN,1);
+ dly = 100; // Reset dly before first delay
+ while(--dly)
+ tight_loop_contents();
+
+ gpio_put(SPI_SCK_PIN,0);
+ dly = 100; // Reset dly before second delay
+ while(--dly)
+ tight_loop_contents();;
+ }
+
+ //sdcard_getfs(); // Mounts SD card if not already mounted
+ #endif
+
+ //flexgpio_update_pins();
+
+ /*if((alm_nvs_address = nvs_alloc(sizeof(motor_alarm_settings_t)))) {
+ settings_register(&setting_details);
+ } */
+
+ hal.driver_cap.toolsetter = 1;
+
+ hal.motor_fault_cap.a.x = 1;
+ hal.motor_fault_cap.a.y = 1;
+ hal.motor_fault_cap.a.z = 1;
+ hal.motor_fault_cap.a.a = 1;
+ hal.motor_fault_cap.a.b = 1;
+ hal.motor_fault_cap.a.c = 1;
+}
+
+
+
+
+#endif
diff --git a/boards/flexihal2350_map.h b/boards/flexihal2350_map.h
new file mode 100644
index 0000000..141bd9f
--- /dev/null
+++ b/boards/flexihal2350_map.h
@@ -0,0 +1,217 @@
+/*
+ FlexiHAL 2350 driver pin map
+
+ Part of grblHAL
+
+ Copyright (c) 2024 Terje Io
+ Copyright (c) 2024 PL Barrett
+
+ grblHAL is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ grblHAL is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with grblHAL. If not, see .
+*/
+
+#if TRINAMIC_ENABLE
+#error Trinamic plugin not supported!
+#endif
+
+#if N_ABC_MOTORS > 3
+#error "Axis configuration is not supported!"
+#endif
+
+#if RP_MCU != 2350
+#error "Board has a RP2350 processor!"
+#endif
+
+#define BOARD_NAME "FLEXIHAL2350"
+#define USE_EXPANDERS
+#define HAS_BOARD_INIT
+
+#undef I2C_ENABLE
+#undef EEPROM_ENABLE
+#define I2C_ENABLE 1
+#define EEPROM_ENABLE 2
+
+#define FLEXGPIO_ENABLE 1
+
+// Define step pulse output pins.
+#define STEP_PORT GPIO_PIO_1 // Single pin PIO SM
+#define X_STEP_PIN 12
+#define Y_STEP_PIN 14
+#define Z_STEP_PIN 16
+
+// Define step direction output pins.
+#define DIRECTION_PORT GPIO_OUTPUT
+#define DIRECTION_OUTMODE GPIO_MAP
+#define X_DIRECTION_PIN 13
+#define Y_DIRECTION_PIN 15
+#define Z_DIRECTION_PIN 17
+
+// Define stepper driver enable/disable output pins.
+#define ENABLE_PORT EXPANDER_PORT
+#define X_ENABLE_PIN 29 //RP2040 pin
+#define Y_ENABLE_PIN 28 //RP2040 pin
+#define Z_ENABLE_PIN 27 //RP2040 pin
+
+// Define alarm pins.
+#define MOTOR_ALARM_PORT EXPANDER_PORT
+#define X_ALARM_PIN 5 //RP2040 pin
+#define Y_ALARM_PIN 6 //RP2040 pin
+#define Z_ALARM_PIN 7 //RP2040 pin
+
+// Define homing/hard limit switch input pins.
+#define X_LIMIT_PIN 38
+#define Y_LIMIT_PIN 37
+#define Z_LIMIT_PIN 36
+#define LIMIT_INMODE GPIO_MAP
+
+// Define ganged axis or A axis step pulse and step direction output pins.
+#if N_ABC_MOTORS > 0
+#define M3_AVAILABLE
+#define M3_STEP_PIN 18
+#define M3_DIRECTION_PIN 19
+#define M3_LIMIT_PIN 35
+#define M3_ENABLE_PORT EXPANDER_PORT
+#define M3_ENABLE_PIN 26 //RP2040 pin
+#define M3_ALARM_PIN 8 //RP2040 pin
+#endif
+
+#if N_ABC_MOTORS >= 2
+#define M4_AVAILABLE
+#define M4_STEP_PIN 20
+#define M4_DIRECTION_PIN 21
+#define M4_ENABLE_PORT EXPANDER_PORT
+#define M4_LIMIT_PIN 34
+#define M4_ENABLE_PIN 25 //RP2040 pin
+#define M4_ALARM_PIN 9 //RP2040 pin
+#endif
+
+#if N_ABC_MOTORS == 3
+#define M5_AVAILABLE
+#define M5_STEP_PIN 22
+#define M5_DIRECTION_PIN 23
+#define M5_ENABLE_PORT EXPANDER_PORT
+#define M5_ENABLE_PIN 24 //RP2040 pin
+#define M5_ALARM_PIN 10 //RP2040 pin
+#endif
+
+#define NUM_FLEXGPIO_AUXOUT 15+N_ABC_MOTORS //includes enables, coolant and spindle pins
+ //These are set up in the board init
+#define AUXOUTPUT0_PORT EXPANDER_PORT
+#define AUXOUTPUT0_PIN 23 //RP2040 pin
+#define AUXOUTPUT1_PORT EXPANDER_PORT
+#define AUXOUTPUT1_PIN 22 //RP2040 pin
+#define AUXOUTPUT2_PORT EXPANDER_PORT
+#define AUXOUTPUT2_PIN 21 //RP2040 pin
+#define AUXOUTPUT3_PORT EXPANDER_PORT
+#define AUXOUTPUT3_PIN 20 //RP2040 pin
+#define AUXOUTPUT4_PORT EXPANDER_PORT
+#define AUXOUTPUT4_PIN 19 //RP2040 pin
+#define AUXOUTPUT5_PORT EXPANDER_PORT
+#define AUXOUTPUT5_PIN 18 //RP2040 pin
+#define AUXOUTPUT6_PORT EXPANDER_PORT
+#define AUXOUTPUT6_PIN 17 //RP2040 pin
+#define AUXOUTPUT7_PORT EXPANDER_PORT
+#define AUXOUTPUT7_PIN 16 //RP2040 pin
+
+#if COOLANT_ENABLE
+#define COOLANT_PORT EXPANDER_PORT
+#endif
+#if COOLANT_ENABLE & COOLANT_MIST
+#define COOLANT_MIST_PIN 13 //RP2040 pin
+#endif
+#if COOLANT_ENABLE & COOLANT_FLOOD
+#define COOLANT_FLOOD_PIN 14 //RP2040 pin
+#endif
+
+#if DRIVER_SPINDLE_ENABLE
+#define SPINDLE_PORT EXPANDER_PORT
+#define SPINDLE_ENABLE_PORT EXPANDER_PORT
+#define SPINDLE_DIRECTION_PORT EXPANDER_PORT
+#define SPINDLE_PWM_PORT GPIO_OUTPUT // Spindle PWM
+#endif
+#if DRIVER_SPINDLE_ENABLE & SPINDLE_ENA
+#define SPINDLE_ENABLE_PIN 11 //RP2040 pin
+#endif
+#if DRIVER_SPINDLE_ENABLE & SPINDLE_PWM
+#define SPINDLE_PWM_PIN 26
+#endif
+#if DRIVER_SPINDLE_ENABLE & SPINDLE_DIR
+#define SPINDLE_DIRECTION_PIN 12 //RP2040 pin
+#endif
+
+#define RESET_PIN 24
+#define FEED_HOLD_PIN 27
+#define CYCLE_START_PIN 30
+
+#define AUXINPUT0_PIN 47 //Encoder 2
+#define AUXINPUT1_PIN 46 //Encoder 2
+#define AUXINPUT2_PIN 45 //Encoder 2
+
+#define AUXINPUT3_PIN 9 //Encoder 1
+#define AUXINPUT4_PIN 10 //Encoder 1
+#define AUXINPUT5_PIN 11 //Encoder 1
+
+#define AUXINPUT6_PIN 32 // Safety door
+#define AUXINPUT7_PIN 31 // Motor Alarm
+//#define AUXINPUT8_PIN 39 // Probe
+
+//#define AUXINPUT9_PIN 8 // I2C strobe pin
+
+#if PROBE_ENABLE
+#define PROBE_PORT GPIO_INPUT
+#define PROBE_PIN 39
+#define PROBE_EXPANDER_PIN 4 //RP2040 pin
+#define TOOL_EXPANDER_PIN 3 //RP2040 pin
+#define MCU_PROBE_PIN 15 //rp2040 output pin
+#endif
+
+#if MOTOR_FAULT_ENABLE
+#define MOTOR_FAULT_PORT GPIO_INPUT
+#define MOTOR_FAULT_PIN 31
+#endif
+
+#if SAFETY_DOOR_ENABLE
+#define SAFETY_DOOR_PIN AUXINPUT6_PIN
+#endif
+
+#if I2C_STROBE_ENABLE
+#define I2C_STROBE_PORT GPIO_INPUT
+#define I2C_STROBE_PIN 8
+#endif
+
+#if SDCARD_ENABLE || ETHERNET_ENABLE
+
+#define SPI_PORT 0
+#define SPI_SCK_PIN 2
+#define SPI_MOSI_PIN 3
+#define SPI_MISO_PIN 0
+#define SD_CS_PIN 44
+
+#if ETHERNET_ENABLE
+#define SPI_CS_PIN 33
+#define SPI_IRQ_PIN 25
+#endif
+
+#endif // SDCARD_ENABLE || ETHERNET_ENABLE
+
+#if I2C_ENABLE
+#define I2C_PORT 1
+#define I2C_SDA 6
+#define I2C_SCL 7
+#endif
+
+#if MODBUS_ENABLE
+#define MODBUS_RTU_STREAM 0
+#define UART_RX_PIN 29
+#define UART_TX_PIN 28
+#endif
diff --git a/driver.c b/driver.c
index 90901e9..7beea26 100644
--- a/driver.c
+++ b/driver.c
@@ -55,7 +55,7 @@
#include "driverPIO.pio.h"
#include "ws2812.pio.h"
-#define AUX_DEVICES // until all drivers are converted?
+//#define AUX_DEVICES // until all drivers are converted? **AM Could not get the board to properly enumerate the ports without removing this.
#ifndef AUX_CONTROLS
#define AUX_CONTROLS (AUX_CONTROL_SPINDLE|AUX_CONTROL_COOLANT)
#endif
@@ -149,7 +149,7 @@ static uint z2_step_sm;
#endif
#ifdef A_STEP_PIN
static PIO a_step_pio;
-static uint a_step_sm;f
+static uint a_step_sm;
#endif
#ifdef B_STEP_PIN
static PIO b_step_pio;
@@ -219,7 +219,7 @@ static input_signal_t *safety_door;
#endif
#ifdef USE_EXPANDERS
-static xbar_t *iox_out[16] = {};
+static xbar_t *iox_out[32] = {};
#endif
#ifdef NEOPIXELS_PIN
@@ -565,28 +565,28 @@ static output_signal_t outputpin[] = {
#ifdef LED_W_PIN
{ .id = Output_LED_W, .port = GPIO_OUTPUT, .pin = LED_W_PIN, .group = PinGroup_LED },
#endif
-#ifdef AUXOUTPUT0_PORT
+#if add_pin (AUXOUTPUT0_PIN)
{ .id = Output_Aux0, .port = AUXOUTPUT0_PORT, .pin = AUXOUTPUT0_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT1_PORT
+#if add_pin (AUXOUTPUT1_PIN)
{ .id = Output_Aux1, .port = AUXOUTPUT1_PORT, .pin = AUXOUTPUT1_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT2_PORT
+#if add_pin (AUXOUTPUT2_PIN)
{ .id = Output_Aux2, .port = AUXOUTPUT2_PORT, .pin = AUXOUTPUT2_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT3_PORT
+#if add_pin (AUXOUTPUT3_PIN)
{ .id = Output_Aux3, .port = AUXOUTPUT3_PORT, .pin = AUXOUTPUT3_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT4_PORT
+#if add_pin (AUXOUTPUT4_PIN)
{ .id = Output_Aux4, .port = AUXOUTPUT4_PORT, .pin = AUXOUTPUT4_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT5_PORT
+#if add_pin (AUXOUTPUT5_PIN)
{ .id = Output_Aux5, .port = AUXOUTPUT5_PORT, .pin = AUXOUTPUT5_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT6_PORT
+#if add_pin (AUXOUTPUT6_PIN)
{ .id = Output_Aux6, .port = AUXOUTPUT6_PORT, .pin = AUXOUTPUT6_PIN, .group = PinGroup_AuxOutput},
#endif
-#ifdef AUXOUTPUT7_PORT
+#if add_pin (AUXOUTPUT7_PIN)
{ .id = Output_Aux7, .port = AUXOUTPUT7_PORT, .pin = AUXOUTPUT7_PIN, .group = PinGroup_AuxOutput},
#endif
#ifdef AUXOUTPUT0_PWM_PIN
diff --git a/driver.h b/driver.h
index a171251..880f333 100644
--- a/driver.h
+++ b/driver.h
@@ -79,7 +79,11 @@
#endif
#define EXPANDER_IN(pin) (iox_out[pin] && iox_out[pin]->get_value(iox_out[pin]) != 0.0f)
-#define EXPANDER_OUT(pin, state) { if(iox_out[pin]) iox_out[pin]->set_value(iox_out[pin], (float)(state)); }
+#define EXPANDER_OUT(pin, state) \
+ do { \
+ if ((pin) >= 0 && (pin) < 32 && iox_out[(pin)]) \
+ iox_out[(pin)]->set_value(iox_out[(pin)], (float)(state)); \
+ } while (0)
#define GPIO_IRQ_ALL (GPIO_IRQ_LEVEL_HIGH|GPIO_IRQ_LEVEL_LOW|GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL)
@@ -176,6 +180,8 @@
#include "boards/generic_map_4axis.h"
#elif defined(BOARD_GENERIC_8AXIS)
#include "boards/generic_map_8axis.h"
+#elif defined(BOARD_FLEXIHAL2350)
+ #include "boards/flexihal2350_map.h"
#else // default board
#include "boards/generic_map.h"
#endif
diff --git a/driver.json b/driver.json
index 6cf4646..e509894 100644
--- a/driver.json
+++ b/driver.json
@@ -259,6 +259,28 @@
"RP_MCU": "2350",
"RP_BOARD": "pico2"
}
- }
+ },
+ {
+ "name": "FLEXIHAL2350",
+ "symbol": "BOARD_FLEXIHAL2350",
+ "URL": "https://github.com/Expatria-Technologies/FlexiHAL-Pro",
+ "MAP": "boards/flexihal2350_map.h",
+ "caps": {
+ "axes": 6,
+ "digital_in": 1,
+ "digital_out": 3,
+ "i2c_strobe": 1,
+ "eeprom": 1,
+ "fram": 0,
+ "i2c": 1,
+ "sdcard": 2,
+ "wifi": 0,
+ "wiznet": 1,
+ "bluetooth": 0
+ },
+ "symbols": {
+ "RP_MCU": "2350"
+ }
+ }
]
}
diff --git a/flexgpio b/flexgpio
new file mode 160000
index 0000000..01aa7ab
--- /dev/null
+++ b/flexgpio
@@ -0,0 +1 @@
+Subproject commit 01aa7ab0e3b89211fd57dbd7ba9312eb019be4b0
diff --git a/grbl b/grbl
index 070f80c..08671a0 160000
--- a/grbl
+++ b/grbl
@@ -1 +1 @@
-Subproject commit 070f80cc5c0d095ff63d5980795b5a15c5bb0202
+Subproject commit 08671a02eb0fbed50f9492ce5f217adbf2f43a03
diff --git a/my_machine.h b/my_machine.h
index e25644d..260fb69 100644
--- a/my_machine.h
+++ b/my_machine.h
@@ -34,6 +34,7 @@
//#define BOARD_GENERIC_4AXIS
//#define BOARD_GENERIC_8AXIS
//#define BOARD_MY_MACHINE // Add my_machine_map.h before enabling this!
+#define BOARD_FLEXIHAL2350
// Configuration
// Uncomment to enable.
@@ -48,28 +49,28 @@
// If none are specified the default PWM spindle is instantiated.
// Spindle definitions can be found in grbl/spindle_control.h.
// More here https://github.com/grblHAL/Plugins_spindle
-//#define SPINDLE0_ENABLE SPINDLE_HUANYANG1
-//#define SPINDLE1_ENABLE SPINDLE_PWM0
+#define SPINDLE0_ENABLE SPINDLE_GS20
+#define SPINDLE1_ENABLE SPINDLE_PWM0
//#define SPINDLE2_ENABLE SPINDLE_NONE
//#define SPINDLE2_ENABLE SPINDLE_NONE
//#define SPINDLE_OFFSET 1 // Set to 1 to add offset move when switching between laser and spindle
// **********************
-//#define MODBUS_ENABLE 1 // Set to 1 for auto direction, 2 for direction signal on auxiliary output pin.
+#define MODBUS_ENABLE 1 // Set to 1 for auto direction, 2 for direction signal on auxiliary output pin.
//#define WIFI_ENABLE 0 // Do NOT enable here, enable in CMakeLists.txt!
//#define WIFI_SOFTAP 1 // Use Soft AP mode for WiFi. NOTE: WIP - not yet complete!
//#define ETHERNET_ENABLE 0 // Do NOT enable here, enable in CMakeLists.txt!
-//#define _WIZCHIP_ 5500 // Selects WIZnet ethernet breakout connected via SPI.
+#define _WIZCHIP_ 5500 // Selects WIZnet ethernet breakout connected via SPI.
// Uncomment to enable W5500 chip, default is W5100S. Requires ethernet enabled in CMakeLists.txt.
//#define WEBUI_ENABLE 3 // Enable ESP3D-WEBUI plugin along with networking and SD card plugins. Requires WiFi enabled.
//#define WEBUI_AUTH_ENABLE 1 // Enable ESP3D-WEBUI authentication.
//#define WEBUI_INFLASH 0 // Uncomment to store WebUI files on SD card instead of in flash (littlefs).
-//#define SDCARD_ENABLE 2 // Run gcode programs from SD card. Set to 2 to enable YModem upload.
+#define SDCARD_ENABLE 2 // Run gcode programs from SD card. Set to 2 to enable YModem upload.
//#define MPG_ENABLE 2 // Enable MPG interface. Requires a serial stream and means to switch between normal and MPG mode.
// 1: Mode switching is by handshake pin.
// 2: Mode switching is by the CMD_MPG_MODE_TOGGLE (0x8B) command character.
-//#define KEYPAD_ENABLE 1 // 1: uses a I2C keypad for input.
+#define KEYPAD_ENABLE 1 // 1: uses a I2C keypad for input.
// 2: uses a serial stream for input. If MPG_ENABLE is set > 0 the serial stream is shared with the MPG.
-//#define DISPLAY_ENABLE 9 // Set to 9 for I2C display protocol, 17 for I2C LED protocol.
+#define DISPLAY_ENABLE 9 // Set to 9 for I2C display protocol, 17 for I2C LED protocol.
//#define ODOMETER_ENABLE 1 // Odometer plugin.
//#define PLASMA_ENABLE 1 // Plasma (THC) plugin. To be completed.
//#define LASER_COOLANT_ENABLE 1 // Laser coolant plugin. To be completed.
@@ -80,7 +81,7 @@
//#define TRINAMIC_ENABLE 1 // Trinamic TMC2130 stepper driver support. NOTE: work in progress.
//#define TRINAMIC_I2C 1 // Trinamic I2C - SPI bridge interface.
//#define TRINAMIC_DEV 1 // Development mode, adds a few M-codes to aid debugging. Do not enable in production code.
-//#define EEPROM_ENABLE 16 // I2C EEPROM/FRAM support. Set to 16 for 2K, 32 for 4K, 64 for 8K, 128 for 16K and 256 for 16K capacity.
+#define EEPROM_ENABLE 64 // I2C EEPROM/FRAM support. Set to 16 for 2K, 32 for 4K, 64 for 8K, 128 for 16K and 256 for 16K capacity.
//#define EEPROM_IS_FRAM 1 // Uncomment when EEPROM is enabled and chip is FRAM, this to remove write delay.
//#define STEP_INJECT_ENABLE 1
//#define RGB_LED_ENABLE 2 // Set to 1 to enable strip length settings $536 and $537, set to 2 to also enable M150 LED strip control.
@@ -97,12 +98,14 @@
//#define MCP4725_ENABLE 1 // MCP3221 I2C ADC input, default address is 0xC0 (MCP3221_ADDRESS).
//#define PCA9654E_ENABLE 1 // PCA9654E I2C digital I/O, default address is 0x40 (PCA9654E_ADDRESS).
+#define FLEXGPIO_ENABLE 1
+
// Optional control signals:
// These will be assigned to aux input pins. Use the $pins command to check which pins are assigned.
// NOTE: If not enough pins are available assignment will silently fail.
//#define PROBE_ENABLE 0 // Default enabled, remove comment to disable probe input.
//#define SAFETY_DOOR_ENABLE 1
-//#define MOTOR_FAULT_ENABLE 1
+#define MOTOR_FAULT_ENABLE 1
//#define MOTOR_WARNING_ENABLE 1
//#define PROBE_DISCONNECT_ENABLE 1
//#define STOP_DISABLE_ENABLE 1
@@ -137,7 +140,7 @@
#endif
// The following symbols have the default values as shown, uncomment and change as needed.
//#define NETWORK_STA_HOSTNAME "grblHAL"
-//#define NETWORK_STA_IPMODE 1 // 0 = static, 1 = DHCP, 2 = AutoIP
+#define NETWORK_STA_IPMODE 0 // 0 = static, 1 = DHCP, 2 = AutoIP
//#define NETWORK_STA_IP "192.168.5.1"
//#define NETWORK_STA_GATEWAY "192.168.5.1"
//#define NETWORK_STA_MASK "255.255.255.0"