blob: 6e935576b47b7f9ba85b78aa6b125b41115b8435 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.org/license.html
*/
/**
* @file src/gadc/driver.h
* @brief GADC - Periodic ADC driver header file.
*
* @defgroup Driver Driver
* @ingroup GADC
* @{
*/
#ifndef _GADC_LLD_H
#define _GADC_LLD_H
#include "gfx.h"
#if GFX_USE_GADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Type definitions */
/*===========================================================================*/
/**
* @brief The structure passed to start a timer conversion
* @note We use the structure instead of parameters purely to save
* interrupt stack space which is very limited in some platforms.
* @{
*/
typedef struct GadcLldTimerData_t {
uint32_t physdev; /* @< Which physical ADC devices/channels to use. Filled in by High Level Code */
uint32_t frequency; /* @< The conversion frequency. Filled in by High Level Code */
GDataBuffer *pdata; /* @< The buffer to put the ADC samples into. */
bool_t now; /* @< Trigger the first conversion now rather than waiting for the first timer interrupt (if possible) */
} GadcLldTimerData;
/* @} */
/**
* @brief The structure passed to start a non-timer conversion
* @note We use the structure instead of parameters purely to save
* interrupt stack space which is very limited in some platforms.
* @{
*/
typedef struct GadcLldNonTimerData_t {
uint32_t physdev; /* @< A value passed to describe which physical ADC devices/channels to use. */
adcsample_t *buffer; /* @< The static buffer to put the ADC samples into. */
} GadcLldNonTimerData;
/* @} */
/**
* @brief This can be incremented by the low level driver if a timer interrupt is missed.
* @details Defined in the high level GADC code.
*
* @notapi
*/
extern volatile bool_t GADC_Timer_Missed;
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief These routines are the callbacks that the driver uses.
* @details Defined in the high level GADC code.
*
* @notapi
* @{
*/
/**
* @brief The last conversion requested is now complete
*/
void gadcDataReadyI(void);
/**
* @brief The last conversion requested failed
*/
void gadcDataFailI(void);
/**
* @}
*/
/**
* @brief Initialise the driver
*
* @api
*/
void gadc_lld_init(void);
/**
* @brief Start a periodic timer for high frequency conversions.
*
* @param[in] pgtd The structure containing the sample frequency and physical device to use.
*
* @note The exact meaning of physdev is hardware dependent. It describes the channels
* the will be used later on when a "timer" conversion is actually scheduled.
* @note It is assumed that the timer is capable of free-running even when the ADC
* is stopped or doing something else.
* @details When a timer interrupt occurs a conversion should start if there is a "timer" conversion
* active.
* @note Timer interrupts occurring before @p gadc_lld_adc_timerI() has been called,
* if @p gadc_lld_adc_timerI() has been called quick enough, or while
* a non-timer conversion is active should be ignored other than (optionally) incrementing
* the GADC_Timer_Missed variable.
* @note The pdata and now members of the pgtd structure are now yet valid.
*
* @api
*/
void gadc_lld_start_timer(GadcLldTimerData *pgtd);
/**
* @brief Stop the periodic timer for high frequency conversions.
* @details Also stops any current "timer" conversion (but not a current "non-timer" conversion).
*
* @param[in] pgtd The structure containing the sample frequency and physical device to use.
*
* @note After this function returns there should be no more calls to @p gadcDataReadyI()
* or @p gadcDataFailI() in relation to timer conversions.
* @api
*/
void gadc_lld_stop_timer(GadcLldTimerData *pgtd);
/**
* @brief Start a set of "timer" conversions.
* @details Starts a series of conversions triggered by the timer.
*
* @param[in] pgtd Contains the parameters for the timer conversion.
*
* @note The exact meaning of physdev is hardware dependent. It is likely described in the
* drivers gadc_lld_config.h
* @note The driver should call @p gadcDataReadyI() when it completes the operation
* or @p gadcDataFailI() on an error.
* @note The high level code ensures that this is not called while a non-timer conversion is in
* progress
*
* @iclass
*/
void gadc_lld_adc_timerI(GadcLldTimerData *pgtd);
/**
* @brief Start a "non-timer" conversion.
* @details Starts a single conversion now.
*
* @param[in] pgntd Contains the parameters for the non-timer conversion.
*
* @note The exact meaning of physdev is hardware dependent. It is likely described in the
* drivers gadc_lld_config.h
* @note The driver should call @p gadcDataReadyI() when it completes the operation
* or @p gadcDataFailI() on an error.
* @note The high level code ensures that this is not called while a timer conversion is in
* progress
*
* @iclass
*/
void gadc_lld_adc_nontimerI(GadcLldNonTimerData *pgntd);
#ifdef __cplusplus
}
#endif
#endif /* GFX_USE_GADC */
#endif /* _GADC_LLD_H */
/** @} */
|