<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Can&amp;#39;t get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/83838/can-t-get-spi-communication-to-work-on-the-nrf5340-dk</link><description>Hi, 
 For a project I am currently trying to do a simple test to check the SPI communication between the nrf5340 en ADS1299 (ADC for EEG application) before we order our pcbs. 
 So far I haven&amp;#39;t been able to get it to work, to narrow down the source of</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Sat, 20 Aug 2022 18:04:26 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/83838/can-t-get-spi-communication-to-work-on-the-nrf5340-dk" /><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/382529?ContentTypeID=1</link><pubDate>Sat, 20 Aug 2022 18:04:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bf72fcca-b438-4d7b-8772-c2453824af9a</guid><dc:creator>blakbu</dc:creator><description>&lt;p&gt;Hey,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Can you share your schematics? I couldn&amp;#39;t find any resources for using nrf5340 with ads1299. If you can share your schematic, that would be really helpful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/353169?ContentTypeID=1</link><pubDate>Tue, 15 Feb 2022 16:33:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5d519eec-18c5-493c-b639-508206b1e166</guid><dc:creator>MickyT</dc:creator><description>&lt;p&gt;No worries, thank you for replying.&lt;/p&gt;
&lt;p&gt;I did call `nrfx_gpiote_in_init`, but I see now that I didn&amp;#39;t copy it correctly in my previous post, sorry about that. I will edit that post and add my entire file below (see line 75 for the init function).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;quot;ADS1299.h&amp;quot;
#include &amp;lt;zephyr.h&amp;gt;
#include &amp;lt;sys/printk.h&amp;gt;
#include &amp;lt;nrfx_spim.h&amp;gt;
#include &amp;lt;device.h&amp;gt;
#include &amp;lt;devicetree.h&amp;gt;
#include &amp;lt;drivers/gpio.h&amp;gt;

#ifndef POLL_DREADY
    #include &amp;lt;nrfx_gpiote.h&amp;gt;
#endif

#define SPI_INSTANCE 2

#define PIN_SCK NRF_GPIO_PIN_MAP(0, 8)
#define PIN_MOSI NRF_GPIO_PIN_MAP(0, 9)
#define PIN_MISO NRF_GPIO_PIN_MAP(0, 10)
#define PIN_CS NRF_GPIO_PIN_MAP(0, 2)

#define PIN_DRDY NRF_GPIO_PIN_MAP(0, 7)

#define COMMAND_WAKEUP 0x02
#define COMMAND_STANDBY 0x04
#define COMMAND_RESET 0x06
#define COMMAND_START 0x08
#define COMMAND_STOP 0x0A
#define COMMAND_RDATA 0x12
#define COMMAND_RDATAC 0x10
#define COMMAND_SDATAC 0x11
#define COMMAND_RREG 0b00100000
#define COMMAND_WREG 0b01000000

volatile enum state_t {idle, send_command, receive_data, processing_data} state = idle;
bool new_data_available = false;

static const nrfx_spim_t m_spi = NRFX_SPIM_INSTANCE(SPI_INSTANCE);
uint8_t rx_buffer[27], tx_buffer[8];
uint8_t sample_number = 0;

const struct device *gpio_dev_0, *gpio_dev_1;

inline int32_t buffer_to_channel(uint8_t id);
bool ADS1299_receive_data();
ADS1299_data_t ADS1299_convert_data();

#ifndef POLL_DREADY
    void data_ready_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action);
#endif

void spim_event_handler(nrfx_spim_evt_t const *p_event, void *p_context) {
    switch (p_event-&amp;gt;type)
    {
    case NRFX_SPIM_EVENT_DONE:
        if(state == receive_data) {
            new_data_available = true;
        }
        gpio_pin_set(gpio_dev_1, 1, 1);
        state = idle;
        break;
    
    default:
        break;
    }
    return;
}

#ifndef POLL_DREADY
void data_ready_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
    if(pin == PIN_DRDY &amp;amp;&amp;amp; action == NRF_GPIOTE_POLARITY_HITOLO) {
        ADS1299_receive_data();
    }
}
#endif

