unleashed-firmware/lib/pulse_reader/pulse_reader.h
g3gg0.de e1c6e78b2e
added DigitalSequence and PulseReader (#2070)
* added DigitalSequence to chain multiple DigitalSignals
added PulseReader for hardware assisted digital signal sampling
* added send_time option to start a signal at a specific DWT->CYCCNT value
* fixed linter errors and undone function renaming
* fixed renaming
* flagged functions in api_symbols.csv
* allow gpio field to stay uninitialized in digital_signal_prepare_arr()
* fix test cases to match (expected) implementation
* pulse_reader: build as static library
Signed-off-by: g3gg0.de <git@g3gg0.de>
* fix starting level detection in pulse_reader
* added unit test for pulse_reader
* change pulse reader test timings to 1, 10 and 100 ms
* fine tuned timings for pulse_reader test
* pulse_reader_stop now deinits GPIO as recommended by @gornekich
* ran format_py
* pulse_reader: remove from API, allow to link with faps
Signed-off-by: g3gg0.de <git@g3gg0.de>
* remove unit test for pulse_reader again
* pulse_reader: add call to set GPIO pull direction
* make structures private, add C implementation of digital_signal_update_dma()
* digital_signal/pulse_reader: allow parameters for free to be NULL
* digital_signal: show unoptimized and optimized code for digital_signal_update_dma() next to each other
* pulse_reader: further optimize assembly code
* digital_signal: reduce code complexity of digital_signal_update_dma() by only reconfiguring DMA2
* digital_signal: remove assembly code, limiting the performance but increasing portability
* added recovery if the timer already expired
* digital_signal: fix memory leak
* digital_signal: keep lock until all DMA transfers have finished
* DigitalSequence: fix issues with concatenation of same levels and spurious bit flips
* DigitalSignal: use cyclic DMA buffer for sequences
* update api_symbols.csv
* Update api_symbols.csv for f18 target
* Patches from @gornekich to fix linter warnings.
* Remove some redundant if checks
* Remove some magic numbers and reformat.
* Remove forced terminating edge.

Signed-off-by: g3gg0.de <git@g3gg0.de>
Co-authored-by: gornekich <n.gorbadey@gmail.com>
Co-authored-by: Tiernan Messmer <tiernan.messmer@gmail.com>
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
2023-05-09 09:55:17 +09:00

122 lines
3.3 KiB
C

#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <furi_hal_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PULSE_READER_NO_EDGE (0xFFFFFFFFUL)
#define PULSE_READER_LOST_EDGE (0xFFFFFFFEUL)
#define F_TIM2 (64000000UL)
/**
* unit of the edge durations to return
*/
typedef enum {
PulseReaderUnit64MHz,
PulseReaderUnitPicosecond,
PulseReaderUnitNanosecond,
PulseReaderUnitMicrosecond,
} PulseReaderUnit;
/* using an anonymous type */
typedef struct PulseReader PulseReader;
/** Allocate a PulseReader object
*
* Allocates memory for a ringbuffer and initalizes the object
*
* @param[in] gpio the GPIO to use. will get configured as input.
* @param[in] size number of edges to buffer
*/
PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size);
/** Free a PulseReader object
*
* Frees all memory of the given object
*
* @param[in] signal previously allocated PulseReader object.
*/
void pulse_reader_free(PulseReader* signal);
/** Start signal capturing
*
* Initializes DMA1, TIM2 and DMAMUX_REQ_GEN_0 to automatically capture timer values.
* Ensure that interrupts are always enabled, as the used EXTI line is handled as one.
*
* @param[in] signal previously allocated PulseReader object.
*/
void pulse_reader_start(PulseReader* signal);
/** Stop signal capturing
*
* Frees DMA1, TIM2 and DMAMUX_REQ_GEN_0
*
* @param[in] signal previously allocated PulseReader object.
*/
void pulse_reader_stop(PulseReader* signal);
/** Recevie a sample from ringbuffer
*
* Waits for the specified time until a new edge gets detected.
* If not configured otherwise, the pulse duration will be in picosecond resolution.
* If a bittime was configured, the return value will contain the properly rounded
* number of bit times measured.
*
* @param[in] signal previously allocated PulseReader object.
* @param[in] timeout_us time to wait for a signal [µs]
*
* @returns the scaled value of the pulse duration
*/
uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us);
/** Get available samples
*
* Get the number of available samples in the ringbuffer
*
* @param[in] signal previously allocated PulseReader object.
*
* @returns the number of samples in buffer
*/
uint32_t pulse_reader_samples(PulseReader* signal);
/** Set timebase
*
* Set the timebase to be used when returning pulse duration.
*
* @param[in] signal previously allocated PulseReader object.
* @param[in] unit PulseReaderUnit64MHz or PulseReaderUnitPicosecond
*/
void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit);
/** Set bit time
*
* Set the number of timebase units per bit.
* When set, the pulse_reader_receive() will return an already rounded
* bit count value instead of the raw duration.
*
* Set to 1 to return duration again.
*
* @param[in] signal previously allocated PulseReader object.
* @param[in] bit_time
*/
void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time);
/** Set GPIO pull direction
*
* Some GPIOs need pulldown, others don't. By default the
* pull direction is GpioPullNo.
*
* @param[in] signal previously allocated PulseReader object.
* @param[in] pull GPIO pull direction
*/
void pulse_reader_set_pull(PulseReader* signal, GpioPull pull);
#ifdef __cplusplus
}
#endif