20#include <libopencm3/cm3/cortex.h>
21#include <libopencm3/cm3/nvic.h>
22#include <libopencm3/stm32/adc.h>
23#include <libopencm3/stm32/dac.h>
24#include <libopencm3/stm32/gpio.h>
25#include <libopencm3/stm32/rcc.h>
26#include <libopencm3/stm32/timer.h>
27#include <libopencm3/stm32/usart.h>
40#define ASC_USART USART2
44#define RCC_GPIO_LED RCC_GPIOA
53uint32_t adc_sample_period_ms = 1000;
54uint32_t adc_n_overruns = 0;
56#define DAC_RESET_TIME_MS 500
60uint32_t optionFlags = 0;
128 &adc_sample_period_ms,
159static
void gpio_setup(
void) {
160 rcc_periph_clock_enable(RCC_GPIO_LED);
162 gpio_mode_setup(PORT_LED, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED);
165static void adc_setup(
void) {
171 rcc_periph_clock_enable(RCC_ADC);
172 rcc_periph_clock_enable(RCC_GPIOA);
175 gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0);
177 uint8_t adc_channel_sequence[nChans] = {0};
180 adc_set_clk_source(ADC, ADC_CLKSOURCE_ADC);
182 adc_set_operation_mode(
185 adc_disable_external_trigger_regular(ADC);
186 adc_set_right_aligned(ADC);
187 adc_enable_temperature_sensor();
188 adc_set_sample_time_on_all_channels(ADC, ADC_SMPTIME_071DOT5);
189 adc_set_regular_sequence(ADC, nChans, adc_channel_sequence);
190 adc_set_resolution(ADC, ADC_RESOLUTION_12BIT);
191 adc_disable_analog_watchdog(ADC);
195static void dac_setup(
void) {
197 rcc_periph_clock_enable(RCC_TIM6);
198 TIM_PSC(TIM6) = rcc_ahb_frequency / 100 - 1;
200 TIM_CR2(TIM6) |= TIM_CR2_MMS_UPDATE;
201 TIM_CR1(TIM6) |= TIM_CR1_ARPE;
203 TIM_CR1(TIM6) |= TIM_CR1_CEN;
206 rcc_periph_clock_enable(RCC_DAC);
207 rcc_periph_clock_enable(RCC_GPIOA);
212 gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4);
214 dac_disable(DAC1, DAC_CHANNEL1);
215 dac_buffer_enable(DAC1, DAC_CHANNEL1);
216 dac_disable_waveform_generation(DAC1, DAC_CHANNEL1);
217 dac_set_trigger_source(DAC1, DAC_CR_TSEL1_T6);
218 dac_trigger_enable(DAC1, DAC_CHANNEL1);
219 dac_enable(DAC1, DAC_CHANNEL1);
236 rcc_periph_clock_enable(RCC_GPIOA);
237 rcc_periph_clock_enable(RCC_USART2);
238 setup_usart(ASC_USART, 9600, GPIOA, GPIO2, GPIO_AF1, GPIOA, GPIO3,
240 nvic_enable_irq(NVIC_USART2_IRQ);
241 usart_enable_rx_interrupt(ASC_USART);
242 usart_enable(ASC_USART);
244 Catch(e) {
return e; }
248 const bool stream_state_before_receiving = streaming_is_on;
251 if (streaming_is_on && !stream_state_before_receiving) {
253 adc_sample_period_ms);
256 if ((optionFlags >> 1) &
258 dac_disable(DAC1, DAC_CHANNEL1);
259 optionFlags &= ~(1 << 1);
264 dac_enable(DAC1, DAC_CHANNEL1);
267 if (streaming_is_on && !(optionFlags & 1) &&
269 adc_start_conversion_regular(ADC);
273 if (optionFlags & 1) {
274 char counter_buffer[8];
280 if (adc_get_overrun_flag(ADC)) {
282 adc_clear_overrun_flag(ADC);
284 static uint16_t adc_val;
285 static char adc_val_buffer[4];
286 adc_val = adc_read_regular(ADC);
287 ADC_ISR(ADC) |= (1 << ADC_ISR_EOSEQ) | (1 << ADC_ISR_EOC);
295 Catch(e) { nExceptions++; }
#define HANDLE_ASC_COMM_IN_POLLING_LOOP(uart_no)
Polling for ascii_serial_com_device and ascii_serial_com_register_pointers.
#define STREAM_TO_HOST_ASC_DEVICE_W_REGISTER_POINTERS(data, data_size)
Stream data to the host.
#define READY_TO_STREAM_ASC_DEVICE_W_REGISTER_POINTERS
Check if you should stream a message to the host.
#define DECLARE_ASC_DEVICE_W_REGISTER_POINTERS()
Declarations for ascii_serial_com_device and ascii_serial_com_register_pointers.
#define SETUP_ASC_DEVICE_W_REGISTER_POINTERS(register_map, register_write_masks, nRegs)
Setup for ascii_serial_com_device and ascii_serial_com_register_pointers.
void convert_uint16_to_hex(uint16_t num, char *outstr, bool caps)
convert uint16 to hex string
void convert_uint32_to_hex(uint32_t num, char *outstr, bool caps)
convert uint32 to hex string
ASCII Serial Com Register Pointers.
void millisec_timer_systick_setup(uint32_t ahb_frequency)
Setup the systick timer.
void millisec_timer_set_rel(millisec_timer *timer, const millisec_timer_unit_t now, const millisec_timer_unit_t rel)
Set timer to expire in the future.
bool millisec_timer_is_expired_repeat(millisec_timer *timer, const millisec_timer_unit_t now)
Check if timer has expired & if so, re-enable for the same interval.
bool millisec_timer_is_expired(millisec_timer *timer, const millisec_timer_unit_t now)
Check if timer has expired & if so, disable it.
Portable millisecond timer.
static uint32_t MILLISEC_TIMER_NOW
A counter that increments every millisecond.
#define MILLISEC_TIMER_SYSTICK_IT
Millisecond timer SysTick interrupt.
REGTYPE register_write_masks[nRegs]
Write masks for register_map.
volatile REGTYPE * register_map[nRegs]
Register Map.
To be used with the USART peripherals on STM32 microcontrollers.
#define setup_usart(usart, baud, tx_port, tx_pin, tx_af, rx_port, rx_pin, rx_af)
Setup a USART.
#define def_usart_isr_push_rx_to_circ_buf(isr_name, usart, circular_buffer)
Define the ISR for a USART to push rx bytes to a circular buffer.
portable millisecond timer