Mbed-os: SPI read always returns 0xff on Ublox EVK ODIN W2

Created on 1 Aug 2017  路  13Comments  路  Source: ARMmbed/mbed-os

Description

- Type: Bug

Bug

Target
Ublox EVK ODIN W2

Toolchain:
GCC_ARM

Expected behavior
Ublox EVK ODIN W2 board with Atmel RF shield attached, following code should return the radio ID register value 0x0b on 2.4 GHz devices.

#include "mbed.h"
#include "NanostackRfPhyAtmel.h"
#include "AT86RFReg.h"

#define SPI_SPEED 7500000

int main()
{
    DigitalOut CS(ATMEL_SPI_CS);
    DigitalOut RST(ATMEL_SPI_RST);
    SPI spi(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK);
    spi.frequency(SPI_SPEED);

    // Reset the chip
    RST = 0;
    CS = 1;
    wait(0.1);
    RST = 1;
    wait(0.1);

    const char cmd = 0x80 | PART_NUM;
    char rx[2];

    for (;;) {
        CS = 0;
        wait(0.001);
        spi.write(&cmd, 1, rx, 2);
        CS = 1;

        printf("Part num %.2x\n", rx[1]);
        wait(1);
    }
}

When device behaving correctly,

Part num 0b
Part num 0b
Part num 0b
Part num 0b

Actual behavior
On devices with the error condition,

Part num ff
Part num ff
Part num ff
Part num ff

Steps to reproduce
That one is the hardest part. I don't know how to get the device into this condition.

We have CI instance with over 10 Ublox devices. All of them are in this state. They all have been running mesh-minimal earlier.

Reflashing or resetting the device does not fix the state.

Power cycling fixes.

ublox bug

All 13 comments

Steps to reproduce

  1. Get Ublox EVK ODIN W2 board
  2. Get Atmel AT86RF212B SubGhz shield. (NOTE: I cannot make this happen on 2.4Ghz, even that in CI it seems to happen)
  3. mbed import mbed-os-example-mesh-minimal
  4. Edit mbed_app.json to match following
    "mbed-mesh-api.6lowpan-nd-channel-page": 2, "mbed-mesh-api.6lowpan-nd-channel": 1, "mbed-mesh-api.6lowpan-nd-channel-mask": "(1<1)", "mbed-trace.enable": true,
  5. Set target: mbed target UBLOX_EVK_ODIN_W2
  6. Set toolchain: mbed toolchain GCC_ARM
  7. Build. Store the binary
  8. Modify main.cpp to match the example in first message.
  9. Build.
  10. Flash the first binary
  11. Wait for message [DBG ][m6LND]: Link Layer Scan Fail: No Beacons
  12. Flash the second binary.
  13. Observe the serial port:
    Part num ff
  14. Unplug the USB & replug
  15. Observe the serial port:
    Part num 07 Part num 07

Notes

Part number 0x07 is SubGhz
Part number 0x0b is 2.4Ghz

Happens with both GCC6 and GCC 4.9

SPI read requires default byte to be written on SPI bus, usually that is 0xFF. SPI driver was recently updated to set this default value by user using 'set_default_write_value' api. Please verify what was default transmit earlier (successful case) and with failure. Hope this helps

Default byte should be 0xff and it is set on build time, so makes no sense if the behaviour changes just when power plugging the device. I starting to suspect hardware related things.

The SPI bus on this device is shared with SD card (but its not attached now), and also contains level shifters.
screen shot 2017-08-02 at 11 27 06
screen shot 2017-08-02 at 11 30 15

We are now studying how the lines actually behave.

@andreaslarssonublox @andreaspeterssonublox

Here are 2 pictures, showing what is happening

Succesful case:

  • Chip select stays low(sse)
  • Mosi line has command 0x9c (0x80 | 0x1C)
  • Miso line has a correct response 0x07
    ok_cond

Failure case:

  • Chip select stays low(sse)
  • Mosi line has command 0x9c
  • Miso line stays high, resulting 0xff
    error_cond

These measurements were done from 3.3 V side of the voltage converter.

Hi, where can we get the "Atmel AT86RF212B SubGhz shield" you are using to verify with?
@SeppoTakalo

Would this also impact the SD-card if one had an SD-card in the SPI-bus?
CC: @geky @deepikabhavnani

It could. needs verification.

Would this also impact the SD-card if one had an SD-card in the SPI-bus?

Yes if read response is always 0xFF, than no device (including SD card) on SPI bus will work properly. If it is randomly 0xFF than we may see corruption not related to actual data on SD card, but because of SPI.
In this case of corruption data on SD card will be correct, and device may work again after reset.

I would like to know if this behavior is observed on all devices on SPI bus?

Hi,
I looked at the code in NanostackRfPhyAtmel:rf_if_reset_radio and the SLP_TR is set to 0 which is not done in the example above. If this is inserted in the example it seems to work. Can you verify it @SeppoTakalo?

DigitalOut SLP_TR(ATMEL_SPI_SLP);

// Reset the chip
RST = 0;
CS = 1;
wait(0.1);
SLP_TR = 0;
RST = 1;
wait(0.1);

@andreaslarssonublox
Good finding.
I applied the SLP_TR control to the example code and it seems to fix the situation.

Looking at datasheets of AT86RF212B and AT86RF233 the SLP_TR pin is used to control PLL_ON -> TX transitions but also SLEEP modes.
So apparently leaving it low runs the chip into sleep mode.

However, datasheet does not specify that tranceiver sleep mode also disables SPI bus. Therefore this confusion.

The differences between hardwares are clearly that on some (For example K64F) the pin is probably configured high by default, but here it is low by default. That might explain why I'm only able to reach this state in Ublox HW.

I'll close this bug as the original issue is not valid but instead based on false assumption that the Atmel chip's SPI bus is always awake.

References:

  1. AT86RF233 datasheet
  2. AT86RF212B datasheet
Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidantaki picture davidantaki  路  3Comments

rbonghi picture rbonghi  路  3Comments

ashok-rao picture ashok-rao  路  4Comments

hasnainvirk picture hasnainvirk  路  3Comments

DuyTrandeLion picture DuyTrandeLion  路  3Comments