bool ADS1299_init() {
    nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG(PIN_SCK, PIN_MOSI, PIN_MISO, NRFX_SPIM_PIN_NOT_USED);
    config.frequency = NRF_SPIM_FREQ_125K;
    config.ss_active_high = false;
    config.bit_order = SPIM_CONFIG_ORDER_MsbFirst;
    config.mode = NRF_SPIM_MODE_1;
    
    nrfx_spim_uninit(&amp;amp;m_spi);
    int err = nrfx_spim_init(&amp;amp;m_spi, &amp;amp;config, spim_event_handler, NULL);

    if(err == NRFX_SUCCESS) {
        printk(&amp;quot;SPI init success\r\n&amp;quot;);
    } else {
        printk(&amp;quot;FAIL: SPI init failed: %d\r\n&amp;quot;, err);
        return false;
    }
    
    gpio_dev_0 = device_get_binding(&amp;quot;GPIO_0&amp;quot;);
    gpio_dev_1 = device_get_binding(&amp;quot;GPIO_1&amp;quot;);

    if (gpio_dev_0 == NULL) {
		return false;
	}

    if (gpio_dev_1 == NULL) {
		return false;
	}

    #ifdef POLL_DREADY
        printk(&amp;quot;Configure DREADY pin\r\n&amp;quot;);
        err = gpio_pin_configure(gpio_dev_0, 7, GPIO_INPUT);
        printk(&amp;quot;Return config DREADY pin: %d\r\n&amp;quot;, err);
    #else
        // Interrupt
        if(!nrfx_gpiote_is_init()) {
            err = nrfx_gpiote_init(6);

            if(err == NRFX_SUCCESS) {
                printk(&amp;quot;Pin IRQ init success\r\n&amp;quot;);
            } else {
                printk(&amp;quot;FAIL: pin IRQ init failed: %d\r\n&amp;quot;, err);
                return false;
            }
        }

        nrfx_gpiote_in_config_t irq_config = NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); // TODO: what is argument?
        err = nrfx_gpiote_in_init(PIN_DRDY, &amp;amp;irq_config, data_ready_handler);

        if(err == NRFX_SUCCESS) {
            printk(&amp;quot;Pin IRQ config success\r\n&amp;quot;);
        } else {
            printk(&amp;quot;FAIL: pin IRQ config failed: %d\r\n&amp;quot;, err);
            return false;
        }
    #endif
    

	gpio_pin_configure(gpio_dev_1, 1, GPIO_OUTPUT);
    gpio_pin_set(gpio_dev_1, 1, 1);

    #ifndef POLL_DREADY
        nrfx_gpiote_in_event_enable(PIN_DRDY, true);
    #endif

    return true;
}

void poll_dready() {
    if(gpio_pin_get(gpio_dev_0, 7) == 0) {
        ADS1299_receive_data();
    }
}

int spi_transfer(const nrfx_spim_xfer_desc_t *desc) {
    gpio_pin_set(gpio_dev_1, 1, 0);
    return nrfx_spim_xfer(&amp;amp;m_spi, desc, 0);
}

bool ADS1299_send_command(uint8_t command) {
    if(state == idle) {
        nrfx_spim_xfer_desc_t spim_xfer_desc = NRFX_SPIM_XFER_TX(tx_buffer, 1);
        spim_xfer_desc.p_rx_buffer = NULL;
        spim_xfer_desc.rx_length = 0;
        tx_buffer[0] = command;
        state = send_command;
        int err = spi_transfer(&amp;amp;spim_xfer_desc);
        if(err != NRFX_SUCCESS) {
            printk(&amp;quot;send command err: %d\r\n&amp;quot;, err);
        }
        return true;
    } else {
        return false;
    }
}

bool ADS1299_write_register(uint8_t address, uint8_t value) {
    if(state == idle) {
        nrfx_spim_xfer_desc_t spim_xfer_desc = NRFX_SPIM_XFER_TX(tx_buffer, 2);
        spim_xfer_desc.p_rx_buffer = NULL;
        spim_xfer_desc.rx_length = 0;
        tx_buffer[0] = (address &amp;amp; 0b00011111) | COMMAND_WREG;
        tx_buffer[1] = value;
        state = send_command;
        int err = spi_transfer(&amp;amp;spim_xfer_desc);
        if(err != NRFX_SUCCESS) {
            printk(&amp;quot;send command err: %d\r\n&amp;quot;, err);
        }
        return true;
    } else {
        return false;
    }
}

bool ADS1299_send_start() {
    return ADS1299_send_command(COMMAND_START);
}

bool ADS1299_send_read_continuous() {
    return ADS1299_send_command(COMMAND_RDATAC);
}

