3 #include <libopencm3/cm3/cortex.h>
4 #include <libopencm3/cm3/nvic.h>
5 #include <libopencm3/cm3/systick.h>
6 #include <libopencm3/stm32/rcc.h>
7 #include <libopencm3/stm32/gpio.h>
8 #include <libopencm3/stm32/usart.h>
9 #include <libopencm3/stm32/timer.h>
13 static void clock_setup(void)
15 rcc_clock_setup_in_hse_8mhz_out_72mhz();
17 rcc_periph_clock_enable(RCC_GPIOA);
18 rcc_periph_clock_enable(RCC_GPIOB);
19 rcc_periph_clock_enable(RCC_GPIOC);
20 rcc_periph_clock_enable(RCC_USART1);
21 rcc_periph_clock_enable(RCC_TIM1);
22 rcc_periph_clock_enable(RCC_TIM4);
23 rcc_periph_clock_enable(RCC_AFIO);
25 rcc_periph_reset_pulse(RST_GPIOA);
26 rcc_periph_reset_pulse(RST_GPIOB);
27 rcc_periph_reset_pulse(RST_GPIOC);
28 rcc_periph_reset_pulse(RST_USART1);
29 rcc_periph_reset_pulse(RST_TIM1);
30 rcc_periph_reset_pulse(RST_TIM4);
33 static void gpio_setup(void)
35 // PC13 = BluePill LED
36 gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
37 gpio_clear(GPIOC, GPIO13);
39 // Switch JTAG off to free up pins
40 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0);
41 // gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, AFIO_MAPR_TIM2_REMAP_FULL_REMAP);
43 // TIM2_CH3 on PB3 (remapped)
44 // gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO10);
46 // TIM4_CH1 on PB6: PWM for fan control
47 gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO6);
49 // TIM4_CH2 on PB7: PWM for IR LED
50 gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO7);
53 static volatile u32 ms_ticks;
55 void sys_tick_handler(void)
60 static void tick_setup(void)
62 systick_set_frequency(1000, 72000000);
63 systick_counter_enable();
64 systick_interrupt_enable();
67 static void UNUSED delay_ms(uint ms)
69 u32 start_ticks = ms_ticks;
70 while (ms_ticks - start_ticks < ms)
74 static void usart_setup(void)
76 gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
77 gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART1_RX);
79 usart_set_baudrate(USART1, 115200);
80 usart_set_databits(USART1, 8);
81 usart_set_stopbits(USART1, USART_STOPBITS_1);
82 usart_set_mode(USART1, USART_MODE_TX_RX);
83 usart_set_parity(USART1, USART_PARITY_NONE);
84 usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
105 static const char * const rc_patterns[RC_MAX] = {
106 [RC_AUTO] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*A*B*B*A*B*A*A*B*B*A*A*B*A*B*B*A*",
107 [RC_TEMP_UP] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*A*A*B*A*B*A*A*B*B*B*A*B*A*B*B*A*",
108 [RC_FUNC] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*B*A*B*B*B*A*A*B*A*B*A*A*A*B*B*A*",
109 [RC_HI] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*B*A*A*B*B*A*A*B*A*B*B*A*A*B*B*A*",
110 [RC_TIMER] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*A*B*B*B*B*A*A*B*B*A*A*A*A*B*B*A*",
111 [RC_MID] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*B*B*A*B*B*A*A*B*A*A*B*A*A*B*B*A*",
112 [RC_TEMP_DOWN] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*B*A*B*A*B*A*A*B*A*B*A*B*A*B*B*A*",
113 [RC_SLEEP] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*B*B*B*B*B*A*A*B*A*A*A*A*A*B*B*A*",
114 [RC_LOW] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*A*B*A*B*B*A*A*B*B*A*B*A*A*B*B*A*",
115 [RC_POWER] = "^#*A*A*A*A*A*A*A*B*B*B*B*B*B*B*B*A*A*A*B*B*B*A*A*B*B*B*A*A*A*B*B*A*",
116 [RC_XXX_A] = "^#*A*B*A*A*B*A*B*B*A*A*B*A*A*A*A*A*A*B*B*B*B*A*A*A*B*A*A*A*A*B*B*B*",
117 [RC_XXX_B] = "^#*A*B*A*A*B*A*B*B*A*A*B*A*A*A*A*A*B*B*B*B*B*A*A*A*A*A*A*A*A*B*B*B*",
121 static const char rc_keys[] = "aufhtmdslp12";
123 // TIM4 will run on CPU clock, it will overflow with frequency 38 kHz (IR modulation frequency)
124 #define T4_CYCLE ((CPU_CLOCK_MHZ * 1000000 + 37999) / 38000)
126 static void rc_setup(void)
128 timer_set_prescaler(TIM4, 0);
129 timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
130 timer_disable_preload(TIM4);
131 timer_set_period(TIM4, T4_CYCLE - 1);
133 // 50% PWM for the IR LED
134 timer_set_oc_mode(TIM4, TIM_OC2, TIM_OCM_PWM1);
135 timer_set_oc_value(TIM4, TIM_OC2, T4_CYCLE / 2);
136 timer_set_oc_polarity_high(TIM4, TIM_OC2);
137 timer_enable_oc_output(TIM4, TIM_OC2);
139 // PWM for controlling fan
140 timer_set_oc_mode(TIM4, TIM_OC1, TIM_OCM_PWM1);
141 timer_set_oc_value(TIM4, TIM_OC1, T4_CYCLE / 4);
142 timer_set_oc_polarity_high(TIM4, TIM_OC1);
143 timer_enable_oc_output(TIM4, TIM_OC1);
145 timer_enable_counter(TIM4);
147 // TIM1 runs at 1 MHz and it is used for timing of RC pulses
148 timer_set_prescaler(TIM1, CPU_CLOCK_MHZ - 1);
149 timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
150 timer_update_on_overflow(TIM1);
151 timer_disable_preload(TIM1);
152 timer_one_shot_mode(TIM1);
153 timer_enable_irq(TIM1, TIM_DIER_UIE);
154 nvic_enable_irq(NVIC_TIM1_UP_IRQ);
157 static const char *rc_pattern_pos;
159 void tim1_up_isr(void)
161 if (TIM_SR(TIM1) & TIM_SR_UIF) {
162 TIM_SR(TIM1) &= ~TIM_SR_UIF;
164 if (!rc_pattern_pos) // Just to be sure
167 bool val; // 1=pulse, 0=break
168 uint duration; // in μs
170 switch (*rc_pattern_pos++) {
192 // End of transmission
193 gpio_set(GPIOC, GPIO13); // FIXME
194 rc_pattern_pos = NULL;
200 timer_set_oc_mode(TIM4, TIM_OC2, TIM_OCM_PWM1);
202 timer_set_oc_mode(TIM4, TIM_OC2, TIM_OCM_FORCE_HIGH);
204 timer_set_period(TIM1, duration - 1);
205 timer_generate_event(TIM1, TIM_EGR_UG);
206 timer_enable_counter(TIM1);
210 static void rc_send(uint key)
212 rc_pattern_pos = rc_patterns[key];
214 gpio_clear(GPIOC, GPIO13);
216 timer_set_period(TIM1, 1);
217 timer_generate_event(TIM1, TIM_EGR_UG);
218 timer_enable_counter(TIM1);
229 debug_puts("Hello world!\n");
230 gpio_set(GPIOC, GPIO13);
234 gpio_toggle(GPIOC, GPIO13);
236 timer_set_oc_mode(TIM4, TIM_OC2, TIM_OCM_FORCE_HIGH);
237 gpio_toggle(GPIOC, GPIO13);
239 timer_set_oc_mode(TIM4, TIM_OC2, TIM_OCM_PWM1);
241 if (usart_get_flag(USART1, USART_SR_RXNE)) {
242 uint ch = usart_recv(USART1);
243 const char *key = strchr(rc_keys, ch);
246 rc_send(key - rc_keys);