This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Testing variations of int num_events & k_timeout_t timeout arguments in k_poll API for "spi_transceive_async"

Hello,

Let me just briefly state that I have referred to required documentation and also executed spi_transceive_async() test, at zephyr\tests\drivers\spi\spi_loopback.
So request to kindly not suggest going back to documentation or trying sample program.

My question is I want to test  variations of int num_events & k_timeout_t timeout arguments in k_poll API for "spi_transceive_async".

As in what happens if i vary num_events  & what happens  if i vary timeout ...?

And how can I get this variation to reflect on "spi_transceive_async"..?

I need to know how to vary and test the sample code at zephyr\tests\drivers\spi\spi_loopback:
As In,

#if (CONFIG_SPI_ASYNC)
static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER(async_sig);
static struct k_poll_event async_evt =
	K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
				 K_POLL_MODE_NOTIFY_ONLY,
				 &async_sig);
static K_SEM_DEFINE(caller, 0, 1);
K_THREAD_STACK_DEFINE(spi_async_stack, STACK_SIZE);
static int result = 1;

static void spi_async_call_cb(struct k_poll_event *async_evt,
			      struct k_sem *caller_sem,
			      void *unused)
{
	int ret;

	LOG_DBG("Polling...");

	while (1) {
		ret = k_poll(async_evt, 10, K_MSEC(2000)); /***** varied here ******/
		zassert_false(ret, "one or more events are not ready");

		result = async_evt->signal->result;
		k_sem_give(caller_sem);

		/* Reinitializing for next call */
		async_evt->signal->signaled = 0U;
		async_evt->state = K_POLL_STATE_NOT_READY;
	}
}

static int spi_async_call(const struct device *dev,
			  struct spi_config *spi_conf)
{
	const struct spi_buf tx_bufs[] = {
		{
			.buf = buffer_tx,
			.len = BUF_SIZE,
		},
	};
	const struct spi_buf rx_bufs[] = {
		{
			.buf = buffer_rx,
			.len = BUF_SIZE,
		},
	};
	const struct spi_buf_set tx = {
		.buffers = tx_bufs,
		.count = ARRAY_SIZE(tx_bufs)
	};
	const struct spi_buf_set rx = {
		.buffers = rx_bufs,
		.count = ARRAY_SIZE(rx_bufs)
	};
	int ret;

	LOG_INF("Start async call");

	ret = spi_transceive_async(dev, spi_conf, &tx, &rx, &async_sig);
	if (ret == -ENOTSUP) {
		LOG_DBG("Not supported");
		return 0;
	}

	if (ret) {
		LOG_ERR("Code %d", ret);
		zassert_false(ret, "SPI transceive failed");
		return -1;
	}

	k_sem_take(&caller, K_FOREVER);

	if (result)  {
		LOG_ERR("Call code %d", ret);
		zassert_false(result, "SPI transceive failed");
		return -1;
	}

	LOG_INF("Passed");

	return 0;
}
#endif

Thanking you in anticipation,

