printf_retarget.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2019 Ha Thach (tinyusb.org)
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. *
  24. * This file is part of the TinyUSB stack.
  25. */
  26. #include "board.h"
  27. #if CFG_PRINTF_TARGET != PRINTF_TARGET_SEMIHOST
  28. #if CFG_PRINTF_TARGET == PRINTF_TARGET_UART
  29. #define retarget_getchar() board_uart_getchar()
  30. #define retarget_putchar(c) board_uart_putchar(c);
  31. #elif CFG_PRINTF_TARGET == PRINTF_TARGET_SWO
  32. volatile int32_t ITM_RxBuffer; // keil variable to read from SWO
  33. #define retarget_getchar() ITM_ReceiveChar()
  34. #define retarget_putchar(c) ITM_SendChar(c)
  35. #else
  36. #error Target is not implemented yet
  37. #endif
  38. //--------------------------------------------------------------------+
  39. // LPCXPRESSO / RED SUITE
  40. //--------------------------------------------------------------------+
  41. #if defined __CODE_RED
  42. #if CFG_PRINTF_TARGET == PRINTF_TARGET_SWO
  43. #error author does not know how to retarget SWO with lpcxpresso/red-suite
  44. #endif
  45. // Called by bottom level of printf routine within RedLib C library to write
  46. // a character. With the default semihosting stub, this would write the character
  47. // to the debugger console window . But this version writes
  48. // the character to the UART.
  49. int __sys_write (int iFileHandle, char *buf, int length)
  50. {
  51. (void) iFileHandle;
  52. for (int i=0; i<length; i++)
  53. {
  54. if (buf[i] == '\n') retarget_putchar('\r');
  55. retarget_putchar( buf[i] );
  56. }
  57. return length;
  58. }
  59. // Called by bottom level of scanf routine within RedLib C library to read
  60. // a character. With the default semihosting stub, this would read the character
  61. // from the debugger console window (which acts as stdin). But this version reads
  62. // the character from the UART.
  63. int __sys_readc (void)
  64. {
  65. return (int) retarget_getchar();
  66. }
  67. #elif defined __SES_ARM && 0
  68. #include <stdarg.h>
  69. #include <stdio.h>
  70. #include "__libc.h"
  71. int printf(const char *fmt,...) {
  72. char buffer[128];
  73. va_list args;
  74. va_start (args, fmt);
  75. int n = vsnprintf(buffer, sizeof(buffer), fmt, args);
  76. for(int i=0; i < n; i++)
  77. {
  78. retarget_putchar( buffer[i] );
  79. }
  80. va_end(args);
  81. return n;
  82. }
  83. int __putchar(int ch, __printf_tag_ptr ctx)
  84. {
  85. (void)ctx;
  86. retarget_putchar( (uint8_t) ch );
  87. return 1;
  88. }
  89. int __getchar()
  90. {
  91. return retarget_getchar();
  92. }
  93. //--------------------------------------------------------------------+
  94. // KEIL
  95. //--------------------------------------------------------------------+
  96. #elif defined __CC_ARM // keil
  97. struct __FILE {
  98. uint32_t handle;
  99. };
  100. void _ttywrch(int ch)
  101. {
  102. if ( ch == '\n' ) retarget_putchar('\r');
  103. retarget_putchar(ch);
  104. }
  105. int fgetc(FILE *f)
  106. {
  107. return retarget_getchar();
  108. }
  109. int fputc(int ch, FILE *f)
  110. {
  111. _ttywrch(ch);
  112. return ch;
  113. }
  114. //--------------------------------------------------------------------+
  115. // IAR
  116. //--------------------------------------------------------------------+
  117. #elif defined __ICCARM__ // TODO could not able to retarget to UART with IAR
  118. #if CFG_PRINTF_TARGET == PRINTF_TARGET_UART
  119. #include <stddef.h>
  120. size_t __write(int handle, const unsigned char *buf, size_t length)
  121. {
  122. /* Check for the command to flush all handles */
  123. if (handle == -1) return 0;
  124. /* Check for stdout and stderr (only necessary if FILE descriptors are enabled.) */
  125. if (handle != 1 && handle != 2) return -1;
  126. for (size_t i=0; i<length; i++)
  127. {
  128. if (buf[i] == '\n') retarget_putchar('\r');
  129. retarget_putchar( buf[i] );
  130. }
  131. return length;
  132. }
  133. size_t __read(int handle, unsigned char *buf, size_t bufSize)
  134. {
  135. /* Check for stdin (only necessary if FILE descriptors are enabled) */
  136. if (handle != 0) return -1;
  137. size_t i;
  138. for (i=0; i<bufSize; i++)
  139. {
  140. int8_t ch = board_uart_getchar();
  141. if (ch == -1) break;
  142. buf[i] = ch;
  143. }
  144. return i;
  145. }
  146. #endif
  147. #endif
  148. #endif // CFG_PRINTF_TARGET != PRINTF_TARGET_SEMIHOST