<?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>SPIS buffer cannot receive more than 64 bytes</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/110541/spis-buffer-cannot-receive-more-than-64-bytes</link><description>Hi all, 
 
 I have a SPIS implementation on an nRF52840 running smoothly. Recently I&amp;#39;v had the need to receive large packets (up to 270 bytes) in one single transaction. However, the slave only receives 64 bytes. I am making sure that my internal SPI</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 25 Apr 2024 13:21:35 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/110541/spis-buffer-cannot-receive-more-than-64-bytes" /><item><title>RE: SPIS buffer cannot receive more than 64 bytes</title><link>https://devzone.nordicsemi.com/thread/480711?ContentTypeID=1</link><pubDate>Thu, 25 Apr 2024 13:21:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:36222780-5814-44ea-8c25-b0431a82e8d7</guid><dc:creator>kfci-eng</dc:creator><description>&lt;p&gt;Hi Einar,&lt;/p&gt;
&lt;p&gt;thank you so much for your help! All this time I thought maybe the isuue was on the nRF side, but it&amp;#39;s actually on the master side (ESP32). It looks like the SPI FIFO on the ESP32 only allows for 64 bytes per transaction. Thanks for making me think about that! I will try to use another master or even use the nRF52840 as both master and slave (like in the example) to test this.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Kevin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPIS buffer cannot receive more than 64 bytes</title><link>https://devzone.nordicsemi.com/thread/480602?ContentTypeID=1</link><pubDate>Thu, 25 Apr 2024 07:54:13 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4ae1b7dd-9369-4111-a30c-84d8a15a6bfa</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi Kevin,&lt;/p&gt;
&lt;p&gt;I see. I Have still not been able to reproduce, though. I took the sample you refered to and modified it a bit to send 270 bytes and the full 270 byte message is received on the slave side. This is the code I tested with on 2.5.2:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;zephyr/devicetree.h&amp;gt;
#include &amp;lt;zephyr/drivers/gpio.h&amp;gt;
#include &amp;lt;zephyr/drivers/spi.h&amp;gt;


#define MSG_LEN 270


/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* The devicetree node identifier for the &amp;quot;led0&amp;quot; alias. */
#define LED0_NODE DT_ALIAS(led0)

#define MY_SPI_MASTER DT_NODELABEL(my_spi_master)
#define MY_SPI_MASTER_CS_DT_SPEC SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(reg_my_spi_master))

#define MY_SPI_SLAVE  DT_NODELABEL(my_spi_slave)

// SPI master functionality
const struct device *spi_dev;
static struct k_poll_signal spi_done_sig = K_POLL_SIGNAL_INITIALIZER(spi_done_sig);


static void print_array(const uint8_t *in_data, uint32_t in_len)
{
	printk(&amp;quot; (size %lu):&amp;quot;, (unsigned long)in_len);
	if (NULL != in_data) {
		for (uint32_t i = 0; i &amp;lt; in_len; i++) {
			if (i % 16 == 0)
				printk(&amp;quot;\n\t%02X &amp;quot;, in_data[i]);
			else
				printk(&amp;quot;%02X &amp;quot;, in_data[i]);
		}
	}
	printk(&amp;quot;\n&amp;quot;);
}


static void spi_init(void)
{
	spi_dev = DEVICE_DT_GET(MY_SPI_MASTER);
	if(!device_is_ready(spi_dev)) {
		printk(&amp;quot;SPI master device not ready!\n&amp;quot;);
	}
	struct gpio_dt_spec spim_cs_gpio = MY_SPI_MASTER_CS_DT_SPEC;
	if(!device_is_ready(spim_cs_gpio.port)){
		printk(&amp;quot;SPI master chip select device not ready!\n&amp;quot;);
	}
}

static struct spi_config spi_cfg = {
	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL | SPI_MODE_CPHA,
	.frequency = 4000000,
	.slave = 0,
	.cs = {.gpio = MY_SPI_MASTER_CS_DT_SPEC, .delay = 0},
};

static int spi_write_test_msg(void)
{
	static uint8_t tx_buffer[MSG_LEN];
	static uint8_t rx_buffer[MSG_LEN];

	const struct spi_buf tx_buf = {
		.buf = tx_buffer,
		.len = sizeof(tx_buffer)
	};
	const struct spi_buf_set tx = {
		.buffers = &amp;amp;tx_buf,
		.count = 1
	};

	struct spi_buf rx_buf = {
		.buf = rx_buffer,
		.len = sizeof(rx_buffer),
	};
	const struct spi_buf_set rx = {
		.buffers = &amp;amp;rx_buf,
		.count = 1
	};

	// Updagte tx_buffer with dummy data
	for (int i = 0; i &amp;lt; MSG_LEN; i++) {
		tx_buffer[i]= (i &amp;amp; 0xFF);
	}

	// Reset signal
	k_poll_signal_reset(&amp;amp;spi_done_sig);
	
	// Start transaction
	int error = spi_transceive_signal(spi_dev, &amp;amp;spi_cfg, &amp;amp;tx, &amp;amp;rx, &amp;amp;spi_done_sig);
	if(error != 0){
		printk(&amp;quot;SPI transceive error: %i\n&amp;quot;, error);
		return error;
	}

	// Wait for the done signal to be raised and log the rx buffer
	int spi_signaled, spi_result;
	do{
		k_poll_signal_check(&amp;amp;spi_done_sig, &amp;amp;spi_signaled, &amp;amp;spi_result);
	} while(spi_signaled == 0);
	printk(&amp;quot;SPI RX: 0x%.2x, 0x%.2x\n&amp;quot;, rx_buffer[0], rx_buffer[1]);
	return 0;
}

