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

How to send 1 byte via SPI from master to slave

Hello everyone, I'm trying to run my nrf51 with ADS1298 using SPI. nrf51 is master and ADS1298 is slave.

I configured SPI as

const nrf_drv_spi_config_t spi_config =
    {
    		.sck_pin = 25,
			.mosi_pin = 24,
			.miso_pin = 23,
			.ss_pin = 30,
			//.irq_pin = 22,
			.irq_priority = APP_IRQ_PRIORITY_HIGH,
			.orc = 0x00,
			.frequency = NRF_DRV_SPI_FREQ_4M,
			.mode = NRF_DRV_SPI_MODE_0,
			.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST
    };

    err_code = nrf_drv_spi_init(&spi, &spi_config, spi_event_handler);
    APP_ERROR_CHECK(err_code);

And I tried to send one byte via SPI

memset(m_rx_buf, 0, m_length);
spi_xfer_done = false;
uint8_t SDATAC = 0x11;
// it stops continuous mode
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &SDATAC, 1, m_rx_buf, m_length));

But my logic analyser shows that I sent 4 bytes

MOSI: 0x11 MISO 0x00
MOSI: 0xFF MISO 0x00
MOSI: 0xFF MISO 0x00
MOSI: 0xFF MISO 0x00

It wasn't what I expected

Moreover I need to send 3 separate commands in arduino it looks as:

//stop continuous mode
digitalWrite(IPIN_CS, LOW);
SPI.transfer(SDATAC);
delayMicroseconds(1);
digitalWrite(IPIN_CS, HIGH);

//read chip ID
int out = 0;
digitalWrite(IPIN_CS, LOW);
SPI.transfer(0x20 | 0x00);
delayMicroseconds(5);
SPI.transfer(0);	// number of registers to be read/written – 1
delayMicroseconds(5);
out = SPI.transfer(0);
delayMicroseconds(1);
digitalWrite(IPIN_CS, HIGH);

Like that I tried to send it on nrf51 but got 0x00

uint8_t m_tx_buf[] = {0x11, 0x20 | 0x00, 0x00};
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, sizeof(m_tx_buf), m_rx_buf, m_length));

How to send 1 byte and 3 bytes like below, also is it possible to insert delay between 2 transfers like in arduino code?

Also I have a problem with GPIO pin, I configured several pins as GPIO outputs input, they needed to control my ADS1298: START for starting conversion, PWDN to turn my chip on and DRDY to read the status when data from ADS1298 is ready to be read.

#define START 5
#define RESET 6
#define PWDN 7
#define DRDY 8


// init output pins
nrf_gpio_cfg_output(START);							//config pin START as output
nrf_gpio_cfg_output(RESET);							//config pin RESET as output
nrf_gpio_cfg_output(PWDN);		//config pin PWDN as output
nrf_gpio_cfg_input(DRDY, NRF_GPIO_PIN_NOPULL);		//config pin DRDY as input

and set values of pins

nrf_gpio_pin_set(START);
nrf_gpio_pin_set(PWDN);

my logic analyser shows toggling on these pins, but only master changes the state of them.

Also I put into main while this code and set breakpoint on if

while(1)
{
     if(nrf_gpio_pin_read(DRDY) == 0)
     {
          NRF_LOG_INFO("Data is ready\r\n");
     }
     while (!spi_xfer_done)
        {
            __WFE();
        }

        NRF_LOG_FLUSH();
}

Breakpoint works only once and the value is high, but I see on my logic analyser that sometimes it's tied to low, what is the best way to read the status of GPIO pin?

Parents
  • Thanks for your reply. I found the solution of pin changes in examples of SDK.

    So, about SPI, yes I need to send some data without receiving from MISO

    According to your answer it looks like

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &SDATAC, 1, NULL, 1));
    

    Do I need to change rx_buffer_length to 0?

    So and how to implement the arduino code when I send each 1 byte after delay?

    int out = 0;
    digitalWrite(IPIN_CS, LOW);
    SPI.transfer(0x20 | 0x00);
    delayMicroseconds(5);
    SPI.transfer(0);    // number of registers to be read/written – 1
    delayMicroseconds(5);
    out = SPI.transfer(0);
    delayMicroseconds(1);
    digitalWrite(IPIN_CS, HIGH);
    

    What is the best way send like this:

    uint8_t tx[3] = {0x11, 0x20 | 0x00, 0x00};
    

    or

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, 0x11, 1, NULL, 1));
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, 0x20 | 0x00, 1, NULL, 1));
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, 0x00, 1, rx_buf, 1));
    
  • No, the buffer length wil be ignored if the rx buffer pointer is NULL. Does it have to be exactly 5 microseconds between the transfers?

Reply Children
No Data
Related