console.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * console.c
  3. *
  4. * printf-style interface to USART1.
  5. *
  6. * Written & released by Keir Fraser <keir.xen@gmail.com>
  7. *
  8. * This is free and unencumbered software released into the public domain.
  9. * See the file COPYING for more details, or visit <http://unlicense.org>.
  10. */
  11. #ifndef BAUD
  12. #define BAUD 3000000 /* 3Mbaud */
  13. #endif
  14. #if STM32F == 1
  15. #define PCLK SYSCLK
  16. #elif STM32F == 7
  17. #define PCLK (APB2_MHZ * 1000000)
  18. #endif
  19. #define USART1_IRQ 37
  20. static void ser_putc(uint8_t c)
  21. {
  22. #if STM32F == 1
  23. while (!(usart1->sr & USART_SR_TXE))
  24. cpu_relax();
  25. usart1->dr = c;
  26. #elif STM32F == 7
  27. while (!(usart1->isr & USART_ISR_TXE))
  28. cpu_relax();
  29. usart1->tdr = c;
  30. #endif
  31. }
  32. int vprintk(const char *format, va_list ap)
  33. {
  34. static char str[128];
  35. unsigned int flags;
  36. char *p, c;
  37. int n;
  38. IRQ_global_save(flags);
  39. n = vsnprintf(str, sizeof(str), format, ap);
  40. p = str;
  41. while ((c = *p++) != '\0') {
  42. switch (c) {
  43. case '\r': /* CR: ignore as we generate our own CR/LF */
  44. break;
  45. case '\n': /* LF: convert to CR/LF (usual terminal behaviour) */
  46. ser_putc('\r');
  47. /* fall through */
  48. default:
  49. ser_putc(c);
  50. break;
  51. }
  52. }
  53. IRQ_global_restore(flags);
  54. return n;
  55. }
  56. int printk(const char *format, ...)
  57. {
  58. va_list ap;
  59. int n;
  60. va_start(ap, format);
  61. n = vprintk(format, ap);
  62. va_end(ap);
  63. return n;
  64. }
  65. void console_init(void)
  66. {
  67. /* Turn on the clocks. */
  68. rcc->apb2enr |= RCC_APB2ENR_USART1EN;
  69. peripheral_clock_delay();
  70. /* Enable TX pin (PA9) for USART output, RX pin (PA10) as input. */
  71. #if STM32F == 1
  72. gpio_configure_pin(gpioa, 9, AFO_pushpull(_10MHz));
  73. gpio_configure_pin(gpioa, 10, GPI_pull_up);
  74. #elif STM32F == 7
  75. gpio_set_af(gpioa, 9, 7);
  76. gpio_set_af(gpioa, 10, 7);
  77. gpio_configure_pin(gpioa, 9, AFO_pushpull(IOSPD_MED));
  78. gpio_configure_pin(gpioa, 10, AFI(PUPD_up));
  79. #endif
  80. /* BAUD, 8n1. */
  81. usart1->brr = PCLK / BAUD;
  82. usart1->cr1 = (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE);
  83. }
  84. /* Debug helper: if we get stuck somewhere, calling this beforehand will cause
  85. * any serial input to cause a crash dump of the stuck context. */
  86. void console_crash_on_input(void)
  87. {
  88. #if STM32F == 1
  89. (void)usart1->dr; /* clear UART_SR_RXNE */
  90. #elif STM32F == 7
  91. usart1->rqr = USART_RQR_RXFRQ; /* clear ISR_RXNE */
  92. usart1->icr = USART_ICR_ORECF; /* clear ISR_ORE */
  93. #endif
  94. usart1->cr1 |= USART_CR1_RXNEIE;
  95. IRQx_set_prio(USART1_IRQ, RESET_IRQ_PRI);
  96. IRQx_enable(USART1_IRQ);
  97. }
  98. /*
  99. * Local variables:
  100. * mode: C
  101. * c-file-style: "Linux"
  102. * c-basic-offset: 4
  103. * tab-width: 4
  104. * indent-tabs-mode: nil
  105. * End:
  106. */