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

Control of SS pin of SPI with ppi.

Hi.

Development platform : nRF52833-DK, s113, SDK 16.0.0, IAR 8.31.1

I am making an example of periodically reading sensor data using SPI. 

The SPI is triggered through PPI.

static const nrf_drv_spi_t heater_volt_spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE_ID);  /**< SPI instance. */



void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
   // Get spi data...
}


static ret_code_t spi_init(void)
{

  nrf_drv_spi_config_t spi_config =
  {
      .sck_pin        = SPI_SCK_RVAC,
      .mosi_pin       = NRF_DRV_SPI_PIN_NOT_USED,
      .miso_pin       = SPI_MISO_RVAC,
      .ss_pin         = NRF_DRV_SPI_PIN_NOT_USED,
      .irq_priority   = APP_IRQ_PRIORITY_HIGH,
      .orc            = 0xFF,
      .frequency      = NRF_DRV_SPI_FREQ_8M,
      .mode           = NRF_DRV_SPI_MODE_0,
      .bit_order      = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST
  };

  APP_ERROR_CHECK(nrf_drv_spi_init(&heater_volt_spi, &spi_config, spi_event_handler, NULL));

 nrf_drv_spi_xfer_desc_t xfer = NRF_DRV_SPI_XFER_TRX(NULL, 0, m_volt_rx_buf, 2);
 
 uint32_t flags = NRF_DRV_SPI_FLAG_HOLD_XFER           |
//              NRF_DRV_SPI_FLAG_RX_POSTINC          |
//              NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER |
              NRF_DRV_SPI_FLAG_REPEATED_XFER;
              
 nrf_drv_spi_xfer(&heater_volt_spi, &xfer, flags);


// Set PPI

    ret_code_t err_code;
    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);


    uint32_t timer2_compare_event_addr = nrf_drv_timer_event_address_get(&m_timer2, NRF_TIMER_EVENT_COMPARE0);
    uint32_t start_tsk_addr = nrf_drv_spi_start_task_get(&heater_volt_spi);

    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_voltage_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(m_ppi_voltage_channel, timer2_compare_event_addr, start_tsk_addr);
    APP_ERROR_CHECK(err_code);


 return NRF_SUCCESS;
}



static void timer2_init(void)
{
    // Check TIMER2 configuration for details.
    nrf_drv_timer_config_t timer_cfg =     {                                                                                    \
        .frequency          = (nrf_timer_frequency_t)NRF_TIMER_FREQ_16MHz,
        .mode               = (nrf_timer_mode_t)NRF_TIMER_MODE_TIMER,          
        .bit_width          = (nrf_timer_bit_width_t)NRF_TIMER_BIT_WIDTH_32,
        .interrupt_priority = 0,                    
        .p_context          = NULL                                                       
    };
    
    ret_code_t err_code = nrf_drv_timer_init(&m_timer2, &timer_cfg, empty_timer_handler);
    APP_ERROR_CHECK(err_code);


nrf_drv_timer_extended_compare(&m_timer2,
                               NRF_TIMER_CC_CHANNEL0,
                               nrf_drv_timer_us_to_ticks(&m_timer2,
                                                         500),  // #####
                               NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                               false);
}



void heater_driver_init(void)
{

  spi_init();

  timer2_init();

    err_code = nrf_drv_ppi_channel_enable(m_ppi_voltage_channel);
    APP_ERROR_CHECK(err_code);


  nrf_drv_timer_enable(&m_timer2);


}


timer2 operates at 500us cycle.

Transmission of spi is started by NRF_TIMER_EVENT_COMPARE0 of timer2.

My problem is to control the SS pin of SPI.

I think SS pin high can be done in spi_event_handler().

How can I set the SS pin low?

Thanks...

Parents Reply Children
  • Hi. 

    I solved it by using GPIOTE as below.
    Thank you for your advice.

    void power_sampling_event_init(void)
    {
    {
        nrfx_gpiote_out_config_t config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
    
        uint32_t start_task_addr = nrf_drv_spi_start_task_get(&heater_volt_spi);
        uint32_t gpiote_task_addr;
    
        err_code = nrf_drv_gpiote_out_init(SPI_nCS_RVAC, &config);
        APP_ERROR_CHECK(err_code);
    
        gpiote_task_addr = nrfx_gpiote_clr_task_addr_get(SPI_nCS_RVAC);
    
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_voltage_channel);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_assign(m_ppi_voltage_channel, timer2_compare_event_addr, start_task_addr);
        APP_ERROR_CHECK(err_code);
        
        err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_voltage_channel, gpiote_task_addr);
        APP_ERROR_CHECK(err_code);
    }
    
    
    {
      uint32_t start_event_addr = nrf_drv_spi_end_event_get(&heater_volt_spi);
      uint32_t gpiote_task_addr;
      
      gpiote_task_addr = nrfx_gpiote_set_task_addr_get(SPI_nCS_RVAC);
    
      err_code = nrf_drv_ppi_channel_alloc(&m_ppi_voltage_nCS_channel);
      APP_ERROR_CHECK(err_code);
      
      err_code = nrf_drv_ppi_channel_assign(m_ppi_voltage_nCS_channel, start_event_addr, gpiote_task_addr);
      APP_ERROR_CHECK(err_code);
    
    }
    
        err_code = nrf_drv_ppi_channel_enable(m_ppi_voltage_channel);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_enable(m_ppi_voltage_nCS_channel);
        APP_ERROR_CHECK(err_code);
        
        nrf_drv_gpiote_out_task_enable(SPI_nCS_RVAC);
    
    }
    

Related