stm32duino / STM32duinoBLE

ArduinoBLE library fork to support ST BLE modules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BLE connection issues with STM32WBMMGH

dabrahamaz opened this issue · comments

First, thank you for providing this awesome library!

We built our firmware on a Nucleo STM32WB55RG. Everything went smooth and works great! Then our development
team put a STM32WB5MMGH chip on our custom PCB. I have been struggling to get the BLE to even initialize.
In fact, including the BLE library actually makes the simple 1.54" display stop working too! If I comment
out the BLE code, everything else works!

I believe that the Generic STM32WB5MMGHx variant simply does not match 100% to what I need. I have tried
to copy the files and edit according to our design, I am failing. Now the development team wants us to
re-write the firmware in Keil, which will be a daunting task at this stage. I believe with right variant
mapping for our design will solve this problem immediately. I believe this because we have the entire firmware
package running perfectly on two other STM32 Nucleo boards. I did try the solution offered in issue #56 without success.

Here are ALL the details, sorry so verbose! Just making your simple BLE example (button/LED) work with this chip would be HUGE!

STM32CUBEPROGRAMMER SETTINGS
STLink-V3Set
MCU: STM32WB5x/35xx)
Device ID: 0x495
Rev ID: Rev Y
Flash: 1MB
CPU: Cortex-M4
Bootloader Ver: 0xD5

FUS: v1.2.0.0 (stm32wb5x_FUS_fw.bin)
STACK: v1.17.2.1 (stm32wb5x_BLE_HCILayer_fw.bin)

ARDUINO IDE
Version: 2.1.0
Date: 2023-04-19T15:31:10.185Z (4 months ago)
CLI Version: 0.32.2
Board: Generic STM32WB series
Board P/N: Generic STM32WB5MMGHx
Upload Method: STM32CubeProgrammer (SWD)

Libraries
STM32duinoBLE 1.2.5
GxEPD2 1.5.2
STM32duino Low Power 1.2.4

Chip on custom board: STM32WB5MMGH

Adding some code:

#define ENABLE_GxEPD2_GFX 0

#include <GxEPD2_BW.h>
#include "STM32LowPower.h"

// STM32 Nucleo WB55RG
//GxEPD2_BW<GxEPD2_150_BN,GxEPD2_150_BN::HEIGHT> display(GxEPD2_150_BN(/CS/ SS, /DC/ PA2, /RST/ PA1, /BUSY/ PA3));

// Device with STM32WB5MMGH
GxEPD2_BW<GxEPD2_150_BN,GxEPD2_150_BN::HEIGHT> display(GxEPD2_150_BN(/CS/ PB2, /DC/ PC11, /RST/ PC10, /BUSY/ PA15));

// Button pushing tracker for invoking BLE and Boot0
const uint32_t buttonpin = PC12; // Custom Device
const uint32_t ledpin = PC1; // Custom Device
//const uint32_t buttonpin = SW1_BTN; // Nucleo
//const uint32_t ledpin = LED1; // Nucleo

volatile int buttonpushcounter = 0; // counter for the number of button presses
volatile bool newpush = false;
uint32_t start_time = 0; // used for button pressed timer
uint32_t end_time = 0; // used for button pressed timer
uint32_t totaltime = 0; // used for button pressed timer
uint32_t firstclickstarttime = 0; // used to track three click timer

//custom functions - needs to stay here because of dependencies above
#include "PT_Functions.h"
#include "BLE_Functions.h"

void setup() {

// LED1 below
pinMode(ledpin, OUTPUT);
// Warning - depending on boards, INPUT_PULLDOWN may be required instead
pinMode(buttonpin, INPUT_PULLUP);

// Configure low power
LowPower.begin();
// Wakeup interrupt on pin, calling buttonWakeUP when the device is woken up
// Last parameter (LowPowerMode) should match with the low power state used
LowPower.attachInterruptWakeup(buttonpin, buttonWakeUp, FALLING, SLEEP_MODE);

// *** line below only used with CUSTOM DEVICE ONLY ***
display.epd2.init(PB3, PB5, 115200, true, 20, false); // define SW_SCK, SW_MOSI
display.init();
display.setRotation(0);
clearScreen(0);
delay(500);

// If the line below is uncommented, the BLE setup fails and halts at BLE.
//setupBLE();

// turn on led1 as power indicator
digitalWrite(ledpin, HIGH);

}

void loop() {
//do stuff here if we can get BLE to initialize!
}

void buttonWakeUp() {
newpush = true;
buttonpushcounter++;
}

