diff --git a/global.h b/global.h index 4024938..99cebf1 100644 --- a/global.h +++ b/global.h @@ -244,9 +244,6 @@ extern volatile bool button_flag; /**< flag set when board user button has been pressed/released */ -/** default printf output */ -int _write(int file, char *ptr, int len); - /** get binary representation of a number * @param[in] binary number to represent in binary * @param[in] rjust justify representation with leading zeros diff --git a/main.c b/main.c index 0506386..936bb8b 100644 --- a/main.c +++ b/main.c @@ -20,11 +20,8 @@ /* standard libraries */ #include // standard integer types -#include // standard I/O facilities -#include // standard utilities -#include // standard streams +#include // boolean type #include // string utilities -#include // mathematical utilities /* STM32 (including CM3) libraries */ #include // Cortex M3 utilities @@ -40,6 +37,7 @@ /* own libraries */ #include "global.h" // board definitions +#include "print.h" // printing utilities #include "usart.h" // USART utilities #include "usb_cdcacm.h" // USB CDC ACM utilities #include "led_tm1637.h" // TM1637 7-segment controller utilities @@ -53,40 +51,17 @@ volatile bool rtc_internal_tick_flag = false; /**< flag set when internal RTC ticked */ /** @} */ -int _write(int file, char *ptr, int len) -{ - int i; // how much data has been sent - static char newline = 0; // what newline has been sent - - if (file == STDOUT_FILENO || file == STDERR_FILENO) { - for (i = 0; i < len; i++) { - if (ptr[i] == '\r' || ptr[i] == '\n') { // send CR+LF newline for most carriage return and line feed combination - if (newline==0 || (newline==ptr[i])) { // newline has already been detected - usart_putchar_nonblocking('\r'); // send newline over USART - usart_putchar_nonblocking('\n'); // send newline over USART - cdcacm_putchar('\r'); // send newline over USB - cdcacm_putchar('\n'); // send newline over USB - newline = ptr[i]; // remember the newline - } - if (ptr[i] == '\n') { // line feed are always considered to end a line (the LF+CR combination is not supported to better support the others) - newline = 0; // clear new line - } - } else { // non-newline character - usart_putchar_nonblocking(ptr[i]); // send byte over USART - cdcacm_putchar(ptr[i]); // send byte over USB - newline = 0; // clear new line - } - } - return i; - } - return -1; -} - /** user input command */ static char command[32] = {0}; /** user input command index */ uint8_t command_i = 0; +void _putc(char c) +{ + usart_putchar_nonblocking(c); // send byte over USART + cdcacm_putchar(c); // send byte over USB +} + /** process user command * @param[in] str user command string (\0 ended) */ @@ -100,23 +75,23 @@ static void process_command(char* str) } // parse command if (0==strcmp(word,"help")) { - printf("available commands:\n"); - printf("led [on|off|toggle]\n"); - printf("time [HH:MM:SS]\n"); - printf("date [YYYY-MM-DD]\n"); + puts("available commands:\n"); + puts("led [on|off|toggle]\n"); + puts("time [HH:MM:SS]\n"); + puts("date [YYYY-MM-DD]\n"); } else if (0==strcmp(word,"led")) { word = strtok(NULL,delimiter); if (!word) { goto error; } else if (0==strcmp(word,"on")) { led_on(); // switch LED on - printf("LED switched on\n"); // notify user + puts("LED switched on\n"); // notify user } else if (0==strcmp(word,"off")) { led_off(); // switch LED off - printf("LED switched off\n"); // notify user + puts("LED switched off\n"); // notify user } else if (0==strcmp(word,"toggle")) { led_toggle(); // toggle LED - printf("LED toggled\n"); // notify user + puts("LED toggled\n"); // notify user } else { goto error; } @@ -128,14 +103,14 @@ static void process_command(char* str) goto error; } else { if (!rtc_ds1307_write_hours((word[0]-'0')*10+(word[1]-'0')*1)) { - printf("setting hours failed\n"); + puts("setting hours failed\n"); } else if (!rtc_ds1307_write_minutes((word[3]-'0')*10+(word[4]-'0')*1)) { - printf("setting minutes failed\n"); + puts("setting minutes failed\n"); } else if (!rtc_ds1307_write_seconds((word[6]-'0')*10+(word[7]-'0')*1)) { - printf("setting seconds failed\n"); + puts("setting seconds failed\n"); } else { rtc_ds1307_oscillator_enable(); // be sure the oscillation is enabled - printf("time set\n"); + puts("time set\n"); } } } else if (0==strcmp(word,"date")) { @@ -146,13 +121,13 @@ static void process_command(char* str) goto error; } else { if (!rtc_ds1307_write_year((word[2]-'0')*10+(word[3]-'0')*1)) { - printf("setting year failed\n"); + puts("setting year failed\n"); } else if (!rtc_ds1307_write_month((word[5]-'0')*10+(word[6]-'0')*1)) { - printf("setting month failed\n"); + puts("setting month failed\n"); } else if (!rtc_ds1307_write_date((word[8]-'0')*10+(word[9]-'0')*1)) { - printf("setting day failed\n"); + puts("setting day failed\n"); } else { - printf("date set\n"); + puts("date set\n"); } } } else { @@ -161,7 +136,7 @@ static void process_command(char* str) return; // command successfully processed error: - printf("command not recognized. enter help to list commands\n"); + puts("command not recognized. enter help to list commands\n"); return; } @@ -186,79 +161,72 @@ void main(void) iwdg_start(); // start independent watchdog #endif - // setup board - board_setup(); - - // setup USART and USB for user communication - 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 - - // minimal setup ready - printf("welcome to the STM32F1 CuVoodoo example code\n"); // print welcome message + board_setup(); // setup board + usart_setup(); // setup USART for user communication + cdcacm_setup(); // setup USB ACM (serial) for user communication + puts("welcome to the STM32F1 CuVoodoo example code\n"); // print welcome message #if !(DEBUG) // show watchdog information - printf("watchdog set to (%.2fs)\n",WATCHDOG_PERIOD/1000.0); + printf("watchdog set to (%2u.%2us)\n",WATCHDOG_PERIOD/1000, (WATCHDOG_PERIOD/10)%100); if (FLASH_OBR&FLASH_OBR_OPTERR) { - printf("option bytes not set in flash: software wachtdog used (not started at reset)\n"); + puts("option bytes not set in flash: software wachtdog used (not started at reset)\n"); } else if (FLASH_OBR&FLASH_OBR_WDG_SW) { - printf("software wachtdog used (not started at reset)\n"); + puts("software wachtdog used (not started at reset)\n"); } else { - printf("hardware wachtdog used (started at reset)\n"); + puts("hardware wachtdog used (started at reset)\n"); } #endif // setup internal RTC - printf("setup internal RTC: "); + puts("setup internal RTC: "); rtc_auto_awake(RCC_LSE, 32768-1); // ensure internal RTC is on, uses the 32.678 kHz LSE, and the prescale is set to our tick speed, else update backup registers accordingly (power off the micro-controller for the change to take effect) rtc_interrupt_enable(RTC_SEC); // enable RTC interrupt on "seconds" nvic_enable_irq(NVIC_RTC_IRQ); // allow the RTC to interrupt - printf("OK\n"); + puts("OK\n"); // display uptime uint32_t ticks_time = rtc_get_counter_val(); // get time from internal RTC (since first start/power up) - printf("uptime: %lu.%02lu:%02lu:%02lu\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime + printf("uptime: %u.%02u:%02u:%02u\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime // setup external RTC - printf("setup external RTC: "); + puts("setup external RTC: "); rtc_ds1307_setup(); // setup external RTC module - printf("OK\n"); + puts("OK\n"); // verify is external RTC is running if (rtc_ds1307_oscillator_disabled()) { - printf("/!\\ RTC oscillator is disabled: the battery may be empty\n"); + puts("/!\\ RTC oscillator is disabled: the battery may be empty\n"); rtc_ds1307_oscillator_enable(); // enable oscillator again } // display date uint8_t* rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC if (rtc_ds1307_time==NULL) { - fprintf(stderr,"could not get time from DS1307\n"); + puts("could not get time from DS1307\n"); } else { printf("current date: 20%02u-%02u-%02u %02u:%02u:%02u\n", rtc_ds1307_time[6], rtc_ds1307_time[5], rtc_ds1307_time[4], rtc_ds1307_time[2], rtc_ds1307_time[1], rtc_ds1307_time[0]); } // setup TM1637 - printf("setup 7-segment display: "); + puts("setup 7-segment display: "); led_tm1637_setup(); if (!led_tm1637_time(88,88)) { // test display - fprintf(stderr,"could not send time to TM1637\n"); + puts("could not send time to TM1637\n"); } if (!led_tm1637_on()) { // switch on display - fprintf(stderr,"could not switch on TM1637\n"); + puts("could not switch on TM1637\n"); } for (uint32_t i=0; i<5000000; i++) { // wait a bit to have the user check the display __asm__("nop"); } if (!led_tm1637_text(" ")) { // clear display - fprintf(stderr,"could not clear\n"); + puts("could not clear\n"); } if (!led_tm1637_off()) { // switch off display - fprintf(stderr,"could not switch off TM1637\n"); + puts("could not switch off TM1637\n"); } - printf("OK\n"); + puts("OK\n"); // main loop - printf("command input: ready\n"); + puts("command input: ready\n"); bool action = false; // if an action has been performed don't go to sleep button_flag = false; // reset button flag char c = '\0'; // to store received character @@ -280,7 +248,7 @@ void main(void) while (char_flag) { // user data received char_flag = false; // reset flag action = true; // action has been performed - printf("%c",c); // echo receive character + putc(c); // echo receive character if (c=='\r' || c=='\n') { // end of command received if (command_i>0) { // there is a command to process command[command_i] = 0; // end string @@ -296,7 +264,7 @@ void main(void) } while (button_flag) { // user pressed button action = true; // action has been performed - printf("button pressed\n"); + puts("button pressed\n"); led_toggle(); // toggle LED for (uint32_t i=0; i<1000000; i++) { // wait a bit to remove noise and double trigger __asm__("nop"); @@ -309,19 +277,19 @@ void main(void) ticks_time = rtc_get_counter_val(); // copy time from internal RTC for processing action = true; // action has been performed if ((ticks_time%(60))==0) { // one minute passed - printf("uptime: %lu.%02lu:%02lu:%02lu\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime + printf("uptime: %u.%02u:%02u:%02u\n", ticks_time/(60*60*24), (ticks_time/(60*60))%24, (ticks_time%(60*60))/60, (ticks_time%60)); // display uptime } rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC if (rtc_ds1307_time==NULL) { - fprintf(stderr,"could not get time from DS1307: resetting\n"); + puts("could not get time from DS1307: resetting\n"); rtc_ds1307_setup(); // resetting periph } else { if (!led_tm1637_time(rtc_ds1307_time[1], rtc_ds1307_time[0])) { - fprintf(stderr,"could not set time on TM1637\n"); + puts("could not set time on TM1637\n"); } } if (!led_tm1637_on()) { // switch on display - fprintf(stderr,"could not switch on TM1637\n"); + puts("could not switch on TM1637\n"); } } if (action) { // go to sleep if nothing had to be done, else recheck for activity