bool ADS1299_send_reset() {
    return ADS1299_send_command(COMMAND_RESET);
}

bool ADS1299_receive_data() {
    if(state == idle) {
        state = receive_data;
        new_data_available = false;
        nrfx_spim_xfer_desc_t spim_xfer_desc = NRFX_SPIM_XFER_RX(rx_buffer, 27);
        spi_transfer(&amp;amp;spim_xfer_desc);
        return true;
    } else {
        return false;
    }
}

bool ADS1299_poll_new_data(ADS1299_data_t *data) {
    if(new_data_available) {
        new_data_available = false;
        state = processing_data;

        *data = ADS1299_convert_data();

        state = idle;

        return true;
    } else {
        return false;
    }
}

ADS1299_data_t ADS1299_convert_data() {
    /* Data structure: */
    /* 24 bit status */
    /*  - 1100 + LOFF_STATP(8 bit) + LOFF_STATN(8 bit) + GPIO(4 bit) */
    /* 8ch * 24 bits data */

    ADS1299_data_t data;
    
    data.lead_off_positive = rx_buffer[0] &amp;lt;&amp;lt; 4;
    data.lead_off_positive |= (rx_buffer[1] &amp;amp; 0b11110000) &amp;gt;&amp;gt; 4;
    data.lead_off_negative = rx_buffer[1] &amp;lt;&amp;lt; 4;
    data.lead_off_negative |= (rx_buffer[2] &amp;amp; 0b11110000) &amp;gt;&amp;gt; 4;

    data.gpio_0 = rx_buffer[2] &amp;amp; 0b00001000;
    data.gpio_1 = rx_buffer[2] &amp;amp; 0b00000100;
    data.gpio_2 = rx_buffer[2] &amp;amp; 0b00000010;
    data.gpio_3 = rx_buffer[2] &amp;amp; 0b00000001;

    data.channgel_0 = buffer_to_channel(0);
    data.channgel_1 = buffer_to_channel(1);
    data.channgel_2 = buffer_to_channel(2);
    data.channgel_3 = buffer_to_channel(3);
    data.channgel_4 = buffer_to_channel(4);
    data.channgel_5 = buffer_to_channel(5);
    data.channgel_6 = buffer_to_channel(6);
    data.channgel_7 = buffer_to_channel(7);

    return data;
}

inline int32_t buffer_to_channel(uint8_t id) {
    return rx_buffer[3 + id] &amp;lt;&amp;lt; 16 | (rx_buffer[3 + id + 1] &amp;lt;&amp;lt; 8) | rx_buffer[3 + id + 2];
}

bool get_spi_busy() {
    return state != idle;
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/352925?ContentTypeID=1</link><pubDate>Mon, 14 Feb 2022 14:10:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:396b242e-a5d5-414c-8dc5-f385ee2390ea</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;Sry for the late reply.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;The PORT event has been fired, and the PORT event interrupt is enabled so that should also have fired.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Have you called gpiote_in_init() at all?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/352158?ContentTypeID=1</link><pubDate>Wed, 09 Feb 2022 16:33:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f4460376-910f-4c54-9f6c-7da89c53a888</guid><dc:creator>MickyT</dc:creator><description>&lt;p&gt;After a couple pauses I observed the following values:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1644423183058v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1644423196995v2.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1644423217455v3.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So the only event generated is on the EVENTS_PORT and all the configs are 0, which corresponds to the result I am seeing, but not what I would expect given that the two init functions return a NRFX_SUCCESS.&lt;/p&gt;
&lt;p&gt;Any ideas are appreciated, or if you know of a working example that would be great as well.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/351105?ContentTypeID=1</link><pubDate>Thu, 03 Feb 2022 12:53:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3d5144a7-96b9-4db2-8463-5c006df3d68e</guid><dc:creator>haakonsh</dc:creator><description>[quote user="MickyT"]Do you have any idea what this issue might be?[/quote]
&lt;p&gt;I don&amp;#39;t know.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I think you should monitor the GPIOTE registers, specifically&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/gpiote.html?cp=3_0_0_6_13_4_6#register.EVENTS_IN"&gt;EVENTS_IN[n]&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a title="EVENTS_PORT" href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/gpiote.html?cp=3_0_0_6_13_4_7#register.EVENTS_PORT"&gt;EVENTS_PORT &lt;/a&gt;during runtime(pause the debugger a few times after you&amp;#39;ve configured the GPIOTE channel).&lt;br /&gt;&lt;br /&gt;You should also verify that the&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/gpiote.html?cp=3_0_0_6_13_4_13#register.CONFIG"&gt;CONFIG[n]&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a title="INTENSET" href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/gpiote.html?cp=3_0_0_6_13_4_10#register.INTENSET"&gt;INTENSET&lt;/a&gt;&amp;nbsp;register is configured as intended. If you print out the values I can help you parse them.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/349955?ContentTypeID=1</link><pubDate>Thu, 27 Jan 2022 11:45:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7210e72a-5d03-4325-9c68-b064d8c832b4</guid><dc:creator>MickyT</dc:creator><description>&lt;p&gt;I have made some progress on this issue. It turned out that there was either another bad connection or I needed to disconnect the Arduino I used as an analog in (simple oscilloscope), which gave me the following result.&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1643283305697v1.png" /&gt;&lt;/p&gt;
&lt;p&gt;So the signals look a lot cleaner and the sensor responds to commands, which is great.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately now I am having some troubles getting the interrupt for the DRDY pin to work. I looked at some examples online, which resulted in the following (related) code:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;nrfx_gpiote.h&amp;gt;

#define PIN_DRDY NRF_GPIO_PIN_MAP(0, 7)

void data_ready_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
    if(pin == PIN_DRDY &amp;amp;&amp;amp; action == NRF_GPIOTE_POLARITY_HITOLO) {
        ADS1299_receive_data();
    }
}

