<?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>Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/116902/generating-800khz-on-mosi-line</link><description>Hi, 
 we have created a led driver for ucs5603.c taking reference of ws2812-spi.c. we are using nrf52840 with NCS v17.0 
 we have set SPI clock frequency at 1MHz and we are getting 4MHz on clock line. When we check the MOSI line the data is at 500KHz</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 04 Dec 2024 05:06:26 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/116902/generating-800khz-on-mosi-line" /><item><title>RE: Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/thread/513330?ContentTypeID=1</link><pubDate>Wed, 04 Dec 2024 05:06:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8f0883f9-4d97-4a3b-8679-90c8b8552abc</guid><dc:creator>Haresh05</dc:creator><description>&lt;p&gt;Thanks for this explanation.&lt;/p&gt;
&lt;p&gt;Yes we are sending 1 bit of actual data as 8 bits over spi so that clarifies why the MOSI line frequency is divided by 8.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/thread/513208?ContentTypeID=1</link><pubDate>Tue, 03 Dec 2024 12:54:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2f90d415-8ad2-4e8d-9519-aac2ef2056cb</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Do not know what you mean by that, the data on MOSI line aligns with the SCK that is being used.&amp;nbsp;&lt;br /&gt;Can you show me a snapshot of the data on the MOSI pin and SCK side by side?&lt;br /&gt;How do you know that the data on MOSI is 500KHz, when there is data on it, how are you measuring frequency?&amp;nbsp;&lt;br /&gt;Is there some encoding on WS2812 that encodes 1 bit of data into 8 spi bits.&lt;br /&gt;&lt;br /&gt;Doing a google search seems to show that&amp;nbsp;WS2812 have a capability to encode 1-8 bits into frames, please check if that is the thing that you are observing. In your driver code, I see this.&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt; * Serialize an 8-bit color channel value into an equivalent sequence
 * of SPI frames, MSbit first, where a one bit becomes SPI frame
 * one_frame, and zero bit becomes zero_frame.
 */
