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

Committer:
knaresh89
Date:
Mon Feb 12 05:04:29 2018 +0000
Revision:
0:a8bfd25ff975
Sample program on how to use the BME280 sensor on the RAKWirelss iTracker module

Who changed what in which revision?

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