Skip to content

Commit 62431ac

Browse files
dineshgit411LinjingZhang
authored andcommitted
cores/xmc: Implemented Pulse.
Signed-off-by: MDin <Dinesh.M-EE@infineon.com>
1 parent 9401f00 commit 62431ac

1 file changed

Lines changed: 101 additions & 0 deletions

File tree

cores/xmc/Pulse.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include "Arduino.h"
2+
3+
// Ensure we do not wait here forever by setting maximum and default
4+
// timeouts for 3 minutes and 1 second (in micro-seconds)
5+
// Default used if timeout is set at < 6 microseconds
6+
#define MAX_PULSE_TIMEOUT (3 * 60 * 1000 * 1000)
7+
#define DEF_PULSE_TIMEOUT (1000 * 1000)
8+
9+
uint32_t pulse_state; // State to measure pin input HIGH or LOW
10+
uint32_t mask; // bit mask for relevant pin
11+
XMC_GPIO_PORT_t *pulsePort; // Pointer to GPIO port register structure
12+
uint32_t start_time; // start time of measured pulse
13+
uint32_t end_time; // start time of measured pulse
14+
15+
//****************************************************************************
16+
// @Local Functions
17+
//****************************************************************************
18+
19+
/* Measures the length (in microseconds) of a pulse on the Arduino pin;
20+
* Works on pulses from 6 microseconds to 3 minutes in length,
21+
* but must be called at least a few dozen microseconds
22+
* before the start of the pulse.
23+
*
24+
* Waits for input signal to be at opposite level to being measured
25+
* to avoid getting short measurements of wrong pulse.
26+
*
27+
* Parameters
28+
* pin - which pin to monitor
29+
* state - HIGH or LOW, for the level of pulse to measure.
30+
* timeout - max time in microseconds to wait for whole process
31+
*
32+
* Returns 0 for timeout reached or INVALID pin number
33+
*
34+
* ATTENTION:
35+
* This function relies on the SysTick timer in function micros() so is
36+
* LESS prone to interrupts or other activity interfering. However there
37+
* will always be the possibility of at LEAST +/- 1 counts difference to
38+
* actual signal time. If you need high accuracy use another solution
39+
* with hardware timers in capture mode.
40+
*
41+
* Use of SysTick hardware timer and micros( ) function makes the function
42+
* more portable across various micros and CPU clock frequencies.
43+
*
44+
* Assumptions]
45+
* As per AVR Arduino PulseIn pin is expected to be in input mode already
46+
* No major interrupt activity while measurement is taken (including Serial)
47+
*
48+
* Do NOT make changes to use local (stack) variables as this WILL ADD overhead
49+
* to any operations.
50+
* To improve accuracy beyond this will probably need hard coded assembler
51+
*/
52+
unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout) {
53+
// check pin is valid by NUM_DIGITAL_PINS, return 0 if invalid
54+
#ifdef NUM_DIGITAL_PINS
55+
if (pin >= NUM_DIGITAL_PINS)
56+
return 0;
57+
#endif
58+
59+
// Set up pin details for faster port read in loops
60+
pulsePort = mapping_port_pin[pin].port;
61+
// configure register pin mask to check against
62+
mask = 1UL << mapping_port_pin[pin].pin;
63+
64+
// Check timeout is NOT too small or > Maximum
65+
// if so use default 1 second or MAX respectively
66+
if (timeout < 6)
67+
timeout = DEF_PULSE_TIMEOUT;
68+
else if (timeout > MAX_PULSE_TIMEOUT)
69+
timeout = MAX_PULSE_TIMEOUT;
70+
71+
// Initialise conditions
72+
pulse_state = (state) ? mask : 0; // level to measure
73+
74+
timeout = micros() + timeout; // Set timeout for whole process
75+
76+
// If already at measurement level we have a problem
77+
// So wait for pulse to go to OPPOSITE level required (idle) first
78+
while (((pulsePort->IN & mask) == pulse_state))
79+
if (micros() > timeout)
80+
return 0;
81+
82+
// Wait for pulse to go to level required
83+
while (((pulsePort->IN & mask) != pulse_state))
84+
if (micros() > timeout)
85+
return 0;
86+
87+
// measure pulse length of required level
88+
start_time = micros();
89+
while (((pulsePort->IN & mask) == pulse_state))
90+
if (micros() > timeout)
91+
return 0;
92+
end_time = micros();
93+
94+
// Return time difference
95+
return (end_time - start_time);
96+
}
97+
98+
unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout)
99+
{
100+
return pulseIn(pin, state, timeout);
101+
}

0 commit comments

Comments
 (0)