mirror of
https://github.com/grblHAL/core.git
synced 2026-02-05 08:34:01 +08:00
Added soft limits check for corexy kinematics, ref. discussion #536.
Added high level CANbus API for plugin use. Ref. issue #179.
This commit is contained in:
@@ -33,6 +33,7 @@ target_sources(grbl INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/regex.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/ioports.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/vfs.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/canbus.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/kinematics/corexy.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/kinematics/wall_plotter.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/kinematics/delta.c
|
||||
|
||||
@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
|
||||
|
||||
---
|
||||
|
||||
Latest build date is 20240624, see the [changelog](changelog.md) for details.
|
||||
Latest build date is 20240704, see the [changelog](changelog.md) for details.
|
||||
|
||||
__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
|
||||
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.
|
||||
|
||||
209
canbus.c
Normal file
209
canbus.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
|
||||
canbus.c -
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2022 Jon Escombe
|
||||
Copyright (c) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "task.h"
|
||||
#include "protocol.h"
|
||||
#include "canbus.h"
|
||||
|
||||
#ifndef CANBUS_BUFFER_LEN
|
||||
#define CANBUS_BUFFER_LEN 8
|
||||
#endif
|
||||
#ifndef CANBUS_BAUDRATE
|
||||
#define CANBUS_BAUDRATE 0 // 125,000
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
volatile canbus_message_t message;
|
||||
can_rx_ptr callback;
|
||||
} canbus_rx_message;
|
||||
|
||||
typedef struct {
|
||||
volatile canbus_message_t message;
|
||||
bool ext_id;
|
||||
} canbus_tx_message;
|
||||
|
||||
typedef struct {
|
||||
volatile uint8_t head;
|
||||
volatile uint8_t tail;
|
||||
volatile canbus_tx_message tx[CANBUS_BUFFER_LEN];
|
||||
} canbus_tx_buffer_t;
|
||||
|
||||
typedef struct {
|
||||
volatile uint8_t head;
|
||||
volatile uint8_t tail;
|
||||
volatile canbus_rx_message rx[CANBUS_BUFFER_LEN];
|
||||
} canbus_rx_buffer_t;
|
||||
|
||||
static bool isEnabled = false;
|
||||
static const uint32_t baud[] = { 125000, 250000, 500000, 1000000 };
|
||||
static canbus_tx_buffer_t tx_buffer = {0};
|
||||
static canbus_rx_buffer_t rx_buffer = {0};
|
||||
|
||||
// Weak implementations of low level functions to be provided by the driver
|
||||
|
||||
__attribute__((weak)) bool can_start (uint32_t baud, can_rx_enqueue_fn callback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool can_stop (void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool can_set_baud (uint32_t baud)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool can_put (canbus_message_t msg, bool ext_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool can_add_filter (uint32_t id, uint32_t mask, bool ext_id, can_rx_ptr callback)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
ISR_CODE static bool ISR_FUNC(canbus_queue_rx)(canbus_message_t message, can_rx_ptr callback)
|
||||
{
|
||||
bool ok;
|
||||
uint8_t next_head = (rx_buffer.head + 1) % CANBUS_BUFFER_LEN;
|
||||
|
||||
if((ok = next_head != rx_buffer.tail)) {
|
||||
rx_buffer.rx[next_head].callback = callback;
|
||||
rx_buffer.rx[next_head].message = message;
|
||||
|
||||
rx_buffer.head = next_head;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// called every 1 ms
|
||||
static void canbus_poll (void *data)
|
||||
{
|
||||
/* if have TX data, sends one message per iteration.. */
|
||||
if(tx_buffer.head != tx_buffer.tail && can_put(tx_buffer.tx[tx_buffer.tail].message, tx_buffer.tx[tx_buffer.tail].ext_id))
|
||||
tx_buffer.tail = (tx_buffer.tail + 1) % CANBUS_BUFFER_LEN;
|
||||
|
||||
/* if have RX data, process one message per iteration.. */
|
||||
if(rx_buffer.head != rx_buffer.tail) {
|
||||
if(rx_buffer.rx[rx_buffer.tail].callback)
|
||||
rx_buffer.rx[rx_buffer.tail].callback(rx_buffer.rx[rx_buffer.tail].message);
|
||||
rx_buffer.tail = (rx_buffer.tail + 1) % CANBUS_BUFFER_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
static bool canbus_start (uint32_t baud)
|
||||
{
|
||||
if((isEnabled = can_start(baud, canbus_queue_rx)))
|
||||
task_add_systick(canbus_poll, NULL);
|
||||
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
static status_code_t canbus_set_baud (setting_id_t id, uint_fast16_t value)
|
||||
{
|
||||
settings.canbus_baud = value;
|
||||
|
||||
can_set_baud(baud[settings.canbus_baud]);
|
||||
|
||||
return can_set_baud(baud[settings.canbus_baud]) ? Status_OK : Status_SettingValueOutOfRange;
|
||||
}
|
||||
|
||||
static uint32_t canbus_get_baud (setting_id_t setting)
|
||||
{
|
||||
return settings.canbus_baud < (sizeof(baud) / sizeof(uint32_t)) ? settings.canbus_baud : CANBUS_BAUDRATE;
|
||||
}
|
||||
|
||||
static const setting_group_detail_t canbus_groups [] = {
|
||||
{ Group_Root, Group_CANbus, "CAN bus"}
|
||||
};
|
||||
|
||||
static const setting_detail_t canbus_setting_detail[] = {
|
||||
{ Setting_CANbus_BaudRate, Group_CANbus, "CAN bus baud rate", NULL, Format_RadioButtons, "125000,250000,500000,1000000", NULL, NULL, Setting_NonCoreFn, canbus_set_baud, canbus_get_baud, NULL },
|
||||
};
|
||||
|
||||
static void canbus_settings_restore (void)
|
||||
{
|
||||
settings.canbus_baud = CANBUS_BAUDRATE;
|
||||
|
||||
settings_write_global();
|
||||
}
|
||||
|
||||
static void canbus_settings_load (void)
|
||||
{
|
||||
canbus_start(baud[canbus_get_baud(Setting_CANbus_BaudRate)]);
|
||||
}
|
||||
|
||||
static setting_details_t setting_details = {
|
||||
.groups = canbus_groups,
|
||||
.n_groups = sizeof(canbus_groups) / sizeof(setting_group_detail_t),
|
||||
.settings = canbus_setting_detail,
|
||||
.n_settings = sizeof(canbus_setting_detail) / sizeof(setting_detail_t),
|
||||
.save = settings_write_global,
|
||||
.load = canbus_settings_load,
|
||||
.restore = canbus_settings_restore
|
||||
};
|
||||
|
||||
// Public API
|
||||
|
||||
bool canbus_enabled (void)
|
||||
{
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
bool canbus_queue_tx (canbus_message_t message, bool ext_id)
|
||||
{
|
||||
bool ok;
|
||||
uint8_t next_head = (tx_buffer.head + 1) % CANBUS_BUFFER_LEN;
|
||||
|
||||
if((ok = next_head != tx_buffer.tail)) {
|
||||
tx_buffer.tx[tx_buffer.head].ext_id = ext_id;
|
||||
tx_buffer.tx[tx_buffer.head].message = message;
|
||||
tx_buffer.head = next_head;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool canbus_add_filter (uint32_t id, uint32_t mask, bool ext_id, can_rx_ptr callback)
|
||||
{
|
||||
return can_add_filter(id, mask, ext_id, callback);
|
||||
}
|
||||
|
||||
void canbus_init (void)
|
||||
{
|
||||
static bool init_ok = false;
|
||||
|
||||
if(!init_ok) {
|
||||
init_ok = true;
|
||||
settings_register(&setting_details);
|
||||
}
|
||||
}
|
||||
48
canbus.h
Normal file
48
canbus.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
|
||||
canbus.h -
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2022 Jon Escombe
|
||||
Copyright (c) 2024 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _CANBUS_H_
|
||||
#define _CANBUS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint8_t len;
|
||||
uint8_t data[8];
|
||||
} canbus_message_t;
|
||||
|
||||
typedef bool (*can_rx_ptr)(canbus_message_t);
|
||||
typedef bool (*can_rx_enqueue_fn)(canbus_message_t msg, can_rx_ptr callback); // used internally by the driver
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
void canbus_init (void);
|
||||
bool canbus_enabled (void);
|
||||
bool canbus_queue_tx (canbus_message_t message, bool ext_id);
|
||||
bool canbus_add_filter (uint32_t id, uint32_t mask, bool ext_id, can_rx_ptr callback);
|
||||
|
||||
#endif /* _CANBUS_H_ */
|
||||
18
changelog.md
18
changelog.md
@@ -1,5 +1,23 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20240704"/>Build 20240704
|
||||
|
||||
Core:
|
||||
|
||||
* Added high level CANbus API for plugin use. If driver/board combo provides the required lowlevel HAL API the `NEWOPT` string in the `$I` output will contain the `CAN` element when CAN is enabled.
|
||||
Ref. [issue #179](https://github.com/grblHAL/STM32F4xx/issues/179).
|
||||
|
||||
* Added soft limits check for corexy kinematics, ref. [discussion #536](https://github.com/grblHAL/core/discussions/536).
|
||||
|
||||
Drivers:
|
||||
|
||||
* ESP32: fixed WebUI regression. Ref. [issue #116](https://github.com/grblHAL/ESP32/issues/116).
|
||||
|
||||
* STM32F7xx, STM32F4xx: Added lowlevel CANbus API and enabled it for some boards.
|
||||
|
||||
---
|
||||
|
||||
|
||||
<a name="20240624"/>Build 20240624
|
||||
|
||||
Core:
|
||||
|
||||
2
grbl.h
2
grbl.h
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20240624
|
||||
#define GRBL_BUILD 20240704
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define B_MOTOR Y_AXIS // Must be Y_AXIS
|
||||
|
||||
static on_report_options_ptr on_report_options;
|
||||
static travel_limits_ptr check_travel_limits;
|
||||
|
||||
// Returns x or y-axis "steps" based on CoreXY motor steps.
|
||||
inline static int32_t corexy_convert_to_a_motor_steps (int32_t *steps)
|
||||
@@ -77,12 +78,25 @@ static inline float *transform_from_cartesian (float *target, float *position)
|
||||
return target;
|
||||
}
|
||||
|
||||
// Transform position from motor (corexy) coordinate system to cartesian coordinate system
|
||||
static inline float *transform_to_cartesian (float *target, float *position)
|
||||
{
|
||||
uint_fast8_t idx;
|
||||
|
||||
target[X_AXIS] = (position[X_AXIS] + position[Y_AXIS]) * 0.5f;
|
||||
target[Y_AXIS] = (position[X_AXIS] - position[Y_AXIS]) * 0.5f;
|
||||
|
||||
for(idx = Z_AXIS; idx < N_AXIS; idx++)
|
||||
target[idx] = position[idx];
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
static uint_fast8_t corexy_limits_get_axis_mask (uint_fast8_t idx)
|
||||
{
|
||||
return ((idx == A_MOTOR) || (idx == B_MOTOR)) ? (bit(X_AXIS) | bit(Y_AXIS)) : bit(idx);
|
||||
}
|
||||
|
||||
|
||||
static void corexy_limits_set_target_pos (uint_fast8_t idx) // fn name?
|
||||
{
|
||||
int32_t axis_position;
|
||||
@@ -102,6 +116,19 @@ static void corexy_limits_set_target_pos (uint_fast8_t idx) // fn name?
|
||||
}
|
||||
}
|
||||
|
||||
// Checks and reports if target array exceeds machine travel limits. Returns false if check failed.
|
||||
// NOTE: target for axes X and Y are in motor coordinates if is_cartesian is false.
|
||||
static bool corexy_check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian)
|
||||
{
|
||||
if(is_cartesian)
|
||||
return check_travel_limits(target, axes, true);
|
||||
|
||||
float cartesian_coords[N_AXIS];
|
||||
|
||||
transform_to_cartesian(cartesian_coords, target);
|
||||
|
||||
return check_travel_limits(cartesian_coords, axes, true);
|
||||
}
|
||||
|
||||
// Set machine positions for homed limit switches. Don't update non-homed axes.
|
||||
// NOTE: settings.max_travel[] is stored as a negative value.
|
||||
@@ -207,7 +234,7 @@ static void report_options (bool newopt)
|
||||
on_report_options(newopt);
|
||||
|
||||
if(!newopt)
|
||||
hal.stream.write("[KINEMATICS:CoreXY v2.00]" ASCII_EOL);
|
||||
hal.stream.write("[KINEMATICS:CoreXY v2.01]" ASCII_EOL);
|
||||
}
|
||||
|
||||
// Initialize API pointers for CoreXY kinematics
|
||||
@@ -222,6 +249,9 @@ void corexy_init (void)
|
||||
kinematics.homing_cycle_validate = homing_cycle_validate;
|
||||
kinematics.homing_cycle_get_feedrate = homing_cycle_get_feedrate;
|
||||
|
||||
check_travel_limits = grbl.check_travel_limits;
|
||||
grbl.check_travel_limits = corexy_check_travel_limits;
|
||||
|
||||
on_report_options = grbl.on_report_options;
|
||||
grbl.on_report_options = report_options;
|
||||
}
|
||||
|
||||
4
report.c
4
report.c
@@ -38,6 +38,7 @@
|
||||
#include "nvs_buffer.h"
|
||||
#include "machine_limits.h"
|
||||
#include "state_machine.h"
|
||||
#include "canbus.h"
|
||||
#include "regex.h"
|
||||
|
||||
#if ENABLE_SPINDLE_LINEARIZATION
|
||||
@@ -985,6 +986,9 @@ void report_build_info (char *line, bool extended)
|
||||
if(hal.rtc.get_datetime)
|
||||
strcat(buf, "RTC,");
|
||||
|
||||
if(canbus_enabled())
|
||||
strcat(buf, "CAN,");
|
||||
|
||||
#ifdef PID_LOG
|
||||
strcat(buf, "PID,");
|
||||
#endif
|
||||
|
||||
@@ -779,7 +779,8 @@ typedef struct {
|
||||
control_signals_t control_disable_pullup;
|
||||
coolant_state_t coolant_invert;
|
||||
axes_signals_t home_invert;
|
||||
uint16_t hole_1;
|
||||
uint8_t modbus_baud;
|
||||
uint8_t canbus_baud;
|
||||
spindle_settings_t spindle;
|
||||
stepper_settings_t steppers;
|
||||
reportmask_t status_report; // Mask to indicate desired report data.
|
||||
|
||||
Reference in New Issue
Block a user