Bluetooth jdy33: save some memory (#4848)

* bluetooth: remove bluetooth_cancel command

No need. In case of error setup process will be canceled.

* bluetooth: no need to have separate thread for setup

Use same TinerStudio thread.

* bluetooth: pass tsChannel as argument

* bluetooth: use struct for baudrate - parameter table

* bluetooth: query MAC address if debug is enabled
This commit is contained in:
Andrey G 2022-11-27 22:43:54 +03:00 committed by GitHub
parent 8ea5969607
commit 57c5ff6420
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 125 deletions

View File

@ -26,7 +26,7 @@
#define EFI_BLUETOOTH_SETUP_DEBUG TRUE
#endif
static bool btProcessIsStarted = false;
static volatile bool btSetupIsRequested = false;
bluetooth_module_e btModuleType;
static int setBaudIdx = -1;
@ -34,17 +34,23 @@ static char btName[20 + 1];
static char btPinCode[4 + 1];
// JDY-33 has 9: 128000 which we do not
static const unsigned int baudRates[] = { 115200, 9600, 38400, 2400, 4800, 19200, 57600 };
static const unsigned int baudRateCodes[] = { 8, 4, 6, 2, 3, 5, 7 };
static const struct {
uint32_t rate;
uint8_t code;
} baudRates[] = {
//most popular first
{115200, 8},
{9600, 4},
{38400, 6},
{2400, 2},
{4800, 3},
{19200, 5},
{57600, 7}
};
static const int btModuleTimeout = TIME_MS2I(500);
static SerialTsChannelBase *tsChannel;
static THD_WORKING_AREA(btThreadStack, UTILITY_THREAD_STACK_SIZE);
static thread_t *btThread = nullptr;
static thread_reference_t btThreadRef = nullptr; // used by thread suspend/resume as a flag
static void btWrite(const char *str)
static void btWrite(TsChannelBase* tsChannel, const char *str)
{
/* Just a wrapper for debug purposes */
#if EFI_BLUETOOTH_SETUP_DEBUG
@ -53,7 +59,7 @@ static void btWrite(const char *str)
tsChannel->write((uint8_t *)str, strlen(str));
}
static int btReadLine(char *str, size_t max_len)
static int btReadLine(TsChannelBase* tsChannel, char *str, size_t max_len)
{
size_t len = 0;
@ -84,14 +90,14 @@ static int btReadLine(char *str, size_t max_len)
return len;
}
static int btWaitOk(void)
static int btWaitOk(SerialTsChannelBase* tsChannel)
{
int len;
int ret = -1;
char tmp[16];
/* wait for '+OK\r\n' */
len = btReadLine(tmp, sizeof(tmp));
len = btReadLine(tsChannel, tmp, sizeof(tmp));
if (len == 5) {
if (strncmp(tmp, "+OK", 3) == 0)
ret = 0;
@ -102,42 +108,34 @@ static int btWaitOk(void)
// Main communication code
// We assume that the user has disconnected the software before starting the code.
static void runCommands() {
static void runCommands(SerialTsChannelBase* tsChannel) {
char tmp[64];
size_t baudIdx = 0;
bool baudFound = false;
if (!btProcessIsStarted)
return;
efiPrintf("Sleeping...");
chThdSleepMilliseconds(1000); // safety
// find current baudrate
while (baudFound == false) {
tsChannel->stop();
chThdSleepMilliseconds(10); // safety
if (chThdShouldTerminateX() || (baudIdx == efi::size(baudRates))) {
if (baudIdx == efi::size(baudRates)) {
efiPrintf("Failed to find current BT module baudrate");
}
if (baudIdx == efi::size(baudRates)) {
efiPrintf("Failed to find current BT module baudrate");
tsChannel->start(engineConfiguration->tunerStudioSerialSpeed);
return;
}
efiPrintf("Restarting at %d", baudRates[baudIdx]);
tsChannel->start(baudRates[baudIdx]);
efiPrintf("Restarting at %d", baudRates[baudIdx].rate);
tsChannel->start(baudRates[baudIdx].rate);
chThdSleepMilliseconds(10); // safety
/* Ping BT module */
btWrite("AT\r\n");
if (btWaitOk() == 0) {
btWrite(tsChannel, "AT\r\n");
if (btWaitOk(tsChannel) == 0) {
baudFound = true;
} else if (btModuleType == BLUETOOTH_JDY_3x) {
/* try to diconnect in case device already configured and in silence mode */
btWrite("AT+DISC\r\n");
if (btWaitOk() == 0) {
btWrite(tsChannel, "AT+DISC\r\n");
if (btWaitOk(tsChannel) == 0) {
efiPrintf("JDY33 disconnected");
chThdSleepMilliseconds(10); // safety
baudFound = true;
@ -151,60 +149,63 @@ static void runCommands() {
if (btModuleType == BLUETOOTH_JDY_3x) {
#if EFI_BLUETOOTH_SETUP_DEBUG
/* Debug, get version, current settings */
btWrite("AT+VERSION\r\n");
btReadLine(tmp, sizeof(tmp));
btWrite(tsChannel, "AT+VERSION\r\n");
btReadLine(tsChannel, tmp, sizeof(tmp));
btWrite("AT+BAUD\r\n");
btReadLine(tmp, sizeof(tmp));
btWrite(tsChannel, "AT+BAUD\r\n");
btReadLine(tsChannel, tmp, sizeof(tmp));
btWrite("AT+TYPE\r\n");
btReadLine(tmp, sizeof(tmp));
btWrite(tsChannel, "AT+TYPE\r\n");
btReadLine(tsChannel, tmp, sizeof(tmp));
btWrite("AT+PIN\r\n");
btReadLine(tmp, sizeof(tmp));
btWrite(tsChannel, "AT+PIN\r\n");
btReadLine(tsChannel, tmp, sizeof(tmp));
btWrite(tsChannel, "AT+LADDR\r\n");
btReadLine(tsChannel, tmp, sizeof(tmp));
#endif
/* JDY33 specific settings */
/* Reset to defaults */
btWrite("AT+DEFAULT\r\n");
btWaitOk();
btWrite(tsChannel, "AT+DEFAULT\r\n");
btWaitOk(tsChannel);
/* No serial port status output */
btWrite("AT+ENLOG0\r\n");
btWaitOk();
btWrite(tsChannel, "AT+ENLOG0\r\n");
btWaitOk(tsChannel);
/* SPP connection with no password */
btWrite("AT+TYPE0\r\n");
btWaitOk();
btWrite(tsChannel, "AT+TYPE0\r\n");
btWaitOk(tsChannel);
}
if (btModuleType == BLUETOOTH_HC_05)
chsnprintf(tmp, sizeof(tmp), "AT+UART=%d,0,0\r\n", baudRates[setBaudIdx]); // baud rate, 0=(1 stop bit), 0=(no parity bits)
chsnprintf(tmp, sizeof(tmp), "AT+UART=%d,0,0\r\n", baudRates[setBaudIdx].rate); // baud rate, 0=(1 stop bit), 0=(no parity bits)
else
chsnprintf(tmp, sizeof(tmp), "AT+BAUD%d\r\n", baudRateCodes[setBaudIdx]);
btWrite(tmp);
if (btWaitOk() != 0) {
chsnprintf(tmp, sizeof(tmp), "AT+BAUD%d\r\n", baudRates[setBaudIdx].code);
btWrite(tsChannel, tmp);
if (btWaitOk(tsChannel) != 0) {
goto cmdFailed;
}
/* restart with new baud */
tsChannel->stop();
chThdSleepMilliseconds(10); // safety
tsChannel->start(baudRates[setBaudIdx]);
tsChannel->start(baudRates[setBaudIdx].rate);
if (btModuleType == BLUETOOTH_HC_05)
chsnprintf(tmp, sizeof(tmp), "AT+NAME=%s\r\n", btName);
else
chsnprintf(tmp, sizeof(tmp), "AT+NAME%s\r\n", btName);
btWrite(tmp);
if (btWaitOk() != 0) {
btWrite(tsChannel, tmp);
if (btWaitOk(tsChannel) != 0) {
goto cmdFailed;
}
if (btModuleType == BLUETOOTH_JDY_3x) {
/* BLE broadcast name */
chsnprintf(tmp, sizeof(tmp), "AT+NAMB%s\r\n", btName);
btWrite(tmp);
if (btWaitOk() != 0) {
btWrite(tsChannel, tmp);
if (btWaitOk(tsChannel) != 0) {
goto cmdFailed;
}
}
@ -214,15 +215,15 @@ static void runCommands() {
else
chsnprintf(tmp, sizeof(tmp), "AT+PIN%s\r\n", btPinCode);
btWrite(tmp);
if (btWaitOk() != 0) {
btWrite(tsChannel, tmp);
if (btWaitOk(tsChannel) != 0) {
goto cmdFailed;
}
if (btModuleType == BLUETOOTH_JDY_3x) {
/* Now reset module to apply new settings */
btWrite("AT+RESET\r\n");
if (btWaitOk() != 0) {
btWrite(tsChannel, "AT+RESET\r\n");
if (btWaitOk(tsChannel) != 0) {
efiPrintf("JDY33 fialed to reset");
}
}
@ -234,37 +235,6 @@ cmdFailed:
efiPrintf("FAIL! Command %s failed", tmp);
}
static THD_FUNCTION(btThreadEntryPoint, arg) {
(void) arg;
chRegSetThreadName("bluetooth thread");
efiPrintf("*** Bluetooth module setup procedure ***");
/* JDY33 supports disconnect on request */
if (btModuleType != BLUETOOTH_JDY_3x) {
efiPrintf("!Warning! Please make sure you're not currently using the BT module for communication (not paired)!");
efiPrintf("TO START THE PROCEDURE: PLEASE DISCONNECT YOUR PC COM-PORT FROM THE BOARD NOW!");
efiPrintf("After that please don't turn off the board power and wait for ~15 seconds to complete. Then reconnect to the board!");
}
// now wait
chSysLock();
btProcessIsStarted = true;
msg_t msg = chThdSuspendTimeoutS(&btThreadRef, BLUETOOTH_COMMAND_TIMEOUT);
chSysUnlock();
if (msg == MSG_TIMEOUT) {
// timeout waiting for silence on uart...
efiPrintf("The Bluetooth module init procedure is cancelled (timeout)!");
} else {
// call this when the thread is resumed (after the disconnect)
runCommands();
}
// release the command
btProcessIsStarted = false;
}
void bluetoothStart(bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode) {
static const char *usage = "Usage: bluetooth_<hc05/hc06/bk/jdy> <baud> <name> <pincode>";
@ -273,14 +243,13 @@ void bluetoothStart(bluetooth_module_e moduleType, const char *baudRate, const c
return;
}
tsChannel = getBluetoothChannel();
if (tsChannel == nullptr) {
if (getBluetoothChannel() == nullptr) {
efiPrintf("No Bluetooth channel configured! Check your board config.");
return;
}
if (btProcessIsStarted) {
efiPrintf("The Bluetooth module init procedure is already started and waiting! To cancel it, run \"bluetooth_cancel\" command!");
if (btSetupIsRequested) {
efiPrintf("The Bluetooth module init procedure is already started!");
return;
}
@ -290,7 +259,7 @@ void bluetoothStart(bluetooth_module_e moduleType, const char *baudRate, const c
// find a known baud rate in our list
setBaudIdx = -1;
for (size_t i = 0; i < efi::size(baudRates); i++) {
if (baudRates[i] == baud) {
if ((int)baudRates[i].rate == baud) {
setBaudIdx = i;
break;
}
@ -325,33 +294,31 @@ void bluetoothStart(bluetooth_module_e moduleType, const char *baudRate, const c
strncpy(btPinCode, pinCode, 4);
btModuleType = moduleType;
// create a thread to execute these commands after TS disconnected
// See bluetoothSoftwareDisconnectNotify
btThread = chThdCreateStatic(btThreadStack, sizeof(btThreadStack), PRIO_CONSOLE, (tfunc_t)btThreadEntryPoint, NULL);
btSetupIsRequested = true;
}
// Called after 1S of silence on BT UART...
void bluetoothSoftwareDisconnectNotify() {
if (btProcessIsStarted) {
// start communication with the module
chThdResume(&btThreadRef, MSG_OK);
// wait the thread to finish
chThdWait(btThread);
void bluetoothSoftwareDisconnectNotify(SerialTsChannelBase* tsChannel) {
if (btSetupIsRequested) {
efiPrintf("*** Bluetooth module setup procedure ***");
/* JDY33 supports disconnect on request */
if (btModuleType != BLUETOOTH_JDY_3x) {
efiPrintf("!Warning! Please make sure you're not currently using the BT module for communication (not paired)!");
efiPrintf("TO START THE PROCEDURE: PLEASE DISCONNECT YOUR PC COM-PORT FROM THE BOARD NOW!");
efiPrintf("After that please don't turn off the board power and wait for ~15 seconds to complete. Then reconnect to the board!");
}
uint8_t tmp[1];
if (tsChannel->readTimeout(tmp, 1, BLUETOOTH_SILENT_TIMEOUT) != 0) {
efiPrintf("The Bluetooth module init procedure is cancelled (wait for silent timeout)!");
btSetupIsRequested = false;
return;
}
runCommands(tsChannel);
btSetupIsRequested = false;
}
}
void bluetoothCancel() {
if (!btProcessIsStarted) {
efiPrintf("The Bluetooth module init procedure was not started! Nothing to cancel!");
return;
}
// terminate thread
chThdTerminate(btThread);
btProcessIsStarted = false;
efiPrintf("The Bluetooth module init procedure is cancelled!");
}
#endif /* EFI_BLUETOOTH_SETUP */

View File

@ -12,10 +12,10 @@
#include "tunerstudio_io.h"
// The Bluetooth setup procedure will wait 10 seconds for the user to disconnect the UART cable.
// The Bluetooth setup procedure will wait (TS_COMMUNICATION_TIMEOUT + 3) seconds for the user to disconnect BT.
// This is required because the BT setup procedure reads a response from the module during the communication.
// Thus any bytes sent from the Console Software may interfere with the procedure.
#define BLUETOOTH_COMMAND_TIMEOUT TIME_MS2I(10000)
#define BLUETOOTH_SILENT_TIMEOUT TIME_MS2I(3000)
// Supported Bluetooth module types
typedef enum {
@ -37,14 +37,9 @@ typedef enum {
*/
void bluetoothStart(bluetooth_module_e moduleType, const char *baudRate, const char *name, const char *pinCode);
/**
* Cancel Bluetooth procedure
*/
void bluetoothCancel(void);
/**
* Called by runBinaryProtocolLoop() if a connection disconnect is detected.
* Bluetooth init code needs to make sure that there's no interference of the BT module and USB-UART (connected to PC)
*/
void bluetoothSoftwareDisconnectNotify();
void bluetoothSoftwareDisconnectNotify(SerialTsChannelBase* tsChannel);

View File

@ -482,7 +482,7 @@ static int tsProcessOne(TsChannelBase* tsChannel) {
if (tsChannel == getBluetoothChannel()) {
// no data in a whole second means time to disconnect BT
// assume there's connection loss and notify the bluetooth init code
bluetoothSoftwareDisconnectNotify();
bluetoothSoftwareDisconnectNotify(getBluetoothChannel());
}
#endif /* EFI_BLUETOOTH_SETUP */
tsChannel->in_sync = false;
@ -838,7 +838,6 @@ void startTunerStudioConnectivity(void) {
addConsoleActionSSS("bluetooth_jdy", [](const char *baudRate, const char *name, const char *pinCode) {
bluetoothStart(BLUETOOTH_JDY_3x, baudRate, name, pinCode);
});
addConsoleAction("bluetooth_cancel", bluetoothCancel);
#endif /* EFI_BLUETOOTH_SETUP */
}