cancel
Showing results for 
Search instead for 
Did you mean: 

No Response on SPI from BlueNRG-MS. How do I know where the problem is ?

CCopp.1
Associate II

Hello everyone,

I've designed a PCB With a STM32H7 which is supposed to control a BlueNRG-MS. The design is the similar to the Figure 6 of the component datasheet: https://www.st.com/resource/en/datasheet/bluenrg-ms.pdf

I didn't put XTAL1 since it's optional. I also put a Balun instead of the impedence matching circuit (not related to the problem).

My PCB is ready and have all the component. My program is running on the STM32H7 as intended, except for the Bluetooth part.

I am using the X-CUBE-BLE1 BLE stack and sample applications for BlueNRG-MS module.

The init call returns succesfully and pull the RESET PIN of the BlueNRG-MS module High on my PCB.

hci_init(NULL, NULL);

According to this document: https://www.st.com/resource/en/application_note/dm00116738-bringing-up-the-bluenrg-and-bluenrgms-devices-stmicroelectronics.pdf

under the Test procedure paragraph, there should be signals on MISO, IRQ and CS Pins , unless i'm wrong. On my PCB, CS and RESET are HIGH.

The 1V8 and 1V2 are OK and the 16MHz clock is ticking at 16MHz correctly.

Then, I try to run the following function:

aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, BT_address)

which return 255 (TIMEOUT).

I found that the error comes from this function:

/**
 * @brief  Writes data from local buffer to SPI.
 *
 * @param  buffer : data buffer to be written
 * @param  size   : size of first data buffer to be written
 * @retval int32_t: Number of read bytes
 */
int32_t HCI_TL_SPI_Send(uint8_t* buffer, uint16_t size)
{
  int32_t result;
 
  uint8_t header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
  uint8_t header_slave[HEADER_SIZE];
 
  static uint8_t read_char_buf[MAX_BUFFER_SIZE];
  uint32_t tickstart = HAL_GetTick();
 
  do
  {
    result = 0;
 
    /* CS reset */
    HAL_GPIO_WritePin(HCI_TL_SPI_CS_PORT, HCI_TL_SPI_CS_PIN, GPIO_PIN_RESET);
 
    /* Read header */
    BSP_SPI4_SendRecv(header_master, header_slave, HEADER_SIZE);
 
    if(header_slave[0] == 0x02)
    {
      /* SPI is ready */
      if(header_slave[1] >= size)
      {
        BSP_SPI4_SendRecv(buffer, read_char_buf, size);
      }
      else
      {
        /* Buffer is too small */
        result = -2;
      }
    } else {
      /* SPI is not ready */
      result = -1;
    }
 
    /* Release CS line */
    HAL_GPIO_WritePin(HCI_TL_SPI_CS_PORT, HCI_TL_SPI_CS_PIN, GPIO_PIN_SET);
 
    if((HAL_GetTick() - tickstart) > TIMEOUT_DURATION)
    {
      result = -3;
      break;
    }
  } while(result < 0);
 
  return result;
}

I can see the trame {0x0a, 0x00, 0x00, 0x00, 0x00} on the oscilloscope on MOSI and there is nothing on MISO. Which indicate that the SPI is not ready, then the function return a Timeout.

0693W000008GPvQQAW.jpgFigure 1. SPI_MOSI and SPI_CLK during (BSP_SPI4_SendRecv(header_master, header_slave, HEADER_SIZE);)

0693W000008GPw9QAG.jpgFigure 2. SPI_MOSI and SPI_CS during (BSP_SPI4_SendRecv(header_master, header_slave, HEADER_SIZE);)

0693W000008GPwOQAW.jpgFigure 3. XTAL2 after SPI_RESET goes HIGH.

According to the Test document, if there is no signal on IRQ after a reset, it means that the BlueNRG firmware is not running.

Here are some explanations possible to my problem:

  • Is the firmware on the BlueNRG-MS when you buy it ?
  • Should I have a XTAL1 for the firmware to run ?
  • Something else hardware or software related ?

 Thank you for any suggestions.

5 REPLIES 5
Winfred LU
ST Employee

Please check STSW-BNRGUI package

https://www.st.com/content/st_com/en/products/embedded-software/wireless-connectivity-software/stsw-bnrgui.html

  • The firmware on BlueNRG-MS is ready when you buy it
    • But you can still upgrade the firmware (to replace the existing one)
  • XTAL1 is optional
    • IFR has to be configured accordingly (to use RO instead)
    • ifr_3v1_003_mode02-16MHz-RO32K_4M.dat (prebuilt) shall be used, located in C:\Program Files (x86)\STMicroelectronics\BlueNRG GUI 3.2.1\Firmware\BlueNRG-MS_stack\

0693W000008GVbHQAW.png 

Thank you for the reply.

