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

An issue in NRF51822 custom board as spi slave with BLE

Hello there,

I'm trying to use my NRF51822 custom board as spi slave with BLE that sending whatever received from the master. I'm using MSP430FR5994 as the master. 

I'm using 110 softdevice and SDK v10.  I tried to combine both BLE peripheral and spi slave examples from the SDK. BLE code works fine (received all zeros value using N RFconnect) but spi slave does not.

I tried to debug the master spi pins using the oscilloscope. I can see the master source the clock when the CS goes low, but this happens only when the NRF51822 custom board is not connected to the master. When I connected the NRF51822 custom board, the CS never goes low ( it always high even when the Master drives it low to start the spi communication ). 

I sat the clock speed to 1MHz in the master because from my search in this forum I knew that maximum clock speed fro spi slave for nrf51822 is 2MHz. Also, I set up the spi mode, bit order to be the same in both master and slave. 

I'm pretty sure I miss something in the NRF51822 configuration or my logic is wrong. Do I need to configure the clock in the NRF51822 ? 

Any help would be highly appreciated. 

Here is a snippet of my code:

// setting up the spi pins
#define 	NRF_GPIO_PIN_MAP(port, pin)   ((port << 5) | (pin & 0x1F))
#define SPIS_SCLK_PIN NRF_GPIO_PIN_MAP(0, 3)   // pin P03
#define SPIS_MOSI_PIN NRF_GPIO_PIN_MAP(0, 1)   //pin P01
#define SPIS_MISO_PIN NRF_GPIO_PIN_MAP(0, 2)   //pin P02
#define SPIS_CS_PIN NRF_GPIO_PIN_MAP(0, 4)    //pin P03

int main(void)
{

    uint32_t err_code;
    uint8_t i;
    
    // Initialize spis
    err_code = spi_slave_init();
    APP_ERROR_CHECK(err_code);

    // Initialize BLE
    ble_stack_init();
    gap_params_init();
    advertising_init();
    services_init();
    // Start execution.
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

    // Enter main loop.
    while(1)
    {
        nrf_delay_ms(10000);
        for(i=0;i<CHARACTERISTIC_SIZE;i++)
        {
             char1_data[i] = m_rx_buf[i]; // update BLE data using RX buffer
        }
        err_code = custom_service_update_data(m_conn_handle,char1_data);
        APP_ERROR_CHECK(err_code);
    }
}


uint32_t spi_slave_init(void)
{
    uint32_t              err_code;
    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG(SPIS_INSTANCE_NUMBER);

    spis_config.miso_pin        = SPIS_MISO_PIN;
    spis_config.mosi_pin        = SPIS_MOSI_PIN;
    spis_config.sck_pin         = SPIS_SCLK_PIN;
    spis_config.csn_pin         = SPIS_CS_PIN;
    spis_config.mode            = NRF_DRV_SPIS_MODE_0;
    /*
    NRF_DRV_SPIS_MODE_0   -----> (CPOL = 0, CPHA = 0)
    NRF_DRV_SPIS_MODE_1   -----> (CPOL = 0, CPHA = 1)
    NRF_DRV_SPIS_MODE_2   -----> (CPOL = 1, CPHA = 0)
    NRF_DRV_SPIS_MODE_3   -----> (CPOL = 1, CPHA = 1)
    */
    spis_config.bit_order       = NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST;
    spis_config.def             = DEF_CHARACTER;
    spis_config.orc             = ORC_CHARACTER;

    err_code = nrf_drv_spis_init(&m_spis, &spis_config, spi_slave_event_handle);
    APP_ERROR_CHECK(err_code);

    //Initialize buffers.
    spi_slave_buffers_init(m_tx_buf, m_rx_buf, (uint16_t)TX_BUF_SIZE);

    //Set buffers.
    err_code = nrf_drv_spis_buffers_set(&m_spis, m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_rx_buf));
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

Parents
  • hen I connected the NRF51822 custom board, the CS never goes low ( it always high even when the Master drives it low to start the spi communication ). 

    That could only happen if it is either not properly connected or the pin is configured elsewhere as an output (e.g. for UART).

    If two outputs fight each other, the resulting voltage is usually somewhere "in the middle" - but if the pin is in high drive mode there might be a chance it overwhelms the MSP IO pin.

  • I found this in the SDK v10 documentation about GPIOs which might explain why CS pin never goes low:

    Working with a SoftDevice

    When a SoftDevice is enabled, it can interrupt the application at any time for a certain amount of time. This can lead to the situation where some pin level changes are missed. If the application must track an input pin that can change its level frequently, PPI should be used with a high-accuracy event together with a TIMER in counter mode to count the detected transitions. 

    Any idea/example of how to do what is suggested?

  • Irrelevant: SPIS does not rely on pin changing interrupts - it uses the CS signal directly in hardware.

    The only effect here would be a delay between end-of-transaction and the actual SPIS interrupt handler being executed.

    At this point I recommend cutting the CS wire/trace and putting a series resistor (100R - 1k) in. This lets you measure which chip powers the line with a multimeter. Oscilloscope would be nice, too...

Reply
  • Irrelevant: SPIS does not rely on pin changing interrupts - it uses the CS signal directly in hardware.

    The only effect here would be a delay between end-of-transaction and the actual SPIS interrupt handler being executed.

    At this point I recommend cutting the CS wire/trace and putting a series resistor (100R - 1k) in. This lets you measure which chip powers the line with a multimeter. Oscilloscope would be nice, too...

Children
No Data
Related