Revert "Merge branch 'pr/446' into 420"

This reverts commit 761dc48b3e, reversing
changes made to 91f037c63f.
This commit is contained in:
RogueMaster
2022-11-25 03:08:53 -05:00
parent d9e7780fb9
commit 28cc99ad2d
40 changed files with 184 additions and 3617 deletions
-205
View File
@@ -1,205 +0,0 @@
#include <limits.h>
#include <furi.h>
#include <furi_hal.h>
#include <furi_hal_gpio.h>
#include "pulse_reader.h"
#define GPIO_PIN_MAP(pin, prefix) \
(((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \
((pin) == (LL_GPIO_PIN_1)) ? prefix##1 : \
((pin) == (LL_GPIO_PIN_2)) ? prefix##2 : \
((pin) == (LL_GPIO_PIN_3)) ? prefix##3 : \
((pin) == (LL_GPIO_PIN_4)) ? prefix##4 : \
((pin) == (LL_GPIO_PIN_5)) ? prefix##5 : \
((pin) == (LL_GPIO_PIN_6)) ? prefix##6 : \
((pin) == (LL_GPIO_PIN_7)) ? prefix##7 : \
((pin) == (LL_GPIO_PIN_8)) ? prefix##8 : \
((pin) == (LL_GPIO_PIN_9)) ? prefix##9 : \
((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \
((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \
((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \
((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \
((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \
prefix##15)
#define GET_DMAMUX_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_DMAMUX_REQ_GEN_EXTI_LINE)
PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size) {
PulseReader* signal = malloc(sizeof(PulseReader));
signal->timer_buffer = malloc(size * sizeof(uint32_t));
signal->gpio_buffer = malloc(size * sizeof(uint32_t));
signal->dma_channel = LL_DMA_CHANNEL_4;
signal->gpio = gpio;
signal->size = size;
signal->timer_value = 0;
signal->pos = 0;
pulse_reader_set_timebase(signal, PulseReaderUnit64MHz);
pulse_reader_set_bittime(signal, 1);
signal->dma_config_timer.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
signal->dma_config_timer.PeriphOrM2MSrcAddress = (uint32_t) &(TIM2->CNT);
signal->dma_config_timer.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
signal->dma_config_timer.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD;
signal->dma_config_timer.MemoryOrM2MDstAddress = (uint32_t) signal->timer_buffer;
signal->dma_config_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
signal->dma_config_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD;
signal->dma_config_timer.Mode = LL_DMA_MODE_CIRCULAR;
signal->dma_config_timer.PeriphRequest = LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */
signal->dma_config_timer.Priority = LL_DMA_PRIORITY_VERYHIGH;
signal->dma_config_gpio.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
signal->dma_config_gpio.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
signal->dma_config_gpio.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD;
signal->dma_config_gpio.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
signal->dma_config_gpio.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD;
signal->dma_config_gpio.Mode = LL_DMA_MODE_CIRCULAR;
signal->dma_config_gpio.PeriphRequest = LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */
signal->dma_config_gpio.Priority = LL_DMA_PRIORITY_VERYHIGH;
return signal;
}
void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit) {
switch(unit) {
case PulseReaderUnit64MHz:
signal->unit_multiplier = 1;
signal->unit_divider = 1;
break;
case PulseReaderUnitPicosecond:
signal->unit_multiplier = 15625;
signal->unit_divider = 1;
break;
case PulseReaderUnitNanosecond:
signal->unit_multiplier = 15625;
signal->unit_divider = 1000;
break;
case PulseReaderUnitMicrosecond:
signal->unit_multiplier = 15625;
signal->unit_divider = 1000000;
break;
}
}
void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time) {
signal->bit_time = bit_time;
}
void pulse_reader_free(PulseReader* signal) {
free(signal->timer_buffer);
free(signal->gpio_buffer);
free(signal);
}
uint32_t pulse_reader_samples(PulseReader* signal) {
uint32_t dma_pos = signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel);
return ((signal->pos + signal->size) - dma_pos) % signal->size;
}
void pulse_reader_stop(PulseReader* signal) {
LL_DMA_DisableChannel(DMA1, signal->dma_channel);
LL_DMA_DisableChannel(DMA1, signal->dma_channel+1);
LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
LL_TIM_DisableCounter(TIM2);
}
void pulse_reader_start(PulseReader* signal) {
/* configure DMA to read from a timer peripheral */
signal->dma_config_timer.NbData = signal->size;
signal->dma_config_gpio.PeriphOrM2MSrcAddress = (uint32_t) &(signal->gpio->port->IDR);
signal->dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t) signal->gpio_buffer;
signal->dma_config_gpio.NbData = signal->size;
/* start counter */
LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
LL_TIM_SetPrescaler(TIM2, 0);
LL_TIM_SetAutoReload(TIM2, 0xFFFFFFFF);
LL_TIM_SetCounter(TIM2, 0);
LL_TIM_EnableCounter(TIM2);
/* generator 0 gets fed by EXTI_LINEn */
LL_DMAMUX_SetRequestSignalID(NULL, LL_DMAMUX_REQ_GEN_0, GET_DMAMUX_EXTI_LINE(signal->gpio->pin));
/* trigger on rising edge of the interrupt */
LL_DMAMUX_SetRequestGenPolarity(NULL, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING);
/* now enable request generation again */
LL_DMAMUX_EnableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
/* we need the EXTI to be configured as interrupt generating line, but no ISR registered */
furi_hal_gpio_init_ex(signal->gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused);
/* capture current timer */
signal->pos = 0;
signal->start_level = furi_hal_gpio_read(signal->gpio);
signal->timer_value = TIM2->CNT;
signal->gpio_mask = signal->gpio->pin;
/* now set up DMA with these settings */
LL_DMA_Init(DMA1, signal->dma_channel, &signal->dma_config_timer);
LL_DMA_Init(DMA1, signal->dma_channel+1, &signal->dma_config_gpio);
LL_DMA_EnableChannel(DMA1, signal->dma_channel);
LL_DMA_EnableChannel(DMA1, signal->dma_channel+1);
}
uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) {
uint32_t start_time = DWT->CYCCNT;
uint32_t timeout_ticks = timeout_us * (F_TIM2/1000000);
do {
/* get the DMA's next write position by reading "remaining length" register */
uint32_t dma_pos = signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel);
/* the DMA has advanced in the ringbuffer */
if(dma_pos != signal->pos) {
uint32_t delta = signal->timer_buffer[signal->pos] - signal->timer_value;
uint32_t last_gpio_value = signal->gpio_value;
signal->gpio_value = signal->gpio_buffer[signal->pos];
/* check if the GPIO really toggled. if not, we lost an edge :( */
if(((last_gpio_value ^ signal->gpio_value) & signal->gpio_mask) != signal->gpio_mask) {
signal->gpio_value ^= signal->gpio_mask;
return PULSE_READER_LOST_EDGE;
}
signal->timer_value = signal->timer_buffer[signal->pos];
signal->pos++;
signal->pos %= signal->size;
uint32_t delta_unit = 0;
/* probably larger values, so choose a wider data type */
if(signal->unit_divider > 1) {
delta_unit = (uint32_t)((uint64_t)delta * (uint64_t)signal->unit_multiplier / signal->unit_divider);
} else {
delta_unit = delta * signal->unit_multiplier;
}
/* if to be scaled to bit times, save a few instructions. should be faster */
if(signal->bit_time > 1) {
return (delta_unit + signal->bit_time / 2) / signal->bit_time;
}
return delta_unit;
}
/* check for timeout */
uint32_t elapsed = DWT->CYCCNT - start_time;
if(elapsed > timeout_ticks) {
return PULSE_READER_NO_EDGE;
}
//furi_delay_ms(0);
} while(true);
}
-140
View File
@@ -1,140 +0,0 @@
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stm32wbxx_ll_dma.h>
#include <stm32wbxx_ll_dmamux.h>
#include <stm32wbxx_ll_tim.h>
#include <stm32wbxx_ll_exti.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;
typedef struct {
bool start_level;
uint32_t* timer_buffer;
uint32_t* gpio_buffer;
uint32_t size;
uint32_t pos;
uint32_t timer_value;
uint32_t gpio_value;
uint32_t gpio_mask;
uint32_t unit_multiplier;
uint32_t unit_divider;
uint32_t bit_time;
uint32_t dma_channel;
const GpioPin* gpio;
LL_DMA_InitTypeDef dma_config_timer;
LL_DMA_InitTypeDef dma_config_gpio;
} 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
*
* @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);
#ifdef __cplusplus
}
#endif