I'm trying to communicate with BlueNRG chip (on X-NUCLEO-IDB04A1 extension board) connected to STM32L1 (on NUCLEO-L152RE board) over SPI protocol.
According to BlueNRG manual, I can send an empty SPI packet of 5 bytes: (0x0B, 0, 0, 0, 0)
to get the read/write buffer sizes as well as the device status. The status is supposed to be 0x02
(ready), or 0x00
or 0xFF
if the device was sleeping and is waking up.
Here is the communication I'm getting:
Send (0x0B, 0, 0, 0, 0)
Receive (0x00, 0x00) // why 2 bytes?
Send (0x0B, 0, 0, 0, 0) // assuming device is waking up, re-trying
Receive (0x06, 0x00) // what is code 6?
My test app is written in Rust using Zinc. The MCU is running the default clock (2048 MHz from MSI). Here is the code responsible for SPI initialization:
// PB.3 = CLCK
let _spi_clock = pin::Pin::new(pin::PortB, 3,
pin::AltFunction(pin::AfSpi1_Spi2, pin::OutPushPull, pin::Medium),
pin::PullDown);
// PA.6 = MISO
let _spi_in = pin::Pin::new(pin::PortA, 6,
pin::AltFunction(pin::AfSpi1_Spi2, pin::OutPushPull, pin::Medium),
pin::PullNone);
// PA.7 = MOSI
let _spi_out = pin::Pin::new(pin::PortA, 7,
pin::AltFunction(pin::AfSpi1_Spi2, pin::OutPushPull, pin::Medium),
pin::PullNone);
// PA.1 = CS
let spi_csn = pin::Pin::new(pin::PortA, 1,
pin::GpioOut(pin::OutPushPull, pin::Medium),
pin::PullUp);
spi_csn.set_high();
let spi = spi::Spi::new(spi::Spi1, spi::DirFullDuplex, spi::RoleMaster,
spi::Data8b, spi::DataMsbFirst, 1); // baud pre-scaler = 2
let bnrg_reset = pin::Pin::new(pin::PortA, 8,
pin::GpioOut(pin::OutPushPull, pin::VeryLow),
pin::PullUp);
bnrg_reset.set_low();
// do something
bnrg_reset.set_high();
SPI internals are slightly modified from zinc master. The send/receive code is organized as follows:
loop {
spi_csn.set_low();
// send a dummy read request
spi.write(SpiRead as u8); // = 0x0B
spi.write(0);
spi.write(0);
spi.write(0);
spi.write(0);
let status = spi.read();
// debug print status
while spi.has_more_data() {
let data = spi.read();
// debug print data
}
spi_csn.set_high();
}
The question is - how to explain or treat these BlueNRG responses? I wasn't able to find any formal description of the low-level protocol it uses (not talking about HCI/ACI here, but about the status codes other than 0x02
= ready). It is very possible that I'm just initializing the hardware incorrectly, or even missing something obvious here. Would appreciate any guidance.