<?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>No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/18645/no-slave-select-on-spim-xfer-using-ppi-and-gpiote</link><description>I have a custom board that has an MPU9250 attached as a SPI device. The MPU can generate data ready interrupts. I have set the MPU to generate data ready 4x per second which is about the slowest it can run. 
 I am using SDK 12.2.0 and I have modified</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 23 Feb 2017 10:29:59 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/18645/no-slave-select-on-spim-xfer-using-ppi-and-gpiote" /><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72031?ContentTypeID=1</link><pubDate>Thu, 23 Feb 2017 10:29:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5aafbd12-6b51-448d-a375-884805c60943</guid><dc:creator>Alessandro</dc:creator><description>&lt;p&gt;Rusty thanks for this. I used part of your code to transfer more than 255 bytes with spi master &lt;a href="https://devzone.nordicsemi.com/question/116869/transfer-more-than-255-bytes-with-spi-master-on-nrf52/"&gt;devzone.nordicsemi.com/.../&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72030?ContentTypeID=1</link><pubDate>Tue, 24 Jan 2017 14:24:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ab8bb634-22e4-40e4-81e0-4f3ec6ab20b5</guid><dc:creator>Petter Myhre</dc:creator><description>&lt;p&gt;Great that you got it working, and thanks for sharing :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72029?ContentTypeID=1</link><pubDate>Tue, 24 Jan 2017 01:17:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:415c41d1-d774-42b8-bb14-99bce6f97d39</guid><dc:creator>Rusty Scott</dc:creator><description>&lt;p&gt;So I tried the suggestion from Petter Myhre in the comments to my original question, and used the fork to trigger both the slave select toggle task and the SPI start task.  My initial concern was that slave select would need time to be low before the clock started,  so I made the slave select task the main task in the PPI, and the SPI start the forked task.  This works exactly as intended. My SPI end event triggers the SS toggle task to raise the select again.  I have attached the changed functions from my main above for anyone interested.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static void ppi_setup()
{
    uint32_t int_evt_addr;
    uint32_t cs_task_addr;
    uint32_t spi_evt_addr;
    uint32_t spi_task_addr;
    uint32_t gpiote_task_addr;
    ret_code_t err_code;
    nrf_drv_gpiote_out_config_t config_led_out = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); // start low             
    nrf_drv_gpiote_out_config_t config_cs_out = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); // Start high

    err_code = nrf_drv_gpiote_out_init(GPIO_OUTPUT_PIN_NUMBER, &amp;amp;config_led_out);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_gpiote_out_init(SPI0_CONFIG_SS_PIN, &amp;amp;config_cs_out);
    APP_ERROR_CHECK(err_code);

    // Setup the input interrupt pin
    nrf_drv_gpiote_in_config_t config_in = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    err_code = nrf_drv_gpiote_in_init(MPU_INT_PIN, &amp;amp;config_in, NULL); // No handler function
    APP_ERROR_CHECK(err_code);
    
    // allocate PPI channels for hardware
    err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel_int);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel_toggle);
    APP_ERROR_CHECK(err_code);

    int_evt_addr = nrf_drv_gpiote_in_event_addr_get(MPU_INT_PIN);
    cs_task_addr = nrf_drv_gpiote_out_task_addr_get(SPI0_CONFIG_SS_PIN);
    spi_task_addr = nrf_drv_spi_start_task_get(&amp;amp;m_spi_instance);
    err_code = nrf_drv_ppi_channel_assign(ppi_channel_int, int_evt_addr, cs_task_addr);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_fork_assign(ppi_channel_int, spi_task_addr);
    APP_ERROR_CHECK(err_code);

    spi_evt_addr = nrf_drv_spi_end_event_get(&amp;amp;m_spi_instance);
    gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(GPIO_OUTPUT_PIN_NUMBER);

    err_code = nrf_drv_ppi_channel_assign(ppi_channel_toggle, spi_evt_addr, cs_task_addr);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_fork_assign(ppi_channel_toggle, gpiote_task_addr);
    APP_ERROR_CHECK(err_code);
}

void transfer_enable()
{
    ret_code_t err_code;
    // end to front
    nrf_drv_gpiote_out_task_enable(GPIO_OUTPUT_PIN_NUMBER);
    nrf_drv_gpiote_out_task_enable(SPI0_CONFIG_SS_PIN);
    err_code = nrf_drv_ppi_channel_enable(ppi_channel_toggle);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(ppi_channel_int);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(MPU_INT_PIN,true);
}

void transfer_disable()
{
    ret_code_t err_code;
    
    nrf_drv_gpiote_in_event_disable(MPU_INT_PIN);
    err_code = nrf_drv_ppi_channel_disable(ppi_channel_int);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_disable(ppi_channel_toggle);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_out_task_disable(GPIO_OUTPUT_PIN_NUMBER);
    nrf_drv_gpiote_out_task_disable(SPI0_CONFIG_SS_PIN);
}
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72028?ContentTypeID=1</link><pubDate>Sat, 07 Jan 2017 08:57:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:980e185c-8daf-4846-93e9-75837aed7a2d</guid><dc:creator>Petter Myhre</dc:creator><description>&lt;p&gt;Give it a try, and let me know if you get into trouble, and really great if you share your solution. We always try to improve, so if you have specific feedback we love to have it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72027?ContentTypeID=1</link><pubDate>Fri, 06 Jan 2017 17:02:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f0af75d5-ea51-4aec-a2c5-fa7baad9d728</guid><dc:creator>Rusty Scott</dc:creator><description>&lt;p&gt;I will give that a try. If it works I will post here as an answer.  I will say, as an embedded programmer with 20 years experience, I like the innovation and functionality Nordic has in this part, but the documentation is scattered and hard to follow at times.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72026?ContentTypeID=1</link><pubDate>Fri, 06 Jan 2017 11:48:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fae86dc9-2f59-4ae1-8de0-98b400c075b5</guid><dc:creator>Petter Myhre</dc:creator><description>&lt;p&gt;No, the SPIM does not implement support for slave select directly. Maybe you can try forking the GPIOTE event from the interrupt to a GPIOTE task that sets SS? And forking the SPIM event end to a GPIOTE task that clears the SS? You can fork with nrf_drv_ppi_channel_fork_assign().&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72025?ContentTypeID=1</link><pubDate>Thu, 05 Jan 2017 21:17:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5ed8f374-f010-47af-8fe8-471a3ce6a608</guid><dc:creator>Rusty Scott</dc:creator><description>&lt;p&gt;It is appearing like slave select isn&amp;#39;t really under hardware control then. So doing repeated spim xfers triggered by a gpiote pin event really isn&amp;#39;t possible without interrupting the CPU.  Slave select must go high between each transfer. I can still use the interrupt, but I will probably need to call nrf_spi_xfer again after each single xfer.  Can you or someone else with Nordic confirm that this is indeed the case?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: No slave select on SPIM xfer using PPI and GPIOTE</title><link>https://devzone.nordicsemi.com/thread/72024?ContentTypeID=1</link><pubDate>Mon, 02 Jan 2017 11:15:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6ed00d15-35d6-4dc0-a08e-13e8f4328d60</guid><dc:creator>Petter Myhre</dc:creator><description>&lt;p&gt;Which pin are you using for SS? Have you tried to use the debugger to see if you hit nrf_gpio_pin_clear(p_cb-&amp;gt;ss_pin); inside nrf_drv_spi_xfer()?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>