diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 59c70d2..4f14c54 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "spincoat-plater-firmware.c" "dshot_esc_encoder.c" - PRIV_REQUIRES esp_driver_rmt esp_driver_gpio + PRIV_REQUIRES esp_driver_rmt esp_driver_uart INCLUDE_DIRS ".") diff --git a/main/Kconfig b/main/Kconfig new file mode 100644 index 0000000..47094ac --- /dev/null +++ b/main/Kconfig @@ -0,0 +1,12 @@ +menu "Pin Mapping Configuration" + config ESC_CTRL_PIN + int "ESC control GPIO pin" + default 22 + help + This is the pin used for sending DSHOT packets to the ESC. + config TELEMETRY_RX_PIN + int "ESC telemetry uart rx pin" + default 27 + help + This is the pin used for receiving UART telemetry from the ESC. +endmenu diff --git a/main/spincoat-plater-firmware.c b/main/spincoat-plater-firmware.c index 45e665c..32300ae 100644 --- a/main/spincoat-plater-firmware.c +++ b/main/spincoat-plater-firmware.c @@ -4,11 +4,13 @@ * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ +#include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/rmt_tx.h" -#include "driver/gpio.h" +#include "driver/uart.h" #include "dshot_esc_encoder.h" #if CONFIG_IDF_TARGET_ESP32H2 @@ -16,11 +18,18 @@ #else #define DSHOT_ESC_RESOLUTION_HZ 40000000 // 40MHz resolution, DSHot protocol needs a relative high resolution #endif -#define DSHOT_ESC_GPIO_NUM 22 -#define DSHOT_ESC_TELEMETRY_GPIO_NUM 27 +#define GPIO_ESC_CTRL CONFIG_ESC_CTRL_PIN +#define GPIO_ESC_RX CONFIG_TELEMETRY_RX_PIN +#define UART_NUM UART_NUM_2 + +#define ESP_INTR_FLAG_DEFAULT 0 static const char *TAG = "spincoat-plater-firmware"; +//static QueueHandle_t gpio_evt_queue = NULL; +static QueueHandle_t uart_queue = NULL; +const int uart_buffer_size = (1024 * 2); + rmt_encoder_handle_t dshot_encoder = NULL; rmt_channel_handle_t esc_chan = NULL; @@ -37,7 +46,7 @@ dshot_esc_throttle_t throttle = { * Sends a telemetry packet at a set, constant interval */ void v_telemetry_packet_func(void *pvParameters) { - TickType_t frequency = 1000 / portTICK_PERIOD_MS; + TickType_t frequency = 10 / portTICK_PERIOD_MS; TickType_t last_wake_time = xTaskGetTickCount(); while(1) { throttle.telemetry_req = true; @@ -63,7 +72,6 @@ void initialize_esc_throttle(void) { xTaskCreate(&v_initialize_esc_throttle_func, "v_init_throttle_func", 2048, NULL, 5, &v_init_throttle_handle); vTaskDelay(pdMS_TO_TICKS(5000)); vTaskDelete(v_init_throttle_handle); - //vTaskDelay(pdMS_TO_TICKS(1000)); } /** @@ -73,7 +81,7 @@ void init_rmt_esc_tx(void) { ESP_LOGI(TAG, "Create RMT TX channel"); rmt_tx_channel_config_t tx_chan_config = { .clk_src = RMT_CLK_SRC_DEFAULT, // select a clock that can provide needed resolution - .gpio_num = DSHOT_ESC_GPIO_NUM, + .gpio_num = GPIO_ESC_CTRL, .mem_block_symbols = 64, .resolution_hz = DSHOT_ESC_RESOLUTION_HZ, .trans_queue_depth = 10, // set the number of transactions that can be pending in the background @@ -95,6 +103,21 @@ void init_rmt_esc_tx(void) { initialize_esc_throttle(); } +void init_telemetry_uart_rx(void) { + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + .rx_flow_ctrl_thresh = 122, + }; + + ESP_ERROR_CHECK(uart_driver_install(UART_NUM, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0)); + ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NUM, UART_PIN_NO_CHANGE, GPIO_ESC_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); +} + /** * Sends a DSHOT packet via the RMT. Make sure the RMT channel has been initialized * by calling *init_rmt_esc_tx()* @@ -107,30 +130,79 @@ void send_dshot_packet(void) { } } +/** + * Calculate one step of the crc8 and return it + */ +uint8_t update_crc8(uint8_t crc, uint8_t crc_seed){ + uint8_t crc_u, i; + crc_u = crc; + crc_u ^= crc_seed; + for ( i=0; i<8; i++) crc_u = ( crc_u & 0x80 ) ? 0x7 ^ ( crc_u << 1 ) : ( crc_u << 1 ); + return (crc_u); +} + +/** + * Calculate the entire crc8 for a KISS frame and return it for validation against the + * transmitted crc8 + */ +uint8_t get_crc8(uint8_t *Buf, uint8_t BufLen){ + uint8_t crc = 0, i; + for( i=0; i= 10) { + parse_telemetry(); + } } }