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:26:52 2018 +0000
Revision:
0:6ca6723bc32e
Sampel app for the GSM module on the RAK Wireless itracker; - basic support for serial interfacing; - added GSM module on/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_printf.c
knaresh89 0:6ca6723bc32e 56 Purpose : Replacement for printf to write formatted data via RTT
knaresh89 0:6ca6723bc32e 57 Revision: $Rev: 4351 $
knaresh89 0:6ca6723bc32e 58 ----------------------------------------------------------------------
knaresh89 0:6ca6723bc32e 59 */
knaresh89 0:6ca6723bc32e 60 #include "SEGGER_RTT.h"
knaresh89 0:6ca6723bc32e 61 #include "SEGGER_RTT_Conf.h"
knaresh89 0:6ca6723bc32e 62
knaresh89 0:6ca6723bc32e 63 /*********************************************************************
knaresh89 0:6ca6723bc32e 64 *
knaresh89 0:6ca6723bc32e 65 * Defines, configurable
knaresh89 0:6ca6723bc32e 66 *
knaresh89 0:6ca6723bc32e 67 **********************************************************************
knaresh89 0:6ca6723bc32e 68 */
knaresh89 0:6ca6723bc32e 69
knaresh89 0:6ca6723bc32e 70 #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
knaresh89 0:6ca6723bc32e 71 #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
knaresh89 0:6ca6723bc32e 72 #endif
knaresh89 0:6ca6723bc32e 73
knaresh89 0:6ca6723bc32e 74 #include <stdlib.h>
knaresh89 0:6ca6723bc32e 75 #include <stdarg.h>
knaresh89 0:6ca6723bc32e 76
knaresh89 0:6ca6723bc32e 77
knaresh89 0:6ca6723bc32e 78 #define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0)
knaresh89 0:6ca6723bc32e 79 #define FORMAT_FLAG_PAD_ZERO (1u << 1)
knaresh89 0:6ca6723bc32e 80 #define FORMAT_FLAG_PRINT_SIGN (1u << 2)
knaresh89 0:6ca6723bc32e 81 #define FORMAT_FLAG_ALTERNATE (1u << 3)
knaresh89 0:6ca6723bc32e 82
knaresh89 0:6ca6723bc32e 83 /*********************************************************************
knaresh89 0:6ca6723bc32e 84 *
knaresh89 0:6ca6723bc32e 85 * Types
knaresh89 0:6ca6723bc32e 86 *
knaresh89 0:6ca6723bc32e 87 **********************************************************************
knaresh89 0:6ca6723bc32e 88 */
knaresh89 0:6ca6723bc32e 89
knaresh89 0:6ca6723bc32e 90 typedef struct {
knaresh89 0:6ca6723bc32e 91 char* pBuffer;
knaresh89 0:6ca6723bc32e 92 unsigned BufferSize;
knaresh89 0:6ca6723bc32e 93 unsigned Cnt;
knaresh89 0:6ca6723bc32e 94
knaresh89 0:6ca6723bc32e 95 int ReturnValue;
knaresh89 0:6ca6723bc32e 96
knaresh89 0:6ca6723bc32e 97 unsigned RTTBufferIndex;
knaresh89 0:6ca6723bc32e 98 } SEGGER_RTT_PRINTF_DESC;
knaresh89 0:6ca6723bc32e 99
knaresh89 0:6ca6723bc32e 100 /*********************************************************************
knaresh89 0:6ca6723bc32e 101 *
knaresh89 0:6ca6723bc32e 102 * Function prototypes
knaresh89 0:6ca6723bc32e 103 *
knaresh89 0:6ca6723bc32e 104 **********************************************************************
knaresh89 0:6ca6723bc32e 105 */
knaresh89 0:6ca6723bc32e 106 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList);
knaresh89 0:6ca6723bc32e 107
knaresh89 0:6ca6723bc32e 108 /*********************************************************************
knaresh89 0:6ca6723bc32e 109 *
knaresh89 0:6ca6723bc32e 110 * Static code
knaresh89 0:6ca6723bc32e 111 *
knaresh89 0:6ca6723bc32e 112 **********************************************************************
knaresh89 0:6ca6723bc32e 113 */
knaresh89 0:6ca6723bc32e 114 /*********************************************************************
knaresh89 0:6ca6723bc32e 115 *
knaresh89 0:6ca6723bc32e 116 * _StoreChar
knaresh89 0:6ca6723bc32e 117 */
knaresh89 0:6ca6723bc32e 118 static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
knaresh89 0:6ca6723bc32e 119 unsigned Cnt;
knaresh89 0:6ca6723bc32e 120
knaresh89 0:6ca6723bc32e 121 Cnt = p->Cnt;
knaresh89 0:6ca6723bc32e 122 if ((Cnt + 1u) <= p->BufferSize) {
knaresh89 0:6ca6723bc32e 123 *(p->pBuffer + Cnt) = c;
knaresh89 0:6ca6723bc32e 124 p->Cnt = Cnt + 1u;
knaresh89 0:6ca6723bc32e 125 p->ReturnValue++;
knaresh89 0:6ca6723bc32e 126 }
knaresh89 0:6ca6723bc32e 127 //
knaresh89 0:6ca6723bc32e 128 // Write part of string, when the buffer is full
knaresh89 0:6ca6723bc32e 129 //
knaresh89 0:6ca6723bc32e 130 if (p->Cnt == p->BufferSize) {
knaresh89 0:6ca6723bc32e 131 if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
knaresh89 0:6ca6723bc32e 132 p->ReturnValue = -1;
knaresh89 0:6ca6723bc32e 133 } else {
knaresh89 0:6ca6723bc32e 134 p->Cnt = 0u;
knaresh89 0:6ca6723bc32e 135 }
knaresh89 0:6ca6723bc32e 136 }
knaresh89 0:6ca6723bc32e 137 }
knaresh89 0:6ca6723bc32e 138
knaresh89 0:6ca6723bc32e 139 /*********************************************************************
knaresh89 0:6ca6723bc32e 140 *
knaresh89 0:6ca6723bc32e 141 * _PrintUnsigned
knaresh89 0:6ca6723bc32e 142 */
knaresh89 0:6ca6723bc32e 143 static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
knaresh89 0:6ca6723bc32e 144 static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
knaresh89 0:6ca6723bc32e 145 unsigned Div;
knaresh89 0:6ca6723bc32e 146 unsigned Digit;
knaresh89 0:6ca6723bc32e 147 unsigned Number;
knaresh89 0:6ca6723bc32e 148 unsigned Width;
knaresh89 0:6ca6723bc32e 149 char c;
knaresh89 0:6ca6723bc32e 150
knaresh89 0:6ca6723bc32e 151 Number = v;
knaresh89 0:6ca6723bc32e 152 Digit = 1u;
knaresh89 0:6ca6723bc32e 153 //
knaresh89 0:6ca6723bc32e 154 // Get actual field width
knaresh89 0:6ca6723bc32e 155 //
knaresh89 0:6ca6723bc32e 156 Width = 1u;
knaresh89 0:6ca6723bc32e 157 while (Number >= Base) {
knaresh89 0:6ca6723bc32e 158 Number = (Number / Base);
knaresh89 0:6ca6723bc32e 159 Width++;
knaresh89 0:6ca6723bc32e 160 }
knaresh89 0:6ca6723bc32e 161 if (NumDigits > Width) {
knaresh89 0:6ca6723bc32e 162 Width = NumDigits;
knaresh89 0:6ca6723bc32e 163 }
knaresh89 0:6ca6723bc32e 164 //
knaresh89 0:6ca6723bc32e 165 // Print leading chars if necessary
knaresh89 0:6ca6723bc32e 166 //
knaresh89 0:6ca6723bc32e 167 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
knaresh89 0:6ca6723bc32e 168 if (FieldWidth != 0u) {
knaresh89 0:6ca6723bc32e 169 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
knaresh89 0:6ca6723bc32e 170 c = '0';
knaresh89 0:6ca6723bc32e 171 } else {
knaresh89 0:6ca6723bc32e 172 c = ' ';
knaresh89 0:6ca6723bc32e 173 }
knaresh89 0:6ca6723bc32e 174 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
knaresh89 0:6ca6723bc32e 175 FieldWidth--;
knaresh89 0:6ca6723bc32e 176 _StoreChar(pBufferDesc, c);
knaresh89 0:6ca6723bc32e 177 if (pBufferDesc->ReturnValue < 0) {
knaresh89 0:6ca6723bc32e 178 break;
knaresh89 0:6ca6723bc32e 179 }
knaresh89 0:6ca6723bc32e 180 }
knaresh89 0:6ca6723bc32e 181 }
knaresh89 0:6ca6723bc32e 182 }
knaresh89 0:6ca6723bc32e 183 if (pBufferDesc->ReturnValue >= 0) {
knaresh89 0:6ca6723bc32e 184 //
knaresh89 0:6ca6723bc32e 185 // Compute Digit.
knaresh89 0:6ca6723bc32e 186 // Loop until Digit has the value of the highest digit required.
knaresh89 0:6ca6723bc32e 187 // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
knaresh89 0:6ca6723bc32e 188 //
knaresh89 0:6ca6723bc32e 189 while (1) {
knaresh89 0:6ca6723bc32e 190 if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned)
knaresh89 0:6ca6723bc32e 191 NumDigits--;
knaresh89 0:6ca6723bc32e 192 } else {
knaresh89 0:6ca6723bc32e 193 Div = v / Digit;
knaresh89 0:6ca6723bc32e 194 if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done
knaresh89 0:6ca6723bc32e 195 break;
knaresh89 0:6ca6723bc32e 196 }
knaresh89 0:6ca6723bc32e 197 }
knaresh89 0:6ca6723bc32e 198 Digit *= Base;
knaresh89 0:6ca6723bc32e 199 }
knaresh89 0:6ca6723bc32e 200 //
knaresh89 0:6ca6723bc32e 201 // Output digits
knaresh89 0:6ca6723bc32e 202 //
knaresh89 0:6ca6723bc32e 203 do {
knaresh89 0:6ca6723bc32e 204 Div = v / Digit;
knaresh89 0:6ca6723bc32e 205 v -= Div * Digit;
knaresh89 0:6ca6723bc32e 206 _StoreChar(pBufferDesc, _aV2C[Div]);
knaresh89 0:6ca6723bc32e 207 if (pBufferDesc->ReturnValue < 0) {
knaresh89 0:6ca6723bc32e 208 break;
knaresh89 0:6ca6723bc32e 209 }
knaresh89 0:6ca6723bc32e 210 Digit /= Base;
knaresh89 0:6ca6723bc32e 211 } while (Digit);
knaresh89 0:6ca6723bc32e 212 //
knaresh89 0:6ca6723bc32e 213 // Print trailing spaces if necessary
knaresh89 0:6ca6723bc32e 214 //
knaresh89 0:6ca6723bc32e 215 if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
knaresh89 0:6ca6723bc32e 216 if (FieldWidth != 0u) {
knaresh89 0:6ca6723bc32e 217 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
knaresh89 0:6ca6723bc32e 218 FieldWidth--;
knaresh89 0:6ca6723bc32e 219 _StoreChar(pBufferDesc, ' ');
knaresh89 0:6ca6723bc32e 220 if (pBufferDesc->ReturnValue < 0) {
knaresh89 0:6ca6723bc32e 221 break;
knaresh89 0:6ca6723bc32e 222 }
knaresh89 0:6ca6723bc32e 223 }
knaresh89 0:6ca6723bc32e 224 }
knaresh89 0:6ca6723bc32e 225 }
knaresh89 0:6ca6723bc32e 226 }
knaresh89 0:6ca6723bc32e 227 }
knaresh89 0:6ca6723bc32e 228
knaresh89 0:6ca6723bc32e 229 /*********************************************************************
knaresh89 0:6ca6723bc32e 230 *
knaresh89 0:6ca6723bc32e 231 * _PrintInt
knaresh89 0:6ca6723bc32e 232 */
knaresh89 0:6ca6723bc32e 233 static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
knaresh89 0:6ca6723bc32e 234 unsigned Width;
knaresh89 0:6ca6723bc32e 235 int Number;
knaresh89 0:6ca6723bc32e 236
knaresh89 0:6ca6723bc32e 237 Number = (v < 0) ? -v : v;
knaresh89 0:6ca6723bc32e 238
knaresh89 0:6ca6723bc32e 239 //
knaresh89 0:6ca6723bc32e 240 // Get actual field width
knaresh89 0:6ca6723bc32e 241 //
knaresh89 0:6ca6723bc32e 242 Width = 1u;
knaresh89 0:6ca6723bc32e 243 while (Number >= (int)Base) {
knaresh89 0:6ca6723bc32e 244 Number = (Number / (int)Base);
knaresh89 0:6ca6723bc32e 245 Width++;
knaresh89 0:6ca6723bc32e 246 }
knaresh89 0:6ca6723bc32e 247 if (NumDigits > Width) {
knaresh89 0:6ca6723bc32e 248 Width = NumDigits;
knaresh89 0:6ca6723bc32e 249 }
knaresh89 0:6ca6723bc32e 250 if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
knaresh89 0:6ca6723bc32e 251 FieldWidth--;
knaresh89 0:6ca6723bc32e 252 }
knaresh89 0:6ca6723bc32e 253
knaresh89 0:6ca6723bc32e 254 //
knaresh89 0:6ca6723bc32e 255 // Print leading spaces if necessary
knaresh89 0:6ca6723bc32e 256 //
knaresh89 0:6ca6723bc32e 257 if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
knaresh89 0:6ca6723bc32e 258 if (FieldWidth != 0u) {
knaresh89 0:6ca6723bc32e 259 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
knaresh89 0:6ca6723bc32e 260 FieldWidth--;
knaresh89 0:6ca6723bc32e 261 _StoreChar(pBufferDesc, ' ');
knaresh89 0:6ca6723bc32e 262 if (pBufferDesc->ReturnValue < 0) {
knaresh89 0:6ca6723bc32e 263 break;
knaresh89 0:6ca6723bc32e 264 }
knaresh89 0:6ca6723bc32e 265 }
knaresh89 0:6ca6723bc32e 266 }
knaresh89 0:6ca6723bc32e 267 }
knaresh89 0:6ca6723bc32e 268 //
knaresh89 0:6ca6723bc32e 269 // Print sign if necessary
knaresh89 0:6ca6723bc32e 270 //
knaresh89 0:6ca6723bc32e 271 if (pBufferDesc->ReturnValue >= 0) {
knaresh89 0:6ca6723bc32e 272 if (v < 0) {
knaresh89 0:6ca6723bc32e 273 v = -v;
knaresh89 0:6ca6723bc32e 274 _StoreChar(pBufferDesc, '-');
knaresh89 0:6ca6723bc32e 275 } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
knaresh89 0:6ca6723bc32e 276 _StoreChar(pBufferDesc, '+');
knaresh89 0:6ca6723bc32e 277 } else {
knaresh89 0:6ca6723bc32e 278
knaresh89 0:6ca6723bc32e 279 }
knaresh89 0:6ca6723bc32e 280 if (pBufferDesc->ReturnValue >= 0) {
knaresh89 0:6ca6723bc32e 281 //
knaresh89 0:6ca6723bc32e 282 // Print leading zeros if necessary
knaresh89 0:6ca6723bc32e 283 //
knaresh89 0:6ca6723bc32e 284 if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
knaresh89 0:6ca6723bc32e 285 if (FieldWidth != 0u) {
knaresh89 0:6ca6723bc32e 286 while ((FieldWidth != 0u) && (Width < FieldWidth)) {
knaresh89 0:6ca6723bc32e 287 FieldWidth--;
knaresh89 0:6ca6723bc32e 288 _StoreChar(pBufferDesc, '0');
knaresh89 0:6ca6723bc32e 289 if (pBufferDesc->ReturnValue < 0) {
knaresh89 0:6ca6723bc32e 290 break;
knaresh89 0:6ca6723bc32e 291 }
knaresh89 0:6ca6723bc32e 292 }
knaresh89 0:6ca6723bc32e 293 }
knaresh89 0:6ca6723bc32e 294 }
knaresh89 0:6ca6723bc32e 295 if (pBufferDesc->ReturnValue >= 0) {
knaresh89 0:6ca6723bc32e 296 //
knaresh89 0:6ca6723bc32e 297 // Print number without sign
knaresh89 0:6ca6723bc32e 298 //
knaresh89 0:6ca6723bc32e 299 _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
knaresh89 0:6ca6723bc32e 300 }
knaresh89 0:6ca6723bc32e 301 }
knaresh89 0:6ca6723bc32e 302 }
knaresh89 0:6ca6723bc32e 303 }
knaresh89 0:6ca6723bc32e 304
knaresh89 0:6ca6723bc32e 305 /*********************************************************************
knaresh89 0:6ca6723bc32e 306 *
knaresh89 0:6ca6723bc32e 307 * Public code
knaresh89 0:6ca6723bc32e 308 *
knaresh89 0:6ca6723bc32e 309 **********************************************************************
knaresh89 0:6ca6723bc32e 310 */
knaresh89 0:6ca6723bc32e 311 /*********************************************************************
knaresh89 0:6ca6723bc32e 312 *
knaresh89 0:6ca6723bc32e 313 * SEGGER_RTT_vprintf
knaresh89 0:6ca6723bc32e 314 *
knaresh89 0:6ca6723bc32e 315 * Function description
knaresh89 0:6ca6723bc32e 316 * Stores a formatted string in SEGGER RTT control block.
knaresh89 0:6ca6723bc32e 317 * This data is read by the host.
knaresh89 0:6ca6723bc32e 318 *
knaresh89 0:6ca6723bc32e 319 * Parameters
knaresh89 0:6ca6723bc32e 320 * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
knaresh89 0:6ca6723bc32e 321 * sFormat Pointer to format string
knaresh89 0:6ca6723bc32e 322 * pParamList Pointer to the list of arguments for the format string
knaresh89 0:6ca6723bc32e 323 *
knaresh89 0:6ca6723bc32e 324 * Return values
knaresh89 0:6ca6723bc32e 325 * >= 0: Number of bytes which have been stored in the "Up"-buffer.
knaresh89 0:6ca6723bc32e 326 * < 0: Error
knaresh89 0:6ca6723bc32e 327 */
knaresh89 0:6ca6723bc32e 328 int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
knaresh89 0:6ca6723bc32e 329 char c;
knaresh89 0:6ca6723bc32e 330 SEGGER_RTT_PRINTF_DESC BufferDesc;
knaresh89 0:6ca6723bc32e 331 int v;
knaresh89 0:6ca6723bc32e 332 unsigned NumDigits;
knaresh89 0:6ca6723bc32e 333 unsigned FormatFlags;
knaresh89 0:6ca6723bc32e 334 unsigned FieldWidth;
knaresh89 0:6ca6723bc32e 335 char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
knaresh89 0:6ca6723bc32e 336
knaresh89 0:6ca6723bc32e 337 BufferDesc.pBuffer = acBuffer;
knaresh89 0:6ca6723bc32e 338 BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE;
knaresh89 0:6ca6723bc32e 339 BufferDesc.Cnt = 0u;
knaresh89 0:6ca6723bc32e 340 BufferDesc.RTTBufferIndex = BufferIndex;
knaresh89 0:6ca6723bc32e 341 BufferDesc.ReturnValue = 0;
knaresh89 0:6ca6723bc32e 342
knaresh89 0:6ca6723bc32e 343 do {
knaresh89 0:6ca6723bc32e 344 c = *sFormat;
knaresh89 0:6ca6723bc32e 345 sFormat++;
knaresh89 0:6ca6723bc32e 346 if (c == 0u) {
knaresh89 0:6ca6723bc32e 347 break;
knaresh89 0:6ca6723bc32e 348 }
knaresh89 0:6ca6723bc32e 349 if (c == '%') {
knaresh89 0:6ca6723bc32e 350 //
knaresh89 0:6ca6723bc32e 351 // Filter out flags
knaresh89 0:6ca6723bc32e 352 //
knaresh89 0:6ca6723bc32e 353 FormatFlags = 0u;
knaresh89 0:6ca6723bc32e 354 v = 1;
knaresh89 0:6ca6723bc32e 355 do {
knaresh89 0:6ca6723bc32e 356 c = *sFormat;
knaresh89 0:6ca6723bc32e 357 switch (c) {
knaresh89 0:6ca6723bc32e 358 case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
knaresh89 0:6ca6723bc32e 359 case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break;
knaresh89 0:6ca6723bc32e 360 case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break;
knaresh89 0:6ca6723bc32e 361 case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break;
knaresh89 0:6ca6723bc32e 362 default: v = 0; break;
knaresh89 0:6ca6723bc32e 363 }
knaresh89 0:6ca6723bc32e 364 } while (v);
knaresh89 0:6ca6723bc32e 365 //
knaresh89 0:6ca6723bc32e 366 // filter out field with
knaresh89 0:6ca6723bc32e 367 //
knaresh89 0:6ca6723bc32e 368 FieldWidth = 0u;
knaresh89 0:6ca6723bc32e 369 do {
knaresh89 0:6ca6723bc32e 370 c = *sFormat;
knaresh89 0:6ca6723bc32e 371 if ((c < '0') || (c > '9')) {
knaresh89 0:6ca6723bc32e 372 break;
knaresh89 0:6ca6723bc32e 373 }
knaresh89 0:6ca6723bc32e 374 sFormat++;
knaresh89 0:6ca6723bc32e 375 FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
knaresh89 0:6ca6723bc32e 376 } while (1);
knaresh89 0:6ca6723bc32e 377
knaresh89 0:6ca6723bc32e 378 //
knaresh89 0:6ca6723bc32e 379 // Filter out precision (number of digits to display)
knaresh89 0:6ca6723bc32e 380 //
knaresh89 0:6ca6723bc32e 381 NumDigits = 0u;
knaresh89 0:6ca6723bc32e 382 c = *sFormat;
knaresh89 0:6ca6723bc32e 383 if (c == '.') {
knaresh89 0:6ca6723bc32e 384 sFormat++;
knaresh89 0:6ca6723bc32e 385 do {
knaresh89 0:6ca6723bc32e 386 c = *sFormat;
knaresh89 0:6ca6723bc32e 387 if ((c < '0') || (c > '9')) {
knaresh89 0:6ca6723bc32e 388 break;
knaresh89 0:6ca6723bc32e 389 }
knaresh89 0:6ca6723bc32e 390 sFormat++;
knaresh89 0:6ca6723bc32e 391 NumDigits = NumDigits * 10u + ((unsigned)c - '0');
knaresh89 0:6ca6723bc32e 392 } while (1);
knaresh89 0:6ca6723bc32e 393 }
knaresh89 0:6ca6723bc32e 394 //
knaresh89 0:6ca6723bc32e 395 // Filter out length modifier
knaresh89 0:6ca6723bc32e 396 //
knaresh89 0:6ca6723bc32e 397 c = *sFormat;
knaresh89 0:6ca6723bc32e 398 do {
knaresh89 0:6ca6723bc32e 399 if ((c == 'l') || (c == 'h')) {
knaresh89 0:6ca6723bc32e 400 sFormat++;
knaresh89 0:6ca6723bc32e 401 c = *sFormat;
knaresh89 0:6ca6723bc32e 402 } else {
knaresh89 0:6ca6723bc32e 403 break;
knaresh89 0:6ca6723bc32e 404 }
knaresh89 0:6ca6723bc32e 405 } while (1);
knaresh89 0:6ca6723bc32e 406 //
knaresh89 0:6ca6723bc32e 407 // Handle specifiers
knaresh89 0:6ca6723bc32e 408 //
knaresh89 0:6ca6723bc32e 409 switch (c) {
knaresh89 0:6ca6723bc32e 410 case 'c': {
knaresh89 0:6ca6723bc32e 411 char c0;
knaresh89 0:6ca6723bc32e 412 v = va_arg(*pParamList, int);
knaresh89 0:6ca6723bc32e 413 c0 = (char)v;
knaresh89 0:6ca6723bc32e 414 _StoreChar(&BufferDesc, c0);
knaresh89 0:6ca6723bc32e 415 break;
knaresh89 0:6ca6723bc32e 416 }
knaresh89 0:6ca6723bc32e 417 case 'd':
knaresh89 0:6ca6723bc32e 418 v = va_arg(*pParamList, int);
knaresh89 0:6ca6723bc32e 419 _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
knaresh89 0:6ca6723bc32e 420 break;
knaresh89 0:6ca6723bc32e 421 case 'u':
knaresh89 0:6ca6723bc32e 422 v = va_arg(*pParamList, int);
knaresh89 0:6ca6723bc32e 423 _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
knaresh89 0:6ca6723bc32e 424 break;
knaresh89 0:6ca6723bc32e 425 case 'x':
knaresh89 0:6ca6723bc32e 426 case 'X':
knaresh89 0:6ca6723bc32e 427 v = va_arg(*pParamList, int);
knaresh89 0:6ca6723bc32e 428 _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
knaresh89 0:6ca6723bc32e 429 break;
knaresh89 0:6ca6723bc32e 430 case 's':
knaresh89 0:6ca6723bc32e 431 {
knaresh89 0:6ca6723bc32e 432 const char * s = va_arg(*pParamList, const char *);
knaresh89 0:6ca6723bc32e 433 do {
knaresh89 0:6ca6723bc32e 434 c = *s;
knaresh89 0:6ca6723bc32e 435 s++;
knaresh89 0:6ca6723bc32e 436 if (c == '\0') {
knaresh89 0:6ca6723bc32e 437 break;
knaresh89 0:6ca6723bc32e 438 }
knaresh89 0:6ca6723bc32e 439 _StoreChar(&BufferDesc, c);
knaresh89 0:6ca6723bc32e 440 } while (BufferDesc.ReturnValue >= 0);
knaresh89 0:6ca6723bc32e 441 }
knaresh89 0:6ca6723bc32e 442 break;
knaresh89 0:6ca6723bc32e 443 case 'p':
knaresh89 0:6ca6723bc32e 444 v = va_arg(*pParamList, int);
knaresh89 0:6ca6723bc32e 445 _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
knaresh89 0:6ca6723bc32e 446 break;
knaresh89 0:6ca6723bc32e 447 case '%':
knaresh89 0:6ca6723bc32e 448 _StoreChar(&BufferDesc, '%');
knaresh89 0:6ca6723bc32e 449 break;
knaresh89 0:6ca6723bc32e 450 default:
knaresh89 0:6ca6723bc32e 451 break;
knaresh89 0:6ca6723bc32e 452 }
knaresh89 0:6ca6723bc32e 453 sFormat++;
knaresh89 0:6ca6723bc32e 454 } else {
knaresh89 0:6ca6723bc32e 455 _StoreChar(&BufferDesc, c);
knaresh89 0:6ca6723bc32e 456 }
knaresh89 0:6ca6723bc32e 457 } while (BufferDesc.ReturnValue >= 0);
knaresh89 0:6ca6723bc32e 458
knaresh89 0:6ca6723bc32e 459 if (BufferDesc.ReturnValue > 0) {
knaresh89 0:6ca6723bc32e 460 //
knaresh89 0:6ca6723bc32e 461 // Write remaining data, if any
knaresh89 0:6ca6723bc32e 462 //
knaresh89 0:6ca6723bc32e 463 if (BufferDesc.Cnt != 0u) {
knaresh89 0:6ca6723bc32e 464 SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
knaresh89 0:6ca6723bc32e 465 }
knaresh89 0:6ca6723bc32e 466 BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
knaresh89 0:6ca6723bc32e 467 }
knaresh89 0:6ca6723bc32e 468 return BufferDesc.ReturnValue;
knaresh89 0:6ca6723bc32e 469 }
knaresh89 0:6ca6723bc32e 470
knaresh89 0:6ca6723bc32e 471 /*********************************************************************
knaresh89 0:6ca6723bc32e 472 *
knaresh89 0:6ca6723bc32e 473 * SEGGER_RTT_printf
knaresh89 0:6ca6723bc32e 474 *
knaresh89 0:6ca6723bc32e 475 * Function description
knaresh89 0:6ca6723bc32e 476 * Stores a formatted string in SEGGER RTT control block.
knaresh89 0:6ca6723bc32e 477 * This data is read by the host.
knaresh89 0:6ca6723bc32e 478 *
knaresh89 0:6ca6723bc32e 479 * Parameters
knaresh89 0:6ca6723bc32e 480 * BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
knaresh89 0:6ca6723bc32e 481 * sFormat Pointer to format string, followed by the arguments for conversion
knaresh89 0:6ca6723bc32e 482 *
knaresh89 0:6ca6723bc32e 483 * Return values
knaresh89 0:6ca6723bc32e 484 * >= 0: Number of bytes which have been stored in the "Up"-buffer.
knaresh89 0:6ca6723bc32e 485 * < 0: Error
knaresh89 0:6ca6723bc32e 486 *
knaresh89 0:6ca6723bc32e 487 * Notes
knaresh89 0:6ca6723bc32e 488 * (1) Conversion specifications have following syntax:
knaresh89 0:6ca6723bc32e 489 * %[flags][FieldWidth][.Precision]ConversionSpecifier
knaresh89 0:6ca6723bc32e 490 * (2) Supported flags:
knaresh89 0:6ca6723bc32e 491 * -: Left justify within the field width
knaresh89 0:6ca6723bc32e 492 * +: Always print sign extension for signed conversions
knaresh89 0:6ca6723bc32e 493 * 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
knaresh89 0:6ca6723bc32e 494 * Supported conversion specifiers:
knaresh89 0:6ca6723bc32e 495 * c: Print the argument as one char
knaresh89 0:6ca6723bc32e 496 * d: Print the argument as a signed integer
knaresh89 0:6ca6723bc32e 497 * u: Print the argument as an unsigned integer
knaresh89 0:6ca6723bc32e 498 * x: Print the argument as an hexadecimal integer
knaresh89 0:6ca6723bc32e 499 * s: Print the string pointed to by the argument
knaresh89 0:6ca6723bc32e 500 * p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
knaresh89 0:6ca6723bc32e 501 */
knaresh89 0:6ca6723bc32e 502 int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
knaresh89 0:6ca6723bc32e 503 int r;
knaresh89 0:6ca6723bc32e 504 va_list ParamList;
knaresh89 0:6ca6723bc32e 505
knaresh89 0:6ca6723bc32e 506 va_start(ParamList, sFormat);
knaresh89 0:6ca6723bc32e 507 r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
knaresh89 0:6ca6723bc32e 508 va_end(ParamList);
knaresh89 0:6ca6723bc32e 509 return r;
knaresh89 0:6ca6723bc32e 510 }
knaresh89 0:6ca6723bc32e 511 /*************************** End of file ****************************/