// SPI slave functionality
const struct device *spi_slave_dev;
static struct k_poll_signal spi_slave_done_sig = K_POLL_SIGNAL_INITIALIZER(spi_slave_done_sig);

static const struct spi_config spi_slave_cfg = {
	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
				 SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_OP_MODE_SLAVE,
	.frequency = 4000000,
	.slave = 0,
};

static void spi_slave_init(void)
{
	spi_slave_dev = DEVICE_DT_GET(MY_SPI_SLAVE);
	if(!device_is_ready(spi_dev)) {
		printk(&amp;quot;SPI slave device not ready!\n&amp;quot;);
	}
}

static uint8_t slave_tx_buffer[MSG_LEN];
static uint8_t slave_rx_buffer[MSG_LEN];
static int spi_slave_write_test_msg(void)
{
	static uint8_t counter = 0;


	const struct spi_buf s_tx_buf = {
		.buf = slave_tx_buffer,
		.len = sizeof(slave_tx_buffer)
	};
	const struct spi_buf_set s_tx = {
		.buffers = &amp;amp;s_tx_buf,
		.count = 1
	};

	struct spi_buf s_rx_buf = {
		.buf = slave_rx_buffer,
		.len = sizeof(slave_rx_buffer),
	};
	const struct spi_buf_set s_rx = {
		.buffers = &amp;amp;s_rx_buf,
		.count = 1
	};

	// Reset signal
	k_poll_signal_reset(&amp;amp;spi_slave_done_sig);
	
	// Start transaction
	int error = spi_transceive_signal(spi_slave_dev, &amp;amp;spi_slave_cfg, &amp;amp;s_tx, &amp;amp;s_rx, &amp;amp;spi_slave_done_sig);
	if(error != 0){
		printk(&amp;quot;SPI slave transceive error: %i\n&amp;quot;, error);
		return error;
	}
	return 0;
}
/*
 * Return length of received message. If no message has been received, return -1.
 */
static int spi_slave_check_for_message(void)
{
	int signaled, result;
	k_poll_signal_check(&amp;amp;spi_slave_done_sig, &amp;amp;signaled, &amp;amp;result);
	printk(&amp;quot;received %i bytes\n&amp;quot;, result);
	if(signaled != 0){
		return result;
	}
	else return -1;
}

/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

int main(void)
{
	int ret;

	if (!device_is_ready(led.port)) {
		return 0;
	}

	ret = gpio_pin_configure_dt(&amp;amp;led, GPIO_OUTPUT_ACTIVE);
	if (ret &amp;lt; 0) {
		return 0;
	}

	spi_init();

	spi_slave_init();

	printk(&amp;quot;SPI master/slave example started\n&amp;quot;);
	
	spi_slave_write_test_msg();

	while (1) {
		spi_write_test_msg();
		ret = gpio_pin_toggle_dt(&amp;amp;led);
		if (ret &amp;lt; 0) {
			return 0;
		}
		k_msleep(SLEEP_TIME_MS);

		int received = spi_slave_check_for_message();
		if(received &amp;gt; 0){
			// Print the last received data
			printk(&amp;quot;SPI SLAVE RX:\n&amp;quot;);
			print_array(slave_rx_buffer, received);
			
			// Prepare the next SPI slave transaction
			spi_slave_write_test_msg();
		}
	}

	return 0;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If you don&amp;#39;t make progress, can you share a logic analyzer trace of the SPI lines so that we can see if the master is actually sendign all the data (and if there are other things that stick out)?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPIS buffer cannot receive more than 64 bytes</title><link>https://devzone.nordicsemi.com/thread/480486?ContentTypeID=1</link><pubDate>Wed, 24 Apr 2024 13:43:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c8b93c3b-144a-4356-8e67-040fad7c98e4</guid><dc:creator>kfci-eng</dc:creator><description>&lt;p&gt;Hi Einar,&lt;/p&gt;
&lt;p&gt;Yes. I based my routine on &lt;a href="https://github.com/too1/ncs-spi-master-slave-example.git"&gt;this&lt;/a&gt;&amp;nbsp;example. The routine is basically the same, I only changed the data that has been exchanged. Inside the function&amp;nbsp;spi_slave_check_for_message(), I print the value of &amp;quot;result&amp;quot; to the console and it shows 64. To my understanding, this is the number opf bytes received. I then tested sending smaller messages in one transaction (45 bytes) and the value of the &amp;quot;result&amp;quot; variable changes to 45. But anytime I try to send buffers larger than 64 bytes, &amp;quot;result&amp;quot; stays at 64 bytes and the rest of the bytes are lost.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I made sure that the master I am using (an ESP32) has the same SPI config (speed, mode, word size, bit order. etc..).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best,&lt;/p&gt;
&lt;p&gt;Kevin&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPIS buffer cannot receive more than 64 bytes</title><link>https://devzone.nordicsemi.com/thread/480450?ContentTypeID=1</link><pubDate>Wed, 24 Apr 2024 12:36:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:22e3e769-b290-46c8-bd46-a7ba558c353b</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi Kevin,&lt;/p&gt;
&lt;p&gt;There should not be any limitation of 64 bytes. Can you share more details about what you are doing and what you have found by debugging and testing?&lt;/p&gt;
&lt;p&gt;Br,&lt;/p&gt;
&lt;p&gt;Einar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>