mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	* Initial commit * Clean up * Remove display code * Change cmake build * Add SimpleLink SDK for CC13xx/CC26xx as submodule * Remove commented line from build.sh * Working build * Remove SDK submodule * Squashed 'examples/knx-cc1310/coresdk_cc13xx_cc26xx/' content from commit 0d78d32 git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5 * Add more comments and enable Power_idleFunc() for NoRTOS variant. Internal SDK driver functions which have to wait for something will cause Power_idleFunc to be called instead of doing busy wait. * Move CC1310 platform init around * Optimize a bit more in debug build config as the binary does not fit into 128Kb flash otherwise. * Explicitly list each source/header file in build config. Use linker group to resolve circular dependencies. * Ignore vscode settings.json * Increase stacks size * Only compile CC1310 source code if #define DeviceFamily_CC13X0 * initial commit of CC1310 RF driver with first working RX version * Better handling of buttonUp() across platforms * Start cleanup * continue cleanup * Fix bau2920 compilation * Continue cleanup * Fix compilation in other examples * Fix compilation * htons() and ntohs() only for SAMD and STM32, but not for Linux and ESP8266 and ESP32 * htons(9 and ntohs() needed for CC13x0 * Continue cleanup * Add CC1310 platform to CI * Fix CI * Use more recent toolchain from ARM * Fix travis * Use Ubuntu Focal * Fix toolchain for travis * Fix package name * Fix toolchain * Add libstdc++-dev package * Add newlib packages * Remove commented commands from CI * Fix travis * Fix compilation of knxPython * Clean up linefeeds * Fix RX callback * Move RF CRC16-DNP to bits.cpp * Fix TX * Optimization: do not calc CRC for block1 again in rf_data_link_layer * Make newline optional in printHex * Cleanup. First working version: ETS5 programming of individual address via KNX/RF coupler. * Use LEDs and Buttons to control ProgMode and Flash Erase * Remove settings.json (VScode) * Add README.md * Update README.md * Update README.md * Fix typo
		
			
				
	
	
		
			501 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			501 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*********************************************************************
 | |
| *                    SEGGER Microcontroller GmbH                     *
 | |
| *                        The Embedded Experts                        *
 | |
| **********************************************************************
 | |
| *                                                                    *
 | |
| *            (c) 1995 - 2019 SEGGER Microcontroller GmbH             *
 | |
| *                                                                    *
 | |
| *       www.segger.com     Support: support@segger.com               *
 | |
| *                                                                    *
 | |
| **********************************************************************
 | |
| *                                                                    *
 | |
| *       SEGGER RTT * Real Time Transfer for embedded targets         *
 | |
| *                                                                    *
 | |
| **********************************************************************
 | |
| *                                                                    *
 | |
| * All rights reserved.                                               *
 | |
| *                                                                    *
 | |
| * SEGGER strongly recommends to not make any changes                 *
 | |
| * to or modify the source code of this software in order to stay     *
 | |
| * compatible with the RTT protocol and J-Link.                       *
 | |
| *                                                                    *
 | |
| * Redistribution and use in source and binary forms, with or         *
 | |
| * without modification, are permitted provided that the following    *
 | |
| * condition is met:                                                  *
 | |
| *                                                                    *
 | |
| * o Redistributions of source code must retain the above copyright   *
 | |
| *   notice, this condition and the following disclaimer.             *
 | |
| *                                                                    *
 | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
 | |
| * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
 | |
| * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
 | |
| * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
 | |
| * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
 | |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
 | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
 | |
| * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
 | |
| * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
 | |
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
 | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
 | |
| * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
 | |
| * DAMAGE.                                                            *
 | |
| *                                                                    *
 | |
| **********************************************************************
 | |
| ---------------------------END-OF-HEADER------------------------------
 | |
| File    : SEGGER_RTT_printf.c
 | |
| Purpose : Replacement for printf to write formatted data via RTT
 | |
| Revision: $Rev: 17697 $
 | |
| ----------------------------------------------------------------------
 | |
| */
 | |
| #include "SEGGER_RTT.h"
 | |
| #include "SEGGER_RTT_Conf.h"
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       Defines, configurable
 | |
| *
 | |
| **********************************************************************
 | |
| */
 | |
| 
 | |
| #ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE
 | |
|   #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64)
 | |
| #endif
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdarg.h>
 | |
| 
 | |
| 
 | |
| #define FORMAT_FLAG_LEFT_JUSTIFY   (1u << 0)
 | |
| #define FORMAT_FLAG_PAD_ZERO       (1u << 1)
 | |
