Sample program on how to use the LIS3DH sensor on the RAKWireless iTracker module

Committer:
knaresh89
Date:
Mon Feb 12 05:05:29 2018 +0000
Revision:
0:cd96b05ace6e
Sample program on how to use the LIS3DH sensor on the RAKWireless iTracker module

Who changed what in which revision?

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