選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

triceUart.c 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //! \file triceUart.c
  2. //! \author Thomas.Hoehenleitner [at] seerose.net
  3. //! //////////////////////////////////////////////////////////////////////////
  4. #include "trice.h"
  5. #include <stdint.h>
  6. #include <stdlib.h>
  7. #if TRICE_DEFERRED_UARTA == 1 && TRICE_OFF == 0
  8. #include "triceUart.h" // User has to provide this hardeware specific file, see examples folders.
  9. //! triceOutBufferUartA points into the double or ring buffer to the next (encoded) trice package.
  10. static const uint8_t *triceOutBufferUartA;
  11. //! triceOutCountUartA is the not yet transmitted byte count after a TriceNonBlockingWriteUartA() call.
  12. static size_t triceOutCountUartA = 0;
  13. //! triceOutIndexUartA is the triceOutBufferUartA offset to the next to transmit byte.
  14. static unsigned triceOutIndexUartA = 0;
  15. //! TriceNonBlockingWriteUartA registers a buffer for TRICE_UARTA transmission.
  16. //! \param buf is byte buffer start.
  17. //! \param nByte is the number of bytes to transfer
  18. void TriceNonBlockingWriteUartA(const void *buf, size_t nByte)
  19. {
  20. #if TRICE_CGO == 1 // automated tests
  21. TriceWriteDeviceCgo(buf, nByte);
  22. #else // #if TRICE_CGO == 1// automated tests
  23. TRICE_ENTER_CRITICAL_SECTION
  24. #if 1
  25. triceOutBufferUartA = buf;
  26. #else
  27. static uint8_t t[TRICE_DEFERRED_BUFFER_SIZE / 2]; // todo: find a better solution to avoid RAM wasting
  28. memcpy(t, buf, nByte);
  29. triceOutBufferUartA = t;
  30. #endif
  31. triceOutIndexUartA = 0;
  32. triceOutCountUartA = nByte;
  33. triceEnableTxEmptyInterruptUartA(); // triceTriggerTransmitUartA();
  34. TRICE_LEAVE_CRITICAL_SECTION
  35. #endif // #else // #if TRICE_CGO == 1// automated tests
  36. }
  37. //! TriceOutDepthUartA returns the amount of bytes not written yet to UARTB.
  38. unsigned TriceOutDepthUartA(void)
  39. {
  40. unsigned depth;
  41. TRICE_ENTER_CRITICAL_SECTION
  42. depth = triceOutCountUartA - triceOutIndexUartA;
  43. TRICE_LEAVE_CRITICAL_SECTION
  44. return depth;
  45. }
  46. //! triceNextUint8UartA returns the next trice byte for transmission to TRICE_UARTA.
  47. TRICE_INLINE uint8_t triceNextUint8UartA(void)
  48. {
  49. uint8_t c;
  50. TRICE_ENTER_CRITICAL_SECTION
  51. c = triceOutBufferUartA[triceOutIndexUartA++];
  52. TRICE_LEAVE_CRITICAL_SECTION
  53. return c;
  54. }
  55. //! triceServeTransmitUartA must be called cyclically to proceed ongoing write out.
  56. //! A good place is UARTA ISR.
  57. void triceServeTransmitUartA(void)
  58. {
  59. TRICE_ENTER_CRITICAL_SECTION
  60. triceTransmitData8UartA(triceNextUint8UartA());
  61. if (0 == TriceOutDepthUartA()) // no more bytes
  62. {
  63. triceDisableTxEmptyInterruptUartA();
  64. }
  65. TRICE_LEAVE_CRITICAL_SECTION
  66. }
  67. // // triceTriggerTransmitUartA must be called cyclically to initialize write out.
  68. // void triceTriggerTransmitUartA(void){
  69. // if( TriceOutDepthUartA() && triceTxDataRegisterEmptyUartA() ){
  70. // triceEnableTxEmptyInterruptUartA(); // next bytes
  71. // }
  72. // }
  73. #endif // #if TRICE_DEFERRED_UARTA == 1
  74. #if TRICE_DEFERRED_UARTB == 1
  75. #include "triceUart.h" // User has to provide this hardeware specific file, see examples folders.
  76. //! triceOutBufferUartB holds the uart out buffer address.
  77. static const uint8_t *triceOutBufferUartB;
  78. //! triceOutCountUartB holds th uarts out buffer size.
  79. static size_t triceOutCountUartB = 0;
  80. //! triceOutIndexUartB is the next to transmit byte index.
  81. static unsigned triceOutIndexUartB = 0;
  82. //! TriceNonBlockingWriteUartB registers a buffer for TRICE_UARTB transmission.
  83. //! \param buf is byte buffer start.
  84. //! \param nByte is the number of bytes to transfer
  85. void TriceNonBlockingWriteUartB(const void *buf, size_t nByte)
  86. {
  87. #if TRICE_CGO == 1 // automated tests
  88. TriceWriteDeviceCgo(buf, nByte);
  89. #else // #if TRICE_CGO == 1// automated tests
  90. triceOutBufferUartB = buf;
  91. triceOutIndexUartB = 0;
  92. triceOutCountUartB = nByte;
  93. triceTriggerTransmitUartB();
  94. #endif // #else // #if TRICE_CGO == 1// automated tests
  95. }
  96. //! TriceOutDepthUartB returns the amount of bytes not written yet to UARTB.
  97. unsigned TriceOutDepthUartB(void)
  98. {
  99. // unsigned depthRtt0 = 0; -> assuming RTT is fast enough
  100. unsigned depth = triceOutCountUartB - triceOutIndexUartB;
  101. return depth;
  102. }
  103. //! triceNextUint8UartB returns the next trice byte for transmission to TRICE_UARTA.
  104. TRICE_INLINE uint8_t triceNextUint8UartB(void)
  105. {
  106. return triceOutBufferUartB[triceOutIndexUartB++];
  107. }
  108. //! triceServeTransmitUartB must be called cyclically to proceed ongoing write out.
  109. //! A good place is UARTA ISR.
  110. void triceServeTransmitUartB(void)
  111. {
  112. triceTransmitData8UartB(triceNextUint8UartB());
  113. if (0 == TriceOutDepthUartB()) // no more bytes
  114. {
  115. triceDisableTxEmptyInterruptUartB();
  116. }
  117. }
  118. // triceTriggerTransmitUartB must be called cyclically to initialize write out.
  119. void triceTriggerTransmitUartB(void)
  120. {
  121. if (TriceOutDepthUartB() && triceTxDataRegisterEmptyUartB())
  122. {
  123. triceEnableTxEmptyInterruptUartB(); // next bytes
  124. }
  125. }
  126. #endif // #if TRICE_DEFERRED_UARTB == 1 && TRICE_OFF == 0