├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── README.md ├── components └── klipper │ ├── CMakeLists.txt │ ├── board │ ├── adc.c │ ├── console.c │ ├── gpio.c │ ├── hard_pwm.c │ ├── i2c.c │ ├── include │ │ ├── autoconf.h │ │ └── board │ │ │ ├── gpio.h │ │ │ ├── internal.h │ │ │ ├── io.h │ │ │ ├── irq.h │ │ │ ├── misc.h │ │ │ ├── pgm.h │ │ │ ├── serial_irq.h │ │ │ └── timer_irq.h │ ├── internal.c │ ├── spi.c │ └── timer.c │ └── compile_time_request.txt ├── main ├── CMakeLists.txt ├── Kconfig.projbuild └── main.c ├── printer.cfg └── sdkconfig.defaults /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt.user 2 | CMakeCache.txt 3 | CMakeFiles 4 | CMakeScripts 5 | Testing 6 | Makefile 7 | cmake_install.cmake 8 | install_manifest.txt 9 | compile_commands.json 10 | CTestTestfile.cmake 11 | _deps 12 | build 13 | .vscode 14 | sdkconfig 15 | sdkconfig.old 16 | components/klipper/compile_time_request.c 17 | components/klipper/klipper.dict -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/klipper/klipper"] 2 | path = components/klipper/klipper 3 | url = https://github.com/nikhil-robinson/klipper.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following five lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.16) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | project(klipper) 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Klipper_ESP32 2 | 3 | Klipper_ESP32 is an implementation of the Klipper protocol for Espressif's ESP32 microcontroller set. 4 | 5 | ## Important Notice 6 | 7 | Klipper_ESP32 acts as a wrapper on the original Klipper protocol from the master branch of the Klipper repository, utilizing the underlying Klipper source to facilitate communication between ESP32-based chips and the Klipper software. Please note that this project is currently experimental and not stable. We are not responsible for any damages caused by using this framework. 8 | 9 | ## Installation and Usage 10 | 11 | ### Prerequisites 12 | 13 | Before using Klipper_ESP32, ensure you have the following prerequisites installed: 14 | 15 | - [ESP-IDF >= 5.2.1](https://github.com/espressif/esp-idf.git) development environment set up. 16 | - Klipper firmware source code. 17 | 18 | ### Setup Steps 19 | 20 | 1. **Clone the Repository:** 21 | 22 | ```bash 23 | git clone --recursive https://github.com/nikhil-robinson/klipper_esp32 24 | ``` 25 | 26 | 2. **Navigate to the Project Directory:** 27 | 28 | ```bash 29 | cd klipper-esp32 30 | ``` 31 | 32 | 3. **Configure ESP-IDF:** 33 | 34 | Follow the instructions in the ESP-IDF documentation to set up your environment. 35 | 36 | 4. **Build the Firmware:** 37 | 38 | ```bash 39 | idf.py build 40 | ``` 41 | 42 | 5. **Flash the Firmware:** 43 | 44 | Connect your ESP32 board and run: 45 | 46 | ```bash 47 | idf.py -p PORT flash 48 | ``` 49 | 50 | Replace `PORT` with the port your ESP32 is connected to. 51 | 52 | 6. **Configure Klipper Settings:** 53 | 54 | Configure your 3D printer settings in the `printer.cfg` file. 55 | 56 | 7. **Connect and Start Printing:** 57 | 58 | Connect your 3D printer hardware to the ESP32 board, power on your printer, and start sending G-code commands to Klipper running on ESP32. 59 | 60 | ## Contributing 61 | 62 | Contributions to Klipper_ESP32 are welcome! If you have suggestions for improvements or new features, feel free to open an issue or submit a pull request. 63 | 64 | ## Licensing 65 | 66 | Please refer to the individual source files within the klipper _esp32 for detailed licensing information. 67 | 68 | ## Acknowledgements 69 | 70 | This project is not officially endorsed by the Klipper project. Please refrain from directing any support requests to the Klipper project. 71 | 72 | - [Klipper](https://www.klipper3d.org/) by [Kevin O'Connor](https://www.patreon.com/koconnor) 73 | -------------------------------------------------------------------------------- /components/klipper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "klipper/src/adccmds.c" 2 | "klipper/src/basecmd.c" 3 | "klipper/src/buttons.c" 4 | "klipper/src/command.c" 5 | "klipper/src/debugcmds.c" 6 | "klipper/src/endstop.c" 7 | "klipper/src/gpiocmds.c" 8 | "klipper/src/i2c_software.c" 9 | "klipper/src/i2ccmds.c" 10 | "klipper/src/initial_pins.c" 11 | "klipper/src/lcd_hd44780.c" 12 | "klipper/src/lcd_st7920.c" 13 | "klipper/src/neopixel.c" 14 | "klipper/src/pulse_counter.c" 15 | "klipper/src/pwmcmds.c" 16 | "klipper/src/sched.c" 17 | "klipper/src/sensor_ldc1612.c" 18 | "klipper/src/sensor_adxl345.c" 19 | "klipper/src/sensor_angle.c" 20 | "klipper/src/sensor_bulk.c" 21 | "klipper/src/sensor_lis2dw.c" 22 | "klipper/src/sensor_mpu9250.c" 23 | "klipper/src/spi_software.c" 24 | "klipper/src/spicmds.c" 25 | "klipper/src/stepper.c" 26 | "klipper/src/thermocouple.c" 27 | "klipper/src/tmcuart.c" 28 | "klipper/src/trsync.c" 29 | "klipper/src/generic/alloc.c" 30 | "klipper/src/generic/crc16_ccitt.c" 31 | "klipper/src/generic/timer_irq.c" 32 | "board/adc.c" 33 | "board/gpio.c" 34 | "board/timer.c" 35 | "board/internal.c" 36 | "board/console.c" 37 | "board/hard_pwm.c" 38 | "board/i2c.c" 39 | "board/spi.c" 40 | INCLUDE_DIRS "klipper/src/" "board/include" 41 | REQUIRES driver esp_adc) 42 | 43 | 44 | # Add custom command to generate compile_time_request.c 45 | add_custom_command( 46 | OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/compile_time_request.c 47 | COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR}/klipper/ python3 ./scripts/buildcommands.py -d ${CMAKE_CURRENT_SOURCE_DIR}/klipper.dict ${CMAKE_CURRENT_SOURCE_DIR}/compile_time_request.txt ${CMAKE_CURRENT_SOURCE_DIR}/compile_time_request.c 48 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/klipper.dict ${CMAKE_CURRENT_SOURCE_DIR}/compile_time_request.txt 49 | COMMENT "Generating compile_time_request.c" 50 | VERBATIM 51 | ) 52 | 53 | # Define custom target to ensure compile_time_request.c is generated 54 | add_custom_target(compile_time_request_target DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/compile_time_request.c) 55 | 56 | # Make sure the component library depends on the generated file 57 | add_dependencies(${COMPONENT_LIB} compile_time_request_target) 58 | 59 | # Add the generated file to the sources of the component target 60 | target_sources(${COMPONENT_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/compile_time_request.c) 61 | -------------------------------------------------------------------------------- /components/klipper/board/adc.c: -------------------------------------------------------------------------------- 1 | // Read analog values from Esp32 chips 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/gpio.h" // gpio_adc_setup 12 | #include "board/misc.h" // timer_from_us 13 | #include "command.h" // shutdown 14 | #include "sched.h" // sched_shutdown 15 | 16 | DECL_CONSTANT("ADC_MAX", 4095); 17 | 18 | typedef struct { 19 | adc_unit_t unit; 20 | adc_channel_t channel; 21 | gpio_num_t pin 22 | } adc_mapping_t; 23 | 24 | static const adc_mapping_t adc_lookup[] = { 25 | #if CONFIG_IDF_TARGET_ESP32 26 | {ADC_UNIT_1, ADC_CHANNEL_0, GPIO_NUM_36}, 27 | {ADC_UNIT_1, ADC_CHANNEL_1, GPIO_NUM_37}, 28 | {ADC_UNIT_1, ADC_CHANNEL_2, GPIO_NUM_38}, 29 | {ADC_UNIT_1, ADC_CHANNEL_3, GPIO_NUM_39}, 30 | {ADC_UNIT_1, ADC_CHANNEL_4, GPIO_NUM_32}, 31 | {ADC_UNIT_1, ADC_CHANNEL_5, GPIO_NUM_33}, 32 | {ADC_UNIT_1, ADC_CHANNEL_6, GPIO_NUM_34}, 33 | {ADC_UNIT_1, ADC_CHANNEL_7, GPIO_NUM_35}, 34 | {ADC_UNIT_2, ADC_CHANNEL_0, GPIO_NUM_4}, 35 | {ADC_UNIT_2, ADC_CHANNEL_1, GPIO_NUM_0}, 36 | {ADC_UNIT_2, ADC_CHANNEL_2, GPIO_NUM_2}, 37 | {ADC_UNIT_2, ADC_CHANNEL_3, GPIO_NUM_15}, 38 | {ADC_UNIT_2, ADC_CHANNEL_4, GPIO_NUM_13}, 39 | {ADC_UNIT_2, ADC_CHANNEL_5, GPIO_NUM_12}, 40 | {ADC_UNIT_2, ADC_CHANNEL_6, GPIO_NUM_14}, 41 | {ADC_UNIT_2, ADC_CHANNEL_7, GPIO_NUM_27}, 42 | {ADC_UNIT_2, ADC_CHANNEL_8, GPIO_NUM_25}, 43 | {ADC_UNIT_2, ADC_CHANNEL_9, GPIO_NUM_26}, 44 | #elif CONFIG_IDF_TARGET_ESP32C3 45 | {ADC_UNIT_1, ADC_CHANNEL_0, GPIO_NUM_0}, 46 | {ADC_UNIT_1, ADC_CHANNEL_1, GPIO_NUM_1}, 47 | {ADC_UNIT_1, ADC_CHANNEL_2, GPIO_NUM_2}, 48 | {ADC_UNIT_1, ADC_CHANNEL_3, GPIO_NUM_3}, 49 | {ADC_UNIT_1, ADC_CHANNEL_4, GPIO_NUM_4}, 50 | {ADC_UNIT_2, ADC_CHANNEL_0, GPIO_NUM_5}, 51 | #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 52 | {ADC_UNIT_1, ADC_CHANNEL_0, GPIO_NUM_1}, 53 | {ADC_UNIT_1, ADC_CHANNEL_1, GPIO_NUM_2}, 54 | {ADC_UNIT_1, ADC_CHANNEL_2, GPIO_NUM_3}, 55 | {ADC_UNIT_1, ADC_CHANNEL_3, GPIO_NUM_4}, 56 | {ADC_UNIT_1, ADC_CHANNEL_4, GPIO_NUM_5}, 57 | {ADC_UNIT_1, ADC_CHANNEL_5, GPIO_NUM_6}, 58 | {ADC_UNIT_1, ADC_CHANNEL_6, GPIO_NUM_7}, 59 | {ADC_UNIT_1, ADC_CHANNEL_7, GPIO_NUM_8}, 60 | {ADC_UNIT_1, ADC_CHANNEL_8, GPIO_NUM_9}, 61 | {ADC_UNIT_1, ADC_CHANNEL_9, GPIO_NUM_10}, 62 | {ADC_UNIT_2, ADC_CHANNEL_0, GPIO_NUM_11}, 63 | {ADC_UNIT_2, ADC_CHANNEL_1, GPIO_NUM_12}, 64 | {ADC_UNIT_2, ADC_CHANNEL_2, GPIO_NUM_13}, 65 | {ADC_UNIT_2, ADC_CHANNEL_3, GPIO_NUM_14}, 66 | {ADC_UNIT_2, ADC_CHANNEL_4, GPIO_NUM_15}, 67 | {ADC_UNIT_2, ADC_CHANNEL_5, GPIO_NUM_16}, 68 | {ADC_UNIT_2, ADC_CHANNEL_6, GPIO_NUM_17}, 69 | {ADC_UNIT_2, ADC_CHANNEL_7, GPIO_NUM_18}, 70 | {ADC_UNIT_2, ADC_CHANNEL_8, GPIO_NUM_19}, 71 | {ADC_UNIT_2, ADC_CHANNEL_9, GPIO_NUM_20}, 72 | 73 | #endif 74 | }; 75 | 76 | // #define ADC_TEMPERATURE_PIN 0xfe 77 | // DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN); 78 | 79 | static adc_mapping_t *adc_serach(uint32_t pin) { 80 | 81 | for (size_t i = 0; i < (sizeof(adc_lookup) / sizeof((adc_lookup)[0])); i++) { 82 | adc_mapping_t *adc = &adc_lookup[pin]; 83 | if (adc->pin == pin) { 84 | return adc; 85 | } 86 | } 87 | return NULL; 88 | } 89 | 90 | struct gpio_adc gpio_adc_setup(uint32_t pin) { 91 | const adc_mapping_t *adc = adc_serach(pin); 92 | if (adc == NULL) { 93 | shutdown("Not a valid ADC pin"); 94 | } 95 | 96 | adc_oneshot_unit_handle_t adc_handle; 97 | adc_oneshot_unit_init_cfg_t init_config1 = { 98 | .unit_id = adc->unit, 99 | }; 100 | ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc_handle)); 101 | 102 | //-------------ADC1 Config---------------// 103 | adc_oneshot_chan_cfg_t config = { 104 | .bitwidth = ADC_BITWIDTH_DEFAULT, 105 | .atten = ADC_ATTEN_DB_12, 106 | }; 107 | 108 | ESP_ERROR_CHECK( 109 | adc_oneshot_config_channel(adc_handle, adc->channel, &config)); 110 | 111 | return (struct gpio_adc){.handle = adc_handle}; 112 | } 113 | 114 | // Try to sample a value. Returns zero if sample ready, otherwise 115 | // returns the number of clock ticks the caller should wait before 116 | // retrying this function. 117 | uint32_t gpio_adc_sample(struct gpio_adc g) { return 0; } 118 | 119 | // Read a value; use only after gpio_adc_sample() returns zero 120 | uint16_t gpio_adc_read(struct gpio_adc g) { 121 | int adc_raw = 0; 122 | ESP_ERROR_CHECK(adc_oneshot_read(g.handle, g.chan, &adc_raw)); 123 | return (uint16_t)adc_raw; 124 | } 125 | 126 | // Cancel a sample that may have been started with gpio_adc_sample() 127 | void gpio_adc_cancel_sample(struct gpio_adc g) {} 128 | -------------------------------------------------------------------------------- /components/klipper/board/console.c: -------------------------------------------------------------------------------- 1 | 2 | // UART based Console 3 | // 4 | // Copyright (C) 2024 Nikhil Robinson 5 | // 6 | // This file may be distributed under the terms of the GNU GPLv3 license. 7 | 8 | // Unless required by applicable law or agreed to in writing, this 9 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 10 | // CONDITIONS OF ANY KIND, either express or implied. 11 | 12 | #include "board/internal.h" // console_setup 13 | #include "board/irq.h" // irq_wait 14 | #include "board/misc.h" // console_sendf 15 | #include "command.h" // command_find_block 16 | #include "driver/gpio.h" 17 | #include "driver/uart.h" 18 | #include "esp_log.h" 19 | #include "sched.h" // sched_wake_task 20 | #include "sdkconfig.h" 21 | #include // errno 22 | #include // fprintf 23 | #include // memmove 24 | 25 | // Report 'errno' in a message written to stderr 26 | void report_errno(char *where, int rc) { 27 | int e = errno; 28 | printf("Got error %d in %s: (%d)%s\n", rc, where, e, strerror(e)); 29 | } 30 | 31 | static struct task_wake console_wake; 32 | static uint8_t receive_buf[4096]; 33 | static int receive_pos; 34 | 35 | /**************************************************************** 36 | * Setup 37 | ****************************************************************/ 38 | 39 | int console_setup(char *name) { 40 | uart_config_t uart_config = { 41 | .baud_rate = CONFIG_SERIAL_BAUD, 42 | .data_bits = UART_DATA_8_BITS, 43 | .parity = UART_PARITY_DISABLE, 44 | .stop_bits = UART_STOP_BITS_1, 45 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, 46 | .source_clk = UART_SCLK_DEFAULT, 47 | }; 48 | int intr_alloc_flags = 0; 49 | 50 | #if CONFIG_UART_ISR_IN_IRAM 51 | intr_alloc_flags = ESP_INTR_FLAG_IRAM; 52 | #endif 53 | 54 | ESP_ERROR_CHECK(uart_driver_install(0, sizeof(receive_buf) * 2, 0, 0, NULL, 55 | intr_alloc_flags)); 56 | ESP_ERROR_CHECK(uart_param_config(0, &uart_config)); 57 | ESP_ERROR_CHECK(uart_set_pin(0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 58 | UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); 59 | 60 | return 0; 61 | } 62 | 63 | /**************************************************************** 64 | * Console handling 65 | ****************************************************************/ 66 | 67 | void *console_receive_buffer(void) { return receive_buf; } 68 | 69 | // Process any incoming commands 70 | void console_task(void) { 71 | if (!sched_check_wake(&console_wake)) 72 | return; 73 | int ret = uart_read_bytes(0, &receive_buf[receive_pos], 74 | sizeof(receive_buf) - receive_pos, 1); 75 | if (ret < 0) { 76 | if (errno == EWOULDBLOCK) { 77 | ret = 0; 78 | } else { 79 | report_errno("read", ret); 80 | return; 81 | } 82 | } 83 | if (ret == 15 && receive_buf[receive_pos + 14] == '\n' && 84 | memcmp(&receive_buf[receive_pos], "FORCE_SHUTDOWN\n", 15) == 0) 85 | shutdown("Force shutdown command"); 86 | 87 | // Find and dispatch message blocks in the input 88 | int len = receive_pos + ret; 89 | uint_fast8_t pop_count, msglen = len > MESSAGE_MAX ? MESSAGE_MAX : len; 90 | ret = command_find_and_dispatch(receive_buf, msglen, &pop_count); 91 | if (ret) { 92 | len -= pop_count; 93 | if (len) { 94 | memmove(receive_buf, &receive_buf[pop_count], len); 95 | sched_wake_task(&console_wake); 96 | } 97 | } 98 | receive_pos = len; 99 | } 100 | DECL_TASK(console_task); 101 | 102 | // Encode and transmit a "response" message 103 | void console_sendf(const struct command_encoder *ce, va_list args) { 104 | // Generate message 105 | uint8_t buf[MESSAGE_MAX]; 106 | uint_fast8_t msglen = command_encode_and_frame(buf, ce, args); 107 | 108 | // Transmit message 109 | int ret = uart_write_bytes(0, buf, msglen); 110 | if (ret < 0) 111 | report_errno("write", ret); 112 | } 113 | 114 | void console_kick() { sched_wake_task(&console_wake); } 115 | -------------------------------------------------------------------------------- /components/klipper/board/gpio.c: -------------------------------------------------------------------------------- 1 | // GPIO functions on esp32 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/gpio.h" // gpio_out_setup 12 | #include "board/irq.h" // irq_save 13 | #include "command.h" // shutdown 14 | #include "esp_log.h" 15 | #include "hal/gpio_ll.h" 16 | #include "sched.h" // sched_shutdown 17 | #include "soc/gpio_num.h" 18 | #include "soc/gpio_struct.h" 19 | #include // ffs 20 | #define TAG "KLIPPER_GPIO" 21 | 22 | /**************************************************************** 23 | * Pin mappings 24 | ****************************************************************/ 25 | 26 | // DECL_ENUMERATION_RANGE("pin", "GPIO_NUM_", 0, 30); 27 | DECL_ENUMERATION_RANGE("pin", "GPIO_NUM_0", 0, 255); 28 | 29 | gpio_dev_t *hw = &GPIO; 30 | 31 | /**************************************************************** 32 | * General Purpose Input Output (GPIO) pins 33 | ****************************************************************/ 34 | 35 | struct gpio_out gpio_out_setup(uint32_t gpio_num, uint32_t val) { 36 | 37 | static struct gpio_line gpio_line; 38 | gpio_line.pin = gpio_num; 39 | gpio_line.state = !!val; 40 | struct gpio_out g = {.line = &gpio_line}; 41 | gpio_ll_output_enable(hw, gpio_num); 42 | gpio_out_write(g, val); 43 | return g; 44 | } 45 | 46 | void gpio_out_reset(struct gpio_out g, uint32_t val) { 47 | gpio_out_setup(g.line->pin, val); 48 | } 49 | 50 | void gpio_out_toggle_noirq(struct gpio_out g) { 51 | 52 | gpio_out_write(g, !g.line->state); 53 | } 54 | 55 | void gpio_out_toggle(struct gpio_out g) { gpio_out_toggle_noirq(g); } 56 | 57 | void gpio_out_write(struct gpio_out g, uint32_t val) { 58 | gpio_ll_set_level(hw, g.line->pin, val); 59 | g.line->state = !!val; 60 | } 61 | 62 | struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up) { 63 | struct gpio_in g = {.pin = pin}; 64 | gpio_ll_input_enable(hw, pin); 65 | if (pull_up) { 66 | gpio_ll_pullup_en(hw, pin); 67 | } else { 68 | gpio_ll_pullup_dis(hw, pin); 69 | } 70 | 71 | return g; 72 | } 73 | 74 | void gpio_in_reset(struct gpio_in g, int8_t pull_up) { 75 | gpio_in_setup(g.pin, pull_up); 76 | } 77 | 78 | uint8_t gpio_in_read(struct gpio_in g) { return gpio_ll_get_level(hw, g.pin); } 79 | -------------------------------------------------------------------------------- /components/klipper/board/hard_pwm.c: -------------------------------------------------------------------------------- 1 | // Hardware PWM control 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/gpio.h" // struct gpio_pwm 12 | #include "board/internal.h" // NSECS_PER_TICK 13 | #include "command.h" // shutdown 14 | #include "sched.h" // sched_shutdown 15 | #include 16 | #include 17 | 18 | #include "driver/ledc.h" 19 | #include "esp_err.h" 20 | #include "hal/ledc_types.h" 21 | 22 | #define PWM_MAX (1 << 13) 23 | DECL_CONSTANT("PWM_MAX", PWM_MAX); 24 | 25 | uint8_t timer = 0; 26 | uint8_t channel = 0; 27 | 28 | ledc_timer_config_t ledc_timer = {.speed_mode = LEDC_LOW_SPEED_MODE, 29 | .timer_num = 0, 30 | .duty_resolution = LEDC_TIMER_13_BIT, 31 | .freq_hz = 0, // Set output frequency at 4 kHz 32 | .clk_cfg = LEDC_AUTO_CLK}; 33 | 34 | struct gpio_pwm gpio_pwm_setup(uint32_t pin, uint32_t cycle_time, 35 | uint16_t val) { 36 | // Prepare and then apply the LEDC PWM timer configuration 37 | 38 | struct gpio_pwm g = {}; 39 | if (cycle_time != ledc_timer.freq_hz) { 40 | timer++; 41 | if (timer >= LEDC_TIMER_MAX) { 42 | goto fail; 43 | } 44 | ledc_timer.timer_num = timer; 45 | ledc_timer.freq_hz = cycle_time; 46 | 47 | ledc_timer_config(&ledc_timer); 48 | } 49 | 50 | channel++; 51 | if (channel >= LEDC_CHANNEL_MAX) { 52 | goto fail; 53 | } 54 | ledc_channel_config_t ledc_channel = {.speed_mode = LEDC_LOW_SPEED_MODE, 55 | .channel = channel, 56 | .timer_sel = timer, 57 | .intr_type = LEDC_INTR_DISABLE, 58 | .gpio_num = pin, 59 | .duty = val, 60 | .hpoint = 0}; 61 | int ret = ledc_channel_config(&ledc_channel); 62 | if (ret != ESP_OK) { 63 | goto fail; 64 | } 65 | 66 | g.channel = channel; 67 | 68 | return g; 69 | fail: 70 | shutdown("Unable to config pwm device"); 71 | } 72 | 73 | void gpio_pwm_write(struct gpio_pwm g, uint16_t val) { 74 | ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, g.channel, val)); 75 | ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, g.channel)); 76 | } 77 | -------------------------------------------------------------------------------- /components/klipper/board/i2c.c: -------------------------------------------------------------------------------- 1 | // I2C functions for esp32 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/gpio.h" // i2c_setup, i2c_read, i2c_write 12 | #include "board/internal.h" // pclock, gpio_peripheral 13 | #include "board/misc.h" // timer_is_before 14 | #include "command.h" // shutdown 15 | #include "driver/i2c_master.h" 16 | #include "sched.h" // sched_shutdown 17 | #include "soc/clk_tree_defs.h" 18 | #include "soc/soc_caps.h" 19 | 20 | DECL_ENUMERATION_RANGE("i2c_bus", "I2C_NUM_0", 0, 2); 21 | DECL_CONSTANT_STR("BUS_PINS_i2c0", "GPIO_NUM_8,GPIO_NUM_9"); 22 | DECL_CONSTANT_STR("BUS_PINS_i2c1", "GPIO_NUM_48,GPIO_NUM_47"); 23 | 24 | struct i2c_info { 25 | i2c_port_t port; 26 | uint32_t sda_pin, scl_pin; 27 | }; 28 | 29 | static const struct i2c_info i2c_bus[] = { 30 | {I2C_NUM_0, 8, 9}, 31 | #if SOC_I2C_NUM >= 2 32 | {I2C_NUM_1, 48, 47}, 33 | #endif 34 | }; 35 | 36 | struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr) { 37 | if (bus > ARRAY_SIZE(i2c_bus)) 38 | shutdown("Invalid i2c bus"); 39 | 40 | const struct i2c_info *info = &i2c_bus[bus]; 41 | 42 | i2c_master_bus_config_t i2c_mst_config = { 43 | .clk_source = I2C_CLK_SRC_DEFAULT, 44 | .i2c_port = info->port, 45 | .scl_io_num = info->scl_pin, 46 | .sda_io_num = info->sda_pin, 47 | .glitch_ignore_cnt = 7, 48 | .flags.enable_internal_pullup = true, 49 | }; 50 | 51 | i2c_master_bus_handle_t bus_handle; 52 | ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); 53 | 54 | i2c_device_config_t dev_cfg = { 55 | .dev_addr_length = I2C_ADDR_BIT_LEN_7, 56 | .device_address = addr, 57 | .scl_speed_hz = rate, 58 | }; 59 | 60 | i2c_master_dev_handle_t dev_handle; 61 | ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); 62 | 63 | return (struct i2c_config){.handle = dev_handle}; 64 | } 65 | 66 | void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write) { 67 | i2c_master_transmit(config.handle, write, write_len, -1); 68 | } 69 | 70 | void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg, 71 | uint8_t read_len, uint8_t *read) { 72 | i2c_master_transmit_receive(config.handle, reg, reg_len, read, read_len, -1); 73 | } 74 | -------------------------------------------------------------------------------- /components/klipper/board/include/autoconf.h: -------------------------------------------------------------------------------- 1 | #include "sdkconfig.h" 2 | 3 | #ifndef CONFIG_LOW_LEVEL_OPTIONS 4 | #define CONFIG_LOW_LEVEL_OPTIONS 0 5 | #endif 6 | 7 | #ifndef CONFIG_SERIAL 8 | #define CONFIG_SERIAL 0 9 | #endif 10 | 11 | #ifndef CONFIG_SERIAL_BAUD 12 | #define CONFIG_SERIAL_BAUD 0 13 | #endif 14 | 15 | #ifndef CONFIG_USBSERIAL 16 | #define CONFIG_USBSERIAL 0 17 | #endif 18 | 19 | #ifndef CONFIG_USBCANBUS 20 | #define CONFIG_USBCANBUS 0 21 | #endif 22 | 23 | #ifndef CONFIG_USB 24 | #define CONFIG_USB 0 25 | #endif 26 | 27 | #ifndef CONFIG_USB_VENDOR_ID 28 | #define CONFIG_USB_VENDOR_ID 0 29 | #endif 30 | 31 | #ifndef CONFIG_USB_DEVICE_ID 32 | #define CONFIG_USB_DEVICE_ID 0 33 | #endif 34 | 35 | #ifndef CONFIG_USB_SERIAL_NUMBER_CHIPID 36 | #define CONFIG_USB_SERIAL_NUMBER_CHIPID 0 37 | #endif 38 | 39 | #ifndef CONFIG_USB_SERIAL_NUMBER 40 | #define CONFIG_USB_SERIAL_NUMBER 0 41 | #endif 42 | 43 | 44 | #ifndef CONFIG_NEED_SENSOR_BULK 45 | #define CONFIG_NEED_SENSOR_BULK 0 46 | #endif 47 | 48 | #ifndef CONFIG_WANT_GPIO_BITBANGING 49 | #define CONFIG_WANT_GPIO_BITBANGING 0 50 | #endif 51 | 52 | #ifndef CONFIG_WANT_DISPLAYS 53 | #define CONFIG_WANT_DISPLAYS 0 54 | #endif 55 | 56 | #ifndef CONFIG_WANT_SENSORS 57 | #define CONFIG_WANT_SENSORS 0 58 | #endif 59 | 60 | #ifndef CONFIG_WANT_LIS2DW 61 | #define CONFIG_WANT_LIS2DW 0 62 | #endif 63 | 64 | #ifndef CONFIG_WANT_LDC1612 65 | #define CONFIG_WANT_LDC1612 0 66 | #endif 67 | 68 | #ifndef CONFIG_CANSERIAL 69 | #define CONFIG_CANSERIAL 0 70 | #endif 71 | 72 | #ifndef CONFIG_CANBUS 73 | #define CONFIG_CANBUS 0 74 | #endif 75 | 76 | #ifndef CONFIG_CANBUS_FREQUENCY 77 | #define CONFIG_CANBUS_FREQUENCY 0 78 | #endif 79 | 80 | #ifndef CONFIG_CANBUS_FILTER 81 | #define CONFIG_CANBUS_FILTER 0 82 | #endif 83 | 84 | #ifndef CONFIG_INITIAL_PINS 85 | #define CONFIG_INITIAL_PINS 0 86 | #endif 87 | 88 | #ifndef CONFIG_HAVE_GPIO 89 | #define CONFIG_HAVE_GPIO 0 90 | #endif 91 | 92 | #ifndef CONFIG_HAVE_GPIO_ADC 93 | #define CONFIG_HAVE_GPIO_ADC 0 94 | #endif 95 | 96 | #ifndef CONFIG_HAVE_GPIO_SPI 97 | #define CONFIG_HAVE_GPIO_SPI 0 98 | #endif 99 | 100 | #ifndef CONFIG_HAVE_GPIO_SDIO 101 | #define CONFIG_HAVE_GPIO_SDIO 0 102 | #endif 103 | 104 | #ifndef CONFIG_HAVE_GPIO_I2C 105 | #define CONFIG_HAVE_GPIO_I2C 0 106 | #endif 107 | 108 | #ifndef CONFIG_HAVE_GPIO_HARD_PWM 109 | #define CONFIG_HAVE_GPIO_HARD_PWM 0 110 | #endif 111 | 112 | #ifndef CONFIG_HAVE_CHIPID 113 | #define CONFIG_HAVE_CHIPID 0 114 | #endif 115 | 116 | #ifndef CONFIG_HAVE_STEPPER_BOTH_EDGE 117 | #define CONFIG_HAVE_STEPPER_BOTH_EDGE 0 118 | #endif 119 | 120 | #ifndef CONFIG_HAVE_LIMITED_CODE_SIZE 121 | #define CONFIG_HAVE_LIMITED_CODE_SIZE 0 122 | #endif 123 | 124 | 125 | #ifndef CONFIG_INLINE_STEPPER_HACK 126 | #define CONFIG_INLINE_STEPPER_HACK 0 127 | #endif 128 | 129 | #ifndef CONFIG_WANT_SOFTWARE_I2C 130 | #define CONFIG_WANT_SOFTWARE_I2C 0 131 | #endif //CONFIG_WANT_SOFTWARE_I2C 132 | 133 | 134 | #ifndef CONFIG_HAVE_STRICT_TIMING 135 | #define CONFIG_HAVE_STRICT_TIMING 0 136 | #endif //CONFIG_HAVE_STRICT_TIMING 137 | 138 | 139 | #ifndef CONFIG_HAVE_BOOTLOADER_REQUEST 140 | #define CONFIG_HAVE_BOOTLOADER_REQUEST 0 141 | #endif //CONFIG_HAVE_BOOTLOADER_REQUEST 142 | 143 | 144 | #ifndef CONFIG_WANT_SOFTWARE_SPI 145 | #define CONFIG_WANT_SOFTWARE_SPI 0 146 | #endif //CONFIG_WANT_SOFTWARE_SPI 147 | 148 | 149 | 150 | #define CONFIG_MACH_AVR 0 151 | #define CONFIG_MACH_ATSAM 0 152 | #define CONFIG_MACH_ATSAMD 0 153 | #define CONFIG_MACH_LPC176X 0 154 | #define CONFIG_MACH_STM32 0 155 | #define CONFIG_MACH_HC32F460 0 156 | #define CONFIG_MACH_RP2040 0 157 | #define CONFIG_MACH_PRU 0 158 | #define CONFIG_MACH_AR100 0 159 | #define CONFIG_MACH_LINUX 0 160 | #define CONFIG_MACH_SIMU 0 -------------------------------------------------------------------------------- /components/klipper/board/include/board/gpio.h: -------------------------------------------------------------------------------- 1 | #ifndef __ESP32_GPIO_H 2 | #define __ESP32_GPIO_H 3 | 4 | #include "driver/gpio.h" 5 | #include "driver/ledc.h" 6 | #include "esp_adc/adc_cali.h" 7 | #include "esp_adc/adc_cali_scheme.h" 8 | #include "esp_adc/adc_oneshot.h" 9 | #include // uint32_t 10 | #include "driver/i2c_master.h" 11 | #include "driver/spi_master.h" 12 | 13 | 14 | struct gpio_line { 15 | uint32_t pin; 16 | uint32_t state; 17 | }; 18 | struct gpio_out { 19 | struct gpio_line* line; 20 | }; 21 | 22 | 23 | struct gpio_out gpio_out_setup(uint32_t gpio_num, uint32_t val); 24 | void gpio_out_reset(struct gpio_out g, uint32_t val); 25 | void gpio_out_toggle_noirq(struct gpio_out g); 26 | void gpio_out_toggle(struct gpio_out g); 27 | void gpio_out_write(struct gpio_out g, uint32_t val); 28 | 29 | struct gpio_in { 30 | uint32_t pin; 31 | }; 32 | struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up); 33 | void gpio_in_reset(struct gpio_in g, int8_t pull_up); 34 | uint8_t gpio_in_read(struct gpio_in g); 35 | 36 | struct gpio_pwm { 37 | ledc_channel_t channel; 38 | }; 39 | struct gpio_pwm gpio_pwm_setup(uint32_t pin, uint32_t cycle_time, uint16_t val); 40 | void gpio_pwm_write(struct gpio_pwm g, uint16_t val); 41 | 42 | struct gpio_adc { 43 | adc_oneshot_unit_handle_t handle; 44 | adc_channel_t chan; 45 | }; 46 | struct gpio_adc gpio_adc_setup(uint32_t pin); 47 | uint32_t gpio_adc_sample(struct gpio_adc g); 48 | uint16_t gpio_adc_read(struct gpio_adc g); 49 | void gpio_adc_cancel_sample(struct gpio_adc g); 50 | 51 | struct spi_config { 52 | spi_device_handle_t bus; 53 | }; 54 | struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); 55 | void spi_prepare(struct spi_config config); 56 | void spi_transfer(struct spi_config config, uint8_t receive_data, uint8_t len, 57 | uint8_t *data); 58 | 59 | struct i2c_config { 60 | i2c_master_dev_handle_t handle; 61 | }; 62 | 63 | struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); 64 | void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write); 65 | void i2c_read(struct i2c_config config, uint8_t reg_len, uint8_t *reg, 66 | uint8_t read_len, uint8_t *read); 67 | 68 | #endif // gpio.h 69 | -------------------------------------------------------------------------------- /components/klipper/board/include/board/internal.h: -------------------------------------------------------------------------------- 1 | #include "autoconf.h" // CONFIG_FLASH_APPLICATION_ADDRESS 2 | #include "stdlib.h" 3 | 4 | void command_reset(uint32_t *args); 5 | int console_setup(); -------------------------------------------------------------------------------- /components/klipper/board/include/board/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_IO_H 2 | #define __GENERIC_IO_H 3 | 4 | #include "compiler.h" // barrier 5 | #include // uint32_t 6 | 7 | static inline void writel(void *addr, uint32_t val) { 8 | barrier(); 9 | *(volatile uint32_t *)addr = val; 10 | } 11 | static inline void writew(void *addr, uint16_t val) { 12 | barrier(); 13 | *(volatile uint16_t *)addr = val; 14 | } 15 | static inline void writeb(void *addr, uint8_t val) { 16 | barrier(); 17 | *(volatile uint8_t *)addr = val; 18 | } 19 | static inline uint32_t readl(const void *addr) { 20 | uint32_t val = *(volatile const uint32_t *)addr; 21 | barrier(); 22 | return val; 23 | } 24 | static inline uint16_t readw(const void *addr) { 25 | uint16_t val = *(volatile const uint16_t *)addr; 26 | barrier(); 27 | return val; 28 | } 29 | static inline uint8_t readb(const void *addr) { 30 | uint8_t val = *(volatile const uint8_t *)addr; 31 | barrier(); 32 | return val; 33 | } 34 | 35 | #endif // io.h 36 | -------------------------------------------------------------------------------- /components/klipper/board/include/board/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_IRQ_H 2 | #define __GENERIC_IRQ_H 3 | 4 | #include "freertos/FreeRTOS.h" 5 | #include "freertos/queue.h" 6 | #include "freertos/task.h" 7 | #include "sched.h" // DECL_SHUTDOWN 8 | typedef unsigned long irqstatus_t; 9 | 10 | void irq_disable(void); 11 | void irq_enable(void); 12 | irqstatus_t irq_save(void); 13 | void irq_restore(irqstatus_t flag); 14 | void irq_wait(void); 15 | void irq_poll(void); 16 | void clear_active_irq(void); 17 | 18 | #endif // irq.h 19 | -------------------------------------------------------------------------------- /components/klipper/board/include/board/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_MISC_H 2 | #define __GENERIC_MISC_H 3 | 4 | #include // va_list 5 | #include // uint8_t 6 | 7 | struct command_encoder; 8 | void console_sendf(const struct command_encoder *ce, va_list args); 9 | void *console_receive_buffer(void); 10 | 11 | uint32_t timer_from_us(uint32_t us); 12 | uint8_t timer_is_before(uint32_t time1, uint32_t time2); 13 | uint32_t timer_read_time(void); 14 | void timer_kick(void); 15 | 16 | void *dynmem_start(void); 17 | void *dynmem_end(void); 18 | 19 | uint16_t crc16_ccitt(uint8_t *buf, uint_fast8_t len); 20 | 21 | void bootloader_request(void); 22 | 23 | #endif // misc.h 24 | -------------------------------------------------------------------------------- /components/klipper/board/include/board/pgm.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_PGM_H 2 | #define __GENERIC_PGM_H 3 | // This header provides wrappers for the AVR specific "PROGMEM" 4 | // declarations on non-avr platforms. 5 | 6 | #define NEED_PROGMEM 0 7 | #define PROGMEM 8 | #define PSTR(S) S 9 | #define READP(VAR) VAR 10 | #define vsnprintf_P(D, S, F, A) vsnprintf(D, S, F, A) 11 | #define strcasecmp_P(S1, S2) strcasecmp(S1, S2) 12 | #define memcpy_P(DST, SRC, SIZE) memcpy((DST), (SRC), (SIZE)) 13 | 14 | #endif // pgm.h 15 | -------------------------------------------------------------------------------- /components/klipper/board/include/board/serial_irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_SERIAL_IRQ_H 2 | #define __GENERIC_SERIAL_IRQ_H 3 | 4 | #include // uint32_t 5 | 6 | 7 | // callback provided by board specific code 8 | void serial_enable_tx_irq(void); 9 | 10 | // serial_irq.c 11 | void serial_rx_byte(uint_fast8_t data); 12 | int serial_get_tx_byte(uint8_t *pdata); 13 | 14 | #endif // serial_irq.h 15 | -------------------------------------------------------------------------------- /components/klipper/board/include/board/timer_irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __GENERIC_TIMER_IRQ_H 2 | #define __GENERIC_TIMER_IRQ_H 3 | 4 | uint32_t timer_dispatch_many(void); 5 | 6 | #endif // timer_irq.h 7 | -------------------------------------------------------------------------------- /components/klipper/board/internal.c: -------------------------------------------------------------------------------- 1 | // Esp32 internal commands 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/internal.h" // NVIC_SystemReset 12 | #include "autoconf.h" // CONFIG_FLASH_APPLICATION_ADDRESS 13 | #include "board/irq.h" // irq_disable 14 | #include "command.h" // DECL_COMMAND_FLAGS 15 | #include "esp_system.h" 16 | 17 | void command_reset(uint32_t *args) { esp_restart(); } 18 | DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset"); 19 | -------------------------------------------------------------------------------- /components/klipper/board/spi.c: -------------------------------------------------------------------------------- 1 | // Spi control for esp32 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/gpio.h" // spi_setup, spi_prepare, spi_transfer 12 | #include "board/internal.h" // pclock, gpio_peripheral 13 | #include "command.h" // shutdown" 14 | #include "driver/gpio.h" 15 | #include "driver/spi_master.h" 16 | #include "sched.h" // sched_shutdown" 17 | #include 18 | 19 | DECL_ENUMERATION("spi_bus", "SPI1_HOST", 0); 20 | DECL_ENUMERATION("spi_bus", "SPI2_HOST", 1); 21 | DECL_ENUMERATION("spi_bus", "SPI3_HOST", 2); 22 | 23 | struct spi_info { 24 | spi_host_device_t bus; 25 | uint8_t miso_pin, mosi_pin, sck_pin; 26 | }; 27 | 28 | static const struct spi_info spi_bus[] = { 29 | {SPI1_HOST, 7, 8, 6}, 30 | {SPI2_HOST, 13, 12, 11}, 31 | #if SOC_SPI_PERIPH_NUM > 2 32 | {SPI3_HOST, 16, 19, 18}, 33 | #endif 34 | }; 35 | 36 | struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate) { 37 | if (bus >= ARRAY_SIZE(spi_bus)) 38 | shutdown("Invalid spi bus"); 39 | 40 | const struct spi_info *info = &spi_bus[bus]; 41 | 42 | spi_bus_config_t buscfg = { 43 | .miso_io_num = info->miso_pin, 44 | .mosi_io_num = info->mosi_pin, 45 | .sclk_io_num = info->sck_pin, 46 | .quadwp_io_num = -1, 47 | .quadhd_io_num = -1, 48 | .max_transfer_sz = 32, 49 | }; 50 | // Initialize the SPI bus 51 | 52 | spi_device_interface_config_t devcfg = { 53 | .clock_speed_hz = rate, // Clock out at 10 MHz 54 | .mode = mode, // SPI mode 0 55 | .spics_io_num = -1, // CS pin 56 | .queue_size = 7, // We want to be able to queue 7 transactions at a time 57 | }; 58 | 59 | spi_device_handle_t spi; 60 | spi_bus_initialize(info->bus, &buscfg, SPI_DMA_CH_AUTO); 61 | spi_bus_add_device(info->bus, &devcfg, &spi); 62 | 63 | return (struct spi_config){.bus = spi}; 64 | } 65 | 66 | void spi_prepare(struct spi_config config) {} 67 | 68 | void spi_write(struct spi_config config, uint8_t len, uint8_t *data) { 69 | spi_transaction_t t = { 70 | .length = len * 8, 71 | .flags = SPI_TRANS_USE_TXDATA, 72 | .tx_data = {data}, 73 | .user = 0, 74 | }; 75 | spi_device_acquire_bus(config.bus, portMAX_DELAY); 76 | spi_device_polling_transmit(config.bus, &t); 77 | spi_device_release_bus(config.bus); 78 | } 79 | 80 | void spi_read(struct spi_config config, uint8_t len, uint8_t *data) { 81 | spi_transaction_t t = { 82 | .rxlength = len * 8, 83 | .flags = SPI_TRANS_USE_RXDATA, 84 | .user = 0, 85 | }; 86 | spi_device_acquire_bus(config.bus, portMAX_DELAY); 87 | esp_err_t err = spi_device_polling_transmit(config.bus, &t); 88 | spi_device_release_bus(config.bus); 89 | memcpy(data, t.rx_data, len); 90 | } 91 | 92 | void spi_transfer(struct spi_config config, uint8_t receive_data, uint8_t len, 93 | uint8_t *data) { 94 | 95 | spi_write(config, len, data); 96 | if (receive_data) { 97 | spi_read(config, len, data); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /components/klipper/board/timer.c: -------------------------------------------------------------------------------- 1 | // esp32 timer support 2 | // 3 | // Copyright (C) 2024 Nikhil Robinson 4 | // 5 | // This file may be distributed under the terms of the GNU GPLv3 license. 6 | 7 | // Unless required by applicable law or agreed to in writing, this 8 | // software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. 10 | 11 | #include "board/irq.h" // irq_disable 12 | #include "board/misc.h" // timer_read_time 13 | #include "board/timer_irq.h" // timer_dispatch_many 14 | #include "command.h" // DECL_SHUTDOWN 15 | #include "driver/gptimer.h" 16 | #include "esp_log.h" 17 | #include "freertos/FreeRTOS.h" 18 | #include "freertos/queue.h" 19 | #include "freertos/task.h" 20 | #include "sched.h" // DECL_INIT 21 | #include 22 | 23 | static gptimer_handle_t gptimer = NULL; 24 | 25 | volatile bool dispatch_timer = false; 26 | 27 | /**************************************************************** 28 | * Low level timer code 29 | ****************************************************************/ 30 | 31 | // Return the current time (in absolute clock ticks). 32 | uint32_t timer_read_time(void) { 33 | uint32_t count; 34 | ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &count)); 35 | return count; 36 | } 37 | 38 | void timer_set(uint32_t next) { 39 | gptimer_alarm_config_t alarm_config = { 40 | .alarm_count = next, // period = 1s 41 | }; 42 | ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config)); 43 | ESP_ERROR_CHECK(gptimer_start(gptimer)); 44 | } 45 | 46 | // Activate timer dispatch as soon as possible 47 | void timer_kick(void) { timer_set(timer_read_time() + 50); } 48 | 49 | /**************************************************************** 50 | * Setup and irqs 51 | ****************************************************************/ 52 | 53 | static bool IRAM_ATTR example_timer_on_alarm_cb_v1( 54 | gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, 55 | void *user_data) { 56 | 57 | BaseType_t high_task_awoken = pdFALSE; 58 | gptimer_stop(timer); 59 | dispatch_timer = true; 60 | return (high_task_awoken == pdTRUE); 61 | } 62 | 63 | void timer_init(void) { 64 | irq_disable(); 65 | gptimer_config_t timer_config = { 66 | .clk_src = GPTIMER_CLK_SRC_DEFAULT, 67 | .direction = GPTIMER_COUNT_UP, 68 | .resolution_hz = 1000000, // 1MHz, 1 tick=1us 69 | }; 70 | ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer)); 71 | 72 | gptimer_event_callbacks_t cbs = { 73 | .on_alarm = example_timer_on_alarm_cb_v1, 74 | }; 75 | ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, NULL)); 76 | 77 | ESP_ERROR_CHECK(gptimer_enable(gptimer)); 78 | timer_kick(); 79 | irq_enable(); 80 | } 81 | DECL_INIT(timer_init); 82 | 83 | void timer_dispatch() { 84 | if (dispatch_timer) { 85 | uint32_t next = timer_dispatch_many(); 86 | timer_set(next); 87 | dispatch_timer = false; 88 | } 89 | } 90 | 91 | void irq_disable(void) {} 92 | void irq_enable(void) {} 93 | irqstatus_t irq_save(void) { return 0; } 94 | 95 | void irq_restore(irqstatus_t flag) {} 96 | 97 | void irq_wait(void) { 98 | extern void console_kick(); 99 | console_kick(); 100 | vTaskDelay(1); 101 | } 102 | void irq_poll(void) { timer_dispatch(); } 103 | 104 | void clear_active_irq(void) {} 105 | DECL_SHUTDOWN(clear_active_irq); -------------------------------------------------------------------------------- /components/klipper/compile_time_request.txt: -------------------------------------------------------------------------------- 1 | _DECL_ENCODER starting 2 | _DECL_ENCODER is_shutdown static_string_id=%hu 3 | _DECL_ENCODER shutdown clock=%u static_string_id=%hu 4 | _DECL_STATIC_STR Shutdown cleared when not shutdown 5 | _DECL_STATIC_STR Timer too close 6 | _DECL_STATIC_STR sentinel timer called 7 | _DECL_STATIC_STR Invalid command 8 | _DECL_CALLLIST ctr_run_shutdownfuncs sendf_shutdown 9 | _DECL_STATIC_STR Message encode error 10 | _DECL_STATIC_STR Command parser error 11 | DECL_COMMAND_FLAGS command_identify 0x01 identify offset=%u count=%c 12 | _DECL_ENCODER identify_response offset=%u data=%.*s 13 | DECL_COMMAND_FLAGS command_clear_shutdown 0x01 clear_shutdown 14 | DECL_COMMAND_FLAGS command_emergency_stop 0x01 emergency_stop 15 | _DECL_STATIC_STR Command request 16 | _DECL_ENCODER stats count=%u sum=%u sumsq=%u 17 | DECL_CONSTANT STATS_SUMSQ_BASE +0x00000100 18 | DECL_COMMAND_FLAGS command_get_uptime 0x01 get_uptime 19 | _DECL_ENCODER uptime high=%u clock=%u 20 | DECL_COMMAND_FLAGS command_get_clock 0x01 get_clock 21 | _DECL_ENCODER clock clock=%u 22 | _DECL_STATIC_STR config_reset only available when shutdown 23 | DECL_COMMAND_FLAGS command_finalize_config 0 finalize_config crc=%u 24 | DECL_COMMAND_FLAGS command_get_config 0x01 get_config 25 | _DECL_ENCODER config is_config=%c crc=%u is_shutdown=%c move_count=%hu 26 | DECL_COMMAND_FLAGS command_allocate_oids 0 allocate_oids count=%c 27 | _DECL_STATIC_STR oids already allocated 28 | _DECL_STATIC_STR Can't assign oid 29 | _DECL_STATIC_STR Invalid oid type 30 | _DECL_STATIC_STR Already finalized 31 | _DECL_CALLLIST ctr_run_shutdownfuncs move_reset 32 | _DECL_STATIC_STR Invalid move request size 33 | _DECL_STATIC_STR Move queue overflow 34 | _DECL_STATIC_STR alloc_chunks failed 35 | _DECL_STATIC_STR alloc_chunk failed 36 | _DECL_CALLLIST ctr_run_initfuncs alloc_init 37 | DECL_COMMAND_FLAGS command_debug_nop 0x01 debug_nop 38 | DECL_COMMAND_FLAGS command_debug_ping 0x01 debug_ping data=%*s 39 | _DECL_ENCODER pong data=%*s 40 | DECL_COMMAND_FLAGS command_debug_write 0x01 debug_write order=%c addr=%u val=%u 41 | DECL_COMMAND_FLAGS command_debug_read 0x01 debug_read order=%c addr=%u 42 | _DECL_ENCODER debug_result val=%u 43 | _DECL_CALLLIST ctr_run_initfuncs initial_pins_setup 44 | DECL_INITIAL_PINS "" 45 | DECL_COMMAND_FLAGS command_set_digital_out 0 set_digital_out pin=%u value=%c 46 | _DECL_CALLLIST ctr_run_shutdownfuncs digital_out_shutdown 47 | DECL_COMMAND_FLAGS command_update_digital_out 0 update_digital_out oid=%c value=%c 48 | _DECL_STATIC_STR update_digital_out not valid with active queue 49 | DECL_COMMAND_FLAGS command_queue_digital_out 0 queue_digital_out oid=%c clock=%u on_ticks=%u 50 | _DECL_STATIC_STR Scheduled digital out event will exceed max_duration 51 | DECL_COMMAND_FLAGS command_set_digital_out_pwm_cycle 0 set_digital_out_pwm_cycle oid=%c cycle_ticks=%u 52 | _DECL_STATIC_STR Can not set soft pwm cycle ticks while updates pending 53 | DECL_COMMAND_FLAGS command_config_digital_out 0 config_digital_out oid=%c pin=%u value=%c default_value=%c max_duration=%u 54 | _DECL_STATIC_STR Scheduled digital out event will exceed max_duration 55 | _DECL_STATIC_STR Missed scheduling of next digital out event 56 | _DECL_CALLLIST ctr_run_shutdownfuncs stepper_shutdown 57 | DECL_COMMAND_FLAGS command_stepper_stop_on_trigger 0 stepper_stop_on_trigger oid=%c trsync_oid=%c 58 | DECL_COMMAND_FLAGS command_stepper_get_position 0 stepper_get_position oid=%c 59 | _DECL_ENCODER stepper_position oid=%c pos=%i 60 | DECL_COMMAND_FLAGS command_reset_step_clock 0 reset_step_clock oid=%c clock=%u 61 | _DECL_STATIC_STR Can't reset time when stepper active 62 | DECL_COMMAND_FLAGS command_set_next_step_dir 0 set_next_step_dir oid=%c dir=%c 63 | DECL_COMMAND_FLAGS command_queue_step 0 queue_step oid=%c interval=%u count=%hu add=%hi 64 | _DECL_STATIC_STR Invalid count parameter 65 | DECL_COMMAND_FLAGS command_config_stepper 0 config_stepper oid=%c step_pin=%c dir_pin=%c invert_step=%c step_pulse_ticks=%u 66 | _DECL_STATIC_STR Stepper too far in past 67 | DECL_COMMAND_FLAGS command_endstop_query_state 0 endstop_query_state oid=%c 68 | _DECL_ENCODER endstop_state oid=%c homing=%c next_clock=%u pin_value=%c 69 | DECL_COMMAND_FLAGS command_endstop_home 0 endstop_home oid=%c clock=%u sample_ticks=%u sample_count=%c rest_ticks=%u pin_value=%c trsync_oid=%c trigger_reason=%c 70 | DECL_COMMAND_FLAGS command_config_endstop 0 config_endstop oid=%c pin=%c pull_up=%c 71 | _DECL_CALLLIST ctr_run_shutdownfuncs trsync_shutdown 72 | _DECL_CALLLIST ctr_run_taskfuncs trsync_task 73 | DECL_COMMAND_FLAGS command_trsync_trigger 0 trsync_trigger oid=%c reason=%c 74 | _DECL_ENCODER trsync_state oid=%c can_trigger=%c trigger_reason=%c clock=%u 75 | DECL_COMMAND_FLAGS command_trsync_set_timeout 0 trsync_set_timeout oid=%c clock=%u 76 | DECL_COMMAND_FLAGS command_trsync_start 0 trsync_start oid=%c report_clock=%u report_ticks=%u expire_reason=%c 77 | _DECL_STATIC_STR Can't add signal that is already active 78 | DECL_COMMAND_FLAGS command_config_trsync 0 config_trsync oid=%c 79 | _DECL_CALLLIST ctr_run_shutdownfuncs analog_in_shutdown 80 | _DECL_CALLLIST ctr_run_taskfuncs analog_in_task 81 | _DECL_ENCODER analog_in_state oid=%c next_clock=%u value=%hu 82 | DECL_COMMAND_FLAGS command_query_analog_in 0 query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c rest_ticks=%u min_value=%hu max_value=%hu range_check_count=%c 83 | DECL_COMMAND_FLAGS command_config_analog_in 0 config_analog_in oid=%c pin=%u 84 | _DECL_STATIC_STR ADC out of range 85 | _DECL_CALLLIST ctr_run_shutdownfuncs spidev_shutdown 86 | DECL_COMMAND_FLAGS command_config_spi_shutdown 0 config_spi_shutdown oid=%c spi_oid=%c shutdown_msg=%*s 87 | DECL_COMMAND_FLAGS command_spi_send 0 spi_send oid=%c data=%*s 88 | DECL_COMMAND_FLAGS command_spi_transfer 0 spi_transfer oid=%c data=%*s 89 | _DECL_ENCODER spi_transfer_response oid=%c response=%*s 90 | _DECL_STATIC_STR Invalid spi config 91 | DECL_COMMAND_FLAGS command_spi_set_bus 0 spi_set_bus oid=%c spi_bus=%u mode=%u rate=%u 92 | _DECL_STATIC_STR Invalid spi config 93 | DECL_COMMAND_FLAGS command_config_spi_without_cs 0 config_spi_without_cs oid=%c 94 | DECL_COMMAND_FLAGS command_config_spi 0 config_spi oid=%c pin=%u cs_active_high=%c 95 | DECL_COMMAND_FLAGS command_i2c_modify_bits 0 i2c_modify_bits oid=%c reg=%*s clear_set_bits=%*s 96 | _DECL_STATIC_STR i2c_modify_bits: Odd number of bits! 97 | DECL_COMMAND_FLAGS command_i2c_read 0 i2c_read oid=%c reg=%*s read_len=%u 98 | _DECL_ENCODER i2c_read_response oid=%c response=%*s 99 | DECL_COMMAND_FLAGS command_i2c_write 0 i2c_write oid=%c data=%*s 100 | DECL_COMMAND_FLAGS command_i2c_set_bus 0 i2c_set_bus oid=%c i2c_bus=%u rate=%u address=%u 101 | DECL_COMMAND_FLAGS command_config_i2c 0 config_i2c oid=%c 102 | DECL_COMMAND_FLAGS command_set_pwm_out 0 set_pwm_out pin=%u cycle_ticks=%u value=%hu 103 | _DECL_CALLLIST ctr_run_shutdownfuncs pwm_shutdown 104 | DECL_COMMAND_FLAGS command_queue_pwm_out 0 queue_pwm_out oid=%c clock=%u value=%hu 105 | _DECL_STATIC_STR Scheduled pwm event will exceed max_duration 106 | DECL_COMMAND_FLAGS command_config_pwm_out 0 config_pwm_out oid=%c pin=%u cycle_ticks=%u value=%hu default_value=%hu max_duration=%u 107 | _DECL_STATIC_STR Scheduled pwm event will exceed max_duration 108 | _DECL_STATIC_STR Missed scheduling of next hard pwm event 109 | _DECL_CALLLIST ctr_run_taskfuncs buttons_task 110 | _DECL_ENCODER buttons_state oid=%c ack_count=%c state=%*s 111 | DECL_COMMAND_FLAGS command_buttons_ack 0 buttons_ack oid=%c count=%c 112 | DECL_COMMAND_FLAGS command_buttons_query 0 buttons_query oid=%c clock=%u rest_ticks=%u retransmit_count=%c invert=%c 113 | _DECL_STATIC_STR Invalid buttons retransmit count 114 | DECL_COMMAND_FLAGS command_buttons_add 0 buttons_add oid=%c pos=%c pin=%u pull_up=%c 115 | _DECL_STATIC_STR Set button past maximum button count 116 | DECL_COMMAND_FLAGS command_config_buttons 0 config_buttons oid=%c button_count=%c 117 | _DECL_STATIC_STR Max of 8 buttons 118 | _DECL_CALLLIST ctr_run_shutdownfuncs tmcuart_shutdown 119 | _DECL_CALLLIST ctr_run_taskfuncs tmcuart_task 120 | _DECL_ENCODER tmcuart_response oid=%c read=%*s 121 | DECL_COMMAND_FLAGS command_tmcuart_send 0 tmcuart_send oid=%c write=%*s read=%c 122 | _DECL_STATIC_STR tmcuart data too large 123 | DECL_COMMAND_FLAGS command_config_tmcuart 0 config_tmcuart oid=%c rx_pin=%u pull_up=%c tx_pin=%u bit_time=%u 124 | DECL_COMMAND_FLAGS command_neopixel_send 0 neopixel_send oid=%c 125 | _DECL_ENCODER neopixel_result oid=%c success=%c 126 | DECL_COMMAND_FLAGS command_neopixel_update 0 neopixel_update oid=%c pos=%hu data=%*s 127 | _DECL_STATIC_STR Invalid neopixel update command 128 | DECL_COMMAND_FLAGS command_config_neopixel 0 config_neopixel oid=%c pin=%u data_size=%hu bit_max_ticks=%u reset_min_ticks=%u 129 | _DECL_STATIC_STR Invalid neopixel data_size 130 | _DECL_CALLLIST ctr_run_taskfuncs counter_task 131 | _DECL_ENCODER counter_state oid=%c next_clock=%u count=%u count_clock=%u 132 | DECL_COMMAND_FLAGS command_query_counter 0 query_counter oid=%c clock=%u poll_ticks=%u sample_ticks=%u 133 | DECL_COMMAND_FLAGS command_config_counter 0 config_counter oid=%c pin=%u pull_up=%c 134 | _DECL_CALLLIST ctr_run_shutdownfuncs st7920_shutdown 135 | DECL_COMMAND_FLAGS command_st7920_send_data 0 st7920_send_data oid=%c data=%*s 136 | DECL_COMMAND_FLAGS command_st7920_send_cmds 0 st7920_send_cmds oid=%c cmds=%*s 137 | DECL_COMMAND_FLAGS command_config_st7920 0 config_st7920 oid=%c cs_pin=%u sclk_pin=%u sid_pin=%u sync_delay_ticks=%u cmd_delay_ticks=%u 138 | _DECL_CALLLIST ctr_run_shutdownfuncs hd44780_shutdown 139 | DECL_COMMAND_FLAGS command_hd44780_send_data 0 hd44780_send_data oid=%c data=%*s 140 | DECL_COMMAND_FLAGS command_hd44780_send_cmds 0 hd44780_send_cmds oid=%c cmds=%*s 141 | DECL_COMMAND_FLAGS command_config_hd44780 0 config_hd44780 oid=%c rs_pin=%u e_pin=%u d4_pin=%u d5_pin=%u d6_pin=%u d7_pin=%u delay_ticks=%u 142 | DECL_COMMAND_FLAGS command_spi_set_software_bus 0 spi_set_software_bus oid=%c miso_pin=%u mosi_pin=%u sclk_pin=%u mode=%u rate=%u 143 | _DECL_STATIC_STR Invalid spi config 144 | _DECL_STATIC_STR soft_i2c NACK 145 | DECL_COMMAND_FLAGS command_i2c_set_software_bus 0 i2c_set_software_bus oid=%c scl_pin=%u sda_pin=%u rate=%u address=%u 146 | _DECL_CALLLIST ctr_run_taskfuncs thermocouple_task 147 | _DECL_STATIC_STR Thermocouple reader fault 148 | _DECL_ENCODER thermocouple_result oid=%c next_clock=%u value=%u fault=%c 149 | DECL_COMMAND_FLAGS command_query_thermocouple 0 query_thermocouple oid=%c clock=%u rest_ticks=%u min_value=%u max_value=%u max_invalid_count=%c 150 | DECL_COMMAND_FLAGS command_config_thermocouple 0 config_thermocouple oid=%c spi_oid=%c thermocouple_type=%c 151 | _DECL_STATIC_STR Invalid thermocouple chip type 152 | DECL_ENUMERATION thermocouple_type MAX6675 +0x00000003 153 | DECL_ENUMERATION thermocouple_type MAX31865 +0x00000002 154 | DECL_ENUMERATION thermocouple_type MAX31856 +0x00000001 155 | DECL_ENUMERATION thermocouple_type MAX31855 +0x00000000 156 | _DECL_CALLLIST ctr_run_taskfuncs adxl345_task 157 | DECL_COMMAND_FLAGS command_query_adxl345_status 0 query_adxl345_status oid=%c 158 | DECL_COMMAND_FLAGS command_query_adxl345 0 query_adxl345 oid=%c rest_ticks=%u 159 | DECL_COMMAND_FLAGS command_config_adxl345 0 config_adxl345 oid=%c spi_oid=%c 160 | _DECL_CALLLIST ctr_run_taskfuncs spi_angle_task 161 | DECL_COMMAND_FLAGS command_spi_angle_transfer 0 spi_angle_transfer oid=%c data=%*s 162 | _DECL_ENCODER spi_angle_transfer_response oid=%c clock=%u response=%*s 163 | DECL_COMMAND_FLAGS command_query_spi_angle 0 query_spi_angle oid=%c clock=%u rest_ticks=%u time_shift=%c 164 | DECL_COMMAND_FLAGS command_config_spi_angle 0 config_spi_angle oid=%c spi_oid=%c spi_angle_type=%c 165 | _DECL_STATIC_STR angle sensor requires cs pin 166 | _DECL_STATIC_STR Invalid spi_angle chip type 167 | DECL_ENUMERATION spi_angle_type tle5012b +0x00000002 168 | DECL_ENUMERATION spi_angle_type as5047d +0x00000001 169 | DECL_ENUMERATION spi_angle_type a1333 +0x00000000 170 | _DECL_CALLLIST ctr_run_taskfuncs mpu9250_task 171 | DECL_COMMAND_FLAGS command_query_mpu9250_status 0 query_mpu9250_status oid=%c 172 | DECL_COMMAND_FLAGS command_query_mpu9250 0 query_mpu9250 oid=%c rest_ticks=%u 173 | DECL_COMMAND_FLAGS command_config_mpu9250 0 config_mpu9250 oid=%c i2c_oid=%c 174 | _DECL_CALLLIST ctr_run_taskfuncs lis2dw_task 175 | DECL_COMMAND_FLAGS command_query_lis2dw_status 0 query_lis2dw_status oid=%c 176 | DECL_COMMAND_FLAGS command_query_lis2dw 0 query_lis2dw oid=%c rest_ticks=%u 177 | DECL_COMMAND_FLAGS command_config_lis2dw 0 config_lis2dw oid=%c spi_oid=%c 178 | _DECL_CALLLIST ctr_run_taskfuncs ldc1612_task 179 | DECL_COMMAND_FLAGS command_query_ldc1612_status 0 query_ldc1612_status oid=%c 180 | DECL_COMMAND_FLAGS command_query_ldc1612 0 query_ldc1612 oid=%c rest_ticks=%u 181 | DECL_COMMAND_FLAGS command_query_ldc1612_home_state 0 query_ldc1612_home_state oid=%c 182 | _DECL_ENCODER ldc1612_home_state oid=%c homing=%c trigger_clock=%u 183 | DECL_COMMAND_FLAGS command_ldc1612_setup_home 0 ldc1612_setup_home oid=%c clock=%u threshold=%u trsync_oid=%c trigger_reason=%c 184 | DECL_COMMAND_FLAGS command_config_ldc1612 0 config_ldc1612 oid=%c i2c_oid=%c 185 | _DECL_ENCODER sensor_bulk_status oid=%c clock=%u query_ticks=%u next_sequence=%hu buffered=%u possible_overflows=%hu 186 | _DECL_ENCODER sensor_bulk_data oid=%c sequence=%hu data=%*s 187 | DECL_COMMAND_FLAGS command_config_reset 0x01 config_reset 188 | _DECL_STATIC_STR config_reset only available when shutdown 189 | DECL_CONSTANT_STR MCU linux 190 | _DECL_CALLLIST ctr_run_initfuncs timer_init 191 | _DECL_STATIC_STR Rescheduled timer in the past 192 | DECL_CONSTANT CLOCK_FREQ +0x02FAF080 193 | _DECL_CALLLIST ctr_run_taskfuncs console_task 194 | _DECL_STATIC_STR Force shutdown command 195 | _DECL_STATIC_STR Unable to write to spi 196 | _DECL_STATIC_STR Unable to issue spi ioctl 197 | _DECL_STATIC_STR Unable to set SPI mode 198 | _DECL_STATIC_STR Unable to set SPI speed 199 | _DECL_STATIC_STR Unable to set non-blocking on spi device 200 | _DECL_STATIC_STR Unable to open spi device 201 | _DECL_STATIC_STR Too many spi devices 202 | DECL_ENUMERATION spi_bus SPI3_HOST +0x00000002 203 | DECL_ENUMERATION spi_bus SPI2_HOST +0x00000001 204 | DECL_ENUMERATION spi_bus SPI1_HOST +0x00000000 205 | _DECL_STATIC_STR Error on analog read 206 | _DECL_STATIC_STR Unable to open adc device 207 | DECL_CONSTANT ADC_MAX +0x00000FFF 208 | _DECL_STATIC_STR Unable to config pwm device 209 | DECL_CONSTANT PWM_MAX +0x00002000 210 | _DECL_STATIC_STR Unable to read i2c device 211 | _DECL_STATIC_STR Unable write i2c device 212 | _DECL_STATIC_STR Unable to open i2c device 213 | DECL_CONSTANT_STR BUS_PINS_i2c1 GPIO_NUM_48,GPIO_NUM_47 214 | DECL_CONSTANT_STR BUS_PINS_i2c0 GPIO_NUM_8,GPIO_NUM_9 215 | DECL_ENUMERATION_RANGE i2c_bus I2C_NUM_0 +0x00000000 +0x00000002 216 | _DECL_STATIC_STR Unable to open in GPIO chip line 217 | _DECL_STATIC_STR Unable to open out GPIO chip line 218 | _DECL_STATIC_STR Unable to open GPIO chip device 219 | _DECL_STATIC_STR GPIO chip device not found 220 | DECL_ENUMERATION_RANGE pin GPIO_NUM_0 +0x00000000 +0x000000FF 221 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "main.c" 2 | INCLUDE_DIRS "." 3 | REQUIRES klipper) -------------------------------------------------------------------------------- /main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Klipper Firmware Configuration" 2 | config MCU 3 | string "MCU NAME" 4 | default "esp32" 5 | config CLOCK_FREQ 6 | int "Timer frequency" 7 | default 1000000 8 | config HAVE_GPIO 9 | bool "Board support GPIO" 10 | config HAVE_GPIO_ADC 11 | bool "Board support ADC" 12 | config HAVE_GPIO_SPI 13 | bool "Board support SPI" 14 | config HAVE_GPIO_SDIO 15 | bool "Board support SDIO" 16 | config HAVE_GPIO_I2C 17 | bool "Board support I2C" 18 | config HAVE_GPIO_HARD_PWM 19 | bool "Board support PWM" 20 | config HAVE_STRICT_TIMING 21 | bool "Board needs STRICT timing" 22 | config HAVE_CHIPID 23 | bool "Board have chip-id" 24 | config HAVE_STEPPER_BOTH_EDGE 25 | bool "Board support stepper both edge" 26 | config HAVE_BOOTLOADER_REQUEST 27 | bool "Board have bootloader request" 28 | config HAVE_LIMITED_CODE_SIZE 29 | bool "Board have limited code size" 30 | config INLINE_STEPPER_HACK 31 | bool "Enables gcc to inline stepper_event() into the main timer irq handler" 32 | config SERIAL 33 | bool "Enable serial" 34 | config SERIAL_BAUD 35 | int "Baud rate for serial port" 36 | default 250000 37 | help 38 | Specify the baud rate of the serial port. This should be set 39 | to 250000. Read the FAQ before changing this value. 40 | config WANT_GPIO_BITBANGING 41 | bool "Support GPIO bit-banging devices" 42 | config WANT_DISPLAYS 43 | bool "Support LCD devices" 44 | config WANT_SENSORS 45 | bool "Support external sensor devices" 46 | config WANT_LIS2DW 47 | bool "Support lis2dw 3-axis accelerometer" 48 | config WANT_LDC1612 49 | bool "Support ldc1612 eddy current sensor" 50 | config WANT_SOFTWARE_I2C 51 | bool "Support software based I2C bit-banging" 52 | config WANT_SOFTWARE_SPI 53 | bool "Support software based SPI bit-banging" 54 | 55 | 56 | endmenu 57 | -------------------------------------------------------------------------------- /main/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "board/misc.h" // console_sendf 4 | #include "command.h" // DECL_CONSTANT 5 | #include "board/internal.h" // console_setup 6 | #include "sched.h" // sched_main 7 | #include "freertos/FreeRTOS.h" 8 | #include "freertos/queue.h" 9 | #include "freertos/task.h" 10 | 11 | DECL_CONSTANT_STR("MCU", "esp32"); 12 | 13 | 14 | void command_config_reset(uint32_t *args) 15 | { 16 | if (! sched_is_shutdown()) 17 | shutdown("config_reset only available when shutdown"); 18 | esp_restart(); 19 | } 20 | DECL_COMMAND_FLAGS(command_config_reset, HF_IN_SHUTDOWN, "config_reset"); 21 | 22 | void main_task(void *pvparameters) 23 | { 24 | console_setup(); 25 | for (;;) 26 | { 27 | sched_main(); 28 | } 29 | vTaskDelete(NULL); 30 | 31 | } 32 | 33 | void app_main(void) 34 | { 35 | xTaskCreatePinnedToCore(main_task, "main_task", 4096, NULL, 20, NULL, 36 | 0); 37 | } 38 | -------------------------------------------------------------------------------- /printer.cfg: -------------------------------------------------------------------------------- 1 | [include mainsail.cfg] 2 | 3 | [mcu] 4 | serial: /dev/serial/by-path/pci-0000:01:00.0-usb-0:7:1.0-port0 5 | 6 | 7 | [printer] 8 | kinematics: none 9 | max_velocity: 300 10 | max_accel: 300 11 | 12 | -------------------------------------------------------------------------------- /sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | CONFIG_FREERTOS_HZ=1000 --------------------------------------------------------------------------------