GEX core repository.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gex-core/units/adc/_adc_internal.h

138 lines
6.1 KiB

7 years ago
//
// Created by MightyPork on 2018/02/03.
//
#ifndef GEX_F072_ADC_INTERNAL_H
#define GEX_F072_ADC_INTERNAL_H
#ifndef ADC_INTERNAL
#error bad include!
#endif
#include "unit_base.h"
#define UADC_MAX_FREQ_FOR_AVERAGING 20000
enum uadc_opmode {
ADC_OPMODE_UNINIT, //!< Not yet switched to any mode
ADC_OPMODE_IDLE, //!< Idle. Allows immediate value readout and averaging.
ADC_OPMODE_REARM_PENDING, //!< Idle, waiting for the next sample to re-arm (auto trigger).
ADC_OPMODE_ARMED, //!< Armed for a trigger. Direct access and averaging are disabled.
ADC_OPMODE_TRIGD, //!< Triggered, sending pre-trigger and streaming captured data.
ADC_OPMODE_BLCAP, //!< Capture of fixed length without a trigger
ADC_OPMODE_STREAM, //!< Unlimited capture
ADC_OPMODE_EMERGENCY_SHUTDOWN, //!< Used when the buffers overrun to safely transition to IDLE after a delay
};
enum uadc_event {
EVT_CAPT_START = 50, //!< Capture start (used in event in the first frame when trigger is detected)
EVT_CAPT_MORE = 51, //!< Capture data payload (used as TYPE for all capture types)
EVT_CAPT_DONE = 52, //!< End of trig'd or block capture payload (last frame with data),
//!< or a farewell message after closing stream using abort(), in this case without data.
};
7 years ago
/** Private data structure */
struct priv {
// settings
uint16_t channels; //!< bit flags (will be recorded in order 0-15)
bool enable_tsense; //!< append a signal from the temperature channel (voltage proportional to Tj)
bool enable_vref; //!< append a signal from the internal voltage reference
uint8_t sample_time; //!< 0-7 (corresponds to 1.5-239.5 cycles) - time for the sampling capacitor to charge
uint32_t frequency; //!< Timer frequency in Hz. Note: not all frequencies can be achieved accurately
uint16_t buffer_size; //!< Buffer size in bytes (count 2 bytes per channel per measurement) - faster sampling freq needs bigger buffer
uint16_t averaging_factor; //!< Exponential averaging factor 0-1000
7 years ago
// internal state
7 years ago
float real_frequency;
uint32_t real_frequency_int;
uint32_t extended_channels_mask; //!< channels bitfield including tsense and vref
float avg_factor_as_float;
ADC_TypeDef *ADCx; //!< The ADC peripheral used
ADC_Common_TypeDef *ADCx_Common; //!< The ADC common control block
TIM_TypeDef *TIMx; //!< ADC timing timer instance
DMA_TypeDef *DMAx; //!< DMA isnatnce used
uint8_t dma_chnum; //!< DMA channel number
DMA_Channel_TypeDef *DMA_CHx; //!< DMA channel instance
uint16_t *dma_buffer; //!< malloc'd buffer for the samples
uint8_t nb_channels; //!< nbr of enabled adc channels
uint16_t dma_buffer_itemcount; //!< real size of the buffer in samples (adjusted to fit 2x whole multiple of sample group)
uint32_t trig_stream_remain; //!< Counter of samples remaining to be sent in the post-trigger stream
uint16_t trig_holdoff_remain; //!< Tmp counter for the currently active hold-off
uint16_t trig_prev_level; //!< Value of the previous sample, used to detect trigger edge
uint16_t stream_startpos; //!< Byte offset in the DMA buffer where the next capture for a stream should start.
//!< Updated in TH/TC and on trigger (after the preceding data is sent as a pretrig buffer)
enum uadc_opmode opmode; //!< OpMode (state machine state)
float averaging_bins[18]; //!< Averaging buffers, enough space to accommodate all channels (16 external + 2 internal)
uint16_t last_samples[18]; //!< If averaging is disabled, the last captured sample is stored here.
uint8_t trigger_source; //!< number of the pin selected as a trigger source
uint16_t pretrig_len; //!< Pre-trigger length, nbr of historical samples to report when trigger occurs
uint32_t trig_len; //!< Trigger length, nbr of samples to report AFTER a trigger occurs
uint16_t trig_level; //!< Triggering level in LSB
uint8_t trig_edge; //!< Which edge we want to trigger on. 1-rising, 2-falling, 3-both
bool auto_rearm; //!< Flag that the trigger should be re-armed after the stream finishes
uint16_t trig_holdoff; //!< Trigger hold-off time, set when configuring the trigger
TF_ID stream_frame_id; //!< Session ID for multi-part stream (response or report)
uint8_t stream_serial;
7 years ago
};
/** Allocate data structure and set defaults */
error_t UADC_preInit(Unit *unit);
/** Load from a binary buffer stored in Flash */
void UADC_loadBinary(Unit *unit, PayloadParser *pp);
/** Write to a binary buffer for storing in Flash */
void UADC_writeBinary(Unit *unit, PayloadBuilder *pb);
// ------------------------------------------------------------------------
/** Parse a key-value pair from the INI file */
error_t UADC_loadIni(Unit *unit, const char *key, const char *value);
/** Generate INI file section for the unit */
void UADC_writeIni(Unit *unit, IniWriter *iw);
// ------------------------------------------------------------------------
/** Finalize unit set-up */
error_t UADC_init(Unit *unit);
/** Tear down the unit */
void UADC_deInit(Unit *unit);
// ------------------------------------------------------------------------
/** DMA half/complete handler */
void UADC_DMA_Handler(void *arg);
/** ADC eod of sequence handler */
void UADC_ADC_EOS_Handler(void *arg);
/** Switch to a different opmode */
void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode);
/** Handle trigger - process pre-trigger and start streaming the requested number of samples */
void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp);
/** Handle a periodic tick - expiring the hold-off */
void UADC_updateTick(Unit *unit);
/** Send a end-of-stream message to PC's stream listener so it can shut down. */
void UADC_ReportEndOfStream(Unit *unit);
/** Start a block capture */
void UADC_StartBlockCapture(Unit *unit, uint32_t len, TF_ID frame_id);
/** Start stream */
void UADC_StartStream(Unit *unit, TF_ID frame_id);
/** End stream */
void UADC_StopStream(Unit *unit);
7 years ago
/** Configure frequency */
error_t UADC_SetSampleRate(Unit *unit, uint32_t hertz);
7 years ago
#endif //GEX_F072_ADC_INTERNAL_H