ASCII Serial Com
Serial communication library between computers, microcontrollers, FPGAs, etc. Uses only ASCII. Not the most efficient protocol, but meant to be easy to read
Loading...
Searching...
No Matches
stm32f091nucleo64_pulser.c
Go to the documentation of this file.
1/** \file
2 *
3 * \brief Outputs a pulser and (one day will) measures pulses
4 *
5 * Outputs configurable pulses on the LED pin, PA5, which is "D13" on the
6 * Arduino connector
7 *
8 * Reads input pulses on PA8, which is "D7" on the Arduino connector
9 *
10 * Register map is documented at \ref register_map
11 *
12 */
13
14#include <libopencm3/cm3/cortex.h>
15#include <libopencm3/cm3/nvic.h>
16#include <libopencm3/stm32/adc.h>
17#include <libopencm3/stm32/dac.h>
18#include <libopencm3/stm32/gpio.h>
19#include <libopencm3/stm32/rcc.h>
20#include <libopencm3/stm32/timer.h>
21#include <libopencm3/stm32/usart.h>
22
23#include "arm/stm_timers.h"
24#include "arm/stm_usart.h"
25#include "asc_exception.h"
26#include "asc_helpers.h"
27#include "ascii_serial_com.h"
30#include "circular_buffer.h"
31#include "millisec_timer.h"
32
33// USART2 should be connected through USB
34#define ASC_USART_NO 2
35#define ASC_USART USART2
36
37#define PORT_LED GPIOA
38#define PIN_LED GPIO5
39#define RCC_GPIO_LED RCC_GPIOA
40#define TIM_LED TIM2
41#define TIM_OC_LED TIM_OC1
42#define RCC_TIM_LED RCC_TIM2
43#define AF_TIM_LED GPIO_AF2
44
45// pulser stuff
46#define pulser_tick_freq 1000 // should do 1 tick per ms
47#define pulser_period 1000
48#define pulser_width 500
49
50// Input compare stuff on PA8 AF2, TIM1 input 1 (Arduino connector pin D7)
51#define IC_PORT GPIOA
52#define IC_PIN GPIO8
53#define IC_RCC_GPIO RCC_GPIOA
54#define IC_TIM TIM1
55#define IC_RCC_TIM RCC_TIM1
56#define IC_TI TIM_IC_IN_TI1
57#define IC_AF GPIO_AF2
58uint32_t ic_pulse_length;
59uint32_t ic_period;
60uint32_t ic_overrun;
61
62/////////////////////////////////
63
64CEXCEPTION_T e;
65uint16_t nExceptions;
66
68
69/////////////////////////////////
70
71uint32_t optionFlags = 0;
72
73#define nRegs 10
74
75/** \brief Register Map
76 *
77 * ## Register Map
78 *
79 * |Register Number | Description | r/w |
80 * | -------------- |------------ | --- |
81 * | 0 | PORTA input data register, bit 5 is LED | r |
82 * | 1 | PORTA output data register, bit 5 is LED | r, bit 5 is w |
83 * | 2 | optionFlags: see below | r/w |
84 * | 3 | Current millisecond_timer value | r |
85 * | 4 | LED pulser prescaler | r/w 16 bits |
86 * | 5 | LED pulser period | r/w 16 bits |
87 * | 6 | LED pulser pulse length | r/w 16 bits |
88 * | 7 | Input capture pulse period | r |
89 * | 8 | Input capture pulse width | r |
90 * | 9 | Input capture overrun flags (bit 0 for period and 4 for width) | r |
91 *
92 * @see register_write_masks
93 *
94 */
95volatile REGTYPE *register_map[nRegs] = {
96 &GPIOA_IDR, // input data reg
97 &GPIOA_ODR, // output data reg
98 &optionFlags, // option flags
99 &MILLISEC_TIMER_NOW, // millisec timer value
100 &TIM_PSC(TIM_LED), // LED pulser prescaler
101 &TIM_ARR(TIM_LED), // LED pulser period
102 &TIM_CCR1(TIM_LED), // LED pulser pulse length
103 &ic_period, // Input capture pulse period
104 &ic_pulse_length, // Input capture pulse length
105 &ic_overrun, // Input capture overrun flags
106};
107
108/** \brief Write masks for \ref register_map
109 *
110 * These define whether the given register in register_map is writable or not
111 *
112 */
113REGTYPE register_write_masks[nRegs] = {
114 0, // input data reg
115 1 << 5, // output data reg
116 0xFFFFFFFF, // option flags
117 0, // MILLISEC_TIMER_NOW
118 0xFFFF, // LED pulser prescaler
119 0xFFFF, // LED pulser period
120 0xFFFF, // LEd pulser pulse length
121 0, // Input capture pulse period
122 0, // Input capture pulse length
123 0, // Input capture overrun flags
124};
125
127
128///////////////////////////////////
129
130uint8_t tmp_byte = 0;
131int main(void) {
132
133 Try {
135 nRegs);
136
137 millisec_timer_systick_setup(rcc_ahb_frequency);
138
139 // USART2 TX: PA2 AF1
140 // USART2 RX: PA3 AF1
141 rcc_periph_clock_enable(RCC_GPIOA);
142 rcc_periph_clock_enable(RCC_USART2);
143 setup_usart(ASC_USART, 9600, GPIOA, GPIO2, GPIO_AF1, GPIOA, GPIO3,
144 GPIO_AF1);
145 nvic_enable_irq(NVIC_USART2_IRQ);
146 usart_enable_rx_interrupt(ASC_USART);
147 usart_enable(ASC_USART);
148
149 rcc_periph_clock_enable(RCC_GPIO_LED);
150 rcc_periph_clock_enable(RCC_TIM_LED);
152 TIM_LED, rcc_get_timer_clk_freq(TIM_LED) / pulser_tick_freq,
153 pulser_period, pulser_width, TIM_OC_LED, PORT_LED, PIN_LED, AF_TIM_LED);
154 timer_enable_counter(TIM_LED);
155
156 rcc_periph_clock_enable(IC_RCC_GPIO);
157 rcc_periph_clock_enable(IC_RCC_TIM);
159 IC_TIM, rcc_get_timer_clk_freq(IC_TIM) / pulser_tick_freq, 0xFFFF,
160 IC_TI, IC_PORT, IC_PIN, IC_AF);
161 timer_enable_counter(IC_TIM);
162 }
163 Catch(e) { return e; }
164
165 while (1) {
166 Try {
168
169 if (timer_get_flag(IC_TIM, TIM_SR_CC1IF)) {
170 ic_pulse_length = TIM_CCR2(IC_TIM);
171 ic_period = TIM_CCR1(IC_TIM);
172 ic_overrun = 0;
173 if (timer_get_flag(IC_TIM, TIM_SR_CC1OF)) {
174 ic_overrun |= 1;
175 timer_clear_flag(IC_TIM, TIM_SR_CC1OF);
176 }
177 if (timer_get_flag(IC_TIM, TIM_SR_CC2OF)) {
178 ic_overrun |= 1 << 4;
179 timer_clear_flag(IC_TIM, TIM_SR_CC2OF);
180 }
181 }
182 }
183 Catch(e) { nExceptions++; }
184 }
185
186 return 0;
187}
188
189def_usart_isr_push_rx_to_circ_buf(usart2_isr, ASC_USART, &extraInputBuffer)
#define HANDLE_ASC_COMM_IN_POLLING_LOOP(uart_no)
Polling for ascii_serial_com_device and ascii_serial_com_register_pointers.
#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.
ASCII Serial Com Device.
ASCII Serial Com Register Pointers.
void millisec_timer_systick_setup(uint32_t ahb_frequency)
Setup the systick timer.
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 timer peripherals on STM32 microcontrollers.
#define setup_timer_capture_pwm_input(timer, prescale, max_timer_counts, input, gpio_port, gpio_pin, gpio_af)
Initialize a timer to capture periodic pulses on an input pin.
Definition stm_timers.h:156
#define setup_timer_periodic_output_pulse(timer, prescale, period, pulse_length, output, gpio_port, gpio_pin, gpio_af)
Initialize a timer to output a periodic pulse on an output pin.
Definition stm_timers.h:66
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.
Definition stm_usart.h:52
#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.
Definition stm_usart.h:95