<?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>Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/52388/capturing-gpio-transitions-of-a-4khz-signal-with-ble-enabled</link><description>I need to capture the time between rising transition of a GPIO pin in order to integrate a Manchester decoder of an RFID reader chip. In my particular case, the reader chip emits a waveform where the minimum time between the rising edges is ~256uS. The</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 18 Aug 2022 07:46:05 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/52388/capturing-gpio-transitions-of-a-4khz-signal-with-ble-enabled" /><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/382154?ContentTypeID=1</link><pubDate>Thu, 18 Aug 2022 07:46:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f46790a-e6fe-4f6f-9a7c-dd7ed1026af3</guid><dc:creator>RSchmale</dc:creator><description>&lt;p&gt;hi dj1234&lt;/p&gt;
&lt;p&gt;i have the same question about capture gpio to read manchester code. do you solve the problem and it is possible to get the code from you?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/213091?ContentTypeID=1</link><pubDate>Thu, 03 Oct 2019 05:57:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fc3fc7aa-1f1b-4e3e-aed0-245dada33a66</guid><dc:creator>dj1234</dc:creator><description>&lt;p&gt;Ok got it working! Here&amp;#39;s my flow&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;SAADC points to a sample buffer to capture 512us worth of samples&lt;/li&gt;
&lt;li&gt;Start SAADC (loads the contents RESULT.PTR registers and generates a STARTED event)&lt;/li&gt;
&lt;li&gt;PPI initiates Sampling of the SAADC on the STARTED event&lt;/li&gt;
&lt;li&gt;STARTED event generates an interrupt. Prepare the RESULT.PTR register with the next buffer&lt;/li&gt;
&lt;li&gt;SAADC generates an END event when sampling buffer is full&lt;/li&gt;
&lt;li&gt;PPI Starts the SAADC on the END event (outcome same as step 2)&lt;/li&gt;
&lt;li&gt;END event generates an interrupt. Notify the thread that sampling is complete.&lt;/li&gt;
&lt;li&gt;Thread processes the buffer with the sampling data that was complete&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I measured a 4kHz input signal and the period measurement was spot on. Thanks a lot for your help&amp;nbsp;haakonsh.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212846?ContentTypeID=1</link><pubDate>Tue, 01 Oct 2019 13:54:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0762ea9d-d09a-4080-9b5e-5da351150d69</guid><dc:creator>haakonsh</dc:creator><description>[quote user="dj1234"]The STARTED event is generated when SAADC starts filling in the supplied buffer.[/quote][quote user="dj1234"]An Interrupt is generated where I&amp;#39;m free to update the RESULT.PTR register.[/quote]
&lt;p&gt;The STARTED event is generated after the RESULT.PTR and RESULT.MAXCNT registers have been read and loaded by the SAADC peripheral. At which point it is safe to update the .PTR and .MAXCNT registers again by the application. When the END event is fired a START task can be immediately triggered to load the next .PTR and .MAXCNT values into the SAADC.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;You can, for instance, connect the START task to the END event via PPI, given that the .PTR and .MAXCNT registers have been updated since the last STARTED event fired.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void ppi_saadc_init()
{
	NRF_PPI-&amp;gt;CH[0].EEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;EVENTS_END;
	// NRF_PPI-&amp;gt;CH[0].TEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;TASKS_SAMPLE; Undefined operation, STARTED event must fire before sampling can continue.
	NRF_PPI-&amp;gt;FORK[0].TEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;TASKS_START;
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL0);
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It seems that you trigger the sample task via CPU at regular intervals, I recommend that you instead employ a TIMER&amp;#39;s COMPARE event to trigger the SAMPLE task, trigger the TIMER&amp;#39;s START task from the SAADC&amp;#39;s STARTED event, and trigger the TIMER&amp;#39;s STOP task from the SAADC&amp;#39;s END event.&lt;br /&gt;&lt;br /&gt;This will set up a continuous cycle of sampling with a fixed delay between the END event and until the first sample is taken. &lt;br /&gt;You can even refreign from stopping the TIMER at the END event and let it run to get a truly jitter-free sample rate across all buffers, but only if the SAADC&amp;#39;s STARTED event has fired before the first SAMPLE task is triggered by the TIMER. I don&amp;#39;t know the exact time from the SAADC&amp;#39;s started task until it fires the STARTED event btw.&lt;br /&gt;&lt;br /&gt;Also, by&amp;nbsp;enabling the shortcut between a TIMER&amp;#39;s COMPARE event and it&amp;#39;s CLEAR task you create a free-running timer. See&amp;nbsp;&lt;a title="SHORTS" href="https://infocenter.nordicsemi.com/topic/ps_nrf52840/timer.html?cp=3_0_0_5_29_4_7#register.SHORTS"&gt;SHORTS&lt;/a&gt;.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212703?ContentTypeID=1</link><pubDate>Tue, 01 Oct 2019 06:03:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ad0e343f-dc19-4c2a-80ac-fe596eab9cd2</guid><dc:creator>dj1234</dc:creator><description>&lt;p&gt;Yes it is a fun project.&lt;/p&gt;
&lt;p&gt;One more thing. I don&amp;#39;t think I can simply rely on the GPIO to start the SAADC because, a transponder may not be in contact, in which case&amp;nbsp;I think the DOUT pin will be toggling at random intervals. The Manchester sample code that I linked to earlier looks for the preamble to actually get the timing. So I think I will need an edge detection algorithm.&lt;/p&gt;
&lt;p&gt;This is what I started doing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Setup the SAADC to run continuously at 16us intervals (using the internal timer) filling a 64 sample buffer (which covers a millisecond worth of samples)&lt;/li&gt;
&lt;li&gt;Run a process that looks for edges. At 16us, I have 16 samples within a 256us interval which gives me a 6% error margin which I think is acceptable.&lt;/li&gt;
&lt;li&gt;Run the Manchester decoder on the processed data&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My implementation assumes the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The STARTED event is generated when SAADC starts filling in the supplied buffer.
&lt;ul&gt;
&lt;li&gt;An Interrupt is generated where I&amp;#39;m free to update the RESULT.PTR register.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Once the buffer is filled, an END event is generated&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The PPI restarts the SAADC with the new RESULT.PTR register value&lt;/li&gt;
&lt;li&gt;By the time the END interrupt handler is&amp;nbsp;invoked, the SAADC is already filling up the next buffer, I have plenty of time to process the previous buffer&lt;/li&gt;
&lt;li&gt;Because the PPI has restarted the SAADC, a STARTED event is generated allowing the process to continue&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But I seem to be occasionally missing some samples as the period between transitions vary a bit too much (especially while BLE is running).&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s an extract of my implementation (C + pseudocode):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define BUFFER_COUNT		3
#define BUFFER_SIZE			32

