2024-12-17 06:40 AM
When I use my arduino and the demo code it works perfectly but when I connect to my stm32 and do my code based on the demo code I have a problem during the factory reset, the module shuts down and I can't see the ble module on my phone.
I have checked my wires 3 times and also the power supply provided by the nucleo I have the 3.3V
I use doclight to monitor uart communication for debugging
You will find my code below:
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdlib.h"
#include "stdio.h"
#include <string.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define SPI_CS_PIN GPIO_PIN_8
#define SPI_CS_PORT GPIOB
#define SPI_IRQ_PIN GPIO_PIN_7
#define SPI_IRQ_PORT GPIOB
#define SPI_RST_PIN GPIO_PIN_6
#define SPI_RST_PORT GPIOB
#define BUFSIZE 128
#define VERBOSE_MODE 1
#define BLE_READPACKET_TIMEOUT 500
#define FACTORYRESET_ENABLE 1
#define BLUEFRUIT_CMD_TIMEOUT 1000
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_SPI2_Init(void);
/* USER CODE BEGIN PFP */
uint8_t ble_begin(void);
uint8_t ble_factoryReset(void);
void ble_echo(uint8_t enable);
void ble_info(void);
uint8_t sendCommand(const char* cmd, char* response, uint16_t timeout);
void UART_Print(UART_HandleTypeDef *huart, const char *str);
void printHex(const uint8_t *data, const uint32_t numBytes);
uint8_t readPacket(uint16_t timeout);
uint8_t packetbuffer[BUFSIZE];
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void UART_SendBuffer(uint8_t *buffer, uint16_t size){
HAL_UART_Transmit(&huart2, buffer, size, HAL_MAX_DELAY);
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
UART_Print(&huart2, "Adafruit Bluefruit Command Mode Example\n");
UART_Print(&huart2, "---------------------------------------\n");
UART_Print(&huart2, "Starting ble_begin...\n");
if (!ble_begin())
{
UART_Print(&huart2, "Couldn't find Bluefruit, make sure it's in Command mode & check wiring?\n");
while (1);
}
UART_Print(&huart2, "OK!\n");
if (FACTORYRESET_ENABLE)
{
UART_Print(&huart2, "Starting factory reset...\n");
if (!ble_factoryReset())
{
UART_Print(&huart2, "Couldn't factory reset\n");
while (1);
}
UART_Print(&huart2, "Factory reset complete\n");
HAL_Delay(2000); // Allow the module to restart
}
UART_Print(&huart2, "Disabling echo...\n");
ble_echo(0);
UART_Print(&huart2, "Echo disabled\n");
UART_Print(&huart2, "Requesting Bluefruit info:\n");
ble_info();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
UART_Print(&huart2, "Reading packet...\n");
uint8_t len = readPacket(BLE_READPACKET_TIMEOUT);
if (len > 0)
{
UART_Print(&huart2, "Received packet: ");
printHex(packetbuffer, len);
}
HAL_Delay(1000);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief SPI2 Initialization Function
* @PAram None
* @retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
/**
* @brief USART2 Initialization Function
* @PAram None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, SPI_RST_Pin|SPI_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : SPI_RST_Pin SPI_CS_Pin */
GPIO_InitStruct.Pin = SPI_RST_Pin|SPI_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : SPI_IRQ_Pin */
GPIO_InitStruct.Pin = SPI_IRQ_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI_IRQ_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
uint8_t ble_begin(void)
{
UART_Print(&huart2, "Initializing SPI communication...\n");
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_RESET);
// Add SPI initialization code here if necessary
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_SET);
UART_Print(&huart2, "SPI communication initialized.\n");
return 1; // Return 1 for success, 0 for failure
}
uint8_t ble_factoryReset(void)
{
char response[BUFSIZE];
if (sendCommand("AT+FACTORYRESET", response, BLUEFRUIT_CMD_TIMEOUT))
{
UART_Print(&huart2, "Factory Reset Response: ");
UART_Print(&huart2, response);
UART_Print(&huart2, "\n");
return 1; // Success
}
else
{
UART_Print(&huart2, "Factory Reset Timeout or Error\n");
return 0; // Failure
}
}
void ble_echo(uint8_t enable)
{
char response[BUFSIZE];
if (enable)
{
sendCommand("ATE=1", response, BLUEFRUIT_CMD_TIMEOUT);
}
else
{
sendCommand("ATE=0", response, BLUEFRUIT_CMD_TIMEOUT);
}
UART_Print(&huart2, "Echo Response: ");
UART_Print(&huart2, response);
UART_Print(&huart2, "\n");
}
void ble_info(void)
{
char response[BUFSIZE];
if (sendCommand("ATI", response, BLUEFRUIT_CMD_TIMEOUT))
{
UART_Print(&huart2, "Module Info: ");
UART_Print(&huart2, response);
UART_Print(&huart2, "\n");
}
else
{
UART_Print(&huart2, "Info Command Timeout or Error\n");
}
}
uint8_t sendCommand(const char* cmd, char* response, uint16_t timeout)
{
UART_Print(&huart2, "Sending command: ");
UART_Print(&huart2, cmd);
UART_Print(&huart2, "\n");
uint8_t cmdLength = strlen(cmd);
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_RESET);
for (uint8_t i = 0; i < cmdLength; i++)
{
if (HAL_SPI_Transmit(&hspi2, (uint8_t*)&cmd[i], 1, HAL_MAX_DELAY) != HAL_OK)
{
UART_Print(&huart2, "SPI Transmit Error\n");
}
}
uint8_t newline = '\n';
if (HAL_SPI_Transmit(&hspi2, &newline, 1, HAL_MAX_DELAY) != HAL_OK)
{
UART_Print(&huart2, "SPI Transmit Error\n");
}
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_SET);
UART_Print(&huart2, "Command sent, waiting for response...\n");
uint32_t startTick = HAL_GetTick();
uint8_t index = 0;
while ((HAL_GetTick() - startTick) < timeout)
{
uint8_t byte;
if (HAL_SPI_Receive(&hspi2, &byte, 1, HAL_MAX_DELAY) == HAL_OK)
{
response[index++] = byte;
if (byte == '\n')
{
response[index] = '\0';
UART_Print(&huart2, "Received response: ");
UART_Print(&huart2, response);
UART_Print(&huart2, "\n");
return 1; // Success
}
}
}
response[index] = '\0';
UART_Print(&huart2, "Response Timeout\n");
return 0; // Timeout or failure
}
void UART_Print(UART_HandleTypeDef *huart, const char *str)
{
HAL_UART_Transmit(huart, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
}
void printHex(const uint8_t *data, const uint32_t numBytes)
{
char buffer[3];
for (uint32_t i = 0; i < numBytes; i++)
{
snprintf(buffer, sizeof(buffer), "%02X ", data[i]);
UART_Print(&huart2, buffer);
}
UART_Print(&huart2, "\n");
}
uint8_t readPacket(uint16_t timeout)
{
UART_Print(&huart2, "Reading packet...\n");
uint16_t origtimeout = timeout, replyidx = 0;
uint8_t packetbuffer[BUFSIZE] = {0};
while (timeout--)
{
if (replyidx >= 20) break;
if((packetbuffer[1] == 'B') && replyidx == PACKET_BUTTON_LEN)
break;
uint8_t byte;
HAL_StatusTypeDef status = HAL_SPI_Receive(&hspi2, &byte, 1, HAL_MAX_DELAY);
if (status == HAL_OK)
{
if (byte == '!')
{
replyidx = 0;
}
packetbuffer[replyidx++] = byte;
timeout = origtimeout; // Reset timeout after receiving a byte
// If a newline character is received, end of packet
if (byte == '\n')
{
break;
}
}
if (timeout == 0) break;
HAL_Delay(1); // Delay to prevent CPU overload
}
packetbuffer[replyidx] = 0;
if (!replyidx) return 0;
if (packetbuffer[0] != '!') return 0;
uint8_t xsum = 0;
uint8_t checksum = packetbuffer[replyidx - 1];
for (uint8_t i = 0; i < replyidx - 1; i++)
{
xsum += packetbuffer[i];
}
xsum = ~xsum;
if (xsum != checksum)
{
UART_Print(&huart2, "Checksum mismatch in packet: ");
printHex((const uint8_t *)packetbuffer, replyidx);
return 0;
}
return replyidx;
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
//__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @PAram file: pointer to the source file name
* @PAram line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
I want to send a data frame from my phone (like pressing a button) and receive data back to my phone (like ‘button 6 is pressed’) with the Bluetooth module.
2024-12-17 09:44 AM
So look at the linked resources for how to debug that.
2024-12-21 03:28 AM
Hey @Andrew Neil,
Thanks for the link, I managed to get past the hardfault which was an IRQ configuration error.
I tried the STMDuino, to download the arduino code and debug and find out why I still can't communicate with the module. I discovered that there was a problem with the SPI clock speed as shown in the screenshot.
So I've changed the SPI clock (presacaler for Baud Rate) so that it's closer to 4Mhz like the arduino, but I still don't have any communication. Should I change the clock for the whole system?
Best regards.
Paulo971
2024-12-21 03:37 AM - edited 2024-12-21 03:43 AM
Please see: How to insert source code
@Paulo971 wrote:I discovered that there was a problem with the SPI clock speed as shown in the screenshot.
You mean this:
That more likely shows a baud rate error on the UART link between your target and the host system.
Or are you sending raw binary to the Serial Monitor? It needs to be printable text.
PS:
Have you tried using the Software SPI:
That should rule-out any issues with the hardware SPI configuration & operation ...
2024-12-21 05:43 AM
@Andrew Neil i tried to reproduce this code in C for the stm32 but not working and i cannot find the cause for the moment