xref: /btstack/3rd-party/segger-rtt/SEGGER_RTT.c (revision ce6f85e79d1d141c1b45dfa16b2671762457cbb4)
17dc86dfdSMatthias Ringwald /*********************************************************************
2779af47bSMatthias Ringwald *                    SEGGER Microcontroller GmbH                     *
3779af47bSMatthias Ringwald *                        The Embedded Experts                        *
47dc86dfdSMatthias Ringwald **********************************************************************
57dc86dfdSMatthias Ringwald *                                                                    *
6779af47bSMatthias Ringwald *            (c) 1995 - 2019 SEGGER Microcontroller GmbH             *
77dc86dfdSMatthias Ringwald *                                                                    *
87dc86dfdSMatthias Ringwald *       www.segger.com     Support: [email protected]               *
97dc86dfdSMatthias Ringwald *                                                                    *
107dc86dfdSMatthias Ringwald **********************************************************************
117dc86dfdSMatthias Ringwald *                                                                    *
127dc86dfdSMatthias Ringwald *       SEGGER RTT * Real Time Transfer for embedded targets         *
137dc86dfdSMatthias Ringwald *                                                                    *
147dc86dfdSMatthias Ringwald **********************************************************************
157dc86dfdSMatthias Ringwald *                                                                    *
167dc86dfdSMatthias Ringwald * All rights reserved.                                               *
177dc86dfdSMatthias Ringwald *                                                                    *
187dc86dfdSMatthias Ringwald * SEGGER strongly recommends to not make any changes                 *
197dc86dfdSMatthias Ringwald * to or modify the source code of this software in order to stay     *
207dc86dfdSMatthias Ringwald * compatible with the RTT protocol and J-Link.                       *
217dc86dfdSMatthias Ringwald *                                                                    *
227dc86dfdSMatthias Ringwald * Redistribution and use in source and binary forms, with or         *
237dc86dfdSMatthias Ringwald * without modification, are permitted provided that the following    *
24*ce6f85e7SMatthias Ringwald * condition is met:                                                  *
257dc86dfdSMatthias Ringwald *                                                                    *
267dc86dfdSMatthias Ringwald * o Redistributions of source code must retain the above copyright   *
27*ce6f85e7SMatthias Ringwald *   notice, this condition and the following disclaimer.             *
287dc86dfdSMatthias Ringwald *                                                                    *
297dc86dfdSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
307dc86dfdSMatthias Ringwald * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
317dc86dfdSMatthias Ringwald * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
327dc86dfdSMatthias Ringwald * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
337dc86dfdSMatthias Ringwald * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
347dc86dfdSMatthias Ringwald * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
357dc86dfdSMatthias Ringwald * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
367dc86dfdSMatthias Ringwald * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
377dc86dfdSMatthias Ringwald * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
387dc86dfdSMatthias Ringwald * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
397dc86dfdSMatthias Ringwald * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
407dc86dfdSMatthias Ringwald * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
417dc86dfdSMatthias Ringwald * DAMAGE.                                                            *
427dc86dfdSMatthias Ringwald *                                                                    *
437dc86dfdSMatthias Ringwald **********************************************************************
447dc86dfdSMatthias Ringwald ---------------------------END-OF-HEADER------------------------------
457dc86dfdSMatthias Ringwald File    : SEGGER_RTT.c
467dc86dfdSMatthias Ringwald Purpose : Implementation of SEGGER real-time transfer (RTT) which
477dc86dfdSMatthias Ringwald           allows real-time communication on targets which support
487dc86dfdSMatthias Ringwald           debugger memory accesses while the CPU is running.
49*ce6f85e7SMatthias Ringwald Revision: $Rev: 28168 $
507dc86dfdSMatthias Ringwald 
517dc86dfdSMatthias Ringwald Additional information:
527dc86dfdSMatthias Ringwald           Type "int" is assumed to be 32-bits in size
537dc86dfdSMatthias Ringwald           H->T    Host to target communication
547dc86dfdSMatthias Ringwald           T->H    Target to host communication
557dc86dfdSMatthias Ringwald 
567dc86dfdSMatthias Ringwald           RTT channel 0 is always present and reserved for Terminal usage.
577dc86dfdSMatthias Ringwald           Name is fixed to "Terminal"
587dc86dfdSMatthias Ringwald 
597dc86dfdSMatthias Ringwald           Effective buffer size: SizeOfBuffer - 1
607dc86dfdSMatthias Ringwald 
617dc86dfdSMatthias Ringwald           WrOff == RdOff:       Buffer is empty
627dc86dfdSMatthias Ringwald           WrOff == (RdOff - 1): Buffer is full
637dc86dfdSMatthias Ringwald           WrOff >  RdOff:       Free space includes wrap-around
647dc86dfdSMatthias Ringwald           WrOff <  RdOff:       Used space includes wrap-around
657dc86dfdSMatthias Ringwald           (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0):
667dc86dfdSMatthias Ringwald                                 Buffer full and wrap-around after next byte
677dc86dfdSMatthias Ringwald 
687dc86dfdSMatthias Ringwald 
697dc86dfdSMatthias Ringwald ----------------------------------------------------------------------
707dc86dfdSMatthias Ringwald */
717dc86dfdSMatthias Ringwald 
727dc86dfdSMatthias Ringwald #include "SEGGER_RTT.h"
737dc86dfdSMatthias Ringwald 
747dc86dfdSMatthias Ringwald #include <string.h>                 // for memcpy
757dc86dfdSMatthias Ringwald 
767dc86dfdSMatthias Ringwald /*********************************************************************
777dc86dfdSMatthias Ringwald *
787dc86dfdSMatthias Ringwald *       Configuration, default values
797dc86dfdSMatthias Ringwald *
807dc86dfdSMatthias Ringwald **********************************************************************
817dc86dfdSMatthias Ringwald */
827dc86dfdSMatthias Ringwald 
83*ce6f85e7SMatthias Ringwald #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
84*ce6f85e7SMatthias Ringwald   #ifdef SEGGER_RTT_CB_ALIGN
85*ce6f85e7SMatthias Ringwald     #error "Custom SEGGER_RTT_CB_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
86*ce6f85e7SMatthias Ringwald   #endif
87*ce6f85e7SMatthias Ringwald   #ifdef SEGGER_RTT_BUFFER_ALIGN
88*ce6f85e7SMatthias Ringwald     #error "Custom SEGGER_RTT_BUFFER_ALIGN() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
89*ce6f85e7SMatthias Ringwald   #endif
90*ce6f85e7SMatthias Ringwald   #ifdef SEGGER_RTT_PUT_CB_SECTION
91*ce6f85e7SMatthias Ringwald     #error "Custom SEGGER_RTT_PUT_CB_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
92*ce6f85e7SMatthias Ringwald   #endif
93*ce6f85e7SMatthias Ringwald   #ifdef SEGGER_RTT_PUT_BUFFER_SECTION
94*ce6f85e7SMatthias Ringwald     #error "Custom SEGGER_RTT_PUT_BUFFER_SECTION() is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
95*ce6f85e7SMatthias Ringwald   #endif
96*ce6f85e7SMatthias Ringwald   #ifdef SEGGER_RTT_BUFFER_ALIGNMENT
97*ce6f85e7SMatthias Ringwald     #error "Custom SEGGER_RTT_BUFFER_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
98*ce6f85e7SMatthias Ringwald   #endif
99*ce6f85e7SMatthias Ringwald   #ifdef SEGGER_RTT_ALIGNMENT
100*ce6f85e7SMatthias Ringwald     #error "Custom SEGGER_RTT_ALIGNMENT is not supported for SEGGER_RTT_CPU_CACHE_LINE_SIZE != 0"
101*ce6f85e7SMatthias Ringwald   #endif
102*ce6f85e7SMatthias Ringwald #endif
103*ce6f85e7SMatthias Ringwald 
1047dc86dfdSMatthias Ringwald #ifndef   BUFFER_SIZE_UP
1057dc86dfdSMatthias Ringwald   #define BUFFER_SIZE_UP                                  1024  // Size of the buffer for terminal output of target, up to host
1067dc86dfdSMatthias Ringwald #endif
1077dc86dfdSMatthias Ringwald 
1087dc86dfdSMatthias Ringwald #ifndef   BUFFER_SIZE_DOWN
1097dc86dfdSMatthias Ringwald   #define BUFFER_SIZE_DOWN                                16    // Size of the buffer for terminal input to target from host (Usually keyboard input)
1107dc86dfdSMatthias Ringwald #endif
1117dc86dfdSMatthias Ringwald 
1127dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_MAX_NUM_UP_BUFFERS
1137dc86dfdSMatthias Ringwald   #define SEGGER_RTT_MAX_NUM_UP_BUFFERS                    2    // Number of up-buffers (T->H) available on this target
1147dc86dfdSMatthias Ringwald #endif
1157dc86dfdSMatthias Ringwald 
1167dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
1177dc86dfdSMatthias Ringwald   #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS                  2    // Number of down-buffers (H->T) available on this target
1187dc86dfdSMatthias Ringwald #endif
1197dc86dfdSMatthias Ringwald 
1207dc86dfdSMatthias Ringwald #ifndef SEGGER_RTT_BUFFER_SECTION
1217dc86dfdSMatthias Ringwald   #if defined(SEGGER_RTT_SECTION)
1227dc86dfdSMatthias Ringwald     #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
1237dc86dfdSMatthias Ringwald   #endif
1247dc86dfdSMatthias Ringwald #endif
1257dc86dfdSMatthias Ringwald 
1267dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_ALIGNMENT
127*ce6f85e7SMatthias Ringwald   #define SEGGER_RTT_ALIGNMENT                            SEGGER_RTT_CPU_CACHE_LINE_SIZE
1287dc86dfdSMatthias Ringwald #endif
1297dc86dfdSMatthias Ringwald 
1307dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_BUFFER_ALIGNMENT
131*ce6f85e7SMatthias Ringwald   #define SEGGER_RTT_BUFFER_ALIGNMENT                     SEGGER_RTT_CPU_CACHE_LINE_SIZE
1327dc86dfdSMatthias Ringwald #endif
1337dc86dfdSMatthias Ringwald 
1347dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_MODE_DEFAULT
1357dc86dfdSMatthias Ringwald   #define SEGGER_RTT_MODE_DEFAULT                         SEGGER_RTT_MODE_NO_BLOCK_SKIP
1367dc86dfdSMatthias Ringwald #endif
1377dc86dfdSMatthias Ringwald 
1387dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_LOCK
1397dc86dfdSMatthias Ringwald   #define SEGGER_RTT_LOCK()
1407dc86dfdSMatthias Ringwald #endif
1417dc86dfdSMatthias Ringwald 
1427dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_UNLOCK
1437dc86dfdSMatthias Ringwald   #define SEGGER_RTT_UNLOCK()
1447dc86dfdSMatthias Ringwald #endif
1457dc86dfdSMatthias Ringwald 
1467dc86dfdSMatthias Ringwald #ifndef   STRLEN
1477dc86dfdSMatthias Ringwald   #define STRLEN(a)                                       strlen((a))
1487dc86dfdSMatthias Ringwald #endif
1497dc86dfdSMatthias Ringwald 
150*ce6f85e7SMatthias Ringwald #ifndef   STRCPY
151*ce6f85e7SMatthias Ringwald   #define STRCPY(pDest, pSrc)                             strcpy((pDest), (pSrc))
152*ce6f85e7SMatthias Ringwald #endif
153*ce6f85e7SMatthias Ringwald 
1547dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_MEMCPY_USE_BYTELOOP
1557dc86dfdSMatthias Ringwald   #define SEGGER_RTT_MEMCPY_USE_BYTELOOP                  0
1567dc86dfdSMatthias Ringwald #endif
1577dc86dfdSMatthias Ringwald 
1587dc86dfdSMatthias Ringwald #ifndef   SEGGER_RTT_MEMCPY
1597dc86dfdSMatthias Ringwald   #ifdef  MEMCPY
1607dc86dfdSMatthias Ringwald     #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes)      MEMCPY((pDest), (pSrc), (NumBytes))
1617dc86dfdSMatthias Ringwald   #else
1627dc86dfdSMatthias Ringwald     #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes)      memcpy((pDest), (pSrc), (NumBytes))
1637dc86dfdSMatthias Ringwald   #endif
1647dc86dfdSMatthias Ringwald #endif
1657dc86dfdSMatthias Ringwald 
1667dc86dfdSMatthias Ringwald #ifndef   MIN
1677dc86dfdSMatthias Ringwald   #define MIN(a, b)         (((a) < (b)) ? (a) : (b))
1687dc86dfdSMatthias Ringwald #endif
1697dc86dfdSMatthias Ringwald 
1707dc86dfdSMatthias Ringwald #ifndef   MAX
1717dc86dfdSMatthias Ringwald   #define MAX(a, b)         (((a) > (b)) ? (a) : (b))
1727dc86dfdSMatthias Ringwald #endif
1737dc86dfdSMatthias Ringwald //
1747dc86dfdSMatthias Ringwald // For some environments, NULL may not be defined until certain headers are included
1757dc86dfdSMatthias Ringwald //
1767dc86dfdSMatthias Ringwald #ifndef NULL
1777dc86dfdSMatthias Ringwald   #define NULL 0
1787dc86dfdSMatthias Ringwald #endif
1797dc86dfdSMatthias Ringwald 
1807dc86dfdSMatthias Ringwald /*********************************************************************
1817dc86dfdSMatthias Ringwald *
1827dc86dfdSMatthias Ringwald *       Defines, fixed
1837dc86dfdSMatthias Ringwald *
1847dc86dfdSMatthias Ringwald **********************************************************************
1857dc86dfdSMatthias Ringwald */
1867dc86dfdSMatthias Ringwald #if (defined __ICCARM__) || (defined __ICCRX__)
1877dc86dfdSMatthias Ringwald   #define RTT_PRAGMA(P) _Pragma(#P)
1887dc86dfdSMatthias Ringwald #endif
1897dc86dfdSMatthias Ringwald 
1907dc86dfdSMatthias Ringwald #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT
191*ce6f85e7SMatthias Ringwald   #if ((defined __GNUC__) || (defined __clang__))
1927dc86dfdSMatthias Ringwald     #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
1937dc86dfdSMatthias Ringwald   #elif (defined __ICCARM__) || (defined __ICCRX__)
1947dc86dfdSMatthias Ringwald     #define PRAGMA(A) _Pragma(#A)
1957dc86dfdSMatthias Ringwald #define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \
1967dc86dfdSMatthias Ringwald                                   Var
1977dc86dfdSMatthias Ringwald   #elif (defined __CC_ARM)
1987dc86dfdSMatthias Ringwald     #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
1997dc86dfdSMatthias Ringwald   #else
2007dc86dfdSMatthias Ringwald     #error "Alignment not supported for this compiler."
2017dc86dfdSMatthias Ringwald   #endif
2027dc86dfdSMatthias Ringwald #else
2037dc86dfdSMatthias Ringwald   #define SEGGER_RTT_ALIGN(Var, Alignment) Var
2047dc86dfdSMatthias Ringwald #endif
2057dc86dfdSMatthias Ringwald 
2067dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION)
207*ce6f85e7SMatthias Ringwald   #if ((defined __GNUC__) || (defined __clang__))
2087dc86dfdSMatthias Ringwald     #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var
2097dc86dfdSMatthias Ringwald   #elif (defined __ICCARM__) || (defined __ICCRX__)
2107dc86dfdSMatthias Ringwald #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \
2117dc86dfdSMatthias Ringwald                                         Var
2127dc86dfdSMatthias Ringwald   #elif (defined __CC_ARM)
2137dc86dfdSMatthias Ringwald     #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init))  Var
2147dc86dfdSMatthias Ringwald   #else
2157dc86dfdSMatthias Ringwald     #error "Section placement not supported for this compiler."
2167dc86dfdSMatthias Ringwald   #endif
2177dc86dfdSMatthias Ringwald #else
2187dc86dfdSMatthias Ringwald   #define SEGGER_RTT_PUT_SECTION(Var, Section) Var
2197dc86dfdSMatthias Ringwald #endif
2207dc86dfdSMatthias Ringwald 
2217dc86dfdSMatthias Ringwald #if SEGGER_RTT_ALIGNMENT
2227dc86dfdSMatthias Ringwald   #define SEGGER_RTT_CB_ALIGN(Var)  SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT)
2237dc86dfdSMatthias Ringwald #else
2247dc86dfdSMatthias Ringwald   #define SEGGER_RTT_CB_ALIGN(Var)  Var
2257dc86dfdSMatthias Ringwald #endif
2267dc86dfdSMatthias Ringwald 
2277dc86dfdSMatthias Ringwald #if SEGGER_RTT_BUFFER_ALIGNMENT
2287dc86dfdSMatthias Ringwald   #define SEGGER_RTT_BUFFER_ALIGN(Var)  SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT)
2297dc86dfdSMatthias Ringwald #else
2307dc86dfdSMatthias Ringwald   #define SEGGER_RTT_BUFFER_ALIGN(Var)  Var
2317dc86dfdSMatthias Ringwald #endif
2327dc86dfdSMatthias Ringwald 
2337dc86dfdSMatthias Ringwald 
2347dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_SECTION)
2357dc86dfdSMatthias Ringwald   #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION)
2367dc86dfdSMatthias Ringwald #else
2377dc86dfdSMatthias Ringwald   #define SEGGER_RTT_PUT_CB_SECTION(Var) Var
2387dc86dfdSMatthias Ringwald #endif
2397dc86dfdSMatthias Ringwald 
2407dc86dfdSMatthias Ringwald #if defined(SEGGER_RTT_BUFFER_SECTION)
2417dc86dfdSMatthias Ringwald   #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION)
2427dc86dfdSMatthias Ringwald #else
2437dc86dfdSMatthias Ringwald   #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var
2447dc86dfdSMatthias Ringwald #endif
2457dc86dfdSMatthias Ringwald 
2467dc86dfdSMatthias Ringwald /*********************************************************************
2477dc86dfdSMatthias Ringwald *
2487dc86dfdSMatthias Ringwald *       Static const data
2497dc86dfdSMatthias Ringwald *
2507dc86dfdSMatthias Ringwald **********************************************************************
2517dc86dfdSMatthias Ringwald */
2527dc86dfdSMatthias Ringwald 
2537dc86dfdSMatthias Ringwald static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
2547dc86dfdSMatthias Ringwald 
2557dc86dfdSMatthias Ringwald /*********************************************************************
2567dc86dfdSMatthias Ringwald *
2577dc86dfdSMatthias Ringwald *       Static data
2587dc86dfdSMatthias Ringwald *
2597dc86dfdSMatthias Ringwald **********************************************************************
2607dc86dfdSMatthias Ringwald */
261*ce6f85e7SMatthias Ringwald 
2627dc86dfdSMatthias Ringwald //
2637dc86dfdSMatthias Ringwald // RTT Control Block and allocate buffers for channel 0
2647dc86dfdSMatthias Ringwald //
265*ce6f85e7SMatthias Ringwald #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
266*ce6f85e7SMatthias Ringwald   #if ((defined __GNUC__) || (defined __clang__))
267*ce6f85e7SMatthias Ringwald     SEGGER_RTT_CB _SEGGER_RTT                                                             __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
268*ce6f85e7SMatthias Ringwald     static char   _acUpBuffer  [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)]   __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
269*ce6f85e7SMatthias Ringwald     static char   _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
270*ce6f85e7SMatthias Ringwald   #elif (defined __ICCARM__)
271*ce6f85e7SMatthias Ringwald     #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
272*ce6f85e7SMatthias Ringwald     SEGGER_RTT_CB _SEGGER_RTT;
273*ce6f85e7SMatthias Ringwald     #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
274*ce6f85e7SMatthias Ringwald     static char   _acUpBuffer  [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)];
275*ce6f85e7SMatthias Ringwald     #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
276*ce6f85e7SMatthias Ringwald     static char   _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)];
277*ce6f85e7SMatthias Ringwald   #else
278*ce6f85e7SMatthias Ringwald     #error "Don't know how to place _SEGGER_RTT, _acUpBuffer, _acDownBuffer cache-line aligned"
279*ce6f85e7SMatthias Ringwald   #endif
280*ce6f85e7SMatthias Ringwald #else
2817dc86dfdSMatthias Ringwald   SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
2827dc86dfdSMatthias Ringwald   SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer  [BUFFER_SIZE_UP]));
2837dc86dfdSMatthias Ringwald   SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
284*ce6f85e7SMatthias Ringwald #endif
2857dc86dfdSMatthias Ringwald 
286779af47bSMatthias Ringwald static unsigned char _ActiveTerminal;
2877dc86dfdSMatthias Ringwald 
2887dc86dfdSMatthias Ringwald /*********************************************************************
2897dc86dfdSMatthias Ringwald *
2907dc86dfdSMatthias Ringwald *       Static functions
2917dc86dfdSMatthias Ringwald *
2927dc86dfdSMatthias Ringwald **********************************************************************
2937dc86dfdSMatthias Ringwald */
2947dc86dfdSMatthias Ringwald 
2957dc86dfdSMatthias Ringwald /*********************************************************************
2967dc86dfdSMatthias Ringwald *
2977dc86dfdSMatthias Ringwald *       _DoInit()
2987dc86dfdSMatthias Ringwald *
2997dc86dfdSMatthias Ringwald *  Function description
3007dc86dfdSMatthias Ringwald *    Initializes the control block an buffers.
3017dc86dfdSMatthias Ringwald *    May only be called via INIT() to avoid overriding settings.
3027dc86dfdSMatthias Ringwald *
3037dc86dfdSMatthias Ringwald */
304*ce6f85e7SMatthias Ringwald #define INIT()  {                                                                                    \
305*ce6f85e7SMatthias Ringwald                   volatile SEGGER_RTT_CB* pRTTCBInit;                                                \
306*ce6f85e7SMatthias Ringwald                   pRTTCBInit = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF); \
307*ce6f85e7SMatthias Ringwald                   do {                                                                               \
308*ce6f85e7SMatthias Ringwald                     if (pRTTCBInit->acID[0] == '\0') {                                               \
309*ce6f85e7SMatthias Ringwald                       _DoInit();                                                                     \
310*ce6f85e7SMatthias Ringwald                     }                                                                                \
311*ce6f85e7SMatthias Ringwald                   } while (0);                                                                       \
312*ce6f85e7SMatthias Ringwald                 }
313*ce6f85e7SMatthias Ringwald 
_DoInit(void)3147dc86dfdSMatthias Ringwald static void _DoInit(void) {
315*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* p;   // Volatile to make sure that compiler cannot change the order of accesses to the control block
316*ce6f85e7SMatthias Ringwald   static const char _aInitStr[] = "\0\0\0\0\0\0TTR REGGES";  // Init complete ID string to make sure that things also work if RTT is linked to a no-init memory area
317*ce6f85e7SMatthias Ringwald   unsigned i;
3187dc86dfdSMatthias Ringwald   //
3197dc86dfdSMatthias Ringwald   // Initialize control block
3207dc86dfdSMatthias Ringwald   //
321*ce6f85e7SMatthias Ringwald   p                     = (volatile SEGGER_RTT_CB*)((char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access control block uncached so that nothing in the cache ever becomes dirty and all changes are visible in HW directly
322*ce6f85e7SMatthias Ringwald   memset((SEGGER_RTT_CB*)p, 0, sizeof(_SEGGER_RTT));         // Make sure that the RTT CB is always zero initialized.
3237dc86dfdSMatthias Ringwald   p->MaxNumUpBuffers    = SEGGER_RTT_MAX_NUM_UP_BUFFERS;
3247dc86dfdSMatthias Ringwald   p->MaxNumDownBuffers  = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS;
3257dc86dfdSMatthias Ringwald   //
3267dc86dfdSMatthias Ringwald   // Initialize up buffer 0
3277dc86dfdSMatthias Ringwald   //
3287dc86dfdSMatthias Ringwald   p->aUp[0].sName         = "Terminal";
3297dc86dfdSMatthias Ringwald   p->aUp[0].pBuffer       = _acUpBuffer;
330*ce6f85e7SMatthias Ringwald   p->aUp[0].SizeOfBuffer  = BUFFER_SIZE_UP;
3317dc86dfdSMatthias Ringwald   p->aUp[0].RdOff         = 0u;
3327dc86dfdSMatthias Ringwald   p->aUp[0].WrOff         = 0u;
3337dc86dfdSMatthias Ringwald   p->aUp[0].Flags         = SEGGER_RTT_MODE_DEFAULT;
3347dc86dfdSMatthias Ringwald   //
3357dc86dfdSMatthias Ringwald   // Initialize down buffer 0
3367dc86dfdSMatthias Ringwald   //
3377dc86dfdSMatthias Ringwald   p->aDown[0].sName         = "Terminal";
3387dc86dfdSMatthias Ringwald   p->aDown[0].pBuffer       = _acDownBuffer;
339*ce6f85e7SMatthias Ringwald   p->aDown[0].SizeOfBuffer  = BUFFER_SIZE_DOWN;
3407dc86dfdSMatthias Ringwald   p->aDown[0].RdOff         = 0u;
3417dc86dfdSMatthias Ringwald   p->aDown[0].WrOff         = 0u;
3427dc86dfdSMatthias Ringwald   p->aDown[0].Flags         = SEGGER_RTT_MODE_DEFAULT;
3437dc86dfdSMatthias Ringwald   //
3447dc86dfdSMatthias Ringwald   // Finish initialization of the control block.
345*ce6f85e7SMatthias Ringwald   // Copy Id string backwards to make sure that "SEGGER RTT" is not found in initializer memory (usually flash),
346*ce6f85e7SMatthias Ringwald   // as this would cause J-Link to "find" the control block at a wrong address.
3477dc86dfdSMatthias Ringwald   //
348*ce6f85e7SMatthias Ringwald   RTT__DMB();                       // Force order of memory accesses for cores that may perform out-of-order memory accesses
349*ce6f85e7SMatthias Ringwald   for (i = 0; i < sizeof(_aInitStr) - 1; ++i) {
350*ce6f85e7SMatthias Ringwald     p->acID[i] = _aInitStr[sizeof(_aInitStr) - 2 - i];  // Skip terminating \0 at the end of the array
351*ce6f85e7SMatthias Ringwald   }
352*ce6f85e7SMatthias Ringwald   RTT__DMB();                       // Force order of memory accesses for cores that may perform out-of-order memory accesses
3537dc86dfdSMatthias Ringwald }
3547dc86dfdSMatthias Ringwald 
3557dc86dfdSMatthias Ringwald /*********************************************************************
3567dc86dfdSMatthias Ringwald *
3577dc86dfdSMatthias Ringwald *       _WriteBlocking()
3587dc86dfdSMatthias Ringwald *
3597dc86dfdSMatthias Ringwald *  Function description
3607dc86dfdSMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT ring buffer
3617dc86dfdSMatthias Ringwald *    and updates the associated write pointer which is periodically
3627dc86dfdSMatthias Ringwald *    read by the host.
3637dc86dfdSMatthias Ringwald *    The caller is responsible for managing the write chunk sizes as
3647dc86dfdSMatthias Ringwald *    _WriteBlocking() will block until all data has been posted successfully.
3657dc86dfdSMatthias Ringwald *
3667dc86dfdSMatthias Ringwald *  Parameters
3677dc86dfdSMatthias Ringwald *    pRing        Ring buffer to post to.
3687dc86dfdSMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
3697dc86dfdSMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
3707dc86dfdSMatthias Ringwald *
3717dc86dfdSMatthias Ringwald *  Return value
3727dc86dfdSMatthias Ringwald *    >= 0 - Number of bytes written into buffer.
3737dc86dfdSMatthias Ringwald */
_WriteBlocking(SEGGER_RTT_BUFFER_UP * pRing,const char * pBuffer,unsigned NumBytes)3747dc86dfdSMatthias Ringwald static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) {
3757dc86dfdSMatthias Ringwald   unsigned NumBytesToWrite;
3767dc86dfdSMatthias Ringwald   unsigned NumBytesWritten;
3777dc86dfdSMatthias Ringwald   unsigned RdOff;
3787dc86dfdSMatthias Ringwald   unsigned WrOff;
379*ce6f85e7SMatthias Ringwald   volatile char* pDst;
3807dc86dfdSMatthias Ringwald   //
3817dc86dfdSMatthias Ringwald   // Write data to buffer and handle wrap-around if necessary
3827dc86dfdSMatthias Ringwald   //
3837dc86dfdSMatthias Ringwald   NumBytesWritten = 0u;
3847dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff;
3857dc86dfdSMatthias Ringwald   do {
3867dc86dfdSMatthias Ringwald     RdOff = pRing->RdOff;                         // May be changed by host (debug probe) in the meantime
3877dc86dfdSMatthias Ringwald     if (RdOff > WrOff) {
3887dc86dfdSMatthias Ringwald       NumBytesToWrite = RdOff - WrOff - 1u;
3897dc86dfdSMatthias Ringwald     } else {
3907dc86dfdSMatthias Ringwald       NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u);
3917dc86dfdSMatthias Ringwald     }
3927dc86dfdSMatthias Ringwald     NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff));      // Number of bytes that can be written until buffer wrap-around
3937dc86dfdSMatthias Ringwald     NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
394*ce6f85e7SMatthias Ringwald     pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
3957dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
3967dc86dfdSMatthias Ringwald     NumBytesWritten += NumBytesToWrite;
3977dc86dfdSMatthias Ringwald     NumBytes        -= NumBytesToWrite;
3987dc86dfdSMatthias Ringwald     WrOff           += NumBytesToWrite;
3997dc86dfdSMatthias Ringwald     while (NumBytesToWrite--) {
4007dc86dfdSMatthias Ringwald       *pDst++ = *pBuffer++;
4017dc86dfdSMatthias Ringwald     };
4027dc86dfdSMatthias Ringwald #else
403*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY((void*)pDst, pBuffer, NumBytesToWrite);
4047dc86dfdSMatthias Ringwald     NumBytesWritten += NumBytesToWrite;
4057dc86dfdSMatthias Ringwald     pBuffer         += NumBytesToWrite;
4067dc86dfdSMatthias Ringwald     NumBytes        -= NumBytesToWrite;
4077dc86dfdSMatthias Ringwald     WrOff           += NumBytesToWrite;
4087dc86dfdSMatthias Ringwald #endif
4097dc86dfdSMatthias Ringwald     if (WrOff == pRing->SizeOfBuffer) {
4107dc86dfdSMatthias Ringwald       WrOff = 0u;
4117dc86dfdSMatthias Ringwald     }
412*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
4137dc86dfdSMatthias Ringwald     pRing->WrOff = WrOff;
4147dc86dfdSMatthias Ringwald   } while (NumBytes);
4157dc86dfdSMatthias Ringwald   return NumBytesWritten;
4167dc86dfdSMatthias Ringwald }
4177dc86dfdSMatthias Ringwald 
4187dc86dfdSMatthias Ringwald /*********************************************************************
4197dc86dfdSMatthias Ringwald *
4207dc86dfdSMatthias Ringwald *       _WriteNoCheck()
4217dc86dfdSMatthias Ringwald *
4227dc86dfdSMatthias Ringwald *  Function description
4237dc86dfdSMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT ring buffer
4247dc86dfdSMatthias Ringwald *    and updates the associated write pointer which is periodically
4257dc86dfdSMatthias Ringwald *    read by the host.
4267dc86dfdSMatthias Ringwald *    It is callers responsibility to make sure data actually fits in buffer.
4277dc86dfdSMatthias Ringwald *
4287dc86dfdSMatthias Ringwald *  Parameters
4297dc86dfdSMatthias Ringwald *    pRing        Ring buffer to post to.
4307dc86dfdSMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
4317dc86dfdSMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
4327dc86dfdSMatthias Ringwald *
4337dc86dfdSMatthias Ringwald *  Notes
4347dc86dfdSMatthias Ringwald *    (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking
4357dc86dfdSMatthias Ringwald */
_WriteNoCheck(SEGGER_RTT_BUFFER_UP * pRing,const char * pData,unsigned NumBytes)4367dc86dfdSMatthias Ringwald static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) {
4377dc86dfdSMatthias Ringwald   unsigned NumBytesAtOnce;
4387dc86dfdSMatthias Ringwald   unsigned WrOff;
4397dc86dfdSMatthias Ringwald   unsigned Rem;
440*ce6f85e7SMatthias Ringwald   volatile char* pDst;
4417dc86dfdSMatthias Ringwald 
4427dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff;
4437dc86dfdSMatthias Ringwald   Rem = pRing->SizeOfBuffer - WrOff;
4447dc86dfdSMatthias Ringwald   if (Rem > NumBytes) {
4457dc86dfdSMatthias Ringwald     //
4467dc86dfdSMatthias Ringwald     // All data fits before wrap around
4477dc86dfdSMatthias Ringwald     //
448*ce6f85e7SMatthias Ringwald     pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
4497dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
4507dc86dfdSMatthias Ringwald     WrOff += NumBytes;
4517dc86dfdSMatthias Ringwald     while (NumBytes--) {
4527dc86dfdSMatthias Ringwald       *pDst++ = *pData++;
4537dc86dfdSMatthias Ringwald     };
454*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
4557dc86dfdSMatthias Ringwald     pRing->WrOff = WrOff;
4567dc86dfdSMatthias Ringwald #else
457*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes);
458*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
4597dc86dfdSMatthias Ringwald     pRing->WrOff = WrOff + NumBytes;
4607dc86dfdSMatthias Ringwald #endif
4617dc86dfdSMatthias Ringwald   } else {
4627dc86dfdSMatthias Ringwald     //
4637dc86dfdSMatthias Ringwald     // We reach the end of the buffer, so need to wrap around
4647dc86dfdSMatthias Ringwald     //
4657dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
466*ce6f85e7SMatthias Ringwald     pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
4677dc86dfdSMatthias Ringwald     NumBytesAtOnce = Rem;
4687dc86dfdSMatthias Ringwald     while (NumBytesAtOnce--) {
4697dc86dfdSMatthias Ringwald       *pDst++ = *pData++;
4707dc86dfdSMatthias Ringwald     };
471*ce6f85e7SMatthias Ringwald     pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF;
4727dc86dfdSMatthias Ringwald     NumBytesAtOnce = NumBytes - Rem;
4737dc86dfdSMatthias Ringwald     while (NumBytesAtOnce--) {
4747dc86dfdSMatthias Ringwald       *pDst++ = *pData++;
4757dc86dfdSMatthias Ringwald     };
476*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
4777dc86dfdSMatthias Ringwald     pRing->WrOff = NumBytes - Rem;
4787dc86dfdSMatthias Ringwald #else
4797dc86dfdSMatthias Ringwald     NumBytesAtOnce = Rem;
480*ce6f85e7SMatthias Ringwald     pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
481*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytesAtOnce);
4827dc86dfdSMatthias Ringwald     NumBytesAtOnce = NumBytes - Rem;
483*ce6f85e7SMatthias Ringwald     pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF;
484*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY((void*)pDst, pData + Rem, NumBytesAtOnce);
485*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
4867dc86dfdSMatthias Ringwald     pRing->WrOff = NumBytesAtOnce;
4877dc86dfdSMatthias Ringwald #endif
4887dc86dfdSMatthias Ringwald   }
4897dc86dfdSMatthias Ringwald }
4907dc86dfdSMatthias Ringwald 
4917dc86dfdSMatthias Ringwald /*********************************************************************
4927dc86dfdSMatthias Ringwald *
4937dc86dfdSMatthias Ringwald *       _PostTerminalSwitch()
4947dc86dfdSMatthias Ringwald *
4957dc86dfdSMatthias Ringwald *  Function description
4967dc86dfdSMatthias Ringwald *    Switch terminal to the given terminal ID.  It is the caller's
4977dc86dfdSMatthias Ringwald *    responsibility to ensure the terminal ID is correct and there is
4987dc86dfdSMatthias Ringwald *    enough space in the buffer for this to complete successfully.
4997dc86dfdSMatthias Ringwald *
5007dc86dfdSMatthias Ringwald *  Parameters
5017dc86dfdSMatthias Ringwald *    pRing        Ring buffer to post to.
5027dc86dfdSMatthias Ringwald *    TerminalId   Terminal ID to switch to.
5037dc86dfdSMatthias Ringwald */
_PostTerminalSwitch(SEGGER_RTT_BUFFER_UP * pRing,unsigned char TerminalId)5047dc86dfdSMatthias Ringwald static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
505779af47bSMatthias Ringwald   unsigned char ac[2];
5067dc86dfdSMatthias Ringwald 
5077dc86dfdSMatthias Ringwald   ac[0] = 0xFFu;
5087dc86dfdSMatthias Ringwald   ac[1] = _aTerminalId[TerminalId];  // Caller made already sure that TerminalId does not exceed our terminal limit
509779af47bSMatthias Ringwald   _WriteBlocking(pRing, (const char*)ac, 2u);
5107dc86dfdSMatthias Ringwald }
5117dc86dfdSMatthias Ringwald 
5127dc86dfdSMatthias Ringwald /*********************************************************************
5137dc86dfdSMatthias Ringwald *
5147dc86dfdSMatthias Ringwald *       _GetAvailWriteSpace()
5157dc86dfdSMatthias Ringwald *
5167dc86dfdSMatthias Ringwald *  Function description
5177dc86dfdSMatthias Ringwald *    Returns the number of bytes that can be written to the ring
5187dc86dfdSMatthias Ringwald *    buffer without blocking.
5197dc86dfdSMatthias Ringwald *
5207dc86dfdSMatthias Ringwald *  Parameters
5217dc86dfdSMatthias Ringwald *    pRing        Ring buffer to check.
5227dc86dfdSMatthias Ringwald *
5237dc86dfdSMatthias Ringwald *  Return value
5247dc86dfdSMatthias Ringwald *    Number of bytes that are free in the buffer.
5257dc86dfdSMatthias Ringwald */
_GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP * pRing)5267dc86dfdSMatthias Ringwald static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) {
5277dc86dfdSMatthias Ringwald   unsigned RdOff;
5287dc86dfdSMatthias Ringwald   unsigned WrOff;
5297dc86dfdSMatthias Ringwald   unsigned r;
5307dc86dfdSMatthias Ringwald   //
5317dc86dfdSMatthias Ringwald   // Avoid warnings regarding volatile access order.  It's not a problem
5327dc86dfdSMatthias Ringwald   // in this case, but dampen compiler enthusiasm.
5337dc86dfdSMatthias Ringwald   //
5347dc86dfdSMatthias Ringwald   RdOff = pRing->RdOff;
5357dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff;
5367dc86dfdSMatthias Ringwald   if (RdOff <= WrOff) {
5377dc86dfdSMatthias Ringwald     r = pRing->SizeOfBuffer - 1u - WrOff + RdOff;
5387dc86dfdSMatthias Ringwald   } else {
5397dc86dfdSMatthias Ringwald     r = RdOff - WrOff - 1u;
5407dc86dfdSMatthias Ringwald   }
5417dc86dfdSMatthias Ringwald   return r;
5427dc86dfdSMatthias Ringwald }
5437dc86dfdSMatthias Ringwald 
5447dc86dfdSMatthias Ringwald /*********************************************************************
5457dc86dfdSMatthias Ringwald *
5467dc86dfdSMatthias Ringwald *       Public code
5477dc86dfdSMatthias Ringwald *
5487dc86dfdSMatthias Ringwald **********************************************************************
5497dc86dfdSMatthias Ringwald */
550*ce6f85e7SMatthias Ringwald 
551*ce6f85e7SMatthias Ringwald /*********************************************************************
552*ce6f85e7SMatthias Ringwald *
553*ce6f85e7SMatthias Ringwald *       SEGGER_RTT_ReadUpBufferNoLock()
554*ce6f85e7SMatthias Ringwald *
555*ce6f85e7SMatthias Ringwald *  Function description
556*ce6f85e7SMatthias Ringwald *    Reads characters from SEGGER real-time-terminal control block
557*ce6f85e7SMatthias Ringwald *    which have been previously stored by the application.
558*ce6f85e7SMatthias Ringwald *    Do not lock against interrupts and multiple access.
559*ce6f85e7SMatthias Ringwald *    Used to do the same operation that J-Link does, to transfer
560*ce6f85e7SMatthias Ringwald *    RTT data via other channels, such as TCP/IP or UART.
561*ce6f85e7SMatthias Ringwald *
562*ce6f85e7SMatthias Ringwald *  Parameters
563*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of Up-buffer to be used.
564*ce6f85e7SMatthias Ringwald *    pBuffer      Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to.
565*ce6f85e7SMatthias Ringwald *    BufferSize   Size of the target application buffer.
566*ce6f85e7SMatthias Ringwald *
567*ce6f85e7SMatthias Ringwald *  Return value
568*ce6f85e7SMatthias Ringwald *    Number of bytes that have been read.
569*ce6f85e7SMatthias Ringwald *
570*ce6f85e7SMatthias Ringwald *  Additional information
571*ce6f85e7SMatthias Ringwald *    This function must not be called when J-Link might also do RTT.
572*ce6f85e7SMatthias Ringwald */
SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex,void * pData,unsigned BufferSize)573*ce6f85e7SMatthias Ringwald unsigned SEGGER_RTT_ReadUpBufferNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
574*ce6f85e7SMatthias Ringwald   unsigned                NumBytesRem;
575*ce6f85e7SMatthias Ringwald   unsigned                NumBytesRead;
576*ce6f85e7SMatthias Ringwald   unsigned                RdOff;
577*ce6f85e7SMatthias Ringwald   unsigned                WrOff;
578*ce6f85e7SMatthias Ringwald   unsigned char*          pBuffer;
579*ce6f85e7SMatthias Ringwald   SEGGER_RTT_BUFFER_UP*   pRing;
580*ce6f85e7SMatthias Ringwald   volatile char*          pSrc;
581*ce6f85e7SMatthias Ringwald 
582*ce6f85e7SMatthias Ringwald   INIT();
583*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
584*ce6f85e7SMatthias Ringwald   pBuffer = (unsigned char*)pData;
585*ce6f85e7SMatthias Ringwald   RdOff = pRing->RdOff;
586*ce6f85e7SMatthias Ringwald   WrOff = pRing->WrOff;
587*ce6f85e7SMatthias Ringwald   NumBytesRead = 0u;
588*ce6f85e7SMatthias Ringwald   //
589*ce6f85e7SMatthias Ringwald   // Read from current read position to wrap-around of buffer, first
590*ce6f85e7SMatthias Ringwald   //
591*ce6f85e7SMatthias Ringwald   if (RdOff > WrOff) {
592*ce6f85e7SMatthias Ringwald     NumBytesRem = pRing->SizeOfBuffer - RdOff;
593*ce6f85e7SMatthias Ringwald     NumBytesRem = MIN(NumBytesRem, BufferSize);
594*ce6f85e7SMatthias Ringwald     pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
595*ce6f85e7SMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
596*ce6f85e7SMatthias Ringwald     NumBytesRead += NumBytesRem;
597*ce6f85e7SMatthias Ringwald     BufferSize   -= NumBytesRem;
598*ce6f85e7SMatthias Ringwald     RdOff        += NumBytesRem;
599*ce6f85e7SMatthias Ringwald     while (NumBytesRem--) {
600*ce6f85e7SMatthias Ringwald       *pBuffer++ = *pSrc++;
601*ce6f85e7SMatthias Ringwald     };
602*ce6f85e7SMatthias Ringwald #else
603*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
604*ce6f85e7SMatthias Ringwald     NumBytesRead += NumBytesRem;
605*ce6f85e7SMatthias Ringwald     pBuffer      += NumBytesRem;
606*ce6f85e7SMatthias Ringwald     BufferSize   -= NumBytesRem;
607*ce6f85e7SMatthias Ringwald     RdOff        += NumBytesRem;
608*ce6f85e7SMatthias Ringwald #endif
609*ce6f85e7SMatthias Ringwald     //
610*ce6f85e7SMatthias Ringwald     // Handle wrap-around of buffer
611*ce6f85e7SMatthias Ringwald     //
612*ce6f85e7SMatthias Ringwald     if (RdOff == pRing->SizeOfBuffer) {
613*ce6f85e7SMatthias Ringwald       RdOff = 0u;
614*ce6f85e7SMatthias Ringwald     }
615*ce6f85e7SMatthias Ringwald   }
616*ce6f85e7SMatthias Ringwald   //
617*ce6f85e7SMatthias Ringwald   // Read remaining items of buffer
618*ce6f85e7SMatthias Ringwald   //
619*ce6f85e7SMatthias Ringwald   NumBytesRem = WrOff - RdOff;
620*ce6f85e7SMatthias Ringwald   NumBytesRem = MIN(NumBytesRem, BufferSize);
621*ce6f85e7SMatthias Ringwald   if (NumBytesRem > 0u) {
622*ce6f85e7SMatthias Ringwald     pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
623*ce6f85e7SMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
624*ce6f85e7SMatthias Ringwald     NumBytesRead += NumBytesRem;
625*ce6f85e7SMatthias Ringwald     BufferSize   -= NumBytesRem;
626*ce6f85e7SMatthias Ringwald     RdOff        += NumBytesRem;
627*ce6f85e7SMatthias Ringwald     while (NumBytesRem--) {
628*ce6f85e7SMatthias Ringwald       *pBuffer++ = *pSrc++;
629*ce6f85e7SMatthias Ringwald     };
630*ce6f85e7SMatthias Ringwald #else
631*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
632*ce6f85e7SMatthias Ringwald     NumBytesRead += NumBytesRem;
633*ce6f85e7SMatthias Ringwald     pBuffer      += NumBytesRem;
634*ce6f85e7SMatthias Ringwald     BufferSize   -= NumBytesRem;
635*ce6f85e7SMatthias Ringwald     RdOff        += NumBytesRem;
636*ce6f85e7SMatthias Ringwald #endif
637*ce6f85e7SMatthias Ringwald   }
638*ce6f85e7SMatthias Ringwald   //
639*ce6f85e7SMatthias Ringwald   // Update read offset of buffer
640*ce6f85e7SMatthias Ringwald   //
641*ce6f85e7SMatthias Ringwald   if (NumBytesRead) {
642*ce6f85e7SMatthias Ringwald     pRing->RdOff = RdOff;
643*ce6f85e7SMatthias Ringwald   }
644*ce6f85e7SMatthias Ringwald   //
645*ce6f85e7SMatthias Ringwald   return NumBytesRead;
646*ce6f85e7SMatthias Ringwald }
647*ce6f85e7SMatthias Ringwald 
6487dc86dfdSMatthias Ringwald /*********************************************************************
6497dc86dfdSMatthias Ringwald *
6507dc86dfdSMatthias Ringwald *       SEGGER_RTT_ReadNoLock()
6517dc86dfdSMatthias Ringwald *
6527dc86dfdSMatthias Ringwald *  Function description
6537dc86dfdSMatthias Ringwald *    Reads characters from SEGGER real-time-terminal control block
6547dc86dfdSMatthias Ringwald *    which have been previously stored by the host.
6557dc86dfdSMatthias Ringwald *    Do not lock against interrupts and multiple access.
6567dc86dfdSMatthias Ringwald *
6577dc86dfdSMatthias Ringwald *  Parameters
6587dc86dfdSMatthias Ringwald *    BufferIndex  Index of Down-buffer to be used (e.g. 0 for "Terminal").
6597dc86dfdSMatthias Ringwald *    pBuffer      Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
6607dc86dfdSMatthias Ringwald *    BufferSize   Size of the target application buffer.
6617dc86dfdSMatthias Ringwald *
6627dc86dfdSMatthias Ringwald *  Return value
6637dc86dfdSMatthias Ringwald *    Number of bytes that have been read.
6647dc86dfdSMatthias Ringwald */
SEGGER_RTT_ReadNoLock(unsigned BufferIndex,void * pData,unsigned BufferSize)6657dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
6667dc86dfdSMatthias Ringwald   unsigned                NumBytesRem;
6677dc86dfdSMatthias Ringwald   unsigned                NumBytesRead;
6687dc86dfdSMatthias Ringwald   unsigned                RdOff;
6697dc86dfdSMatthias Ringwald   unsigned                WrOff;
6707dc86dfdSMatthias Ringwald   unsigned char*          pBuffer;
6717dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_DOWN* pRing;
672*ce6f85e7SMatthias Ringwald   volatile char*          pSrc;
6737dc86dfdSMatthias Ringwald   //
6747dc86dfdSMatthias Ringwald   INIT();
675*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
6767dc86dfdSMatthias Ringwald   pBuffer = (unsigned char*)pData;
6777dc86dfdSMatthias Ringwald   RdOff = pRing->RdOff;
6787dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff;
6797dc86dfdSMatthias Ringwald   NumBytesRead = 0u;
6807dc86dfdSMatthias Ringwald   //
6817dc86dfdSMatthias Ringwald   // Read from current read position to wrap-around of buffer, first
6827dc86dfdSMatthias Ringwald   //
6837dc86dfdSMatthias Ringwald   if (RdOff > WrOff) {
6847dc86dfdSMatthias Ringwald     NumBytesRem = pRing->SizeOfBuffer - RdOff;
6857dc86dfdSMatthias Ringwald     NumBytesRem = MIN(NumBytesRem, BufferSize);
686*ce6f85e7SMatthias Ringwald     pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
6877dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
6887dc86dfdSMatthias Ringwald     NumBytesRead += NumBytesRem;
6897dc86dfdSMatthias Ringwald     BufferSize   -= NumBytesRem;
6907dc86dfdSMatthias Ringwald     RdOff        += NumBytesRem;
6917dc86dfdSMatthias Ringwald     while (NumBytesRem--) {
6927dc86dfdSMatthias Ringwald       *pBuffer++ = *pSrc++;
6937dc86dfdSMatthias Ringwald     };
6947dc86dfdSMatthias Ringwald #else
695*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
6967dc86dfdSMatthias Ringwald     NumBytesRead += NumBytesRem;
6977dc86dfdSMatthias Ringwald     pBuffer      += NumBytesRem;
6987dc86dfdSMatthias Ringwald     BufferSize   -= NumBytesRem;
6997dc86dfdSMatthias Ringwald     RdOff        += NumBytesRem;
7007dc86dfdSMatthias Ringwald #endif
7017dc86dfdSMatthias Ringwald     //
7027dc86dfdSMatthias Ringwald     // Handle wrap-around of buffer
7037dc86dfdSMatthias Ringwald     //
7047dc86dfdSMatthias Ringwald     if (RdOff == pRing->SizeOfBuffer) {
7057dc86dfdSMatthias Ringwald       RdOff = 0u;
7067dc86dfdSMatthias Ringwald     }
7077dc86dfdSMatthias Ringwald   }
7087dc86dfdSMatthias Ringwald   //
7097dc86dfdSMatthias Ringwald   // Read remaining items of buffer
7107dc86dfdSMatthias Ringwald   //
7117dc86dfdSMatthias Ringwald   NumBytesRem = WrOff - RdOff;
7127dc86dfdSMatthias Ringwald   NumBytesRem = MIN(NumBytesRem, BufferSize);
7137dc86dfdSMatthias Ringwald   if (NumBytesRem > 0u) {
714*ce6f85e7SMatthias Ringwald     pSrc = (pRing->pBuffer + RdOff) + SEGGER_RTT_UNCACHED_OFF;
7157dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
7167dc86dfdSMatthias Ringwald     NumBytesRead += NumBytesRem;
7177dc86dfdSMatthias Ringwald     BufferSize   -= NumBytesRem;
7187dc86dfdSMatthias Ringwald     RdOff        += NumBytesRem;
7197dc86dfdSMatthias Ringwald     while (NumBytesRem--) {
7207dc86dfdSMatthias Ringwald       *pBuffer++ = *pSrc++;
7217dc86dfdSMatthias Ringwald     };
7227dc86dfdSMatthias Ringwald #else
723*ce6f85e7SMatthias Ringwald     SEGGER_RTT_MEMCPY(pBuffer, (void*)pSrc, NumBytesRem);
7247dc86dfdSMatthias Ringwald     NumBytesRead += NumBytesRem;
7257dc86dfdSMatthias Ringwald     pBuffer      += NumBytesRem;
7267dc86dfdSMatthias Ringwald     BufferSize   -= NumBytesRem;
7277dc86dfdSMatthias Ringwald     RdOff        += NumBytesRem;
7287dc86dfdSMatthias Ringwald #endif
7297dc86dfdSMatthias Ringwald   }
7307dc86dfdSMatthias Ringwald   if (NumBytesRead) {
7317dc86dfdSMatthias Ringwald     pRing->RdOff = RdOff;
7327dc86dfdSMatthias Ringwald   }
7337dc86dfdSMatthias Ringwald   //
7347dc86dfdSMatthias Ringwald   return NumBytesRead;
7357dc86dfdSMatthias Ringwald }
7367dc86dfdSMatthias Ringwald 
7377dc86dfdSMatthias Ringwald /*********************************************************************
7387dc86dfdSMatthias Ringwald *
739*ce6f85e7SMatthias Ringwald *       SEGGER_RTT_ReadUpBuffer
740*ce6f85e7SMatthias Ringwald *
741*ce6f85e7SMatthias Ringwald *  Function description
742*ce6f85e7SMatthias Ringwald *    Reads characters from SEGGER real-time-terminal control block
743*ce6f85e7SMatthias Ringwald *    which have been previously stored by the application.
744*ce6f85e7SMatthias Ringwald *    Used to do the same operation that J-Link does, to transfer
745*ce6f85e7SMatthias Ringwald *    RTT data via other channels, such as TCP/IP or UART.
746*ce6f85e7SMatthias Ringwald *
747*ce6f85e7SMatthias Ringwald *  Parameters
748*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of Up-buffer to be used.
749*ce6f85e7SMatthias Ringwald *    pBuffer      Pointer to buffer provided by target application, to copy characters from RTT-up-buffer to.
750*ce6f85e7SMatthias Ringwald *    BufferSize   Size of the target application buffer.
751*ce6f85e7SMatthias Ringwald *
752*ce6f85e7SMatthias Ringwald *  Return value
753*ce6f85e7SMatthias Ringwald *    Number of bytes that have been read.
754*ce6f85e7SMatthias Ringwald *
755*ce6f85e7SMatthias Ringwald *  Additional information
756*ce6f85e7SMatthias Ringwald *    This function must not be called when J-Link might also do RTT.
757*ce6f85e7SMatthias Ringwald *    This function locks against all other RTT operations. I.e. during
758*ce6f85e7SMatthias Ringwald *    the read operation, writing is also locked.
759*ce6f85e7SMatthias Ringwald *    If only one consumer reads from the up buffer,
760*ce6f85e7SMatthias Ringwald *    call sEGGER_RTT_ReadUpBufferNoLock() instead.
761*ce6f85e7SMatthias Ringwald */
SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex,void * pBuffer,unsigned BufferSize)762*ce6f85e7SMatthias Ringwald unsigned SEGGER_RTT_ReadUpBuffer(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
763*ce6f85e7SMatthias Ringwald   unsigned NumBytesRead;
764*ce6f85e7SMatthias Ringwald 
765*ce6f85e7SMatthias Ringwald   SEGGER_RTT_LOCK();
766*ce6f85e7SMatthias Ringwald   //
767*ce6f85e7SMatthias Ringwald   // Call the non-locking read function
768*ce6f85e7SMatthias Ringwald   //
769*ce6f85e7SMatthias Ringwald   NumBytesRead = SEGGER_RTT_ReadUpBufferNoLock(BufferIndex, pBuffer, BufferSize);
770*ce6f85e7SMatthias Ringwald   //
771*ce6f85e7SMatthias Ringwald   // Finish up.
772*ce6f85e7SMatthias Ringwald   //
773*ce6f85e7SMatthias Ringwald   SEGGER_RTT_UNLOCK();
774*ce6f85e7SMatthias Ringwald   //
775*ce6f85e7SMatthias Ringwald   return NumBytesRead;
776*ce6f85e7SMatthias Ringwald }
777*ce6f85e7SMatthias Ringwald 
778*ce6f85e7SMatthias Ringwald /*********************************************************************
779*ce6f85e7SMatthias Ringwald *
7807dc86dfdSMatthias Ringwald *       SEGGER_RTT_Read
7817dc86dfdSMatthias Ringwald *
7827dc86dfdSMatthias Ringwald *  Function description
7837dc86dfdSMatthias Ringwald *    Reads characters from SEGGER real-time-terminal control block
7847dc86dfdSMatthias Ringwald *    which have been previously stored by the host.
7857dc86dfdSMatthias Ringwald *
7867dc86dfdSMatthias Ringwald *  Parameters
7877dc86dfdSMatthias Ringwald *    BufferIndex  Index of Down-buffer to be used (e.g. 0 for "Terminal").
7887dc86dfdSMatthias Ringwald *    pBuffer      Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
7897dc86dfdSMatthias Ringwald *    BufferSize   Size of the target application buffer.
7907dc86dfdSMatthias Ringwald *
7917dc86dfdSMatthias Ringwald *  Return value
7927dc86dfdSMatthias Ringwald *    Number of bytes that have been read.
7937dc86dfdSMatthias Ringwald */
SEGGER_RTT_Read(unsigned BufferIndex,void * pBuffer,unsigned BufferSize)7947dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
7957dc86dfdSMatthias Ringwald   unsigned NumBytesRead;
796*ce6f85e7SMatthias Ringwald 
7977dc86dfdSMatthias Ringwald   SEGGER_RTT_LOCK();
7987dc86dfdSMatthias Ringwald   //
7997dc86dfdSMatthias Ringwald   // Call the non-locking read function
8007dc86dfdSMatthias Ringwald   //
8017dc86dfdSMatthias Ringwald   NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize);
8027dc86dfdSMatthias Ringwald   //
8037dc86dfdSMatthias Ringwald   // Finish up.
8047dc86dfdSMatthias Ringwald   //
8057dc86dfdSMatthias Ringwald   SEGGER_RTT_UNLOCK();
8067dc86dfdSMatthias Ringwald   //
8077dc86dfdSMatthias Ringwald   return NumBytesRead;
8087dc86dfdSMatthias Ringwald }
8097dc86dfdSMatthias Ringwald 
8107dc86dfdSMatthias Ringwald /*********************************************************************
8117dc86dfdSMatthias Ringwald *
8127dc86dfdSMatthias Ringwald *       SEGGER_RTT_WriteWithOverwriteNoLock
8137dc86dfdSMatthias Ringwald *
8147dc86dfdSMatthias Ringwald *  Function description
8157dc86dfdSMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT
8167dc86dfdSMatthias Ringwald *    control block.
8177dc86dfdSMatthias Ringwald *    SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application
8187dc86dfdSMatthias Ringwald *    and overwrites data if the data does not fit into the buffer.
8197dc86dfdSMatthias Ringwald *
8207dc86dfdSMatthias Ringwald *  Parameters
8217dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
8227dc86dfdSMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
8237dc86dfdSMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
8247dc86dfdSMatthias Ringwald *
8257dc86dfdSMatthias Ringwald *  Notes
8267dc86dfdSMatthias Ringwald *    (1) If there is not enough space in the "Up"-buffer, data is overwritten.
8277dc86dfdSMatthias Ringwald *    (2) For performance reasons this function does not call Init()
8287dc86dfdSMatthias Ringwald *        and may only be called after RTT has been initialized.
8297dc86dfdSMatthias Ringwald *        Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
8307dc86dfdSMatthias Ringwald *    (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link
8317dc86dfdSMatthias Ringwald *        connection reads RTT data.
8327dc86dfdSMatthias Ringwald */
SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex,const void * pBuffer,unsigned NumBytes)8337dc86dfdSMatthias Ringwald void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
8347dc86dfdSMatthias Ringwald   const char*           pData;
8357dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
8367dc86dfdSMatthias Ringwald   unsigned              Avail;
837*ce6f85e7SMatthias Ringwald   volatile char*        pDst;
8387dc86dfdSMatthias Ringwald   //
8397dc86dfdSMatthias Ringwald   // Get "to-host" ring buffer and copy some elements into local variables.
8407dc86dfdSMatthias Ringwald   //
841*ce6f85e7SMatthias Ringwald   pData = (const char *)pBuffer;
842*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
8437dc86dfdSMatthias Ringwald   //
8447dc86dfdSMatthias Ringwald   // Check if we will overwrite data and need to adjust the RdOff.
8457dc86dfdSMatthias Ringwald   //
8467dc86dfdSMatthias Ringwald   if (pRing->WrOff == pRing->RdOff) {
8477dc86dfdSMatthias Ringwald     Avail = pRing->SizeOfBuffer - 1u;
8487dc86dfdSMatthias Ringwald   } else if ( pRing->WrOff < pRing->RdOff) {
8497dc86dfdSMatthias Ringwald     Avail = pRing->RdOff - pRing->WrOff - 1u;
8507dc86dfdSMatthias Ringwald   } else {
8517dc86dfdSMatthias Ringwald     Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer;
8527dc86dfdSMatthias Ringwald   }
8537dc86dfdSMatthias Ringwald   if (NumBytes > Avail) {
8547dc86dfdSMatthias Ringwald     pRing->RdOff += (NumBytes - Avail);
8557dc86dfdSMatthias Ringwald     while (pRing->RdOff >= pRing->SizeOfBuffer) {
8567dc86dfdSMatthias Ringwald       pRing->RdOff -= pRing->SizeOfBuffer;
8577dc86dfdSMatthias Ringwald     }
8587dc86dfdSMatthias Ringwald   }
8597dc86dfdSMatthias Ringwald   //
8607dc86dfdSMatthias Ringwald   // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds
8617dc86dfdSMatthias Ringwald   //
8627dc86dfdSMatthias Ringwald   Avail = pRing->SizeOfBuffer - pRing->WrOff;
8637dc86dfdSMatthias Ringwald   do {
8647dc86dfdSMatthias Ringwald     if (Avail > NumBytes) {
8657dc86dfdSMatthias Ringwald       //
8667dc86dfdSMatthias Ringwald       // Last round
8677dc86dfdSMatthias Ringwald       //
868*ce6f85e7SMatthias Ringwald       pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
8697dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
8707dc86dfdSMatthias Ringwald       Avail = NumBytes;
8717dc86dfdSMatthias Ringwald       while (NumBytes--) {
8727dc86dfdSMatthias Ringwald         *pDst++ = *pData++;
8737dc86dfdSMatthias Ringwald       };
874*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
8757dc86dfdSMatthias Ringwald       pRing->WrOff += Avail;
8767dc86dfdSMatthias Ringwald #else
877*ce6f85e7SMatthias Ringwald       SEGGER_RTT_MEMCPY((void*)pDst, pData, NumBytes);
878*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
8797dc86dfdSMatthias Ringwald       pRing->WrOff += NumBytes;
8807dc86dfdSMatthias Ringwald #endif
8817dc86dfdSMatthias Ringwald       break;
8827dc86dfdSMatthias Ringwald     } else {
8837dc86dfdSMatthias Ringwald       //
8847dc86dfdSMatthias Ringwald       //  Wrap-around necessary, write until wrap-around and reset WrOff
8857dc86dfdSMatthias Ringwald       //
886*ce6f85e7SMatthias Ringwald       pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
8877dc86dfdSMatthias Ringwald #if SEGGER_RTT_MEMCPY_USE_BYTELOOP
8887dc86dfdSMatthias Ringwald       NumBytes -= Avail;
8897dc86dfdSMatthias Ringwald       while (Avail--) {
8907dc86dfdSMatthias Ringwald         *pDst++ = *pData++;
8917dc86dfdSMatthias Ringwald       };
892*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
8937dc86dfdSMatthias Ringwald       pRing->WrOff = 0;
8947dc86dfdSMatthias Ringwald #else
895*ce6f85e7SMatthias Ringwald       SEGGER_RTT_MEMCPY((void*)pDst, pData, Avail);
8967dc86dfdSMatthias Ringwald       pData += Avail;
897*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
8987dc86dfdSMatthias Ringwald       pRing->WrOff = 0;
8997dc86dfdSMatthias Ringwald       NumBytes -= Avail;
9007dc86dfdSMatthias Ringwald #endif
9017dc86dfdSMatthias Ringwald       Avail = (pRing->SizeOfBuffer - 1);
9027dc86dfdSMatthias Ringwald     }
9037dc86dfdSMatthias Ringwald   } while (NumBytes);
9047dc86dfdSMatthias Ringwald }
9057dc86dfdSMatthias Ringwald 
9067dc86dfdSMatthias Ringwald /*********************************************************************
9077dc86dfdSMatthias Ringwald *
9087dc86dfdSMatthias Ringwald *       SEGGER_RTT_WriteSkipNoLock
9097dc86dfdSMatthias Ringwald *
9107dc86dfdSMatthias Ringwald *  Function description
9117dc86dfdSMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT
9127dc86dfdSMatthias Ringwald *    control block which is then read by the host.
9137dc86dfdSMatthias Ringwald *    SEGGER_RTT_WriteSkipNoLock does not lock the application and
9147dc86dfdSMatthias Ringwald *    skips all data, if the data does not fit into the buffer.
9157dc86dfdSMatthias Ringwald *
9167dc86dfdSMatthias Ringwald *  Parameters
9177dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
9187dc86dfdSMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
9197dc86dfdSMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
920779af47bSMatthias Ringwald *                 MUST be > 0!!!
921779af47bSMatthias Ringwald *                 This is done for performance reasons, so no initial check has do be done.
9227dc86dfdSMatthias Ringwald *
9237dc86dfdSMatthias Ringwald *  Return value
924779af47bSMatthias Ringwald *    1: Data has been copied
925779af47bSMatthias Ringwald *    0: No space, data has not been copied
9267dc86dfdSMatthias Ringwald *
9277dc86dfdSMatthias Ringwald *  Notes
9287dc86dfdSMatthias Ringwald *    (1) If there is not enough space in the "Up"-buffer, all data is dropped.
9297dc86dfdSMatthias Ringwald *    (2) For performance reasons this function does not call Init()
9307dc86dfdSMatthias Ringwald *        and may only be called after RTT has been initialized.
9317dc86dfdSMatthias Ringwald *        Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
9327dc86dfdSMatthias Ringwald */
933779af47bSMatthias Ringwald #if (RTT_USE_ASM == 0)
SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex,const void * pBuffer,unsigned NumBytes)9347dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
9357dc86dfdSMatthias Ringwald   const char*           pData;
9367dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
9377dc86dfdSMatthias Ringwald   unsigned              Avail;
9387dc86dfdSMatthias Ringwald   unsigned              RdOff;
9397dc86dfdSMatthias Ringwald   unsigned              WrOff;
9407dc86dfdSMatthias Ringwald   unsigned              Rem;
941*ce6f85e7SMatthias Ringwald   volatile char*        pDst;
942779af47bSMatthias Ringwald   //
943779af47bSMatthias Ringwald   // Cases:
944779af47bSMatthias Ringwald   //   1) RdOff <= WrOff => Space until wrap-around is sufficient
945779af47bSMatthias Ringwald   //   2) RdOff <= WrOff => Space after wrap-around needed (copy in 2 chunks)
946779af47bSMatthias Ringwald   //   3) RdOff <  WrOff => No space in buf
947779af47bSMatthias Ringwald   //   4) RdOff >  WrOff => Space is sufficient
948779af47bSMatthias Ringwald   //   5) RdOff >  WrOff => No space in buf
949779af47bSMatthias Ringwald   //
950779af47bSMatthias Ringwald   // 1) is the most common case for large buffers and assuming that J-Link reads the data fast enough
951779af47bSMatthias Ringwald   //
9527dc86dfdSMatthias Ringwald   pData = (const char *)pBuffer;
953*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
9547dc86dfdSMatthias Ringwald   RdOff = pRing->RdOff;
9557dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff;
956*ce6f85e7SMatthias Ringwald   pDst = (pRing->pBuffer + WrOff) + SEGGER_RTT_UNCACHED_OFF;
957779af47bSMatthias Ringwald   if (RdOff <= WrOff) {                                 // Case 1), 2) or 3)
958779af47bSMatthias Ringwald     Avail = pRing->SizeOfBuffer - WrOff - 1u;           // Space until wrap-around (assume 1 byte not usable for case that RdOff == 0)
959779af47bSMatthias Ringwald     if (Avail >= NumBytes) {                            // Case 1)?
960*ce6f85e7SMatthias Ringwald       memcpy((void*)pDst, pData, NumBytes);
961*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
9627dc86dfdSMatthias Ringwald       pRing->WrOff = WrOff + NumBytes;
9637dc86dfdSMatthias Ringwald       return 1;
9647dc86dfdSMatthias Ringwald     }
965779af47bSMatthias Ringwald     Avail += RdOff;                                     // Space incl. wrap-around
966779af47bSMatthias Ringwald     if (Avail >= NumBytes) {                            // Case 2? => If not, we have case 3) (does not fit)
9677dc86dfdSMatthias Ringwald       Rem = pRing->SizeOfBuffer - WrOff;                // Space until end of buffer
968*ce6f85e7SMatthias Ringwald       memcpy((void*)pDst, pData, Rem);                  // Copy 1st chunk
9697dc86dfdSMatthias Ringwald       NumBytes -= Rem;
970779af47bSMatthias Ringwald       //
971779af47bSMatthias Ringwald       // Special case: First check that assumed RdOff == 0 calculated that last element before wrap-around could not be used
972779af47bSMatthias Ringwald       // But 2nd check (considering space until wrap-around and until RdOff) revealed that RdOff is not 0, so we can use the last element
973779af47bSMatthias Ringwald       // In this case, we may use a copy straight until buffer end anyway without needing to copy 2 chunks
974779af47bSMatthias Ringwald       // Therefore, check if 2nd memcpy is necessary at all
975779af47bSMatthias Ringwald       //
976779af47bSMatthias Ringwald       if (NumBytes) {
977*ce6f85e7SMatthias Ringwald         pDst = pRing->pBuffer + SEGGER_RTT_UNCACHED_OFF;
978*ce6f85e7SMatthias Ringwald         memcpy((void*)pDst, pData + Rem, NumBytes);
9797dc86dfdSMatthias Ringwald       }
980*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
981779af47bSMatthias Ringwald       pRing->WrOff = NumBytes;
9827dc86dfdSMatthias Ringwald       return 1;
9837dc86dfdSMatthias Ringwald     }
984779af47bSMatthias Ringwald   } else {                                             // Potential case 4)
9857dc86dfdSMatthias Ringwald     Avail = RdOff - WrOff - 1u;
986779af47bSMatthias Ringwald     if (Avail >= NumBytes) {                           // Case 4)? => If not, we have case 5) (does not fit)
987*ce6f85e7SMatthias Ringwald       memcpy((void*)pDst, pData, NumBytes);
988*ce6f85e7SMatthias Ringwald       RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
989*ce6f85e7SMatthias Ringwald       pRing->WrOff = WrOff + NumBytes;
990*ce6f85e7SMatthias Ringwald       return 1;
991779af47bSMatthias Ringwald     }
992779af47bSMatthias Ringwald   }
993779af47bSMatthias Ringwald   return 0;     // No space in buffer
994779af47bSMatthias Ringwald }
9957dc86dfdSMatthias Ringwald #endif
9967dc86dfdSMatthias Ringwald 
9977dc86dfdSMatthias Ringwald /*********************************************************************
9987dc86dfdSMatthias Ringwald *
999*ce6f85e7SMatthias Ringwald *       SEGGER_RTT_WriteDownBufferNoLock
10007dc86dfdSMatthias Ringwald *
10017dc86dfdSMatthias Ringwald *  Function description
10027dc86dfdSMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT
1003*ce6f85e7SMatthias Ringwald *    control block inside a <Down> buffer.
1004*ce6f85e7SMatthias Ringwald *    SEGGER_RTT_WriteDownBufferNoLock does not lock the application.
1005*ce6f85e7SMatthias Ringwald *    Used to do the same operation that J-Link does, to transfer
1006*ce6f85e7SMatthias Ringwald *    RTT data from other channels, such as TCP/IP or UART.
10077dc86dfdSMatthias Ringwald *
10087dc86dfdSMatthias Ringwald *  Parameters
1009*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of "Down"-buffer to be used.
10107dc86dfdSMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
10117dc86dfdSMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
10127dc86dfdSMatthias Ringwald *
10137dc86dfdSMatthias Ringwald *  Return value
1014*ce6f85e7SMatthias Ringwald *    Number of bytes which have been stored in the "Down"-buffer.
10157dc86dfdSMatthias Ringwald *
10167dc86dfdSMatthias Ringwald *  Notes
10177dc86dfdSMatthias Ringwald *    (1) Data is stored according to buffer flags.
10187dc86dfdSMatthias Ringwald *    (2) For performance reasons this function does not call Init()
10197dc86dfdSMatthias Ringwald *        and may only be called after RTT has been initialized.
10207dc86dfdSMatthias Ringwald *        Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
1021*ce6f85e7SMatthias Ringwald *
1022*ce6f85e7SMatthias Ringwald *  Additional information
1023*ce6f85e7SMatthias Ringwald *    This function must not be called when J-Link might also do RTT.
10247dc86dfdSMatthias Ringwald */
SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex,const void * pBuffer,unsigned NumBytes)1025*ce6f85e7SMatthias Ringwald unsigned SEGGER_RTT_WriteDownBufferNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
10267dc86dfdSMatthias Ringwald   unsigned                Status;
10277dc86dfdSMatthias Ringwald   unsigned                Avail;
10287dc86dfdSMatthias Ringwald   const char*             pData;
10297dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP*   pRing;
1030*ce6f85e7SMatthias Ringwald   //
1031*ce6f85e7SMatthias Ringwald   // Get "to-target" ring buffer.
1032*ce6f85e7SMatthias Ringwald   // It is save to cast that to a "to-host" buffer. Up and Down buffer differ in volatility of offsets that might be modified by J-Link.
1033*ce6f85e7SMatthias Ringwald   //
10347dc86dfdSMatthias Ringwald   pData = (const char *)pBuffer;
1035*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
10367dc86dfdSMatthias Ringwald   //
10377dc86dfdSMatthias Ringwald   // How we output depends upon the mode...
10387dc86dfdSMatthias Ringwald   //
10397dc86dfdSMatthias Ringwald   switch (pRing->Flags) {
10407dc86dfdSMatthias Ringwald   case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
10417dc86dfdSMatthias Ringwald     //
10427dc86dfdSMatthias Ringwald     // If we are in skip mode and there is no space for the whole
10437dc86dfdSMatthias Ringwald     // of this output, don't bother.
10447dc86dfdSMatthias Ringwald     //
10457dc86dfdSMatthias Ringwald     Avail = _GetAvailWriteSpace(pRing);
10467dc86dfdSMatthias Ringwald     if (Avail < NumBytes) {
10477dc86dfdSMatthias Ringwald       Status = 0u;
10487dc86dfdSMatthias Ringwald     } else {
10497dc86dfdSMatthias Ringwald       Status = NumBytes;
10507dc86dfdSMatthias Ringwald       _WriteNoCheck(pRing, pData, NumBytes);
10517dc86dfdSMatthias Ringwald     }
10527dc86dfdSMatthias Ringwald     break;
10537dc86dfdSMatthias Ringwald   case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
10547dc86dfdSMatthias Ringwald     //
10557dc86dfdSMatthias Ringwald     // If we are in trim mode, trim to what we can output without blocking.
10567dc86dfdSMatthias Ringwald     //
10577dc86dfdSMatthias Ringwald     Avail = _GetAvailWriteSpace(pRing);
10587dc86dfdSMatthias Ringwald     Status = Avail < NumBytes ? Avail : NumBytes;
10597dc86dfdSMatthias Ringwald     _WriteNoCheck(pRing, pData, Status);
10607dc86dfdSMatthias Ringwald     break;
10617dc86dfdSMatthias Ringwald   case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
10627dc86dfdSMatthias Ringwald     //
10637dc86dfdSMatthias Ringwald     // If we are in blocking mode, output everything.
10647dc86dfdSMatthias Ringwald     //
10657dc86dfdSMatthias Ringwald     Status = _WriteBlocking(pRing, pData, NumBytes);
10667dc86dfdSMatthias Ringwald     break;
10677dc86dfdSMatthias Ringwald   default:
10687dc86dfdSMatthias Ringwald     Status = 0u;
10697dc86dfdSMatthias Ringwald     break;
10707dc86dfdSMatthias Ringwald   }
10717dc86dfdSMatthias Ringwald   //
10727dc86dfdSMatthias Ringwald   // Finish up.
10737dc86dfdSMatthias Ringwald   //
10747dc86dfdSMatthias Ringwald   return Status;
10757dc86dfdSMatthias Ringwald }
10767dc86dfdSMatthias Ringwald 
10777dc86dfdSMatthias Ringwald /*********************************************************************
10787dc86dfdSMatthias Ringwald *
1079*ce6f85e7SMatthias Ringwald *       SEGGER_RTT_WriteNoLock
1080*ce6f85e7SMatthias Ringwald *
1081*ce6f85e7SMatthias Ringwald *  Function description
1082*ce6f85e7SMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT
1083*ce6f85e7SMatthias Ringwald *    control block which is then read by the host.
1084*ce6f85e7SMatthias Ringwald *    SEGGER_RTT_WriteNoLock does not lock the application.
1085*ce6f85e7SMatthias Ringwald *
1086*ce6f85e7SMatthias Ringwald *  Parameters
1087*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1088*ce6f85e7SMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
1089*ce6f85e7SMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
1090*ce6f85e7SMatthias Ringwald *
1091*ce6f85e7SMatthias Ringwald *  Return value
1092*ce6f85e7SMatthias Ringwald *    Number of bytes which have been stored in the "Up"-buffer.
1093*ce6f85e7SMatthias Ringwald *
1094*ce6f85e7SMatthias Ringwald *  Notes
1095*ce6f85e7SMatthias Ringwald *    (1) Data is stored according to buffer flags.
1096*ce6f85e7SMatthias Ringwald *    (2) For performance reasons this function does not call Init()
1097*ce6f85e7SMatthias Ringwald *        and may only be called after RTT has been initialized.
1098*ce6f85e7SMatthias Ringwald *        Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
1099*ce6f85e7SMatthias Ringwald */
SEGGER_RTT_WriteNoLock(unsigned BufferIndex,const void * pBuffer,unsigned NumBytes)1100*ce6f85e7SMatthias Ringwald unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
1101*ce6f85e7SMatthias Ringwald   unsigned              Status;
1102*ce6f85e7SMatthias Ringwald   unsigned              Avail;
1103*ce6f85e7SMatthias Ringwald   const char*           pData;
1104*ce6f85e7SMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
1105*ce6f85e7SMatthias Ringwald   //
1106*ce6f85e7SMatthias Ringwald   // Get "to-host" ring buffer.
1107*ce6f85e7SMatthias Ringwald   //
1108*ce6f85e7SMatthias Ringwald   pData = (const char *)pBuffer;
1109*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1110*ce6f85e7SMatthias Ringwald   //
1111*ce6f85e7SMatthias Ringwald   // How we output depends upon the mode...
1112*ce6f85e7SMatthias Ringwald   //
1113*ce6f85e7SMatthias Ringwald   switch (pRing->Flags) {
1114*ce6f85e7SMatthias Ringwald   case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
1115*ce6f85e7SMatthias Ringwald     //
1116*ce6f85e7SMatthias Ringwald     // If we are in skip mode and there is no space for the whole
1117*ce6f85e7SMatthias Ringwald     // of this output, don't bother.
1118*ce6f85e7SMatthias Ringwald     //
1119*ce6f85e7SMatthias Ringwald     Avail = _GetAvailWriteSpace(pRing);
1120*ce6f85e7SMatthias Ringwald     if (Avail < NumBytes) {
1121*ce6f85e7SMatthias Ringwald       Status = 0u;
1122*ce6f85e7SMatthias Ringwald     } else {
1123*ce6f85e7SMatthias Ringwald       Status = NumBytes;
1124*ce6f85e7SMatthias Ringwald       _WriteNoCheck(pRing, pData, NumBytes);
1125*ce6f85e7SMatthias Ringwald     }
1126*ce6f85e7SMatthias Ringwald     break;
1127*ce6f85e7SMatthias Ringwald   case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
1128*ce6f85e7SMatthias Ringwald     //
1129*ce6f85e7SMatthias Ringwald     // If we are in trim mode, trim to what we can output without blocking.
1130*ce6f85e7SMatthias Ringwald     //
1131*ce6f85e7SMatthias Ringwald     Avail = _GetAvailWriteSpace(pRing);
1132*ce6f85e7SMatthias Ringwald     Status = Avail < NumBytes ? Avail : NumBytes;
1133*ce6f85e7SMatthias Ringwald     _WriteNoCheck(pRing, pData, Status);
1134*ce6f85e7SMatthias Ringwald     break;
1135*ce6f85e7SMatthias Ringwald   case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
1136*ce6f85e7SMatthias Ringwald     //
1137*ce6f85e7SMatthias Ringwald     // If we are in blocking mode, output everything.
1138*ce6f85e7SMatthias Ringwald     //
1139*ce6f85e7SMatthias Ringwald     Status = _WriteBlocking(pRing, pData, NumBytes);
1140*ce6f85e7SMatthias Ringwald     break;
1141*ce6f85e7SMatthias Ringwald   default:
1142*ce6f85e7SMatthias Ringwald     Status = 0u;
1143*ce6f85e7SMatthias Ringwald     break;
1144*ce6f85e7SMatthias Ringwald   }
1145*ce6f85e7SMatthias Ringwald   //
1146*ce6f85e7SMatthias Ringwald   // Finish up.
1147*ce6f85e7SMatthias Ringwald   //
1148*ce6f85e7SMatthias Ringwald   return Status;
1149*ce6f85e7SMatthias Ringwald }
1150*ce6f85e7SMatthias Ringwald 
1151*ce6f85e7SMatthias Ringwald /*********************************************************************
1152*ce6f85e7SMatthias Ringwald *
1153*ce6f85e7SMatthias Ringwald *       SEGGER_RTT_WriteDownBuffer
1154*ce6f85e7SMatthias Ringwald *
1155*ce6f85e7SMatthias Ringwald *  Function description
1156*ce6f85e7SMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT control block in a <Down> buffer.
1157*ce6f85e7SMatthias Ringwald *
1158*ce6f85e7SMatthias Ringwald *  Parameters
1159*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
1160*ce6f85e7SMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
1161*ce6f85e7SMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
1162*ce6f85e7SMatthias Ringwald *
1163*ce6f85e7SMatthias Ringwald *  Return value
1164*ce6f85e7SMatthias Ringwald *    Number of bytes which have been stored in the "Down"-buffer.
1165*ce6f85e7SMatthias Ringwald *
1166*ce6f85e7SMatthias Ringwald *  Notes
1167*ce6f85e7SMatthias Ringwald *    (1) Data is stored according to buffer flags.
1168*ce6f85e7SMatthias Ringwald *
1169*ce6f85e7SMatthias Ringwald *  Additional information
1170*ce6f85e7SMatthias Ringwald *    This function must not be called when J-Link might also do RTT.
1171*ce6f85e7SMatthias Ringwald *    This function locks against all other RTT operations. I.e. during
1172*ce6f85e7SMatthias Ringwald *    the write operation, writing from the application is also locked.
1173*ce6f85e7SMatthias Ringwald *    If only one consumer writes to the down buffer,
1174*ce6f85e7SMatthias Ringwald *    call SEGGER_RTT_WriteDownBufferNoLock() instead.
1175*ce6f85e7SMatthias Ringwald */
SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex,const void * pBuffer,unsigned NumBytes)1176*ce6f85e7SMatthias Ringwald unsigned SEGGER_RTT_WriteDownBuffer(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
1177*ce6f85e7SMatthias Ringwald   unsigned Status;
1178*ce6f85e7SMatthias Ringwald 
1179*ce6f85e7SMatthias Ringwald   INIT();
1180*ce6f85e7SMatthias Ringwald   SEGGER_RTT_LOCK();
1181*ce6f85e7SMatthias Ringwald   Status = SEGGER_RTT_WriteDownBufferNoLock(BufferIndex, pBuffer, NumBytes);  // Call the non-locking write function
1182*ce6f85e7SMatthias Ringwald   SEGGER_RTT_UNLOCK();
1183*ce6f85e7SMatthias Ringwald   return Status;
1184*ce6f85e7SMatthias Ringwald }
1185*ce6f85e7SMatthias Ringwald 
1186*ce6f85e7SMatthias Ringwald /*********************************************************************
1187*ce6f85e7SMatthias Ringwald *
11887dc86dfdSMatthias Ringwald *       SEGGER_RTT_Write
11897dc86dfdSMatthias Ringwald *
11907dc86dfdSMatthias Ringwald *  Function description
11917dc86dfdSMatthias Ringwald *    Stores a specified number of characters in SEGGER RTT
11927dc86dfdSMatthias Ringwald *    control block which is then read by the host.
11937dc86dfdSMatthias Ringwald *
11947dc86dfdSMatthias Ringwald *  Parameters
11957dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
11967dc86dfdSMatthias Ringwald *    pBuffer      Pointer to character array. Does not need to point to a \0 terminated string.
11977dc86dfdSMatthias Ringwald *    NumBytes     Number of bytes to be stored in the SEGGER RTT control block.
11987dc86dfdSMatthias Ringwald *
11997dc86dfdSMatthias Ringwald *  Return value
12007dc86dfdSMatthias Ringwald *    Number of bytes which have been stored in the "Up"-buffer.
12017dc86dfdSMatthias Ringwald *
12027dc86dfdSMatthias Ringwald *  Notes
12037dc86dfdSMatthias Ringwald *    (1) Data is stored according to buffer flags.
12047dc86dfdSMatthias Ringwald */
SEGGER_RTT_Write(unsigned BufferIndex,const void * pBuffer,unsigned NumBytes)12057dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
12067dc86dfdSMatthias Ringwald   unsigned Status;
1207*ce6f85e7SMatthias Ringwald 
12087dc86dfdSMatthias Ringwald   INIT();
12097dc86dfdSMatthias Ringwald   SEGGER_RTT_LOCK();
1210*ce6f85e7SMatthias Ringwald   Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes);  // Call the non-locking write function
12117dc86dfdSMatthias Ringwald   SEGGER_RTT_UNLOCK();
12127dc86dfdSMatthias Ringwald   return Status;
12137dc86dfdSMatthias Ringwald }
12147dc86dfdSMatthias Ringwald 
12157dc86dfdSMatthias Ringwald /*********************************************************************
12167dc86dfdSMatthias Ringwald *
12177dc86dfdSMatthias Ringwald *       SEGGER_RTT_WriteString
12187dc86dfdSMatthias Ringwald *
12197dc86dfdSMatthias Ringwald *  Function description
12207dc86dfdSMatthias Ringwald *    Stores string in SEGGER RTT control block.
12217dc86dfdSMatthias Ringwald *    This data is read by the host.
12227dc86dfdSMatthias Ringwald *
12237dc86dfdSMatthias Ringwald *  Parameters
12247dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
12257dc86dfdSMatthias Ringwald *    s            Pointer to string.
12267dc86dfdSMatthias Ringwald *
12277dc86dfdSMatthias Ringwald *  Return value
12287dc86dfdSMatthias Ringwald *    Number of bytes which have been stored in the "Up"-buffer.
12297dc86dfdSMatthias Ringwald *
12307dc86dfdSMatthias Ringwald *  Notes
12317dc86dfdSMatthias Ringwald *    (1) Data is stored according to buffer flags.
12327dc86dfdSMatthias Ringwald *    (2) String passed to this function has to be \0 terminated
12337dc86dfdSMatthias Ringwald *    (3) \0 termination character is *not* stored in RTT buffer
12347dc86dfdSMatthias Ringwald */
SEGGER_RTT_WriteString(unsigned BufferIndex,const char * s)12357dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
12367dc86dfdSMatthias Ringwald   unsigned Len;
12377dc86dfdSMatthias Ringwald 
12387dc86dfdSMatthias Ringwald   Len = STRLEN(s);
12397dc86dfdSMatthias Ringwald   return SEGGER_RTT_Write(BufferIndex, s, Len);
12407dc86dfdSMatthias Ringwald }
12417dc86dfdSMatthias Ringwald 
12427dc86dfdSMatthias Ringwald /*********************************************************************
12437dc86dfdSMatthias Ringwald *
12447dc86dfdSMatthias Ringwald *       SEGGER_RTT_PutCharSkipNoLock
12457dc86dfdSMatthias Ringwald *
12467dc86dfdSMatthias Ringwald *  Function description
12477dc86dfdSMatthias Ringwald *    Stores a single character/byte in SEGGER RTT buffer.
12487dc86dfdSMatthias Ringwald *    SEGGER_RTT_PutCharSkipNoLock does not lock the application and
12497dc86dfdSMatthias Ringwald *    skips the byte, if it does not fit into the buffer.
12507dc86dfdSMatthias Ringwald *
12517dc86dfdSMatthias Ringwald *  Parameters
12527dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
12537dc86dfdSMatthias Ringwald *    c            Byte to be stored.
12547dc86dfdSMatthias Ringwald *
12557dc86dfdSMatthias Ringwald *  Return value
12567dc86dfdSMatthias Ringwald *    Number of bytes which have been stored in the "Up"-buffer.
12577dc86dfdSMatthias Ringwald *
12587dc86dfdSMatthias Ringwald *  Notes
12597dc86dfdSMatthias Ringwald *    (1) If there is not enough space in the "Up"-buffer, the character is dropped.
12607dc86dfdSMatthias Ringwald *    (2) For performance reasons this function does not call Init()
12617dc86dfdSMatthias Ringwald *        and may only be called after RTT has been initialized.
12627dc86dfdSMatthias Ringwald *        Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
12637dc86dfdSMatthias Ringwald */
12647dc86dfdSMatthias Ringwald 
SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex,char c)12657dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) {
12667dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
12677dc86dfdSMatthias Ringwald   unsigned              WrOff;
12687dc86dfdSMatthias Ringwald   unsigned              Status;
1269*ce6f85e7SMatthias Ringwald   volatile char*        pDst;
12707dc86dfdSMatthias Ringwald   //
12717dc86dfdSMatthias Ringwald   // Get "to-host" ring buffer.
12727dc86dfdSMatthias Ringwald   //
1273*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
12747dc86dfdSMatthias Ringwald   //
12757dc86dfdSMatthias Ringwald   // Get write position and handle wrap-around if necessary
12767dc86dfdSMatthias Ringwald   //
12777dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff + 1;
12787dc86dfdSMatthias Ringwald   if (WrOff == pRing->SizeOfBuffer) {
12797dc86dfdSMatthias Ringwald     WrOff = 0;
12807dc86dfdSMatthias Ringwald   }
12817dc86dfdSMatthias Ringwald   //
12827dc86dfdSMatthias Ringwald   // Output byte if free space is available
12837dc86dfdSMatthias Ringwald   //
12847dc86dfdSMatthias Ringwald   if (WrOff != pRing->RdOff) {
1285*ce6f85e7SMatthias Ringwald     pDst = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
1286*ce6f85e7SMatthias Ringwald     *pDst = c;
1287*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
12887dc86dfdSMatthias Ringwald     pRing->WrOff = WrOff;
12897dc86dfdSMatthias Ringwald     Status = 1;
12907dc86dfdSMatthias Ringwald   } else {
12917dc86dfdSMatthias Ringwald     Status = 0;
12927dc86dfdSMatthias Ringwald   }
12937dc86dfdSMatthias Ringwald   //
12947dc86dfdSMatthias Ringwald   return Status;
12957dc86dfdSMatthias Ringwald }
12967dc86dfdSMatthias Ringwald 
12977dc86dfdSMatthias Ringwald /*********************************************************************
12987dc86dfdSMatthias Ringwald *
12997dc86dfdSMatthias Ringwald *       SEGGER_RTT_PutCharSkip
13007dc86dfdSMatthias Ringwald *
13017dc86dfdSMatthias Ringwald *  Function description
13027dc86dfdSMatthias Ringwald *    Stores a single character/byte in SEGGER RTT buffer.
13037dc86dfdSMatthias Ringwald *
13047dc86dfdSMatthias Ringwald *  Parameters
13057dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
13067dc86dfdSMatthias Ringwald *    c            Byte to be stored.
13077dc86dfdSMatthias Ringwald *
13087dc86dfdSMatthias Ringwald *  Return value
13097dc86dfdSMatthias Ringwald *    Number of bytes which have been stored in the "Up"-buffer.
13107dc86dfdSMatthias Ringwald *
13117dc86dfdSMatthias Ringwald *  Notes
13127dc86dfdSMatthias Ringwald *    (1) If there is not enough space in the "Up"-buffer, the character is dropped.
13137dc86dfdSMatthias Ringwald */
13147dc86dfdSMatthias Ringwald 
SEGGER_RTT_PutCharSkip(unsigned BufferIndex,char c)13157dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) {
13167dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
13177dc86dfdSMatthias Ringwald   unsigned              WrOff;
13187dc86dfdSMatthias Ringwald   unsigned              Status;
1319*ce6f85e7SMatthias Ringwald   volatile char*        pDst;
13207dc86dfdSMatthias Ringwald   //
13217dc86dfdSMatthias Ringwald   // Prepare
13227dc86dfdSMatthias Ringwald   //
13237dc86dfdSMatthias Ringwald   INIT();
13247dc86dfdSMatthias Ringwald   SEGGER_RTT_LOCK();
13257dc86dfdSMatthias Ringwald   //
13267dc86dfdSMatthias Ringwald   // Get "to-host" ring buffer.
13277dc86dfdSMatthias Ringwald   //
1328*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
13297dc86dfdSMatthias Ringwald   //
13307dc86dfdSMatthias Ringwald   // Get write position and handle wrap-around if necessary
13317dc86dfdSMatthias Ringwald   //
13327dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff + 1;
13337dc86dfdSMatthias Ringwald   if (WrOff == pRing->SizeOfBuffer) {
13347dc86dfdSMatthias Ringwald     WrOff = 0;
13357dc86dfdSMatthias Ringwald   }
13367dc86dfdSMatthias Ringwald   //
13377dc86dfdSMatthias Ringwald   // Output byte if free space is available
13387dc86dfdSMatthias Ringwald   //
13397dc86dfdSMatthias Ringwald   if (WrOff != pRing->RdOff) {
1340*ce6f85e7SMatthias Ringwald     pDst  = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
1341*ce6f85e7SMatthias Ringwald     *pDst = c;
1342*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
13437dc86dfdSMatthias Ringwald     pRing->WrOff = WrOff;
13447dc86dfdSMatthias Ringwald     Status = 1;
13457dc86dfdSMatthias Ringwald   } else {
13467dc86dfdSMatthias Ringwald     Status = 0;
13477dc86dfdSMatthias Ringwald   }
13487dc86dfdSMatthias Ringwald   //
13497dc86dfdSMatthias Ringwald   // Finish up.
13507dc86dfdSMatthias Ringwald   //
13517dc86dfdSMatthias Ringwald   SEGGER_RTT_UNLOCK();
13527dc86dfdSMatthias Ringwald   //
13537dc86dfdSMatthias Ringwald   return Status;
13547dc86dfdSMatthias Ringwald }
13557dc86dfdSMatthias Ringwald 
13567dc86dfdSMatthias Ringwald  /*********************************************************************
13577dc86dfdSMatthias Ringwald *
13587dc86dfdSMatthias Ringwald *       SEGGER_RTT_PutChar
13597dc86dfdSMatthias Ringwald *
13607dc86dfdSMatthias Ringwald *  Function description
13617dc86dfdSMatthias Ringwald *    Stores a single character/byte in SEGGER RTT buffer.
13627dc86dfdSMatthias Ringwald *
13637dc86dfdSMatthias Ringwald *  Parameters
13647dc86dfdSMatthias Ringwald *    BufferIndex  Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
13657dc86dfdSMatthias Ringwald *    c            Byte to be stored.
13667dc86dfdSMatthias Ringwald *
13677dc86dfdSMatthias Ringwald *  Return value
13687dc86dfdSMatthias Ringwald *    Number of bytes which have been stored in the "Up"-buffer.
13697dc86dfdSMatthias Ringwald *
13707dc86dfdSMatthias Ringwald *  Notes
13717dc86dfdSMatthias Ringwald *    (1) Data is stored according to buffer flags.
13727dc86dfdSMatthias Ringwald */
13737dc86dfdSMatthias Ringwald 
SEGGER_RTT_PutChar(unsigned BufferIndex,char c)13747dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) {
13757dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
13767dc86dfdSMatthias Ringwald   unsigned              WrOff;
13777dc86dfdSMatthias Ringwald   unsigned              Status;
1378*ce6f85e7SMatthias Ringwald   volatile char*        pDst;
13797dc86dfdSMatthias Ringwald   //
13807dc86dfdSMatthias Ringwald   // Prepare
13817dc86dfdSMatthias Ringwald   //
13827dc86dfdSMatthias Ringwald   INIT();
13837dc86dfdSMatthias Ringwald   SEGGER_RTT_LOCK();
13847dc86dfdSMatthias Ringwald   //
13857dc86dfdSMatthias Ringwald   // Get "to-host" ring buffer.
13867dc86dfdSMatthias Ringwald   //
1387*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
13887dc86dfdSMatthias Ringwald   //
13897dc86dfdSMatthias Ringwald   // Get write position and handle wrap-around if necessary
13907dc86dfdSMatthias Ringwald   //
13917dc86dfdSMatthias Ringwald   WrOff = pRing->WrOff + 1;
13927dc86dfdSMatthias Ringwald   if (WrOff == pRing->SizeOfBuffer) {
13937dc86dfdSMatthias Ringwald     WrOff = 0;
13947dc86dfdSMatthias Ringwald   }
13957dc86dfdSMatthias Ringwald   //
13967dc86dfdSMatthias Ringwald   // Wait for free space if mode is set to blocking
13977dc86dfdSMatthias Ringwald   //
13987dc86dfdSMatthias Ringwald   if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
13997dc86dfdSMatthias Ringwald     while (WrOff == pRing->RdOff) {
14007dc86dfdSMatthias Ringwald       ;
14017dc86dfdSMatthias Ringwald     }
14027dc86dfdSMatthias Ringwald   }
14037dc86dfdSMatthias Ringwald   //
14047dc86dfdSMatthias Ringwald   // Output byte if free space is available
14057dc86dfdSMatthias Ringwald   //
14067dc86dfdSMatthias Ringwald   if (WrOff != pRing->RdOff) {
1407*ce6f85e7SMatthias Ringwald     pDst  = (pRing->pBuffer + pRing->WrOff) + SEGGER_RTT_UNCACHED_OFF;
1408*ce6f85e7SMatthias Ringwald     *pDst = c;
1409*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
14107dc86dfdSMatthias Ringwald     pRing->WrOff = WrOff;
14117dc86dfdSMatthias Ringwald     Status = 1;
14127dc86dfdSMatthias Ringwald   } else {
14137dc86dfdSMatthias Ringwald     Status = 0;
14147dc86dfdSMatthias Ringwald   }
14157dc86dfdSMatthias Ringwald   //
14167dc86dfdSMatthias Ringwald   // Finish up.
14177dc86dfdSMatthias Ringwald   //
14187dc86dfdSMatthias Ringwald   SEGGER_RTT_UNLOCK();
14197dc86dfdSMatthias Ringwald   return Status;
14207dc86dfdSMatthias Ringwald }
14217dc86dfdSMatthias Ringwald 
14227dc86dfdSMatthias Ringwald /*********************************************************************
14237dc86dfdSMatthias Ringwald *
14247dc86dfdSMatthias Ringwald *       SEGGER_RTT_GetKey
14257dc86dfdSMatthias Ringwald *
14267dc86dfdSMatthias Ringwald *  Function description
14277dc86dfdSMatthias Ringwald *    Reads one character from the SEGGER RTT buffer.
14287dc86dfdSMatthias Ringwald *    Host has previously stored data there.
14297dc86dfdSMatthias Ringwald *
14307dc86dfdSMatthias Ringwald *  Return value
14317dc86dfdSMatthias Ringwald *    <  0 -   No character available (buffer empty).
14327dc86dfdSMatthias Ringwald *    >= 0 -   Character which has been read. (Possible values: 0 - 255)
14337dc86dfdSMatthias Ringwald *
14347dc86dfdSMatthias Ringwald *  Notes
14357dc86dfdSMatthias Ringwald *    (1) This function is only specified for accesses to RTT buffer 0.
14367dc86dfdSMatthias Ringwald */
SEGGER_RTT_GetKey(void)14377dc86dfdSMatthias Ringwald int SEGGER_RTT_GetKey(void) {
14387dc86dfdSMatthias Ringwald   char c;
14397dc86dfdSMatthias Ringwald   int r;
14407dc86dfdSMatthias Ringwald 
14417dc86dfdSMatthias Ringwald   r = (int)SEGGER_RTT_Read(0u, &c, 1u);
14427dc86dfdSMatthias Ringwald   if (r == 1) {
14437dc86dfdSMatthias Ringwald     r = (int)(unsigned char)c;
14447dc86dfdSMatthias Ringwald   } else {
14457dc86dfdSMatthias Ringwald     r = -1;
14467dc86dfdSMatthias Ringwald   }
14477dc86dfdSMatthias Ringwald   return r;
14487dc86dfdSMatthias Ringwald }
14497dc86dfdSMatthias Ringwald 
14507dc86dfdSMatthias Ringwald /*********************************************************************
14517dc86dfdSMatthias Ringwald *
14527dc86dfdSMatthias Ringwald *       SEGGER_RTT_WaitKey
14537dc86dfdSMatthias Ringwald *
14547dc86dfdSMatthias Ringwald *  Function description
14557dc86dfdSMatthias Ringwald *    Waits until at least one character is avaible in the SEGGER RTT buffer.
14567dc86dfdSMatthias Ringwald *    Once a character is available, it is read and this function returns.
14577dc86dfdSMatthias Ringwald *
14587dc86dfdSMatthias Ringwald *  Return value
14597dc86dfdSMatthias Ringwald *    >=0 -   Character which has been read.
14607dc86dfdSMatthias Ringwald *
14617dc86dfdSMatthias Ringwald *  Notes
14627dc86dfdSMatthias Ringwald *    (1) This function is only specified for accesses to RTT buffer 0
14637dc86dfdSMatthias Ringwald *    (2) This function is blocking if no character is present in RTT buffer
14647dc86dfdSMatthias Ringwald */
SEGGER_RTT_WaitKey(void)14657dc86dfdSMatthias Ringwald int SEGGER_RTT_WaitKey(void) {
14667dc86dfdSMatthias Ringwald   int r;
14677dc86dfdSMatthias Ringwald 
14687dc86dfdSMatthias Ringwald   do {
14697dc86dfdSMatthias Ringwald     r = SEGGER_RTT_GetKey();
14707dc86dfdSMatthias Ringwald   } while (r < 0);
14717dc86dfdSMatthias Ringwald   return r;
14727dc86dfdSMatthias Ringwald }
14737dc86dfdSMatthias Ringwald 
14747dc86dfdSMatthias Ringwald /*********************************************************************
14757dc86dfdSMatthias Ringwald *
14767dc86dfdSMatthias Ringwald *       SEGGER_RTT_HasKey
14777dc86dfdSMatthias Ringwald *
14787dc86dfdSMatthias Ringwald *  Function description
14797dc86dfdSMatthias Ringwald *    Checks if at least one character for reading is available in the SEGGER RTT buffer.
14807dc86dfdSMatthias Ringwald *
14817dc86dfdSMatthias Ringwald *  Return value
14827dc86dfdSMatthias Ringwald *    == 0 -     No characters are available to read.
14837dc86dfdSMatthias Ringwald *    == 1 -     At least one character is available.
14847dc86dfdSMatthias Ringwald *
14857dc86dfdSMatthias Ringwald *  Notes
14867dc86dfdSMatthias Ringwald *    (1) This function is only specified for accesses to RTT buffer 0
14877dc86dfdSMatthias Ringwald */
SEGGER_RTT_HasKey(void)14887dc86dfdSMatthias Ringwald int SEGGER_RTT_HasKey(void) {
1489*ce6f85e7SMatthias Ringwald   SEGGER_RTT_BUFFER_DOWN* pRing;
14907dc86dfdSMatthias Ringwald   unsigned RdOff;
14917dc86dfdSMatthias Ringwald   int r;
14927dc86dfdSMatthias Ringwald 
14937dc86dfdSMatthias Ringwald   INIT();
1494*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[0] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1495*ce6f85e7SMatthias Ringwald   RdOff = pRing->RdOff;
1496*ce6f85e7SMatthias Ringwald   if (RdOff != pRing->WrOff) {
14977dc86dfdSMatthias Ringwald     r = 1;
14987dc86dfdSMatthias Ringwald   } else {
14997dc86dfdSMatthias Ringwald     r = 0;
15007dc86dfdSMatthias Ringwald   }
15017dc86dfdSMatthias Ringwald   return r;
15027dc86dfdSMatthias Ringwald }
15037dc86dfdSMatthias Ringwald 
15047dc86dfdSMatthias Ringwald /*********************************************************************
15057dc86dfdSMatthias Ringwald *
15067dc86dfdSMatthias Ringwald *       SEGGER_RTT_HasData
15077dc86dfdSMatthias Ringwald *
15087dc86dfdSMatthias Ringwald *  Function description
15097dc86dfdSMatthias Ringwald *    Check if there is data from the host in the given buffer.
15107dc86dfdSMatthias Ringwald *
15117dc86dfdSMatthias Ringwald *  Return value:
15127dc86dfdSMatthias Ringwald *  ==0:  No data
15137dc86dfdSMatthias Ringwald *  !=0:  Data in buffer
15147dc86dfdSMatthias Ringwald *
15157dc86dfdSMatthias Ringwald */
SEGGER_RTT_HasData(unsigned BufferIndex)15167dc86dfdSMatthias Ringwald unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
15177dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_DOWN* pRing;
15187dc86dfdSMatthias Ringwald   unsigned                v;
15197dc86dfdSMatthias Ringwald 
1520*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_DOWN*)((char*)&_SEGGER_RTT.aDown[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
15217dc86dfdSMatthias Ringwald   v = pRing->WrOff;
15227dc86dfdSMatthias Ringwald   return v - pRing->RdOff;
15237dc86dfdSMatthias Ringwald }
15247dc86dfdSMatthias Ringwald 
15257dc86dfdSMatthias Ringwald /*********************************************************************
15267dc86dfdSMatthias Ringwald *
1527779af47bSMatthias Ringwald *       SEGGER_RTT_HasDataUp
1528779af47bSMatthias Ringwald *
1529779af47bSMatthias Ringwald *  Function description
1530779af47bSMatthias Ringwald *    Check if there is data remaining to be sent in the given buffer.
1531779af47bSMatthias Ringwald *
1532779af47bSMatthias Ringwald *  Return value:
1533779af47bSMatthias Ringwald *  ==0:  No data
1534779af47bSMatthias Ringwald *  !=0:  Data in buffer
1535779af47bSMatthias Ringwald *
1536779af47bSMatthias Ringwald */
SEGGER_RTT_HasDataUp(unsigned BufferIndex)1537779af47bSMatthias Ringwald unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) {
1538779af47bSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
1539779af47bSMatthias Ringwald   unsigned                v;
1540779af47bSMatthias Ringwald 
1541*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1542779af47bSMatthias Ringwald   v = pRing->RdOff;
1543779af47bSMatthias Ringwald   return pRing->WrOff - v;
1544779af47bSMatthias Ringwald }
1545779af47bSMatthias Ringwald 
1546779af47bSMatthias Ringwald /*********************************************************************
1547779af47bSMatthias Ringwald *
15487dc86dfdSMatthias Ringwald *       SEGGER_RTT_AllocDownBuffer
15497dc86dfdSMatthias Ringwald *
15507dc86dfdSMatthias Ringwald *  Function description
15517dc86dfdSMatthias Ringwald *    Run-time configuration of the next down-buffer (H->T).
15527dc86dfdSMatthias Ringwald *    The next buffer, which is not used yet is configured.
15537dc86dfdSMatthias Ringwald *    This includes: Buffer address, size, name, flags, ...
15547dc86dfdSMatthias Ringwald *
15557dc86dfdSMatthias Ringwald *  Parameters
15567dc86dfdSMatthias Ringwald *    sName        Pointer to a constant name string.
15577dc86dfdSMatthias Ringwald *    pBuffer      Pointer to a buffer to be used.
15587dc86dfdSMatthias Ringwald *    BufferSize   Size of the buffer.
15597dc86dfdSMatthias Ringwald *    Flags        Operating modes. Define behavior if buffer is full (not enough space for entire message).
1560*ce6f85e7SMatthias Ringwald *                 Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
15617dc86dfdSMatthias Ringwald *
15627dc86dfdSMatthias Ringwald *  Return value
15637dc86dfdSMatthias Ringwald *    >= 0 - O.K. Buffer Index
15647dc86dfdSMatthias Ringwald *     < 0 - Error
15657dc86dfdSMatthias Ringwald */
SEGGER_RTT_AllocDownBuffer(const char * sName,void * pBuffer,unsigned BufferSize,unsigned Flags)15667dc86dfdSMatthias Ringwald int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
15677dc86dfdSMatthias Ringwald   int BufferIndex;
1568*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
15697dc86dfdSMatthias Ringwald 
15707dc86dfdSMatthias Ringwald   INIT();
15717dc86dfdSMatthias Ringwald   SEGGER_RTT_LOCK();
1572*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
15737dc86dfdSMatthias Ringwald   BufferIndex = 0;
15747dc86dfdSMatthias Ringwald   do {
1575*ce6f85e7SMatthias Ringwald     if (pRTTCB->aDown[BufferIndex].pBuffer == NULL) {
15767dc86dfdSMatthias Ringwald       break;
15777dc86dfdSMatthias Ringwald     }
15787dc86dfdSMatthias Ringwald     BufferIndex++;
1579*ce6f85e7SMatthias Ringwald   } while (BufferIndex < pRTTCB->MaxNumDownBuffers);
1580*ce6f85e7SMatthias Ringwald   if (BufferIndex < pRTTCB->MaxNumDownBuffers) {
1581*ce6f85e7SMatthias Ringwald     pRTTCB->aDown[BufferIndex].sName        = sName;
1582*ce6f85e7SMatthias Ringwald     pRTTCB->aDown[BufferIndex].pBuffer      = (char*)pBuffer;
1583*ce6f85e7SMatthias Ringwald     pRTTCB->aDown[BufferIndex].SizeOfBuffer = BufferSize;
1584*ce6f85e7SMatthias Ringwald     pRTTCB->aDown[BufferIndex].RdOff        = 0u;
1585*ce6f85e7SMatthias Ringwald     pRTTCB->aDown[BufferIndex].WrOff        = 0u;
1586*ce6f85e7SMatthias Ringwald     pRTTCB->aDown[BufferIndex].Flags        = Flags;
1587*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
15887dc86dfdSMatthias Ringwald   } else {
15897dc86dfdSMatthias Ringwald     BufferIndex = -1;
15907dc86dfdSMatthias Ringwald   }
15917dc86dfdSMatthias Ringwald   SEGGER_RTT_UNLOCK();
15927dc86dfdSMatthias Ringwald   return BufferIndex;
15937dc86dfdSMatthias Ringwald }
15947dc86dfdSMatthias Ringwald 
15957dc86dfdSMatthias Ringwald /*********************************************************************
15967dc86dfdSMatthias Ringwald *
15977dc86dfdSMatthias Ringwald *       SEGGER_RTT_AllocUpBuffer
15987dc86dfdSMatthias Ringwald *
15997dc86dfdSMatthias Ringwald *  Function description
16007dc86dfdSMatthias Ringwald *    Run-time configuration of the next up-buffer (T->H).
16017dc86dfdSMatthias Ringwald *    The next buffer, which is not used yet is configured.
16027dc86dfdSMatthias Ringwald *    This includes: Buffer address, size, name, flags, ...
16037dc86dfdSMatthias Ringwald *
16047dc86dfdSMatthias Ringwald *  Parameters
16057dc86dfdSMatthias Ringwald *    sName        Pointer to a constant name string.
16067dc86dfdSMatthias Ringwald *    pBuffer      Pointer to a buffer to be used.
16077dc86dfdSMatthias Ringwald *    BufferSize   Size of the buffer.
16087dc86dfdSMatthias Ringwald *    Flags        Operating modes. Define behavior if buffer is full (not enough space for entire message).
1609*ce6f85e7SMatthias Ringwald *                 Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
16107dc86dfdSMatthias Ringwald *
16117dc86dfdSMatthias Ringwald *  Return value
16127dc86dfdSMatthias Ringwald *    >= 0 - O.K. Buffer Index
16137dc86dfdSMatthias Ringwald *     < 0 - Error
16147dc86dfdSMatthias Ringwald */
SEGGER_RTT_AllocUpBuffer(const char * sName,void * pBuffer,unsigned BufferSize,unsigned Flags)16157dc86dfdSMatthias Ringwald int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
16167dc86dfdSMatthias Ringwald   int BufferIndex;
1617*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
16187dc86dfdSMatthias Ringwald 
16197dc86dfdSMatthias Ringwald   INIT();
16207dc86dfdSMatthias Ringwald   SEGGER_RTT_LOCK();
1621*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
16227dc86dfdSMatthias Ringwald   BufferIndex = 0;
16237dc86dfdSMatthias Ringwald   do {
1624*ce6f85e7SMatthias Ringwald     if (pRTTCB->aUp[BufferIndex].pBuffer == NULL) {
16257dc86dfdSMatthias Ringwald       break;
16267dc86dfdSMatthias Ringwald     }
16277dc86dfdSMatthias Ringwald     BufferIndex++;
1628*ce6f85e7SMatthias Ringwald   } while (BufferIndex < pRTTCB->MaxNumUpBuffers);
1629*ce6f85e7SMatthias Ringwald   if (BufferIndex < pRTTCB->MaxNumUpBuffers) {
1630*ce6f85e7SMatthias Ringwald     pRTTCB->aUp[BufferIndex].sName        = sName;
1631*ce6f85e7SMatthias Ringwald     pRTTCB->aUp[BufferIndex].pBuffer      = (char*)pBuffer;
1632*ce6f85e7SMatthias Ringwald     pRTTCB->aUp[BufferIndex].SizeOfBuffer = BufferSize;
1633*ce6f85e7SMatthias Ringwald     pRTTCB->aUp[BufferIndex].RdOff        = 0u;
1634*ce6f85e7SMatthias Ringwald     pRTTCB->aUp[BufferIndex].WrOff        = 0u;
1635*ce6f85e7SMatthias Ringwald     pRTTCB->aUp[BufferIndex].Flags        = Flags;
1636*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
16377dc86dfdSMatthias Ringwald   } else {
16387dc86dfdSMatthias Ringwald     BufferIndex = -1;
16397dc86dfdSMatthias Ringwald   }
16407dc86dfdSMatthias Ringwald   SEGGER_RTT_UNLOCK();
16417dc86dfdSMatthias Ringwald   return BufferIndex;
16427dc86dfdSMatthias Ringwald }
16437dc86dfdSMatthias Ringwald 
16447dc86dfdSMatthias Ringwald /*********************************************************************
16457dc86dfdSMatthias Ringwald *
16467dc86dfdSMatthias Ringwald *       SEGGER_RTT_ConfigUpBuffer
16477dc86dfdSMatthias Ringwald *
16487dc86dfdSMatthias Ringwald *  Function description
16497dc86dfdSMatthias Ringwald *    Run-time configuration of a specific up-buffer (T->H).
16507dc86dfdSMatthias Ringwald *    Buffer to be configured is specified by index.
16517dc86dfdSMatthias Ringwald *    This includes: Buffer address, size, name, flags, ...
16527dc86dfdSMatthias Ringwald *
16537dc86dfdSMatthias Ringwald *  Parameters
16547dc86dfdSMatthias Ringwald *    BufferIndex  Index of the buffer to configure.
16557dc86dfdSMatthias Ringwald *    sName        Pointer to a constant name string.
16567dc86dfdSMatthias Ringwald *    pBuffer      Pointer to a buffer to be used.
16577dc86dfdSMatthias Ringwald *    BufferSize   Size of the buffer.
16587dc86dfdSMatthias Ringwald *    Flags        Operating modes. Define behavior if buffer is full (not enough space for entire message).
1659*ce6f85e7SMatthias Ringwald *                 Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
16607dc86dfdSMatthias Ringwald *
16617dc86dfdSMatthias Ringwald *  Return value
16627dc86dfdSMatthias Ringwald *    >= 0 - O.K.
16637dc86dfdSMatthias Ringwald *     < 0 - Error
16647dc86dfdSMatthias Ringwald *
16657dc86dfdSMatthias Ringwald *  Additional information
16667dc86dfdSMatthias Ringwald *    Buffer 0 is configured on compile-time.
16677dc86dfdSMatthias Ringwald *    May only be called once per buffer.
16687dc86dfdSMatthias Ringwald *    Buffer name and flags can be reconfigured using the appropriate functions.
16697dc86dfdSMatthias Ringwald */
SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex,const char * sName,void * pBuffer,unsigned BufferSize,unsigned Flags)16707dc86dfdSMatthias Ringwald int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
16717dc86dfdSMatthias Ringwald   int r;
1672*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
1673*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_BUFFER_UP* pUp;
16747dc86dfdSMatthias Ringwald 
16757dc86dfdSMatthias Ringwald   INIT();
1676*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1677*ce6f85e7SMatthias Ringwald   if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) {
16787dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
1679*ce6f85e7SMatthias Ringwald     pUp = &pRTTCB->aUp[BufferIndex];
1680*ce6f85e7SMatthias Ringwald     if (BufferIndex) {
1681*ce6f85e7SMatthias Ringwald       pUp->sName        = sName;
1682*ce6f85e7SMatthias Ringwald       pUp->pBuffer      = (char*)pBuffer;
1683*ce6f85e7SMatthias Ringwald       pUp->SizeOfBuffer = BufferSize;
1684*ce6f85e7SMatthias Ringwald       pUp->RdOff        = 0u;
1685*ce6f85e7SMatthias Ringwald       pUp->WrOff        = 0u;
16867dc86dfdSMatthias Ringwald     }
1687*ce6f85e7SMatthias Ringwald     pUp->Flags          = Flags;
16887dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
16897dc86dfdSMatthias Ringwald     r =  0;
16907dc86dfdSMatthias Ringwald   } else {
16917dc86dfdSMatthias Ringwald     r = -1;
16927dc86dfdSMatthias Ringwald   }
16937dc86dfdSMatthias Ringwald   return r;
16947dc86dfdSMatthias Ringwald }
16957dc86dfdSMatthias Ringwald 
16967dc86dfdSMatthias Ringwald /*********************************************************************
16977dc86dfdSMatthias Ringwald *
16987dc86dfdSMatthias Ringwald *       SEGGER_RTT_ConfigDownBuffer
16997dc86dfdSMatthias Ringwald *
17007dc86dfdSMatthias Ringwald *  Function description
17017dc86dfdSMatthias Ringwald *    Run-time configuration of a specific down-buffer (H->T).
17027dc86dfdSMatthias Ringwald *    Buffer to be configured is specified by index.
17037dc86dfdSMatthias Ringwald *    This includes: Buffer address, size, name, flags, ...
17047dc86dfdSMatthias Ringwald *
17057dc86dfdSMatthias Ringwald *  Parameters
17067dc86dfdSMatthias Ringwald *    BufferIndex  Index of the buffer to configure.
17077dc86dfdSMatthias Ringwald *    sName        Pointer to a constant name string.
17087dc86dfdSMatthias Ringwald *    pBuffer      Pointer to a buffer to be used.
17097dc86dfdSMatthias Ringwald *    BufferSize   Size of the buffer.
17107dc86dfdSMatthias Ringwald *    Flags        Operating modes. Define behavior if buffer is full (not enough space for entire message).
1711*ce6f85e7SMatthias Ringwald *                 Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
17127dc86dfdSMatthias Ringwald *
17137dc86dfdSMatthias Ringwald *  Return value
17147dc86dfdSMatthias Ringwald *    >= 0  O.K.
17157dc86dfdSMatthias Ringwald *     < 0  Error
17167dc86dfdSMatthias Ringwald *
17177dc86dfdSMatthias Ringwald *  Additional information
17187dc86dfdSMatthias Ringwald *    Buffer 0 is configured on compile-time.
17197dc86dfdSMatthias Ringwald *    May only be called once per buffer.
17207dc86dfdSMatthias Ringwald *    Buffer name and flags can be reconfigured using the appropriate functions.
17217dc86dfdSMatthias Ringwald */
SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex,const char * sName,void * pBuffer,unsigned BufferSize,unsigned Flags)17227dc86dfdSMatthias Ringwald int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
17237dc86dfdSMatthias Ringwald   int r;
1724*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
1725*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_BUFFER_DOWN* pDown;
17267dc86dfdSMatthias Ringwald 
17277dc86dfdSMatthias Ringwald   INIT();
1728*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1729*ce6f85e7SMatthias Ringwald   if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) {
17307dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
1731*ce6f85e7SMatthias Ringwald     pDown = &pRTTCB->aDown[BufferIndex];
1732*ce6f85e7SMatthias Ringwald     if (BufferIndex) {
1733*ce6f85e7SMatthias Ringwald       pDown->sName        = sName;
1734*ce6f85e7SMatthias Ringwald       pDown->pBuffer      = (char*)pBuffer;
1735*ce6f85e7SMatthias Ringwald       pDown->SizeOfBuffer = BufferSize;
1736*ce6f85e7SMatthias Ringwald       pDown->RdOff        = 0u;
1737*ce6f85e7SMatthias Ringwald       pDown->WrOff        = 0u;
17387dc86dfdSMatthias Ringwald     }
1739*ce6f85e7SMatthias Ringwald     pDown->Flags          = Flags;
1740*ce6f85e7SMatthias Ringwald     RTT__DMB();                     // Force data write to be complete before writing the <WrOff>, in case CPU is allowed to change the order of memory accesses
17417dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
17427dc86dfdSMatthias Ringwald     r =  0;
17437dc86dfdSMatthias Ringwald   } else {
17447dc86dfdSMatthias Ringwald     r = -1;
17457dc86dfdSMatthias Ringwald   }
17467dc86dfdSMatthias Ringwald   return r;
17477dc86dfdSMatthias Ringwald }
17487dc86dfdSMatthias Ringwald 
17497dc86dfdSMatthias Ringwald /*********************************************************************
17507dc86dfdSMatthias Ringwald *
17517dc86dfdSMatthias Ringwald *       SEGGER_RTT_SetNameUpBuffer
17527dc86dfdSMatthias Ringwald *
17537dc86dfdSMatthias Ringwald *  Function description
17547dc86dfdSMatthias Ringwald *    Run-time configuration of a specific up-buffer name (T->H).
17557dc86dfdSMatthias Ringwald *    Buffer to be configured is specified by index.
17567dc86dfdSMatthias Ringwald *
17577dc86dfdSMatthias Ringwald *  Parameters
17587dc86dfdSMatthias Ringwald *    BufferIndex  Index of the buffer to renamed.
17597dc86dfdSMatthias Ringwald *    sName        Pointer to a constant name string.
17607dc86dfdSMatthias Ringwald *
17617dc86dfdSMatthias Ringwald *  Return value
17627dc86dfdSMatthias Ringwald *    >= 0  O.K.
17637dc86dfdSMatthias Ringwald *     < 0  Error
17647dc86dfdSMatthias Ringwald */
SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex,const char * sName)17657dc86dfdSMatthias Ringwald int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) {
17667dc86dfdSMatthias Ringwald   int r;
1767*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
1768*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_BUFFER_UP* pUp;
17697dc86dfdSMatthias Ringwald 
17707dc86dfdSMatthias Ringwald   INIT();
1771*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1772*ce6f85e7SMatthias Ringwald   if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) {
17737dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
1774*ce6f85e7SMatthias Ringwald     pUp = &pRTTCB->aUp[BufferIndex];
1775*ce6f85e7SMatthias Ringwald     pUp->sName = sName;
17767dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
17777dc86dfdSMatthias Ringwald     r =  0;
17787dc86dfdSMatthias Ringwald   } else {
17797dc86dfdSMatthias Ringwald     r = -1;
17807dc86dfdSMatthias Ringwald   }
17817dc86dfdSMatthias Ringwald   return r;
17827dc86dfdSMatthias Ringwald }
17837dc86dfdSMatthias Ringwald 
17847dc86dfdSMatthias Ringwald /*********************************************************************
17857dc86dfdSMatthias Ringwald *
17867dc86dfdSMatthias Ringwald *       SEGGER_RTT_SetNameDownBuffer
17877dc86dfdSMatthias Ringwald *
17887dc86dfdSMatthias Ringwald *  Function description
17897dc86dfdSMatthias Ringwald *    Run-time configuration of a specific Down-buffer name (T->H).
17907dc86dfdSMatthias Ringwald *    Buffer to be configured is specified by index.
17917dc86dfdSMatthias Ringwald *
17927dc86dfdSMatthias Ringwald *  Parameters
17937dc86dfdSMatthias Ringwald *    BufferIndex  Index of the buffer to renamed.
17947dc86dfdSMatthias Ringwald *    sName        Pointer to a constant name string.
17957dc86dfdSMatthias Ringwald *
17967dc86dfdSMatthias Ringwald *  Return value
17977dc86dfdSMatthias Ringwald *    >= 0  O.K.
17987dc86dfdSMatthias Ringwald *     < 0  Error
17997dc86dfdSMatthias Ringwald */
SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex,const char * sName)18007dc86dfdSMatthias Ringwald int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
18017dc86dfdSMatthias Ringwald   int r;
1802*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
1803*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_BUFFER_DOWN* pDown;
18047dc86dfdSMatthias Ringwald 
18057dc86dfdSMatthias Ringwald   INIT();
1806*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1807*ce6f85e7SMatthias Ringwald   if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) {
18087dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
1809*ce6f85e7SMatthias Ringwald     pDown = &pRTTCB->aDown[BufferIndex];
1810*ce6f85e7SMatthias Ringwald     pDown->sName = sName;
18117dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
18127dc86dfdSMatthias Ringwald     r =  0;
18137dc86dfdSMatthias Ringwald   } else {
18147dc86dfdSMatthias Ringwald     r = -1;
18157dc86dfdSMatthias Ringwald   }
18167dc86dfdSMatthias Ringwald   return r;
18177dc86dfdSMatthias Ringwald }
18187dc86dfdSMatthias Ringwald 
18197dc86dfdSMatthias Ringwald /*********************************************************************
18207dc86dfdSMatthias Ringwald *
18217dc86dfdSMatthias Ringwald *       SEGGER_RTT_SetFlagsUpBuffer
18227dc86dfdSMatthias Ringwald *
18237dc86dfdSMatthias Ringwald *  Function description
18247dc86dfdSMatthias Ringwald *    Run-time configuration of specific up-buffer flags (T->H).
18257dc86dfdSMatthias Ringwald *    Buffer to be configured is specified by index.
18267dc86dfdSMatthias Ringwald *
18277dc86dfdSMatthias Ringwald *  Parameters
18287dc86dfdSMatthias Ringwald *    BufferIndex  Index of the buffer.
18297dc86dfdSMatthias Ringwald *    Flags        Flags to set for the buffer.
1830*ce6f85e7SMatthias Ringwald *                 Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
18317dc86dfdSMatthias Ringwald *
18327dc86dfdSMatthias Ringwald *  Return value
18337dc86dfdSMatthias Ringwald *    >= 0  O.K.
18347dc86dfdSMatthias Ringwald *     < 0  Error
18357dc86dfdSMatthias Ringwald */
SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex,unsigned Flags)18367dc86dfdSMatthias Ringwald int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
18377dc86dfdSMatthias Ringwald   int r;
1838*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
1839*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_BUFFER_UP* pUp;
18407dc86dfdSMatthias Ringwald 
18417dc86dfdSMatthias Ringwald   INIT();
1842*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1843*ce6f85e7SMatthias Ringwald   if (BufferIndex < SEGGER_RTT_MAX_NUM_UP_BUFFERS) {
18447dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
1845*ce6f85e7SMatthias Ringwald     pUp = &pRTTCB->aUp[BufferIndex];
1846*ce6f85e7SMatthias Ringwald     pUp->Flags = Flags;
18477dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
18487dc86dfdSMatthias Ringwald     r =  0;
18497dc86dfdSMatthias Ringwald   } else {
18507dc86dfdSMatthias Ringwald     r = -1;
18517dc86dfdSMatthias Ringwald   }
18527dc86dfdSMatthias Ringwald   return r;
18537dc86dfdSMatthias Ringwald }
18547dc86dfdSMatthias Ringwald 
18557dc86dfdSMatthias Ringwald /*********************************************************************
18567dc86dfdSMatthias Ringwald *
18577dc86dfdSMatthias Ringwald *       SEGGER_RTT_SetFlagsDownBuffer
18587dc86dfdSMatthias Ringwald *
18597dc86dfdSMatthias Ringwald *  Function description
18607dc86dfdSMatthias Ringwald *    Run-time configuration of specific Down-buffer flags (T->H).
18617dc86dfdSMatthias Ringwald *    Buffer to be configured is specified by index.
18627dc86dfdSMatthias Ringwald *
18637dc86dfdSMatthias Ringwald *  Parameters
18647dc86dfdSMatthias Ringwald *    BufferIndex  Index of the buffer to renamed.
18657dc86dfdSMatthias Ringwald *    Flags        Flags to set for the buffer.
1866*ce6f85e7SMatthias Ringwald *                 Flags[31:24] are used for validity check and must be zero. Flags[23:2] are reserved for future use. Flags[1:0] = RTT operating mode.
18677dc86dfdSMatthias Ringwald *
18687dc86dfdSMatthias Ringwald *  Return value
18697dc86dfdSMatthias Ringwald *    >= 0  O.K.
18707dc86dfdSMatthias Ringwald *     < 0  Error
18717dc86dfdSMatthias Ringwald */
SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex,unsigned Flags)18727dc86dfdSMatthias Ringwald int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
18737dc86dfdSMatthias Ringwald   int r;
1874*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
1875*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_BUFFER_DOWN* pDown;
18767dc86dfdSMatthias Ringwald 
18777dc86dfdSMatthias Ringwald   INIT();
1878*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
1879*ce6f85e7SMatthias Ringwald   if (BufferIndex < SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) {
18807dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
1881*ce6f85e7SMatthias Ringwald     pDown = &pRTTCB->aDown[BufferIndex];
1882*ce6f85e7SMatthias Ringwald     pDown->Flags = Flags;
18837dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
18847dc86dfdSMatthias Ringwald     r =  0;
18857dc86dfdSMatthias Ringwald   } else {
18867dc86dfdSMatthias Ringwald     r = -1;
18877dc86dfdSMatthias Ringwald   }
18887dc86dfdSMatthias Ringwald   return r;
18897dc86dfdSMatthias Ringwald }
18907dc86dfdSMatthias Ringwald 
18917dc86dfdSMatthias Ringwald /*********************************************************************
18927dc86dfdSMatthias Ringwald *
18937dc86dfdSMatthias Ringwald *       SEGGER_RTT_Init
18947dc86dfdSMatthias Ringwald *
18957dc86dfdSMatthias Ringwald *  Function description
18967dc86dfdSMatthias Ringwald *    Initializes the RTT Control Block.
18977dc86dfdSMatthias Ringwald *    Should be used in RAM targets, at start of the application.
18987dc86dfdSMatthias Ringwald *
18997dc86dfdSMatthias Ringwald */
SEGGER_RTT_Init(void)19007dc86dfdSMatthias Ringwald void SEGGER_RTT_Init (void) {
19017dc86dfdSMatthias Ringwald   _DoInit();
19027dc86dfdSMatthias Ringwald }
19037dc86dfdSMatthias Ringwald 
19047dc86dfdSMatthias Ringwald /*********************************************************************
19057dc86dfdSMatthias Ringwald *
19067dc86dfdSMatthias Ringwald *       SEGGER_RTT_SetTerminal
19077dc86dfdSMatthias Ringwald *
19087dc86dfdSMatthias Ringwald *  Function description
19097dc86dfdSMatthias Ringwald *    Sets the terminal to be used for output on channel 0.
19107dc86dfdSMatthias Ringwald *
19117dc86dfdSMatthias Ringwald *  Parameters
19127dc86dfdSMatthias Ringwald *    TerminalId  Index of the terminal.
19137dc86dfdSMatthias Ringwald *
19147dc86dfdSMatthias Ringwald *  Return value
19157dc86dfdSMatthias Ringwald *    >= 0  O.K.
19167dc86dfdSMatthias Ringwald *     < 0  Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id)
1917*ce6f85e7SMatthias Ringwald *
1918*ce6f85e7SMatthias Ringwald *  Notes
1919*ce6f85e7SMatthias Ringwald *    (1) Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
19207dc86dfdSMatthias Ringwald */
SEGGER_RTT_SetTerminal(unsigned char TerminalId)1921779af47bSMatthias Ringwald int SEGGER_RTT_SetTerminal (unsigned char TerminalId) {
1922779af47bSMatthias Ringwald   unsigned char         ac[2];
19237dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
19247dc86dfdSMatthias Ringwald   unsigned Avail;
19257dc86dfdSMatthias Ringwald   int r;
1926*ce6f85e7SMatthias Ringwald 
19277dc86dfdSMatthias Ringwald   INIT();
19287dc86dfdSMatthias Ringwald   r = 0;
1929779af47bSMatthias Ringwald   ac[0] = 0xFFu;
1930779af47bSMatthias Ringwald   if (TerminalId < sizeof(_aTerminalId)) { // We only support a certain number of channels
1931779af47bSMatthias Ringwald     ac[1] = _aTerminalId[TerminalId];
1932*ce6f85e7SMatthias Ringwald     pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
19337dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();                     // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing
19347dc86dfdSMatthias Ringwald     if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
19357dc86dfdSMatthias Ringwald       _ActiveTerminal = TerminalId;
1936779af47bSMatthias Ringwald       _WriteBlocking(pRing, (const char*)ac, 2u);
19377dc86dfdSMatthias Ringwald     } else {                                                                            // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
19387dc86dfdSMatthias Ringwald       Avail = _GetAvailWriteSpace(pRing);
19397dc86dfdSMatthias Ringwald       if (Avail >= 2) {
19407dc86dfdSMatthias Ringwald         _ActiveTerminal = TerminalId;    // Only change active terminal in case of success
1941779af47bSMatthias Ringwald         _WriteNoCheck(pRing, (const char*)ac, 2u);
19427dc86dfdSMatthias Ringwald       } else {
19437dc86dfdSMatthias Ringwald         r = -1;
19447dc86dfdSMatthias Ringwald       }
19457dc86dfdSMatthias Ringwald     }
19467dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
19477dc86dfdSMatthias Ringwald   } else {
19487dc86dfdSMatthias Ringwald     r = -1;
19497dc86dfdSMatthias Ringwald   }
19507dc86dfdSMatthias Ringwald   return r;
19517dc86dfdSMatthias Ringwald }
19527dc86dfdSMatthias Ringwald 
19537dc86dfdSMatthias Ringwald /*********************************************************************
19547dc86dfdSMatthias Ringwald *
19557dc86dfdSMatthias Ringwald *       SEGGER_RTT_TerminalOut
19567dc86dfdSMatthias Ringwald *
19577dc86dfdSMatthias Ringwald *  Function description
19587dc86dfdSMatthias Ringwald *    Writes a string to the given terminal
19597dc86dfdSMatthias Ringwald *     without changing the terminal for channel 0.
19607dc86dfdSMatthias Ringwald *
19617dc86dfdSMatthias Ringwald *  Parameters
19627dc86dfdSMatthias Ringwald *    TerminalId   Index of the terminal.
19637dc86dfdSMatthias Ringwald *    s            String to be printed on the terminal.
19647dc86dfdSMatthias Ringwald *
19657dc86dfdSMatthias Ringwald *  Return value
19667dc86dfdSMatthias Ringwald *    >= 0 - Number of bytes written.
19677dc86dfdSMatthias Ringwald *     < 0 - Error.
19687dc86dfdSMatthias Ringwald *
19697dc86dfdSMatthias Ringwald */
SEGGER_RTT_TerminalOut(unsigned char TerminalId,const char * s)1970779af47bSMatthias Ringwald int SEGGER_RTT_TerminalOut (unsigned char TerminalId, const char* s) {
19717dc86dfdSMatthias Ringwald   int                   Status;
19727dc86dfdSMatthias Ringwald   unsigned              FragLen;
19737dc86dfdSMatthias Ringwald   unsigned              Avail;
19747dc86dfdSMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
19757dc86dfdSMatthias Ringwald   //
19767dc86dfdSMatthias Ringwald   INIT();
19777dc86dfdSMatthias Ringwald   //
19787dc86dfdSMatthias Ringwald   // Validate terminal ID.
19797dc86dfdSMatthias Ringwald   //
19807dc86dfdSMatthias Ringwald   if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels
19817dc86dfdSMatthias Ringwald     //
19827dc86dfdSMatthias Ringwald     // Get "to-host" ring buffer.
19837dc86dfdSMatthias Ringwald     //
1984*ce6f85e7SMatthias Ringwald     pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[0] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
19857dc86dfdSMatthias Ringwald     //
19867dc86dfdSMatthias Ringwald     // Need to be able to change terminal, write data, change back.
19877dc86dfdSMatthias Ringwald     // Compute the fixed and variable sizes.
19887dc86dfdSMatthias Ringwald     //
19897dc86dfdSMatthias Ringwald     FragLen = STRLEN(s);
19907dc86dfdSMatthias Ringwald     //
19917dc86dfdSMatthias Ringwald     // How we output depends upon the mode...
19927dc86dfdSMatthias Ringwald     //
19937dc86dfdSMatthias Ringwald     SEGGER_RTT_LOCK();
19947dc86dfdSMatthias Ringwald     Avail = _GetAvailWriteSpace(pRing);
19957dc86dfdSMatthias Ringwald     switch (pRing->Flags & SEGGER_RTT_MODE_MASK) {
19967dc86dfdSMatthias Ringwald     case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
19977dc86dfdSMatthias Ringwald       //
19987dc86dfdSMatthias Ringwald       // If we are in skip mode and there is no space for the whole
19997dc86dfdSMatthias Ringwald       // of this output, don't bother switching terminals at all.
20007dc86dfdSMatthias Ringwald       //
20017dc86dfdSMatthias Ringwald       if (Avail < (FragLen + 4u)) {
20027dc86dfdSMatthias Ringwald         Status = 0;
20037dc86dfdSMatthias Ringwald       } else {
20047dc86dfdSMatthias Ringwald         _PostTerminalSwitch(pRing, TerminalId);
20057dc86dfdSMatthias Ringwald         Status = (int)_WriteBlocking(pRing, s, FragLen);
20067dc86dfdSMatthias Ringwald         _PostTerminalSwitch(pRing, _ActiveTerminal);
20077dc86dfdSMatthias Ringwald       }
20087dc86dfdSMatthias Ringwald       break;
20097dc86dfdSMatthias Ringwald     case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
20107dc86dfdSMatthias Ringwald       //
20117dc86dfdSMatthias Ringwald       // If we are in trim mode and there is not enough space for everything,
20127dc86dfdSMatthias Ringwald       // trim the output but always include the terminal switch.  If no room
20137dc86dfdSMatthias Ringwald       // for terminal switch, skip that totally.
20147dc86dfdSMatthias Ringwald       //
20157dc86dfdSMatthias Ringwald       if (Avail < 4u) {
20167dc86dfdSMatthias Ringwald         Status = -1;
20177dc86dfdSMatthias Ringwald       } else {
20187dc86dfdSMatthias Ringwald         _PostTerminalSwitch(pRing, TerminalId);
20197dc86dfdSMatthias Ringwald         Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u));
20207dc86dfdSMatthias Ringwald         _PostTerminalSwitch(pRing, _ActiveTerminal);
20217dc86dfdSMatthias Ringwald       }
20227dc86dfdSMatthias Ringwald       break;
20237dc86dfdSMatthias Ringwald     case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
20247dc86dfdSMatthias Ringwald       //
20257dc86dfdSMatthias Ringwald       // If we are in blocking mode, output everything.
20267dc86dfdSMatthias Ringwald       //
20277dc86dfdSMatthias Ringwald       _PostTerminalSwitch(pRing, TerminalId);
20287dc86dfdSMatthias Ringwald       Status = (int)_WriteBlocking(pRing, s, FragLen);
20297dc86dfdSMatthias Ringwald       _PostTerminalSwitch(pRing, _ActiveTerminal);
20307dc86dfdSMatthias Ringwald       break;
20317dc86dfdSMatthias Ringwald     default:
20327dc86dfdSMatthias Ringwald       Status = -1;
20337dc86dfdSMatthias Ringwald       break;
20347dc86dfdSMatthias Ringwald     }
20357dc86dfdSMatthias Ringwald     //
20367dc86dfdSMatthias Ringwald     // Finish up.
20377dc86dfdSMatthias Ringwald     //
20387dc86dfdSMatthias Ringwald     SEGGER_RTT_UNLOCK();
20397dc86dfdSMatthias Ringwald   } else {
20407dc86dfdSMatthias Ringwald     Status = -1;
20417dc86dfdSMatthias Ringwald   }
20427dc86dfdSMatthias Ringwald   return Status;
20437dc86dfdSMatthias Ringwald }
20447dc86dfdSMatthias Ringwald 
2045a20be900SMatthias Ringwald /*********************************************************************
2046a20be900SMatthias Ringwald *
2047a20be900SMatthias Ringwald *       SEGGER_RTT_GetAvailWriteSpace
2048*ce6f85e7SMatthias Ringwald *
2049*ce6f85e7SMatthias Ringwald *  Function description
2050*ce6f85e7SMatthias Ringwald *    Returns the number of bytes available in the ring buffer.
2051a20be900SMatthias Ringwald *
2052a20be900SMatthias Ringwald *  Parameters
2053*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of the up buffer.
2054a20be900SMatthias Ringwald *
2055a20be900SMatthias Ringwald *  Return value
2056*ce6f85e7SMatthias Ringwald *    Number of bytes that are free in the selected up buffer.
2057a20be900SMatthias Ringwald */
SEGGER_RTT_GetAvailWriteSpace(unsigned BufferIndex)2058a20be900SMatthias Ringwald unsigned SEGGER_RTT_GetAvailWriteSpace (unsigned BufferIndex) {
2059*ce6f85e7SMatthias Ringwald   SEGGER_RTT_BUFFER_UP* pRing;
2060*ce6f85e7SMatthias Ringwald 
2061*ce6f85e7SMatthias Ringwald   pRing = (SEGGER_RTT_BUFFER_UP*)((char*)&_SEGGER_RTT.aUp[BufferIndex] + SEGGER_RTT_UNCACHED_OFF);  // Access uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
2062*ce6f85e7SMatthias Ringwald   return _GetAvailWriteSpace(pRing);
2063a20be900SMatthias Ringwald }
2064a20be900SMatthias Ringwald 
20657dc86dfdSMatthias Ringwald 
2066*ce6f85e7SMatthias Ringwald /*********************************************************************
2067*ce6f85e7SMatthias Ringwald *
2068*ce6f85e7SMatthias Ringwald *       SEGGER_RTT_GetBytesInBuffer()
2069*ce6f85e7SMatthias Ringwald *
2070*ce6f85e7SMatthias Ringwald *  Function description
2071*ce6f85e7SMatthias Ringwald *    Returns the number of bytes currently used in the up buffer.
2072*ce6f85e7SMatthias Ringwald *
2073*ce6f85e7SMatthias Ringwald *  Parameters
2074*ce6f85e7SMatthias Ringwald *    BufferIndex  Index of the up buffer.
2075*ce6f85e7SMatthias Ringwald *
2076*ce6f85e7SMatthias Ringwald *  Return value
2077*ce6f85e7SMatthias Ringwald *    Number of bytes that are used in the buffer.
2078*ce6f85e7SMatthias Ringwald */
SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex)2079*ce6f85e7SMatthias Ringwald unsigned SEGGER_RTT_GetBytesInBuffer(unsigned BufferIndex) {
2080*ce6f85e7SMatthias Ringwald   unsigned RdOff;
2081*ce6f85e7SMatthias Ringwald   unsigned WrOff;
2082*ce6f85e7SMatthias Ringwald   unsigned r;
2083*ce6f85e7SMatthias Ringwald   volatile SEGGER_RTT_CB* pRTTCB;
2084*ce6f85e7SMatthias Ringwald   //
2085*ce6f85e7SMatthias Ringwald   // Avoid warnings regarding volatile access order.  It's not a problem
2086*ce6f85e7SMatthias Ringwald   // in this case, but dampen compiler enthusiasm.
2087*ce6f85e7SMatthias Ringwald   //
2088*ce6f85e7SMatthias Ringwald   pRTTCB = (volatile SEGGER_RTT_CB*)((unsigned char*)&_SEGGER_RTT + SEGGER_RTT_UNCACHED_OFF);  // Access RTTCB uncached to make sure we see changes made by the J-Link side and all of our changes go into HW directly
2089*ce6f85e7SMatthias Ringwald   RdOff = pRTTCB->aUp[BufferIndex].RdOff;
2090*ce6f85e7SMatthias Ringwald   WrOff = pRTTCB->aUp[BufferIndex].WrOff;
2091*ce6f85e7SMatthias Ringwald   if (RdOff <= WrOff) {
2092*ce6f85e7SMatthias Ringwald     r = WrOff - RdOff;
2093*ce6f85e7SMatthias Ringwald   } else {
2094*ce6f85e7SMatthias Ringwald     r = pRTTCB->aUp[BufferIndex].SizeOfBuffer - (WrOff - RdOff);
2095*ce6f85e7SMatthias Ringwald   }
2096*ce6f85e7SMatthias Ringwald   return r;
2097*ce6f85e7SMatthias Ringwald }
2098*ce6f85e7SMatthias Ringwald 
20997dc86dfdSMatthias Ringwald /*************************** End of file ****************************/
2100