Add BT1035 driver with manual chapter and expand Si4684 tuning docs.
Implement Bt1035Driver AT init (AT+AUXCFG=1), core AT parser with host tests, wire boot into HardwareBootstrap, and document DAB/FM tuning workflows in ch-si4684. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -22,6 +22,7 @@ idf_component_register(
|
||||
"src/EnhancementsDesign.cpp"
|
||||
"src/AudioProfile.cpp"
|
||||
"src/AudioProfileJson.cpp"
|
||||
"src/Bt1035At.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @file Bt1035At.hpp
|
||||
* @brief Typed AT command builder and response parser for FSC-BT1035.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/ParseError.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace core {
|
||||
|
||||
/**
|
||||
* @brief Bt1035AtCommand — supported AT commands (enumerated subset).
|
||||
*
|
||||
* @dname Bt1035AtCommand
|
||||
* @return n/a (type)
|
||||
* @pubstate Each variant maps to one line via buildBt1035AtLine().
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
enum class Bt1035AtCommand {
|
||||
Ping, ///< AT — link check.
|
||||
AuxLineIn, ///< AT+AUXCFG=1 — wired Line-In from ADAU1701 (mandatory).
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Bt1035AtResponseKind — parsed module reply class.
|
||||
*
|
||||
* @dname Bt1035AtResponseKind
|
||||
* @return n/a (type)
|
||||
* @pubstate Unknown payloads map to Unexpected, never ignored.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
enum class Bt1035AtResponseKind {
|
||||
Ok,
|
||||
Error,
|
||||
Unexpected,
|
||||
};
|
||||
|
||||
/** Number of commands in bootInitSequence(). */
|
||||
inline constexpr std::size_t kBt1035BootInitCommandCount = 2U;
|
||||
|
||||
/**
|
||||
* @brief buildBt1035AtLine — serialise a command with CRLF terminator.
|
||||
*
|
||||
* @dname buildBt1035AtLine
|
||||
* @param command Typed AT command.
|
||||
* @return Full line including \r\n suffix.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::string buildBt1035AtLine(Bt1035AtCommand command);
|
||||
|
||||
/**
|
||||
* @brief bootInitSequence — mandatory bring-up commands in order.
|
||||
*
|
||||
* @dname bootInitSequence
|
||||
* @return Ping then AuxLineIn (AT+AUXCFG=1).
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::array<Bt1035AtCommand, kBt1035BootInitCommandCount>
|
||||
bootInitSequence() noexcept;
|
||||
|
||||
/**
|
||||
* @brief parseBt1035AtResponse — classify a single response line.
|
||||
*
|
||||
* @dname parseBt1035AtResponse
|
||||
* @param line Untrusted UART payload (may include whitespace).
|
||||
* @return Ok, Error, or Unexpected.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] Bt1035AtResponseKind parseBt1035AtResponse(
|
||||
std::string_view line) noexcept;
|
||||
|
||||
} // namespace core
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file Bt1035At.cpp
|
||||
* @brief Bt1035At implementation.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
#include "core/Bt1035At.hpp"
|
||||
|
||||
namespace core {
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] std::string_view trimAscii(std::string_view text) noexcept
|
||||
{
|
||||
while (!text.empty()
|
||||
&& (text.front() == ' ' || text.front() == '\r'
|
||||
|| text.front() == '\n' || text.front() == '\t')) {
|
||||
text.remove_prefix(1U);
|
||||
}
|
||||
while (!text.empty()
|
||||
&& (text.back() == ' ' || text.back() == '\r' || text.back() == '\n'
|
||||
|| text.back() == '\t')) {
|
||||
text.remove_suffix(1U);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string buildBt1035AtLine(Bt1035AtCommand command)
|
||||
{
|
||||
switch (command) {
|
||||
case Bt1035AtCommand::Ping:
|
||||
return "AT\r\n";
|
||||
case Bt1035AtCommand::AuxLineIn:
|
||||
return "AT+AUXCFG=1\r\n";
|
||||
}
|
||||
return "AT\r\n";
|
||||
}
|
||||
|
||||
std::array<Bt1035AtCommand, kBt1035BootInitCommandCount> bootInitSequence() noexcept
|
||||
{
|
||||
return std::array<Bt1035AtCommand, kBt1035BootInitCommandCount>{
|
||||
Bt1035AtCommand::Ping,
|
||||
Bt1035AtCommand::AuxLineIn,
|
||||
};
|
||||
}
|
||||
|
||||
Bt1035AtResponseKind parseBt1035AtResponse(std::string_view line) noexcept
|
||||
{
|
||||
const std::string_view trimmed = trimAscii(line);
|
||||
if (trimmed == "OK") {
|
||||
return Bt1035AtResponseKind::Ok;
|
||||
}
|
||||
if (trimmed == "ERROR" || trimmed.starts_with("ERROR")) {
|
||||
return Bt1035AtResponseKind::Error;
|
||||
}
|
||||
return Bt1035AtResponseKind::Unexpected;
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
@@ -34,6 +34,7 @@ add_library(digiradio_core STATIC
|
||||
"${CORE_SRC_DIR}/EnhancementsDesign.cpp"
|
||||
"${CORE_SRC_DIR}/AudioProfile.cpp"
|
||||
"${CORE_SRC_DIR}/AudioProfileJson.cpp"
|
||||
"${CORE_SRC_DIR}/Bt1035At.cpp"
|
||||
)
|
||||
target_include_directories(digiradio_core PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include"
|
||||
@@ -70,3 +71,7 @@ add_test(NAME audio_profile_json_test COMMAND audio_profile_json_test)
|
||||
add_executable(enhancements_design_test enhancements_design_test.cpp)
|
||||
target_link_libraries(enhancements_design_test PRIVATE digiradio_core)
|
||||
add_test(NAME enhancements_design_test COMMAND enhancements_design_test)
|
||||
|
||||
add_executable(bt1035_at_test bt1035_at_test.cpp)
|
||||
target_link_libraries(bt1035_at_test PRIVATE digiradio_core)
|
||||
add_test(NAME bt1035_at_test COMMAND bt1035_at_test)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file bt1035_at_test.cpp
|
||||
* @brief Host tests for FSC-BT1035 AT command builder and parser.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
#include "core/Bt1035At.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] int runInitSequenceTest()
|
||||
{
|
||||
const auto sequence = core::bootInitSequence();
|
||||
if (sequence.size() != core::kBt1035BootInitCommandCount) {
|
||||
std::cerr << "init sequence size mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (sequence[1U] != core::Bt1035AtCommand::AuxLineIn) {
|
||||
std::cerr << "AUXCFG=1 must be in init sequence\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const std::string aux = core::buildBt1035AtLine(core::Bt1035AtCommand::AuxLineIn);
|
||||
if (aux != "AT+AUXCFG=1\r\n") {
|
||||
std::cerr << "AUXCFG command line mismatch\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
[[nodiscard]] int runParseTest()
|
||||
{
|
||||
if (core::parseBt1035AtResponse("OK\r\n") != core::Bt1035AtResponseKind::Ok) {
|
||||
std::cerr << "OK parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (core::parseBt1035AtResponse("ERROR\r\n")
|
||||
!= core::Bt1035AtResponseKind::Error) {
|
||||
std::cerr << "ERROR parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (core::parseBt1035AtResponse("garbage")
|
||||
!= core::Bt1035AtResponseKind::Unexpected) {
|
||||
std::cerr << "unexpected parse failed\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
if (runInitSequenceTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (runParseTest() != EXIT_SUCCESS) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
idf_component_register(
|
||||
SRCS "src/component_stub.cpp"
|
||||
SRCS "src/Bt1035Driver.cpp"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES core driver esp_driver_gpio esp_driver_uart
|
||||
)
|
||||
|
||||
target_compile_features(${COMPONENT_LIB} PUBLIC cxx_std_23)
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* @file Bt1035Driver.hpp
|
||||
* @brief FSC-BT1035 Bluetooth transmitter — UART AT control.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "bt1035/Bt1035Error.hpp"
|
||||
|
||||
#include "core/Bt1035At.hpp"
|
||||
|
||||
#include <expected>
|
||||
|
||||
namespace bt1035 {
|
||||
|
||||
/**
|
||||
* @brief Bt1035Pins — board GPIO/UART identifiers for the module.
|
||||
*
|
||||
* @dname Bt1035Pins
|
||||
* @return n/a (type)
|
||||
* @pubstate Immutable wiring snapshot from board_pins.hpp.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
struct Bt1035Pins {
|
||||
int uartTx; ///< ESP32 TX -> module RX.
|
||||
int uartRx; ///< ESP32 RX <- module TX.
|
||||
int rtsGpio; ///< RTS (flow control).
|
||||
int ctsGpio; ///< CTS (flow control).
|
||||
int resetGpio; ///< Module RESET (active level per schematic).
|
||||
int sysCtlGpio; ///< SYS_CTL (optional module enable).
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Bt1035Driver — owns UART + reset, runs mandatory AT init.
|
||||
*
|
||||
* @dname Bt1035Driver
|
||||
* @return n/a (type)
|
||||
* @pubstate Owns UART port after boot(). booted_ true after init sequence
|
||||
* including AT+AUXCFG=1 (Line-In from ADAU1701).
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
class Bt1035Driver {
|
||||
public:
|
||||
/**
|
||||
* @brief Bt1035Driver — construct with board pin map.
|
||||
*
|
||||
* @dname Bt1035Driver
|
||||
* @param pins UART, flow control, reset, SYS_CTL wiring.
|
||||
* @pubstate stores pins_; not booted until boot().
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
explicit Bt1035Driver(Bt1035Pins pins);
|
||||
|
||||
/**
|
||||
* @brief ~Bt1035Driver — release UART resources.
|
||||
*
|
||||
* @dname ~Bt1035Driver
|
||||
* @pubstate deletes UART driver when installed.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
~Bt1035Driver();
|
||||
|
||||
Bt1035Driver(const Bt1035Driver&) = delete;
|
||||
Bt1035Driver& operator=(const Bt1035Driver&) = delete;
|
||||
|
||||
/**
|
||||
* @brief boot — reset module and run mandatory AT init sequence.
|
||||
*
|
||||
* @dname boot
|
||||
* @return Ok on success, or Bt1035Error.
|
||||
* @pubstate sets booted_ after Ping + AT+AUXCFG=1 both return OK.
|
||||
*
|
||||
* Sequence: hardware reset, UART @ 115200 with RTS/CTS, then
|
||||
* core::bootInitSequence() (Chapter~\ref{ch:bt1035}).
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Bt1035Error> boot();
|
||||
|
||||
/**
|
||||
* @brief isBooted — query whether Line-In init succeeded.
|
||||
*
|
||||
* @dname isBooted
|
||||
* @return true after successful boot().
|
||||
* @pubstate reads booted_.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] bool isBooted() const noexcept;
|
||||
|
||||
/**
|
||||
* @brief sendCommand — transmit one typed AT command and expect OK.
|
||||
*
|
||||
* @dname sendCommand
|
||||
* @param command Enumerated AT command.
|
||||
* @return Ok on OK response, or Bt1035Error.
|
||||
* @pubstate writes UART; reads until OK/ERROR/timeout.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Bt1035Error> sendCommand(
|
||||
core::Bt1035AtCommand command);
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::expected<void, Bt1035Error> ensureBooted() const;
|
||||
[[nodiscard]] std::expected<void, Bt1035Error> runInitSequence();
|
||||
[[nodiscard]] std::expected<void, Bt1035Error> transmitAndExpectOk(
|
||||
std::string_view commandLine);
|
||||
|
||||
Bt1035Pins pins_;
|
||||
bool booted_;
|
||||
bool uartInstalled_;
|
||||
int uartPort_;
|
||||
};
|
||||
|
||||
} // namespace bt1035
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file Bt1035Error.hpp
|
||||
* @brief Typed errors for FSC-BT1035 driver operations.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace bt1035 {
|
||||
|
||||
/**
|
||||
* @brief Bt1035Error — failure causes for BT1035 bring-up and AT I/O.
|
||||
*
|
||||
* @dname Bt1035Error
|
||||
* @return n/a (type)
|
||||
* @pubstate n/a
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
enum class Bt1035Error {
|
||||
ResetFailed,
|
||||
UartInitFailed,
|
||||
NotBooted,
|
||||
AtTimeout,
|
||||
AtError,
|
||||
UnexpectedResponse,
|
||||
};
|
||||
|
||||
} // namespace bt1035
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @file Bt1035Driver.cpp
|
||||
* @brief Bt1035Driver implementation.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
#include "bt1035/Bt1035Driver.hpp"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace bt1035 {
|
||||
|
||||
namespace {
|
||||
constexpr char kTag[] = "Bt1035";
|
||||
constexpr int kUartPort = 2;
|
||||
constexpr int kBaudRate = 115200;
|
||||
constexpr int kUartRxBuffer = 512;
|
||||
constexpr int kUartTxBuffer = 256;
|
||||
constexpr int kResponseTimeoutMs = 2000;
|
||||
constexpr int kPostResetMs = 300;
|
||||
constexpr int kPostUartMs = 100;
|
||||
} // namespace
|
||||
|
||||
Bt1035Driver::Bt1035Driver(Bt1035Pins pins)
|
||||
: pins_(pins)
|
||||
, booted_(false)
|
||||
, uartInstalled_(false)
|
||||
, uartPort_(kUartPort)
|
||||
{
|
||||
}
|
||||
|
||||
Bt1035Driver::~Bt1035Driver()
|
||||
{
|
||||
if (uartInstalled_) {
|
||||
uart_driver_delete(static_cast<uart_port_t>(uartPort_));
|
||||
uartInstalled_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Bt1035Driver::isBooted() const noexcept
|
||||
{
|
||||
return booted_;
|
||||
}
|
||||
|
||||
std::expected<void, Bt1035Error> Bt1035Driver::ensureBooted() const
|
||||
{
|
||||
if (!booted_) {
|
||||
return std::unexpected(Bt1035Error::NotBooted);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Bt1035Error> Bt1035Driver::transmitAndExpectOk(
|
||||
std::string_view commandLine)
|
||||
{
|
||||
const int written = uart_write_bytes(static_cast<uart_port_t>(uartPort_),
|
||||
commandLine.data(),
|
||||
commandLine.size());
|
||||
if (written < 0
|
||||
|| static_cast<std::size_t>(written) != commandLine.size()) {
|
||||
return std::unexpected(Bt1035Error::UartInitFailed);
|
||||
}
|
||||
|
||||
std::array<char, 128> buffer{};
|
||||
std::string accumulated;
|
||||
const TickType_t deadline =
|
||||
xTaskGetTickCount() + pdMS_TO_TICKS(kResponseTimeoutMs);
|
||||
|
||||
while (xTaskGetTickCount() < deadline) {
|
||||
const int received = uart_read_bytes(static_cast<uart_port_t>(uartPort_),
|
||||
buffer.data(), buffer.size(),
|
||||
pdMS_TO_TICKS(50));
|
||||
if (received > 0) {
|
||||
accumulated.append(buffer.data(), static_cast<std::size_t>(received));
|
||||
const core::Bt1035AtResponseKind kind =
|
||||
core::parseBt1035AtResponse(accumulated);
|
||||
if (kind == core::Bt1035AtResponseKind::Ok) {
|
||||
return {};
|
||||
}
|
||||
if (kind == core::Bt1035AtResponseKind::Error) {
|
||||
return std::unexpected(Bt1035Error::AtError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(Bt1035Error::AtTimeout);
|
||||
}
|
||||
|
||||
std::expected<void, Bt1035Error> Bt1035Driver::sendCommand(
|
||||
core::Bt1035AtCommand command)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
return transmitAndExpectOk(core::buildBt1035AtLine(command));
|
||||
}
|
||||
|
||||
std::expected<void, Bt1035Error> Bt1035Driver::runInitSequence()
|
||||
{
|
||||
for (const core::Bt1035AtCommand command : core::bootInitSequence()) {
|
||||
if (auto result = transmitAndExpectOk(core::buildBt1035AtLine(command));
|
||||
!result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Bt1035Error> Bt1035Driver::boot()
|
||||
{
|
||||
if (booted_) {
|
||||
return {};
|
||||
}
|
||||
|
||||
gpio_config_t resetCfg = {};
|
||||
resetCfg.pin_bit_mask = 1ULL << pins_.resetGpio;
|
||||
resetCfg.mode = GPIO_MODE_OUTPUT;
|
||||
if (gpio_config(&resetCfg) != ESP_OK) {
|
||||
return std::unexpected(Bt1035Error::ResetFailed);
|
||||
}
|
||||
|
||||
gpio_config_t sysCfg = {};
|
||||
sysCfg.pin_bit_mask = 1ULL << pins_.sysCtlGpio;
|
||||
sysCfg.mode = GPIO_MODE_OUTPUT;
|
||||
if (gpio_config(&sysCfg) != ESP_OK) {
|
||||
return std::unexpected(Bt1035Error::ResetFailed);
|
||||
}
|
||||
|
||||
gpio_set_level(static_cast<gpio_num_t>(pins_.sysCtlGpio), 1);
|
||||
gpio_set_level(static_cast<gpio_num_t>(pins_.resetGpio), 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
gpio_set_level(static_cast<gpio_num_t>(pins_.resetGpio), 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(kPostResetMs));
|
||||
|
||||
if (!uartInstalled_) {
|
||||
const uart_config_t uartCfg = {
|
||||
.baud_rate = kBaudRate,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
|
||||
.rx_flow_ctrl_thresh = 122,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
|
||||
if (uart_driver_install(static_cast<uart_port_t>(uartPort_), kUartRxBuffer,
|
||||
kUartTxBuffer, 0, nullptr, 0)
|
||||
!= ESP_OK) {
|
||||
return std::unexpected(Bt1035Error::UartInitFailed);
|
||||
}
|
||||
|
||||
if (uart_param_config(static_cast<uart_port_t>(uartPort_), &uartCfg)
|
||||
!= ESP_OK) {
|
||||
return std::unexpected(Bt1035Error::UartInitFailed);
|
||||
}
|
||||
|
||||
if (uart_set_pin(static_cast<uart_port_t>(uartPort_), pins_.uartTx,
|
||||
pins_.uartRx, pins_.rtsGpio, pins_.ctsGpio)
|
||||
!= ESP_OK) {
|
||||
return std::unexpected(Bt1035Error::UartInitFailed);
|
||||
}
|
||||
|
||||
uartInstalled_ = true;
|
||||
}
|
||||
|
||||
uart_flush_input(static_cast<uart_port_t>(uartPort_));
|
||||
vTaskDelay(pdMS_TO_TICKS(kPostUartMs));
|
||||
|
||||
if (auto init = runInitSequence(); !init) {
|
||||
ESP_LOGE(kTag, "AT init failed");
|
||||
return init;
|
||||
}
|
||||
|
||||
booted_ = true;
|
||||
ESP_LOGI(kTag, "Line-In mode enabled (AT+AUXCFG=1)");
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace bt1035
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* @file component_stub.cpp
|
||||
* @brief FSC-BT1035 driver component placeholder (Slice 6).
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
namespace bt1035::detail {
|
||||
|
||||
/**
|
||||
* @brief bt1035ComponentLinked — ensures the driver component links.
|
||||
*
|
||||
* @dname bt1035ComponentLinked
|
||||
* @return n/a (type)
|
||||
* @pubstate n/a
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
void bt1035ComponentLinked() noexcept {}
|
||||
|
||||
} // namespace bt1035::detail
|
||||
Reference in New Issue
Block a user