首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未知BlueNRG SPI响应

未知BlueNRG SPI响应
EN

Stack Overflow用户
提问于 2014-11-21 04:03:00
回答 2查看 2K关注 0票数 1

我试图与BlueNRG芯片(在X-NUCLEO-IDB04A1扩展板上)通过SPI协议与STM32L1 (在原子核-L152RE板上)进行通信。

根据BlueNRG 手册,我可以发送一个5字节的空SPI数据包:(0x0B, 0, 0, 0, 0)来获取读/写缓冲区大小以及设备状态。状态应该是0x02 (就绪),或者0x000xFF,如果设备处于休眠状态并正在醒来。

下面是我得到的信息:

代码语言:javascript
复制
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?

我的测试应用程序是用用Rust编写的。单片机正在运行默认时钟(2048 MHz来自MSI)。下面是负责SPI初始化的代码:

代码语言:javascript
复制
// 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内部部件从锌母料中略为修改。发送/接收代码组织如下:

代码语言:javascript
复制
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();
}

问题是-如何解释或处理这些BlueNRG反应?我无法找到它使用的低级协议的任何正式描述(这里不是谈论HCI/ACI,而是0x02 =ready之外的状态代码)。很可能我只是不正确地初始化硬件,甚至遗漏了一些显而易见的东西。如果能提供任何指导的话。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-21 09:05:54

SPI驱动程序似乎有一些根本问题。它是否在硬件或软件中有一个缓冲区来存储输入的字节,或者它是如何工作的?通常,您不发送或接收与SPI,您接受全双工。SPI驱动程序本身不可能判断传入的数据是有效的还是垃圾的,因此不存在“当发送5时我只接收2个字节”之类的东西。发送5个字节时总是接收5个字节。

这个应用程序中的MCU将是SPI的主处理器,外部的芯片将是从芯片。对于发送的每一个字节,您也会收到一个字节。这个字节是否有意义取决于外部芯片的工作方式。遗憾的是,目前还没有SPI标准,因此外部芯片可以声明各种延迟要求,例如“在SCK & MOSI启动前必须将从选择拉低x时间单元”。您必须详细阅读外部芯片的手册。

然后,当所有的混乱都解决了,当然,当SPI不能正常工作时,人们通常会怀疑:时钟因为不正确的时钟极性或时钟相位设置而倾斜。

票数 3
EN

Stack Overflow用户

发布于 2018-02-12 08:28:45

请参考ST UM1865,第5章: SPI接口。它适用于BlueNRG(不是BlueNRG),但HCI/ACI接口是相同的。

正如您已经注意到的,第一个字节是SPI就绪指示,0x02表示从SPI接口已经就绪。如果它是0x02以外的任何值,主服务器必须忽略以下4个字节并中止SPI事务。

如果BlueNRG (或-MS) SPI已经准备好(0x02),下面的4个字节为写入和读取提供了2个缓冲区大小:

  • 第二个字节包含写缓冲区大小(最大值为127)
  • 第四个字节包含读取缓冲区大小

在您的示例中,{0xb、0、0、0、0}仅用于检查BlueNRG读取缓冲区的大小。类似地,{0xa,0,0,0,0}用于检查写缓冲区的大小。

如果返回的大小不是0,就像在您的示例{0x6,0}中一样,我假设它应该是{0x6,0,0,0},这意味着BlueNRG已经准备好读取6 (0 << 8,0)字节的数据。然后,您将尽快从BlueNRG读取6个字节。

请参考C:\Program (x86)\STMicroelectronics\BlueNRG 2.0.2\Projects\Drivers\BSP\STM32L1xx_BlueNRG\SDK_EVAL_Spi_Driver.c函数BlueNRG_SPI_Read_All()。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27053902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档