Sample app on how to interface with the BC95 GSM NB IoT module on the RAK Wireless itracker

Committer:
knaresh89
Date:
Tue Feb 13 08:27:24 2018 +0000
Revision:
1:3ced3cedee8f
Parent:
0:6ca6723bc32e
code edit for gsm off functionality

Who changed what in which revision?

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