Parents
  • Hi,

    I modified the code just to include async API, The intention is to make the code poll twice,
    My code is as:

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <string.h>
    #include <stdio.h>
    #include <drivers/spi.h>
    #include <drivers/gpio.h>
    
    
    #define STACK_SIZE 512
    #define BUF_SIZE 17
    uint8_t buffer_tx[] = "0123456789abcdef\0";
    uint8_t buffer_rx[BUF_SIZE] = {};
    
    struct spi_cs_control spi_cs = {
    	.gpio_pin = 11,
    	.gpio_dt_flags = GPIO_ACTIVE_LOW,
    	.delay = 0,
    };
    
    /*
     * We need 5x(buffer size) + 1 to print a comma-separated list of each
     * byte in hex, plus a null.
     */
    uint8_t buffer_print_tx[BUF_SIZE * 5 + 1];
    uint8_t buffer_print_rx[BUF_SIZE * 5 + 1];
    
    #define SPI_CS (&spi_cs)
    
    struct spi_config spi_cfg_slow = {
    	.frequency = 250000,
    
    	.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
    	SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
    	.slave = 1,
    	.cs = SPI_CS,
    };
    
    #if (CONFIG_SPI_ASYNC)
    static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER(async_sig);
    static struct k_poll_event async_evt =
    	K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
    				 K_POLL_MODE_NOTIFY_ONLY,
    				 &async_sig);
    static K_SEM_DEFINE(caller, 0, 1);
    K_THREAD_STACK_DEFINE(spi_async_stack, STACK_SIZE);
    static int result = 1;
    
    static void spi_async_call_cb(struct k_poll_event *async_evt,
    			      struct k_sem *caller_sem,
    			      void *unused)
    {
    	int ret;
    
    	printk("Polling...");
    
    	while (1) {
    		ret = k_poll(async_evt, 2, K_MSEC(200));
    
    		result = async_evt->signal->result;
    		k_sem_give(caller_sem);
    
    		/* Reinitializing for next call */
    		async_evt->signal->signaled = 0U;
    		async_evt->state = K_POLL_STATE_NOT_READY;
    	}
    }
    
    static int spi_async_call(const struct device *dev,
    			  struct spi_config *spi_conf)
    {
    	const struct spi_buf tx_bufs[] = {
    		{
    			.buf = buffer_tx,
    			.len = BUF_SIZE,
    		},
    	};
    	const struct spi_buf rx_bufs[] = {
    		{
    			.buf = buffer_rx,
    			.len = BUF_SIZE,
    		},
    	};
    	const struct spi_buf_set tx = {
    		.buffers = tx_bufs,
    		.count = ARRAY_SIZE(tx_bufs)
    	};
    	const struct spi_buf_set rx = {
    		.buffers = rx_bufs,
    		.count = ARRAY_SIZE(rx_bufs)
    	};
    	int ret;
    
    	printk("Start async call");
    
    	ret = spi_transceive_async(dev, spi_conf, &tx, &rx, &async_sig);
    	if (ret == -ENOTSUP) {
    		printk("Not supported");
    		return 0;
    	}
    
    	if (ret) {
    		printk("Code %d", ret);
    		return -1;
    	}
    
    	k_sem_take(&caller, K_FOREVER);
    
    	if (result)  {
    		printk("Call code %d", ret);
    		return -1;
    	}
    
    	printk("Passed");
    
    	return 0;
    }
    #endif
    
    
    void test_spi_loopback(void)
    {
    #if (CONFIG_SPI_ASYNC)
    	struct k_thread async_thread;
    	k_tid_t async_thread_id;
    #endif
    	const struct device *spi_slow;
    	const struct device *spi_fast;
    
    	printk("SPI test on buffers TX/RX %p/%p", buffer_tx, buffer_rx);
    
    #if defined(CONFIG_SPI_LOOPBACK_CS_GPIO)
    	if (cs_ctrl_gpio_config()) {
    		return;
    	}
    #endif /* CONFIG_SPI_LOOPBACK_CS_GPIO */
    
    	spi_slow = device_get_binding("SPI_0");
    	if (!spi_slow) {
    		printk("Cannot find !\n");
    		return;
    	}
    
    	spi_fast = spi_slow;
    
    #if (CONFIG_SPI_ASYNC)
    	async_thread_id = k_thread_create(&async_thread,
    					  spi_async_stack, STACK_SIZE,
    					  (k_thread_entry_t)spi_async_call_cb,
    					  &async_evt, &caller, NULL,
    					  K_PRIO_COOP(7), 0, K_NO_WAIT);
    #endif
    
    	printk("SPI test slow config");
    
    	if (
    #if (CONFIG_SPI_ASYNC)
    	    spi_async_call(spi_slow, &spi_cfg_slow)
    #endif
    	    ) {
    		goto end;
    	}
    
    	printk("All tx/rx passed");
    end:
    #if (CONFIG_SPI_ASYNC)
    	k_thread_abort(async_thread_id);
    #else
    	;
    #endif
    }
    
    
    
    void main(void)
    {
    	printk("Hello World! %s\n", CONFIG_BOARD);
    	test_spi_loopback();
    }
    

    If you look at line number 63, I increased number of events to 2, to get it to poll twice:

    ret = k_poll(async_evt, 2, K_MSEC(200));


    Yet this works only once and prints:

    Kindly suggest the code changes in the above code that would get me to poll twice.


    Thanks,

