mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-04-18 09:25:06 +00:00
Add kernel drivers for SPI and UART and make locking APIs more consistent (#489)
- Add kernel support for SPI driver - Add kernel support for UART driver - Implemented ESP32 UART kernel driver - Update existing UART-related code in Tactility to use new kernel driver - Remove UART from tt::hal::Configuration - Remove tt_hal_uart functionality but keep functions for now - Update devicetrees for UART changes - Kernel mutex and recursive mutex: improved locking API design - Other kernel improvements - Added device_exists_of_type() and device_find_by_name()
This commit is contained in:
parent
7e24105d0c
commit
74127a5f6c
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -80,31 +81,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
},
|
||||
},
|
||||
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "P1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_1,
|
||||
.txPin = GPIO_NUM_3,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -20,4 +21,13 @@
|
||||
pin-sda = <27>;
|
||||
pin-scl = <22>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <3>;
|
||||
pin-rx = <1>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -80,30 +81,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
},
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "P1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_1,
|
||||
.txPin = GPIO_NUM_3,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -20,4 +21,13 @@
|
||||
pin-sda = <27>;
|
||||
pin-scl = <22>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <3>;
|
||||
pin-rx = <1>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/St7701Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "PwmBacklight.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
|
||||
@ -46,31 +47,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// P4 header, JST SH 1.0, GND / 3.3V / IO17 / IO18
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_17,
|
||||
.txPin = GPIO_NUM_18,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.config = {
|
||||
.baud_rate = 9600,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -30,4 +31,13 @@
|
||||
pin-sda = <17>;
|
||||
pin-scl = <18>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <18>;
|
||||
pin-rx = <17>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/SdCard.h"
|
||||
#include "devices/Display.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "devices/SdCard.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/Power.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "PwmBacklight.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -70,55 +71,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr // No custom lock needed
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART0-IN"
|
||||
uart::Configuration {
|
||||
.name = "UART0",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
// "UART1-OUT"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_2,
|
||||
.rxPin = GPIO_NUM_18,
|
||||
.txPin = GPIO_NUM_17,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,22 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <17>;
|
||||
pin-rx = <18>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -72,55 +73,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr // No custom lock needed
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART0-IN"
|
||||
uart::Configuration {
|
||||
.name = "UART0",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
// "UART1-OUT"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_2,
|
||||
.rxPin = GPIO_NUM_18,
|
||||
.txPin = GPIO_NUM_17,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,22 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <17>;
|
||||
pin-rx = <18>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <TCA9534.h>
|
||||
@ -56,55 +57,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr // No custom lock needed
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART0-OUT"
|
||||
uart::Configuration {
|
||||
.name = "UART0",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
// "UART1-OUT"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_2,
|
||||
.rxPin = GPIO_NUM_19,
|
||||
.txPin = GPIO_NUM_20,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,22 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <20>;
|
||||
pin-rx = <19>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "PwmBacklight.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -72,31 +73,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr // No custom lock needed
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART1"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_16,
|
||||
.txPin = GPIO_NUM_17,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <17>;
|
||||
pin-rx = <16>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Xpt2046Power.h>
|
||||
@ -74,31 +75,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr // No custom lock needed
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART1"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_3,
|
||||
.txPin = GPIO_NUM_1,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <1>;
|
||||
pin-rx = <3>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <PwmBacklight.h>
|
||||
@ -46,31 +47,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART1"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <PwmBacklight.h>
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
@ -80,31 +81,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
//CN1 header, JST SH 1.25, GND / IO22 / IO21 / 3.3V
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_21,
|
||||
.txPin = GPIO_NUM_22,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.config = {
|
||||
.baud_rate = 9600,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -13,7 +14,7 @@
|
||||
gpio-count = <40>;
|
||||
};
|
||||
|
||||
i2c_internal {
|
||||
i2c_internal: i2c0 {
|
||||
compatible = "espressif,esp32-i2c";
|
||||
port = <I2C_NUM_0>;
|
||||
clock-frequency = <400000>;
|
||||
@ -21,12 +22,22 @@
|
||||
pin-scl = <32>;
|
||||
};
|
||||
|
||||
/* CN1 header */
|
||||
i2c_external {
|
||||
// CN1 header
|
||||
i2c_external: i2c1 {
|
||||
compatible = "espressif,esp32-i2c";
|
||||
port = <I2C_NUM_1>;
|
||||
clock-frequency = <400000>;
|
||||
pin-sda = <21>;
|
||||
pin-scl = <22>;
|
||||
};
|
||||
|
||||
// CN1 header, JST SH 1.25, GND / IO22 / IO21 / 3.3V
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <22>;
|
||||
pin-rx = <21>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -74,31 +75,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
//P1 header, JST SH 1.25, 5V / TXD (43) / RXD (44) / GND
|
||||
uart::Configuration {
|
||||
.name = "UART0",
|
||||
.port = UART_NUM_0,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -13,7 +14,7 @@
|
||||
gpio-count = <49>;
|
||||
};
|
||||
|
||||
i2c_internal {
|
||||
i2c_internal: i2c0 {
|
||||
compatible = "espressif,esp32-i2c";
|
||||
port = <I2C_NUM_0>;
|
||||
clock-frequency = <400000>;
|
||||
@ -23,7 +24,7 @@
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
i2c_external {
|
||||
i2c_external: i2c1 {
|
||||
compatible = "espressif,esp32-i2c";
|
||||
port = <I2C_NUM_1>;
|
||||
clock-frequency = <400000>;
|
||||
@ -32,4 +33,14 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
// P1 header
|
||||
uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "PwmBacklight.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
|
||||
@ -45,31 +46,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
//P4 header, JST SH 1.0, GND / 3.3V / IO17 / IO18
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_17,
|
||||
.txPin = GPIO_NUM_18,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.config = {
|
||||
.baud_rate = 9600,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -13,7 +14,7 @@
|
||||
gpio-count = <49>;
|
||||
};
|
||||
|
||||
i2c_internal {
|
||||
i2c_internal: i2c0 {
|
||||
compatible = "espressif,esp32-i2c";
|
||||
port = <I2C_NUM_0>;
|
||||
clock-frequency = <400000>;
|
||||
@ -23,7 +24,7 @@
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
i2c_external {
|
||||
i2c_external: i2c1 {
|
||||
compatible = "espressif,esp32-i2c";
|
||||
port = <I2C_NUM_1>;
|
||||
clock-frequency = <400000>;
|
||||
@ -32,4 +33,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <18>;
|
||||
pin-rx = <17>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "devices/Sdcard.h"
|
||||
#include "devices/TdeckKeyboard.h"
|
||||
#include "devices/TrackballDevice.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -50,30 +51,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Grove",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.config = {
|
||||
.baud_rate = 38400,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,7 +58,7 @@ bool initBoot() {
|
||||
std::vector<tt::hal::gps::GpsConfiguration> gps_configurations;
|
||||
gps_service->getGpsConfigurations(gps_configurations);
|
||||
if (gps_configurations.empty()) {
|
||||
if (gps_service->addGpsConfiguration(tt::hal::gps::GpsConfiguration {.uartName = "Grove", .baudRate = 38400, .model = tt::hal::gps::GpsModel::UBLOX10})) {
|
||||
if (gps_service->addGpsConfiguration(tt::hal::gps::GpsConfiguration {.uartName = "uart1", .baudRate = 38400, .model = tt::hal::gps::GpsModel::UBLOX10})) {
|
||||
LOGGER.info("Configured internal GPS");
|
||||
} else {
|
||||
LOGGER.error("Failed to configure internal GPS");
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
// Reference: https://wiki.lilygo.cc/get_started/en/Wearable/T-Deck-Plus/T-Deck-Plus.html#Pin-Overview
|
||||
/ {
|
||||
@ -40,4 +41,13 @@
|
||||
pin-data-in = <GPIO_PIN_NONE>;
|
||||
pin-mclk = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/Power.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "devices/Display.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <PwmBacklight.h>
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/Sdcard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -44,30 +45,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
},
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "STEMMA QT",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.config = {
|
||||
.baud_rate = 38400,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
stemma_qt: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "devices/TpagerEncoder.h"
|
||||
#include "devices/TpagerKeyboard.h"
|
||||
#include "devices/TpagerPower.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -60,28 +61,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.initMode = spi::InitMode::ByTactility,
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}},
|
||||
.uart {uart::Configuration {
|
||||
.name = "Internal",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_4,
|
||||
.txPin = GPIO_NUM_12,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.config = {
|
||||
.baud_rate = 38400,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}}
|
||||
};
|
||||
|
||||
@ -41,7 +41,7 @@ bool tpagerInit() {
|
||||
gps_service->getGpsConfigurations(gps_configurations);
|
||||
if (gps_configurations.empty()) {
|
||||
if (gps_service->addGpsConfiguration(tt::hal::gps::GpsConfiguration {
|
||||
.uartName = "Internal",
|
||||
.uartName = "uart0",
|
||||
.baudRate = 38400,
|
||||
.model = tt::hal::gps::GpsModel::UBLOX10
|
||||
})) {
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
// Reference: https://wiki.lilygo.cc/get_started/en/LoRa_GPS/T-LoraPager/T-LoraPager.html#Pin-Overview
|
||||
/ {
|
||||
@ -34,4 +35,22 @@
|
||||
pin-data-in = <17>;
|
||||
pin-mclk = <10>;
|
||||
};
|
||||
|
||||
uart_internal: uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <12>;
|
||||
pin-rx = <4>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart_external: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "devices/SdCard.h"
|
||||
#include "devices/CardputerKeyboard.h"
|
||||
#include "devices/CardputerPower.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -79,31 +80,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
},
|
||||
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Port A",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_2,
|
||||
.txPin = GPIO_NUM_1,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
// Reference: https://docs.m5stack.com/en/core/Cardputer-Adv
|
||||
/ {
|
||||
@ -45,4 +46,13 @@
|
||||
pin-data-in = <46>;
|
||||
pin-mclk = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart_port_a: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <1>;
|
||||
pin-rx = <2>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "devices/CardputerEncoder.h"
|
||||
#include "devices/CardputerKeyboard.h"
|
||||
#include "devices/CardputerPower.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <PwmBacklight.h>
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
@ -10,7 +11,7 @@
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
bool initBoot() {
|
||||
static bool initBoot() {
|
||||
return driver::pwmbacklight::init(LCD_PIN_BACKLIGHT, 512);
|
||||
}
|
||||
|
||||
@ -78,30 +79,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.lock = nullptr
|
||||
},
|
||||
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Port A",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_2,
|
||||
.txPin = GPIO_NUM_1,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
// Reference: https://docs.m5stack.com/en/core/Cardputer
|
||||
/ {
|
||||
@ -36,4 +37,13 @@
|
||||
pin-data-in = <46>;
|
||||
pin-mclk = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart_port_a: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <1>;
|
||||
pin-rx = <2>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include "devices/Power.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -46,30 +47,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Port A", // Grove
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_32,
|
||||
.txPin = GPIO_NUM_33,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
// Reference: https://docs.m5stack.com/en/core/Core2
|
||||
/ {
|
||||
@ -46,4 +47,13 @@
|
||||
pin-data-in = <34>;
|
||||
pin-mclk = <GPIO_PIN_NONE>;
|
||||
};
|
||||
|
||||
uart_port_a: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <33>;
|
||||
pin-rx = <32>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
#include "InitBoot.h"
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Axp2101Power.h>
|
||||
|
||||
@ -46,76 +46,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Port A",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_2,
|
||||
.txPin = GPIO_NUM_1,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
uart::Configuration {
|
||||
.name = "Port B",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_9,
|
||||
.txPin = GPIO_NUM_8,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
uart::Configuration {
|
||||
.name = "Port C",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_18,
|
||||
.txPin = GPIO_NUM_17,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
// Reference: https://docs.m5stack.com/en/core/CoreS3
|
||||
/ {
|
||||
@ -68,4 +69,13 @@
|
||||
pin-data-in = <14>;
|
||||
pin-mclk = <0>;
|
||||
};
|
||||
|
||||
uart_port_a: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <1>;
|
||||
pin-rx = <2>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/Power.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -52,30 +53,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Grove",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_32,
|
||||
.txPin = GPIO_NUM_33,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -32,4 +33,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart_grove: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <33>;
|
||||
pin-rx = <32>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "devices/Display.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -54,30 +55,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
uart::Configuration {
|
||||
.name = "Grove",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_32,
|
||||
.txPin = GPIO_NUM_33,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -31,4 +32,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart_grove: uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <33>;
|
||||
pin-rx = <32>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/hal/i2c/I2c.h>
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
|
||||
@ -21,15 +21,5 @@ static std::vector<std::shared_ptr<tt::hal::Device>> createDevices() {
|
||||
|
||||
extern const Configuration hardwareConfiguration = {
|
||||
.initBoot = nullptr,
|
||||
.createDevices = createDevices,
|
||||
.uart = {
|
||||
uart::Configuration {
|
||||
.name = "/dev/ttyUSB0",
|
||||
.baudRate = 115200
|
||||
},
|
||||
uart::Configuration {
|
||||
.name = "/dev/ttyACM0",
|
||||
.baudRate = 115200
|
||||
}
|
||||
}
|
||||
.createDevices = createDevices
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "UnPhoneFeatures.h"
|
||||
#include "devices/Hx8357Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -49,31 +50,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
//UART Header
|
||||
uart::Configuration {
|
||||
.name = "UART0",
|
||||
.port = UART_NUM_0,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart0 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_0>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/Sdcard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
@ -68,6 +69,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
|
||||
@ -39,31 +40,5 @@ extern const Configuration hardwareConfiguration = {
|
||||
.isMutable = false,
|
||||
.lock = nullptr
|
||||
}
|
||||
},
|
||||
.uart {
|
||||
// "UART1"
|
||||
uart::Configuration {
|
||||
.name = "UART1",
|
||||
.port = UART_NUM_1,
|
||||
.rxPin = GPIO_NUM_44,
|
||||
.txPin = GPIO_NUM_43,
|
||||
.rtsPin = GPIO_NUM_NC,
|
||||
.ctsPin = GPIO_NUM_NC,
|
||||
.rxBufferSize = 1024,
|
||||
.txBufferSize = 1024,
|
||||
.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_DISABLE,
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <tactility/bindings/root.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
|
||||
/ {
|
||||
compatible = "root";
|
||||
@ -22,4 +23,13 @@
|
||||
pin-sda-pullup;
|
||||
pin-scl-pullup;
|
||||
};
|
||||
|
||||
uart1 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
port = <UART_NUM_1>;
|
||||
pin-tx = <43>;
|
||||
pin-rx = <44>;
|
||||
pin-cts = <GPIO_PIN_NONE>;
|
||||
pin-rts = <GPIO_PIN_NONE>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "devices/Display.h"
|
||||
#include "devices/SdCard.h"
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
@ -110,7 +110,9 @@ static error_t stop(Device* device) {
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern const struct DeviceType HAL_DEVICE_TYPE {0};
|
||||
const struct DeviceType HAL_DEVICE_TYPE {
|
||||
"hal-device"
|
||||
};
|
||||
|
||||
extern struct Module hal_device_module;
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ bool lvgl_lock(void) {
|
||||
|
||||
bool lvgl_try_lock_timed(uint32_t timeout) {
|
||||
if (!lvgl_mutex_initialised) return false;
|
||||
return recursive_mutex_try_lock_timed(&lvgl_mutex, millis_to_ticks(timeout));
|
||||
return recursive_mutex_try_lock(&lvgl_mutex, millis_to_ticks(timeout));
|
||||
}
|
||||
|
||||
void lvgl_unlock(void) {
|
||||
|
||||
27
Platforms/PlatformEsp32/Bindings/espressif,esp32-uart.yaml
Normal file
27
Platforms/PlatformEsp32/Bindings/espressif,esp32-uart.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
description: ESP32 UART Controller
|
||||
|
||||
include: ["uart-controller.yaml"]
|
||||
|
||||
compatible: "espressif,esp32-uart"
|
||||
|
||||
properties:
|
||||
port:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
The port number, defined by uart_port_t.
|
||||
Depending on the hardware, these values are available: UART_NUM_0, UART_NUM_1, UART_NUM_2
|
||||
pin-tx:
|
||||
type: int
|
||||
required: true
|
||||
description: TX pin
|
||||
pin-rx:
|
||||
type: int
|
||||
required: true
|
||||
description: RX pin
|
||||
pin-cts:
|
||||
type: int
|
||||
description: CTS pin
|
||||
pin-rts:
|
||||
type: int
|
||||
description: RTS pin
|
||||
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tactility/bindings/bindings.h>
|
||||
#include <tactility/drivers/esp32_uart.h>
|
||||
#include <driver/uart.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICETREE(esp32_uart, struct Esp32UartConfig)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -17,7 +17,6 @@ struct Esp32I2cConfig {
|
||||
bool pinSclPullUp;
|
||||
};
|
||||
|
||||
error_t esp32_i2c_get_port(struct Device* device, i2c_port_t* port);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <driver/spi_common.h>
|
||||
#include <tactility/drivers/spi_controller.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Esp32SpiConfig {
|
||||
spi_host_device_t host;
|
||||
int pin_mosi;
|
||||
int pin_miso;
|
||||
int pin_sclk;
|
||||
int pin_wp;
|
||||
int pin_hd;
|
||||
int max_transfer_size;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <driver/uart.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Esp32UartConfig {
|
||||
uart_port_t port;
|
||||
int pinTx;
|
||||
int pinRx;
|
||||
int pinCts;
|
||||
int pinRts;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -12,20 +12,20 @@
|
||||
#define TAG "esp32_i2c"
|
||||
#define ACK_CHECK_EN 1
|
||||
|
||||
struct InternalData {
|
||||
struct Esp32SpiInternal {
|
||||
Mutex mutex { 0 };
|
||||
|
||||
InternalData() {
|
||||
Esp32SpiInternal() {
|
||||
mutex_construct(&mutex);
|
||||
}
|
||||
|
||||
~InternalData() {
|
||||
~Esp32SpiInternal() {
|
||||
mutex_destruct(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
#define GET_CONFIG(device) ((Esp32I2cConfig*)device->config)
|
||||
#define GET_DATA(device) ((InternalData*)device_get_driver_data(device))
|
||||
#define GET_DATA(device) ((Esp32SpiInternal*)device_get_driver_data(device))
|
||||
|
||||
#define lock(data) mutex_lock(&data->mutex);
|
||||
#define unlock(data) mutex_unlock(&data->mutex);
|
||||
@ -144,11 +144,6 @@ on_error:
|
||||
return esp_err_to_error(error);
|
||||
}
|
||||
|
||||
error_t esp32_i2c_get_port(struct Device* device, i2c_port_t* port) {
|
||||
auto* config = GET_CONFIG(device);
|
||||
*port = config->port;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t start(Device* device) {
|
||||
ESP_LOGI(TAG, "start %s", device->name);
|
||||
@ -177,14 +172,14 @@ static error_t start(Device* device) {
|
||||
LOG_E(TAG, "Failed to install driver at port %d: %s", static_cast<int>(dts_config->port), esp_err_to_name(error));
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
auto* data = new InternalData();
|
||||
auto* data = new Esp32SpiInternal();
|
||||
device_set_driver_data(device, data);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t stop(Device* device) {
|
||||
ESP_LOGI(TAG, "stop %s", device->name);
|
||||
auto* driver_data = static_cast<InternalData*>(device_get_driver_data(device));
|
||||
auto* driver_data = static_cast<Esp32SpiInternal*>(device_get_driver_data(device));
|
||||
|
||||
i2c_port_t port = GET_CONFIG(device)->port;
|
||||
esp_err_t result = i2c_driver_delete(port);
|
||||
|
||||
@ -14,31 +14,31 @@
|
||||
|
||||
#define TAG "esp32_i2s"
|
||||
|
||||
struct InternalData {
|
||||
Mutex mutex { 0 };
|
||||
struct Esp32I2sInternal {
|
||||
Mutex mutex {};
|
||||
i2s_chan_handle_t tx_handle = nullptr;
|
||||
i2s_chan_handle_t rx_handle = nullptr;
|
||||
I2sConfig config {};
|
||||
bool config_set = false;
|
||||
|
||||
InternalData() {
|
||||
Esp32I2sInternal() {
|
||||
mutex_construct(&mutex);
|
||||
}
|
||||
|
||||
~InternalData() {
|
||||
~Esp32I2sInternal() {
|
||||
mutex_destruct(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
#define GET_CONFIG(device) ((Esp32I2sConfig*)device->config)
|
||||
#define GET_DATA(device) ((InternalData*)device_get_driver_data(device))
|
||||
#define GET_DATA(device) ((Esp32I2sInternal*)device_get_driver_data(device))
|
||||
|
||||
#define lock(data) mutex_lock(&data->mutex);
|
||||
#define unlock(data) mutex_unlock(&data->mutex);
|
||||
|
||||
extern "C" {
|
||||
|
||||
static error_t cleanup_channel_handles(InternalData* driver_data) {
|
||||
static error_t cleanup_channel_handles(Esp32I2sInternal* driver_data) {
|
||||
// TODO: error handling of i2ss functions
|
||||
if (driver_data->tx_handle) {
|
||||
i2s_channel_disable(driver_data->tx_handle);
|
||||
@ -188,7 +188,7 @@ static error_t get_config(Device* device, struct I2sConfig* config) {
|
||||
|
||||
static error_t start(Device* device) {
|
||||
ESP_LOGI(TAG, "start %s", device->name);
|
||||
auto* data = new(std::nothrow) InternalData();
|
||||
auto* data = new(std::nothrow) Esp32I2sInternal();
|
||||
if (!data) return ERROR_OUT_OF_MEMORY;
|
||||
|
||||
device_set_driver_data(device, data);
|
||||
|
||||
122
Platforms/PlatformEsp32/Source/drivers/esp32_spi.cpp
Normal file
122
Platforms/PlatformEsp32/Source/drivers/esp32_spi.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/esp32_spi.h>
|
||||
#include <tactility/concurrent/mutex.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <esp_log.h>
|
||||
#include <new>
|
||||
#include <soc/gpio_num.h>
|
||||
|
||||
#define TAG "esp32_spi"
|
||||
|
||||
#define GET_CONFIG(device) ((const struct Esp32SpiConfig*)device->config)
|
||||
#define GET_DATA(device) ((struct Esp32SpiInternal*)device_get_driver_data(device))
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct Esp32SpiInternal {
|
||||
Mutex mutex;
|
||||
bool initialized = false;
|
||||
|
||||
Esp32SpiInternal() {
|
||||
mutex_construct(&mutex);
|
||||
}
|
||||
|
||||
~Esp32SpiInternal() {
|
||||
mutex_destruct(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
static error_t lock(Device* device) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
mutex_lock(&driver_data->mutex);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t try_lock(Device* device, TickType_t timeout) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
if (mutex_try_lock(&driver_data->mutex, timeout)) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
return ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
static error_t unlock(Device* device) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
mutex_unlock(&driver_data->mutex);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t start(Device* device) {
|
||||
ESP_LOGI(TAG, "start %s", device->name);
|
||||
auto* data = new(std::nothrow) Esp32SpiInternal();
|
||||
if (!data) return ERROR_OUT_OF_MEMORY;
|
||||
|
||||
device_set_driver_data(device, data);
|
||||
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
spi_bus_config_t buscfg = {
|
||||
.mosi_io_num = dts_config->pin_mosi,
|
||||
.miso_io_num = dts_config->pin_miso,
|
||||
.sclk_io_num = dts_config->pin_sclk,
|
||||
.data2_io_num = dts_config->pin_wp,
|
||||
.data3_io_num = dts_config->pin_hd,
|
||||
.data4_io_num = GPIO_NUM_NC,
|
||||
.data5_io_num = GPIO_NUM_NC,
|
||||
.data6_io_num = GPIO_NUM_NC,
|
||||
.data7_io_num = GPIO_NUM_NC,
|
||||
.data_io_default_level = false,
|
||||
.max_transfer_sz = dts_config->max_transfer_size,
|
||||
.flags = 0,
|
||||
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||
.intr_flags = 0
|
||||
};
|
||||
|
||||
esp_err_t ret = spi_bus_initialize(dts_config->host, &buscfg, SPI_DMA_CH_AUTO);
|
||||
if (ret != ESP_OK) {
|
||||
delete data;
|
||||
device_set_driver_data(device, nullptr);
|
||||
ESP_LOGE(TAG, "Failed to initialize SPI bus: %s", esp_err_to_name(ret));
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
data->initialized = true;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t stop(Device* device) {
|
||||
ESP_LOGI(TAG, "stop %s", device->name);
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
if (driver_data->initialized) {
|
||||
spi_bus_free(dts_config->host);
|
||||
}
|
||||
|
||||
device_set_driver_data(device, nullptr);
|
||||
delete driver_data;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
const static struct SpiControllerApi esp32_spi_api = {
|
||||
.lock = lock,
|
||||
.try_lock = try_lock,
|
||||
.unlock = unlock
|
||||
};
|
||||
|
||||
extern struct Module platform_module;
|
||||
|
||||
Driver esp32_spi_driver = {
|
||||
.name = "esp32_spi",
|
||||
.compatible = (const char*[]) { "espressif,esp32-spi", nullptr },
|
||||
.start_device = start,
|
||||
.stop_device = stop,
|
||||
.api = (void*)&esp32_spi_api,
|
||||
.device_type = &SPI_CONTROLLER_TYPE,
|
||||
.owner = &platform_module,
|
||||
.internal = nullptr
|
||||
};
|
||||
|
||||
} // extern "C"
|
||||
379
Platforms/PlatformEsp32/Source/drivers/esp32_uart.cpp
Normal file
379
Platforms/PlatformEsp32/Source/drivers/esp32_uart.cpp
Normal file
@ -0,0 +1,379 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <driver/uart.h>
|
||||
|
||||
#include <tactility/concurrent/mutex.h>
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
#include <tactility/drivers/esp32_uart.h>
|
||||
#include <tactility/error_esp32.h>
|
||||
#include <tactility/log.h>
|
||||
#include <tactility/time.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#define TAG "esp32_uart"
|
||||
|
||||
struct Esp32UartInternal {
|
||||
Mutex mutex {};
|
||||
UartConfig config {};
|
||||
bool config_set = false;
|
||||
bool is_open = false;
|
||||
|
||||
Esp32UartInternal() {
|
||||
mutex_construct(&mutex);
|
||||
}
|
||||
|
||||
~Esp32UartInternal() {
|
||||
mutex_destruct(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
#define GET_CONFIG(device) ((Esp32UartConfig*)device->config)
|
||||
#define GET_DATA(device) ((Esp32UartInternal*)device_get_driver_data(device))
|
||||
|
||||
#define lock(data) mutex_lock(&data->mutex)
|
||||
#define unlock(data) mutex_unlock(&data->mutex)
|
||||
|
||||
extern "C" {
|
||||
|
||||
static uart_parity_t to_esp32_parity(enum UartParity parity) {
|
||||
switch (parity) {
|
||||
case UART_CONTROLLER_PARITY_DISABLE: return UART_PARITY_DISABLE;
|
||||
case UART_CONTROLLER_PARITY_EVEN: return UART_PARITY_EVEN;
|
||||
case UART_CONTROLLER_PARITY_ODD: return UART_PARITY_ODD;
|
||||
default: return UART_PARITY_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
static uart_word_length_t to_esp32_data_bits(enum UartDataBits bits) {
|
||||
switch (bits) {
|
||||
case UART_CONTROLLER_DATA_5_BITS: return UART_DATA_5_BITS;
|
||||
case UART_CONTROLLER_DATA_6_BITS: return UART_DATA_6_BITS;
|
||||
case UART_CONTROLLER_DATA_7_BITS: return UART_DATA_7_BITS;
|
||||
case UART_CONTROLLER_DATA_8_BITS: return UART_DATA_8_BITS;
|
||||
default: return UART_DATA_8_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
static uart_stop_bits_t to_esp32_stop_bits(enum UartStopBits bits) {
|
||||
switch (bits) {
|
||||
case UART_CONTROLLER_STOP_BITS_1: return UART_STOP_BITS_1;
|
||||
case UART_CONTROLLER_STOP_BITS_1_5: return UART_STOP_BITS_1_5;
|
||||
case UART_CONTROLLER_STOP_BITS_2: return UART_STOP_BITS_2;
|
||||
default: return UART_STOP_BITS_1;
|
||||
}
|
||||
}
|
||||
|
||||
static error_t read_byte(Device* device, uint8_t* out, TickType_t timeout) {
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
int len = uart_read_bytes(dts_config->port, out, 1, timeout);
|
||||
unlock(driver_data);
|
||||
|
||||
if (len < 0) return ERROR_RESOURCE;
|
||||
if (len == 0) return ERROR_TIMEOUT;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t write_byte(Device* device, uint8_t out, TickType_t timeout) {
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
int len = uart_write_bytes(dts_config->port, (const char*)&out, 1);
|
||||
if (len < 0) {
|
||||
unlock(driver_data);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
// uart_write_bytes is non-blocking on the buffer but we might want to wait for it to be sent?
|
||||
// The API signature has timeout, but ESP-IDF's uart_write_bytes doesn't use it for blocking.
|
||||
// However, if we want to ensure it's SENT, we could use uart_wait_tx_done.
|
||||
if (timeout > 0) {
|
||||
esp_err_t err = uart_wait_tx_done(dts_config->port, timeout);
|
||||
unlock(driver_data);
|
||||
if (err == ESP_ERR_TIMEOUT) return ERROR_TIMEOUT;
|
||||
if (err != ESP_OK) return ERROR_RESOURCE;
|
||||
} else {
|
||||
unlock(driver_data);
|
||||
}
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t write_bytes(Device* device, const uint8_t* buffer, size_t buffer_size, TickType_t timeout) {
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
int len = uart_write_bytes(dts_config->port, (const char*)buffer, buffer_size);
|
||||
if (len < 0) {
|
||||
unlock(driver_data);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
if (timeout > 0) {
|
||||
esp_err_t err = uart_wait_tx_done(dts_config->port, timeout);
|
||||
unlock(driver_data);
|
||||
if (err == ESP_ERR_TIMEOUT) return ERROR_TIMEOUT;
|
||||
if (err != ESP_OK) return ERROR_RESOURCE;
|
||||
} else {
|
||||
unlock(driver_data);
|
||||
}
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t read_bytes(Device* device, uint8_t* buffer, size_t buffer_size, TickType_t timeout) {
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
int len = uart_read_bytes(dts_config->port, buffer, buffer_size, timeout);
|
||||
unlock(driver_data);
|
||||
|
||||
if (len < 0) return ERROR_RESOURCE;
|
||||
if (len < (int)buffer_size) return ERROR_TIMEOUT;
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t get_available(Device* device, size_t* available_bytes) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t err = uart_get_buffered_data_len(dts_config->port, available_bytes);
|
||||
unlock(driver_data);
|
||||
|
||||
if (err != ESP_OK) return esp_err_to_error(err);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t set_config(Device* device, const struct UartConfig* config) {
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
|
||||
auto* driver_data = GET_DATA(device);
|
||||
lock(driver_data);
|
||||
|
||||
if (driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
memcpy(&driver_data->config, config, sizeof(UartConfig));
|
||||
driver_data->config_set = true;
|
||||
|
||||
unlock(driver_data);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t get_config(Device* device, struct UartConfig* config) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->config_set) {
|
||||
unlock(driver_data);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
memcpy(config, &driver_data->config, sizeof(UartConfig));
|
||||
unlock(driver_data);
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t open(Device* device) {
|
||||
ESP_LOGI(TAG, "%s open", device->name);
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
LOG_W(TAG, "%s is already open", device->name);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!driver_data->config_set) {
|
||||
unlock(driver_data);
|
||||
LOG_E(TAG, "%s open failed: config not set", device->name);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t esp_error = uart_driver_install(dts_config->port, 1024, 0, 0, NULL, 0);
|
||||
if (esp_error != ESP_OK) {
|
||||
LOG_E(TAG, "%s failed to install: %s", device->name, esp_err_to_name(esp_error));
|
||||
unlock(driver_data);
|
||||
return esp_err_to_error(esp_error);
|
||||
}
|
||||
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = (int)driver_data->config.baud_rate,
|
||||
.data_bits = to_esp32_data_bits(driver_data->config.data_bits),
|
||||
.parity = to_esp32_parity(driver_data->config.parity),
|
||||
.stop_bits = to_esp32_stop_bits(driver_data->config.stop_bits),
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, // Flow control is not yet exposed via UartConfig
|
||||
.rx_flow_ctrl_thresh = 0,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.flags = {
|
||||
.allow_pd = 0,
|
||||
.backup_before_sleep = 0
|
||||
}
|
||||
};
|
||||
|
||||
if (dts_config->pinCts != UART_PIN_NO_CHANGE || dts_config->pinRts != UART_PIN_NO_CHANGE) {
|
||||
LOG_W(TAG, "%s: CTS/RTS pins are defined but hardware flow control is disabled (not supported in UartConfig)", device->name);
|
||||
}
|
||||
|
||||
esp_error = uart_param_config(dts_config->port, &uart_config);
|
||||
if (esp_error != ESP_OK) {
|
||||
LOG_E(TAG, "%s failed to configure: %s", device->name, esp_err_to_name(esp_error));
|
||||
uart_driver_delete(dts_config->port);
|
||||
unlock(driver_data);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
esp_error = uart_set_pin(dts_config->port, dts_config->pinTx, dts_config->pinRx, dts_config->pinCts, dts_config->pinRts);
|
||||
if (esp_error != ESP_OK) {
|
||||
LOG_E(TAG, "%s failed to set uart pins: %s", device->name, esp_err_to_name(esp_error));
|
||||
uart_driver_delete(dts_config->port);
|
||||
unlock(driver_data);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
driver_data->is_open = true;
|
||||
|
||||
unlock(driver_data);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t close(Device* device) {
|
||||
ESP_LOGI(TAG, "%s close", device->name);
|
||||
if (xPortInIsrContext()) return ERROR_ISR_STATUS;
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
LOG_W(TAG, "Already closed");
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
uart_driver_delete(dts_config->port);
|
||||
driver_data->is_open = false;
|
||||
unlock(driver_data);
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static bool is_open(Device* device) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
lock(driver_data);
|
||||
bool status = driver_data->is_open;
|
||||
unlock(driver_data);
|
||||
return status;
|
||||
}
|
||||
|
||||
static error_t flush_input(Device* device) {
|
||||
auto* driver_data = GET_DATA(device);
|
||||
auto* dts_config = GET_CONFIG(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (!driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t err = uart_flush_input(dts_config->port);
|
||||
unlock(driver_data);
|
||||
|
||||
return esp_err_to_error(err);
|
||||
}
|
||||
|
||||
static error_t start(Device* device) {
|
||||
ESP_LOGI(TAG, "%s start", device->name);
|
||||
auto* data = new(std::nothrow) Esp32UartInternal();
|
||||
if (!data) return ERROR_OUT_OF_MEMORY;
|
||||
|
||||
device_set_driver_data(device, data);
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t stop(Device* device) {
|
||||
ESP_LOGI(TAG, "%s stop", device->name);
|
||||
auto* driver_data = GET_DATA(device);
|
||||
|
||||
lock(driver_data);
|
||||
if (driver_data->is_open) {
|
||||
unlock(driver_data);
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
unlock(driver_data);
|
||||
device_set_driver_data(device, nullptr);
|
||||
delete driver_data;
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
const static UartControllerApi esp32_uart_api = {
|
||||
.read_byte = read_byte,
|
||||
.write_byte = write_byte,
|
||||
.write_bytes = write_bytes,
|
||||
.read_bytes = read_bytes,
|
||||
.get_available = get_available,
|
||||
.set_config = set_config,
|
||||
.get_config = get_config,
|
||||
.open = open,
|
||||
.close = close,
|
||||
.is_open = is_open,
|
||||
.flush_input = flush_input
|
||||
};
|
||||
|
||||
extern struct Module platform_module;
|
||||
|
||||
Driver esp32_uart_driver = {
|
||||
.name = "esp32_uart",
|
||||
.compatible = (const char*[]) { "espressif,esp32-uart", nullptr },
|
||||
.start_device = start,
|
||||
.stop_device = stop,
|
||||
.api = (void*)&esp32_uart_api,
|
||||
.device_type = &UART_CONTROLLER_TYPE,
|
||||
.owner = &platform_module,
|
||||
.internal = nullptr
|
||||
};
|
||||
|
||||
} // extern "C"
|
||||
@ -7,6 +7,8 @@ extern "C" {
|
||||
extern Driver esp32_gpio_driver;
|
||||
extern Driver esp32_i2c_driver;
|
||||
extern Driver esp32_i2s_driver;
|
||||
extern Driver esp32_spi_driver;
|
||||
extern Driver esp32_uart_driver;
|
||||
|
||||
static error_t start() {
|
||||
/* We crash when construct fails, because if a single driver fails to construct,
|
||||
@ -14,6 +16,8 @@ static error_t start() {
|
||||
check(driver_construct_add(&esp32_gpio_driver) == ERROR_NONE);
|
||||
check(driver_construct_add(&esp32_i2c_driver) == ERROR_NONE);
|
||||
check(driver_construct_add(&esp32_i2s_driver) == ERROR_NONE);
|
||||
check(driver_construct_add(&esp32_spi_driver) == ERROR_NONE);
|
||||
check(driver_construct_add(&esp32_uart_driver) == ERROR_NONE);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -23,6 +27,8 @@ static error_t stop() {
|
||||
check(driver_remove_destruct(&esp32_gpio_driver) == ERROR_NONE);
|
||||
check(driver_remove_destruct(&esp32_i2c_driver) == ERROR_NONE);
|
||||
check(driver_remove_destruct(&esp32_i2s_driver) == ERROR_NONE);
|
||||
check(driver_remove_destruct(&esp32_spi_driver) == ERROR_NONE);
|
||||
check(driver_remove_destruct(&esp32_uart_driver) == ERROR_NONE);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
|
||||
#include <Tactility/hal/sdcard/SdCardDevice.h>
|
||||
#include <Tactility/hal/spi/Spi.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include "i2c/I2c.h"
|
||||
|
||||
namespace tt::hal {
|
||||
|
||||
@ -43,9 +41,6 @@ struct Configuration {
|
||||
|
||||
/** A list of SPI interface configurations */
|
||||
const std::vector<spi::Configuration> spi = {};
|
||||
|
||||
/** A list of UART interface configurations */
|
||||
const std::vector<uart::Configuration> uart = {};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "UartCompat.h"
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
struct Configuration {
|
||||
/** The unique name for this UART */
|
||||
std::string name;
|
||||
/** The port identifier (e.g. UART_NUM_0) */
|
||||
uart_port_t port;
|
||||
/** Receive GPIO pin */
|
||||
gpio_num_t rxPin;
|
||||
/** Transmit GPIO pin */
|
||||
gpio_num_t txPin;
|
||||
/** Read-To-Send GPIO pin */
|
||||
gpio_num_t rtsPin;
|
||||
/** Clear-To-Send Send GPIO pin */
|
||||
gpio_num_t ctsPin;
|
||||
/** Receive buffer size in bytes */
|
||||
unsigned int rxBufferSize;
|
||||
/** Transmit buffer size in bytes */
|
||||
unsigned int txBufferSize;
|
||||
/** Native configuration */
|
||||
uart_config_t config;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct Configuration {
|
||||
/** The unique name for this UART */
|
||||
std::string name;
|
||||
/** The port identifier (e.g. UART_NUM_0) */
|
||||
uart_port_t port;
|
||||
/** Initial baud rate in bits per second */
|
||||
uint32_t baudRate;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -1,131 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/freertoscompat/RTOS.h>
|
||||
|
||||
#include "../gpio/Gpio.h"
|
||||
#include "Tactility/Lock.h"
|
||||
#include "UartCompat.h"
|
||||
#include "Tactility/hal/uart/Configuration.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
constexpr TickType_t defaultTimeout = 10 / portTICK_PERIOD_MS;
|
||||
|
||||
enum class InitMode {
|
||||
ByTactility, // Tactility will initialize it in the correct bootup phase
|
||||
ByExternal, // The device is already initialized and Tactility should assume it works
|
||||
Disabled // Not initialized by default
|
||||
};
|
||||
|
||||
enum class Status {
|
||||
Started,
|
||||
Stopped,
|
||||
Unknown
|
||||
};
|
||||
|
||||
class Uart {
|
||||
|
||||
uint32_t id;
|
||||
|
||||
public:
|
||||
|
||||
Uart();
|
||||
virtual ~Uart();
|
||||
|
||||
uint32_t getId() const { return id; }
|
||||
|
||||
virtual bool start() = 0;
|
||||
virtual bool isStarted() const = 0;
|
||||
|
||||
virtual bool stop() = 0;
|
||||
|
||||
/**
|
||||
* Read up to a specified amount of bytes
|
||||
* @param[out] buffer
|
||||
* @param[in] bufferSize
|
||||
* @param[in] timeout
|
||||
* @return the amount of bytes that were read
|
||||
*/
|
||||
virtual size_t readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) = 0;
|
||||
|
||||
size_t readBytes(std::uint8_t* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) {
|
||||
return readBytes(reinterpret_cast<std::byte*>(buffer), bufferSize, timeout);
|
||||
}
|
||||
|
||||
/** Read a single byte */
|
||||
virtual bool readByte(std::byte* output, TickType_t timeout = defaultTimeout) = 0;
|
||||
|
||||
bool readByte(char* output, TickType_t timeout = defaultTimeout) {
|
||||
return readByte(reinterpret_cast<std::byte*>(output), timeout);
|
||||
}
|
||||
|
||||
bool readByte(uint8_t* output, TickType_t timeout = defaultTimeout) {
|
||||
return readByte(reinterpret_cast<std::byte*>(output), timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read up to a specified amount of bytes
|
||||
* @param[in] buffer
|
||||
* @param[in] bufferSize
|
||||
* @param[in] timeout
|
||||
* @return the amount of bytes that were read
|
||||
*/
|
||||
virtual size_t writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) = 0;
|
||||
|
||||
size_t writeBytes(const std::uint8_t* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) {
|
||||
return writeBytes(reinterpret_cast<const std::byte*>(buffer), bufferSize, timeout);
|
||||
}
|
||||
|
||||
/** @return the amount of bytes available for reading */
|
||||
virtual size_t available(TickType_t timeout = defaultTimeout) = 0;
|
||||
|
||||
/** Set the baud rate for the specified port */
|
||||
virtual bool setBaudRate(uint32_t baudRate, TickType_t timeout = defaultTimeout) = 0;
|
||||
|
||||
/** Get the baud rate for the specified port */
|
||||
virtual uint32_t getBaudRate() = 0;
|
||||
|
||||
/** Flush input buffers */
|
||||
virtual void flushInput() = 0;
|
||||
|
||||
/**
|
||||
* Write a string (excluding null terminator character)
|
||||
* @param[in] buffer
|
||||
* @param[in] timeout
|
||||
* @return the amount of bytes that were written
|
||||
*/
|
||||
bool writeString(const char* buffer, TickType_t timeout = defaultTimeout);
|
||||
|
||||
/**
|
||||
* Read a buffer as a string until the specified character (the "untilChar" is included in the result)
|
||||
* @warning if the input data doesn't return "untilByte" then the device goes out of memory
|
||||
*/
|
||||
std::string readStringUntil(char untilChar, TickType_t timeout = defaultTimeout);
|
||||
|
||||
/**
|
||||
* Read a buffer as a byte array until the specified character (the "untilChar" is included in the result)
|
||||
* @return the amount of bytes read from UART
|
||||
*/
|
||||
size_t readUntil(std::byte* buffer, size_t bufferSize, uint8_t untilByte, TickType_t timeout = defaultTimeout, bool addNullTerminator = true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens a UART.
|
||||
* @param[in] name the UART name as specified in the board configuration.
|
||||
* @return the UART when it was successfully opened, or nullptr when it is in use.
|
||||
*/
|
||||
std::unique_ptr<Uart> open(std::string name);
|
||||
|
||||
/**
|
||||
* Opens a UART.
|
||||
* @param[in] port the UART port as specified in the board configuration.
|
||||
* @return the UART when it was successfully opened, or nullptr when it is in use.
|
||||
*/
|
||||
std::unique_ptr<Uart> open(uart_port_t port);
|
||||
|
||||
std::vector<std::string> getNames();
|
||||
|
||||
} // namespace tt::hal::uart
|
||||
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <driver/uart.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <hal/uart_types.h>
|
||||
|
||||
#else
|
||||
|
||||
#define UART_NUM_MAX 3
|
||||
typedef int uart_port_t;
|
||||
|
||||
typedef struct {
|
||||
} uart_config_t;
|
||||
|
||||
#endif
|
||||
@ -2,13 +2,13 @@
|
||||
|
||||
#include "Tactility/hal/gps/GpsDevice.h"
|
||||
|
||||
namespace tt::hal::uart { class Uart; }
|
||||
struct Device;
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
/**
|
||||
* Init sequence on UART for a specific GPS model.
|
||||
*/
|
||||
bool init(uart::Uart& uart, GpsModel type);
|
||||
bool init(::Device* uart, GpsModel type);
|
||||
|
||||
}
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/gps/GpsDevice.h"
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
struct Device;
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
GpsModel probe(uart::Uart& iart);
|
||||
GpsModel probe(::Device* uart);
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/gps/GpsDevice.h"
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
struct Device;
|
||||
|
||||
namespace tt::hal::gps::ublox {
|
||||
|
||||
void checksum(uint8_t* message, size_t length);
|
||||
@ -13,15 +14,8 @@ void checksum(uint8_t* message, size_t length);
|
||||
// From https://github.com/meshtastic/firmware/blob/7648391f91f2b84e367ae2b38220b30936fb45b1/src/gps/GPS.cpp#L128
|
||||
uint8_t makePacket(uint8_t classId, uint8_t messageId, const uint8_t* payload, uint8_t payloadSize, uint8_t* bufferOut);
|
||||
|
||||
template<size_t DataSize>
|
||||
inline void sendPacket(uart_port_t port, uint8_t type, uint8_t id, uint8_t data[DataSize], const char* errorMessage, TickType_t timeout) {
|
||||
static uint8_t buffer[250] = {0};
|
||||
size_t length = makePacket(type, id, data, DataSize, buffer);
|
||||
// hal::uart::writeBytes(port, buffer, length);
|
||||
GpsModel probe(::Device* uart);
|
||||
|
||||
bool init(::Device* uart, GpsModel model);
|
||||
|
||||
}
|
||||
|
||||
GpsModel probe(uart::Uart& uart);
|
||||
|
||||
bool init(uart::Uart& uart, GpsModel model);
|
||||
|
||||
} // namespace tt::service::gps
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/Mutex.h"
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
#include "Tactility/hal/uart/Configuration.h"
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
class UartEsp final : public Uart {
|
||||
|
||||
Mutex mutex;
|
||||
const Configuration& configuration;
|
||||
bool started = false;
|
||||
|
||||
public:
|
||||
|
||||
explicit UartEsp(const Configuration& configuration) : configuration(configuration) {}
|
||||
|
||||
bool start() override;
|
||||
bool isStarted() const override;
|
||||
bool stop() override;
|
||||
size_t readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout) override;
|
||||
bool readByte(std::byte* output, TickType_t timeout) override;
|
||||
size_t writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout) override;
|
||||
size_t available(TickType_t timeout) override;
|
||||
bool setBaudRate(uint32_t baudRate, TickType_t timeout) override;
|
||||
uint32_t getBaudRate() override;
|
||||
void flushInput() override;
|
||||
};
|
||||
|
||||
std::unique_ptr<Uart> create(const Configuration& configuration);
|
||||
|
||||
} // namespace tt::hal::uart
|
||||
|
||||
#endif
|
||||
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
bool init(const std::vector<uart::Configuration>& configurations);
|
||||
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/Mutex.h"
|
||||
#include "Tactility/hal/uart/Configuration.h"
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
class UartPosix final : public Uart {
|
||||
|
||||
private:
|
||||
struct AutoCloseFileDeleter {
|
||||
void operator()(FILE* file) {
|
||||
fclose(file);
|
||||
}
|
||||
};
|
||||
|
||||
Mutex mutex;
|
||||
const Configuration& configuration;
|
||||
std::unique_ptr<FILE, AutoCloseFileDeleter> device;
|
||||
|
||||
bool awaitAvailable(TickType_t timeout);
|
||||
|
||||
public:
|
||||
|
||||
explicit UartPosix(const Configuration& configuration) : configuration(configuration) {}
|
||||
|
||||
bool start() final;
|
||||
bool isStarted() const final;
|
||||
bool stop() final;
|
||||
size_t readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout) final;
|
||||
bool readByte(std::byte* output, TickType_t timeout) final;
|
||||
size_t writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout) final;
|
||||
size_t available(TickType_t timeout) final;
|
||||
bool setBaudRate(uint32_t baudRate, TickType_t timeout) final;
|
||||
uint32_t getBaudRate() final;
|
||||
void flushInput() final;
|
||||
};
|
||||
|
||||
std::unique_ptr<Uart> create(const Configuration& configuration);
|
||||
|
||||
} // namespace tt::hal::uart
|
||||
|
||||
#endif
|
||||
@ -26,8 +26,9 @@
|
||||
#include <Tactility/settings/TimePrivate.h>
|
||||
|
||||
#include <tactility/concurrent/thread.h>
|
||||
#include <tactility/kernel_init.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
#include <tactility/hal_device_module.h>
|
||||
#include <tactility/kernel_init.h>
|
||||
#include <tactility/lvgl_module.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
@ -180,7 +181,7 @@ static void registerInternalApps() {
|
||||
addAppManifest(app::chat::manifest);
|
||||
#endif
|
||||
|
||||
if (!hal::getConfiguration()->uart.empty()) {
|
||||
if (device_exists_of_type(&UART_CONTROLLER_TYPE)) {
|
||||
addAppManifest(app::addgps::manifest);
|
||||
addAppManifest(app::gpssettings::manifest);
|
||||
}
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
#include <Tactility/hal/gps/GpsDevice.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/lvgl/Style.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/service/gps/GpsService.h>
|
||||
|
||||
#include "tactility/drivers/uart_controller.h"
|
||||
#include <cstring>
|
||||
#include <lvgl.h>
|
||||
|
||||
@ -21,6 +21,8 @@ class AddGpsApp final : public App {
|
||||
lv_obj_t* modelDropdown = nullptr;
|
||||
lv_obj_t* baudDropdown = nullptr;
|
||||
|
||||
std::vector<::Device*> devices;
|
||||
|
||||
// Store as string instead of int, so app startup doesn't require parsing all entries.
|
||||
// We only need to parse back to int when adding the new GPS entry
|
||||
std::array<uint32_t, 6> baudRates = { 9600, 19200, 28800, 38400, 57600, 115200 };
|
||||
@ -69,6 +71,24 @@ class AddGpsApp final : public App {
|
||||
}
|
||||
}
|
||||
|
||||
void updateUartDevices() {
|
||||
devices.clear();
|
||||
device_for_each_of_type(&UART_CONTROLLER_TYPE, &devices, [](auto* device, auto* context){
|
||||
auto* vector_ptr = static_cast<std::vector<::Device*>*>(context);
|
||||
vector_ptr->push_back(device);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
std::string getUartDropdownNames() {
|
||||
std::vector<std::string> names;
|
||||
names.push_back("");
|
||||
for (auto* device: devices) {
|
||||
names.push_back(device->name);
|
||||
}
|
||||
return string::join(names, "\n");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void onShow(AppContext& app, lv_obj_t* parent) final {
|
||||
@ -95,9 +115,9 @@ public:
|
||||
|
||||
uartDropdown = lv_dropdown_create(uart_wrapper);
|
||||
|
||||
auto uart_names = hal::uart::getNames();
|
||||
uart_names.insert(uart_names.begin(), "");
|
||||
auto uart_options = string::join(uart_names, "\n");
|
||||
updateUartDevices();
|
||||
|
||||
auto uart_options = getUartDropdownNames();
|
||||
lv_dropdown_set_options(uartDropdown, uart_options.c_str());
|
||||
lv_obj_align(uartDropdown, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
lv_obj_set_width(uartDropdown, LV_PCT(50));
|
||||
|
||||
@ -292,6 +292,7 @@ class GpsSettingsApp final : public App {
|
||||
lv_obj_add_flag(statusLabelWidget, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
if (!lv_obj_has_flag(gpsConfigWrapper, LV_OBJ_FLAG_HIDDEN)) {
|
||||
lv_obj_clean(gpsConfigWrapper);
|
||||
std::vector<tt::hal::gps::GpsConfiguration> configurations;
|
||||
auto gps_service = tt::service::gps::findGpsService();
|
||||
@ -301,6 +302,9 @@ class GpsSettingsApp final : public App {
|
||||
createGpsView(configuration, index++);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lv_obj_clean(gpsConfigWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "Tactility/app/i2cscanner/I2cHelpers.h"
|
||||
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/StringUtils.h>
|
||||
#include <Tactility/hal/i2c/I2c.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
@ -3,9 +3,7 @@
|
||||
#include <tactility/check.h>
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <tactility/hal/Device.h>
|
||||
#include <Tactility/hal/power/PowerDevice.h>
|
||||
#include <Tactility/hal/spi/SpiInit.h>
|
||||
#include <Tactility/hal/uart/UartInit.h>
|
||||
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <Tactility/hal/sdcard/SdCardMounting.h>
|
||||
@ -67,7 +65,6 @@ void init(const Configuration& configuration) {
|
||||
kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalBegin);
|
||||
|
||||
check(spi::init(configuration.spi), "SPI init failed");
|
||||
check(uart::init(configuration.uart), "UART init failed");
|
||||
|
||||
if (configuration.initBoot != nullptr) {
|
||||
check(configuration.initBoot(), "Init boot failed");
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
#include <Tactility/hal/gps/GpsDevice.h>
|
||||
#include <Tactility/hal/gps/GpsInit.h>
|
||||
#include <Tactility/hal/gps/Probe.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/Logger.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <minmea.h>
|
||||
|
||||
@ -16,25 +18,34 @@ static const auto LOGGER = Logger("GpsDevice");
|
||||
int32_t GpsDevice::threadMain() {
|
||||
uint8_t buffer[GPS_UART_BUFFER_SIZE];
|
||||
|
||||
auto uart = uart::open(configuration.uartName);
|
||||
auto* uart = device_find_by_name(configuration.uartName);
|
||||
if (uart == nullptr) {
|
||||
LOGGER.error("Failed to open UART {}", configuration.uartName);
|
||||
LOGGER.error("Failed to find UART {}", configuration.uartName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!uart->start()) {
|
||||
LOGGER.error("Failed to start UART {}", configuration.uartName);
|
||||
struct UartConfig uartConfig = {
|
||||
.baud_rate = configuration.baudRate,
|
||||
.data_bits = UART_CONTROLLER_DATA_8_BITS,
|
||||
.parity = UART_CONTROLLER_PARITY_DISABLE,
|
||||
.stop_bits = UART_CONTROLLER_STOP_BITS_1
|
||||
};
|
||||
|
||||
error_t error = uart_controller_set_config(uart, &uartConfig);
|
||||
if (error != ERROR_NONE) {
|
||||
LOGGER.error("Failed to configure UART {}: {}", configuration.uartName, error_to_string(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!uart->setBaudRate(static_cast<int>(configuration.baudRate))) {
|
||||
LOGGER.error("Failed to set baud rate to {} for UART {}", configuration.baudRate, configuration.uartName);
|
||||
error = uart_controller_open(uart);
|
||||
if (error != ERROR_NONE) {
|
||||
LOGGER.error("Failed to open UART {}: {}", configuration.uartName, error_to_string(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
GpsModel model = configuration.model;
|
||||
if (model == GpsModel::Unknown) {
|
||||
model = probe(*uart);
|
||||
model = probe(uart);
|
||||
if (model == GpsModel::Unknown) {
|
||||
LOGGER.error("Probe failed");
|
||||
setState(State::Error);
|
||||
@ -45,7 +56,7 @@ int32_t GpsDevice::threadMain() {
|
||||
this->model = model;
|
||||
mutex.unlock();
|
||||
|
||||
if (!init(*uart, model)) {
|
||||
if (!init(uart, model)) {
|
||||
LOGGER.error("Init failed");
|
||||
setState(State::Error);
|
||||
return -1;
|
||||
@ -55,7 +66,8 @@ int32_t GpsDevice::threadMain() {
|
||||
|
||||
// Reference: https://gpsd.gitlab.io/gpsd/NMEA.html
|
||||
while (!isThreadInterrupted()) {
|
||||
size_t bytes_read = uart->readUntil(reinterpret_cast<std::byte*>(buffer), GPS_UART_BUFFER_SIZE, '\n', 100 / portTICK_PERIOD_MS);
|
||||
size_t bytes_read = 0;
|
||||
uart_controller_read_until(uart, buffer, GPS_UART_BUFFER_SIZE, '\n', true, &bytes_read, 100 / portTICK_PERIOD_MS);
|
||||
|
||||
// Thread might've been interrupted in the meanwhile
|
||||
if (isThreadInterrupted()) {
|
||||
@ -103,7 +115,7 @@ int32_t GpsDevice::threadMain() {
|
||||
}
|
||||
}
|
||||
|
||||
if (uart->isStarted() && !uart->stop()) {
|
||||
if (uart_controller_close(uart) != ERROR_NONE) {
|
||||
LOGGER.warn("Failed to stop UART {}", configuration.uartName);
|
||||
}
|
||||
|
||||
|
||||
@ -5,18 +5,21 @@
|
||||
#include <Tactility/hal/gps/Ublox.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
static const auto LOGGER = Logger("Gps");
|
||||
|
||||
bool initMtk(uart::Uart& uart);
|
||||
bool initMtkL76b(uart::Uart& uart);
|
||||
bool initMtkPa1616s(uart::Uart& uart);
|
||||
bool initAtgm336h(uart::Uart& uart);
|
||||
bool initUc6580(uart::Uart& uart);
|
||||
bool initAg33xx(uart::Uart& uart);
|
||||
bool initMtk(::Device* uart);
|
||||
bool initMtkL76b(::Device* uart);
|
||||
bool initMtkPa1616s(::Device* uart);
|
||||
bool initAtgm336h(::Device* uart);
|
||||
bool initUc6580(::Device* uart);
|
||||
bool initAg33xx(::Device* uart);
|
||||
|
||||
// region CAS
|
||||
|
||||
@ -73,11 +76,12 @@ static uint8_t makeCASPacket(uint8_t* buffer, uint8_t class_id, uint8_t msg_id,
|
||||
return (payload_size + 10);
|
||||
}
|
||||
|
||||
GpsResponse getACKCas(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
||||
GpsResponse getACKCas(::Device* uart, uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
||||
{
|
||||
uint32_t startTime = kernel::getMillis();
|
||||
uint8_t buffer[CAS_ACK_NACK_MSG_SIZE] = {0};
|
||||
uint8_t bufferPos = 0;
|
||||
TickType_t waitTicks = pdMS_TO_TICKS(waitMillis);
|
||||
|
||||
// CAS-ACK-(N)ACK structure
|
||||
// | H1 | H2 | Payload Len | cls | msg | Payload | Checksum (4) |
|
||||
@ -86,9 +90,11 @@ GpsResponse getACKCas(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32
|
||||
// ACK-NACK| 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x00 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX |
|
||||
// ACK-ACK | 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x01 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX |
|
||||
|
||||
while (kernel::getTicks() - startTime < waitMillis) {
|
||||
if (uart.available()) {
|
||||
uart.readByte(&buffer[bufferPos++]);
|
||||
while (kernel::getTicks() - startTime < waitTicks) {
|
||||
size_t available = 0;
|
||||
uart_controller_get_available(uart, &available);
|
||||
if (available > 0) {
|
||||
uart_controller_read_byte(uart, &buffer[bufferPos++], 1);
|
||||
|
||||
// keep looking at the first two bytes of buffer until
|
||||
// we have found the CAS frame header (0xBA, 0xCE), if not
|
||||
@ -136,7 +142,7 @@ GpsResponse getACKCas(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32
|
||||
|
||||
// endregion
|
||||
|
||||
bool init(uart::Uart& uart, GpsModel type) {
|
||||
bool init(::Device* uart, GpsModel type) {
|
||||
switch (type) {
|
||||
case GpsModel::Unknown:
|
||||
check(false);
|
||||
@ -167,58 +173,58 @@ bool init(uart::Uart& uart, GpsModel type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool initAg33xx(uart::Uart& uart) {
|
||||
uart.writeString("$PAIR066,1,0,1,0,0,1*3B\r\n"); // Enable GPS+GALILEO+NAVIC
|
||||
bool initAg33xx(::Device* uart) {
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR066,1,0,1,0,0,1*3B\r\n", 25, 250); // Enable GPS+GALILEO+NAVIC
|
||||
|
||||
// Configure NMEA (sentences will output once per fix)
|
||||
uart.writeString("$PAIR062,0,1*3F\r\n"); // GGA ON
|
||||
uart.writeString("$PAIR062,1,0*3F\r\n"); // GLL OFF
|
||||
uart.writeString("$PAIR062,2,0*3C\r\n"); // GSA OFF
|
||||
uart.writeString("$PAIR062,3,0*3D\r\n"); // GSV OFF
|
||||
uart.writeString("$PAIR062,4,1*3B\r\n"); // RMC ON
|
||||
uart.writeString("$PAIR062,5,0*3B\r\n"); // VTG OFF
|
||||
uart.writeString("$PAIR062,6,0*38\r\n"); // ZDA ON
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,0,1*3F\r\n", 17, 250); // GGA ON
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,1,0*3F\r\n", 17, 250); // GLL OFF
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,2,0*3C\r\n", 17, 250); // GSA OFF
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,3,0*3D\r\n", 17, 250); // GSV OFF
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,4,1*3B\r\n", 17, 250); // RMC ON
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,5,0*3B\r\n", 17, 250); // VTG OFF
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,6,0*38\r\n", 17, 250); // ZDA ON
|
||||
|
||||
kernel::delayMillis(250);
|
||||
uart.writeString("$PAIR513*3D\r\n"); // save configuration
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR513*3D\r\n", 13, 250); // save configuration
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initUc6580(uart::Uart& uart) {
|
||||
bool initUc6580(::Device* uart) {
|
||||
// The Unicore UC6580 can use a lot of sat systems, enable it to
|
||||
// use GPS L1 & L5 + BDS B1I & B2a + GLONASS L1 + GALILEO E1 & E5a + SBAS + QZSS
|
||||
// This will reset the receiver, so wait a bit afterwards
|
||||
// The paranoid will wait for the OK*04 confirmation response after each command.
|
||||
uart.writeString("$CFGSYS,h35155\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$CFGSYS,h35155\r\n", 16, 250);
|
||||
kernel::delayMillis(750);
|
||||
// Must be done after the CFGSYS command
|
||||
// Turn off GSV messages, we don't really care about which and where the sats are, maybe someday.
|
||||
uart.writeString("$CFGMSG,0,3,0\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$CFGMSG,0,3,0\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Turn off GSA messages, TinyGPS++ doesn't use this message.
|
||||
uart.writeString("$CFGMSG,0,2,0\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$CFGMSG,0,2,0\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Turn off NOTICE __TXT messages, these may provide Unicore some info but we don't care.
|
||||
uart.writeString("$CFGMSG,6,0,0\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$CFGMSG,6,0,0\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
uart.writeString("$CFGMSG,6,1,0\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$CFGMSG,6,1,0\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initAtgm336h(uart::Uart& uart) {
|
||||
bool initAtgm336h(::Device* uart) {
|
||||
uint8_t buffer[256];
|
||||
|
||||
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
|
||||
int msglen = makeCASPacket(buffer, 0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
|
||||
uart.writeBytes(buffer, msglen);
|
||||
uart_controller_write_bytes(uart, buffer, msglen, 250);
|
||||
if (getACKCas(uart, 0x06, 0x07, 250) != GpsResponse::Ok) {
|
||||
LOGGER.warn("ATGM336H: Could not set Config");
|
||||
}
|
||||
|
||||
// Set the update frequence to 1Hz
|
||||
msglen = makeCASPacket(buffer, 0x06, 0x04, sizeof(_message_CAS_CFG_RATE_1HZ), _message_CAS_CFG_RATE_1HZ);
|
||||
uart.writeBytes(buffer, msglen);
|
||||
uart_controller_write_bytes(uart, buffer, msglen, 250);
|
||||
if (getACKCas(uart, 0x06, 0x04, 250) != GpsResponse::Ok) {
|
||||
LOGGER.warn("ATGM336H: Could not set Update Frequency");
|
||||
}
|
||||
@ -230,7 +236,7 @@ bool initAtgm336h(uart::Uart& uart) {
|
||||
// Construct a CAS-CFG-MSG packet
|
||||
uint8_t cas_cfg_msg_packet[] = {0x4e, fields[i], 0x01, 0x00};
|
||||
msglen = makeCASPacket(buffer, 0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
|
||||
uart.writeBytes(buffer, msglen);
|
||||
uart_controller_write_bytes(uart, buffer, msglen, 250);
|
||||
if (getACKCas(uart, 0x06, 0x01, 250) != GpsResponse::Ok) {
|
||||
LOGGER.warn("ATGM336H: Could not enable NMEA MSG: {}", fields[i]);
|
||||
}
|
||||
@ -238,53 +244,53 @@ bool initAtgm336h(uart::Uart& uart) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initMtkPa1616s(uart::Uart& uart) {
|
||||
bool initMtkPa1616s(::Device* uart) {
|
||||
// PA1616S is used in some GPS breakout boards from Adafruit
|
||||
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
|
||||
uart.writeString("$PMTK353,1,0,0,0,0*2A\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK353,1,0,0,0,0*2A\r\n", 23, 250);
|
||||
// Above command will reset the GPS and takes longer before it will accept new commands
|
||||
kernel::delayMillis(1000);
|
||||
// Only ask for RMC and GGA (GNRMC and GNGGA)
|
||||
uart.writeString("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n", 51, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Enable SBAS / WAAS
|
||||
uart.writeString("$PMTK301,2*2E\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK301,2*2E\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initMtkL76b(uart::Uart& uart) {
|
||||
bool initMtkL76b(::Device* uart) {
|
||||
// Waveshare Pico-GPS hat uses the L76B with 9600 baud
|
||||
// Initialize the L76B Chip, use GPS + GLONASS
|
||||
// See note in L76_Series_GNSS_Protocol_Specification, chapter 3.29
|
||||
uart.writeString("$PMTK353,1,1,0,0,0*2B\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK353,1,1,0,0,0*2B\r\n", 23, 250);
|
||||
// Above command will reset the GPS and takes longer before it will accept new commands
|
||||
kernel::delayMillis(1000);
|
||||
// only ask for RMC and GGA (GNRMC and GNGGA)
|
||||
// See note in L76_Series_GNSS_Protocol_Specification, chapter 2.1
|
||||
uart.writeString("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n", 51, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Enable SBAS
|
||||
uart.writeString("$PMTK301,2*2E\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK301,2*2E\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Enable PPS for 2D/3D fix only
|
||||
uart.writeString("$PMTK285,3,100*3F\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK285,3,100*3F\r\n", 19, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
|
||||
uart.writeString("$PMTK886,1*29\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK886,1*29\r\n", 15, 250);
|
||||
kernel::delayMillis(250);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initMtk(uart::Uart& uart) {
|
||||
bool initMtk(::Device* uart) {
|
||||
// Initialize the L76K Chip, use GPS + GLONASS + BEIDOU
|
||||
uart.writeString("$PCAS04,7*1E\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PCAS04,7*1E\r\n", 14, 250);
|
||||
kernel::delayMillis(250);
|
||||
// only ask for RMC and GGA
|
||||
uart.writeString("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n", 38, 250);
|
||||
kernel::delayMillis(250);
|
||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||
uart.writeString("$PCAS11,3*1E\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PCAS11,3*1E\r\n", 14, 250);
|
||||
kernel::delayMillis(250);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
#include "Tactility/hal/gps/GpsDevice.h"
|
||||
#include "Tactility/hal/gps/Ublox.h"
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
static const auto LOGGER = tt::Logger("Gps");
|
||||
@ -41,7 +43,7 @@ char* strnstr(const char* s, const char* find, size_t slen) {
|
||||
/**
|
||||
* From: https://github.com/meshtastic/firmware/blob/f81d3b045dd1b7e3ca7870af3da915ff4399ea98/src/gps/GPS.cpp
|
||||
*/
|
||||
GpsResponse getAck(uart::Uart& uart, const char* message, uint32_t waitMillis) {
|
||||
GpsResponse getAck(::Device* uart, const char* message, uint32_t waitMillis) {
|
||||
uint8_t buffer[768] = {0};
|
||||
uint8_t b;
|
||||
int bytesRead = 0;
|
||||
@ -50,8 +52,10 @@ GpsResponse getAck(uart::Uart& uart, const char* message, uint32_t waitMillis) {
|
||||
std::string debugmsg = "";
|
||||
#endif
|
||||
while (kernel::getMillis() < startTimeout) {
|
||||
if (uart.available()) {
|
||||
uart.readByte(&b);
|
||||
size_t available = 0;
|
||||
uart_controller_get_available(uart, &available);
|
||||
if (available > 0) {
|
||||
uart_controller_read_byte(uart, &b, 1);
|
||||
|
||||
#ifdef GPS_DEBUG
|
||||
debugmsg += vformat("%c", (b >= 32 && b <= 126) ? b : '.');
|
||||
@ -82,8 +86,8 @@ GpsResponse getAck(uart::Uart& uart, const char* message, uint32_t waitMillis) {
|
||||
#define PROBE_SIMPLE(UART, CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
||||
do { \
|
||||
LOGGER.info("Probing for {} ({})", CHIP, TOWRITE); \
|
||||
UART.flushInput(); \
|
||||
UART.writeString(TOWRITE "\r\n", TIMEOUT); \
|
||||
uart_controller_flush_input(UART); \
|
||||
uart_controller_write_bytes(UART, (const uint8_t*)(TOWRITE "\r\n"), strlen(TOWRITE "\r\n"), TIMEOUT); \
|
||||
if (getAck(UART, RESPONSE, TIMEOUT) == GpsResponse::Ok) { \
|
||||
LOGGER.info("Probe detected {} {}", CHIP, #DRIVER); \
|
||||
return DRIVER; \
|
||||
@ -93,15 +97,15 @@ GpsResponse getAck(uart::Uart& uart, const char* message, uint32_t waitMillis) {
|
||||
/**
|
||||
* From: https://github.com/meshtastic/firmware/blob/f81d3b045dd1b7e3ca7870af3da915ff4399ea98/src/gps/GPS.cpp
|
||||
*/
|
||||
GpsModel probe(uart::Uart& uart) {
|
||||
GpsModel probe(::Device* uart) {
|
||||
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
|
||||
uart.writeString("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n", 40, 500);
|
||||
kernel::delayMillis(20);
|
||||
|
||||
// Close NMEA sequences on Ublox
|
||||
uart.writeString("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n");
|
||||
uart.writeString("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n");
|
||||
uart.writeString("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n", 29, 500);
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PUBX,40,GSV,0,0,0,0,0,0*59\r\n", 29, 500);
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n", 29, 500);
|
||||
kernel::delayMillis(20);
|
||||
|
||||
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
|
||||
@ -114,9 +118,9 @@ GpsModel probe(uart::Uart& uart) {
|
||||
PROBE_SIMPLE(uart, "ATGM332D", "$PCAS06,1*1A", "$GPTXT,01,01,02,HW=ATGM332D", GpsModel::ATGM336H, 500);
|
||||
|
||||
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
|
||||
uart.writeString("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
|
||||
uart.writeString("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
|
||||
uart.writeString("$PAIR513*3D\r\n"); // save configuration
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,2,0*3C\r\n", 17, 500); // GSA OFF to reduce volume
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR062,3,0*3D\r\n", 17, 500); // GSV OFF to reduce volume
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PAIR513*3D\r\n", 13, 500); // save configuration
|
||||
PROBE_SIMPLE(uart, "AG3335", "$PAIR021*39", "$PAIR021,AG3335", GpsModel::AG3335, 500);
|
||||
PROBE_SIMPLE(uart, "AG3352", "$PAIR021*39", "$PAIR021,AG3352", GpsModel::AG3352, 500);
|
||||
PROBE_SIMPLE(uart, "LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GpsModel::AG3352, 500);
|
||||
@ -124,7 +128,7 @@ GpsModel probe(uart::Uart& uart) {
|
||||
PROBE_SIMPLE(uart, "L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GpsModel::MTK, 500);
|
||||
|
||||
// Close all NMEA sentences, valid for L76B MTK platform (Waveshare Pico GPS)
|
||||
uart.writeString("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
|
||||
uart_controller_write_bytes(uart, (const uint8_t*)"$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n", 51, 500);
|
||||
kernel::delayMillis(20);
|
||||
|
||||
PROBE_SIMPLE(uart, "L76B", "$PMTK605*31", "Quectel-L76B", GpsModel::MTK_L76B, 500);
|
||||
@ -134,7 +138,7 @@ GpsModel probe(uart::Uart& uart) {
|
||||
if (ublox_result != GpsModel::Unknown) {
|
||||
return ublox_result;
|
||||
} else {
|
||||
LOGGER.warn("No GNSS Module (baud rate {})", uart.getBaudRate());
|
||||
LOGGER.warn("No GNSS Module");
|
||||
return GpsModel::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,24 +1,26 @@
|
||||
#include <Tactility/hal/gps/Ublox.h>
|
||||
#include <Tactility/hal/gps/UbloxMessages.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
#include <Tactility/Logger.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/uart_controller.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tt::hal::gps::ublox {
|
||||
|
||||
static const auto LOGGER = Logger("Ublox");
|
||||
|
||||
bool initUblox6(uart::Uart& uart);
|
||||
bool initUblox789(uart::Uart& uart, GpsModel model);
|
||||
bool initUblox10(uart::Uart& uart);
|
||||
bool initUblox6(::Device* uart);
|
||||
bool initUblox789(::Device* uart, GpsModel model);
|
||||
bool initUblox10(::Device* uart);
|
||||
|
||||
#define SEND_UBX_PACKET(UART, BUFFER, TYPE, ID, DATA, ERRMSG, TIMEOUT) \
|
||||
#define SEND_UBX_PACKET(UART, BUFFER, TYPE, ID, DATA, ERRMSG, TIMEOUT_MILLIS) \
|
||||
do { \
|
||||
auto msglen = makePacket(TYPE, ID, DATA, sizeof(DATA), BUFFER); \
|
||||
UART.writeBytes(BUFFER, sizeof(BUFFER)); \
|
||||
if (getAck(UART, TYPE, ID, TIMEOUT) != GpsResponse::Ok) { \
|
||||
uart_controller_write_bytes(UART, BUFFER, msglen, TIMEOUT_MILLIS / portTICK_PERIOD_MS); \
|
||||
if (getAck(UART, TYPE, ID, TIMEOUT_MILLIS) != GpsResponse::Ok) { \
|
||||
LOGGER.info("Sending packet failed: {}", #ERRMSG); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -56,12 +58,13 @@ uint8_t makePacket(uint8_t classId, uint8_t messageId, const uint8_t* payload, u
|
||||
return (payloadSize + 8U);
|
||||
}
|
||||
|
||||
GpsResponse getAck(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) {
|
||||
GpsResponse getAck(::Device* uart, uint8_t class_id, uint8_t msg_id, uint32_t waitMillis) {
|
||||
uint8_t b;
|
||||
uint8_t ack = 0;
|
||||
const uint8_t ackP[2] = {class_id, msg_id};
|
||||
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint32_t startTime = kernel::getMillis();
|
||||
uint32_t startTime = kernel::getTicks();
|
||||
TickType_t waitTicks = pdMS_TO_TICKS(waitMillis);
|
||||
const char frame_errors[] = "More than 100 frame errors";
|
||||
int sCounter = 0;
|
||||
#ifdef GPS_DEBUG
|
||||
@ -79,15 +82,17 @@ GpsResponse getAck(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32_t
|
||||
buf[9] += buf[8];
|
||||
}
|
||||
|
||||
while (kernel::getTicks() - startTime < waitMillis) {
|
||||
while (kernel::getTicks() - startTime < waitTicks) {
|
||||
if (ack > 9) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOGGER.info("Got ACK for class {:02X} message {:02X} in {}ms", class_id, msg_id, kernel::getMillis() - startTime);
|
||||
#endif
|
||||
return GpsResponse::Ok; // ACK received
|
||||
}
|
||||
if (uart.available()) {
|
||||
uart.readByte(&b);
|
||||
size_t available = 0;
|
||||
uart_controller_get_available(uart, &available);
|
||||
if (available > 0) {
|
||||
uart_controller_read_byte(uart, &b, 1);
|
||||
if (b == frame_errors[sCounter]) {
|
||||
sCounter++;
|
||||
if (sCounter == 26) {
|
||||
@ -124,15 +129,19 @@ GpsResponse getAck(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32_t
|
||||
return GpsResponse::None; // No response received within timeout
|
||||
}
|
||||
|
||||
static int getAck(uart::Uart& uart, uint8_t* buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedId, TickType_t timeout) {
|
||||
static int getAck(::Device* uart, uint8_t* buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedId, uint32_t timeoutMillis) {
|
||||
uint16_t ubxFrameCounter = 0;
|
||||
uint32_t startTime = kernel::getTicks();
|
||||
TickType_t startTime = kernel::getTicks();
|
||||
TickType_t timeoutTicks = pdMS_TO_TICKS(timeoutMillis);
|
||||
uint16_t needRead = 0;
|
||||
|
||||
while (kernel::getTicks() - startTime < timeout) {
|
||||
while (uart.available()) {
|
||||
while ((kernel::getTicks() - startTime) < timeoutTicks) {
|
||||
size_t available = 0;
|
||||
uart_controller_get_available(uart, &available);
|
||||
while (available > 0) {
|
||||
uint8_t c;
|
||||
uart.readByte(&c);
|
||||
uart_controller_read_byte(uart, &c, 1);
|
||||
available--;
|
||||
|
||||
switch (ubxFrameCounter) {
|
||||
case 0:
|
||||
@ -174,7 +183,8 @@ static int getAck(uart::Uart& uart, uint8_t* buffer, uint16_t size, uint8_t requ
|
||||
ubxFrameCounter = 0;
|
||||
break;
|
||||
}
|
||||
auto read_bytes = uart.readBytes(buffer, needRead, 250 / portTICK_PERIOD_MS);
|
||||
auto read_bytes = 0U;
|
||||
uart_controller_read_bytes(uart, buffer, needRead, 250 / portTICK_PERIOD_MS);
|
||||
if (read_bytes != needRead) {
|
||||
ubxFrameCounter = 0;
|
||||
} else {
|
||||
@ -203,21 +213,21 @@ static struct uBloxGnssModelInfo {
|
||||
uint8_t protocol_version;
|
||||
} ublox_info;
|
||||
|
||||
GpsModel probe(uart::Uart& uart) {
|
||||
GpsModel probe(::Device* uart) {
|
||||
LOGGER.info("Probing for U-blox");
|
||||
constexpr auto DETECTED_MESSAGE = "{} detected, using {} Module";
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
checksum(cfg_rate, sizeof(cfg_rate));
|
||||
uart.flushInput();
|
||||
uart.writeBytes(cfg_rate, sizeof(cfg_rate));
|
||||
uart_controller_flush_input(uart);
|
||||
uart_controller_write_bytes(uart, cfg_rate, sizeof(cfg_rate), 500 / portTICK_PERIOD_MS);
|
||||
// Check that the returned response class and message ID are correct
|
||||
GpsResponse response = getAck(uart, 0x06, 0x08, 750);
|
||||
if (response == GpsResponse::None) {
|
||||
LOGGER.warn("No GNSS Module (baudrate {})", uart.getBaudRate());
|
||||
LOGGER.warn("No GNSS Module");
|
||||
return GpsModel::Unknown;
|
||||
} else if (response == GpsResponse::FrameErrors) {
|
||||
LOGGER.warn("UBlox Frame Errors (baudrate {})", uart.getBaudRate());
|
||||
LOGGER.warn("UBlox Frame Errors");
|
||||
}
|
||||
|
||||
uint8_t buffer[256];
|
||||
@ -230,8 +240,8 @@ GpsModel probe(uart::Uart& uart) {
|
||||
};
|
||||
// Get Ublox gnss module hardware and software info
|
||||
checksum(_message_MONVER, sizeof(_message_MONVER));
|
||||
uart.flushInput();
|
||||
uart.writeBytes(_message_MONVER, sizeof(_message_MONVER));
|
||||
uart_controller_flush_input(uart);
|
||||
uart_controller_write_bytes(uart, _message_MONVER, sizeof(_message_MONVER), 500);
|
||||
|
||||
uint16_t ack_response_len = getAck(uart, buffer, sizeof(buffer), 0x0A, 0x04, 1200);
|
||||
if (ack_response_len) {
|
||||
@ -303,7 +313,7 @@ GpsModel probe(uart::Uart& uart) {
|
||||
return GpsModel::Unknown;
|
||||
}
|
||||
|
||||
bool init(uart::Uart& uart, GpsModel model) {
|
||||
bool init(::Device* uart, GpsModel model) {
|
||||
LOGGER.info("U-blox init");
|
||||
switch (model) {
|
||||
case GpsModel::UBLOX6:
|
||||
@ -320,19 +330,19 @@ bool init(uart::Uart& uart, GpsModel model) {
|
||||
}
|
||||
}
|
||||
|
||||
bool initUblox10(uart::Uart& uart) {
|
||||
bool initUblox10(::Device* uart) {
|
||||
uint8_t buffer[256];
|
||||
kernel::delayMillis(1000);
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x8A, _message_VALSET_DISABLE_NMEA_RAM, "disable NMEA messages in M10 RAM", 300);
|
||||
kernel::delayMillis(750);
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x8A, _message_VALSET_DISABLE_NMEA_BBR, "disable NMEA messages in M10 BBR", 300);
|
||||
kernel::delayMillis(750);
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_RAM, "disable Info messages for M10 GPS RAM", 300);
|
||||
kernel::delayMillis(750);
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_BBR, "disable Info messages for M10 GPS BBR", 300);
|
||||
kernel::delayMillis(750);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x8A, _message_VALSET_PM_RAM, "enable powersave for M10 GPS RAM", 300);
|
||||
@ -362,7 +372,7 @@ bool initUblox10(uart::Uart& uart) {
|
||||
// BBR will survive a restart, and power off for a while, but modules with small backup
|
||||
// batteries or super caps will not retain the config for a long power off time.
|
||||
auto packet_size = makePacket(0x06, 0x09, _message_SAVE_10, sizeof(_message_SAVE_10), buffer);
|
||||
uart.writeBytes(buffer, packet_size);
|
||||
uart_controller_write_bytes(uart, buffer, packet_size, 2000 / portTICK_PERIOD_MS);
|
||||
if (getAck(uart, 0x06, 0x09, 2000) != GpsResponse::Ok) {
|
||||
LOGGER.warn("Unable to save GNSS module config");
|
||||
} else {
|
||||
@ -371,15 +381,15 @@ bool initUblox10(uart::Uart& uart) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initUblox789(uart::Uart& uart, GpsModel model) {
|
||||
bool initUblox789(::Device* uart, GpsModel model) {
|
||||
uint8_t buffer[256];
|
||||
if (model == GpsModel::UBLOX7) {
|
||||
LOGGER.debug("Set GPS+SBAS");
|
||||
auto msglen = makePacket(0x06, 0x3e, _message_GNSS_7, sizeof(_message_GNSS_7), buffer);
|
||||
uart.writeBytes(buffer, msglen);
|
||||
uart_controller_write_bytes(uart, buffer, msglen, 800 / portTICK_PERIOD_MS);
|
||||
} else { // 8,9
|
||||
auto msglen = makePacket(0x06, 0x3e, _message_GNSS_8, sizeof(_message_GNSS_8), buffer);
|
||||
uart.writeBytes(buffer, msglen);
|
||||
uart_controller_write_bytes(uart, buffer, msglen, 800 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
if (getAck(uart, 0x06, 0x3e, 800) == GpsResponse::NotAck) {
|
||||
@ -396,15 +406,15 @@ bool initUblox789(uart::Uart& uart, GpsModel model) {
|
||||
kernel::delayMillis(1000);
|
||||
}
|
||||
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x02, _message_DISABLE_TXT_INFO, "disable text info messages", 500);
|
||||
|
||||
if (model == GpsModel::UBLOX8) { // 8
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x39, _message_JAM_8, "enable interference resistance", 500);
|
||||
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x23, _message_NAVX5_8, "configure NAVX5_8 settings", 500);
|
||||
} else { // 6,7,9
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x39, _message_JAM_6_7, "enable interference resistance", 500);
|
||||
@ -421,13 +431,13 @@ bool initUblox789(uart::Uart& uart, GpsModel model) {
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
|
||||
|
||||
if (ublox_info.protocol_version >= 18) {
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x86, _message_PMS, "enable powersave for GPS", 500);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x3B, _message_CFG_PM2, "enable powersave details for GPS", 500);
|
||||
|
||||
// For M8 we want to enable NMEA version 4.10 so we can see the additional satellites.
|
||||
if (model == GpsModel::UBLOX8) {
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x17, _message_NMEA, "enable NMEA 4.10", 500);
|
||||
}
|
||||
} else {
|
||||
@ -436,7 +446,7 @@ bool initUblox789(uart::Uart& uart, GpsModel model) {
|
||||
}
|
||||
|
||||
auto packet_size = makePacket(0x06, 0x09, _message_SAVE, sizeof(_message_SAVE), buffer);
|
||||
uart.writeBytes(buffer, packet_size);
|
||||
uart_controller_write_bytes(uart, buffer, packet_size, 2000 / portTICK_PERIOD_MS);
|
||||
if (getAck(uart, 0x06, 0x09, 2000) != GpsResponse::Ok) {
|
||||
LOGGER.warn("Unable to save GNSS module config");
|
||||
} else {
|
||||
@ -445,10 +455,10 @@ bool initUblox789(uart::Uart& uart, GpsModel model) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initUblox6(uart::Uart& uart) {
|
||||
bool initUblox6(::Device* uart) {
|
||||
uint8_t buffer[256];
|
||||
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x02, _message_DISABLE_TXT_INFO, "disable text info messages", 500);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x39, _message_JAM_6_7, "enable interference resistance", 500);
|
||||
@ -463,14 +473,14 @@ bool initUblox6(uart::Uart& uart) {
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
|
||||
|
||||
uart.flushInput();
|
||||
uart_controller_flush_input(uart);
|
||||
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x11, _message_CFG_RXM_ECO, "enable powersave ECO mode for Neo-6", 500);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x3B, _message_CFG_PM2, "enable powersave details for GPS", 500);
|
||||
SEND_UBX_PACKET(uart, buffer, 0x06, 0x01, _message_AID, "disable UBX-AID", 500);
|
||||
|
||||
auto packet_size = makePacket(0x06, 0x09, _message_SAVE, sizeof(_message_SAVE), buffer);
|
||||
uart.writeBytes(buffer, packet_size);
|
||||
uart_controller_write_bytes(uart, buffer, packet_size, 2000);
|
||||
if (getAck(uart, 0x06, 0x09, 2000) != GpsResponse::Ok) {
|
||||
LOGGER.warn("Unable to save GNSS module config");
|
||||
} else {
|
||||
|
||||
@ -37,9 +37,8 @@ Device* findDevice(i2c_port_t port) {
|
||||
auto* driver = device_get_driver(device);
|
||||
if (driver == nullptr) return true;
|
||||
if (!driver_is_compatible(driver, "espressif,esp32-i2c")) return true;
|
||||
i2c_port_t port;
|
||||
if (esp32_i2c_get_port(device, &port) != ERROR_NONE) return true;
|
||||
if (port != params_ptr->port) return true;
|
||||
auto* config = static_cast<const Esp32I2cConfig*>(device->config);
|
||||
if (config->port != params_ptr->port) return true;
|
||||
// Found it, stop iterating
|
||||
params_ptr->device = device;
|
||||
return false;
|
||||
|
||||
@ -1,192 +0,0 @@
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
|
||||
#include <ranges>
|
||||
#include <cstring>
|
||||
#include <Tactility/Tactility.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <Tactility/hal/uart/UartEsp.h>
|
||||
#include <esp_check.h>
|
||||
#else
|
||||
#include <Tactility/hal/uart/UartPosix.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
static const auto LOGGER = Logger("UART");
|
||||
|
||||
constexpr uint32_t uartIdNotInUse = 0;
|
||||
|
||||
struct UartEntry {
|
||||
uint32_t usageId = uartIdNotInUse;
|
||||
Configuration configuration;
|
||||
};
|
||||
|
||||
static std::vector<UartEntry> uartEntries = {};
|
||||
static uint32_t lastUartId = uartIdNotInUse;
|
||||
|
||||
bool init(const std::vector<Configuration>& configurations) {
|
||||
LOGGER.info("Init");
|
||||
for (const auto& configuration: configurations) {
|
||||
uartEntries.push_back({
|
||||
.usageId = uartIdNotInUse,
|
||||
.configuration = configuration
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Uart::writeString(const char* buffer, TickType_t timeout) {
|
||||
auto size = strlen(buffer);
|
||||
writeBytes((std::byte*)buffer, size, timeout);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Uart::readUntil(std::byte* buffer, size_t bufferSize, uint8_t untilByte, TickType_t timeout, bool addNullTerminator) {
|
||||
TickType_t start_time = kernel::getTicks();
|
||||
auto* buffer_write_ptr = reinterpret_cast<uint8_t*>(buffer);
|
||||
uint8_t* buffer_limit = buffer_write_ptr + bufferSize - 1; // Keep 1 extra char as mull terminator
|
||||
TickType_t timeout_left = timeout;
|
||||
while (readByte(reinterpret_cast<std::byte*>(buffer_write_ptr), timeout_left) && buffer_write_ptr < buffer_limit) {
|
||||
#ifdef DEBUG_READ_UNTIL
|
||||
// If first successful read and we're not receiving an empty response
|
||||
if (buffer_write_ptr == buffer && *buffer_write_ptr != 0x00U && *buffer_write_ptr != untilByte) {
|
||||
printf(">>");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*buffer_write_ptr == untilByte) {
|
||||
// TODO: Fix when untilByte is null terminator char already
|
||||
if (addNullTerminator) {
|
||||
buffer_write_ptr++;
|
||||
*buffer_write_ptr = 0x00U;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_READ_UNTIL
|
||||
printf("%c", *buffer_write_ptr);
|
||||
#endif
|
||||
|
||||
buffer_write_ptr++;
|
||||
|
||||
TickType_t now = kernel::getTicks();
|
||||
if (now > (start_time + timeout)) {
|
||||
#ifdef DEBUG_READ_UNTIL
|
||||
LOGGER.warn("readUntil() timeout");
|
||||
#endif
|
||||
break;
|
||||
} else {
|
||||
timeout_left = timeout - (now - start_time);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_READ_UNTIL
|
||||
// If we read data and it's not an empty response
|
||||
if (buffer_write_ptr != buffer && *buffer != 0x00U && *buffer != untilByte) {
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (addNullTerminator && (buffer_write_ptr > reinterpret_cast<uint8_t*>(buffer))) {
|
||||
return reinterpret_cast<size_t>(buffer_write_ptr) - reinterpret_cast<size_t>(buffer) - 1UL;
|
||||
} else {
|
||||
return reinterpret_cast<size_t>(buffer_write_ptr) - reinterpret_cast<size_t>(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static std::unique_ptr<Uart> open(UartEntry& entry) {
|
||||
if (entry.usageId != uartIdNotInUse) {
|
||||
LOGGER.error("UART in use: {}", entry.configuration.name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto uart = create(entry.configuration);
|
||||
assert(uart != nullptr);
|
||||
entry.usageId = uart->getId();
|
||||
LOGGER.info("Opened {}", entry.usageId);
|
||||
return uart;
|
||||
}
|
||||
|
||||
std::unique_ptr<Uart> open(uart_port_t port) {
|
||||
LOGGER.info("Open {}", static_cast<int>(port));
|
||||
|
||||
auto result = std::views::filter(uartEntries, [port](auto& entry) {
|
||||
return entry.configuration.port == port;
|
||||
});
|
||||
|
||||
if (result.empty()) {
|
||||
LOGGER.error("UART not found: {}", static_cast<int>(port));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return open(*result.begin());
|
||||
}
|
||||
|
||||
std::unique_ptr<Uart> open(std::string name) {
|
||||
LOGGER.info("Open {}", name);
|
||||
|
||||
auto result = std::views::filter(uartEntries, [&name](auto& entry) {
|
||||
return entry.configuration.name == name;
|
||||
});
|
||||
|
||||
if (result.empty()) {
|
||||
LOGGER.error("UART not found: {}", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return open(*result.begin());
|
||||
}
|
||||
|
||||
void close(uint32_t uartId) {
|
||||
LOGGER.info("Close {}", uartId);
|
||||
auto result = std::views::filter(uartEntries, [&uartId](auto& entry) {
|
||||
return entry.usageId == uartId;
|
||||
});
|
||||
|
||||
if (!result.empty()) {
|
||||
auto& entry = *result.begin();
|
||||
entry.usageId = uartIdNotInUse;
|
||||
} else {
|
||||
LOGGER.warn("Auto-closing UART, but can't find it");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> getNames() {
|
||||
std::vector<std::string> names;
|
||||
#ifdef ESP_PLATFORM
|
||||
for (auto& config : getConfiguration()->uart) {
|
||||
names.push_back(config.name);
|
||||
}
|
||||
#else
|
||||
DIR* dir = opendir("/dev");
|
||||
if (dir == nullptr) {
|
||||
LOGGER.error("Failed to read /dev");
|
||||
return names;
|
||||
}
|
||||
struct dirent* current_entry;
|
||||
while ((current_entry = readdir(dir)) != nullptr) {
|
||||
auto name = std::string(current_entry->d_name);
|
||||
if (name.starts_with("tty")) {
|
||||
auto path = std::string("/dev/") + name;
|
||||
names.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
#endif
|
||||
return names;
|
||||
}
|
||||
|
||||
Uart::Uart() : id(++lastUartId) {}
|
||||
|
||||
Uart::~Uart() {
|
||||
close(getId());
|
||||
}
|
||||
|
||||
} // namespace tt::hal::uart
|
||||
@ -1,157 +0,0 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <Tactility/hal/uart/UartEsp.h>
|
||||
|
||||
#include <Tactility/Logger.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
|
||||
#include <esp_check.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
static const auto LOGGER = Logger("UART");
|
||||
|
||||
bool UartEsp::start() {
|
||||
LOGGER.info("[{}] Starting", configuration.name);
|
||||
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (started) {
|
||||
LOGGER.error("[{}] Starting: Already started", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
int intr_alloc_flags;
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
intr_alloc_flags = ESP_INTR_FLAG_IRAM;
|
||||
#else
|
||||
intr_alloc_flags = 0;
|
||||
#endif
|
||||
|
||||
esp_err_t result = uart_param_config(configuration.port, &configuration.config);
|
||||
if (result != ESP_OK) {
|
||||
LOGGER.error("[{}] Starting: Failed to configure: {}", configuration.name, esp_err_to_name(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uart_is_driver_installed(configuration.port)) {
|
||||
LOGGER.error("[{}] Driver was still installed. You probably forgot to stop, or another system uses/used the driver.", configuration.name);
|
||||
uart_driver_delete(configuration.port);
|
||||
}
|
||||
|
||||
result = uart_set_pin(configuration.port, configuration.txPin, configuration.rxPin, configuration.rtsPin, configuration.ctsPin);
|
||||
if (result != ESP_OK) {
|
||||
LOGGER.error("[{}] Starting: Failed set pins: {}", configuration.name, esp_err_to_name(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
result = uart_driver_install(configuration.port, (int)configuration.rxBufferSize, (int)configuration.txBufferSize, 0, nullptr, intr_alloc_flags);
|
||||
if (result != ESP_OK) {
|
||||
LOGGER.error("[{}] Starting: Failed to install driver: {}", configuration.name, esp_err_to_name(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
LOGGER.info("[{}] Started", configuration.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UartEsp::stop() {
|
||||
LOGGER.info("[{}] Stopping", configuration.name);
|
||||
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (!started) {
|
||||
LOGGER.error("[{}] Stopping: Not started", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_err_t result = uart_driver_delete(configuration.port);
|
||||
if (result != ESP_OK) {
|
||||
LOGGER.error("[{}] Stopping: Failed to delete driver: {}", configuration.name, esp_err_to_name(result));
|
||||
return false;
|
||||
}
|
||||
|
||||
started = false;
|
||||
|
||||
LOGGER.info("[{}] Stopped", configuration.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UartEsp::isStarted() const {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
return started;
|
||||
}
|
||||
|
||||
size_t UartEsp::readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto start_time = kernel::getTicks();
|
||||
auto lock_time = kernel::getTicks() - start_time;
|
||||
auto remaining_timeout = std::max(timeout - lock_time, 0UL);
|
||||
auto result = uart_read_bytes(configuration.port, buffer, bufferSize, remaining_timeout);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UartEsp::readByte(std::byte* output, TickType_t timeout) {
|
||||
return readBytes(output, 1, timeout) == 1;
|
||||
}
|
||||
|
||||
size_t UartEsp::writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return uart_write_bytes(configuration.port, buffer, bufferSize);
|
||||
}
|
||||
|
||||
size_t UartEsp::available(TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size = 0;
|
||||
uart_get_buffered_data_len(configuration.port, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void UartEsp::flushInput() {
|
||||
uart_flush_input(configuration.port);
|
||||
}
|
||||
|
||||
uint32_t UartEsp::getBaudRate() {
|
||||
uint32_t baud_rate = 0;
|
||||
auto result = uart_get_baudrate(configuration.port, &baud_rate);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
|
||||
return baud_rate;
|
||||
}
|
||||
|
||||
bool UartEsp::setBaudRate(uint32_t baudRate, TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = uart_set_baudrate(configuration.port, baudRate);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(result);
|
||||
return result == ESP_OK;
|
||||
}
|
||||
|
||||
std::unique_ptr<Uart> create(const Configuration& configuration) {
|
||||
return std::make_unique<UartEsp>(configuration);
|
||||
}
|
||||
|
||||
} // namespace tt::hal::uart
|
||||
|
||||
#endif
|
||||
@ -1,191 +0,0 @@
|
||||
#ifndef ESP_PLATFORM
|
||||
|
||||
#include <Tactility/hal/uart/UartPosix.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
#include <Tactility/Logger.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace tt::hal::uart {
|
||||
|
||||
static const auto LOGGER = Logger("UART");
|
||||
|
||||
bool UartPosix::start() {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (device != nullptr) {
|
||||
LOGGER.error("[{}] Starting: Already started", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto file = fopen(configuration.name.c_str(), "w");
|
||||
if (file == nullptr) {
|
||||
LOGGER.error("[{}] Open device failed", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto new_device = std::unique_ptr<FILE, AutoCloseFileDeleter>(file);
|
||||
|
||||
struct termios tty;
|
||||
if (tcgetattr(fileno(file), &tty) < 0) {
|
||||
LOGGER.error("[{}] tcgetattr failed: {}", configuration.name, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cfsetospeed(&tty, (speed_t)configuration.baudRate) == -1) {
|
||||
LOGGER.error("[{}] Setting output speed failed", configuration.name);
|
||||
}
|
||||
|
||||
if (cfsetispeed(&tty, (speed_t)configuration.baudRate) == -1) {
|
||||
LOGGER.error("[{}] Setting input speed failed", configuration.name);
|
||||
}
|
||||
|
||||
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
|
||||
tty.c_cflag &= ~CSIZE;
|
||||
tty.c_cflag |= CS8; /* 8-bit characters */
|
||||
tty.c_cflag &= ~PARENB; /* no parity bit */
|
||||
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
|
||||
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
|
||||
|
||||
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
tty.c_oflag &= ~OPOST;
|
||||
|
||||
/* fetch bytes as they become available */
|
||||
tty.c_cc[VMIN] = 1;
|
||||
tty.c_cc[VTIME] = 1;
|
||||
|
||||
if (tcsetattr(fileno(file), TCSANOW, &tty) != 0) {
|
||||
LOGGER.error("[{}] tcsetattr failed: {}", configuration.name, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
device = std::move(new_device);
|
||||
|
||||
LOGGER.info("[{}] Started", configuration.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UartPosix::stop() {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (device == nullptr) {
|
||||
LOGGER.error("[{}] Stopping: Not started", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
device = nullptr;
|
||||
|
||||
LOGGER.info("[{}] Stopped", configuration.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UartPosix::isStarted() const {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
return device != nullptr;
|
||||
}
|
||||
|
||||
size_t UartPosix::readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (awaitAvailable(timeout)) {
|
||||
return read(fileno(device.get()), buffer, bufferSize);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool UartPosix::readByte(std::byte* output, TickType_t timeout) {
|
||||
if (awaitAvailable(timeout)) {
|
||||
return read(fileno(device.get()), output, 1) == 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
size_t UartPosix::writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout) {
|
||||
if (!mutex.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return write(fileno(device.get()), buffer, bufferSize);
|
||||
}
|
||||
|
||||
size_t UartPosix::available(TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t bytes_available = 0;
|
||||
ioctl(fileno(device.get()), FIONREAD, bytes_available);
|
||||
return bytes_available;
|
||||
}
|
||||
|
||||
void UartPosix::flushInput() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint32_t UartPosix::getBaudRate() {
|
||||
struct termios tty;
|
||||
if (tcgetattr(fileno(device.get()), &tty) < 0) {
|
||||
LOGGER.error("[{}] tcgetattr failed: {}", configuration.name, strerror(errno));
|
||||
return false;
|
||||
} else {
|
||||
return (uint32_t)cfgetispeed(&tty);
|
||||
}
|
||||
}
|
||||
|
||||
bool UartPosix::setBaudRate(uint32_t baudRate, TickType_t timeout) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
if (!lock.lock(timeout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct termios tty;
|
||||
if (tcgetattr(fileno(device.get()), &tty) < 0) {
|
||||
LOGGER.error("[{}] tcgetattr failed: {}", configuration.name, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cfsetospeed(&tty, (speed_t)configuration.baudRate) == -1) {
|
||||
LOGGER.error("[{}] Failed to set output speed", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cfsetispeed(&tty, (speed_t)configuration.baudRate) == -1) {
|
||||
LOGGER.error("[{}] Failed to set input speed", configuration.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UartPosix::awaitAvailable(TickType_t timeout) {
|
||||
auto start_time = kernel::getTicks();
|
||||
do {
|
||||
if (available(timeout) > 0) {
|
||||
return true;
|
||||
}
|
||||
kernel::delayTicks(timeout / 10);
|
||||
} while ((kernel::getTicks() - start()) < timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<Uart> create(const Configuration& configuration) {
|
||||
return std::make_unique<UartPosix>(configuration);
|
||||
}
|
||||
|
||||
} // namespace tt::hal::uart
|
||||
|
||||
#endif
|
||||
@ -9,6 +9,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* WARNING: THIS API IS NON-FUNCTIONAL AND DEPRECATED.
|
||||
* IT WILL BE REMOVED IN A FUTURE RELEASE ONCE OFFICIAL APPS ARE MIGRATED.
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file tt_hal_uart.h
|
||||
* @brief C HAL interface for UART devices used by Tactility C modules.
|
||||
|
||||
@ -1,84 +1,61 @@
|
||||
#include "tt_hal_uart.h"
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
struct UartWrapper {
|
||||
std::shared_ptr<uart::Uart> uart;
|
||||
};
|
||||
|
||||
#define HANDLE_AS_UART(handle) static_cast<UartWrapper*>(handle)->uart
|
||||
|
||||
extern "C" {
|
||||
|
||||
size_t tt_hal_uart_get_count() {
|
||||
return uart::getNames().size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tt_hal_uart_get_name(size_t index, char* name, size_t nameSizeLimit) {
|
||||
assert(index < uart::getNames().size());
|
||||
auto source_name = uart::getNames()[index];
|
||||
return strncpy(name, source_name.c_str(), nameSizeLimit) != nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
UartHandle tt_hal_uart_alloc(size_t index) {
|
||||
assert(index < uart::getNames().size());
|
||||
auto* wrapper = new UartWrapper();
|
||||
auto name = uart::getNames()[index];
|
||||
wrapper->uart = uart::open(name);
|
||||
assert(wrapper->uart != nullptr);
|
||||
return wrapper;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void tt_hal_uart_free(UartHandle handle) {
|
||||
auto* wrapper = static_cast<UartWrapper*>(handle);
|
||||
assert(wrapper->uart != nullptr);
|
||||
if (wrapper->uart->isStarted()) {
|
||||
wrapper->uart->stop();
|
||||
}
|
||||
delete wrapper;
|
||||
}
|
||||
|
||||
bool tt_hal_uart_start(UartHandle handle) {
|
||||
return HANDLE_AS_UART(handle)->start();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tt_hal_uart_is_started(UartHandle handle) {
|
||||
return HANDLE_AS_UART(handle)->isStarted();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tt_hal_uart_stop(UartHandle handle) {
|
||||
return HANDLE_AS_UART(handle)->stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t tt_hal_uart_read_bytes(UartHandle handle, char* buffer, size_t bufferSize, TickType_t timeout) {
|
||||
return HANDLE_AS_UART(handle)->readBytes(reinterpret_cast<std::byte*>(buffer), bufferSize, timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tt_hal_uart_read_byte(UartHandle handle, char* output, TickType_t timeout) {
|
||||
return HANDLE_AS_UART(handle)->readByte(reinterpret_cast<std::byte*>(output), timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t tt_hal_uart_write_bytes(UartHandle handle, const char* buffer, size_t bufferSize, TickType_t timeout) {
|
||||
return HANDLE_AS_UART(handle)->writeBytes(reinterpret_cast<const std::byte*>(buffer), bufferSize, timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tt_hal_uart_available(UartHandle handle) {
|
||||
return HANDLE_AS_UART(handle)->available();
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tt_hal_uart_set_baud_rate(UartHandle handle, size_t baud_rate) {
|
||||
return HANDLE_AS_UART(handle)->setBaudRate(baud_rate);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t tt_hal_uart_get_baud_rate(UartHandle handle) {
|
||||
return HANDLE_AS_UART(handle)->getBaudRate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tt_hal_uart_flush_input(UartHandle handle) {
|
||||
HANDLE_AS_UART(handle)->flushInput();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user