I have checked yesterday this IFR configuration. I found this file "ifr_3v1_003_mode02-32MHz-RO32K_SMPS_OFF.dat" under the folder : "BlueNRG DK 2.0.2\Firmware\BlueNRG-MS_stack\SMPS_OFF" which correspond to my design.

I've copied the last 192Bytes which correspond to the IFR section of the µC and pasted them in bluenrg_IFR.c like this:

[...]
 
#define BLUENRG_CONFIG 			BLUENRG_CUSTOM_CONFIG
 
[...]
 
#elif BLUENRG_CONFIG == BLUENRG_CUSTOM_CONFIG
/* Copy and paste here your custom IFR_config structure. It can be generated
 * with BlueNRG GUI.
 */
const IFR_config_TypeDef IFR_config = {
  0x02443A02,
  0x39021B34,
  0x003C02A2,
  0xFFFFFF00,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0x02431C02,
  0x1F02EC20,
  0xFFFF00AF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFF02,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFF0001F4,
  0xFFFF0148,
  0xFFFFFFFF,
  0x130616FF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF,
  0xFFFFFFFF
};
 
[...]

I think it's the correct way to do it.

I then found this function:

int program_IFR(const IFR_config_TypeDef *ifr_image)

to change the IFR.

This calls

getBlueNRGVersion(&hwVersion, &fwVersion)

which will call

hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, 
                                     &manufacturer_name, &lmp_pal_subversion);

which will call

hci_send_req(&rq, FALSE)

which will call

send_cmd(r->ogf, r->ocf, r->clen, r->cparam);

which will call

hciContext.io.Send (payload, HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE + plen)

which refer to the same function that was returning me a Timeout previously.

I really think there should be data comming from the BlueNRG-MS on the MISO trace after a reset, and this is my main problem.

Might a broken chip start 1.2V & 1.8V regulators and start the 16MHz without sending anything on both SPI_MISO & SPI_IRQ ?

If it's the case, I might have to change the chip and test with another one.

CCopp.1
Associate II

The chip was indeed broken. I changed it on the board. Now it's reponding. Unfortunatelly I have a ne problem.

As soon as the IRQ is high. My main µC, the STM32H743 enters an infinite loop:

/**
 * @brief  This is the code that gets called when the processor receives an 
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 * @param  None     
 * @retval None       
*/
    .section  .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
  .size  Default_Handler, .-Default_Handler

I dont really know why this is happening. The interrupt is defined in this function:

/**
 * @brief  Register hci_tl_interface IO bus services
 *
 * @param  None
 * @retval None
 */
void hci_tl_lowlevel_init(void)
{
  /* USER CODE BEGIN hci_tl_lowlevel_init 1 */
 
  /* USER CODE END hci_tl_lowlevel_init 1 */
  tHciIO fops;
 
  /* Register IO bus services */
  fops.Init    = HCI_TL_SPI_Init;
  fops.DeInit  = HCI_TL_SPI_DeInit;
  fops.Send    = HCI_TL_SPI_Send;
  fops.Receive = HCI_TL_SPI_Receive;
  fops.Reset   = HCI_TL_SPI_Reset;
  fops.GetTick = BSP_GetTick;
 
  hci_register_io_bus (&fops);
 
  /* USER CODE BEGIN hci_tl_lowlevel_init 2 */
 
  /* USER CODE END hci_tl_lowlevel_init 2 */
 
  /* Register event irq handler */
  HAL_EXTI_GetHandle(&hexti11, EXTI_LINE_11);
  HAL_EXTI_RegisterCallback(&hexti11, HAL_EXTI_COMMON_CB_ID, hci_tl_lowlevel_isr);
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
 
  /* USER CODE BEGIN hci_tl_lowlevel_init 3 */
 
  /* USER CODE END hci_tl_lowlevel_init 3 */
 
}

which is called by hci_init in my main program as I told before.

Maybe it has something to do with the pins I use: 0693W000008Ga1YQAS.pngIf you have any guesses =)

EDIT: I found the interruption by implementing this function:

void EXTI15_10_IRQHandler(void) {
	while(1);
}

I've checked and it means that the Callback function hci_tl_lowlevel_isr() is not called. So it doen't read the data. I hacked my way throught by doing this:

void EXTI15_10_IRQHandler(void) {
	hci_tl_lowlevel_isr();
}

I still need to investigate if everything is ok or not.

In the end, I will probably use a BlueNRG-M0L (the module version of the BlueNRG-MS) to avoid Hardware problems.

When Default_Handler is called, it means the processor receives an interrupt but doesn't know to handle that interrupt. This is mostly because the interrupt (ISR etc) is not configured correctly.

It seems that the configuration of EXTI line is missing from your implementation? Check HAL_EXTI_SetConfigLine()?

Thank you for the answer.

I Activated the EXTI lines Interrupts and verified that the interrupt was correctly configured. It seems to work.

0693W000008GeumQAC.png0693W000008GevBQAS.png