/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* Copyright (c) 2016 King Kévin */ /* standard libraries */ #include // standard integer types #include // standard I/O facilities #include // standard utilities #include // standard streams #include // error number utilities /* STM32 (including CM3) libraries */ #include // real-time control clock library #include // general purpose input output library #include // vector table definition #include // Cortex M3 utilities #include // interrupt utilities #include // external interrupt utilities /* own libraries */ #include "global.h" // board definitions #include "usart.h" // USART utilities #include "usb_cdcacm.h" // USB CDC ACM utilities /* flag set in interrupts to be processed in main taks */ volatile bool button_flag = false; // button has been presse /* default output (i.e. for printf) */ int _write(int file, char *ptr, int len) { int i; if (file == STDOUT_FILENO || file == STDERR_FILENO) { for (i = 0; i < len; i++) { if (ptr[i] == '\n') { // add carrier return before line feed. this is recommended for most UART terminals usart_putchar_nonblocking('\r'); // a second line feed doesn't break the display cdcacm_putchar('\r'); // a second line feed doesn't break the display } usart_putchar_nonblocking(ptr[i]); // send byte over USART cdcacm_putchar(ptr[i]); // send byte over USB } return i; } errno = EIO; return -1; } /* switch on LED */ void led_on(void) { #ifdef SYSTEM_BOARD gpio_clear(LED_PORT, LED_PIN); #elif MAPLE_MINI gpio_set(LED_PORT, LED_PIN); #endif } /* switch off LED */ void led_off(void) { #ifdef SYSTEM_BOARD gpio_set(LED_PORT, LED_PIN); #elif MAPLE_MINI gpio_clear(LED_PORT, LED_PIN); #endif } /* toggle LED */ void led_toggle(void) { gpio_toggle(LED_PORT, LED_PIN); } int main(void) { SCB_VTOR = (uint32_t) 0x08002000; // relocate vector table because of the bootloader rcc_clock_setup_in_hse_8mhz_out_72mhz(); // use 8 MHz high speed external clock to generate 72 MHz internal clock usart_setup(); // setup USART (for printing) cdcacm_setup(); // setup USB CDC ACM (for printing) setbuf(stdout, NULL); // set standard out buffer to NULL to immediately print setbuf(stderr, NULL); // set standard error buffer to NULL to immediately print // setup LED rcc_periph_clock_enable(LED_RCC); // enable clock for LED gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, LED_PIN); // set LED pin to 'output push-pull' led_off(); // switch off LED to indicate setup started // setup button #if defined(BUTTON_RCC) && defined(BUTTON_PORT) && defined(BUTTON_PIN) && defined(BUTTON_EXTI) && defined(BUTTON_IRQ) rcc_periph_clock_enable(BUTTON_RCC); // enable clock for button gpio_set_mode(BUTTON_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, BUTTON_PIN); // set button pin to input rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt exti_select_source(BUTTON_EXTI, BUTTON_PORT); // mask external interrupt of this pin only for this port exti_set_trigger(BUTTON_EXTI, EXTI_TRIGGER_BOTH); // trigger on both edge exti_enable_request(BUTTON_EXTI); // enable external interrupt nvic_enable_irq(BUTTON_IRQ); // enable interrupt #endif printf("welcome to the STM32F1 CuVoodoo example code\n"); // print welcome message led_on(); // switch on LED to indicate setup completed bool action = false; // if an action has been performed don't go to sleep button_flag = false; // reset button flag /* toggle the LED with every transmitted character */ while (true) { // infinite loop while (usart_received) { // echo every received character action = true; // action has been performed led_toggle(); // toggle LED printf("%c",usart_getchar()); // transmit receive character } while (cdcacm_received) { // echo every received character action = true; // action has been performed led_toggle(); // toggle LED printf("%c",cdcacm_getchar()); // transmit receive character } while (button_flag) { button_flag = false; // reset flag action = true; // action has been performed led_toggle(); // toggle LED } // go to sleep if nothing had to be done, else recheck for activity if (action) { action = false; } else { __WFI(); // go to sleep } } return 0; } #if defined(BUTTON_ISR) && defined(BUTTON_EXTI) void BUTTON_ISR(void) { exti_reset_request(BUTTON_EXTI); // reset interrupt button_flag = true; // perform button action } #endif