iTracker mbed os sample to show how to user the BLE API to expose sensor values (float and ints)

Committer:
knaresh89
Date:
Mon Feb 12 06:41:24 2018 +0000
Revision:
0:e4fe77192b73
iTracker mbed os sample to show how to user the BLE API to expose sensor values (float and ints)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
knaresh89 0:e4fe77192b73 1 /*********************************************************************
knaresh89 0:e4fe77192b73 2 * SEGGER MICROCONTROLLER GmbH & Co. KG *
knaresh89 0:e4fe77192b73 3 * Solutions for real time microcontroller applications *
knaresh89 0:e4fe77192b73 4 **********************************************************************
knaresh89 0:e4fe77192b73 5 * *
knaresh89 0:e4fe77192b73 6 * (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG *
knaresh89 0:e4fe77192b73 7 * *
knaresh89 0:e4fe77192b73 8 * www.segger.com Support: support@segger.com *
knaresh89 0:e4fe77192b73 9 * *
knaresh89 0:e4fe77192b73 10 **********************************************************************
knaresh89 0:e4fe77192b73 11 * *
knaresh89 0:e4fe77192b73 12 * SEGGER RTT * Real Time Transfer for embedded targets *
knaresh89 0:e4fe77192b73 13 * *
knaresh89 0:e4fe77192b73 14 **********************************************************************
knaresh89 0:e4fe77192b73 15 * *
knaresh89 0:e4fe77192b73 16 * All rights reserved. *
knaresh89 0:e4fe77192b73 17 * *
knaresh89 0:e4fe77192b73 18 * SEGGER strongly recommends to not make any changes *
knaresh89 0:e4fe77192b73 19 * to or modify the source code of this software in order to stay *
knaresh89 0:e4fe77192b73 20 * compatible with the RTT protocol and J-Link. *
knaresh89 0:e4fe77192b73 21 * *
knaresh89 0:e4fe77192b73 22 * Redistribution and use in source and binary forms, with or *
knaresh89 0:e4fe77192b73 23 * without modification, are permitted provided that the following *
knaresh89 0:e4fe77192b73 24 * conditions are met: *
knaresh89 0:e4fe77192b73 25 * *
knaresh89 0:e4fe77192b73 26 * o Redistributions of source code must retain the above copyright *
knaresh89 0:e4fe77192b73 27 * notice, this list of conditions and the following disclaimer. *
knaresh89 0:e4fe77192b73 28 * *
knaresh89 0:e4fe77192b73 29 * o Redistributions in binary form must reproduce the above *
knaresh89 0:e4fe77192b73 30 * copyright notice, this list of conditions and the following *
knaresh89 0:e4fe77192b73 31 * disclaimer in the documentation and/or other materials provided *
knaresh89 0:e4fe77192b73 32 * with the distribution. *
knaresh89 0:e4fe77192b73 33 * *
knaresh89 0:e4fe77192b73 34 * o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
knaresh89 0:e4fe77192b73 35 * nor the names of its contributors may be used to endorse or *
knaresh89 0:e4fe77192b73 36 * promote products derived from this software without specific *
knaresh89 0:e4fe77192b73 37 * prior written permission. *
knaresh89 0:e4fe77192b73 38 * *
knaresh89 0:e4fe77192b73 39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
knaresh89 0:e4fe77192b73 40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
knaresh89 0:e4fe77192b73 41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
knaresh89 0:e4fe77192b73 42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
knaresh89 0:e4fe77192b73 43 * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
knaresh89 0:e4fe77192b73 44 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
knaresh89 0:e4fe77192b73 45 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
knaresh89 0:e4fe77192b73 46 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
knaresh89 0:e4fe77192b73 47 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
knaresh89 0:e4fe77192b73 48 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
knaresh89 0:e4fe77192b73 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
knaresh89 0:e4fe77192b73 50 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
knaresh89 0:e4fe77192b73 51 * DAMAGE. *
knaresh89 0:e4fe77192b73 52 * *
knaresh89 0:e4fe77192b73 53 **********************************************************************
knaresh89 0:e4fe77192b73 54 ---------------------------END-OF-HEADER------------------------------
knaresh89 0:e4fe77192b73 55 File : SEGGER_RTT.c
knaresh89 0:e4fe77192b73 56 Purpose : Implementation of SEGGER real-time transfer (RTT) which
knaresh89 0:e4fe77192b73 57 allows real-time communication on targets which support
knaresh89 0:e4fe77192b73 58 debugger memory accesses while the CPU is running.
knaresh89 0:e4fe77192b73 59 Revision: $Rev: 4351 $
knaresh89 0:e4fe77192b73 60
knaresh89 0:e4fe77192b73 61 Additional information:
knaresh89 0:e4fe77192b73 62 Type "int" is assumed to be 32-bits in size
knaresh89 0:e4fe77192b73 63 H->T Host to target communication
knaresh89 0:e4fe77192b73 64 T->H Target to host communication
knaresh89 0:e4fe77192b73 65
knaresh89 0:e4fe77192b73 66 RTT channel 0 is always present and reserved for Terminal usage.
knaresh89 0:e4fe77192b73 67 Name is fixed to "Terminal"
knaresh89 0:e4fe77192b73 68
knaresh89 0:e4fe77192b73 69 Effective buffer size: SizeOfBuffer - 1
knaresh89 0:e4fe77192b73 70
knaresh89 0:e4fe77192b73 71 WrOff == RdOff: Buffer is empty
knaresh89 0:e4fe77192b73 72 WrOff == (RdOff - 1): Buffer is full
knaresh89 0:e4fe77192b73 73 WrOff > RdOff: Free space includes wrap-around
knaresh89 0:e4fe77192b73 74 WrOff < RdOff: Used space includes wrap-around
knaresh89 0:e4fe77192b73 75 (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0):
knaresh89 0:e4fe77192b73 76 Buffer full and wrap-around after next byte
knaresh89 0:e4fe77192b73 77
knaresh89 0:e4fe77192b73 78
knaresh89 0:e4fe77192b73 79 ----------------------------------------------------------------------
knaresh89 0:e4fe77192b73 80 */
knaresh89 0:e4fe77192b73 81
knaresh89 0:e4fe77192b73 82 #include "SEGGER_RTT.h"
knaresh89 0:e4fe77192b73 83
knaresh89 0:e4fe77192b73 84 #include <string.h> // for memcpy
knaresh89 0:e4fe77192b73 85
knaresh89 0:e4fe77192b73 86 /*********************************************************************
knaresh89 0:e4fe77192b73 87 *
knaresh89 0:e4fe77192b73 88 * Configuration, default values
knaresh89 0:e4fe77192b73 89 *
knaresh89 0:e4fe77192b73 90 **********************************************************************
knaresh89 0:e4fe77192b73 91 */
knaresh89 0:e4fe77192b73 92
knaresh89 0:e4fe77192b73 93 #ifndef BUFFER_SIZE_UP
knaresh89 0:e4fe77192b73 94 #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host
knaresh89 0:e4fe77192b73 95 #endif
knaresh89 0:e4fe77192b73 96
knaresh89 0:e4fe77192b73 97 #ifndef BUFFER_SIZE_DOWN
knaresh89 0:e4fe77192b73 98 #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input)
knaresh89 0:e4fe77192b73 99 #endif
knaresh89 0:e4fe77192b73 100
knaresh89 0:e4fe77192b73 101 #ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS
knaresh89 0:e4fe77192b73 102 #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target
knaresh89 0:e4fe77192b73 103 #endif
knaresh89 0:e4fe77192b73 104
knaresh89 0:e4fe77192b73 105 #ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS
knaresh89 0:e4fe77192b73 106 #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target
knaresh89 0:e4fe77192b73 107 #endif
knaresh89 0:e4fe77192b73 108
knaresh89 0:e4fe77192b73 109 #ifndef SEGGER_RTT_BUFFER_SECTION
knaresh89 0:e4fe77192b73 110 #if defined(SEGGER_RTT_SECTION)
knaresh89 0:e4fe77192b73 111 #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION
knaresh89 0:e4fe77192b73 112 #endif
knaresh89 0:e4fe77192b73 113 #endif
knaresh89 0:e4fe77192b73 114
knaresh89 0:e4fe77192b73 115 #ifndef SEGGER_RTT_ALIGNMENT
knaresh89 0:e4fe77192b73 116 #define SEGGER_RTT_ALIGNMENT 0
knaresh89 0:e4fe77192b73 117 #endif
knaresh89 0:e4fe77192b73 118
knaresh89 0:e4fe77192b73 119 #ifndef SEGGER_RTT_BUFFER_ALIGNMENT
knaresh89 0:e4fe77192b73 120 #define SEGGER_RTT_BUFFER_ALIGNMENT 0
knaresh89 0:e4fe77192b73 121 #endif
knaresh89 0:e4fe77192b73 122
knaresh89 0:e4fe77192b73 123 #ifndef SEGGER_RTT_MODE_DEFAULT
knaresh89 0:e4fe77192b73 124 #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
knaresh89 0:e4fe77192b73 125 #endif
knaresh89 0:e4fe77192b73 126
knaresh89 0:e4fe77192b73 127 #ifndef SEGGER_RTT_LOCK
knaresh89 0:e4fe77192b73 128 #define SEGGER_RTT_LOCK()
knaresh89 0:e4fe77192b73 129 #endif
knaresh89 0:e4fe77192b73 130
knaresh89 0:e4fe77192b73 131 #ifndef SEGGER_RTT_UNLOCK
knaresh89 0:e4fe77192b73 132 #define SEGGER_RTT_UNLOCK()
knaresh89 0:e4fe77192b73 133 #endif
knaresh89 0:e4fe77192b73 134
knaresh89 0:e4fe77192b73 135 #ifndef STRLEN
knaresh89 0:e4fe77192b73 136 #define STRLEN(a) strlen((a))
knaresh89 0:e4fe77192b73 137 #endif
knaresh89 0:e4fe77192b73 138
knaresh89 0:e4fe77192b73 139 #ifndef MEMCPY
knaresh89 0:e4fe77192b73 140 #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes))
knaresh89 0:e4fe77192b73 141 #endif
knaresh89 0:e4fe77192b73 142
knaresh89 0:e4fe77192b73 143 #ifndef MIN
knaresh89 0:e4fe77192b73 144 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
knaresh89 0:e4fe77192b73 145 #endif
knaresh89 0:e4fe77192b73 146
knaresh89 0:e4fe77192b73 147 #ifndef MAX
knaresh89 0:e4fe77192b73 148 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
knaresh89 0:e4fe77192b73 149 #endif
knaresh89 0:e4fe77192b73 150 //
knaresh89 0:e4fe77192b73 151 // For some environments, NULL may not be defined until certain headers are included
knaresh89 0:e4fe77192b73 152 //
knaresh89 0:e4fe77192b73 153 #ifndef NULL
knaresh89 0:e4fe77192b73 154 #define NULL 0
knaresh89 0:e4fe77192b73 155 #endif
knaresh89 0:e4fe77192b73 156
knaresh89 0:e4fe77192b73 157 /*********************************************************************
knaresh89 0:e4fe77192b73 158 *
knaresh89 0:e4fe77192b73 159 * Defines, fixed
knaresh89 0:e4fe77192b73 160 *
knaresh89 0:e4fe77192b73 161 **********************************************************************
knaresh89 0:e4fe77192b73 162 */
knaresh89 0:e4fe77192b73 163 #if (defined __ICCARM__) || (defined __ICCRX__)
knaresh89 0:e4fe77192b73 164 #define RTT_PRAGMA(P) _Pragma(#P)
knaresh89 0:e4fe77192b73 165 #endif
knaresh89 0:e4fe77192b73 166
knaresh89 0:e4fe77192b73 167 #if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT
knaresh89 0:e4fe77192b73 168 #if (defined __GNUC__)
knaresh89 0:e4fe77192b73 169 #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
knaresh89 0:e4fe77192b73 170 #elif (defined __ICCARM__) || (defined __ICCRX__)
knaresh89 0:e4fe77192b73 171 #define PRAGMA(A) _Pragma(#A)
knaresh89 0:e4fe77192b73 172 #define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \
knaresh89 0:e4fe77192b73 173 Var
knaresh89 0:e4fe77192b73 174 #elif (defined __CC_ARM__)
knaresh89 0:e4fe77192b73 175 #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment)))
knaresh89 0:e4fe77192b73 176 #else
knaresh89 0:e4fe77192b73 177 #error "Alignment not supported for this compiler."
knaresh89 0:e4fe77192b73 178 #endif
knaresh89 0:e4fe77192b73 179 #else
knaresh89 0:e4fe77192b73 180 #define SEGGER_RTT_ALIGN(Var, Alignment) Var
knaresh89 0:e4fe77192b73 181 #endif
knaresh89 0:e4fe77192b73 182
knaresh89 0:e4fe77192b73 183 #if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION)
knaresh89 0:e4fe77192b73 184 #if (defined __GNUC__)
knaresh89 0:e4fe77192b73 185 #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var
knaresh89 0:e4fe77192b73 186 #elif (defined __ICCARM__) || (defined __ICCRX__)
knaresh89 0:e4fe77192b73 187 #define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \
knaresh89 0:e4fe77192b73 188 Var
knaresh89 0:e4fe77192b73 189 #elif (defined __CC_ARM__)
knaresh89 0:e4fe77192b73 190 #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var
knaresh89 0:e4fe77192b73 191 #else
knaresh89 0:e4fe77192b73 192 #error "Section placement not supported for this compiler."
knaresh89 0:e4fe77192b73 193 #endif
knaresh89 0:e4fe77192b73 194 #else
knaresh89 0:e4fe77192b73 195 #define SEGGER_RTT_PUT_SECTION(Var, Section) Var
knaresh89 0:e4fe77192b73 196 #endif
knaresh89 0:e4fe77192b73 197
knaresh89 0:e4fe77192b73 198
knaresh89 0:e4fe77192b73 199 #if SEGGER_RTT_ALIGNMENT
knaresh89 0:e4fe77192b73 200 #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT)
knaresh89 0:e4fe77192b73 201 #else
knaresh89 0:e4fe77192b73 202 #define SEGGER_RTT_CB_ALIGN(Var) Var
knaresh89 0:e4fe77192b73 203 #endif
knaresh89 0:e4fe77192b73 204
knaresh89 0:e4fe77192b73 205 #if SEGGER_RTT_BUFFER_ALIGNMENT
knaresh89 0:e4fe77192b73 206 #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT)
knaresh89 0:e4fe77192b73 207 #else
knaresh89 0:e4fe77192b73 208 #define SEGGER_RTT_BUFFER_ALIGN(Var) Var
knaresh89 0:e4fe77192b73 209 #endif
knaresh89 0:e4fe77192b73 210
knaresh89 0:e4fe77192b73 211
knaresh89 0:e4fe77192b73 212 #if defined(SEGGER_RTT_SECTION)
knaresh89 0:e4fe77192b73 213 #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION)
knaresh89 0:e4fe77192b73 214 #else
knaresh89 0:e4fe77192b73 215 #define SEGGER_RTT_PUT_CB_SECTION(Var) Var
knaresh89 0:e4fe77192b73 216 #endif
knaresh89 0:e4fe77192b73 217
knaresh89 0:e4fe77192b73 218 #if defined(SEGGER_RTT_BUFFER_SECTION)
knaresh89 0:e4fe77192b73 219 #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION)
knaresh89 0:e4fe77192b73 220 #else
knaresh89 0:e4fe77192b73 221 #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var
knaresh89 0:e4fe77192b73 222 #endif
knaresh89 0:e4fe77192b73 223
knaresh89 0:e4fe77192b73 224 /*********************************************************************
knaresh89 0:e4fe77192b73 225 *
knaresh89 0:e4fe77192b73 226 * Static const data
knaresh89 0:e4fe77192b73 227 *
knaresh89 0:e4fe77192b73 228 **********************************************************************
knaresh89 0:e4fe77192b73 229 */
knaresh89 0:e4fe77192b73 230
knaresh89 0:e4fe77192b73 231 static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
knaresh89 0:e4fe77192b73 232
knaresh89 0:e4fe77192b73 233 /*********************************************************************
knaresh89 0:e4fe77192b73 234 *
knaresh89 0:e4fe77192b73 235 * Static data
knaresh89 0:e4fe77192b73 236 *
knaresh89 0:e4fe77192b73 237 **********************************************************************
knaresh89 0:e4fe77192b73 238 */
knaresh89 0:e4fe77192b73 239 //
knaresh89 0:e4fe77192b73 240 // RTT Control Block and allocate buffers for channel 0
knaresh89 0:e4fe77192b73 241 //
knaresh89 0:e4fe77192b73 242 SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
knaresh89 0:e4fe77192b73 243
knaresh89 0:e4fe77192b73 244 SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP]));
knaresh89 0:e4fe77192b73 245 SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
knaresh89 0:e4fe77192b73 246
knaresh89 0:e4fe77192b73 247 static char _ActiveTerminal;
knaresh89 0:e4fe77192b73 248
knaresh89 0:e4fe77192b73 249 /*********************************************************************
knaresh89 0:e4fe77192b73 250 *
knaresh89 0:e4fe77192b73 251 * Static functions
knaresh89 0:e4fe77192b73 252 *
knaresh89 0:e4fe77192b73 253 **********************************************************************
knaresh89 0:e4fe77192b73 254 */
knaresh89 0:e4fe77192b73 255
knaresh89 0:e4fe77192b73 256 /*********************************************************************
knaresh89 0:e4fe77192b73 257 *
knaresh89 0:e4fe77192b73 258 * _DoInit()
knaresh89 0:e4fe77192b73 259 *
knaresh89 0:e4fe77192b73 260 * Function description
knaresh89 0:e4fe77192b73 261 * Initializes the control block an buffers.
knaresh89 0:e4fe77192b73 262 * May only be called via INIT() to avoid overriding settings.
knaresh89 0:e4fe77192b73 263 *
knaresh89 0:e4fe77192b73 264 */
knaresh89 0:e4fe77192b73 265 #define INIT() do { \
knaresh89 0:e4fe77192b73 266 if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \
knaresh89 0:e4fe77192b73 267 } while (0)
knaresh89 0:e4fe77192b73 268 static void _DoInit(void) {
knaresh89 0:e4fe77192b73 269 SEGGER_RTT_CB* p;
knaresh89 0:e4fe77192b73 270 //
knaresh89 0:e4fe77192b73 271 // Initialize control block
knaresh89 0:e4fe77192b73 272 //
knaresh89 0:e4fe77192b73 273 p = &_SEGGER_RTT;
knaresh89 0:e4fe77192b73 274 p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS;
knaresh89 0:e4fe77192b73 275 p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS;
knaresh89 0:e4fe77192b73 276 //
knaresh89 0:e4fe77192b73 277 // Initialize up buffer 0
knaresh89 0:e4fe77192b73 278 //
knaresh89 0:e4fe77192b73 279 p->aUp[0].sName = "Terminal";
knaresh89 0:e4fe77192b73 280 p->aUp[0].pBuffer = _acUpBuffer;
knaresh89 0:e4fe77192b73 281 p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer);
knaresh89 0:e4fe77192b73 282 p->aUp[0].RdOff = 0u;
knaresh89 0:e4fe77192b73 283 p->aUp[0].WrOff = 0u;
knaresh89 0:e4fe77192b73 284 p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT;
knaresh89 0:e4fe77192b73 285 //
knaresh89 0:e4fe77192b73 286 // Initialize down buffer 0
knaresh89 0:e4fe77192b73 287 //
knaresh89 0:e4fe77192b73 288 p->aDown[0].sName = "Terminal";
knaresh89 0:e4fe77192b73 289 p->aDown[0].pBuffer = _acDownBuffer;
knaresh89 0:e4fe77192b73 290 p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer);
knaresh89 0:e4fe77192b73 291 p->aDown[0].RdOff = 0u;
knaresh89 0:e4fe77192b73 292 p->aDown[0].WrOff = 0u;
knaresh89 0:e4fe77192b73 293 p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT;
knaresh89 0:e4fe77192b73 294 //
knaresh89 0:e4fe77192b73 295 // Finish initialization of the control block.
knaresh89 0:e4fe77192b73 296 // Copy Id string in three steps to make sure "SEGGER RTT" is not found
knaresh89 0:e4fe77192b73 297 // in initializer memory (usually flash) by J-Link
knaresh89 0:e4fe77192b73 298 //
knaresh89 0:e4fe77192b73 299 strcpy(&p->acID[7], "RTT");
knaresh89 0:e4fe77192b73 300 strcpy(&p->acID[0], "SEGGER");
knaresh89 0:e4fe77192b73 301 p->acID[6] = ' ';
knaresh89 0:e4fe77192b73 302 }
knaresh89 0:e4fe77192b73 303
knaresh89 0:e4fe77192b73 304 /*********************************************************************
knaresh89 0:e4fe77192b73 305 *
knaresh89 0:e4fe77192b73 306 * _WriteBlocking()
knaresh89 0:e4fe77192b73 307 *
knaresh89 0:e4fe77192b73 308 * Function description
knaresh89 0:e4fe77192b73 309 * Stores a specified number of characters in SEGGER RTT ring buffer
knaresh89 0:e4fe77192b73 310 * and updates the associated write pointer which is periodically
knaresh89 0:e4fe77192b73 311 * read by the host.
knaresh89 0:e4fe77192b73 312 * The caller is responsible for managing the write chunk sizes as
knaresh89 0:e4fe77192b73 313 * _WriteBlocking() will block until all data has been posted successfully.
knaresh89 0:e4fe77192b73 314 *
knaresh89 0:e4fe77192b73 315 * Parameters
knaresh89 0:e4fe77192b73 316 * pRing Ring buffer to post to.
knaresh89 0:e4fe77192b73 317 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
knaresh89 0:e4fe77192b73 318 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
knaresh89 0:e4fe77192b73 319 *
knaresh89 0:e4fe77192b73 320 * Return value
knaresh89 0:e4fe77192b73 321 * >= 0 - Number of bytes written into buffer.
knaresh89 0:e4fe77192b73 322 */
knaresh89 0:e4fe77192b73 323 static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) {
knaresh89 0:e4fe77192b73 324 unsigned NumBytesToWrite;
knaresh89 0:e4fe77192b73 325 unsigned NumBytesWritten;
knaresh89 0:e4fe77192b73 326 unsigned RdOff;
knaresh89 0:e4fe77192b73 327 unsigned WrOff;
knaresh89 0:e4fe77192b73 328 //
knaresh89 0:e4fe77192b73 329 // Write data to buffer and handle wrap-around if necessary
knaresh89 0:e4fe77192b73 330 //
knaresh89 0:e4fe77192b73 331 NumBytesWritten = 0u;
knaresh89 0:e4fe77192b73 332 WrOff = pRing->WrOff;
knaresh89 0:e4fe77192b73 333 do {
knaresh89 0:e4fe77192b73 334 RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime
knaresh89 0:e4fe77192b73 335 if (RdOff > WrOff) {
knaresh89 0:e4fe77192b73 336 NumBytesToWrite = RdOff - WrOff - 1u;
knaresh89 0:e4fe77192b73 337 } else {
knaresh89 0:e4fe77192b73 338 NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u);
knaresh89 0:e4fe77192b73 339 }
knaresh89 0:e4fe77192b73 340 NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around
knaresh89 0:e4fe77192b73 341 NumBytesToWrite = MIN(NumBytesToWrite, NumBytes);
knaresh89 0:e4fe77192b73 342 memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite);
knaresh89 0:e4fe77192b73 343 NumBytesWritten += NumBytesToWrite;
knaresh89 0:e4fe77192b73 344 pBuffer += NumBytesToWrite;
knaresh89 0:e4fe77192b73 345 NumBytes -= NumBytesToWrite;
knaresh89 0:e4fe77192b73 346 WrOff += NumBytesToWrite;
knaresh89 0:e4fe77192b73 347 if (WrOff == pRing->SizeOfBuffer) {
knaresh89 0:e4fe77192b73 348 WrOff = 0u;
knaresh89 0:e4fe77192b73 349 }
knaresh89 0:e4fe77192b73 350 pRing->WrOff = WrOff;
knaresh89 0:e4fe77192b73 351 } while (NumBytes);
knaresh89 0:e4fe77192b73 352 //
knaresh89 0:e4fe77192b73 353 return NumBytesWritten;
knaresh89 0:e4fe77192b73 354 }
knaresh89 0:e4fe77192b73 355
knaresh89 0:e4fe77192b73 356 /*********************************************************************
knaresh89 0:e4fe77192b73 357 *
knaresh89 0:e4fe77192b73 358 * _WriteNoCheck()
knaresh89 0:e4fe77192b73 359 *
knaresh89 0:e4fe77192b73 360 * Function description
knaresh89 0:e4fe77192b73 361 * Stores a specified number of characters in SEGGER RTT ring buffer
knaresh89 0:e4fe77192b73 362 * and updates the associated write pointer which is periodically
knaresh89 0:e4fe77192b73 363 * read by the host.
knaresh89 0:e4fe77192b73 364 * It is callers responsibility to make sure data actually fits in buffer.
knaresh89 0:e4fe77192b73 365 *
knaresh89 0:e4fe77192b73 366 * Parameters
knaresh89 0:e4fe77192b73 367 * pRing Ring buffer to post to.
knaresh89 0:e4fe77192b73 368 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
knaresh89 0:e4fe77192b73 369 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
knaresh89 0:e4fe77192b73 370 *
knaresh89 0:e4fe77192b73 371 * Notes
knaresh89 0:e4fe77192b73 372 * (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking
knaresh89 0:e4fe77192b73 373 */
knaresh89 0:e4fe77192b73 374 static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) {
knaresh89 0:e4fe77192b73 375 unsigned NumBytesAtOnce;
knaresh89 0:e4fe77192b73 376 unsigned WrOff;
knaresh89 0:e4fe77192b73 377 unsigned Rem;
knaresh89 0:e4fe77192b73 378
knaresh89 0:e4fe77192b73 379 WrOff = pRing->WrOff;
knaresh89 0:e4fe77192b73 380 Rem = pRing->SizeOfBuffer - WrOff;
knaresh89 0:e4fe77192b73 381 if (Rem > NumBytes) {
knaresh89 0:e4fe77192b73 382 //
knaresh89 0:e4fe77192b73 383 // All data fits before wrap around
knaresh89 0:e4fe77192b73 384 //
knaresh89 0:e4fe77192b73 385 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
knaresh89 0:e4fe77192b73 386 pRing->WrOff = WrOff + NumBytes;
knaresh89 0:e4fe77192b73 387 } else {
knaresh89 0:e4fe77192b73 388 //
knaresh89 0:e4fe77192b73 389 // We reach the end of the buffer, so need to wrap around
knaresh89 0:e4fe77192b73 390 //
knaresh89 0:e4fe77192b73 391 NumBytesAtOnce = Rem;
knaresh89 0:e4fe77192b73 392 memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce);
knaresh89 0:e4fe77192b73 393 NumBytesAtOnce = NumBytes - Rem;
knaresh89 0:e4fe77192b73 394 memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce);
knaresh89 0:e4fe77192b73 395 pRing->WrOff = NumBytesAtOnce;
knaresh89 0:e4fe77192b73 396 }
knaresh89 0:e4fe77192b73 397 }
knaresh89 0:e4fe77192b73 398
knaresh89 0:e4fe77192b73 399 /*********************************************************************
knaresh89 0:e4fe77192b73 400 *
knaresh89 0:e4fe77192b73 401 * _PostTerminalSwitch()
knaresh89 0:e4fe77192b73 402 *
knaresh89 0:e4fe77192b73 403 * Function description
knaresh89 0:e4fe77192b73 404 * Switch terminal to the given terminal ID. It is the caller's
knaresh89 0:e4fe77192b73 405 * responsibility to ensure the terminal ID is correct and there is
knaresh89 0:e4fe77192b73 406 * enough space in the buffer for this to complete successfully.
knaresh89 0:e4fe77192b73 407 *
knaresh89 0:e4fe77192b73 408 * Parameters
knaresh89 0:e4fe77192b73 409 * pRing Ring buffer to post to.
knaresh89 0:e4fe77192b73 410 * TerminalId Terminal ID to switch to.
knaresh89 0:e4fe77192b73 411 */
knaresh89 0:e4fe77192b73 412 static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) {
knaresh89 0:e4fe77192b73 413 char ac[2];
knaresh89 0:e4fe77192b73 414
knaresh89 0:e4fe77192b73 415 ac[0] = 0xFFu;
knaresh89 0:e4fe77192b73 416 ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit
knaresh89 0:e4fe77192b73 417 _WriteBlocking(pRing, ac, 2u);
knaresh89 0:e4fe77192b73 418 }
knaresh89 0:e4fe77192b73 419
knaresh89 0:e4fe77192b73 420 /*********************************************************************
knaresh89 0:e4fe77192b73 421 *
knaresh89 0:e4fe77192b73 422 * _GetAvailWriteSpace()
knaresh89 0:e4fe77192b73 423 *
knaresh89 0:e4fe77192b73 424 * Function description
knaresh89 0:e4fe77192b73 425 * Returns the number of bytes that can be written to the ring
knaresh89 0:e4fe77192b73 426 * buffer without blocking.
knaresh89 0:e4fe77192b73 427 *
knaresh89 0:e4fe77192b73 428 * Parameters
knaresh89 0:e4fe77192b73 429 * pRing Ring buffer to check.
knaresh89 0:e4fe77192b73 430 *
knaresh89 0:e4fe77192b73 431 * Return value
knaresh89 0:e4fe77192b73 432 * Number of bytes that are free in the buffer.
knaresh89 0:e4fe77192b73 433 */
knaresh89 0:e4fe77192b73 434 static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) {
knaresh89 0:e4fe77192b73 435 unsigned RdOff;
knaresh89 0:e4fe77192b73 436 unsigned WrOff;
knaresh89 0:e4fe77192b73 437 unsigned r;
knaresh89 0:e4fe77192b73 438 //
knaresh89 0:e4fe77192b73 439 // Avoid warnings regarding volatile access order. It's not a problem
knaresh89 0:e4fe77192b73 440 // in this case, but dampen compiler enthusiasm.
knaresh89 0:e4fe77192b73 441 //
knaresh89 0:e4fe77192b73 442 RdOff = pRing->RdOff;
knaresh89 0:e4fe77192b73 443 WrOff = pRing->WrOff;
knaresh89 0:e4fe77192b73 444 if (RdOff <= WrOff) {
knaresh89 0:e4fe77192b73 445 r = pRing->SizeOfBuffer - 1u - WrOff + RdOff;
knaresh89 0:e4fe77192b73 446 } else {
knaresh89 0:e4fe77192b73 447 r = RdOff - WrOff - 1u;
knaresh89 0:e4fe77192b73 448 }
knaresh89 0:e4fe77192b73 449 return r;
knaresh89 0:e4fe77192b73 450 }
knaresh89 0:e4fe77192b73 451
knaresh89 0:e4fe77192b73 452 /*********************************************************************
knaresh89 0:e4fe77192b73 453 *
knaresh89 0:e4fe77192b73 454 * Public code
knaresh89 0:e4fe77192b73 455 *
knaresh89 0:e4fe77192b73 456 **********************************************************************
knaresh89 0:e4fe77192b73 457 */
knaresh89 0:e4fe77192b73 458 /*********************************************************************
knaresh89 0:e4fe77192b73 459 *
knaresh89 0:e4fe77192b73 460 * SEGGER_RTT_ReadNoLock()
knaresh89 0:e4fe77192b73 461 *
knaresh89 0:e4fe77192b73 462 * Function description
knaresh89 0:e4fe77192b73 463 * Reads characters from SEGGER real-time-terminal control block
knaresh89 0:e4fe77192b73 464 * which have been previously stored by the host.
knaresh89 0:e4fe77192b73 465 * Do not lock against interrupts and multiple access.
knaresh89 0:e4fe77192b73 466 *
knaresh89 0:e4fe77192b73 467 * Parameters
knaresh89 0:e4fe77192b73 468 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 469 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
knaresh89 0:e4fe77192b73 470 * BufferSize Size of the target application buffer.
knaresh89 0:e4fe77192b73 471 *
knaresh89 0:e4fe77192b73 472 * Return value
knaresh89 0:e4fe77192b73 473 * Number of bytes that have been read.
knaresh89 0:e4fe77192b73 474 */
knaresh89 0:e4fe77192b73 475 unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
knaresh89 0:e4fe77192b73 476 unsigned NumBytesRem;
knaresh89 0:e4fe77192b73 477 unsigned NumBytesRead;
knaresh89 0:e4fe77192b73 478 unsigned RdOff;
knaresh89 0:e4fe77192b73 479 unsigned WrOff;
knaresh89 0:e4fe77192b73 480 unsigned char* pBuffer;
knaresh89 0:e4fe77192b73 481 SEGGER_RTT_BUFFER_DOWN* pRing;
knaresh89 0:e4fe77192b73 482 //
knaresh89 0:e4fe77192b73 483 INIT();
knaresh89 0:e4fe77192b73 484 pRing = &_SEGGER_RTT.aDown[BufferIndex];
knaresh89 0:e4fe77192b73 485 pBuffer = (unsigned char*)pData;
knaresh89 0:e4fe77192b73 486 RdOff = pRing->RdOff;
knaresh89 0:e4fe77192b73 487 WrOff = pRing->WrOff;
knaresh89 0:e4fe77192b73 488 NumBytesRead = 0u;
knaresh89 0:e4fe77192b73 489 //
knaresh89 0:e4fe77192b73 490 // Read from current read position to wrap-around of buffer, first
knaresh89 0:e4fe77192b73 491 //
knaresh89 0:e4fe77192b73 492 if (RdOff > WrOff) {
knaresh89 0:e4fe77192b73 493 NumBytesRem = pRing->SizeOfBuffer - RdOff;
knaresh89 0:e4fe77192b73 494 NumBytesRem = MIN(NumBytesRem, BufferSize);
knaresh89 0:e4fe77192b73 495 memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
knaresh89 0:e4fe77192b73 496 NumBytesRead += NumBytesRem;
knaresh89 0:e4fe77192b73 497 pBuffer += NumBytesRem;
knaresh89 0:e4fe77192b73 498 BufferSize -= NumBytesRem;
knaresh89 0:e4fe77192b73 499 RdOff += NumBytesRem;
knaresh89 0:e4fe77192b73 500 //
knaresh89 0:e4fe77192b73 501 // Handle wrap-around of buffer
knaresh89 0:e4fe77192b73 502 //
knaresh89 0:e4fe77192b73 503 if (RdOff == pRing->SizeOfBuffer) {
knaresh89 0:e4fe77192b73 504 RdOff = 0u;
knaresh89 0:e4fe77192b73 505 }
knaresh89 0:e4fe77192b73 506 }
knaresh89 0:e4fe77192b73 507 //
knaresh89 0:e4fe77192b73 508 // Read remaining items of buffer
knaresh89 0:e4fe77192b73 509 //
knaresh89 0:e4fe77192b73 510 NumBytesRem = WrOff - RdOff;
knaresh89 0:e4fe77192b73 511 NumBytesRem = MIN(NumBytesRem, BufferSize);
knaresh89 0:e4fe77192b73 512 if (NumBytesRem > 0u) {
knaresh89 0:e4fe77192b73 513 memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem);
knaresh89 0:e4fe77192b73 514 NumBytesRead += NumBytesRem;
knaresh89 0:e4fe77192b73 515 pBuffer += NumBytesRem;
knaresh89 0:e4fe77192b73 516 BufferSize -= NumBytesRem;
knaresh89 0:e4fe77192b73 517 RdOff += NumBytesRem;
knaresh89 0:e4fe77192b73 518 }
knaresh89 0:e4fe77192b73 519 if (NumBytesRead) {
knaresh89 0:e4fe77192b73 520 pRing->RdOff = RdOff;
knaresh89 0:e4fe77192b73 521 }
knaresh89 0:e4fe77192b73 522 //
knaresh89 0:e4fe77192b73 523 return NumBytesRead;
knaresh89 0:e4fe77192b73 524 }
knaresh89 0:e4fe77192b73 525
knaresh89 0:e4fe77192b73 526 /*********************************************************************
knaresh89 0:e4fe77192b73 527 *
knaresh89 0:e4fe77192b73 528 * SEGGER_RTT_Read
knaresh89 0:e4fe77192b73 529 *
knaresh89 0:e4fe77192b73 530 * Function description
knaresh89 0:e4fe77192b73 531 * Reads characters from SEGGER real-time-terminal control block
knaresh89 0:e4fe77192b73 532 * which have been previously stored by the host.
knaresh89 0:e4fe77192b73 533 *
knaresh89 0:e4fe77192b73 534 * Parameters
knaresh89 0:e4fe77192b73 535 * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 536 * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
knaresh89 0:e4fe77192b73 537 * BufferSize Size of the target application buffer.
knaresh89 0:e4fe77192b73 538 *
knaresh89 0:e4fe77192b73 539 * Return value
knaresh89 0:e4fe77192b73 540 * Number of bytes that have been read.
knaresh89 0:e4fe77192b73 541 */
knaresh89 0:e4fe77192b73 542 unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) {
knaresh89 0:e4fe77192b73 543 unsigned NumBytesRead;
knaresh89 0:e4fe77192b73 544 //
knaresh89 0:e4fe77192b73 545 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 546 //
knaresh89 0:e4fe77192b73 547 // Call the non-locking read function
knaresh89 0:e4fe77192b73 548 //
knaresh89 0:e4fe77192b73 549 NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize);
knaresh89 0:e4fe77192b73 550 //
knaresh89 0:e4fe77192b73 551 // Finish up.
knaresh89 0:e4fe77192b73 552 //
knaresh89 0:e4fe77192b73 553 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 554 //
knaresh89 0:e4fe77192b73 555 return NumBytesRead;
knaresh89 0:e4fe77192b73 556 }
knaresh89 0:e4fe77192b73 557
knaresh89 0:e4fe77192b73 558 /*********************************************************************
knaresh89 0:e4fe77192b73 559 *
knaresh89 0:e4fe77192b73 560 * SEGGER_RTT_WriteWithOverwriteNoLock
knaresh89 0:e4fe77192b73 561 *
knaresh89 0:e4fe77192b73 562 * Function description
knaresh89 0:e4fe77192b73 563 * Stores a specified number of characters in SEGGER RTT
knaresh89 0:e4fe77192b73 564 * control block.
knaresh89 0:e4fe77192b73 565 * SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application
knaresh89 0:e4fe77192b73 566 * and overwrites data if the data does not fit into the buffer.
knaresh89 0:e4fe77192b73 567 *
knaresh89 0:e4fe77192b73 568 * Parameters
knaresh89 0:e4fe77192b73 569 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 570 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
knaresh89 0:e4fe77192b73 571 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
knaresh89 0:e4fe77192b73 572 *
knaresh89 0:e4fe77192b73 573 * Notes
knaresh89 0:e4fe77192b73 574 * (1) If there is not enough space in the "Up"-buffer, data is overwritten.
knaresh89 0:e4fe77192b73 575 * (2) For performance reasons this function does not call Init()
knaresh89 0:e4fe77192b73 576 * and may only be called after RTT has been initialized.
knaresh89 0:e4fe77192b73 577 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
knaresh89 0:e4fe77192b73 578 * (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link
knaresh89 0:e4fe77192b73 579 * connection reads RTT data.
knaresh89 0:e4fe77192b73 580 */
knaresh89 0:e4fe77192b73 581 void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
knaresh89 0:e4fe77192b73 582 const char* pData;
knaresh89 0:e4fe77192b73 583 SEGGER_RTT_BUFFER_UP* pRing;
knaresh89 0:e4fe77192b73 584 unsigned Avail;
knaresh89 0:e4fe77192b73 585
knaresh89 0:e4fe77192b73 586 pData = (const char *)pBuffer;
knaresh89 0:e4fe77192b73 587 //
knaresh89 0:e4fe77192b73 588 // Get "to-host" ring buffer and copy some elements into local variables.
knaresh89 0:e4fe77192b73 589 //
knaresh89 0:e4fe77192b73 590 pRing = &_SEGGER_RTT.aUp[BufferIndex];
knaresh89 0:e4fe77192b73 591 //
knaresh89 0:e4fe77192b73 592 // Check if we will overwrite data and need to adjust the RdOff.
knaresh89 0:e4fe77192b73 593 //
knaresh89 0:e4fe77192b73 594 if (pRing->WrOff == pRing->RdOff) {
knaresh89 0:e4fe77192b73 595 Avail = pRing->SizeOfBuffer - 1u;
knaresh89 0:e4fe77192b73 596 } else if ( pRing->WrOff < pRing->RdOff) {
knaresh89 0:e4fe77192b73 597 Avail = pRing->RdOff - pRing->WrOff - 1u;
knaresh89 0:e4fe77192b73 598 } else {
knaresh89 0:e4fe77192b73 599 Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer;
knaresh89 0:e4fe77192b73 600 }
knaresh89 0:e4fe77192b73 601 if (NumBytes > Avail) {
knaresh89 0:e4fe77192b73 602 pRing->RdOff += (NumBytes - Avail);
knaresh89 0:e4fe77192b73 603 while (pRing->RdOff >= pRing->SizeOfBuffer) {
knaresh89 0:e4fe77192b73 604 pRing->RdOff -= pRing->SizeOfBuffer;
knaresh89 0:e4fe77192b73 605 }
knaresh89 0:e4fe77192b73 606 }
knaresh89 0:e4fe77192b73 607 //
knaresh89 0:e4fe77192b73 608 // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds
knaresh89 0:e4fe77192b73 609 //
knaresh89 0:e4fe77192b73 610 Avail = pRing->SizeOfBuffer - pRing->WrOff;
knaresh89 0:e4fe77192b73 611 do {
knaresh89 0:e4fe77192b73 612 if (Avail > NumBytes) {
knaresh89 0:e4fe77192b73 613 //
knaresh89 0:e4fe77192b73 614 // Last round
knaresh89 0:e4fe77192b73 615 //
knaresh89 0:e4fe77192b73 616 #if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead.
knaresh89 0:e4fe77192b73 617 char* pDst;
knaresh89 0:e4fe77192b73 618 pDst = pRing->pBuffer + pRing->WrOff;
knaresh89 0:e4fe77192b73 619 pRing->WrOff += NumBytes;
knaresh89 0:e4fe77192b73 620 do {
knaresh89 0:e4fe77192b73 621 *pDst++ = *pData++;
knaresh89 0:e4fe77192b73 622 } while (--NumBytes);
knaresh89 0:e4fe77192b73 623 #else
knaresh89 0:e4fe77192b73 624 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
knaresh89 0:e4fe77192b73 625 pRing->WrOff += NumBytes;
knaresh89 0:e4fe77192b73 626 #endif
knaresh89 0:e4fe77192b73 627 break; //Alternatively: NumBytes = 0;
knaresh89 0:e4fe77192b73 628 } else {
knaresh89 0:e4fe77192b73 629 //
knaresh89 0:e4fe77192b73 630 // Wrap-around necessary, write until wrap-around and reset WrOff
knaresh89 0:e4fe77192b73 631 //
knaresh89 0:e4fe77192b73 632 memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail);
knaresh89 0:e4fe77192b73 633 pData += Avail;
knaresh89 0:e4fe77192b73 634 pRing->WrOff = 0;
knaresh89 0:e4fe77192b73 635 NumBytes -= Avail;
knaresh89 0:e4fe77192b73 636 Avail = (pRing->SizeOfBuffer - 1);
knaresh89 0:e4fe77192b73 637 }
knaresh89 0:e4fe77192b73 638 } while (NumBytes);
knaresh89 0:e4fe77192b73 639 }
knaresh89 0:e4fe77192b73 640
knaresh89 0:e4fe77192b73 641 /*********************************************************************
knaresh89 0:e4fe77192b73 642 *
knaresh89 0:e4fe77192b73 643 * SEGGER_RTT_WriteSkipNoLock
knaresh89 0:e4fe77192b73 644 *
knaresh89 0:e4fe77192b73 645 * Function description
knaresh89 0:e4fe77192b73 646 * Stores a specified number of characters in SEGGER RTT
knaresh89 0:e4fe77192b73 647 * control block which is then read by the host.
knaresh89 0:e4fe77192b73 648 * SEGGER_RTT_WriteSkipNoLock does not lock the application and
knaresh89 0:e4fe77192b73 649 * skips all data, if the data does not fit into the buffer.
knaresh89 0:e4fe77192b73 650 *
knaresh89 0:e4fe77192b73 651 * Parameters
knaresh89 0:e4fe77192b73 652 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 653 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
knaresh89 0:e4fe77192b73 654 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
knaresh89 0:e4fe77192b73 655 *
knaresh89 0:e4fe77192b73 656 * Return value
knaresh89 0:e4fe77192b73 657 * Number of bytes which have been stored in the "Up"-buffer.
knaresh89 0:e4fe77192b73 658 *
knaresh89 0:e4fe77192b73 659 * Notes
knaresh89 0:e4fe77192b73 660 * (1) If there is not enough space in the "Up"-buffer, all data is dropped.
knaresh89 0:e4fe77192b73 661 * (2) For performance reasons this function does not call Init()
knaresh89 0:e4fe77192b73 662 * and may only be called after RTT has been initialized.
knaresh89 0:e4fe77192b73 663 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
knaresh89 0:e4fe77192b73 664 */
knaresh89 0:e4fe77192b73 665 unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
knaresh89 0:e4fe77192b73 666 const char* pData;
knaresh89 0:e4fe77192b73 667 SEGGER_RTT_BUFFER_UP* pRing;
knaresh89 0:e4fe77192b73 668 unsigned Avail;
knaresh89 0:e4fe77192b73 669 unsigned RdOff;
knaresh89 0:e4fe77192b73 670 unsigned WrOff;
knaresh89 0:e4fe77192b73 671 unsigned Rem;
knaresh89 0:e4fe77192b73 672
knaresh89 0:e4fe77192b73 673 pData = (const char *)pBuffer;
knaresh89 0:e4fe77192b73 674 //
knaresh89 0:e4fe77192b73 675 // Get "to-host" ring buffer and copy some elements into local variables.
knaresh89 0:e4fe77192b73 676 //
knaresh89 0:e4fe77192b73 677 pRing = &_SEGGER_RTT.aUp[BufferIndex];
knaresh89 0:e4fe77192b73 678 RdOff = pRing->RdOff;
knaresh89 0:e4fe77192b73 679 WrOff = pRing->WrOff;
knaresh89 0:e4fe77192b73 680 //
knaresh89 0:e4fe77192b73 681 // Handle the most common cases fastest.
knaresh89 0:e4fe77192b73 682 // Which is:
knaresh89 0:e4fe77192b73 683 // RdOff <= WrOff -> Space until wrap around is free.
knaresh89 0:e4fe77192b73 684 // AND
knaresh89 0:e4fe77192b73 685 // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary.
knaresh89 0:e4fe77192b73 686 //
knaresh89 0:e4fe77192b73 687 // OR
knaresh89 0:e4fe77192b73 688 //
knaresh89 0:e4fe77192b73 689 // RdOff > WrOff -> Space until RdOff - 1 is free.
knaresh89 0:e4fe77192b73 690 // AND
knaresh89 0:e4fe77192b73 691 // WrOff + NumBytes < RdOff -> Data fits into buffer
knaresh89 0:e4fe77192b73 692 //
knaresh89 0:e4fe77192b73 693 if (RdOff <= WrOff) {
knaresh89 0:e4fe77192b73 694 //
knaresh89 0:e4fe77192b73 695 // Get space until WrOff will be at wrap around.
knaresh89 0:e4fe77192b73 696 //
knaresh89 0:e4fe77192b73 697 Avail = pRing->SizeOfBuffer - 1u - WrOff ;
knaresh89 0:e4fe77192b73 698 if (Avail >= NumBytes) {
knaresh89 0:e4fe77192b73 699 #if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead.
knaresh89 0:e4fe77192b73 700 char* pDst;
knaresh89 0:e4fe77192b73 701 pDst = pRing->pBuffer + WrOff;
knaresh89 0:e4fe77192b73 702 WrOff += NumBytes;
knaresh89 0:e4fe77192b73 703 do {
knaresh89 0:e4fe77192b73 704 *pDst++ = *pData++;
knaresh89 0:e4fe77192b73 705 } while (--NumBytes);
knaresh89 0:e4fe77192b73 706 pRing->WrOff = WrOff + NumBytes;
knaresh89 0:e4fe77192b73 707 #else
knaresh89 0:e4fe77192b73 708 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
knaresh89 0:e4fe77192b73 709 pRing->WrOff = WrOff + NumBytes;
knaresh89 0:e4fe77192b73 710 #endif
knaresh89 0:e4fe77192b73 711 return 1;
knaresh89 0:e4fe77192b73 712 }
knaresh89 0:e4fe77192b73 713 //
knaresh89 0:e4fe77192b73 714 // If data did not fit into space until wrap around calculate complete space in buffer.
knaresh89 0:e4fe77192b73 715 //
knaresh89 0:e4fe77192b73 716 Avail += RdOff;
knaresh89 0:e4fe77192b73 717 //
knaresh89 0:e4fe77192b73 718 // If there is still no space for the whole of this output, don't bother.
knaresh89 0:e4fe77192b73 719 //
knaresh89 0:e4fe77192b73 720 if (Avail >= NumBytes) {
knaresh89 0:e4fe77192b73 721 //
knaresh89 0:e4fe77192b73 722 // OK, we have enough space in buffer. Copy in one or 2 chunks
knaresh89 0:e4fe77192b73 723 //
knaresh89 0:e4fe77192b73 724 Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer
knaresh89 0:e4fe77192b73 725 if (Rem > NumBytes) {
knaresh89 0:e4fe77192b73 726 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
knaresh89 0:e4fe77192b73 727 pRing->WrOff = WrOff + NumBytes;
knaresh89 0:e4fe77192b73 728 } else {
knaresh89 0:e4fe77192b73 729 //
knaresh89 0:e4fe77192b73 730 // We reach the end of the buffer, so need to wrap around
knaresh89 0:e4fe77192b73 731 //
knaresh89 0:e4fe77192b73 732 memcpy(pRing->pBuffer + WrOff, pData, Rem);
knaresh89 0:e4fe77192b73 733 memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem);
knaresh89 0:e4fe77192b73 734 pRing->WrOff = NumBytes - Rem;
knaresh89 0:e4fe77192b73 735 }
knaresh89 0:e4fe77192b73 736 return 1;
knaresh89 0:e4fe77192b73 737 }
knaresh89 0:e4fe77192b73 738 } else {
knaresh89 0:e4fe77192b73 739 Avail = RdOff - WrOff - 1u;
knaresh89 0:e4fe77192b73 740 if (Avail >= NumBytes) {
knaresh89 0:e4fe77192b73 741 memcpy(pRing->pBuffer + WrOff, pData, NumBytes);
knaresh89 0:e4fe77192b73 742 pRing->WrOff = WrOff + NumBytes;
knaresh89 0:e4fe77192b73 743 return 1;
knaresh89 0:e4fe77192b73 744 }
knaresh89 0:e4fe77192b73 745 }
knaresh89 0:e4fe77192b73 746 //
knaresh89 0:e4fe77192b73 747 // If we reach this point no data has been written
knaresh89 0:e4fe77192b73 748 //
knaresh89 0:e4fe77192b73 749 return 0;
knaresh89 0:e4fe77192b73 750 }
knaresh89 0:e4fe77192b73 751
knaresh89 0:e4fe77192b73 752 /*********************************************************************
knaresh89 0:e4fe77192b73 753 *
knaresh89 0:e4fe77192b73 754 * SEGGER_RTT_WriteNoLock
knaresh89 0:e4fe77192b73 755 *
knaresh89 0:e4fe77192b73 756 * Function description
knaresh89 0:e4fe77192b73 757 * Stores a specified number of characters in SEGGER RTT
knaresh89 0:e4fe77192b73 758 * control block which is then read by the host.
knaresh89 0:e4fe77192b73 759 * SEGGER_RTT_WriteNoLock does not lock the application.
knaresh89 0:e4fe77192b73 760 *
knaresh89 0:e4fe77192b73 761 * Parameters
knaresh89 0:e4fe77192b73 762 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 763 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
knaresh89 0:e4fe77192b73 764 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
knaresh89 0:e4fe77192b73 765 *
knaresh89 0:e4fe77192b73 766 * Return value
knaresh89 0:e4fe77192b73 767 * Number of bytes which have been stored in the "Up"-buffer.
knaresh89 0:e4fe77192b73 768 *
knaresh89 0:e4fe77192b73 769 * Notes
knaresh89 0:e4fe77192b73 770 * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
knaresh89 0:e4fe77192b73 771 * (2) For performance reasons this function does not call Init()
knaresh89 0:e4fe77192b73 772 * and may only be called after RTT has been initialized.
knaresh89 0:e4fe77192b73 773 * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
knaresh89 0:e4fe77192b73 774 */
knaresh89 0:e4fe77192b73 775 unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
knaresh89 0:e4fe77192b73 776 unsigned Status;
knaresh89 0:e4fe77192b73 777 unsigned Avail;
knaresh89 0:e4fe77192b73 778 const char* pData;
knaresh89 0:e4fe77192b73 779 SEGGER_RTT_BUFFER_UP* pRing;
knaresh89 0:e4fe77192b73 780
knaresh89 0:e4fe77192b73 781 pData = (const char *)pBuffer;
knaresh89 0:e4fe77192b73 782 //
knaresh89 0:e4fe77192b73 783 // Get "to-host" ring buffer.
knaresh89 0:e4fe77192b73 784 //
knaresh89 0:e4fe77192b73 785 pRing = &_SEGGER_RTT.aUp[BufferIndex];
knaresh89 0:e4fe77192b73 786 //
knaresh89 0:e4fe77192b73 787 // How we output depends upon the mode...
knaresh89 0:e4fe77192b73 788 //
knaresh89 0:e4fe77192b73 789 switch (pRing->Flags) {
knaresh89 0:e4fe77192b73 790 case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
knaresh89 0:e4fe77192b73 791 //
knaresh89 0:e4fe77192b73 792 // If we are in skip mode and there is no space for the whole
knaresh89 0:e4fe77192b73 793 // of this output, don't bother.
knaresh89 0:e4fe77192b73 794 //
knaresh89 0:e4fe77192b73 795 Avail = _GetAvailWriteSpace(pRing);
knaresh89 0:e4fe77192b73 796 if (Avail < NumBytes) {
knaresh89 0:e4fe77192b73 797 Status = 0u;
knaresh89 0:e4fe77192b73 798 } else {
knaresh89 0:e4fe77192b73 799 Status = NumBytes;
knaresh89 0:e4fe77192b73 800 _WriteNoCheck(pRing, pData, NumBytes);
knaresh89 0:e4fe77192b73 801 }
knaresh89 0:e4fe77192b73 802 break;
knaresh89 0:e4fe77192b73 803 case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
knaresh89 0:e4fe77192b73 804 //
knaresh89 0:e4fe77192b73 805 // If we are in trim mode, trim to what we can output without blocking.
knaresh89 0:e4fe77192b73 806 //
knaresh89 0:e4fe77192b73 807 Avail = _GetAvailWriteSpace(pRing);
knaresh89 0:e4fe77192b73 808 Status = Avail < NumBytes ? Avail : NumBytes;
knaresh89 0:e4fe77192b73 809 _WriteNoCheck(pRing, pData, Status);
knaresh89 0:e4fe77192b73 810 break;
knaresh89 0:e4fe77192b73 811 case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
knaresh89 0:e4fe77192b73 812 //
knaresh89 0:e4fe77192b73 813 // If we are in blocking mode, output everything.
knaresh89 0:e4fe77192b73 814 //
knaresh89 0:e4fe77192b73 815 Status = _WriteBlocking(pRing, pData, NumBytes);
knaresh89 0:e4fe77192b73 816 break;
knaresh89 0:e4fe77192b73 817 default:
knaresh89 0:e4fe77192b73 818 Status = 0u;
knaresh89 0:e4fe77192b73 819 break;
knaresh89 0:e4fe77192b73 820 }
knaresh89 0:e4fe77192b73 821 //
knaresh89 0:e4fe77192b73 822 // Finish up.
knaresh89 0:e4fe77192b73 823 //
knaresh89 0:e4fe77192b73 824 return Status;
knaresh89 0:e4fe77192b73 825 }
knaresh89 0:e4fe77192b73 826
knaresh89 0:e4fe77192b73 827 /*********************************************************************
knaresh89 0:e4fe77192b73 828 *
knaresh89 0:e4fe77192b73 829 * SEGGER_RTT_Write
knaresh89 0:e4fe77192b73 830 *
knaresh89 0:e4fe77192b73 831 * Function description
knaresh89 0:e4fe77192b73 832 * Stores a specified number of characters in SEGGER RTT
knaresh89 0:e4fe77192b73 833 * control block which is then read by the host.
knaresh89 0:e4fe77192b73 834 *
knaresh89 0:e4fe77192b73 835 * Parameters
knaresh89 0:e4fe77192b73 836 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 837 * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
knaresh89 0:e4fe77192b73 838 * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
knaresh89 0:e4fe77192b73 839 *
knaresh89 0:e4fe77192b73 840 * Return value
knaresh89 0:e4fe77192b73 841 * Number of bytes which have been stored in the "Up"-buffer.
knaresh89 0:e4fe77192b73 842 *
knaresh89 0:e4fe77192b73 843 * Notes
knaresh89 0:e4fe77192b73 844 * (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped.
knaresh89 0:e4fe77192b73 845 */
knaresh89 0:e4fe77192b73 846 unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
knaresh89 0:e4fe77192b73 847 unsigned Status;
knaresh89 0:e4fe77192b73 848 //
knaresh89 0:e4fe77192b73 849 INIT();
knaresh89 0:e4fe77192b73 850 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 851 //
knaresh89 0:e4fe77192b73 852 // Call the non-locking write function
knaresh89 0:e4fe77192b73 853 //
knaresh89 0:e4fe77192b73 854 Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes);
knaresh89 0:e4fe77192b73 855 //
knaresh89 0:e4fe77192b73 856 // Finish up.
knaresh89 0:e4fe77192b73 857 //
knaresh89 0:e4fe77192b73 858 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 859 //
knaresh89 0:e4fe77192b73 860 return Status;
knaresh89 0:e4fe77192b73 861 }
knaresh89 0:e4fe77192b73 862
knaresh89 0:e4fe77192b73 863 /*********************************************************************
knaresh89 0:e4fe77192b73 864 *
knaresh89 0:e4fe77192b73 865 * SEGGER_RTT_WriteString
knaresh89 0:e4fe77192b73 866 *
knaresh89 0:e4fe77192b73 867 * Function description
knaresh89 0:e4fe77192b73 868 * Stores string in SEGGER RTT control block.
knaresh89 0:e4fe77192b73 869 * This data is read by the host.
knaresh89 0:e4fe77192b73 870 *
knaresh89 0:e4fe77192b73 871 * Parameters
knaresh89 0:e4fe77192b73 872 * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
knaresh89 0:e4fe77192b73 873 * s Pointer to string.
knaresh89 0:e4fe77192b73 874 *
knaresh89 0:e4fe77192b73 875 * Return value
knaresh89 0:e4fe77192b73 876 * Number of bytes which have been stored in the "Up"-buffer.
knaresh89 0:e4fe77192b73 877 *
knaresh89 0:e4fe77192b73 878 * Notes
knaresh89 0:e4fe77192b73 879 * (1) If there is not enough space in the "Up"-buffer, depending on configuration,
knaresh89 0:e4fe77192b73 880 * remaining characters may be dropped or RTT module waits until there is more space in the buffer.
knaresh89 0:e4fe77192b73 881 * (2) String passed to this function has to be \0 terminated
knaresh89 0:e4fe77192b73 882 * (3) \0 termination character is *not* stored in RTT buffer
knaresh89 0:e4fe77192b73 883 */
knaresh89 0:e4fe77192b73 884 unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) {
knaresh89 0:e4fe77192b73 885 unsigned Len;
knaresh89 0:e4fe77192b73 886
knaresh89 0:e4fe77192b73 887 Len = STRLEN(s);
knaresh89 0:e4fe77192b73 888 return SEGGER_RTT_Write(BufferIndex, s, Len);
knaresh89 0:e4fe77192b73 889 }
knaresh89 0:e4fe77192b73 890
knaresh89 0:e4fe77192b73 891 /*********************************************************************
knaresh89 0:e4fe77192b73 892 *
knaresh89 0:e4fe77192b73 893 * SEGGER_RTT_GetKey
knaresh89 0:e4fe77192b73 894 *
knaresh89 0:e4fe77192b73 895 * Function description
knaresh89 0:e4fe77192b73 896 * Reads one character from the SEGGER RTT buffer.
knaresh89 0:e4fe77192b73 897 * Host has previously stored data there.
knaresh89 0:e4fe77192b73 898 *
knaresh89 0:e4fe77192b73 899 * Return value
knaresh89 0:e4fe77192b73 900 * < 0 - No character available (buffer empty).
knaresh89 0:e4fe77192b73 901 * >= 0 - Character which has been read. (Possible values: 0 - 255)
knaresh89 0:e4fe77192b73 902 *
knaresh89 0:e4fe77192b73 903 * Notes
knaresh89 0:e4fe77192b73 904 * (1) This function is only specified for accesses to RTT buffer 0.
knaresh89 0:e4fe77192b73 905 */
knaresh89 0:e4fe77192b73 906 int SEGGER_RTT_GetKey(void) {
knaresh89 0:e4fe77192b73 907 char c;
knaresh89 0:e4fe77192b73 908 int r;
knaresh89 0:e4fe77192b73 909
knaresh89 0:e4fe77192b73 910 r = (int)SEGGER_RTT_Read(0u, &c, 1u);
knaresh89 0:e4fe77192b73 911 if (r == 1) {
knaresh89 0:e4fe77192b73 912 r = (int)(unsigned char)c;
knaresh89 0:e4fe77192b73 913 } else {
knaresh89 0:e4fe77192b73 914 r = -1;
knaresh89 0:e4fe77192b73 915 }
knaresh89 0:e4fe77192b73 916 return r;
knaresh89 0:e4fe77192b73 917 }
knaresh89 0:e4fe77192b73 918
knaresh89 0:e4fe77192b73 919 /*********************************************************************
knaresh89 0:e4fe77192b73 920 *
knaresh89 0:e4fe77192b73 921 * SEGGER_RTT_WaitKey
knaresh89 0:e4fe77192b73 922 *
knaresh89 0:e4fe77192b73 923 * Function description
knaresh89 0:e4fe77192b73 924 * Waits until at least one character is avaible in the SEGGER RTT buffer.
knaresh89 0:e4fe77192b73 925 * Once a character is available, it is read and this function returns.
knaresh89 0:e4fe77192b73 926 *
knaresh89 0:e4fe77192b73 927 * Return value
knaresh89 0:e4fe77192b73 928 * >=0 - Character which has been read.
knaresh89 0:e4fe77192b73 929 *
knaresh89 0:e4fe77192b73 930 * Notes
knaresh89 0:e4fe77192b73 931 * (1) This function is only specified for accesses to RTT buffer 0
knaresh89 0:e4fe77192b73 932 * (2) This function is blocking if no character is present in RTT buffer
knaresh89 0:e4fe77192b73 933 */
knaresh89 0:e4fe77192b73 934 int SEGGER_RTT_WaitKey(void) {
knaresh89 0:e4fe77192b73 935 int r;
knaresh89 0:e4fe77192b73 936
knaresh89 0:e4fe77192b73 937 do {
knaresh89 0:e4fe77192b73 938 r = SEGGER_RTT_GetKey();
knaresh89 0:e4fe77192b73 939 } while (r < 0);
knaresh89 0:e4fe77192b73 940 return r;
knaresh89 0:e4fe77192b73 941 }
knaresh89 0:e4fe77192b73 942
knaresh89 0:e4fe77192b73 943 /*********************************************************************
knaresh89 0:e4fe77192b73 944 *
knaresh89 0:e4fe77192b73 945 * SEGGER_RTT_HasKey
knaresh89 0:e4fe77192b73 946 *
knaresh89 0:e4fe77192b73 947 * Function description
knaresh89 0:e4fe77192b73 948 * Checks if at least one character for reading is available in the SEGGER RTT buffer.
knaresh89 0:e4fe77192b73 949 *
knaresh89 0:e4fe77192b73 950 * Return value
knaresh89 0:e4fe77192b73 951 * == 0 - No characters are available to read.
knaresh89 0:e4fe77192b73 952 * == 1 - At least one character is available.
knaresh89 0:e4fe77192b73 953 *
knaresh89 0:e4fe77192b73 954 * Notes
knaresh89 0:e4fe77192b73 955 * (1) This function is only specified for accesses to RTT buffer 0
knaresh89 0:e4fe77192b73 956 */
knaresh89 0:e4fe77192b73 957 int SEGGER_RTT_HasKey(void) {
knaresh89 0:e4fe77192b73 958 unsigned RdOff;
knaresh89 0:e4fe77192b73 959 int r;
knaresh89 0:e4fe77192b73 960
knaresh89 0:e4fe77192b73 961 INIT();
knaresh89 0:e4fe77192b73 962 RdOff = _SEGGER_RTT.aDown[0].RdOff;
knaresh89 0:e4fe77192b73 963 if (RdOff != _SEGGER_RTT.aDown[0].WrOff) {
knaresh89 0:e4fe77192b73 964 r = 1;
knaresh89 0:e4fe77192b73 965 } else {
knaresh89 0:e4fe77192b73 966 r = 0;
knaresh89 0:e4fe77192b73 967 }
knaresh89 0:e4fe77192b73 968 return r;
knaresh89 0:e4fe77192b73 969 }
knaresh89 0:e4fe77192b73 970
knaresh89 0:e4fe77192b73 971 /*********************************************************************
knaresh89 0:e4fe77192b73 972 *
knaresh89 0:e4fe77192b73 973 * SEGGER_RTT_HasData
knaresh89 0:e4fe77192b73 974 *
knaresh89 0:e4fe77192b73 975 * Function description
knaresh89 0:e4fe77192b73 976 * Check if there is data from the host in the given buffer.
knaresh89 0:e4fe77192b73 977 *
knaresh89 0:e4fe77192b73 978 * Return value:
knaresh89 0:e4fe77192b73 979 * ==0: No data
knaresh89 0:e4fe77192b73 980 * !=0: Data in buffer
knaresh89 0:e4fe77192b73 981 *
knaresh89 0:e4fe77192b73 982 */
knaresh89 0:e4fe77192b73 983 unsigned SEGGER_RTT_HasData(unsigned BufferIndex) {
knaresh89 0:e4fe77192b73 984 SEGGER_RTT_BUFFER_DOWN* pRing;
knaresh89 0:e4fe77192b73 985 unsigned v;
knaresh89 0:e4fe77192b73 986
knaresh89 0:e4fe77192b73 987 pRing = &_SEGGER_RTT.aDown[BufferIndex];
knaresh89 0:e4fe77192b73 988 v = pRing->WrOff;
knaresh89 0:e4fe77192b73 989 return v - pRing->RdOff;
knaresh89 0:e4fe77192b73 990 }
knaresh89 0:e4fe77192b73 991
knaresh89 0:e4fe77192b73 992 /*********************************************************************
knaresh89 0:e4fe77192b73 993 *
knaresh89 0:e4fe77192b73 994 * SEGGER_RTT_AllocDownBuffer
knaresh89 0:e4fe77192b73 995 *
knaresh89 0:e4fe77192b73 996 * Function description
knaresh89 0:e4fe77192b73 997 * Run-time configuration of the next down-buffer (H->T).
knaresh89 0:e4fe77192b73 998 * The next buffer, which is not used yet is configured.
knaresh89 0:e4fe77192b73 999 * This includes: Buffer address, size, name, flags, ...
knaresh89 0:e4fe77192b73 1000 *
knaresh89 0:e4fe77192b73 1001 * Parameters
knaresh89 0:e4fe77192b73 1002 * sName Pointer to a constant name string.
knaresh89 0:e4fe77192b73 1003 * pBuffer Pointer to a buffer to be used.
knaresh89 0:e4fe77192b73 1004 * BufferSize Size of the buffer.
knaresh89 0:e4fe77192b73 1005 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
knaresh89 0:e4fe77192b73 1006 *
knaresh89 0:e4fe77192b73 1007 * Return value
knaresh89 0:e4fe77192b73 1008 * >= 0 - O.K. Buffer Index
knaresh89 0:e4fe77192b73 1009 * < 0 - Error
knaresh89 0:e4fe77192b73 1010 */
knaresh89 0:e4fe77192b73 1011 int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
knaresh89 0:e4fe77192b73 1012 int BufferIndex;
knaresh89 0:e4fe77192b73 1013
knaresh89 0:e4fe77192b73 1014 INIT();
knaresh89 0:e4fe77192b73 1015 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1016 BufferIndex = 0;
knaresh89 0:e4fe77192b73 1017 do {
knaresh89 0:e4fe77192b73 1018 if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) {
knaresh89 0:e4fe77192b73 1019 break;
knaresh89 0:e4fe77192b73 1020 }
knaresh89 0:e4fe77192b73 1021 BufferIndex++;
knaresh89 0:e4fe77192b73 1022 } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers);
knaresh89 0:e4fe77192b73 1023 if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) {
knaresh89 0:e4fe77192b73 1024 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
knaresh89 0:e4fe77192b73 1025 _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
knaresh89 0:e4fe77192b73 1026 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
knaresh89 0:e4fe77192b73 1027 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
knaresh89 0:e4fe77192b73 1028 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
knaresh89 0:e4fe77192b73 1029 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
knaresh89 0:e4fe77192b73 1030 } else {
knaresh89 0:e4fe77192b73 1031 BufferIndex = -1;
knaresh89 0:e4fe77192b73 1032 }
knaresh89 0:e4fe77192b73 1033 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1034 return BufferIndex;
knaresh89 0:e4fe77192b73 1035 }
knaresh89 0:e4fe77192b73 1036
knaresh89 0:e4fe77192b73 1037 /*********************************************************************
knaresh89 0:e4fe77192b73 1038 *
knaresh89 0:e4fe77192b73 1039 * SEGGER_RTT_AllocUpBuffer
knaresh89 0:e4fe77192b73 1040 *
knaresh89 0:e4fe77192b73 1041 * Function description
knaresh89 0:e4fe77192b73 1042 * Run-time configuration of the next up-buffer (T->H).
knaresh89 0:e4fe77192b73 1043 * The next buffer, which is not used yet is configured.
knaresh89 0:e4fe77192b73 1044 * This includes: Buffer address, size, name, flags, ...
knaresh89 0:e4fe77192b73 1045 *
knaresh89 0:e4fe77192b73 1046 * Parameters
knaresh89 0:e4fe77192b73 1047 * sName Pointer to a constant name string.
knaresh89 0:e4fe77192b73 1048 * pBuffer Pointer to a buffer to be used.
knaresh89 0:e4fe77192b73 1049 * BufferSize Size of the buffer.
knaresh89 0:e4fe77192b73 1050 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
knaresh89 0:e4fe77192b73 1051 *
knaresh89 0:e4fe77192b73 1052 * Return value
knaresh89 0:e4fe77192b73 1053 * >= 0 - O.K. Buffer Index
knaresh89 0:e4fe77192b73 1054 * < 0 - Error
knaresh89 0:e4fe77192b73 1055 */
knaresh89 0:e4fe77192b73 1056 int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
knaresh89 0:e4fe77192b73 1057 int BufferIndex;
knaresh89 0:e4fe77192b73 1058
knaresh89 0:e4fe77192b73 1059 INIT();
knaresh89 0:e4fe77192b73 1060 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1061 BufferIndex = 0;
knaresh89 0:e4fe77192b73 1062 do {
knaresh89 0:e4fe77192b73 1063 if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) {
knaresh89 0:e4fe77192b73 1064 break;
knaresh89 0:e4fe77192b73 1065 }
knaresh89 0:e4fe77192b73 1066 BufferIndex++;
knaresh89 0:e4fe77192b73 1067 } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers);
knaresh89 0:e4fe77192b73 1068 if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) {
knaresh89 0:e4fe77192b73 1069 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
knaresh89 0:e4fe77192b73 1070 _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
knaresh89 0:e4fe77192b73 1071 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
knaresh89 0:e4fe77192b73 1072 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
knaresh89 0:e4fe77192b73 1073 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
knaresh89 0:e4fe77192b73 1074 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
knaresh89 0:e4fe77192b73 1075 } else {
knaresh89 0:e4fe77192b73 1076 BufferIndex = -1;
knaresh89 0:e4fe77192b73 1077 }
knaresh89 0:e4fe77192b73 1078 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1079 return BufferIndex;
knaresh89 0:e4fe77192b73 1080 }
knaresh89 0:e4fe77192b73 1081
knaresh89 0:e4fe77192b73 1082 /*********************************************************************
knaresh89 0:e4fe77192b73 1083 *
knaresh89 0:e4fe77192b73 1084 * SEGGER_RTT_ConfigUpBuffer
knaresh89 0:e4fe77192b73 1085 *
knaresh89 0:e4fe77192b73 1086 * Function description
knaresh89 0:e4fe77192b73 1087 * Run-time configuration of a specific up-buffer (T->H).
knaresh89 0:e4fe77192b73 1088 * Buffer to be configured is specified by index.
knaresh89 0:e4fe77192b73 1089 * This includes: Buffer address, size, name, flags, ...
knaresh89 0:e4fe77192b73 1090 *
knaresh89 0:e4fe77192b73 1091 * Parameters
knaresh89 0:e4fe77192b73 1092 * BufferIndex Index of the buffer to configure.
knaresh89 0:e4fe77192b73 1093 * sName Pointer to a constant name string.
knaresh89 0:e4fe77192b73 1094 * pBuffer Pointer to a buffer to be used.
knaresh89 0:e4fe77192b73 1095 * BufferSize Size of the buffer.
knaresh89 0:e4fe77192b73 1096 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
knaresh89 0:e4fe77192b73 1097 *
knaresh89 0:e4fe77192b73 1098 * Return value
knaresh89 0:e4fe77192b73 1099 * >= 0 - O.K.
knaresh89 0:e4fe77192b73 1100 * < 0 - Error
knaresh89 0:e4fe77192b73 1101 *
knaresh89 0:e4fe77192b73 1102 * Additional information
knaresh89 0:e4fe77192b73 1103 * Buffer 0 is configured on compile-time.
knaresh89 0:e4fe77192b73 1104 * May only be called once per buffer.
knaresh89 0:e4fe77192b73 1105 * Buffer name and flags can be reconfigured using the appropriate functions.
knaresh89 0:e4fe77192b73 1106 */
knaresh89 0:e4fe77192b73 1107 int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
knaresh89 0:e4fe77192b73 1108 int r;
knaresh89 0:e4fe77192b73 1109
knaresh89 0:e4fe77192b73 1110 INIT();
knaresh89 0:e4fe77192b73 1111 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
knaresh89 0:e4fe77192b73 1112 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1113 if (BufferIndex > 0u) {
knaresh89 0:e4fe77192b73 1114 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
knaresh89 0:e4fe77192b73 1115 _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer;
knaresh89 0:e4fe77192b73 1116 _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize;
knaresh89 0:e4fe77192b73 1117 _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u;
knaresh89 0:e4fe77192b73 1118 _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u;
knaresh89 0:e4fe77192b73 1119 }
knaresh89 0:e4fe77192b73 1120 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
knaresh89 0:e4fe77192b73 1121 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1122 r = 0;
knaresh89 0:e4fe77192b73 1123 } else {
knaresh89 0:e4fe77192b73 1124 r = -1;
knaresh89 0:e4fe77192b73 1125 }
knaresh89 0:e4fe77192b73 1126 return r;
knaresh89 0:e4fe77192b73 1127 }
knaresh89 0:e4fe77192b73 1128
knaresh89 0:e4fe77192b73 1129 /*********************************************************************
knaresh89 0:e4fe77192b73 1130 *
knaresh89 0:e4fe77192b73 1131 * SEGGER_RTT_ConfigDownBuffer
knaresh89 0:e4fe77192b73 1132 *
knaresh89 0:e4fe77192b73 1133 * Function description
knaresh89 0:e4fe77192b73 1134 * Run-time configuration of a specific down-buffer (H->T).
knaresh89 0:e4fe77192b73 1135 * Buffer to be configured is specified by index.
knaresh89 0:e4fe77192b73 1136 * This includes: Buffer address, size, name, flags, ...
knaresh89 0:e4fe77192b73 1137 *
knaresh89 0:e4fe77192b73 1138 * Parameters
knaresh89 0:e4fe77192b73 1139 * BufferIndex Index of the buffer to configure.
knaresh89 0:e4fe77192b73 1140 * sName Pointer to a constant name string.
knaresh89 0:e4fe77192b73 1141 * pBuffer Pointer to a buffer to be used.
knaresh89 0:e4fe77192b73 1142 * BufferSize Size of the buffer.
knaresh89 0:e4fe77192b73 1143 * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
knaresh89 0:e4fe77192b73 1144 *
knaresh89 0:e4fe77192b73 1145 * Return value
knaresh89 0:e4fe77192b73 1146 * >= 0 O.K.
knaresh89 0:e4fe77192b73 1147 * < 0 Error
knaresh89 0:e4fe77192b73 1148 *
knaresh89 0:e4fe77192b73 1149 * Additional information
knaresh89 0:e4fe77192b73 1150 * Buffer 0 is configured on compile-time.
knaresh89 0:e4fe77192b73 1151 * May only be called once per buffer.
knaresh89 0:e4fe77192b73 1152 * Buffer name and flags can be reconfigured using the appropriate functions.
knaresh89 0:e4fe77192b73 1153 */
knaresh89 0:e4fe77192b73 1154 int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
knaresh89 0:e4fe77192b73 1155 int r;
knaresh89 0:e4fe77192b73 1156
knaresh89 0:e4fe77192b73 1157 INIT();
knaresh89 0:e4fe77192b73 1158 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
knaresh89 0:e4fe77192b73 1159 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1160 if (BufferIndex > 0u) {
knaresh89 0:e4fe77192b73 1161 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
knaresh89 0:e4fe77192b73 1162 _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer;
knaresh89 0:e4fe77192b73 1163 _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize;
knaresh89 0:e4fe77192b73 1164 _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u;
knaresh89 0:e4fe77192b73 1165 _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u;
knaresh89 0:e4fe77192b73 1166 }
knaresh89 0:e4fe77192b73 1167 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
knaresh89 0:e4fe77192b73 1168 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1169 r = 0;
knaresh89 0:e4fe77192b73 1170 } else {
knaresh89 0:e4fe77192b73 1171 r = -1;
knaresh89 0:e4fe77192b73 1172 }
knaresh89 0:e4fe77192b73 1173 return r;
knaresh89 0:e4fe77192b73 1174 }
knaresh89 0:e4fe77192b73 1175
knaresh89 0:e4fe77192b73 1176 /*********************************************************************
knaresh89 0:e4fe77192b73 1177 *
knaresh89 0:e4fe77192b73 1178 * SEGGER_RTT_SetNameUpBuffer
knaresh89 0:e4fe77192b73 1179 *
knaresh89 0:e4fe77192b73 1180 * Function description
knaresh89 0:e4fe77192b73 1181 * Run-time configuration of a specific up-buffer name (T->H).
knaresh89 0:e4fe77192b73 1182 * Buffer to be configured is specified by index.
knaresh89 0:e4fe77192b73 1183 *
knaresh89 0:e4fe77192b73 1184 * Parameters
knaresh89 0:e4fe77192b73 1185 * BufferIndex Index of the buffer to renamed.
knaresh89 0:e4fe77192b73 1186 * sName Pointer to a constant name string.
knaresh89 0:e4fe77192b73 1187 *
knaresh89 0:e4fe77192b73 1188 * Return value
knaresh89 0:e4fe77192b73 1189 * >= 0 O.K.
knaresh89 0:e4fe77192b73 1190 * < 0 Error
knaresh89 0:e4fe77192b73 1191 */
knaresh89 0:e4fe77192b73 1192 int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) {
knaresh89 0:e4fe77192b73 1193 int r;
knaresh89 0:e4fe77192b73 1194
knaresh89 0:e4fe77192b73 1195 INIT();
knaresh89 0:e4fe77192b73 1196 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
knaresh89 0:e4fe77192b73 1197 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1198 _SEGGER_RTT.aUp[BufferIndex].sName = sName;
knaresh89 0:e4fe77192b73 1199 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1200 r = 0;
knaresh89 0:e4fe77192b73 1201 } else {
knaresh89 0:e4fe77192b73 1202 r = -1;
knaresh89 0:e4fe77192b73 1203 }
knaresh89 0:e4fe77192b73 1204 return r;
knaresh89 0:e4fe77192b73 1205 }
knaresh89 0:e4fe77192b73 1206
knaresh89 0:e4fe77192b73 1207 /*********************************************************************
knaresh89 0:e4fe77192b73 1208 *
knaresh89 0:e4fe77192b73 1209 * SEGGER_RTT_SetNameDownBuffer
knaresh89 0:e4fe77192b73 1210 *
knaresh89 0:e4fe77192b73 1211 * Function description
knaresh89 0:e4fe77192b73 1212 * Run-time configuration of a specific Down-buffer name (T->H).
knaresh89 0:e4fe77192b73 1213 * Buffer to be configured is specified by index.
knaresh89 0:e4fe77192b73 1214 *
knaresh89 0:e4fe77192b73 1215 * Parameters
knaresh89 0:e4fe77192b73 1216 * BufferIndex Index of the buffer to renamed.
knaresh89 0:e4fe77192b73 1217 * sName Pointer to a constant name string.
knaresh89 0:e4fe77192b73 1218 *
knaresh89 0:e4fe77192b73 1219 * Return value
knaresh89 0:e4fe77192b73 1220 * >= 0 O.K.
knaresh89 0:e4fe77192b73 1221 * < 0 Error
knaresh89 0:e4fe77192b73 1222 */
knaresh89 0:e4fe77192b73 1223 int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) {
knaresh89 0:e4fe77192b73 1224 int r;
knaresh89 0:e4fe77192b73 1225
knaresh89 0:e4fe77192b73 1226 INIT();
knaresh89 0:e4fe77192b73 1227 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
knaresh89 0:e4fe77192b73 1228 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1229 _SEGGER_RTT.aDown[BufferIndex].sName = sName;
knaresh89 0:e4fe77192b73 1230 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1231 r = 0;
knaresh89 0:e4fe77192b73 1232 } else {
knaresh89 0:e4fe77192b73 1233 r = -1;
knaresh89 0:e4fe77192b73 1234 }
knaresh89 0:e4fe77192b73 1235 return r;
knaresh89 0:e4fe77192b73 1236 }
knaresh89 0:e4fe77192b73 1237
knaresh89 0:e4fe77192b73 1238 /*********************************************************************
knaresh89 0:e4fe77192b73 1239 *
knaresh89 0:e4fe77192b73 1240 * SEGGER_RTT_SetFlagsUpBuffer
knaresh89 0:e4fe77192b73 1241 *
knaresh89 0:e4fe77192b73 1242 * Function description
knaresh89 0:e4fe77192b73 1243 * Run-time configuration of specific up-buffer flags (T->H).
knaresh89 0:e4fe77192b73 1244 * Buffer to be configured is specified by index.
knaresh89 0:e4fe77192b73 1245 *
knaresh89 0:e4fe77192b73 1246 * Parameters
knaresh89 0:e4fe77192b73 1247 * BufferIndex Index of the buffer.
knaresh89 0:e4fe77192b73 1248 * Flags Flags to set for the buffer.
knaresh89 0:e4fe77192b73 1249 *
knaresh89 0:e4fe77192b73 1250 * Return value
knaresh89 0:e4fe77192b73 1251 * >= 0 O.K.
knaresh89 0:e4fe77192b73 1252 * < 0 Error
knaresh89 0:e4fe77192b73 1253 */
knaresh89 0:e4fe77192b73 1254 int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) {
knaresh89 0:e4fe77192b73 1255 int r;
knaresh89 0:e4fe77192b73 1256
knaresh89 0:e4fe77192b73 1257 INIT();
knaresh89 0:e4fe77192b73 1258 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) {
knaresh89 0:e4fe77192b73 1259 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1260 _SEGGER_RTT.aUp[BufferIndex].Flags = Flags;
knaresh89 0:e4fe77192b73 1261 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1262 r = 0;
knaresh89 0:e4fe77192b73 1263 } else {
knaresh89 0:e4fe77192b73 1264 r = -1;
knaresh89 0:e4fe77192b73 1265 }
knaresh89 0:e4fe77192b73 1266 return r;
knaresh89 0:e4fe77192b73 1267 }
knaresh89 0:e4fe77192b73 1268
knaresh89 0:e4fe77192b73 1269 /*********************************************************************
knaresh89 0:e4fe77192b73 1270 *
knaresh89 0:e4fe77192b73 1271 * SEGGER_RTT_SetFlagsDownBuffer
knaresh89 0:e4fe77192b73 1272 *
knaresh89 0:e4fe77192b73 1273 * Function description
knaresh89 0:e4fe77192b73 1274 * Run-time configuration of specific Down-buffer flags (T->H).
knaresh89 0:e4fe77192b73 1275 * Buffer to be configured is specified by index.
knaresh89 0:e4fe77192b73 1276 *
knaresh89 0:e4fe77192b73 1277 * Parameters
knaresh89 0:e4fe77192b73 1278 * BufferIndex Index of the buffer to renamed.
knaresh89 0:e4fe77192b73 1279 * Flags Flags to set for the buffer.
knaresh89 0:e4fe77192b73 1280 *
knaresh89 0:e4fe77192b73 1281 * Return value
knaresh89 0:e4fe77192b73 1282 * >= 0 O.K.
knaresh89 0:e4fe77192b73 1283 * < 0 Error
knaresh89 0:e4fe77192b73 1284 */
knaresh89 0:e4fe77192b73 1285 int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) {
knaresh89 0:e4fe77192b73 1286 int r;
knaresh89 0:e4fe77192b73 1287
knaresh89 0:e4fe77192b73 1288 INIT();
knaresh89 0:e4fe77192b73 1289 if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) {
knaresh89 0:e4fe77192b73 1290 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1291 _SEGGER_RTT.aDown[BufferIndex].Flags = Flags;
knaresh89 0:e4fe77192b73 1292 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1293 r = 0;
knaresh89 0:e4fe77192b73 1294 } else {
knaresh89 0:e4fe77192b73 1295 r = -1;
knaresh89 0:e4fe77192b73 1296 }
knaresh89 0:e4fe77192b73 1297 return r;
knaresh89 0:e4fe77192b73 1298 }
knaresh89 0:e4fe77192b73 1299
knaresh89 0:e4fe77192b73 1300 /*********************************************************************
knaresh89 0:e4fe77192b73 1301 *
knaresh89 0:e4fe77192b73 1302 * SEGGER_RTT_Init
knaresh89 0:e4fe77192b73 1303 *
knaresh89 0:e4fe77192b73 1304 * Function description
knaresh89 0:e4fe77192b73 1305 * Initializes the RTT Control Block.
knaresh89 0:e4fe77192b73 1306 * Should be used in RAM targets, at start of the application.
knaresh89 0:e4fe77192b73 1307 *
knaresh89 0:e4fe77192b73 1308 */
knaresh89 0:e4fe77192b73 1309 void SEGGER_RTT_Init (void) {
knaresh89 0:e4fe77192b73 1310 _DoInit();
knaresh89 0:e4fe77192b73 1311 }
knaresh89 0:e4fe77192b73 1312
knaresh89 0:e4fe77192b73 1313 /*********************************************************************
knaresh89 0:e4fe77192b73 1314 *
knaresh89 0:e4fe77192b73 1315 * SEGGER_RTT_SetTerminal
knaresh89 0:e4fe77192b73 1316 *
knaresh89 0:e4fe77192b73 1317 * Function description
knaresh89 0:e4fe77192b73 1318 * Sets the terminal to be used for output on channel 0.
knaresh89 0:e4fe77192b73 1319 *
knaresh89 0:e4fe77192b73 1320 * Parameters
knaresh89 0:e4fe77192b73 1321 * TerminalId Index of the terminal.
knaresh89 0:e4fe77192b73 1322 *
knaresh89 0:e4fe77192b73 1323 * Return value
knaresh89 0:e4fe77192b73 1324 * >= 0 O.K.
knaresh89 0:e4fe77192b73 1325 * < 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)
knaresh89 0:e4fe77192b73 1326 */
knaresh89 0:e4fe77192b73 1327 int SEGGER_RTT_SetTerminal (char TerminalId) {
knaresh89 0:e4fe77192b73 1328 char ac[2];
knaresh89 0:e4fe77192b73 1329 SEGGER_RTT_BUFFER_UP* pRing;
knaresh89 0:e4fe77192b73 1330 unsigned Avail;
knaresh89 0:e4fe77192b73 1331 int r;
knaresh89 0:e4fe77192b73 1332 //
knaresh89 0:e4fe77192b73 1333 INIT();
knaresh89 0:e4fe77192b73 1334 //
knaresh89 0:e4fe77192b73 1335 r = 0;
knaresh89 0:e4fe77192b73 1336 ac[0] = 0xFFU;
knaresh89 0:e4fe77192b73 1337 if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels
knaresh89 0:e4fe77192b73 1338 ac[1] = _aTerminalId[(unsigned char)TerminalId];
knaresh89 0:e4fe77192b73 1339 pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed
knaresh89 0:e4fe77192b73 1340 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
knaresh89 0:e4fe77192b73 1341 if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) {
knaresh89 0:e4fe77192b73 1342 _ActiveTerminal = TerminalId;
knaresh89 0:e4fe77192b73 1343 _WriteBlocking(pRing, ac, 2u);
knaresh89 0:e4fe77192b73 1344 } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes
knaresh89 0:e4fe77192b73 1345 Avail = _GetAvailWriteSpace(pRing);
knaresh89 0:e4fe77192b73 1346 if (Avail >= 2) {
knaresh89 0:e4fe77192b73 1347 _ActiveTerminal = TerminalId; // Only change active terminal in case of success
knaresh89 0:e4fe77192b73 1348 _WriteNoCheck(pRing, ac, 2u);
knaresh89 0:e4fe77192b73 1349 } else {
knaresh89 0:e4fe77192b73 1350 r = -1;
knaresh89 0:e4fe77192b73 1351 }
knaresh89 0:e4fe77192b73 1352 }
knaresh89 0:e4fe77192b73 1353 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1354 } else {
knaresh89 0:e4fe77192b73 1355 r = -1;
knaresh89 0:e4fe77192b73 1356 }
knaresh89 0:e4fe77192b73 1357 return r;
knaresh89 0:e4fe77192b73 1358 }
knaresh89 0:e4fe77192b73 1359
knaresh89 0:e4fe77192b73 1360 /*********************************************************************
knaresh89 0:e4fe77192b73 1361 *
knaresh89 0:e4fe77192b73 1362 * SEGGER_RTT_TerminalOut
knaresh89 0:e4fe77192b73 1363 *
knaresh89 0:e4fe77192b73 1364 * Function description
knaresh89 0:e4fe77192b73 1365 * Writes a string to the given terminal
knaresh89 0:e4fe77192b73 1366 * without changing the terminal for channel 0.
knaresh89 0:e4fe77192b73 1367 *
knaresh89 0:e4fe77192b73 1368 * Parameters
knaresh89 0:e4fe77192b73 1369 * TerminalId Index of the terminal.
knaresh89 0:e4fe77192b73 1370 * s String to be printed on the terminal.
knaresh89 0:e4fe77192b73 1371 *
knaresh89 0:e4fe77192b73 1372 * Return value
knaresh89 0:e4fe77192b73 1373 * >= 0 - Number of bytes written.
knaresh89 0:e4fe77192b73 1374 * < 0 - Error.
knaresh89 0:e4fe77192b73 1375 *
knaresh89 0:e4fe77192b73 1376 */
knaresh89 0:e4fe77192b73 1377 int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) {
knaresh89 0:e4fe77192b73 1378 int Status;
knaresh89 0:e4fe77192b73 1379 unsigned FragLen;
knaresh89 0:e4fe77192b73 1380 unsigned Avail;
knaresh89 0:e4fe77192b73 1381 SEGGER_RTT_BUFFER_UP* pRing;
knaresh89 0:e4fe77192b73 1382 //
knaresh89 0:e4fe77192b73 1383 INIT();
knaresh89 0:e4fe77192b73 1384 //
knaresh89 0:e4fe77192b73 1385 // Validate terminal ID.
knaresh89 0:e4fe77192b73 1386 //
knaresh89 0:e4fe77192b73 1387 if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels
knaresh89 0:e4fe77192b73 1388 //
knaresh89 0:e4fe77192b73 1389 // Get "to-host" ring buffer.
knaresh89 0:e4fe77192b73 1390 //
knaresh89 0:e4fe77192b73 1391 pRing = &_SEGGER_RTT.aUp[0];
knaresh89 0:e4fe77192b73 1392 //
knaresh89 0:e4fe77192b73 1393 // Need to be able to change terminal, write data, change back.
knaresh89 0:e4fe77192b73 1394 // Compute the fixed and variable sizes.
knaresh89 0:e4fe77192b73 1395 //
knaresh89 0:e4fe77192b73 1396 FragLen = strlen(s);
knaresh89 0:e4fe77192b73 1397 //
knaresh89 0:e4fe77192b73 1398 // How we output depends upon the mode...
knaresh89 0:e4fe77192b73 1399 //
knaresh89 0:e4fe77192b73 1400 SEGGER_RTT_LOCK();
knaresh89 0:e4fe77192b73 1401 Avail = _GetAvailWriteSpace(pRing);
knaresh89 0:e4fe77192b73 1402 switch (pRing->Flags & SEGGER_RTT_MODE_MASK) {
knaresh89 0:e4fe77192b73 1403 case SEGGER_RTT_MODE_NO_BLOCK_SKIP:
knaresh89 0:e4fe77192b73 1404 //
knaresh89 0:e4fe77192b73 1405 // If we are in skip mode and there is no space for the whole
knaresh89 0:e4fe77192b73 1406 // of this output, don't bother switching terminals at all.
knaresh89 0:e4fe77192b73 1407 //
knaresh89 0:e4fe77192b73 1408 if (Avail < (FragLen + 4u)) {
knaresh89 0:e4fe77192b73 1409 Status = 0;
knaresh89 0:e4fe77192b73 1410 } else {
knaresh89 0:e4fe77192b73 1411 _PostTerminalSwitch(pRing, TerminalId);
knaresh89 0:e4fe77192b73 1412 Status = (int)_WriteBlocking(pRing, s, FragLen);
knaresh89 0:e4fe77192b73 1413 _PostTerminalSwitch(pRing, _ActiveTerminal);
knaresh89 0:e4fe77192b73 1414 }
knaresh89 0:e4fe77192b73 1415 break;
knaresh89 0:e4fe77192b73 1416 case SEGGER_RTT_MODE_NO_BLOCK_TRIM:
knaresh89 0:e4fe77192b73 1417 //
knaresh89 0:e4fe77192b73 1418 // If we are in trim mode and there is not enough space for everything,
knaresh89 0:e4fe77192b73 1419 // trim the output but always include the terminal switch. If no room
knaresh89 0:e4fe77192b73 1420 // for terminal switch, skip that totally.
knaresh89 0:e4fe77192b73 1421 //
knaresh89 0:e4fe77192b73 1422 if (Avail < 4u) {
knaresh89 0:e4fe77192b73 1423 Status = -1;
knaresh89 0:e4fe77192b73 1424 } else {
knaresh89 0:e4fe77192b73 1425 _PostTerminalSwitch(pRing, TerminalId);
knaresh89 0:e4fe77192b73 1426 Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u));
knaresh89 0:e4fe77192b73 1427 _PostTerminalSwitch(pRing, _ActiveTerminal);
knaresh89 0:e4fe77192b73 1428 }
knaresh89 0:e4fe77192b73 1429 break;
knaresh89 0:e4fe77192b73 1430 case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:
knaresh89 0:e4fe77192b73 1431 //
knaresh89 0:e4fe77192b73 1432 // If we are in blocking mode, output everything.
knaresh89 0:e4fe77192b73 1433 //
knaresh89 0:e4fe77192b73 1434 _PostTerminalSwitch(pRing, TerminalId);
knaresh89 0:e4fe77192b73 1435 Status = (int)_WriteBlocking(pRing, s, FragLen);
knaresh89 0:e4fe77192b73 1436 _PostTerminalSwitch(pRing, _ActiveTerminal);
knaresh89 0:e4fe77192b73 1437 break;
knaresh89 0:e4fe77192b73 1438 default:
knaresh89 0:e4fe77192b73 1439 Status = -1;
knaresh89 0:e4fe77192b73 1440 break;
knaresh89 0:e4fe77192b73 1441 }
knaresh89 0:e4fe77192b73 1442 //
knaresh89 0:e4fe77192b73 1443 // Finish up.
knaresh89 0:e4fe77192b73 1444 //
knaresh89 0:e4fe77192b73 1445 SEGGER_RTT_UNLOCK();
knaresh89 0:e4fe77192b73 1446 } else {
knaresh89 0:e4fe77192b73 1447 Status = -1;
knaresh89 0:e4fe77192b73 1448 }
knaresh89 0:e4fe77192b73 1449 return Status;
knaresh89 0:e4fe77192b73 1450 }
knaresh89 0:e4fe77192b73 1451
knaresh89 0:e4fe77192b73 1452
knaresh89 0:e4fe77192b73 1453 /*************************** End of file ****************************/