diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2019-02-28 17:04:22 -0500 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2019-02-28 17:04:22 -0500 |
commit | d6869d1ec4bd24cd2c3eafa534f0849b25ec5607 (patch) | |
tree | 79e54ed27b39c31864895535d11399708d5a45c0 /arduino/cores/nRF5/utility/debug.cpp | |
parent | 614ee97bf3a2270c413527a7f35c54cbecd9e601 (diff) |
added basic code
Diffstat (limited to 'arduino/cores/nRF5/utility/debug.cpp')
-rwxr-xr-x | arduino/cores/nRF5/utility/debug.cpp | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/arduino/cores/nRF5/utility/debug.cpp b/arduino/cores/nRF5/utility/debug.cpp new file mode 100755 index 0000000..d786202 --- /dev/null +++ b/arduino/cores/nRF5/utility/debug.cpp @@ -0,0 +1,444 @@ +/**************************************************************************/ +/*! + @file debug.cpp + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Adafruit Industries (adafruit.com) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''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 THE COPYRIGHT HOLDER 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. +*/ +/**************************************************************************/ + +#include <stdint.h> +#include <stdarg.h> +#include <malloc.h> +#include <Arduino.h> +#include <ctype.h> + +// defined in linker script +extern uint32_t __data_start__[]; +extern uint32_t __data_end__[]; + +extern uint32_t __bss_start__[]; +extern uint32_t __bss_end__[]; + +extern unsigned char __HeapBase[]; +extern unsigned char __HeapLimit[]; + +extern uint32_t __StackTop[]; +extern uint32_t __StackLimit[]; + +extern "C" +{ + +void HardFault_Handler(void) +{ + // reset on hardfault + NVIC_SystemReset(); +} + +int dbgHeapTotal(void) +{ + return ((uint32_t) __HeapLimit) - ((uint32_t) __HeapBase); +} + +int dbgHeapUsed(void) +{ + return (mallinfo()).uordblks; +} + +int dbgStackTotal(void) +{ + return ((uint32_t) __StackTop) - ((uint32_t) __StackLimit); +} + +int dbgStackUsed(void) +{ + enum { STACK_PATTERN = 0xADADADAD }; + + uint32_t * p_start = (uint32_t*) &__StackLimit; + uint32_t * p_end = (uint32_t*) &__StackTop; + + uint32_t * p_buf = p_start; + while( *p_buf == STACK_PATTERN && p_buf != p_end) + { + p_buf++; + } + + if (p_buf == p_end) return (-1); + + return ((uint32_t) p_end) - ((uint32_t) p_buf); +} + +static void printMemRegion(const char* name, uint32_t top, uint32_t bottom, uint32_t used) +{ + char buffer[30]; + if ( used ) + { + sprintf(buffer, "%5lu / %5lu (%02lu%%)", used, top-bottom, (used*100)/ (top-bottom)); + }else + { + sprintf(buffer, "%lu", top-bottom); + } + + printf("| %-5s| 0x%04X - 0x%04X | %-19s |\n", name, (uint16_t) bottom, (uint16_t) (top-1), buffer); +} + +void dbgMemInfo(void) +{ + printf(" ______________________________________________\n"); + printf("| Name | Addr 0x2000xxxx | Usage |\n"); + printf("| ---------------------------------------------|\n"); + + // Pritn SRAM used for Stack executed by S132 and ISR + printMemRegion("Stack", ((uint32_t) __StackTop), ((uint32_t) __StackLimit), dbgStackUsed() ); + + // Print Heap usage overall (including memory malloced to tasks) + printMemRegion("Heap", ((uint32_t) __HeapLimit), ((uint32_t) __HeapBase), dbgHeapUsed() ); + + // DATA + BSS + printMemRegion("Bss", ((uint32_t) __bss_end__), ((uint32_t) __data_start__), 0); + + // Print SRAM Used by SoftDevice + printMemRegion("S132", (uint32_t) __data_start__, 0x20000000, 0); + + printf("|______________________________________________|\n"); + printf("\n"); + + // Print Task list + uint32_t tasknum = uxTaskGetNumberOfTasks(); + char* buf = (char*) rtos_malloc(tasknum*40); // 40 bytes per task + + vTaskList(buf); + + printf("Task State Prio StackLeft Num\n"); + printf("-----------------------------------\n"); + printf(buf); + printf("\n"); + rtos_free(buf); +} + +void dbgPrintVersion(void) +{ + printf("\n"); + printf("BSP Library : " ARDUINO_BSP_VERSION "\n"); + printf("Bootloader : %s\n", getBootloaderVersion()); + printf("Serial No : %s\n", getMcuUniqueID()); + printf("\n"); +} + +/******************************************************************************/ +/*! + @brief Helper function to display memory contents in a friendly format +*/ +/******************************************************************************/ +static void dump_str_line(uint8_t const* buf, uint16_t count) +{ + // each line is 16 bytes + for(int i=0; i<count; i++) + { + const char ch = buf[i]; + printf("%c", isprint(ch) ? ch : '.'); + } +} + +void dbgDumpMemory(void const *buf, uint8_t size, uint16_t count, bool printOffset) +{ + if ( !buf || !count ) + { + printf("NULL\n"); + return; + } + + uint8_t const *buf8 = (uint8_t const *) buf; + + char format[] = "%00lX"; + format[2] += 2*size; + + const uint8_t item_per_line = 16 / size; + + for(int i=0; i<count; i++) + { + uint32_t value=0; + + if ( i%item_per_line == 0 ) + { + // Print Ascii + if ( i != 0 ) + { + printf(" | "); + dump_str_line(buf8-16, 16); + printf("\n"); + } + + // print offset or absolute address + if (printOffset) + { + printf("%03lX: ", 16*i/item_per_line); + }else + { + printf("%08lX:", (uint32_t) buf8); + } + } + + memcpy(&value, buf8, size); + buf8 += size; + + printf(" "); + printf(format, value); + } + + // fill up last row to 16 for printing ascii + const uint16_t remain = count%16; + uint8_t nback = (remain ? remain : 16); + + if ( remain ) + { + for(int i=0; i< 16-remain; i++) + { + printf(" "); + for(int j=0; j<2*size; j++) printf(" "); + } + } + + printf(" | "); + dump_str_line(buf8-nback, nback); + printf("\n"); + + printf("\n"); +} + + +void dbgDumpMemoryCFormat(const char* str, void const *buf, uint16_t count) +{ + if ( !buf ) + { + printf("NULL\n"); + return; + } + + printf("%s = \n{\n ", str); + + uint8_t const *buf8 = (uint8_t const *) buf; + + for(int i=0; i<count; i++) + { + uint32_t value=0; + + if ( i%16 == 0 ) + { + if ( i != 0 ) printf(",\n "); + }else + { + if ( i != 0 ) printf(", "); + } + + printf("0x%02lX", *buf8); + buf8++; + } + + printf("\n\};\n"); +} + + + +#if CFG_DEBUG + +#include "ble.h" +#include "ble_hci.h" + +/*------------------------------------------------------------------*/ +/* BLE Event String + *------------------------------------------------------------------*/ +static lookup_entry_t const _strevt_lookup[] = +{ + // BLE common: 0x01 + { .key = BLE_EVT_USER_MEM_REQUEST , .data= "BLE_EVT_USER_MEM_REQUEST" }, + { .key = BLE_EVT_USER_MEM_RELEASE , .data= "BLE_EVT_USER_MEM_RELEASE" }, + + // BLE Gap: 0x10 + { .key = BLE_GAP_EVT_CONNECTED , .data= "BLE_GAP_EVT_CONNECTED" }, + { .key = BLE_GAP_EVT_DISCONNECTED , .data= "BLE_GAP_EVT_DISCONNECTED" }, + { .key = BLE_GAP_EVT_CONN_PARAM_UPDATE , .data= "BLE_GAP_EVT_CONN_PARAM_UPDATE" }, + { .key = BLE_GAP_EVT_SEC_PARAMS_REQUEST , .data= "BLE_GAP_EVT_SEC_PARAMS_REQUEST" }, + { .key = BLE_GAP_EVT_SEC_INFO_REQUEST , .data= "BLE_GAP_EVT_SEC_INFO_REQUEST" }, + { .key = BLE_GAP_EVT_PASSKEY_DISPLAY , .data= "BLE_GAP_EVT_PASSKEY_DISPLAY" }, + { .key = BLE_GAP_EVT_KEY_PRESSED , .data= "BLE_GAP_EVT_KEY_PRESSED" }, + { .key = BLE_GAP_EVT_AUTH_KEY_REQUEST , .data= "BLE_GAP_EVT_AUTH_KEY_REQUEST" }, + { .key = BLE_GAP_EVT_LESC_DHKEY_REQUEST , .data= "BLE_GAP_EVT_LESC_DHKEY_REQUEST" }, + { .key = BLE_GAP_EVT_AUTH_STATUS , .data= "BLE_GAP_EVT_AUTH_STATUS" }, + { .key = BLE_GAP_EVT_CONN_SEC_UPDATE , .data= "BLE_GAP_EVT_CONN_SEC_UPDATE" }, + { .key = BLE_GAP_EVT_TIMEOUT , .data= "BLE_GAP_EVT_TIMEOUT" }, + { .key = BLE_GAP_EVT_RSSI_CHANGED , .data= "BLE_GAP_EVT_RSSI_CHANGED" }, + { .key = BLE_GAP_EVT_ADV_REPORT , .data= "BLE_GAP_EVT_ADV_REPORT" }, + { .key = BLE_GAP_EVT_SEC_REQUEST , .data= "BLE_GAP_EVT_SEC_REQUEST" }, + { .key = BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST , .data= "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST" }, + { .key = BLE_GAP_EVT_SCAN_REQ_REPORT , .data= "BLE_GAP_EVT_SCAN_REQ_REPORT" }, + { .key = BLE_GAP_EVT_PHY_UPDATE_REQUEST , .data= "BLE_GAP_EVT_PHY_UPDATE_REQUEST" }, + { .key = BLE_GAP_EVT_PHY_UPDATE , .data= "BLE_GAP_EVT_PHY_UPDATE" }, + { .key = BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST , .data= "BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST" }, + { .key = BLE_GAP_EVT_DATA_LENGTH_UPDATE , .data= "BLE_GAP_EVT_DATA_LENGTH_UPDATE" }, + { .key = BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT , .data= "BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT" }, + { .key = BLE_GAP_EVT_ADV_SET_TERMINATED , .data= "BLE_GAP_EVT_ADV_SET_TERMINATED" }, + + // BLE Gattc: 0x30 + { .key = BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP , .data= "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP" }, + { .key = BLE_GATTC_EVT_REL_DISC_RSP , .data= "BLE_GATTC_EVT_REL_DISC_RSP" }, + { .key = BLE_GATTC_EVT_CHAR_DISC_RSP , .data= "BLE_GATTC_EVT_CHAR_DISC_RSP" }, + { .key = BLE_GATTC_EVT_DESC_DISC_RSP , .data= "BLE_GATTC_EVT_DESC_DISC_RSP" }, + { .key = BLE_GATTC_EVT_ATTR_INFO_DISC_RSP , .data= "BLE_GATTC_EVT_ATTR_INFO_DISC_RSP" }, + { .key = BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP , .data= "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP" }, + { .key = BLE_GATTC_EVT_READ_RSP , .data= "BLE_GATTC_EVT_READ_RSP" }, + { .key = BLE_GATTC_EVT_CHAR_VALS_READ_RSP , .data= "BLE_GATTC_EVT_CHAR_VALS_READ_RSP" }, + { .key = BLE_GATTC_EVT_WRITE_RSP , .data= "BLE_GATTC_EVT_WRITE_RSP" }, + { .key = BLE_GATTC_EVT_HVX , .data= "BLE_GATTC_EVT_HVX" }, + { .key = BLE_GATTC_EVT_EXCHANGE_MTU_RSP , .data= "BLE_GATTC_EVT_EXCHANGE_MTU_RSP" }, + { .key = BLE_GATTC_EVT_TIMEOUT , .data= "BLE_GATTC_EVT_TIMEOUT" }, + { .key = BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE , .data= "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE" }, + + // BLE Gatts: 0x50 + { .key = BLE_GATTS_EVT_WRITE , .data= "BLE_GATTS_EVT_WRITE" }, + { .key = BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST , .data= "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST" }, + { .key = BLE_GATTS_EVT_SYS_ATTR_MISSING , .data= "BLE_GATTS_EVT_SYS_ATTR_MISSING" }, + { .key = BLE_GATTS_EVT_HVC , .data= "BLE_GATTS_EVT_HVC" }, + { .key = BLE_GATTS_EVT_SC_CONFIRM , .data= "BLE_GATTS_EVT_SC_CONFIRM" }, + { .key = BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST , .data= "BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST" }, + { .key = BLE_GATTS_EVT_TIMEOUT , .data= "BLE_GATTS_EVT_TIMEOUT" }, + { .key = BLE_GATTS_EVT_HVN_TX_COMPLETE , .data= "BLE_GATTS_EVT_HVN_TX_COMPLETE" }, +}; + +lookup_table_t const _strevt_table = +{ + .count = arrcount(_strevt_lookup), + .items = _strevt_lookup +}; + +const char* dbg_ble_event_str(uint16_t evt_id) +{ + const char * str = (const char *) lookup_find(&_strevt_table, evt_id); + static char unknown_str[7] = {0}; + + if ( str == NULL ) + { + sprintf(unknown_str, "0x%04X", evt_id); + str = unknown_str; + } + + return str; +} + +/*------------------------------------------------------------------*/ +/* Error String + *------------------------------------------------------------------*/ +static lookup_entry_t const _strerr_lookup[] = +{ + // General: 0x0000 + { .key = NRF_ERROR_SVC_HANDLER_MISSING , .data = "NRF_ERROR_SVC_HANDLER_MISSING" }, + { .key = NRF_ERROR_SOFTDEVICE_NOT_ENABLED , .data = "NRF_ERROR_SOFTDEVICE_NOT_ENABLED" }, + { .key = NRF_ERROR_INTERNAL , .data = "NRF_ERROR_INTERNAL" }, + { .key = NRF_ERROR_NO_MEM , .data = "NRF_ERROR_NO_MEM" }, + { .key = NRF_ERROR_NOT_FOUND , .data = "NRF_ERROR_NOT_FOUND" }, + { .key = NRF_ERROR_NOT_SUPPORTED , .data = "NRF_ERROR_NOT_SUPPORTED" }, + { .key = NRF_ERROR_INVALID_PARAM , .data = "NRF_ERROR_INVALID_PARAM" }, + { .key = NRF_ERROR_INVALID_STATE , .data = "NRF_ERROR_INVALID_STATE" }, + { .key = NRF_ERROR_INVALID_LENGTH , .data = "NRF_ERROR_INVALID_LENGTH" }, + { .key = NRF_ERROR_INVALID_FLAGS , .data = "NRF_ERROR_INVALID_FLAGS" }, + { .key = NRF_ERROR_INVALID_DATA , .data = "NRF_ERROR_INVALID_DATA" }, + { .key = NRF_ERROR_DATA_SIZE , .data = "NRF_ERROR_DATA_SIZE" }, + { .key = NRF_ERROR_TIMEOUT , .data = "NRF_ERROR_TIMEOUT" }, + { .key = NRF_ERROR_NULL , .data = "NRF_ERROR_NULL" }, + { .key = NRF_ERROR_FORBIDDEN , .data = "NRF_ERROR_FORBIDDEN" }, + { .key = NRF_ERROR_INVALID_ADDR , .data = "NRF_ERROR_INVALID_ADDR" }, + { .key = NRF_ERROR_BUSY , .data = "NRF_ERROR_BUSY" }, + { .key = NRF_ERROR_CONN_COUNT , .data = "NRF_ERROR_CONN_COUNT" }, + { .key = NRF_ERROR_RESOURCES , .data = "NRF_ERROR_RESOURCES" }, + + // SDM: 0x1000 + { .key = NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN , .data = "NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN" }, + { .key = NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION , .data = "NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION" }, + { .key = NRF_ERROR_SDM_INCORRECT_CLENR0 , .data = "NRF_ERROR_SDM_INCORRECT_CLENR0" }, + + // SOC: 0x2000 + { .key = NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN , .data = "NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN" }, + { .key = NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE , .data = "NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE" }, + { .key = NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED , .data = "NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED" }, + { .key = NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN , .data = "NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN" }, + { .key = NRF_ERROR_SOC_POWER_MODE_UNKNOWN , .data = "NRF_ERROR_SOC_POWER_MODE_UNKNOWN" }, + { .key = NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN , .data = "NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN" }, + { .key = NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN , .data = "NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN" }, + { .key = NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES , .data = "NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES" }, + { .key = NRF_ERROR_SOC_PPI_INVALID_CHANNEL , .data = "NRF_ERROR_SOC_PPI_INVALID_CHANNEL" }, + { .key = NRF_ERROR_SOC_PPI_INVALID_GROUP , .data = "NRF_ERROR_SOC_PPI_INVALID_GROUP" }, + + // BLE Generic: 0x2000 + { .key = BLE_ERROR_NOT_ENABLED , .data = "BLE_ERROR_NOT_ENABLED" }, + { .key = BLE_ERROR_INVALID_CONN_HANDLE , .data = "BLE_ERROR_INVALID_CONN_HANDLE" }, + { .key = BLE_ERROR_INVALID_ATTR_HANDLE , .data = "BLE_ERROR_INVALID_ATTR_HANDLE" }, + { .key = BLE_ERROR_INVALID_ADV_HANDLE , .data = "BLE_ERROR_INVALID_ADV_HANDLE" }, + { .key = BLE_ERROR_INVALID_ROLE , .data = "BLE_ERROR_INVALID_ROLE" }, + { .key = BLE_ERROR_BLOCKED_BY_OTHER_LINKS , .data = "BLE_ERROR_BLOCKED_BY_OTHER_LINKS" }, + + // BLE GAP: 0x2200 + { .key = BLE_ERROR_GAP_UUID_LIST_MISMATCH , .data = "BLE_ERROR_GAP_UUID_LIST_MISMATCH" }, + { .key = BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST , .data = "BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST" }, + { .key = BLE_ERROR_GAP_INVALID_BLE_ADDR , .data = "BLE_ERROR_GAP_INVALID_BLE_ADDR" }, + { .key = BLE_ERROR_GAP_WHITELIST_IN_USE , .data = "BLE_ERROR_GAP_WHITELIST_IN_USE" }, + { .key = BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE , .data = "BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE" }, + { .key = BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE , .data = "BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE" }, + + // BLE GATTC: 0x2300 + { .key = BLE_ERROR_GATTC_PROC_NOT_PERMITTED , .data = "BLE_ERROR_GATTC_PROC_NOT_PERMITTED" }, + + // BLE GATTS: 0x2400 + { .key = BLE_ERROR_GATTS_INVALID_ATTR_TYPE , .data = "BLE_ERROR_GATTS_INVALID_ATTR_TYPE" }, + { .key = BLE_ERROR_GATTS_SYS_ATTR_MISSING , .data = "BLE_ERROR_GATTS_SYS_ATTR_MISSING" }, +}; + +lookup_table_t const _strerr_table = +{ + .count = arrcount(_strerr_lookup), + .items = _strerr_lookup +}; + +const char* dbg_err_str(int32_t err_id) +{ + const char * str = (const char *) lookup_find(&_strerr_table, err_id); + static char unknown_str[7] = {0}; + + if ( str == NULL ) + { + sprintf(unknown_str, "0x%04X", err_id); + str = unknown_str; + } + + return str; +} + +#endif + +} |