This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPI Slave and BLE on nRF51822

Hi,

I'm trying to build a SPI Slave <-> BLE bridge, so that everything received over SPI bus is forwarded on BLE and vice versa. In order for the reverse direction to work, the master has to continously pull data from the nRF51822. The problem is that if the BLE part of the code is compiled in and running, the SPI bus just locks up after a random time, between 2 and 60 seconds depending on data rate). I'm using ARM mbed, and the SPISlave::receive() function, which is supposed to tell if any data has been received from the master, starts returning false after that time no matter what the master actually sends to it. My SPI settings are 1 MHz, 8 bit, mode 0.

I've found a couple of posts here about incompatibilities between the PPI and the BLE stack. (Here and here and here.) However it's not clear if what I'm trying to achieve is possible or not. Some comments say that a SPI clock below 2 MHz should have no bad effects. I'm using only 1 MHz. Another comment says this is a problem with the S110 SoftDevice. (Well, I don't know which SoftDevice I have, how can I check it?) There's a mention of "using SPI over the SoftDevice API" but no information how to actually do that. Do I have give up on mbed to use the SoftDevice API? Is SPIS and the BLE stack totally incompatible and hopeless to work together? Thanks!

  • What do you have on the master side on the second transaction ? Would it be the same byte as the first transaction ?

    I am thinking it can discard the transaction if it detects the data from the slave is exactly the same as the last one. But this require you to add 1 bit as the flow control bit. So you only have 7 bit for data.

    Another option is to export the project or use mbed CLI and you can modify the library on your purpose.

  • Well, discarding the transaction is not a good idea in this situation since I'm only sending continuously from the master side to poll if the slave has any data to send to the master. The very simple protocol I'm using on the bus is to send the number of bytes available so the master knows how many bytes to pull from the slave after (this can be zero). That's why I need to keep the bus running all the time, so sending a zero to the slave will allow the master to see if the slave has anything to send to it.

  • What I'm trying to do now is to have the slave to signal the master on a dedicated signal line before it becomes unable to reply. This way the master can throttle polling it and resume when the signal goes low again indicating the slave's CPU is available again to reply. I'm using the nRF5 SDK's radio notification to achieve this. Though I'm not sure if this notification will mark exactly those times when the nRF's CPU is taken over by the BLE stack.

  • It could be a good idea. You can configure to receive radio notification on either ACTIVE, INACTIVE or both. You would need to keep track of this as there is no indication when it's active or the opposite. The CPU usually won't be occupied when the radio is inactive.

    But from my point of view, if you already want to access something mbed is not provide, why don't just bypass mbed SPI and access the SPIS hardware register directly and simply provide large enough buffer with EasyDMA ?

  • I tried radio notifications, and it worked, but it was unsuitable for this purpose since sometimes the CPU was still busy when the notification was inactive.

    What actually worked and ensured a stable communication between the slave and the master was per-transaction flow control. When the slave fills the buffer with data, it also sets a pin high that interrupts the master and enables it to do one transaction. As soon as the slave sees the transaction completed, it reads the data sent by the master from the buffer, sets the interrupt line to low, prepares the next transaction, and interrupts the master again by setting the interrupt line high again. This ensures that whenever the master sends something, there's a transaction already prepared on the slave side, and no more data is sent by the master before the slave is ready to receive again.

Related