Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The PRU is pretty cool. Just had to simulate a dozen eCAP devices and its just a few lines of code. An eCAP records the period (in ticks) of a signal on an input pin. It can be triggered on a rising or falling signal, and can record absolute ticks or the number of ticks since the last trigger (differential mode). Here's the main loop:

   while (1)
	{
		uint32_t sample = __R31;
		uint32_t change = sample ^ pEcap->sample;

		if (change)
		{
			// Calculate which bits have seen a desired edge (it changed, and we trigger on that change)
			uint32_t edge = change & trigger;

			if (edge)
			{
				uint32_t ts = ReadTimestamp();

				int bit = 1;
				int iBit = 0;
				while (iBit < 30)
				{
					if (edge & bit)
					{
						// Store the ts (or the difference in ts) into the capture table for this bit
						//  and increment the slot index (aICap)
						pEcap->ECAP[iBit][pEcap->aICap[iBit]++] = (pEcap->differential & bit)? (ts - tsLast[iBit]) :ts;
						pEcap->aICap[iBit] %= 4;

						// Next time we calculate the difference from this time
						tsLast[iBit] = ts;
					}
					iBit++;
					bit <<= 1;
				}

				pEcap->edgeDetected |= edge;
			}

			pEcap->sample = sample;
			trigger = sample ^ pEcap->edgeUpDown;
		}
	}

It detects an edge within a few dozen nanoseconds (low jitter). A while loop like this would kill a main processor thread; and it would have terrible latency when other threads were scheduled during a trigger event.

And it detects edges on 30 pins in parallel! I could work on the "which pin had a trigger" code to reduce the period calculation from X30 to log(30) but I have no need for that fine latency in my current application.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: