Skip to content

Commit

Permalink
Merge branch 'master' into runout_test
Browse files Browse the repository at this point in the history
  • Loading branch information
Zeanon committed Oct 11, 2023
2 parents 14cb5af + 212a61f commit 09e4721
Show file tree
Hide file tree
Showing 9 changed files with 432 additions and 175 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Changes
M18/M84 supports individual axes(M18 X will only turn off steppers associated with X, if you are running CoreXY, X and Y will be turned off as they are connected)<br>
G28 supports conditional homing (G28 X0 will only home X if X has not been homed yet)<br>
PID Profiles: generate profiles with PID values for different temperatures and load them with a command without restarting<br>
Improved PID tuning algorithm and velocity based PID algorithm (https://github.com/Klipper3d/klipper/pull/5955)<br>
Filament Switch sensors support Marlins Runout Distance (can also be changed on the fly) (currently on the runout_test branch)<br>
Detection Length for Filament Motion Sensors can be changed on the fly (currently on the runout_test branch)<br>
Implementation of Marlins Cold Extrude<br>
Fixed some stuff in the stepper_enable code<br>
Added support for the run_on_error feature from the LED-Effect plugin (also requires our forked version of LED-Effect)<br>
Added jinja Loop-Controls<br>
Implemented controller_temperature_fan (look at the doc for explanation)<br>
Implemented "curve" control algorithm for temperature_fan (look at the doc for explanation)<br>
Other minor fixes and debug features that do not impact general use<br>

All commands and config options for the ffeatures should be documented in the docs, if I forgot something, feel free to open an issue and I will get to it ASAP<br>

Pretty much every normal klipper config is compatible, except for one thing: https://github.com/Klipper3d/klipper/pull/6307<br>



# Original README
Welcome to the Klipper project!

[![Klipper](docs/img/klipper-logo-small.png)](https://www.klipper3d.org/)
Expand Down
6 changes: 5 additions & 1 deletion config/printer-creality-ender5-2019.cfg
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# This file contains common pin mappings for the 2019 Creality
# Ender 5. To use this config, the firmware should be compiled for the
# AVR atmega1284p.
# AVR atmega1284p. This also works for the v1.1.5 silent boards.

# Note, a number of Melzi boards are shipped with a bootloader that
# requires the following command to flash the board:
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
# For v1.1.5 silent boards, the following command is used:
# avrdude -p atmega1284p -c arduino -P /dev/ttyUSB0 -b 115200 -U flash:w:out/klipper.elf.hex
# If the above command does not work and "make flash" does not work
# then one may need to flash a bootloader to the board - see the
# Klipper docs/Bootloaders.md file for more information.
Expand Down Expand Up @@ -80,6 +82,8 @@ pin: PB4

[mcu]
serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
# Silent boards tend to have the exact same serial ID, except without USB2.0, using USB instead.
# e.g. /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0

[printer]
kinematics: cartesian
Expand Down
9 changes: 9 additions & 0 deletions klippy/chelper/serialqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct serialqueue {
int ready_bytes, upcoming_bytes, need_ack_bytes, last_ack_bytes;
uint64_t need_kick_clock;
struct list_head notify_queue;
double last_write_fail_time;
// Received messages
struct list_head receive_queue;
// Fastreader support
Expand Down Expand Up @@ -376,8 +377,16 @@ do_write(struct serialqueue *sq, void *buf, int buflen)
int ret = write(sq->serial_fd, &cf, sizeof(cf));
if (ret < 0) {
report_errno("can write", ret);
double curtime = get_monotonic();
if (!sq->last_write_fail_time) {
sq->last_write_fail_time = curtime;
} else if (curtime > sq->last_write_fail_time + 10.0) {
errorf("Halting reads due to CAN write errors.");
pollreactor_do_exit(sq->pr);
}
return;
}
sq->last_write_fail_time = 0.0;
buf += size;
buflen -= size;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/README
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ used to upload firmware to devices flashed with the CanBoot bootloader.

The can2040 directory contains code from:
https://github.com/KevinOConnor/can2040
revision d1190afcaa6245c20da28199d06e453d2e743099.
version v1.6.0 (af3d21e5d61b8408c63fbdfb0aceb21d69d91693)

The Huada HC32F460 directory contains code from:
https://www.hdsc.com.cn/Category83-1490
Expand Down
97 changes: 72 additions & 25 deletions lib/can2040/can2040.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Software CANbus implementation for rp2040
//
// Copyright (C) 2022 Kevin O'Connor <[email protected]>
// Copyright (C) 2022,2023 Kevin O'Connor <[email protected]>
//
// This file may be distributed under the terms of the GNU GPLv3 license.

Expand Down Expand Up @@ -318,6 +318,14 @@ pio_irq_set(struct can2040 *cd, uint32_t sm_irqs)
pio_hw->inte0 = sm_irqs | SI_RX_DATA;
}

// Completely disable host irqs
static void
pio_irq_disable(struct can2040 *cd)
{
pio_hw_t *pio_hw = cd->pio_hw;
pio_hw->inte0 = 0;
}

// Return current host irq mask
static uint32_t
pio_irq_get(struct can2040 *cd)
Expand Down Expand Up @@ -662,6 +670,7 @@ tx_schedule_transmit(struct can2040 *cd)
pio_signal_set_txpending(cd);
}
cd->tx_state = TS_QUEUED;
cd->stats.tx_attempt++;
struct can2040_transmit *qt = &cd->tx_queue[tx_qpos(cd, tx_pull_pos)];
pio_tx_send(cd, qt->stuffed_data, qt->stuffed_words);
return 0;
Expand Down Expand Up @@ -721,6 +730,7 @@ report_callback_error(struct can2040 *cd, uint32_t error_code)
static void
report_callback_rx_msg(struct can2040 *cd)
{
cd->stats.rx_total++;
cd->rx_cb(cd, CAN2040_NOTIFY_RX, &cd->parse_msg);
}

Expand All @@ -729,6 +739,7 @@ static void
report_callback_tx_msg(struct can2040 *cd)
{
writel(&cd->tx_pull_pos, cd->tx_pull_pos + 1);
cd->stats.tx_total++;
cd->rx_cb(cd, CAN2040_NOTIFY_TX, &cd->parse_msg);
}

Expand All @@ -748,11 +759,11 @@ report_handle_eof(struct can2040 *cd)
pio_match_clear(cd);
}

