version 2.8
gadc.h
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.org/license.html
6  */
7 
8 /**
9  * @file src/gadc/gadc.h
10  *
11  * @addtogroup GADC
12  *
13  * @brief Module to abstract the very variable ADC interfaces of the underlying systems
14  *
15  * @details The reason why uGFX has it's own ADC abstraction is because
16  * the Chibi-OS drivers are very CPU specific and do not
17  * provide a way across all hardware platforms to create periodic
18  * ADC conversions. There are also issues with devices with different
19  * characteristics or periodic requirements on the same ADC
20  * device (but different channels). This layer attempts to solve these
21  * problems to provide a architecture neutral API. It also provides extra
22  * features such as multi-buffer chaining for high speed ADC sources.
23  * It provides one high speed virtual ADC device (eg a microphone) and
24  * numerous low speed (less than 100Hz) virtual ADC devices (eg dials,
25  * temperature sensors etc). The high speed device has timer based polling
26  * to ensure exact conversion periods and a buffer management system.
27  * The low speed devices are assumed to be non-critical timing devices
28  * and do not have any buffer management.
29  * Note that while only one high speed device has been provided it can
30  * be used to read multiple physical ADC channels on the one physical
31  * ADC device.
32  * All callback routines are thread based unlike the Chibi-OS interrupt based
33  * routines.
34  *
35  * @{
36  */
37 
38 #ifndef _GADC_H
39 #define _GADC_H
40 
41 #include "../../gfx.h"
42 
43 #if GFX_USE_GADC || defined(__DOXYGEN__)
44 
45 /* Include the driver defines */
46 #include "gadc_lld_config.h"
47 
48 /*===========================================================================*/
49 /* Type definitions */
50 /*===========================================================================*/
51 
52 // Event types for GADC
53 #define GEVENT_ADC (GEVENT_GADC_FIRST+0)
54 
55 /**
56  * @brief The High Speed ADC event structure.
57  * @{
58  */
59 typedef struct GEventADC_t {
60  #if GFX_USE_GEVENT || defined(__DOXYGEN__)
61  /**
62  * @brief The type of this event (GEVENT_ADC)
63  */
64  GEventType type;
65  #endif
66 
67  /**
68  * @brief The event flags
69  */
70  uint16_t flags;
71  /**
72  * @brief The event flag values.
73  * @{
74  */
75  #define GADC_HSADC_LOSTEVENT 0x0001 /**< @brief The last GEVENT_HSDADC event was lost */
76  #define GADC_HSADC_RUNNING 0x0002 /**< @brief The High Speed ADC is currently running */
77  #define GADC_HSADC_GOTBUFFER 0x0004 /**< @brief A buffer is ready for processing */
78  #define GADC_HSADC_STALL 0x0008 /**< @brief The High Speed ADC has stalled due to no free buffers */
79  /** @} */
80 } GEventADC;
81 /** @} */
82 
83 /**
84  * @brief A callback function (executed in a thread context) for a low speed conversion
85  */
86 typedef void (*GADCCallbackFunction)(adcsample_t *buffer, void *param);
87 
88 /**
89  * @brief A callback function (executed in an ISR context) for a high speed conversion
90  */
91 typedef void (*GADCISRCallbackFunction)(void);
92 
93 /*===========================================================================*/
94 /* External declarations. */
95 /*===========================================================================*/
96 
97 #ifdef __cplusplus
98 extern "C" {
99 #endif
100 
101 /**
102  * @brief Initialise the high speed ADC.
103  * @details Initialises but does not start the conversions.
104  *
105  * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
106  * @param[in] frequency The frequency to create ADC conversions
107  *
108  * @note If the high speed ADC is running it will be stopped. The Event subsystem is
109  * disconnected from the high speed ADC and any binary semaphore event is forgotten.
110  * @note ChibiOS ONLY: Due to a bug in ChibiOS each buffer on the free-list must contain an even number of
111  * samples and for multi-channel devices it must hold a number of samples that is evenly divisible
112  * by 2 times the number of active channels.
113  * @note The physdev parameter may be used to turn on more than one ADC channel.
114  * Each channel is then interleaved into the provided buffer. Make sure your buffers all hold
115  * a number of samples evenly divisible by the number of active channels.
116  * As an example, if physdev turns on 2 devices then the buffer contains
117  * alternate device samples and the buffer must contain multiples of 2 samples.
118  * The exact meaning of physdev is hardware dependent.
119  * @note While the high speed ADC is running, low speed conversions can only occur at
120  * the frequency of the high speed events. Thus if high speed events are
121  * being created at 50Hz (eg 100 samples/buffer, frequency = 5kHz) then the maximum
122  * frequency for low speed conversions will be 50Hz.
123  * @note Only a single sample format is supported - that provided by the GADC driver. That sample
124  * format applies to both high speed and low speed sampling.
125  *
126  * @api
127  */
128 void gadcHighSpeedInit(uint32_t physdev, uint32_t frequency);
129 
130 #if GFX_USE_GEVENT || defined(__DOXYGEN__)
131  /**
132  * @brief Turn on sending results to the GEVENT sub-system.
133  * @details Returns a GSourceHandle to listen for GEVENT_ADC events.
134  *
135  * @note The high speed ADC will not use the GEVENT system unless this is
136  * called first. This saves processing time if the application does
137  * not want to use the GEVENT sub-system for the high speed ADC.
138  * Once turned on it can only be turned off by calling @p gadcHighSpeedInit() again.
139  * @note The high speed ADC is capable of signalling via this method, an ISR callback and a
140  * binary semaphore at the same time.
141  *
142  * @return The GSourceHandle
143  *
144  * @api
145  */
146  GSourceHandle gadcHighSpeedGetSource(void);
147 #endif
148 
149 /**
150  * @brief Allow retrieving of results from the high speed ADC using an ISR callback.
151  *
152  * @param[in] isrfn The callback function (called in an ISR context).
153  *
154  * @note Passing a NULL for isrfn will turn off signalling via this method as will calling
155  * @p gadcHighSpeedInit().
156  * @note The high speed ADC is capable of signalling via this method, a blocked thread and the GEVENT
157  * sub-system at the same time.
158  *
159  * @api
160  */
162 
163 /**
164  * @brief Get a filled buffer from the ADC
165  * @return A GDataBuffer pointer or NULL if the timeout is exceeded
166  *
167  * @param[in] ms The maximum amount of time in milliseconds to wait for data if some is not currently available.
168  *
169  * @note After processing the data, your application must return the buffer to the free-list so that
170  * it can be used again. This can be done using @p gfxBufferRelease().
171  * @note A buffer may be returned to the free-list before you have finished processing it provided you finish
172  * processing it before GADC re-uses it. This is useful when RAM usage is critical to reduce the number
173  * of buffers required. It works before the free list is a FIFO queue and therefore buffers are kept
174  * in the queue as long as possible before they are re-used.
175  * @note The function ending with "I" is the interrupt class function.
176  * @api
177  * @{
178  */
179 GDataBuffer *gadcHighSpeedGetData(delaytime_t ms);
180 GDataBuffer *gadcHighSpeedGetDataI(void);
181 /** @} */
182 
183 /**
184  * @brief Start the high speed ADC conversions.
185  * @pre It must have been initialised first with @p gadcHighSpeedInit()
186  *
187  * @api
188  */
189 void gadcHighSpeedStart(void);
190 
191 /**
192  * @brief Stop the high speed ADC conversions.
193  *
194  * @api
195  */
196 void gadcHighSpeedStop(void);
197 
198 /**
199  * @brief Perform a single low speed ADC conversion
200  * @details Blocks until the conversion is complete
201  * @pre This should not be called from within a GTimer callback as this routine
202  * blocks until the conversion is ready.
203  *
204  * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
205  * @param[in] buffer The static buffer to put the ADC samples into.
206  *
207  * @note This may take a while to complete if the high speed ADC is running as the
208  * conversion is interleaved with the high speed ADC conversions on a buffer
209  * completion.
210  * @note The result buffer must be large enough to store one sample per device
211  * described by the 'physdev' parameter.
212  * @note Specifying more than one device in physdev is possible but discouraged as the
213  * calculations to ensure the high speed ADC correctness will be incorrect. Symptoms
214  * from over-running the high speed ADC include high speed device stalling or samples being lost.
215  *
216  * @api
217  */
218 void gadcLowSpeedGet(uint32_t physdev, adcsample_t *buffer);
219 
220 /**
221  * @brief Perform a low speed ADC conversion with callback (in a thread context)
222  * @details Returns FALSE if internal memory allocation fails
223  *
224  * @param[in] physdev A value passed to describe which physical ADC devices/channels to use.
225  * @param[in] buffer The static buffer to put the ADC samples into.
226  * @param[in] fn The callback function to call when the conversion is complete.
227  * @param[in] param A parameter to pass to the callback function.
228  *
229  * @return FALSE if no free low speed ADC slots.
230  *
231  * @note This may be safely called from within a GTimer callback.
232  * @note The callback may take a while to occur if the high speed ADC is running as the
233  * conversion is interleaved with the high speed ADC conversions on a buffer
234  * completion.
235  * @note The result buffer must be large enough to store one sample per device
236  * described by the 'physdev' parameter.
237  * @note Specifying more than one device in physdev is possible but discouraged as the
238  * calculations to ensure the high speed ADC correctness will be incorrect. Symptoms
239  * from over-running the high speed ADC include high speed samples being lost.
240  *
241  * @api
242  */
243 bool_t gadcLowSpeedStart(uint32_t physdev, adcsample_t *buffer, GADCCallbackFunction fn, void *param);
244 
245 #ifdef __cplusplus
246 }
247 #endif
248 
249 #endif /* GFX_USE_GADC */
250 
251 #endif /* _GADC_H */
252 /** @} */
A Data Buffer Queue.
Definition: gqueue.h:78
struct GEventADC_t GEventADC
The High Speed ADC event structure.
void gadcLowSpeedGet(uint32_t physdev, adcsample_t *buffer)
Perform a single low speed ADC conversion.
void gadcHighSpeedStart(void)
Start the high speed ADC conversions.
void(* GADCISRCallbackFunction)(void)
A callback function (executed in an ISR context) for a high speed conversion.
Definition: gadc.h:91
The High Speed ADC event structure.
Definition: gadc.h:59
uint16_t flags
The event flags.
Definition: gadc.h:70
GDataBuffer * gadcHighSpeedGetData(delaytime_t ms)
Get a filled buffer from the ADC.
void(* GADCCallbackFunction)(adcsample_t *buffer, void *param)
A callback function (executed in a thread context) for a low speed conversion.
Definition: gadc.h:86
void gadcHighSpeedSetISRCallback(GADCISRCallbackFunction isrfn)
Allow retrieving of results from the high speed ADC using an ISR callback.
void gadcHighSpeedInit(uint32_t physdev, uint32_t frequency)
Initialise the high speed ADC.
void gadcHighSpeedStop(void)
Stop the high speed ADC conversions.
GEventType type
The type of this event (GEVENT_ADC)
Definition: gadc.h:64
bool_t gadcLowSpeedStart(uint32_t physdev, adcsample_t *buffer, GADCCallbackFunction fn, void *param)
Perform a low speed ADC conversion with callback (in a thread context)
GSourceHandle gadcHighSpeedGetSource(void)
Turn on sending results to the GEVENT sub-system.