GPIOTE trigger of SPIM read using EasyDMA with manual CS

I’m using NRF Connect SDK 3.2.4 with the nRF54L15-DK. I’ve successfully used the nrfx_gppi_conn_alloc() and  nrfx_gppi_conn_enable() APIs to connect a timer to a GPIOTE output. That output is on P1.12 and it drives ADC conversion control to an ADC IC. The ADC in turn drives the DRDY line to the nRF54L15 P1.11. I now want to have a GPIOTE input on pin 1.11 trigger a SPIM read using manual chip select control. As a first step I’m just trying to toggle the SPIM_CS_PIN (task) using the DRDY_PIN_TOGGLE event. I realize that I will likely have to add a timer to meet the CS timing requirements of the ADC IC, but first things first. I ‘ve spent too much time on this and think I’m doing everything right. Can someone point out what I’m missing. Thank you.

prj.conf

CONFIG_NCS_SAMPLES_DEFAULTS=y
CONFIG_ESB=y
CONFIG_DK_LIBRARY=y
CONFIG_CLOCK_CONTROL=y
CONFIG_ESB_MAX_PAYLOAD_LENGTH=252
#CONFIG_ESB_TX_FIFO_SIZE=10
#CONFIG_ESB_RX_FIFO_SIZE=10
CONFIG_CRC=y
CONFIG_ESB_FAST_CHANNEL_SWITCHING=y
CONFIG_ESB_FAST_SWITCHING=y
#CONFIG_ESB_NEVER_DISABLE_TX=y
CONFIG_FPU=y
CONFIG_CBPRINTF_FP_SUPPORT=y
#CONFIG_SPI=y
CONFIG_TIMING_FUNCTIONS=y
CONFIG_ENTROPY_GENERATOR=y

CONFIG_SPI=n
CONFIG_NRFX_SPIM=y

CONFIG_GPIO=y

# Disable LFXO (external 32kHz crystal)
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n

# Enable LFRC (internal RC oscillator)
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y

# Select RC Accuracy (500ppm is typical for internal, can be 250ppm or 500ppm)
CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y

# Enable calibration to improve accuracy (highly recommended)
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y

# Set LFRC frequency
CONFIG_CLOCK_CONTROL_NRF_K32SRC_FREQUENCY=32768

CONFIG_NRFX_TIMER=y

CONFIG_NRFX_GPPI=y

# CONFIG_SPI_ASYNC=y

device tree overlay

&uicr {
	nfct-pins-as-gpios;
};

/ {
	gpi {
		compatible = "gpio-keys";

		drdy: drdy {
			gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
			label = "ADS9324 DRDY";
		};
	};

	gpo {
		compatible = "gpio-leds";

		reset: reset {
			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
			label = "ADS9324 RESET";
		};

		convst: convst {
			gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
			label = "ADS9324 CONVST";
		};
	};

	aliases {
		reset = &reset;
		convst = &convst;
		drdy = &drdy;
	};
};