// Check if in an rx message is being processed
// Check if message being processed is an rx message (not self feedback from tx)
static int
report_is_rx_eof_pending(struct can2040 *cd)
report_is_not_in_tx(struct can2040 *cd)
{
return cd->report_state == RS_NEED_RX_EOF;
return !(cd->report_state & RS_NEED_TX_ACK);
}

// Parser found a new message start
Expand Down Expand Up @@ -817,7 +828,7 @@ report_note_eof_success(struct can2040 *cd)

// Parser found unexpected data on input
static void
report_note_parse_error(struct can2040 *cd)
report_note_discarding(struct can2040 *cd)
{
if (cd->report_state != RS_IDLE) {
cd->report_state = RS_IDLE;
Expand Down Expand Up @@ -880,7 +891,7 @@ report_line_txpending(struct can2040 *cd)
return;
}
// Tx request from can2040_transmit(), report_note_eof_success(),
// or report_note_parse_error().
// or report_note_discarding().
uint32_t check_txpending = tx_schedule_transmit(cd);
pio_irq_set(cd, (pio_irqs & ~SI_TXPENDING) | check_txpending);
}
Expand All @@ -896,6 +907,13 @@ enum {
MS_CRC, MS_ACK, MS_EOF0, MS_EOF1, MS_DISCARD
};

// Reset any bits in the incoming parsing state
static void
data_state_clear_bits(struct can2040 *cd)
{
cd->raw_bit_count = cd->unstuf.stuffed_bits = cd->unstuf.count_stuff = 0;
}

// Transition to the next parsing state
static void
data_state_go_next(struct can2040 *cd, uint32_t state, uint32_t num_bits)
Expand All @@ -908,23 +926,35 @@ data_state_go_next(struct can2040 *cd, uint32_t state, uint32_t num_bits)
static void
data_state_go_discard(struct can2040 *cd)
{
report_note_parse_error(cd);

if (pio_rx_check_stall(cd)) {
// CPU couldn't keep up for some read data - must reset pio state
cd->raw_bit_count = cd->unstuf.count_stuff = 0;
data_state_clear_bits(cd);
pio_sm_setup(cd);
report_callback_error(cd, 0);
}

data_state_go_next(cd, MS_DISCARD, 32);

// Clear report state and update hw irqs after transition to MS_DISCARD
report_note_discarding(cd);
}

// Note a data parse error and transition to discard state
static void
data_state_go_error(struct can2040 *cd)
{
cd->stats.parse_error++;
data_state_go_discard(cd);
}

// Received six dominant bits on the line
static void
data_state_line_error(struct can2040 *cd)
{
data_state_go_discard(cd);
if (cd->parse_state == MS_DISCARD)
data_state_go_discard(cd);
else
data_state_go_error(cd);
}