| #define FORMAT_FLAG_PRINT_SIGN     (1u << 2)
 | |
| #define FORMAT_FLAG_ALTERNATE      (1u << 3)
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       Types
 | |
| *
 | |
| **********************************************************************
 | |
| */
 | |
| 
 | |
| typedef struct {
 | |
|   char*     pBuffer;
 | |
|   unsigned  BufferSize;
 | |
|   unsigned  Cnt;
 | |
| 
 | |
|   int   ReturnValue;
 | |
| 
 | |
|   unsigned RTTBufferIndex;
 | |
| } SEGGER_RTT_PRINTF_DESC;
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       Function prototypes
 | |
| *
 | |
| **********************************************************************
 | |
| */
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       Static code
 | |
| *
 | |
| **********************************************************************
 | |
| */
 | |
| /*********************************************************************
 | |
| *
 | |
| *       _StoreChar
 | |
| */
 | |
| static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) {
 | |
|   unsigned Cnt;
 | |
| 
 | |
|   Cnt = p->Cnt;
 | |
|   if ((Cnt + 1u) <= p->BufferSize) {
 | |
|     *(p->pBuffer + Cnt) = c;
 | |
|     p->Cnt = Cnt + 1u;
 | |
|     p->ReturnValue++;
 | |
|   }
 | |
|   //
 | |
|   // Write part of string, when the buffer is full
 | |
|   //
 | |
|   if (p->Cnt == p->BufferSize) {
 | |
|     if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) {
 | |
|       p->ReturnValue = -1;
 | |
|     } else {
 | |
|       p->Cnt = 0u;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       _PrintUnsigned
 | |
| */
 | |
| static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
 | |
|   static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
 | |
|   unsigned Div;
 | |
|   unsigned Digit;
 | |
|   unsigned Number;
 | |
|   unsigned Width;
 | |
|   char c;
 | |
| 
 | |
|   Number = v;
 | |
|   Digit = 1u;
 | |
|   //
 | |
|   // Get actual field width
 | |
|   //
 | |
|   Width = 1u;
 | |
|   while (Number >= Base) {
 | |
|     Number = (Number / Base);
 | |
|     Width++;
 | |
|   }
 | |
|   if (NumDigits > Width) {
 | |
|     Width = NumDigits;
 | |
|   }
 | |
|   //
 | |
|   // Print leading chars if necessary
 | |
|   //
 | |
|   if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) {
 | |
|     if (FieldWidth != 0u) {
 | |
|       if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) {
 | |
|         c = '0';
 | |
|       } else {
 | |
|         c = ' ';
 | |
|       }
 | |
|       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | |
|         FieldWidth--;
 | |
|         _StoreChar(pBufferDesc, c);
 | |
|         if (pBufferDesc->ReturnValue < 0) {
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (pBufferDesc->ReturnValue >= 0) {
 | |
|     //
 | |
|     // Compute Digit.
 | |
|     // Loop until Digit has the value of the highest digit required.
 | |
|     // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100.
 | |
|     //
 | |
|     while (1) {
 | |
|       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)
 | |
|         NumDigits--;
 | |
|       } else {
 | |
|         Div = v / Digit;
 | |
|         if (Div < Base) {        // Is our divider big enough to extract the highest digit from value? => Done
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|       Digit *= Base;
 | |
|     }
 | |
|     //
 | |
|     // Output digits
 | |
|     //
 | |
|     do {
 | |
|       Div = v / Digit;
 | |
|       v -= Div * Digit;
 | |
|       _StoreChar(pBufferDesc, _aV2C[Div]);
 | |
|       if (pBufferDesc->ReturnValue < 0) {
 | |
|         break;
 | |
|       }
 | |
|       Digit /= Base;
 | |
|     } while (Digit);
 | |
|     //
 | |
|     // Print trailing spaces if necessary
 | |
|     //
 | |
|     if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) {
 | |
|       if (FieldWidth != 0u) {
 | |
|         while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | |
|           FieldWidth--;
 | |
|           _StoreChar(pBufferDesc, ' ');
 | |
|           if (pBufferDesc->ReturnValue < 0) {
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       _PrintInt
 | |
| */
 | |
| static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) {
 | |
|   unsigned Width;
 | |
|   int Number;
 | |
| 
 | |
|   Number = (v < 0) ? -v : v;
 | |
| 
 | |
|   //
 | |
|   // Get actual field width
 | |
|   //
 | |
|   Width = 1u;
 | |
|   while (Number >= (int)Base) {
 | |
|     Number = (Number / (int)Base);
 | |
|     Width++;
 | |
|   }
 | |
|   if (NumDigits > Width) {
 | |
|     Width = NumDigits;
 | |
|   }
 | |
|   if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) {
 | |
|     FieldWidth--;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Print leading spaces if necessary
 | |
|   //
 | |
|   if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) {
 | |
|     if (FieldWidth != 0u) {
 | |
|       while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | |
|         FieldWidth--;
 | |
|         _StoreChar(pBufferDesc, ' ');
 | |
|         if (pBufferDesc->ReturnValue < 0) {
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   //
 | |
|   // Print sign if necessary
 | |
|   //
 | |
|   if (pBufferDesc->ReturnValue >= 0) {
 | |
|     if (v < 0) {
 | |
|       v = -v;
 | |
|       _StoreChar(pBufferDesc, '-');
 | |
|     } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) {
 | |
|       _StoreChar(pBufferDesc, '+');
 | |
|     } else {
 | |
| 
 | |
|     }
 | |
|     if (pBufferDesc->ReturnValue >= 0) {
 | |
|       //
 | |
|       // Print leading zeros if necessary
 | |
|       //
 | |
|       if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) {
 | |
|         if (FieldWidth != 0u) {
 | |
|           while ((FieldWidth != 0u) && (Width < FieldWidth)) {
 | |
|             FieldWidth--;
 | |
|             _StoreChar(pBufferDesc, '0');
 | |
|             if (pBufferDesc->ReturnValue < 0) {
 | |
|               break;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if (pBufferDesc->ReturnValue >= 0) {
 | |
|         //
 | |
|         // Print number without sign
 | |
|         //
 | |
|         _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       Public code
 | |
| *
 | |
| **********************************************************************
 | |
| */
 | |
| /*********************************************************************
 | |
| *
 | |
| *       SEGGER_RTT_vprintf
 | |
| *
 | |
| *  Function description
 | |
| *    Stores a formatted string in SEGGER RTT control block.
 | |
| *    This data is read by the host.
 | |
| *
 | |
| *  Parameters
 | |
| *    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
 | |
| *    sFormat      Pointer to format string
 | |
| *    pParamList   Pointer to the list of arguments for the format string
 | |
| *
 | |
| *  Return values
 | |
| *    >= 0:  Number of bytes which have been stored in the "Up"-buffer.
 | |
| *     < 0:  Error
 | |
| */
 | |
| int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
 | |
|   char c;
 | |
|   SEGGER_RTT_PRINTF_DESC BufferDesc;
 | |
|   int v;
 | |
|   unsigned NumDigits;
 | |
|   unsigned FormatFlags;
 | |
|   unsigned FieldWidth;
 | |
|   char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
 | |
| 
 | |
|   BufferDesc.pBuffer        = acBuffer;
 | |
|   BufferDesc.BufferSize     = SEGGER_RTT_PRINTF_BUFFER_SIZE;
 | |
|   BufferDesc.Cnt            = 0u;
 | |
|   BufferDesc.RTTBufferIndex = BufferIndex;
 | |
|   BufferDesc.ReturnValue    = 0;
 | |
| 
 | |
|   do {
 | |
|     c = *sFormat;
 | |
|     sFormat++;
 | |
|     if (c == 0u) {
 | |
|       break;
 | |
|     }
 | |
|     if (c == '%') {
 | |
|       //
 | |
|       // Filter out flags
 | |
|       //
 | |
|       FormatFlags = 0u;
 | |
|       v = 1;
 | |
|       do {
 | |
|         c = *sFormat;
 | |
|         switch (c) {
 | |
|         case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
 | |
|         case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO;     sFormat++; break;
 | |
|         case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN;   sFormat++; break;
 | |
|         case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE;    sFormat++; break;
 | |
|         default:  v = 0; break;
 | |
|         }
 | |
|       } while (v);
 | |
|       //
 | |
|       // filter out field with
 | |
|       //
 | |
|       FieldWidth = 0u;
 | |
|       do {
 | |
|         c = *sFormat;
 | |
|         if ((c < '0') || (c > '9')) {
 | |
|           break;
 | |
|         }
 | |
|         sFormat++;
 | |
|         FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
 | |
|       } while (1);
 | |
| 
 | |
|       //
 | |
|       // Filter out precision (number of digits to display)
 | |
|       //
 | |
|       NumDigits = 0u;
 | |
|       c = *sFormat;
 | |
|       if (c == '.') {
 | |
|         sFormat++;
 | |
|         do {
 | |
|           c = *sFormat;
 | |
|           if ((c < '0') || (c > '9')) {
 | |
|             break;
 | |
|           }
 | |
|           sFormat++;
 | |
|           NumDigits = NumDigits * 10u + ((unsigned)c - '0');
 | |
|         } while (1);
 | |
|       }
 | |
|       //
 | |
|       // Filter out length modifier
 | |
|       //
 | |
|       c = *sFormat;
 | |
|       do {
 | |
|         if ((c == 'l') || (c == 'h')) {
 | |
|           sFormat++;
 | |
|           c = *sFormat;
 | |
|         } else {
 | |
|           break;
 | |
|         }
 | |
|       } while (1);
 | |
|       //
 | |
|       // Handle specifiers
 | |
|       //
 | |
|       switch (c) {
 | |
|       case 'c': {
 | |
|         char c0;
 | |
|         v = va_arg(*pParamList, int);
 | |
|         c0 = (char)v;
 | |
|         _StoreChar(&BufferDesc, c0);
 | |
|         break;
 | |
|       }
 | |
|       case 'd':
 | |
|         v = va_arg(*pParamList, int);
 | |
|         _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);
 | |
|         break;
 | |
|       case 'u':
 | |
|         v = va_arg(*pParamList, int);
 | |
|         _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags);
 | |
|         break;
 | |
|       case 'x':
 | |
|       case 'X':
 | |
|         v = va_arg(*pParamList, int);
 | |
|         _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags);
 | |
|         break;
 | |
|       case 's':
 | |
|         {
 | |
|           const char * s = va_arg(*pParamList, const char *);
 | |
|           do {
 | |
|             c = *s;
 | |
|             s++;
 | |
|             if (c == '\0') {
 | |
|               break;
 | |
|             }
 | |
|            _StoreChar(&BufferDesc, c);
 | |
|           } while (BufferDesc.ReturnValue >= 0);
 | |
|         }
 | |
|         break;
 | |
|       case 'p':
 | |
|         v = va_arg(*pParamList, int);
 | |
|         _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u);
 | |
|         break;
 | |
|       case '%':
 | |
|         _StoreChar(&BufferDesc, '%');
 | |
|         break;
 | |
|       default:
 | |
|         break;
 | |
|       }
 | |
|       sFormat++;
 | |
|     } else {
 | |
|       _StoreChar(&BufferDesc, c);
 | |
|     }
 | |
|   } while (BufferDesc.ReturnValue >= 0);
 | |
| 
 | |
|   if (BufferDesc.ReturnValue > 0) {
 | |
|     //
 | |
|     // Write remaining data, if any
 | |
|     //
 | |
|     if (BufferDesc.Cnt != 0u) {
 | |
|       SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt);
 | |
|     }
 | |
|     BufferDesc.ReturnValue += (int)BufferDesc.Cnt;
 | |
|   }
 | |
|   return BufferDesc.ReturnValue;
 | |
| }
 | |
| 
 | |
| /*********************************************************************
 | |
| *
 | |
| *       SEGGER_RTT_printf
 | |
| *
 | |
| *  Function description
 | |
| *    Stores a formatted string in SEGGER RTT control block.
 | |
| *    This data is read by the host.
 | |
| *
 | |
| *  Parameters
 | |
| *    BufferIndex  Index of "Up"-buffer to be used. (e.g. 0 for "Terminal")
 | |
| *    sFormat      Pointer to format string, followed by the arguments for conversion
 | |
| *
 | |
| *  Return values
 | |
| *    >= 0:  Number of bytes which have been stored in the "Up"-buffer.
 | |
| *     < 0:  Error
 | |
| *
 | |
| *  Notes
 | |
| *    (1) Conversion specifications have following syntax:
 | |
| *          %[flags][FieldWidth][.Precision]ConversionSpecifier
 | |
| *    (2) Supported flags:
 | |
| *          -: Left justify within the field width
 | |
| *          +: Always print sign extension for signed conversions
 | |
| *          0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision
 | |
| *        Supported conversion specifiers:
 | |
| *          c: Print the argument as one char
 | |
| *          d: Print the argument as a signed integer
 | |
| *          u: Print the argument as an unsigned integer
 | |
| *          x: Print the argument as an hexadecimal integer
 | |
| *          s: Print the string pointed to by the argument
 | |
| *          p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.)
 | |
| */
 | |
| int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) {
 | |
|   int r;
 | |
|   va_list ParamList;
 | |
| 
 | |
|   va_start(ParamList, sFormat);
 | |
|   r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList);
 | |
|   va_end(ParamList);
 | |
|   return r;
 | |
| }
 | |
| /*************************** End of file ****************************/
 |