Release fw 0.8.5: BT1035 I2S boot init and hardware doc alignment.

Switch BT1035 bring-up from Line-In to I2S slave (AT+AUXCFG=3, AT+I2SCFG=67) to match the ADAU1701 PCM routing, confirm 2 kΩ I2C pull-ups on R1/R16, and sync firmware docs, AGENTS rules, and the DATASHEET bundle.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 14:41:31 +02:00
co-authored by Cursor
parent 3e46b06d4b
commit 0a1188ad66
22 changed files with 244 additions and 125 deletions
@@ -37,7 +37,8 @@ namespace core {
*/
enum class Bt1035AtCommand {
Ping, ///< AT — link check.
AuxLineIn, ///< AT+AUXCFG=1wired Line-In from ADAU1701 (mandatory).
I2sMode, ///< AT+AUXCFG=3I2S input from ADAU1701 (mandatory).
I2sSlave48k32, ///< AT+I2SCFG=67 — I2S slave 48 kHz 32-bit (§5.1.4).
PairDiscoverable, ///< AT+PAIR=1 — enter BR/EDR/BLE discoverable mode.
PairHidden, ///< AT+PAIR=0 — leave discoverable mode.
A2dpStat, ///< AT+A2DPSTAT — read A2DP link state.
@@ -83,7 +84,10 @@ enum class Bt1035AtResponseKind {
};
/** Number of commands in bootInitSequence(). */
inline constexpr std::size_t kBt1035BootInitCommandCount = 2U;
inline constexpr std::size_t kBt1035BootInitCommandCount = 3U;
/** Feasycom programming guide §5.1.4: I2S slave, 48 kHz, 32-bit. */
inline constexpr std::uint8_t kBt1035I2sSlave48k32Param = 67U;
/**
* @brief buildBt1035AtLine — serialise a command with CRLF terminator.
@@ -102,7 +106,7 @@ inline constexpr std::size_t kBt1035BootInitCommandCount = 2U;
* @brief bootInitSequence — mandatory bring-up commands in order.
*
* @dname bootInitSequence
* @return Ping then AuxLineIn (AT+AUXCFG=1).
* @return Ping, I2sMode (AUXCFG=3), I2sSlave48k32 (I2SCFG=67).
* @pubstate none
*
* @author Michele Bigi
@@ -165,6 +169,21 @@ parseBt1035A2dpStatResponse(std::string_view response);
*/
[[nodiscard]] std::string buildBt1035SetAutoConnLine(std::uint8_t times);
/**
* @brief buildBt1035SetNameLine — AT+NAME with optional MAC suffix flag.
*
* @dname buildBt1035SetNameLine
* @param name BR/EDR local name (1--31 ASCII bytes per Feasycom §5.1.16).
* @param enableMacSuffix false sends Param2=0 (disable module suffix).
* @return Full AT line including CRLF.
* @pubstate none
*
* @author Michele Bigi
* @date 2026-07-08
*/
[[nodiscard]] std::string buildBt1035SetNameLine(std::string_view name,
bool enableMacSuffix = false);
/**
* @brief parseBt1035NameResponse — extract +NAME= value.
*
@@ -27,7 +27,7 @@ namespace core {
struct CompanionChipStatus {
bool si4684Ready; ///< Si4684 HOST_LOAD completed.
bool adau1701Ready; ///< ADAU1701 SigmaStudio download completed.
bool bt1035Ready; ///< BT1035 Line-In init (AT+AUXCFG=1) completed.
bool bt1035Ready; ///< BT1035 I2S init (AUXCFG=3 + I2SCFG=67) completed.
};
} // namespace core
+15 -3
View File
@@ -101,8 +101,10 @@ std::string buildBt1035AtLine(Bt1035AtCommand command)
switch (command) {
case Bt1035AtCommand::Ping:
return "AT\r\n";
case Bt1035AtCommand::AuxLineIn:
return "AT+AUXCFG=1\r\n";
case Bt1035AtCommand::I2sMode:
return "AT+AUXCFG=3\r\n";
case Bt1035AtCommand::I2sSlave48k32:
return "AT+I2SCFG=67\r\n";
case Bt1035AtCommand::PairDiscoverable:
return "AT+PAIR=1\r\n";
case Bt1035AtCommand::PairHidden:
@@ -129,11 +131,21 @@ std::string buildBt1035SetAutoConnLine(std::uint8_t times)
return "AT+AUTOCONN=" + std::to_string(times) + "\r\n";
}
std::string buildBt1035SetNameLine(std::string_view name, bool enableMacSuffix)
{
if (name.empty() || name.size() > 31U) {
return {};
}
return std::string("AT+NAME=") + std::string(name) + ","
+ (enableMacSuffix ? "1" : "0") + "\r\n";
}
std::array<Bt1035AtCommand, kBt1035BootInitCommandCount> bootInitSequence() noexcept
{
return std::array<Bt1035AtCommand, kBt1035BootInitCommandCount>{
Bt1035AtCommand::Ping,
Bt1035AtCommand::AuxLineIn,
Bt1035AtCommand::I2sMode,
Bt1035AtCommand::I2sSlave48k32,
};
}
@@ -28,13 +28,24 @@ namespace {
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";
if (sequence[1U] != core::Bt1035AtCommand::I2sMode) {
std::cerr << "I2S mode 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";
if (sequence[2U] != core::Bt1035AtCommand::I2sSlave48k32) {
std::cerr << "I2SCFG must be in init sequence\n";
return EXIT_FAILURE;
}
const std::string i2sMode =
core::buildBt1035AtLine(core::Bt1035AtCommand::I2sMode);
if (i2sMode != "AT+AUXCFG=3\r\n") {
std::cerr << "AUXCFG=3 command line mismatch\n";
return EXIT_FAILURE;
}
const std::string i2sCfg =
core::buildBt1035AtLine(core::Bt1035AtCommand::I2sSlave48k32);
if (i2sCfg != "AT+I2SCFG=67\r\n") {
std::cerr << "I2SCFG=67 command line mismatch\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
@@ -117,6 +128,11 @@ namespace {
std::cerr << "AUTOCONN command line mismatch\n";
return EXIT_FAILURE;
}
if (core::buildBt1035SetNameLine("DigiRadio-A1B2", false)
!= "AT+NAME=DigiRadio-A1B2,0\r\n") {
std::cerr << "NAME set command line mismatch\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
@@ -48,7 +48,7 @@ struct Bt1035Pins {
* @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).
* including AT+AUXCFG=3 and AT+I2SCFG=67 (I2S slave from ADAU1701).
*
* @author Michele Bigi
* @date 2026-07-06
@@ -86,7 +86,7 @@ public:
*
* @dname boot
* @return Ok on success, or Bt1035Error.
* @pubstate sets booted_ after Ping + AT+AUXCFG=1 both return OK.
* @pubstate sets booted_ after Ping + I2S init both return OK.
*
* Sequence: hardware reset, UART @ 115200 with RTS/CTS, then
* core::bootInitSequence() (see manual chapter bt1035).
@@ -97,7 +97,7 @@ public:
[[nodiscard]] std::expected<void, Bt1035Error> boot();
/**
* @brief isBooted — query whether Line-In init succeeded.
* @brief isBooted — query whether I2S init succeeded.
*
* @dname isBooted
* @return true after successful boot().
@@ -177,7 +177,7 @@ public:
* @dname setDeviceName
* @param name Bluetooth name (Feasycom FSC-BT1035 AT+NAME command).
* @return Ok on success, or Bt1035Error.
* @pubstate sends AT+NAME after boot; does not alter AT+AUXCFG=1 init.
* @pubstate sends AT+NAME after boot; does not alter I2S init sequence.
*
* @author Michele Bigi
* @date 2026-07-07
@@ -169,10 +169,14 @@ std::expected<void, Bt1035Error> Bt1035Driver::setDeviceName(
if (auto ready = ensureBooted(); !ready) {
return ready;
}
if (name.empty() || name.size() > 32U) {
if (name.empty() || name.size() > 31U) {
return std::unexpected(Bt1035Error::UnexpectedResponse);
}
const std::string line =
core::buildBt1035SetNameLine(name, false);
if (line.empty()) {
return std::unexpected(Bt1035Error::UnexpectedResponse);
}
std::string line = std::string("AT+NAME=") + std::string(name) + "\r\n";
return transmitAndExpectOk(line);
}
@@ -315,7 +319,7 @@ std::expected<void, Bt1035Error> Bt1035Driver::boot()
}
booted_ = true;
ESP_LOGI(kTag, "Line-In mode enabled (AT+AUXCFG=1)");
ESP_LOGI(kTag, "I2S slave mode enabled (AT+AUXCFG=3, AT+I2SCFG=67)");
return {};
}
@@ -60,7 +60,7 @@ namespace net {
namespace {
constexpr char kTag[] = "SetupWebServer";
constexpr char kFirmwareVersion[] = "0.8.4";
constexpr char kFirmwareVersion[] = "0.8.5";
constexpr unsigned kRebootDelaySec = 3;
extern const uint8_t www_index_html_gz_start[] asm(