static inline void ws2812_spi_ser(uint8_t buf[8], uint8_t color,
				  const uint8_t one_frame, const uint8_t zero_frame)
{
	int i;

	for (i = 0; i &amp;lt; 8; i++) {
		buf[i] = color &amp;amp; BIT(7 - i) ? one_frame : zero_frame;
	}
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/thread/513203?ContentTypeID=1</link><pubDate>Tue, 03 Dec 2024 12:41:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a76c93d7-6da1-4402-9f33-f504402afb19</guid><dc:creator>Haresh05</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Yes, we have set the clock frequency to 4MHz and when we measure the clock, it is 4MHz indeed. But when we measure the frequency of MOSI line to check at what speed data is transmitted, it is 500KHz.&lt;/p&gt;
&lt;p&gt;Can you specify reason behind this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/thread/513202?ContentTypeID=1</link><pubDate>Tue, 03 Dec 2024 12:39:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:969ac674-1bd2-4a6b-bbb5-3a74a073aa07</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;I do not want to dive into this specific driver from ws2812 which is outside the scope of our solution but looking at the below code snippet&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;struct ws2812_spi_cfg {
	struct spi_dt_spec bus;
	uint8_t *px_buf;
	uint8_t one_frame;
	uint8_t zero_frame;
	uint8_t num_colors;
	const uint8_t *color_mapping;
	size_t length;
	uint16_t reset_delay;
};

static const struct ws2812_spi_cfg *dev_cfg(const struct device *dev)
{
	return dev-&amp;gt;config;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;It seems that you are relying that the driver is setting proper clock based on your device tree setting. So make sure that your device tree has set this correctly for the&amp;nbsp; clock-frequency element in the spi node. Something like below&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;amp;spi1 {
    compatible = &amp;quot;nordic,nrf-spi&amp;quot;;
    reg = &amp;lt;0x40004000 0x1000&amp;gt;;
    status = &amp;quot;okay&amp;quot;;
    clock-frequency = &amp;lt;1000000&amp;gt;; // Set to 1 MHz
    cs-gpios = &amp;lt;&amp;amp;gpio0 15 GPIO_ACTIVE_LOW&amp;gt;;
};&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Apart from that it seems like there is nothing much to set the clock speed of the SPI in this driver. it just seems to be using the spi speed already set in the spi driver.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/thread/513176?ContentTypeID=1</link><pubDate>Tue, 03 Dec 2024 11:17:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ca92ae91-f6d0-4271-84ec-eda5224c7eea</guid><dc:creator>Haresh05</dc:creator><description>&lt;p&gt;I mentioned the wrong version. It is NCSv2.7.0&lt;/p&gt;
&lt;p&gt;I have taken reference from ws2812_spi.c driver. So basically I have modified the &amp;quot;ws2812_strip_update_rgb&amp;quot; method for ucs5603. I am sharing the ws2812_spi.c file&amp;#39;s code for your reference.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2019, Nordic Semiconductor ASA
 * Copyright (c) 2021 Seagate Technology LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT worldsemi_ws2812_spi

#include &amp;lt;zephyr/drivers/led_strip.h&amp;gt;

#include &amp;lt;string.h&amp;gt;

#define LOG_LEVEL CONFIG_LED_STRIP_LOG_LEVEL
#include &amp;lt;zephyr/logging/log.h&amp;gt;
LOG_MODULE_REGISTER(ws2812_spi);

#include &amp;lt;zephyr/kernel.h&amp;gt;
#include &amp;lt;zephyr/device.h&amp;gt;
#include &amp;lt;zephyr/drivers/spi.h&amp;gt;
#include &amp;lt;zephyr/sys/math_extras.h&amp;gt;
#include &amp;lt;zephyr/sys/util.h&amp;gt;
#include &amp;lt;zephyr/dt-bindings/led/led.h&amp;gt;

/* spi-one-frame and spi-zero-frame in DT are for 8-bit frames. */
#define SPI_FRAME_BITS 8

/*
 * SPI master configuration:
 *
 * - mode 0 (the default), 8 bit, MSB first (arbitrary), one-line SPI
 * - no shenanigans (don&amp;#39;t hold CS, don&amp;#39;t hold the device lock, this
 *   isn&amp;#39;t an EEPROM)
 */
#define SPI_OPER(idx) (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \
		  SPI_WORD_SET(SPI_FRAME_BITS))

struct ws2812_spi_cfg {
	struct spi_dt_spec bus;
	uint8_t *px_buf;
	uint8_t one_frame;
	uint8_t zero_frame;
	uint8_t num_colors;
	const uint8_t *color_mapping;
	size_t length;
	uint16_t reset_delay;
};

static const struct ws2812_spi_cfg *dev_cfg(const struct device *dev)
{
	return dev-&amp;gt;config;
}

/*
 * Serialize an 8-bit color channel value into an equivalent sequence
 * of SPI frames, MSbit first, where a one bit becomes SPI frame
 * one_frame, and zero bit becomes zero_frame.
 */
static inline void ws2812_spi_ser(uint8_t buf[8], uint8_t color,
				  const uint8_t one_frame, const uint8_t zero_frame)
{
	int i;

	for (i = 0; i &amp;lt; 8; i++) {
		buf[i] = color &amp;amp; BIT(7 - i) ? one_frame : zero_frame;
	}
}

/*
 * Latch current color values on strip and reset its state machines.
 */
static inline void ws2812_reset_delay(uint16_t delay)
{
	k_usleep(delay);
}

static int ws2812_strip_update_rgb(const struct device *dev,
				   struct led_rgb *pixels,
				   size_t num_pixels)
{
	const struct ws2812_spi_cfg *cfg = dev_cfg(dev);
	const uint8_t one = cfg-&amp;gt;one_frame, zero = cfg-&amp;gt;zero_frame;
	struct spi_buf buf = {
		.buf = cfg-&amp;gt;px_buf,
		.len = (cfg-&amp;gt;length * 8 * cfg-&amp;gt;num_colors),
	};
	const struct spi_buf_set tx = {
		.buffers = &amp;amp;buf,
		.count = 1
	};
	uint8_t *px_buf = cfg-&amp;gt;px_buf;
	size_t i;
	int rc;

	/*
	 * Convert pixel data into SPI frames. Each frame has pixel data
	 * in color mapping on-wire format (e.g. GRB, GRBW, RGB, etc).
	 */
	for (i = 0; i &amp;lt; num_pixels; i++) {
		uint8_t j;

		for (j = 0; j &amp;lt; cfg-&amp;gt;num_colors; j++) {
			uint8_t pixel;

			switch (cfg-&amp;gt;color_mapping[j]) {
			/* White channel is not supported by LED strip API. */
			case LED_COLOR_ID_WHITE:
				pixel = 0;
				break;
			case LED_COLOR_ID_RED:
				pixel = pixels[i].r;
				break;
			case LED_COLOR_ID_GREEN:
				pixel = pixels[i].g;
				break;
			case LED_COLOR_ID_BLUE:
				pixel = pixels[i].b;
				break;
			default:
				return -EINVAL;
			}
			ws2812_spi_ser(px_buf, pixel, one, zero);
			px_buf += 8;
		}
	}

	/*
	 * Display the pixel data.
	 */
	rc = spi_write_dt(&amp;amp;cfg-&amp;gt;bus, &amp;amp;tx);
	ws2812_reset_delay(cfg-&amp;gt;reset_delay);

	return rc;
}

static size_t ws2812_strip_length(const struct device *dev)
{
	const struct ws2812_spi_cfg *cfg = dev_cfg(dev);

	return cfg-&amp;gt;length;
}

static int ws2812_spi_init(const struct device *dev)
{
	const struct ws2812_spi_cfg *cfg = dev_cfg(dev);
	uint8_t i;

	if (!spi_is_ready_dt(&amp;amp;cfg-&amp;gt;bus)) {
		LOG_ERR(&amp;quot;SPI device %s not ready&amp;quot;, cfg-&amp;gt;bus.bus-&amp;gt;name);
		return -ENODEV;
	}

	for (i = 0; i &amp;lt; cfg-&amp;gt;num_colors; i++) {
		switch (cfg-&amp;gt;color_mapping[i]) {
		case LED_COLOR_ID_WHITE:
		case LED_COLOR_ID_RED:
		case LED_COLOR_ID_GREEN:
		case LED_COLOR_ID_BLUE:
			break;
		default:
			LOG_ERR(&amp;quot;%s: invalid channel to color mapping.&amp;quot;
				&amp;quot;Check the color-mapping DT property&amp;quot;,
				dev-&amp;gt;name);
			return -EINVAL;
		}
	}

	return 0;
}

static const struct led_strip_driver_api ws2812_spi_api = {
	.update_rgb = ws2812_strip_update_rgb,
	.length = ws2812_strip_length,
};

#define WS2812_SPI_NUM_PIXELS(idx) \
	(DT_INST_PROP(idx, chain_length))
#define WS2812_SPI_HAS_WHITE(idx) \
	(DT_INST_PROP(idx, has_white_channel) == 1)
#define WS2812_SPI_ONE_FRAME(idx) \
	(DT_INST_PROP(idx, spi_one_frame))
#define WS2812_SPI_ZERO_FRAME(idx) \
	(DT_INST_PROP(idx, spi_zero_frame))
#define WS2812_SPI_BUFSZ(idx) \
	(WS2812_NUM_COLORS(idx) * 8 * WS2812_SPI_NUM_PIXELS(idx))

/*
 * Retrieve the channel to color mapping (e.g. RGB, BGR, GRB, ...) from the
 * &amp;quot;color-mapping&amp;quot; DT property.
 */
#define WS2812_COLOR_MAPPING(idx)				  \
	static const uint8_t ws2812_spi_##idx##_color_mapping[] = \
		DT_INST_PROP(idx, color_mapping)

#define WS2812_NUM_COLORS(idx) (DT_INST_PROP_LEN(idx, color_mapping))

/* Get the latch/reset delay from the &amp;quot;reset-delay&amp;quot; DT property. */
#define WS2812_RESET_DELAY(idx) DT_INST_PROP(idx, reset_delay)

#define WS2812_SPI_DEVICE(idx)						 \
									 \
	static uint8_t ws2812_spi_##idx##_px_buf[WS2812_SPI_BUFSZ(idx)]; \
									 \
	WS2812_COLOR_MAPPING(idx);					 \
									 \
	static const struct ws2812_spi_cfg ws2812_spi_##idx##_cfg = {	 \
		.bus = SPI_DT_SPEC_INST_GET(idx, SPI_OPER(idx), 0),	 \
		.px_buf = ws2812_spi_##idx##_px_buf,			 \
		.one_frame = WS2812_SPI_ONE_FRAME(idx),			 \
		.zero_frame = WS2812_SPI_ZERO_FRAME(idx),		 \
		.num_colors = WS2812_NUM_COLORS(idx),			 \
		.color_mapping = ws2812_spi_##idx##_color_mapping,	 \
		.length = DT_INST_PROP(idx, chain_length),               \
		.reset_delay = WS2812_RESET_DELAY(idx),			 \
	};								 \
									 \
	DEVICE_DT_INST_DEFINE(idx,					 \
			      ws2812_spi_init,				 \
			      NULL,					 \
			      NULL,					 \
			      &amp;amp;ws2812_spi_##idx##_cfg,			 \
			      POST_KERNEL,				 \
			      CONFIG_LED_STRIP_INIT_PRIORITY,		 \
			      &amp;amp;ws2812_spi_api);

DT_INST_FOREACH_STATUS_OKAY(WS2812_SPI_DEVICE)&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Generating 800Khz on MOSI line</title><link>https://devzone.nordicsemi.com/thread/513170?ContentTypeID=1</link><pubDate>Tue, 03 Dec 2024 11:00:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4d964968-2215-46cc-8a59-d63d0f2cfbf9</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;NCSv17.0 seems like a wrong SDKk version, did you mean nRF5SDKv17 which is our older deprecated version?&lt;/p&gt;
&lt;p&gt;Even though we do not work with drivers of those sensors ourself, we can guide you with the settings on the SPI to get proper waveforms. It would be nice to show some code snippets on how you configured the SPI so that I understand more on what you are calibrating to get those different clock output frequencies.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>