adafruit / Adafruit_nRF52_Arduino

Adafruit code for the Nordic nRF52 BLE SoC on Arduino
Other
601 stars 489 forks source link

Request for SPI Slave support as it requires IRQ from nrfx drivers #753

Closed HarshalSonar1 closed 1 year ago

HarshalSonar1 commented 1 year ago

Problem: Currently, there is SPI Master support on SPIM2 and SPIM3 (32Mhz) However, I need to use nrf52840 as a SPIS2 slave device in support, while also needing SPIM3 a local data writing on a QSPI flash. I2C0 and I2C1 are already taken for the peripheral sensor systems.

Describe the solution you'd like There is no simple adaptation I could use while relying on the Arduino compatible code base of nrf52 for using SPI slave. If there is any simple solution or preexisting snippets that may help community needing similar uses, it would go long way.

Describe alternatives you've considered So far I tried SPIS library from nrf_SDK @V2.12 that has a sample code, however they use nrf_drv_spis.h locally defined instead of nrfx_spis.h complecating the understanding and merging possibilities with Adafruit_nRF52_Arduino code base.

Additional context Add any other context or screenshots about the feature request here.

nosv-dr commented 1 year ago

Adding SPIS driver from NRF SDK https://github.com/adafruit/Adafruit_nRF52_Arduino/pull/767

Sample code snippet:

#define SPIS_INSTANCE 0                                            /**< SPIS instance index. */
static const nrfx_spis_t spis = NRFX_SPIS_INSTANCE(SPIS_INSTANCE); /**< SPIS instance. */

static const uint8_t m_length = 16; /**< Transfer length. */
static uint8_t m_rx_buf[m_length];  /**< RX buffer. */

static volatile bool spis_xfer_done; /**< Flag used to indicate that SPIS instance completed the transfer. */
static volatile int m_rx_bufPos = 0;

void spis_event_handler(nrfx_spis_evt_t const* event, void* context) {
  if ((*event).evt_type == NRFX_SPIS_XFER_DONE)
  {
    m_rx_bufPos = (*event).rx_amount - 1;

    spis_xfer_done = true;
  }
}

void setup(void) {
  nrfx_spis_config_t spis_config = NRFX_SPIS_DEFAULT_CONFIG(SPIS_SCK_PIN, SPIS_MOSI_PIN, NRFX_SPIS_PIN_NOT_USED, SPIS_CS_PIN);

  nrfx_err_t result = nrfx_spis_init(&spis, &spis_config, spis_event_handler, (void*)NULL);

  if (result > NRFX_ERROR_BASE_NUM)
  {
    DEBUG_PRINT(" Error:");
    DEBUG_PRINTLN(result);
  }

  spis_xfer_done = true;
}

void loop(void) {
  if (spis_xfer_done)
  {
    parseBuf(m_rx_buf, m_rx_bufPos + 1);

    spis_xfer_done = false;
    nrfx_err_t result = nrfx_spis_buffers_set(&spis, (uint8_t*)NULL, 0, m_rx_buf, m_length);

    if (result > NRFX_ERROR_BASE_NUM)
    {
      DEBUG_PRINT(" Error:");
      DEBUG_PRINTLN(result);
    }
  }
}
hathach commented 1 year ago

probably fixed by #767

HarshalSonar1 commented 1 year ago

Thanks a lot, It works. Hope this helps others. May be there can be a small example in SPI_Slave communication mode as library package