&nfct {
Relevant code snippet
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void drdy_init(nrfx_gppi_handle_t* gppi_h) {

	int err;
	
	uint8_t gppi_channel;
	
	uint8_t in_channel;

	uint8_t out_channel;
	
	// ---------------------------------------
	// INIT GPIOTE
	// ---------------------------------------	
	//IRQ_DIRECT_CONNECT(GPIOTE20_0_IRQn, IRQ_PRIO_LOWEST, gpiote_20_direct_isr, 0);
    //IRQ_DIRECT_CONNECT(GPIOTE20_1_IRQn, IRQ_PRIO_LOWEST, gpiote_20_direct_isr, 0);
  
	if(!nrfx_gpiote_init_check(&gpiote_inst))
	{		
		//err = nrfx_gpiote_init(&gpiote_inst, IRQ_PRIO_LOWEST);
		err = nrfx_gpiote_init(&gpiote_inst, NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);		
		if (err != 0) {
			LOG_ERR("GPIOTE init fail: %x", err);	
		}
		LOG_INF("GPIOTE status: %s", nrfx_gpiote_init_check(&gpiote_inst) ? "initialized" : "not initialized");
	}

   //irq_enable(GPIOTE20_1_IRQn);

	// ---------------------------------------
	// DRDY Input
	// ---------------------------------------	
	err = nrfx_gpiote_channel_alloc(&gpiote_inst, &in_channel);
	if (err != 0) {
		LOG_ERR("Channel alloc fail: %x", err);	
	}

	static const nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLDOWN;

	nrfx_gpiote_trigger_config_t trigger_config = {
		.trigger = NRFX_GPIOTE_TRIGGER_LOTOHI,
		.p_in_channel = &in_channel
  	};

	// static const nrfx_gpiote_handler_config_t handler_config = {
	// 	.handler = gpiote_evt_handler,
    // 	.p_context = NULL
	// };

  	nrfx_gpiote_input_pin_config_t gpiote_in_cfg = {
		.p_pull_config = &pull_config,
    	.p_trigger_config = &trigger_config,
    	.p_handler_config = NULL
  	};

	// We want drdy input from ADC to trigger a SPI read 
  	err = nrfx_gpiote_input_configure(&gpiote_inst, DRDY_PIN, &gpiote_in_cfg);
	if (err != 0) {
		LOG_ERR("GPIOTE configure fail: %x", err);	
	}	
	
	nrfx_gpiote_trigger_enable(&gpiote_inst, DRDY_PIN, false);	

	// ---------------------------------------
	// SPIM CS Output
	// ---------------------------------------	
	err = nrfx_gpiote_channel_alloc(&gpiote_inst, &out_channel);
	if (err != 0) {
		LOG_ERR("Channel alloc fail: %x", err);	
	}
	
	nrfx_gpiote_output_config_t gpiote_out_cfg = {
		.drive = NRF_GPIO_PIN_S0S1,
		.input_connect = NRF_GPIO_PIN_INPUT_DISCONNECT,
		.pull = NRF_GPIO_PIN_NOPULL,
	};

	nrfx_gpiote_task_config_t gpiote_task_cfg = {
		.task_ch = out_channel,
		.polarity = GPIOTE_CONFIG_POLARITY_Toggle,
		.init_val = NRF_GPIOTE_INITIAL_VALUE_HIGH,
	};	

	err = nrfx_gpiote_output_configure(&gpiote_inst, SPIM_CS_PIN, &gpiote_out_cfg, &gpiote_task_cfg);
	if (err != 0) {
		LOG_ERR("GPIOTE configure fail: %x", err);	
	}	
	
	// // // ---------------------------------------
	// // // INIT SPI
	// // // ---------------------------------------
	// nrfx_spim_xfer_desc_t adc_xfer_desc;	

	// adc_xfer_desc.p_tx_buffer  = NULL;
	// adc_xfer_desc.tx_length    = 0;
	// adc_xfer_desc.p_rx_buffer  = adc_buff;
	// adc_xfer_desc.rx_length    = 16;	
    
    // uint32_t flags = NRFX_SPIM_FLAG_HOLD_XFER    |
    //                  NRFX_SPIM_FLAG_REPEATED_XFER|
    //                  NRFX_SPIM_FLAG_RX_POSTINC   |
    //                  NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER;
    
    // err = nrfx_spim_xfer(&spi_inst, &adc_xfer_desc, flags);
	// if (err != 0) {		
	// 	LOG_ERR("SPIM transfer failed: %i", err);
	// 	return err;
	// }

	// // ---------------------------------------
	// // 3. CONNECT GPIOTE w/ SPIM via GPPI
	// // ---------------------------------------
	// err = nrfx_gppi_conn_alloc(    
    // 	nrfx_gpiote_in_event_address_get(&gpiote_inst, DRDY_PIN), 
	// 	nrfx_spim_start_task_address_get(&spi_inst), gppi_h);		
		
    // if (err != 0) {
	// 	LOG_ERR("GPPI channel allocation fail: %x", err);	
	// }	
	
	err = nrfx_gppi_conn_alloc( 
		nrfx_gpiote_in_event_address_get(&gpiote_inst, DRDY_PIN),
		nrfx_gpiote_set_task_address_get(&gpiote_inst, SPIM_CS_PIN), gppi_h);		
		
    if (err != 0) {
		LOG_ERR("GPPI channel allocation fail: %x", err);	
	}

	// err = nrfx_gppi_conn_alloc( 
	// 	nrfx_spim_end_event_address_get(&spi_inst),
	// 	nrfx_gpiote_set_task_address_get(&gpiote_inst, SPIM_CS_PIN), gppi_h);				

    // if (err != 0) {
	// 	LOG_ERR("GPPI channel allocation fail: %x", err);	
	// }
	
	nrfx_gpiote_trigger_enable(&gpiote_inst, DRDY_PIN, false);	
	nrfx_gpiote_out_task_enable(&gpiote_inst, SPIM_CS_PIN);
	nrfx_gppi_conn_enable(*gppi_h);


}
Related