static nrf_saadc_value_t     adc_buf[BUFFER_COUNT][BUFFER_SIZE];
static uint8_t buffer_head;
static uint8_t buffer_tail = 1;


static void saadc_init()
{
    nrf_saadc_resolution_set(NRF_SAADC_RESOLUTION_8BIT);
    nrf_saadc_oversample_set(NRF_SAADC_OVERSAMPLE_DISABLED);

    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
    NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, 6);
    NRFX_IRQ_ENABLE(SAADC_IRQn);
    nrf_saadc_int_enable(NRF_SAADC_INT_END);
    nrf_saadc_enable();
}


static void saadc_channel_init()
{
	nrf_saadc_channel_config_t channel_config = SAADC_HISPEED_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    nrf_saadc_channel_init(0, &amp;amp;channel_config);
}


static void saadc_buffer_init()
{
    nrf_saadc_int_enable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END);
	nrf_saadc_buffer_init(adc_buf[0], BUFFER_SIZE);
	nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
	nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
}


static void ppi_saadc_init()
{
	NRF_PPI-&amp;gt;CH[0].EEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;EVENTS_END;
	NRF_PPI-&amp;gt;CH[0].TEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;TASKS_SAMPLE;
	NRF_PPI-&amp;gt;FORK[0].TEP = (uint32_t)&amp;amp;NRF_SAADC-&amp;gt;TASKS_START;
    nrf_ppi_channel_enable(NRF_PPI_CHANNEL0);
}


void process_thread()
{
    uint8_t buffer_index;
    nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
    
    for(;;)
    {
        // Wait for END notification
        AWAIT_BUFFER_READY(&amp;amp;buffer_index);
        ; // process data saadc data here
    }
}


main()
{
    saadc_init();
    saadc_channel_init();
    nrf_saadc_continuous_mode_enable(256);
    saadc_buffer_init();

	ppi_saadc_init();
	
	process_thread();
}


