Sample program on how to use the OPT3001 sensor on the RAKWirelss iTracker module

Committer:
knaresh89
Date:
Mon Feb 12 05:06:24 2018 +0000
Revision:
0:33cb2fa095df
Sample program on how to use the OPT3001 sensor on the RAKWireless iTracker module

Who changed what in which revision?

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