From 91bc53a27ab54566461783a371d4c7865e1c3231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 26 Mar 2018 22:07:29 +0200 Subject: [PATCH] finished documenting fcap --- README.md | 2 +- UNIT_FCAP.md | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 UNIT_FCAP.md diff --git a/README.md b/README.md index d991530..1402fca 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This repository specifies the control protocol implemented by [gex-core](https:/ - [UNIT_SIPO.md](UNIT_SIPO.md) - Shift Register Driver with multicast - [UNIT_I2C.md](UNIT_I2C.md) - I2C master - [UNIT_SPI.md](UNIT_SPI.md) - SPI master with up to 16 slaves and multicast -- UNIT_FCAP.md - Frequency, pulse length, PWM measurement +- [UNIT_FCAP.md](UNIT_FCAP.md) - Frequency, pulse length, PWM measurement; Pulse counter - UNIT_1WIRE.md - 1-Wire master - UNIT_ADC.md - ADC with raw access, triggering, periodic capture - UNIT_DAC.md - DAC with DDS diff --git a/UNIT_FCAP.md b/UNIT_FCAP.md new file mode 100644 index 0000000..fdffc07 --- /dev/null +++ b/UNIT_FCAP.md @@ -0,0 +1,194 @@ +# Frequency / Pulse measurement + +- Frequency measurement + - Direct method (counting pulses in a time period) + - Indirect method (measuring a single pulse) +- PWM measurement - Indirect method also reports duty cycle +- Single pulse measurement +- Free-running pulse counter + +### Direct vs Indirect method + +The direct method works well for a wide range of frequencies, from Hz to tens of MHz. For +very high frequencies, a prescaller can be enabled. This method has a best-case +resolution of 1 Hz, which could be increased by extending the measurement time, which +already needs to be long, usually 1 second or more for low frequencies. + +The indirect method has a sub-Hz resolution and is much faster than the direct method for +low frequencies. It can be used for signals up to tens of kHz, while the direct method +can handle 20 MHz or more without issues. + +*NOTE:* The accuracy of all measurements is dependent on the system clock speed. +To measure the system clock using an external counter, you can output it on a pin using +the MCO function configured in `SYSTEM.INI`. + +### Burst vs Continuous + +Both the direct and indirect methods can operate in a free-running or burst mode. + +- Burst mode performs one or several measurements (with averaging if using the indirect method). +- Free-running (continuous) mode performs periodic measurements without averaging. + The advantage is that the last measurement is always immediately available for read-out, without having to wait for the emasurement. + +## Commands + +### STOP (0) + +Stops all ongoing measurements. + +### INDIRECT_CONT_START (1) + +Start a free-running frequency / duty cycle measuring using the indirect method. + +### INDIRECT_BURST_START (2) + +Start a burst of indirect measurements. +Waits for the next rising edge before starting the measurements. + +*Request:* +- u16 - number of pulses to average + +*Response:* +- u16 - core speed in MHz +- u16 - number of pulses +- u64 - sum of all periods (in core ticks) +- u16 - sum of all on-times (positive interval of the pulse) + +GEX avoids using float here to reduce code size and avoid floating +point errors. To get the period, use `period_sec = periods / (mhz * 10e6 * count)` + +Frequency is `freq = 1 / period`. + +The average duty cycle is `duty = ontimes / periods` + +### DIRECT_CONT_START (3) + +Start repeated measurement using the direct method. + +*Request:* +- u16 - measurement time (ms) + - 0 = no change + - default 1000, configurable in the unit settings +- u8 - prescaller (1,2,4,8) + - 0 = no change + - default 1, configurable in the unit settings + +### DIRECT_BURST_START (4) + +Start a single direct measurement (pulse counting) over +a given time period. Longer periods can be used for higher precision +using averaging. + +*Request:* +- u16 - measurement time (ms), often 1000 (=1s) +- u8 - prescaller (1,2,4,8) + - 0 = no change + - default 1, configurable in the unit settings + +*Response:* +- u8 - prescaller (1,2,4,8) +- u16 - measurement time (ms) +- u32 - pulse count + +Calculate the frequency by `freq = (1000 * count * presc) / time_ms`. + +### FREECOUNT_START (5) + +Clear and start the free-running pulse counter. + +*Request:* +- u8 - prescaller (1,2,4,8) + - 0 = no change + - default 1, configurable in the unit settings + +### MEASURE_SINGLE_PULSE (6) + +Measure a single pulse on the input. Waits for a rising edge. + +*NOTE:* The result may be inaccurate if the input is High when starting the measurement. + +*Response:* +- u16 - core speed in MHz +- u32 - pulse length (core ticks) + +### FREECOUNT_CLEAR (7) + +Clear the free-running counter while retrieving the current value. +Normally no pulses should be missed, but please be aware that this +operation is not atomic and glitches can occur at high frequencies. + +*Response:* +- u32 - last counter value + +### INDIRECT_CONT_READ (10) + +Read the latest result from the continuous indirect method measurement +(measurement of individual pulses). + +*Response:* +- u16 - core speed in MHz +- u32 - period (core ticks) +- u32 - on-time (positive interval of the pulse) + +Duty cycle is `duty = ontime / period`. +Period `period_sec = period / (mhz * 10e6)`. +Frequency `freq = 1 / period_sec`. + +### DIRECT_CONT_READ (11) + +Read the latest result from the continuous direct method measurement (pulse counting). + +*Response:* +- u8 - prescaller (1,2,4,8) +- u16 - measurement time (ms) +- u32 - pulse count + +Frequency is `freq = (1000 * presc * count) / time_ms`. + +### FREECOUNT_READ (12) + +Read the current value of the free-running pulse counter. + +*Response:* +- u32 - counter value + +### SET_POLARITY (20) + +Set the measured pulse polarity. + +*NOTE:* This is normally configured in the unit settings. +Changes done through this method are temporary, not persisted to flash. The same +applies to the other SET_* commands. + +*Request:* +- u8 - active level (0,1) + +### SET_DIR_PRESC (21) + +Set prescaller for the direct mode measurement. + +*NOTE:* This does not take effect until the direct measurement is restarted. (TODO: fix?) + +*Request:* +- u8 - prescaller (1,2,4,8) + +### SET_INPUT_FILTER (22) + +Set input filtering (a hardware feature designed to ignore short glitches) + +*Request:* +- u8 - digital filtering factor (0-15, 0=off) + +### SET_DIR_MSEC (23) + +Set direct measurement period. + +*NOTE:* This does not take effect until the direct measurement is restarted. (TODO: fix?) + +*Request:* +- u16 - period in milliseconds + +### RESTORE_DEFAULTS (30) + +Stop any measurement and restore all the run-time configurable settings to their default +values (as configured in the unit settings).