ECE 486 Support Libraries
ece486.h
Go to the documentation of this file.
1 /*!
2  @file
3  @brief STM32L476G-Discovery ECE 486 Interface
4  @author Don Hummels
5  @date Jan, 2016
6 
7  @mainpage STM32L476G-Discovery support library for ECE 486 Digital Signal Processing
8 
9  This library defines an interface that allows a user use the
10  STM32L476G-Discovery development boards
11  to stream input sampled data
12  in real time from one or two ADCs, process the data,
13  and stream the resulting output samples to one or two output DACs.
14 
15  The user interface is as follows:
16 
17  -# Required include: @code #include "ece486.h" @endcode
18  -# Optionally, the user calls @code
19  setblocksize(nsamp);
20  @endcode
21  This call is used to change the data block size that will be delivered
22  to the user in later function calls. (If setblocksize() is not called,
23  a default value of #DEFAULT_BLOCKSIZE is used.) Using a larger block
24  size may result in more efficient code, while using a smaller block
25  size will reduce the latency of the system.
26  -# The user calls @code
27  initialize_ece486(fs, input_mode, output_mode, clk_ref);
28  @endcode
29  where:
30  - @a fs determines the sampling frequency. Predefined integer
31  constants for @a fs are provided at @ref FS_Count_Values.
32  - @a input_mode should be #MONO_IN or #STEREO_IN
33  - @a output_mode should be #MONO_OUT or #STEREO_OUT
34  - @a clk_ref should be #MSI_INTERNAL_RC or #HSE_EXTERNAL_8MHz
35 
36  The same sample rate is used for the input ADC
37  and output DAC data streams.
38  The initialize_ece486() call enables clocks and configures the
39  appropriate ADC(s), DAC(s), Timers, buttons, DMAs, UART, and
40  interrupts. The function pauses at the beginning of the
41  initialization (with red and green LEDs flashing) to wait
42  for a user push-button (center joystick)
43  indicating to continue (allowing the
44  device to be re-programmed without errors).
45 
46  For @a input_mode = #MONO_IN or #STEREO_IN,
47  Analog input waveforms are sampled using ADC1 (MONO) or
48  ADC1 | ADC2 (STEREO_IN). For the STM32L476G-Discovery board,
49  ADC1 is accessed as an input on
50  PA1, and ADC2 is accessed on PA2.
51 
52  Analog output is generated using DAC Channel 2 (MONO_OUT) or DAC Channels 1 and 2
53  (STEREO_OUT). DAC CHannel 2 is accessed as an output on PA5 (MONO_OUT or
54  STEREO_OUT). DAC Channel 1 actually drives an internal op-amp buffer (OPAMP1), with output
55  to the discovery board connector on PA3 (STEREO_OUT only).
56 
57  The green and red LEDs are configured and enabled. The LEDs are used
58  to provide feedback during program execution. The red LED us used to
59  indicate an error condition.
60  -# The user calls @code
61  nsamp = getblocksize();
62  @endcode
63  @a nsamp gives the data block size which will be delivered to
64  the user in later function calls. Input samples (provided by
65  the ADC(s) via the DMA)
66  will be accessed in blocks of @a nsamp samples at a time.
67  Likewise, the user programs should generate "nsamp" output
68  samples for delivery to the DAC. Typically, users call
69  getblocksize() to learn the required number of samples so
70  that the correct amount of memory for processing the blocks
71  of data may be allocated.
72  -# Optionally, the user calls @code
73  fs = getsamplingfrequency();
74  @endcode
75  This function returns the best guess (perfect accuracy of the MSI time reference)
76  at the actual sampling rate (in
77  samples/second). The actual sample rate may be slightly different from
78  the requested rate or reported rate: The internal MSI oscilator is a factory
79  calibrated RC time reference, and errors of a percent or so would not be
80  unexpected.
81  -# Users then repeatedly call getblock() or getblockstereo() to obtain
82  samples from the ADC(s), and (after processing the samples)
83  putblock() or putblockstereo() to write the results back
84  to the DAC. Using one of:
85  @code
86  getblock(input1); // mono input
87  getblockstereo(input1, input2); // stereo input
88  @endcode
89  will fill in the user's input array(s) (type float) with
90  normalized input (ADC) samples. Callers are responsible to make sure
91  that the arrays @a input1 and @a input2 are allocated with enough
92  memory to hold @a nsamp float values. After processing the
93  input waveforms to create results, the output samples are
94  placed in the DAC output buffers using one of
95  @code
96  putblock(result1); // Mono Output
97  putblockstereo(result1, result2); // Stereo Output
98  @endcode
99  Typically, after calling the putblock() routine, the user
100  calls getblock() to wait for the next available block of
101  input data, and the process repeats. If the DMA
102  completes filling a new block of data before the user calls
103  getblock(), a #SAMPLE_OVERRUN error is indicated, and
104  the RED LED is lit. In this case, the data is not being
105  processed fast enough to keep up with the input data stream,
106  and input samples are being lost.
107 
108  Sample values in the "input" or "result" arrays are of
109  type float, and are normalized to range from -1.0 to +1.0
110  over the voltage range of the ADCs | DACs. (A sample of -1.0 is near 0V,
111  +1.0 is near 3V, and 0.0 indicates the mid-scale voltage of 1.5V)
112 
113  By default, Pin PD0 on the STM32L476-Discovery board is configured
114  as a digital output pin. The pin status may be set using the macros
115  @code
116  DIGITAL_IO_SET(); // Set high
117  DIGITAL_IO_RESET(); // Set low
118  DIGITAL_IO_TOGGLE(); // Toggle state
119  @endcode
120 
121  Other digital output can be configured using the standard HAL libraries
122  The following
123  configures PB6 (Port B, Pin 6) as a digital, push-pull output pin:
124  @code
125  GPIO_InitTypeDef my_io_pin;
126 
127  __GPIOB_CLK_ENABLE(); // Clock on for Port A
128  my_io_pin.Mode = GPIO_MODE_OUTPUT_PP; // Push/Pull digital output
129  my_io_pin.Pull = GPIO_NOPULL; // No pullup or pulldown resistor
130  my_io_pin.Speed = GPIO_SPEED_HIGH; // LOW, MEDIUM, FAST, or HIGH
131  my_io_pin.Pin = GPIO_PIN_6; // Set up PA1
132  HAL_GPIO_Init(GPIOB, |my_io_pin);
133  @endcode
134  Once the pin is initialized, you can set the output state:
135  @code
136  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
137  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
138  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
139  @endcode
140 
141  The LEDs on the discovery boards are accessed using the BSP_LED_xxx()
142  functions. By default, the green LED (LED5) and red LED (LED4)
143  are initialized. While both LEDs are available to the user, the red LED
144  is used by the library to visually indicate error conditions. To
145  drive green LED:
146  @code
147  BSP_LED_On(LED5); // Turn on the LED
148  BSP_LED_Off(LED5); // Turn off the LED
149  BSP_LED_Toggle(LED5); // Toggle the LED
150  @endcode
151 
152  Users can check the global variable #KeyPressed to
153  check whether the (blue) user button on the Discovery board
154  has been pressed. #KeyPressed==SET indicates that
155  a button press has occurred.
156  The user should reset the value using #KeyPressed=RESET;
157 
158  A UART is also configured to direct printf() output to the ST-LINK USB serial
159  port. Assuming that the host is connected to the ST-LINK connector, printf output
160  may be examined on the host by connecting a terminal to the serial port. The terminal
161  should be configured at 115200 bps, 8 bits, no parity, one stop-bit. printf() calls are
162  blocking.
163 
164  The discovery board LCD display may be accessed through the board-specific libraries
165  provided with the discovery board. For example:
166  @code
167  BSP_LCD_GLASS_DisplayString((uint8_t *) "HELLO"); // Short message
168 
169  // Scroll a message 5 times...
170  BSP_LCD_GLASS_ScrollSentence((uint8_t*) "LOTS TO SAY HERE", 5, SCROLL_SPEED_HIGH);
171  @endcode
172 
173 */
174 
175 /*!
176  @page Peripherals Overview of STM32L476 Peripheral/Pin Configuration
177 
178  For the STM32L476-Discovery board, the following peripheral assignments are used:
179 
180 |Pin | Peripheral | Use
181 |------ | ------------- | -------------------------------------------------
182 |PA5 | DAC Channel 2 | Primary (Mono or Stereo) output channel
183 | | DAC Channel 1 | Stereo output channel
184 | | DMA2 Channel 5| Used to move samples from a buffer to the DAC(s).
185 |PA3 | OPAMP1 | Used to buffer DAC Channel 1 to drive an output pin.
186 | | TIMER 4 | Used to trigger ADC1 and DACs.
187 |PA3 | ADC1 | Primary (Mono or Stereo) input channel.
188 |PA2 | ADC2 | Stereo input channel.
189 | | DMA1 Channel 1| Used to move samples from the ADC(s) to a buffer.
190 | | USART2 | Serial Communication to a host terminal
191 
192  - DMA2 Channel 5 is triggered by DAC2 using request 3
193  - DMA1 Channel 1 is triggered by ADC1 using request 0
194  - ADC2 is a slave to ADC1 in dual sampling mode (Stereo input case)
195 
196  DMA1 Channel 1 data is moved into an internal buffer of size #ADC_Buffer_Size.
197  Interrupts from DMA1 CHannel 1 are generated when the buffer is
198  half-full and full, indicating that the user may process one-half
199  of the samples, while the other half is being filled.
200  getblocksize() returns a value of #ADC_Block_Size, which is actually half
201  of the size of the actual DMA buffer (indicating the amount of data free to be processed in each sample block).
202 
203  ADC inputs and DAC output are accessed via the P1 connector on the
204  STM32L476G-Discovery board. Pin assignments are as follows:
205 
206 | P1 Pin | P1 Label | ECE 486 Function
207 |---------------|----------|----------------------------------------------
208 | 1 | 3V3 | Power (3.3~V)
209 | 2 | GND | Ground
210 | 3 | 2V5 | Power (2.5~V)
211 | 4 | GND | Ground
212 | 5 | 3V | Power (3~V)
213 | 6 | BOOT0 | -
214 | 7 | PB3 | 3V3_REG_ON: Tied to 3.3V Regulator via 4.7kohm
215 | 8 | PB2 | Red LED
216 | 9 | PE8 | Green LED
217 | 10 | PA0 | GPIO Input: Connected to Joystic ``center"
218 | 11 | PA5 | Primary DAC Output(MONO and STEREO)
219 | 12 | PA1 | Primary ADC Input (MONO and STEREO)
220 | 13 | PA2 | Second ADC Input (STEREO only)
221 | 14 | PA3 | Second DAC Output via Opamp (STEREO only)
222 | 15 | PB6 | I2C1_SCL
223 | 16 | PB7 | I2C1_SDA
224 | 17 | PD0 | EXT_RST: Configured as GPIO Digital Output
225 | 18 | NC | -
226 | 19 | GND | Ground
227 | 20 | GND | Ground
228 
229 */
230 
231 #ifndef __ECE486__
232 #define __ECE486__
233 
234 #include "init486.h"
235 #include "stm32l476g_discovery_glass_lcd.h"
236 
237 #include "err486.h"
238 #include "sample486.h"
239 
240 #endif
ECE 486 Interface fuctions to manipulate blocks of sampled data.
Error Handling for ECE 486 STM32L476G-Discovery Interface.
STM32L476-Discovery configuration routines to support ECE 486.