// Received six unexpected passive bits on the line
Expand All @@ -933,16 +963,15 @@ data_state_line_passive(struct can2040 *cd)
{
if (cd->parse_state != MS_DISCARD && cd->parse_state != MS_START) {
// Bitstuff error
data_state_go_discard(cd);
data_state_go_error(cd);
return;
}

uint32_t stuffed_bits = unstuf_get_raw(&cd->unstuf);
uint32_t dom_bits = ~stuffed_bits;
if (!dom_bits) {
// Counter overflow in "sync" state machine - reset it
cd->unstuf.stuffed_bits = 0;
cd->raw_bit_count = cd->unstuf.count_stuff = 0;
data_state_clear_bits(cd);
pio_sm_setup(cd);
data_state_go_discard(cd);
return;
Expand Down Expand Up @@ -972,7 +1001,7 @@ data_state_go_crc(struct can2040 *cd)

int ret = report_note_crc_start(cd);
if (ret) {
data_state_go_discard(cd);
data_state_go_error(cd);
return;
}
data_state_go_next(cd, MS_CRC, 16);
Expand Down Expand Up @@ -1065,7 +1094,7 @@ static void
data_state_update_crc(struct can2040 *cd, uint32_t data)
{
if (((cd->parse_crc << 1) | 1) != data) {
data_state_go_discard(cd);
data_state_go_error(cd);
return;
}

Expand All @@ -1083,7 +1112,7 @@ data_state_update_ack(struct can2040 *cd, uint32_t data)
// data_state_line_passive()
unstuf_restore_state(&cd->unstuf, (cd->parse_crc_bits << 2) | data);

data_state_go_discard(cd);
data_state_go_error(cd);
return;
}
report_note_ack_success(cd);
Expand All @@ -1095,7 +1124,7 @@ static void
data_state_update_eof0(struct can2040 *cd, uint32_t data)
{
if (data != 0x0f || pio_rx_check_stall(cd)) {
data_state_go_discard(cd);
data_state_go_error(cd);
return;
}
unstuf_clear_state(&cd->unstuf);
Expand All @@ -1106,14 +1135,17 @@ data_state_update_eof0(struct can2040 *cd, uint32_t data)
static void
data_state_update_eof1(struct can2040 *cd, uint32_t data)
{
if (data >= 0x1c || (data >= 0x18 && report_is_rx_eof_pending(cd)))
// Message is considered fully transmitted
if (data == 0x1f) {
// Success
report_note_eof_success(cd);

if (data == 0x1f)
data_state_go_next(cd, MS_START, 1);
else
} else if (data >= 0x1c || (data >= 0x18 && report_is_not_in_tx(cd))) {
// Message fully transmitted - followed by "overload frame"
report_note_eof_success(cd);
data_state_go_discard(cd);
} else {
data_state_go_error(cd);
}
}

// Handle data received while in MS_DISCARD state
Expand Down Expand Up @@ -1310,13 +1342,28 @@ can2040_start(struct can2040 *cd, uint32_t sys_clock, uint32_t bitrate
{
cd->gpio_rx = gpio_rx;
cd->gpio_tx = gpio_tx;
data_state_clear_bits(cd);
pio_setup(cd, sys_clock, bitrate);
data_state_go_discard(cd);
}

// API function to stop and uninitialize can2040 code
// API function to stop can2040 code
void
can2040_shutdown(struct can2040 *cd)
can2040_stop(struct can2040 *cd)
{
// XXX
pio_irq_disable(cd);
pio_sm_setup(cd);
}

// API function to access can2040 statistics
void
can2040_get_statistics(struct can2040 *cd, struct can2040_stats *stats)
{
for (;;) {
memcpy(stats, &cd->stats, sizeof(*stats));
if (memcmp(stats, &cd->stats, sizeof(*stats)) == 0)
// Successfully copied data
return;
// Raced with irq handler update - retry copy
}
}
10 changes: 9 additions & 1 deletion lib/can2040/can2040.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,18 @@ struct can2040;
typedef void (*can2040_rx_cb)(struct can2040 *cd, uint32_t notify
, struct can2040_msg *msg);

struct can2040_stats {
uint32_t rx_total, tx_total;
uint32_t tx_attempt;
uint32_t parse_error;
};

void can2040_setup(struct can2040 *cd, uint32_t pio_num);
void can2040_callback_config(struct can2040 *cd, can2040_rx_cb rx_cb);
void can2040_start(struct can2040 *cd, uint32_t sys_clock, uint32_t bitrate
, uint32_t gpio_rx, uint32_t gpio_tx);
void can2040_shutdown(struct can2040 *cd);
void can2040_stop(struct can2040 *cd);
void can2040_get_statistics(struct can2040 *cd, struct can2040_stats *stats);
void can2040_pio_irq_handler(struct can2040 *cd);
int can2040_check_transmit(struct can2040 *cd);
int can2040_transmit(struct can2040 *cd, struct can2040_msg *msg);
Expand All @@ -56,6 +63,7 @@ struct can2040 {
void *pio_hw;
uint32_t gpio_rx, gpio_tx;
can2040_rx_cb rx_cb;
struct can2040_stats stats;

// Bit unstuffing
struct can2040_bitunstuffer unstuf;
Expand Down
Loading

0 comments on commit 09e4721

Please sign in to comment.