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"