void setupBLE() {

// begin initialization
if (!BLE.begin()) {
// BLE initialization fails here and never makes it out
while (1);
} else {
// the service is created already with all characteristics and works on two other boards!
// I had to hide the Service setup code as the product is not in production yet and is patent pending.
BLE.addService(P2PService);
}

Hi @dabrahamaz,
As you stated, you tried the solution from #56, so you added the define: GENERIC_WB5MMGHX and redefined the SystemClock_Config to use HSE?
Pay attention that the HSE value and also LSE if you use it have a default value:
https://github.com/stm32duino/Arduino_Core_STM32/blob/01e4f0c9a8d20fc20125fd5be539a1ef3bf9d546/system/STM32WBxx/stm32wbxx_hal_conf_default.h#L147-L149
https://github.com/stm32duino/Arduino_Core_STM32/blob/01e4f0c9a8d20fc20125fd5be539a1ef3bf9d546/system/STM32WBxx/stm32wbxx_hal_conf_default.h#L195C16-L199C1

So if your custom board doesn't have those value then you have to redefine them using https://github.com/stm32duino/Arduino_Core_STM32/wiki/Customize-build-options-using-build_opt.h

with for example an HSE of 25MHz:
-DHSE_VALUE=25000000UL

Thank you for the prompt reply, much appreciated!

Full disclosure, I did not see the line of code referenced in #56 anywhere in the files (HCISharedMemTransport.cpp or HCISharedMemTransport.h). Am I looking in the wrong place? I did add the code for the SystemClock_Config by adding that code to my project and including it. No issues recompiling.

I'm not sure that we use HSE or LSE. I think the disconnect comes from this great tool you have created that shields a lot of the work going on behind the scenes. It is the whole reason developers like me can bring up projects so quickly; albeit we are not as smart on all the work going as a developer like you has a handle on! Thanks again for the guidance.

I have posted the question to our EE regarding HSE and LSE. I will know today. Thank you.

Full disclosure, I did not see the line of code referenced in #56 anywhere in the files (HCISharedMemTransport.cpp or HCISharedMemTransport.h). Am I looking in the wrong place? I

Probably as no reference code in #56 comes from HCISharedMemTrasnsport files. All code referenced are changed to ino file.

I did add the code for the SystemClock_Config by adding that code to my project and including it. No issues recompiling.

Don't know where you add it, in my comment I simply add it to the ino file without forget to prefix with extern "C" like ino is converted in cpp file.

I'm not sure that we use HSE
HSE is required for BLE...

Ahh... So I simply need to add the code to my project (probably in my BLE module at the top) so those definitions are compiled.

The code to be added:

#elif defined(ARDUINO_NUCLEO_WB15CC) || defined(ARDUINO_P_NUCLEO_WB55RG) || defined(ARDUINO_STM32WB5MM_DK) || defined(P_NUCLEO_WB55_USB_DONGLE) || defined(ARDUINO_GENERIC_WB5MMGHX)

is missing the preceding "if", am I missing something?

My apologies, I did see it after I sent. I added all that code to my project and added the generic. The good news is that it compiles and for some reason the display now works again, but I am still failing when trying to call BLE.begin. I feel like we are so close to getting this working...

Here is the answer from our EE regarding HSE and LSE:

The STM32WB5MMG module include a 32MHz HSE crystal and a 32.768kHz LSE crystal. I just use the SystemClock_Config() from the BLE HeartRate example:
\STM32CubeWB\Projects\STM32WB5MM-DK\Applications\BLE\BLE_HeartRate\

Well I am a step closer!

  1. Using STM32CubeProgrammer I started the FUS
  2. I then manually started the WIRELESS STACK.
  3. I fired up my code (with changes from #56) and I can now get past the BLE.Begin()
  4. I never see the device (using ST BLE Toolbox) after I start advertising
  5. Just a reminder, this exact code does work on two other STM32 Nucleo boards, so I know it works!

Thank you so much for your help; definitely getting close!

FYI, I ran the example from #56 and it advertises for about 2 seconds and drops.

Pay attention that the HSE value and also LSE if you use it have a default value:

I checked the file in the links and I do have the statements that define HSE/LSE if they are undefined.

So if your custom board doesn't have those value then you have to redefine them using https://github.com/stm32duino/Arduino_Core_STM32/wiki/Customize-build-options-using-build_opt.h

How do I know if my board does not have those values? Are you saying if the code from the links is missing then I need to do the second step? I looked at the directions to "redefine them" and it is not so obvious what I need to do.

The STM32WB5MMG module include a 32MHz HSE crystal and a 32.768kHz LSE crystal. I just use the SystemClock_Config() from the BLE HeartRate example:
\STM32CubeWB\Projects\STM32WB5MM-DK\Applications\BLE\BLE_HeartRate\

Here is the anwser. HSE is 32MHz so the default value defined in the defaut HAL conf is correct (as stated in my previous comment).
But the default LSE value defined here is 32774UL for the STM32WB5Mxx:

#if !defined  (LSE_VALUE)
#if defined(STM32WB5Mxx)
#define LSE_VALUE    (32774UL)     /*!< Value of the LSE oscillator in Hz */
#else
#define LSE_VALUE    (32768UL)     /*!< Value of the LSE oscillator in Hz */
#endif /* STM32WB5Mxx */
#endif /* LSE_VALUE */

But you have a 32.768kHz which is not the same value. So you have to redefine the LSE_VALUE using the https://github.com/stm32duino/Arduino_Core_STM32/wiki/Customize-build-options-using-build_opt.h feature with this in the file:
-DLSE_VALUE=32768UL

If it does not works then you have to check if your hardware is correct: HSE, power,....

You told it is a custom PCB, is it for a company? do you have a contact with ST FAE? if yes you should contact them to ask support for Hardware part and RF. I could not help more on this subject. This library has been validated with STM32WBMMG and know to work with 2 dedicated boards as you can see here:
https://github.com/stm32duino/Arduino_Core_STM32/tree/01e4f0c9a8d20fc20125fd5be539a1ef3bf9d546/variants/STM32WBxx/WB5MMGH

You can also try this clock config:
https://github.com/stm32duino/Arduino_Core_STM32/blob/01e4f0c9a8d20fc20125fd5be539a1ef3bf9d546/variants/STM32WBxx/WB5MMGH/variant_STM32WB5MM_DK.cpp#L116C2-L194

don't forget this include:
#include "lock_resource.h"

I know you closed this but why can't I simply change the value here:
#define LSE_VALUE (32774UL)

You can but when you will update next time, it will be restored.

I was able to get the BLE working great at close range. I could not have done it without your help. Thanks again!
FYI, both the BLE_HCILayer_fw AND the BLE_HCILayer_EXT work. I actually had a better experience using the latter.