Reply
  • Hi,

    I modified the code just to include async API, The intention is to make the code poll twice,
    My code is as:

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <string.h>
    #include <stdio.h>
    #include <drivers/spi.h>
    #include <drivers/gpio.h>
    
    
    #define STACK_SIZE 512
    #define BUF_SIZE 17
    uint8_t buffer_tx[] = "0123456789abcdef\0";
    uint8_t buffer_rx[BUF_SIZE] = {};
    
    struct spi_cs_control spi_cs = {
    	.gpio_pin = 11,
    	.gpio_dt_flags = GPIO_ACTIVE_LOW,
    	.delay = 0,
    };
    
    /*
     * We need 5x(buffer size) + 1 to print a comma-separated list of each
     * byte in hex, plus a null.
     */
    uint8_t buffer_print_tx[BUF_SIZE * 5 + 1];
    uint8_t buffer_print_rx[BUF_SIZE * 5 + 1];
    
    #define SPI_CS (&spi_cs)
    
    struct spi_config spi_cfg_slow = {
    	.frequency = 250000,
    
    	.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
    	SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
    	.slave = 1,
    	.cs = SPI_CS,
    };
    
    #if (CONFIG_SPI_ASYNC)
    static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER(async_sig);
    static struct k_poll_event async_evt =
    	K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
    				 K_POLL_MODE_NOTIFY_ONLY,
    				 &async_sig);
    static K_SEM_DEFINE(caller, 0, 1);
    K_THREAD_STACK_DEFINE(spi_async_stack, STACK_SIZE);
    static int result = 1;
    
    static void spi_async_call_cb(struct k_poll_event *async_evt,
    			      struct k_sem *caller_sem,
    			      void *unused)
    {
    	int ret;
    
    	printk("Polling...");
    
    	while (1) {
    		ret = k_poll(async_evt, 2, K_MSEC(200));
    
    		result = async_evt->signal->result;
    		k_sem_give(caller_sem);
    
    		/* Reinitializing for next call */
    		async_evt->signal->signaled = 0U;
    		async_evt->state = K_POLL_STATE_NOT_READY;
    	}
    }
    
    static int spi_async_call(const struct device *dev,
    			  struct spi_config *spi_conf)
    {
    	const struct spi_buf tx_bufs[] = {
    		{
    			.buf = buffer_tx,
    			.len = BUF_SIZE,
    		},
    	};
    	const struct spi_buf rx_bufs[] = {
    		{
    			.buf = buffer_rx,
    			.len = BUF_SIZE,
    		},
    	};
    	const struct spi_buf_set tx = {
    		.buffers = tx_bufs,
    		.count = ARRAY_SIZE(tx_bufs)
    	};
    	const struct spi_buf_set rx = {
    		.buffers = rx_bufs,
    		.count = ARRAY_SIZE(rx_bufs)
    	};
    	int ret;
    
    	printk("Start async call");
    
    	ret = spi_transceive_async(dev, spi_conf, &tx, &rx, &async_sig);
    	if (ret == -ENOTSUP) {
    		printk("Not supported");
    		return 0;
    	}
    
    	if (ret) {
    		printk("Code %d", ret);
    		return -1;
    	}
    
    	k_sem_take(&caller, K_FOREVER);
    
    	if (result)  {
    		printk("Call code %d", ret);
    		return -1;
    	}
    
    	printk("Passed");
    
    	return 0;
    }
    #endif
    
    
    void test_spi_loopback(void)
    {
    #if (CONFIG_SPI_ASYNC)
    	struct k_thread async_thread;
    	k_tid_t async_thread_id;
    #endif
    	const struct device *spi_slow;
    	const struct device *spi_fast;
    
    	printk("SPI test on buffers TX/RX %p/%p", buffer_tx, buffer_rx);
    
    #if defined(CONFIG_SPI_LOOPBACK_CS_GPIO)
    	if (cs_ctrl_gpio_config()) {
    		return;
    	}
    #endif /* CONFIG_SPI_LOOPBACK_CS_GPIO */
    
    	spi_slow = device_get_binding("SPI_0");
    	if (!spi_slow) {
    		printk("Cannot find !\n");
    		return;
    	}
    
    	spi_fast = spi_slow;
    
    #if (CONFIG_SPI_ASYNC)
    	async_thread_id = k_thread_create(&async_thread,
    					  spi_async_stack, STACK_SIZE,
    					  (k_thread_entry_t)spi_async_call_cb,
    					  &async_evt, &caller, NULL,
    					  K_PRIO_COOP(7), 0, K_NO_WAIT);
    #endif
    
    	printk("SPI test slow config");
    
    	if (
    #if (CONFIG_SPI_ASYNC)
    	    spi_async_call(spi_slow, &spi_cfg_slow)
    #endif
    	    ) {
    		goto end;
    	}
    
    	printk("All tx/rx passed");
    end:
    #if (CONFIG_SPI_ASYNC)
    	k_thread_abort(async_thread_id);
    #else
    	;
    #endif
    }
    
    
    
    void main(void)
    {
    	printk("Hello World! %s\n", CONFIG_BOARD);
    	test_spi_loopback();
    }
    

    If you look at line number 63, I increased number of events to 2, to get it to poll twice:

    ret = k_poll(async_evt, 2, K_MSEC(200));


    Yet this works only once and prints:

    Kindly suggest the code changes in the above code that would get me to poll twice.


    Thanks,

Children
No Data
Related