bool ADS1299_init() {
.
.
.
    if(!nrfx_gpiote_is_init()) {
        err = nrfx_gpiote_init(6);

        if(err == NRFX_SUCCESS) {
            printk(&amp;quot;Pin IRQ init success\r\n&amp;quot;);
        } else {
            printk(&amp;quot;FAIL: pin IRQ init failed: %d\r\n&amp;quot;, err);
            return false;
        }
    }
.
.   nrfx_gpiote_in_config_t irq_config = NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); // TODO: what is argument?
    err = nrfx_gpiote_in_init(PIN_DRDY, &amp;amp;irq_config, data_ready_handler);

    if(err == NRFX_SUCCESS) {
        printk(&amp;quot;Pin IRQ config success\r\n&amp;quot;);
    } else {
        printk(&amp;quot;FAIL: pin IRQ config failed: %d\r\n&amp;quot;, err);
        return false;
    }
.
    nrfx_gpiote_in_event_enable(PIN_DRDY, true);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;When I put a breakpoint at the start of the `data_ready_handler` function and run in debug mode, I never trigger the breakpoint, while seeing multiple pulses on the input signal.&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1643283917547v2.png" /&gt;&lt;/p&gt;
&lt;p&gt;Do you have any idea what this issue might be?&lt;/p&gt;
&lt;p&gt;Thanks again&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;EDIT: Forgot to copy a couple of lines of code.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/348769?ContentTypeID=1</link><pubDate>Thu, 20 Jan 2022 15:13:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:aff968d7-abd7-4789-893a-cacc6f418751</guid><dc:creator>MickyT</dc:creator><description>&lt;p&gt;Thank you for your&amp;nbsp;reply.&lt;br /&gt;I will have access to an oscilloscope next week, so I will check that and get back to you with that result.&lt;/p&gt;
&lt;p&gt;For now it is just a simple test setup with jumper wires and a breadboard. I already swapped the cable ones, but I will try that again to eliminate that option.&lt;/p&gt;
&lt;p&gt;The ground wire is connected between the 3 devices.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Can't get SPI communication to work on the nrf5340-dk</title><link>https://devzone.nordicsemi.com/thread/348674?ContentTypeID=1</link><pubDate>Thu, 20 Jan 2022 11:10:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f4df485a-5eea-422e-a91b-bbff837b55c1</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;If your clock and data line have inconsistent timings then your signal integrity is far too low. This is most likely a HW issue. Do you have access to an oscilloscope? An analog scope of the clock signal would be of great help.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Typical HW issues that affect signal integrity are poor grounding, parasitic/stray capacitance, and EMI.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
[quote user=""]Remove connection to sensor (so only connected to LA), same result[/quote]
&lt;p&gt;This is strange, I would expect the DK to have sufficient signal integrity in the layout. How do you connect the DA to the DK? Did you remember to connect the DA&amp;#39;s ground lead to DK&amp;#39;s ground?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>