ECE 486 Support Libraries
init486.h
Go to the documentation of this file.
1 /**!
2  * @file
3  *
4  * @brief STM32L476-Discovery configuration routines to support ECE 486
5  *
6  * @author Don Hummels
7  *
8  * @date Jan 2016
9  *
10  * Contains all of the subroutines to configure various peripherals of the stm32L476
11  * RCC, GPIO ports, DMAs, ADCs, DACs, etc.
12  *
13  * @defgroup ECE486_Init ECE 486 Processor Initialization
14  * @{
15  */
16 
17 #ifndef __INIT486__
18 #define __INIT486__
19 
20 /*
21  * Includes..........................................................................
22  */
23 #include <stdint.h>
24 
25 
26 /*
27  * Defines..........................................................................
28  */
29 
30 /*
31  * Compile Flags
32  */
33 // #define TIM4_TO_PB6
34 
35 /*!
36  * @defgroup LED_L476 STM32L476-Discovery LED Assignments
37  * @{
38  */
39 #define ERROR_LED LED4 //!< Red LED, STM32L476G-Discovery
40 #define NORMAL_LED LED5 //!< Green LED, STM32L476G-Discovery
41 /*! @} End of STM32L476-Discovery LED Assignments */
42 
43 
44 
45 // ADC Input pins are also board-specific to avoid hardware conflicts
46 #if defined(STM32L476xx)
47 /*!
48  *
49  * @defgroup ADC_Pin_Assignments_L476 STM32L476-Discovery ADC Assignments
50  * @{
51  *
52  * STM32L476-Discovery Pin Assignments:
53  * ADC1, Channel 6, tied to pin PA1.
54  * ADC2, Channel 7, tied to pin PA2.
55  * Digital Output: PD0
56  */
57 #define ADC1_CHANNEL ADC_CHANNEL_6
58 #define ADC1_GPIO_PORT GPIOA
59 #define ADC1_GPIO_PIN GPIO_PIN_1
60 #define ADC1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
61 
62 #define ADC2_CHANNEL ADC_CHANNEL_7
63 #define ADC2_GPIO_PORT GPIOA
64 #define ADC2_GPIO_PIN GPIO_PIN_2
65 #define ADC2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
66 
67 #define DIGITAL_IO_PORT GPIOD
68 #define DIGITAL_IO_PIN GPIO_PIN_0
69 #define DIGITAL_IO_CLK_ENABLE() __GPIOD_CLK_ENABLE()
70 
71 /*! @} End of STM32L476-Discovery ADC Pin Assignments */
72 
73 #else
74 #error "Unknown development board: Define STM32L486xx for STM32L476-Discovery"
75 #endif
76 
77 /*! @} End of Board_Specific_Config group */
78 
79 // Valid Clock divisors to sample rate constants for initialize()
80 // (Integers used to divide an 80 MHz clock to obtain a desired sample rate)
81 /*!
82  *
83  * @defgroup FS_Count_Values Timer Count constants for determining ADC/DAC sample rates
84  * @{
85  *
86  * Timers are each driven by 80 MHz clock signals. These integer constants are
87  * used to divide this clock rate down to audio sampling frequencies for the
88  * ADCs and DACs (Timer 4). For example, to obtain a 50 ksps ADC/DAC clock, the
89  * timer period should be set to (80 MHz / 50 ksps)=1600 counts.
90  */
91 #define FS_2K 40000 //!< 2 ksamples/sec
92 #define FS_4K 20000 //!< 4 ksamples/sec
93 #define FS_5K 16000 //!< 5 ksamples/sec
94 #define FS_8K 10000 //!< 8 ksamples/sec
95 #define FS_10K 8000 //!< 10 ksamples/sec
96 #define FS_16K 5000 //!< 16 ksamples/sec
97 #define FS_20K 4000 //!< 20 ksamples/sec
98 #define FS_24K 3333 //!< 24.0024 ksamples/sec
99 #define FS_25K 3200 //!< 25 ksamples/sec
100 #define FS_32K 2500 //!< 32 ksamples/sec
101 #define FS_40K 2000 //!< 40 ksamples/sec
102 #define FS_48K 1667 //!< 47.9904 ksamples/sec
103 #define FS_50K 1600 //!< 50 ksamples/sec
104 #define FS_64K 1250 //!< 64 ksamples/sec
105 #define FS_80K 1000 //!< 80 ksamples/sec
106 #define FS_96K 833 //!< 96.0384 ksamples/sec
107 #define FS_100K 800 //!< 100 ksamples/sec
108 #define FS_125K 640 //!< 125 ksamples/sec
109 #define FS_128K 625 //!< 128 ksamples/sec
110 #define FS_160K 500 //!< 160 ksamples/sec
111 #define FS_200K 400 //!< 200 ksamples/sec
112 #define FS_250K 320 //!< 250 ksamples/sec
113 #define FS_320K 250 //!< 320 ksamples/sec
114 #define FS_400K 200 //!< 400 ksamples/sec
115 #define FS_500K 160 //!< 500 ksamples/sec
116 #define FS_625K 128 //!< 625 ksamples/sec
117 #define FS_640K 125 //!< 640 ksamples/sec
118 #define FS_800K 100 //!< 800 ksamples/sec
119 #define FS_1000K 80 //!< 1000 ksamples/sec
120 
121 /*! @} End of FS_Count_Values group */
122 
123 /*!
124  *
125  * @defgroup digital_io_macros Macros for the board-specific digital i/o line
126  * @{
127  *
128  * Each development board has one dedicated configured digital i/o pin.
129  * These macros control the state of that output pin.
130  * (Pin PD0) for STM32L476G-Discovery)
131  */
132 #define DIGITAL_IO_SET() HAL_GPIO_WritePin(DIGITAL_IO_PORT, DIGITAL_IO_PIN, GPIO_PIN_SET)
133 #define DIGITAL_IO_RESET() HAL_GPIO_WritePin(DIGITAL_IO_PORT, DIGITAL_IO_PIN, GPIO_PIN_RESET)
134 #define DIGITAL_IO_TOGGLE() HAL_GPIO_TogglePin(DIGITAL_IO_PORT, DIGITAL_IO_PIN)
135 /*! @} End of digital_io_macros */
136 
137 /*
138  * structs, typedefs, enums .............................................................
139  */
140 
141 /*!
142  * @brief Number of input audio channels
143  */
145  MONO_IN, //!< Mono Input: Only configure ADC1, single DMA Transfer
146  STEREO_IN //!< Stereo Input: Configure ADC1 and ADC2, dual DMA Transfer
147 };
148 
149 
150 /*!
151  * @brief Number of output audio channels
152  */
154  MONO_OUT, //!< Mono Output: Only configure DAC1, single DMA Transfer
155  STEREO_OUT //!< Stereo Output: Configure DAC1 and DAC2, dual DMA Transfer
156 };
157 
158 /*!
159  * @brief Clock Reference Source
160  *
161  * By default, the STM32L476G-Discovery board uses the MSI internal RC Oscillator as
162  * its clock source. Specify MSI_INTERNAL_RC for an unmodified board (SB18 Opened,
163  * SB21 and SB22 closed).
164  *
165  * By modifying jumpers on the board, an external clock reference driving the
166  * high speed external (HSE) OSC_IN pin can be used. The external clock can be
167  * provided by the ST-LINK MCU, or driven externally through the PH0 pin on the
168  * P2 header (pin 9). Specify HSE_EXTERNAL_8MHz to use this improved clock
169  * source if your board has been modified.
170  *
171  * - 8 MHz XTAL Ref from ST-LINK MCU: SB18 closed, SB22 opened, R89 not fitted.
172  *
173  * - External 8MHz signal on PH0 on P2 header: SB18 opened, SB22 closed, R89 not fitted.
174  *
175  */
177  MSI_INTERNAL_RC, //!< Internal MSI RC Oscillator
178  HSE_EXTERNAL_8MHz //!< External 8MHz reference
179 };
180 
181 
182 
183 /*
184  * Global variables.....................................................................
185  */
188 
189 /*
190  * Function Prototypes.....................................................................
191  */
192 
193 /*!
194  * @defgroup Functions Configuration Functions
195  * @{
196  */
197 
198 
199 /*!
200  * @brief Wrapper function to perform all processor initialization for ECE 486
201  *
202  * initialize() is provided for backward compatibility: It assumes that the
203  * internal (MSI) RC oscillator is to be used as the clock reference signal. To
204  * specify use of an external crystal reference, use @code initialize_ece486() @endcode
205  *
206  * This wrapper function is called by users at the start of ECE 486 routines to
207  * perform initialization of I/O pins, ADCs, DACs, Timers, DMAs, and Interrupts.
208  *
209  * Input parameters determine the ADC/DAC sample rate, and the number of input
210  * and output analog channels. Sample rates are determined by specifying a
211  * @a timer_count_value, which determines the ultimate sample frequency.
212  * Various \#define constants are provided to obtain common sample rates:
213  * @ref FS_Count_Values.
214  *
215  * For example:
216  * @code
217  * initialize( FS_50K, MONO_IN, STEREO_OUT );
218  * @endcode
219  * is used to configure the STM32-Discovery board for sampling at a 50 ksamples/second
220  * input and output rate, with one analog input channel, and two analog output channels.
221  *
222  * It is not possible to have different ADC and DAC sample rates using this routine.
223  *
224  * A call to initialize() also pauses program execution until the "USER" button is pressed,
225  * (Joystic "center" on the STM32L476G-Discovery board.)
226  * This pause allows the board to be re-programmed without interference from DMA activity.
227  *
228  */
229 void initialize(
230  uint16_t timer_count_value, //!< [in] Number of timer counts required per analog sample processed.
231  enum Num_Channels_In chanin, //!< [in] Number of input channels: MONO_IN or STEREO_IN
232  enum Num_Channels_Out chanout //!< [in] Number of output channels: MONO_OUT or STEREO_OUT
233 );
234 
235 /*!
236  * @brief Wrapper function to perform all processor initialization for ECE 486
237  *
238  * This wrapper function is called by users at the start of ECE 486 routines to
239  * perform initialization of I/O pins, ADCs, DACs, Timers, DMAs, and Interrupts.
240  *
241  * Input parameters determine the ADC/DAC sample rate, and the number of input
242  * and output analog channels, and the source of the clock reference signal.
243  * Sample rates are determined by specifying a
244  * @a timer_count_value, which determines the ultimate sample frequency.
245  * Various \#define constants are provided to obtain common sample rates:
246  * @ref FS_Count_Values.
247  *
248  * For example:
249  * @code
250  * initialize_ece486( FS_50K, MONO_IN, STEREO_OUT, MSI_INTERNAL_RC );
251  * @endcode
252  * is used to configure the STM32-Discovery board for sampling at a 50 ksamples/second
253  * input and output rate, with one analog input channel, and two analog output channels.
254  * The internal RC MSI oscillator is used to provide the clock generation reference.
255  *
256  * It is not possible to have different ADC and DAC sample rates using this routine.
257  *
258  * A call to initialize_ece486() also pauses program execution until the "USER" button is pressed,
259  * (Joystic "center" on the STM32L476G-Discovery board.)
260  * This pause allows the board to be re-programmed without interference from DMA activity.
261  *
262  */
263 void initialize_ece486(
264  uint16_t timer_count_value, //!< [in] Number of timer counts required per analog sample processed.
265  enum Num_Channels_In chanin, //!< [in] Number of input channels: MONO_IN or STEREO_IN
266  enum Num_Channels_Out chanout, //!< [in] Number of output channels: MONO_OUT or STEREO_OUT
267  enum Clock_Reference clkref //!< [in] Clock ref source: MSI_INTERNAL_RC or HSE_EXTERNAL_8MHz
268 );
269 
270 /*!
271  * @brief Simple function to return the best guess at the actual sampling frequency.
272  *
273  * @returns Estimated sampling frequency in samples/second
274  */
275 float getsamplingfrequency(void);
276 
277 
278 /*! @} End of Functions group */
279 
280 #endif
281 
282 /*!
283  * @} End of ECE486_Init group
284  */
Stereo Output: Configure DAC1 and DAC2, dual DMA Transfer.
Definition: init486.h:155
Mono Input: Only configure ADC1, single DMA Transfer.
Definition: init486.h:145
Internal MSI RC Oscillator.
Definition: init486.h:177
Num_Channels_In
Number of input audio channels.
Definition: init486.h:144
Clock_Reference
Clock Reference Source.
Definition: init486.h:176
float getsamplingfrequency(void)
Simple function to return the best guess at the actual sampling frequency.
Definition: init486.c:441
enum Num_Channels_Out Output_Configuration
Definition: init486.c:87
void initialize(uint16_t timer_count_value, enum Num_Channels_In chanin, enum Num_Channels_Out chanout)
Wrapper function to perform all processor initialization for ECE 486.
Definition: init486.c:95
void initialize_ece486(uint16_t timer_count_value, enum Num_Channels_In chanin, enum Num_Channels_Out chanout, enum Clock_Reference clkref)
Wrapper function to perform all processor initialization for ECE 486.
Definition: init486.c:105
enum Num_Channels_In Input_Configuration
Definition: init486.c:88
External 8MHz reference.
Definition: init486.h:178
Mono Output: Only configure DAC1, single DMA Transfer.
Definition: init486.h:154
Num_Channels_Out
Number of output audio channels.
Definition: init486.h:153
Stereo Input: Configure ADC1 and ADC2, dual DMA Transfer.
Definition: init486.h:146