<?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>Problems about spidma buffer！！！</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/72054/problems-about-spidma-buffer</link><description>Hi, NODRDICSEMI 
 Now I use PPI + gpiote (spidma) to make the hardware read and write by itself. But after I enabled RX list, I found that when the amount of data read exceeds the RX buffer I set, RX buffer will not be updated.So 
 1、How do I know if</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 03 Mar 2021 08:18:24 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/72054/problems-about-spidma-buffer" /><item><title>RE: Problems about spidma buffer！！！</title><link>https://devzone.nordicsemi.com/thread/297383?ContentTypeID=1</link><pubDate>Wed, 03 Mar 2021 08:18:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:93a12647-0070-4488-b9a2-ab6a36e60f11</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Thanks for sharing code snippet. It looks like you want to set up a repated transfer with the &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrf__drv__spi.html#ga04d52f429a0d5a6e965269c5ec524c90"&gt;NRF_DRV_SPI_FLAG_RX_POSTINC&lt;/a&gt;&lt;span&gt; &lt;/span&gt;flag, similiar to the scenario described in the driver documentation:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;em&gt;The following example shows how to set up a sequence of SPI transfers that will be triggered using PPI (for example, using RTC or TIMER compare events). A single transfer consists of a transmission of 1 byte and a reception of 3 bytes. The TX data is repeated for all transfers, but the RX data from all transfers is collected in the buffer. Therefore, &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrf__drv__spi.html#ga04d52f429a0d5a6e965269c5ec524c90"&gt;NRF_DRV_SPI_FLAG_RX_POSTINC&lt;/a&gt; is set so that the buffer address for the received data is incremented. The end of sequence is controlled externally, and the processing of data is postponed until the end of the sequence (the user event handler is disabled). (&lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/hardware_driver_spi_master.html"&gt;link&lt;/a&gt;)&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But I don&amp;#39;t see any calls to &lt;a title="Function for starting the SPI data transfer with additional option flags." href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrf__drv__spi.html#ga246c63788b99226c561bfddd45289372"&gt;nrf_drv_spi_xfer&lt;/a&gt;() in the code you posted.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problems about spidma buffer！！！</title><link>https://devzone.nordicsemi.com/thread/296627?ContentTypeID=1</link><pubDate>Fri, 26 Feb 2021 17:08:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:da05a285-0d18-4308-8938-fa90b7b7aa41</guid><dc:creator>June6</dc:creator><description>&lt;p&gt;Hi, Vidar&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define DMA_TX_BUFFER_SIZE 2
#define DMA_RX_BUFFER_SIZE 80001

typedef struct {
  uint32_t spi_evt_addr;
  uint32_t spi_task_addr;
  uint32_t gpiote_evt_addr;
  uint32_t gpiote_task_addr;
} ppi_addr_t;

typedef struct ArrayList {
  uint8_t tx_buffer[DMA_TX_BUFFER_SIZE];
  uint8_t rx_buffer[DMA_RX_BUFFER_SIZE];
} ArrayList_type;

ppi_addr_t ppi_addr;
ArrayList_type spi_dma_list;
nrf_drv_spi_t spi_0 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE_0);

uint32_t ppi_init(void) {
  uint32_t err_code;
  nrf_ppi_channel_t ppi_channel1, ppi_channel2, ppi_channel3;
  uint32_t gpiote_evt_addr, spi_evt_addr, gpiote_task_addr, spi_task_addr;

  err_code = nrf_drv_ppi_init();
  APP_ERROR_CHECK(err_code);

  gpiote_evt_addr = ppi_addr.gpiote_evt_addr;
  gpiote_task_addr = ppi_addr.gpiote_task_addr;
  spi_evt_addr = ppi_addr.spi_evt_addr;
  spi_task_addr = ppi_addr.spi_task_addr;

  err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel1);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel2);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel3);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_alloc(&amp;amp;ppi_channel4);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_assign(ppi_channel1, gpiote_evt_addr,
                                        gpiote_task_addr);
  APP_ERROR_CHECK(err_code);

  err_code =
      nrf_drv_ppi_channel_assign(ppi_channel2, gpiote_evt_addr, spi_task_addr);
  APP_ERROR_CHECK(err_code);

  err_code =
      nrf_drv_ppi_channel_assign(ppi_channel3, spi_evt_addr, gpiote_task_addr);
  APP_ERROR_CHECK(err_code);

  /* Enable configured PPI channel */
  err_code = nrf_drv_ppi_channel_enable(ppi_channel1);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_enable(ppi_channel2);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_enable(ppi_channel3);
  APP_ERROR_CHECK(err_code);

  return NRF_SUCCESS;
}

uint32_t ppi_uninit(void) {
  uint32_t err_code;
  nrf_ppi_channel_t ppi_channel1, ppi_channel2, ppi_channel3;

  /* Disable configured PPI channel */
  err_code = nrf_drv_ppi_channel_disable(ppi_channel1);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_disable(ppi_channel2);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_disable(ppi_channel3);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_free(ppi_channel1);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_free(ppi_channel2);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_ppi_channel_free(ppi_channel3);
  APP_ERROR_CHECK(err_code);

  memset(&amp;amp;ppi_addr, 0, sizeof(ppi_addr));

  err_code = nrf_drv_ppi_uninit();
  APP_ERROR_CHECK(err_code);

  return NRF_SUCCESS;
}