void nrfx_saadc_irq_handler(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;

	// This is a higher priority event. Handle END first and if necessary also handle the STARTED
	if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
	{
		nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
		
		// Sampling complete / buffer full event. The PPI has already initiated next
		// sampling already started on the next buffer so we have no problems with interrupt latency.
		// Simply notify the running thread that a buffer is ready to be processed. The thread needs
		// to process this buffer before the next one buffer is filled.

		NOTIFY_BUFFER_READY(buffer_head)
        buffer_head = (buffer_head + 1) % BUFFER_COUNT;
	}

	// End of conversion events need to be lower priority compared 
	if (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED))
	{
		// Yes. Prepare the next buffer that the data will be written to
		nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);

		nrf_saadc_buffer_pointer_set(adc_buf[buffer_tail]);
        buffer_tail = (buffer_tail + 1) % BUFFER_COUNT;
	}
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Do you see anything obvious that would account for it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212537?ContentTypeID=1</link><pubDate>Mon, 30 Sep 2019 11:22:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:124b98d3-28f2-453c-b86f-83ce5f567d8d</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;Aah, I see.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;From&lt;span&gt;HT2 Transponder Family Communication Protocol, page 8:&lt;/span&gt; &lt;br /&gt;&amp;quot;The first bit of the transmitted data always starts with the Modulator ON (loaded) state.&amp;quot;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;It looks like the data signal always starts&amp;nbsp;with a logical high, so you can start a TIMER based on a low-to-high GPIOTE transition, as long as you&amp;#39;ve got a weak pull-down resistor on the line.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Also, the Manchester encoding is of the G.E Thomas variety, so you don&amp;#39;t even need to XOR the data bits with the clock, as long as you sample in the first half-period of a symbol.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;With BIPHASE decoding you&amp;#39;ll need to sample both half-periods of each symbol and find what pair has two identical values, representing a &amp;#39;1&amp;#39;, and who&amp;#39;s got two different values, representing a &amp;#39;0&amp;#39;.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Anyways, this looks like a fun project, let me know if you need any more help.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212424?ContentTypeID=1</link><pubDate>Mon, 30 Sep 2019 00:25:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:32796d30-9710-4d3c-aeb7-644be100caa7</guid><dc:creator>dj1234</dc:creator><description>[quote userid="13562" url="~/f/nordic-q-a/52388/capturing-gpio-transitions-of-a-4khz-signal-with-ble-enabled/212098"]The HTRC110 does not appear to be using a manchester encoded protocol since it has a separate clock signal.[/quote]
&lt;p&gt;That&amp;#39;s true as long as we&amp;#39;re talking to the reader chip. However, once the READ_TAG command is issued, the&amp;nbsp;reader chip becomes a effectively a pass-through device to the RF transponder (specs for that are&amp;nbsp;&lt;a href="http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HT2protocol.pdf"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;I just realised that&amp;nbsp;the CPU uses the READ_TAG and WRITE_TAG commands to communicate with the transponder which sends it&amp;#39;s data in Manchester encoded format.&lt;/p&gt;
&lt;p&gt;So I don&amp;#39;t believe that I&amp;#39;ll be able to use the SCLK as a trigger. However, SAADS with a pure timer sampling the data as you suggested I think will do the trick. i&amp;#39;ll give that a go.&lt;/p&gt;
&lt;p&gt;Thank you very much for your help&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212108?ContentTypeID=1</link><pubDate>Thu, 26 Sep 2019 14:53:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dc5da9cc-e975-4d43-8132-f516d71bf714</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;I just realize that you can probably use the SPIM peripheral for this as this looks like SPI without CS/SS. If this is the case then this will be the easiest solution by far.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;It looks like you&amp;#39;ll have to find the frequency of SCLK by trial-and-error, I suggest starting at 125kHz.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212098?ContentTypeID=1</link><pubDate>Thu, 26 Sep 2019 14:16:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dedb9def-740d-46cb-aa12-a287336b79e8</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;&lt;span&gt;The HTRC110 does not appear to be using a manchester encoded protocol since it has a separate clock signal. The defining attribute of a manchester encoded signal is that it&amp;#39;s self-clocking, where the clock signal is modulated into the signal itself.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;But this does not really change much in your case, it actually makes things a&amp;nbsp;lot easier since the MCU controls the SCLK and DIN lines. Now we can use the SCLK timings to trigger SAADC sampling of the DOUT line on positive clock periods.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;See &amp;quot;Fig 4. Serial signaling&amp;quot; in&amp;nbsp;&lt;a href="https://www.nxp.com/docs/en/data-sheet/037031.pdf"&gt;https://www.nxp.com/docs/en/data-sheet/037031.pdf&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What you need to do:&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span&gt;Create a clock signal with a TIMER and GPIOTE.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Create a driver for the digital input line, DIN, with manual SW GPIO toggling or maybe even use the PWM peripheral for that. I&amp;#39;m not 100% sure we can use the PWM for this, but if we can then you will be able to send commands to the&amp;nbsp;&lt;span&gt;HTRC110 without using the CPU to control the GPIO for the DIN line, as the PWM peripheral can be configured to use a pre-defined &amp;#39;sequence&amp;#39; in RAM with EasyDMA.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Setup the SAADC to sample on the SCLK&amp;#39;s positive flank changes, based on the TIMER it runs on.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Run the process I described earlier on the samples to get the data.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/212078?ContentTypeID=1</link><pubDate>Thu, 26 Sep 2019 13:17:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eec30ee4-ea5d-438f-a62a-5e36506fb886</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;Only the first rising edge (or low, as long as it&amp;#39;s consistent), we can use the first rising edge to trigger the start of a TIMER that in turn triggers SAADC sampling in the middle of the positive clock periods.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/211937?ContentTypeID=1</link><pubDate>Thu, 26 Sep 2019 02:58:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9450505c-ac9e-446a-ae70-1e68a0e95162</guid><dc:creator>dj1234</dc:creator><description>&lt;p&gt;This is a bit tricky to answer. I&amp;#39;m interfacing with an HTRC110 reader chip and none of the documentation clearly states what Type of Manchester it is. The only reason I believe it&amp;#39;s Manchester is because a sample driver found&amp;nbsp;&lt;a href="https://github.com/ibexuk/C_RFID_125khz_Readers_HTRC110/blob/master/rfid.c"&gt;here&lt;/a&gt;&amp;nbsp;mentions it.&lt;/p&gt;
&lt;p&gt;I had a look at a waveform of the RF chip on an existing product (I don&amp;#39;t have the source for it) and it&amp;#39;s a waveform with a minimum duration of 256us between two rising edges. This&amp;nbsp;tallies with the comments in the sample code.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/211936?ContentTypeID=1</link><pubDate>Thu, 26 Sep 2019 02:48:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4487dc65-8a79-46db-b820-a5f4bf458d4a</guid><dc:creator>dj1234</dc:creator><description>&lt;p&gt;Hi Thanks very much for your response.&lt;/p&gt;
&lt;p&gt;That&amp;#39;s an interesting idea... I hadn&amp;#39;t considered using the ADC to manually sample a waveform. However, I&amp;#39;m a bit confused with your suggestion to start the timer on the rising edge. Did you mean the *first* rising edge of the signal or *every* rising edge?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/211488?ContentTypeID=1</link><pubDate>Tue, 24 Sep 2019 09:48:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f0d5b515-ca9d-4c3b-9b58-d83036775053</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;Can you specify exactly what kind of Manchester encoding you&amp;#39;re using?&lt;br /&gt;Can you ensure that each transfer starts with a&amp;nbsp;low-to-high or optionally high-to-low transition?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Capturing GPIO transitions of a 4kHz signal with BLE enabled</title><link>https://devzone.nordicsemi.com/thread/211460?ContentTypeID=1</link><pubDate>Tue, 24 Sep 2019 08:41:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f8a42f51-4566-4367-a194-5a1271936c3e</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;If you know the clock frequency and length you can set up a TIMER to trigger a SAADC sample task in the middle of each positive clock period. You start the TIMER on a GPIOTE pin change. That way you can capture a waveform and store it in RAM without using the CPU at all, and then process the data whenever the CPU is available.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Since the signal is digital it should be fairly easy to convert from analog to digital, I suppose you can right-shift the analog 16-bit integer down to msb, then XOR with 1 to get the original data bit.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;ex:&lt;br /&gt;At 10-bit accuracy, say the SAADC samples yield between 512-1023dec for &amp;#39;1&amp;#39;s and 0-511dec for &amp;#39;0&amp;#39;s. Then right shifting the samples by 9 bits will leave you with the manchester-encoded bit.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;The samples are stored as an array, so for a 32-bit transmission, you will need a buffer size of 16bit x 32 = 64bytes&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define BufSize 32

int16_t     MyBuffer[BufSize];
uint32_t    Data = 0;

//After the data is captured:
for(uint16_t i=0; i &amp;lt; BufSize; i++)
{
    My_Buffer[i] &amp;amp;= 0x3FF;          // Remove sign bit if a &amp;#39;0&amp;#39; is registered as negative number
    
    MyBuffer[i] = (MyBuffer &amp;gt;&amp;gt; 9);  /* &amp;#39;9&amp;#39;, because at 10-bit precision with signed value 
                                    the 9th bit is half of max value*/
                                    
    Data |= (MyBuffer[i] &amp;lt;&amp;lt; i);        // OR-in the Manchester-encoded bit into a data buffer
}
Data ^= 0xFFFFFFFF; //XOR with the clock signal, represented by &amp;#39;1&amp;#39;s. 

//Repeat for however many 32-bit words your transfers are.
&lt;/pre&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>