Skip to content

Commit

Permalink
Map pin number argument to internal pin number using digitalPinToPin
Browse files Browse the repository at this point in the history
Adjust loop count to microsecond computations
  • Loading branch information
jhmaloney authored and sandeepmistry committed Nov 10, 2020
1 parent 772990a commit d50e109
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions cores/nRF5/pulse.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,25 @@ extern unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit,
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse. */
uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout)
uint32_t pulseIn(uint32_t ulPin, uint32_t state, uint32_t timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
// PinDescription p = g_APinDescription[pin];
uint32_t bit = 1 << pin; //p.ulPin;
uint32_t bit = 1 << digitalPinToPin(ulPin);
uint32_t stateMask = state ? bit : 0;

// convert the timeout from microseconds to a number of times through
// the initial loop; it takes (roughly) 13 clock cycles per iteration.
uint32_t maxloops = microsecondsToClockCycles(timeout) / 13;

uint32_t width = countPulseASM(&(NRF_GPIO->IN), bit, stateMask, maxloops);

// convert the reading to microseconds. The loop has been determined
// to be 13 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
if (width)
return clockCyclesToMicroseconds(width * 13 + 16);
else
return 0;
// the initial loop; it takes (roughly) 10 clock cycles per iteration.
uint32_t maxloops = microsecondsToClockCycles(timeout) / 10;

// count low-level loops during the pulse (or until maxLoops)
// a zero loopCount means that a complete pulse was not detected within the timeout
uint32_t loopCount = countPulseASM(&(NRF_GPIO->IN), bit, stateMask, maxloops);

// convert the reading to (approximate) microseconds. The loop time as measured with an
// oscilloscope is 10 cycles on a BBC micro:bit 1.3 (nRF51822). There is error because the
// time is quantized to an integral number of loops and because interrupt may steal cycles.
return clockCyclesToMicroseconds(10 * loopCount);
}

0 comments on commit d50e109

Please sign in to comment.