static void spi_event_handler(nrf_drv_spi_evt_t const *p_event,
                              void *p_context) {
                              
}

/**
 * @brief platform specific initialization (platform dependent)
 */
static uint32_t spi_init(void) {
  nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
  spi_config.ss_pin = SPI_CS_PIN;
  spi_config.miso_pin = SPI_MISO_PIN;
  spi_config.mosi_pin = SPI_MOSI_PIN;
  spi_config.sck_pin = SPI_SCK_PIN;
    
  APP_ERROR_CHECK(
      nrf_drv_spi_init(&amp;amp;spi_0, &amp;amp;spi_config, spi_event_handler, NULL));
    
  ppi_addr.spi_evt_addr = nrf_drv_spi_end_event_get(&amp;amp;spi_0);
  ppi_addr.spi_task_addr = nrf_drv_spi_start_task_get(&amp;amp;spi_0);
}

void spi_data_dma_set(void) {
  uint8_t reg = 0xA8; 

  memset(&amp;amp;spi_dma_list, 0, sizeof(spi_dma_list));
  spi_dma_list.tx_buffer[0] = reg;
  nrf_spim_tx_buffer_set(spi_0.u.spim.p_reg, spi_dma_list.tx_buffer, 1);
  nrf_spim_rx_buffer_set(spi_0.u.spim.p_reg, spi_dma_list.rx_buffer, 3);
  /* TODO Confirm whether it is normal */
  nrf_spim_event_clear(spi_0.u.spim.p_reg, NRF_SPIM_EVENT_END);
}

void spi_list_set(void) {
  nrf_spim_tx_list_disable(spi_0.u.spim.p_reg);
  nrf_spim_rx_list_enable(spi_0.u.spim.p_reg);
}

void gpiote_in_evt_enable(void) {
  nrf_drv_gpiote_in_event_enable(SPI_INT_PIN, true);
}

void gpiote_in_evt_disable(void) {
  nrf_drv_gpiote_in_event_disable(SPI_INT_PIN);
}

void gpiote_out_task_enable(void) {
  nrf_drv_gpiote_out_task_enable(SPI_CS_PIN);
}

void gpiote_out_task_disable(void) {
  nrf_drv_gpiote_out_task_disable(SPI_CS_PIN);
}

static void in_pin_handler(nrf_drv_gpiote_pin_t pin,
                           nrf_gpiote_polarity_t action) {
  if (pin == SPI_ACCEL_INT_PIN)
    ;
}

ret_code_t gpiote_init(void) {
  ret_code_t err_code;

  if (!nrf_drv_gpiote_is_init()) {
    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);
  }
  nrf_drv_gpiote_in_config_t in_config_0 = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
  in_config_0.pull = NRF_GPIO_PIN_PULLUP;
  /* When configuration conversion occurs, no callback is generated and PPI is
   * used instead */
  err_code =
      nrf_drv_gpiote_in_init(SPI_ACCEL_INT_PIN, &amp;amp;in_config_0, in_pin_handler);
  APP_ERROR_CHECK(err_code);

  /* The initial state is high */
  nrf_drv_gpiote_out_config_t out_config_0 =
      GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
  err_code = nrf_drv_gpiote_out_init(SPI_CS_PIN, &amp;amp;out_config_0);
  APP_ERROR_CHECK(err_code);

  ppi_addr.gpiote_evt_addr =
      nrf_drv_gpiote_in_event_addr_get(SPI_INT_PIN);
  ppi_addr.gpiote_task_addr =
      nrf_drv_gpiote_out_task_addr_get(SPI_CS_PIN);
      
  gpiote_in_evt_enable();
  gpiote_out_task_enable();

  return NRF_SUCCESS;
}

void gpiote_uninit(void) {
  gpiote_in_evt_disable();
  nrf_drv_gpiote_in_uninit(SPI_INT_PIN);
  gpiote_out_task_disable();
  nrf_drv_gpiote_out_uninit(SPI_CS_PIN);
}

int main(void) {
  spi_init();
  spi_data_dma_set();
  spi_list_set();
  gpiote_init();
  ppi_init();
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The above is the SPI DMA part of the code, other parts involved too much, temporarily difficult to share.&lt;/p&gt;
&lt;p&gt;Do you think there is any problem with the above code?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;After using SPI DMA, I have successfully exchanged data with the sensor, but at present I still get the data in SPI RX buffer regularly. I hope that I can be informed when the RX buffer is full, so that I can get the data without a timer.&lt;/p&gt;
&lt;p&gt;And I didn&amp;#39;t find &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrf__drv__spi.html#gaae9428e15bb640d2944b3950d0f894f0"&gt;NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER&lt;/a&gt;&amp;nbsp;flag in the structure parameter(*p_event) of SPI interrupt callback function(spi_event_handler).&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;June6&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Problems about spidma buffer！！！</title><link>https://devzone.nordicsemi.com/thread/296569?ContentTypeID=1</link><pubDate>Fri, 26 Feb 2021 13:45:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2863d435-2ffb-4779-84a8-3ba1b8212f94</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;Are you able to share the code you are using to set up the transfers here? Preferably the full project so I can more easily replicate the problem on my side.&lt;/p&gt;
&lt;p&gt;Normally you should get a event once the specified read buffer is full, but it is also possible to configure the driver to not use interrupts (with the &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrf__drv__spi.html#gaae9428e15bb640d2944b3950d0f894f0"&gt;NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER&lt;/a&gt; flag).&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>