diff options
Diffstat (limited to 'arduino/cores/nRF5/utility')
-rwxr-xr-x | arduino/cores/nRF5/utility/AdaCallback.c | 93 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/AdaCallback.cpp | 93 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/AdaCallback.h | 112 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/SoftwareTimer.h | 73 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/TimeoutTimer.h | 56 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/adafruit_fifo.cpp | 271 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/adafruit_fifo.h | 87 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/debug.cpp | 444 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/debug.h | 71 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/utilities.c | 102 | ||||
-rwxr-xr-x | arduino/cores/nRF5/utility/utilities.h | 66 |
11 files changed, 1468 insertions, 0 deletions
diff --git a/arduino/cores/nRF5/utility/AdaCallback.c b/arduino/cores/nRF5/utility/AdaCallback.c new file mode 100755 index 0000000..0066bc2 --- /dev/null +++ b/arduino/cores/nRF5/utility/AdaCallback.c @@ -0,0 +1,93 @@ +/**************************************************************************/ +/*! + @file AdaCallback.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 "Arduino.h" + +static QueueHandle_t _cb_queue = NULL; + +void adafruit_callback_task(void* arg) +{ + (void) arg; + + while(1) + { + ada_callback_t* cb_data; + if ( xQueueReceive(_cb_queue, (void*) &cb_data, portMAX_DELAY) ) + { +// PRINT_HEX(cb_data); +// PRINT_HEX(cb_data->malloced_data); + + void* func = cb_data->callback_func; + uint32_t* args = cb_data->arguments; + + switch (cb_data->arg_count) + { + case 0: ((adacb_0arg_t) func)(); break; + case 1: ((adacb_1arg_t) func)(args[0]); break; + case 2: ((adacb_2arg_t) func)(args[0], args[1]); break; + case 3: ((adacb_3arg_t) func)(args[0], args[1], args[2]); break; + case 4: ((adacb_4arg_t) func)(args[0], args[1], args[2], args[3]); break; + case 5: ((adacb_5arg_t) func)(args[0], args[1], args[2], args[3], args[4]); break; + + default: VERIFY_MESS(NRF_ERROR_INVALID_PARAM, dbg_err_str); break; + } + + // free up resource + if (cb_data->malloced_data) rtos_free(cb_data->malloced_data); + rtos_free(cb_data); + } + } +} + +void ada_callback_queue(ada_callback_t* cb_data, bool from_isr) +{ + if ( from_isr ) + { + xQueueSendFromISR(_cb_queue, (void*) &cb_data, NULL); + }else + { + xQueueSend(_cb_queue, (void*) &cb_data, CFG_CALLBACK_TIMEOUT); + } +} + +void ada_callback_init(void) +{ + // queue to hold "Pointer to callback data" + _cb_queue = xQueueCreate(CFG_CALLBACK_QUEUE_LENGTH, sizeof(ada_callback_t*)); + + TaskHandle_t callback_task_hdl; + xTaskCreate( adafruit_callback_task, "Callback", CFG_CALLBACK_TASK_STACKSIZE, NULL, TASK_PRIO_NORMAL, &callback_task_hdl); +} diff --git a/arduino/cores/nRF5/utility/AdaCallback.cpp b/arduino/cores/nRF5/utility/AdaCallback.cpp new file mode 100755 index 0000000..0066bc2 --- /dev/null +++ b/arduino/cores/nRF5/utility/AdaCallback.cpp @@ -0,0 +1,93 @@ +/**************************************************************************/ +/*! + @file AdaCallback.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 "Arduino.h" + +static QueueHandle_t _cb_queue = NULL; + +void adafruit_callback_task(void* arg) +{ + (void) arg; + + while(1) + { + ada_callback_t* cb_data; + if ( xQueueReceive(_cb_queue, (void*) &cb_data, portMAX_DELAY) ) + { +// PRINT_HEX(cb_data); +// PRINT_HEX(cb_data->malloced_data); + + void* func = cb_data->callback_func; + uint32_t* args = cb_data->arguments; + + switch (cb_data->arg_count) + { + case 0: ((adacb_0arg_t) func)(); break; + case 1: ((adacb_1arg_t) func)(args[0]); break; + case 2: ((adacb_2arg_t) func)(args[0], args[1]); break; + case 3: ((adacb_3arg_t) func)(args[0], args[1], args[2]); break; + case 4: ((adacb_4arg_t) func)(args[0], args[1], args[2], args[3]); break; + case 5: ((adacb_5arg_t) func)(args[0], args[1], args[2], args[3], args[4]); break; + + default: VERIFY_MESS(NRF_ERROR_INVALID_PARAM, dbg_err_str); break; + } + + // free up resource + if (cb_data->malloced_data) rtos_free(cb_data->malloced_data); + rtos_free(cb_data); + } + } +} + +void ada_callback_queue(ada_callback_t* cb_data, bool from_isr) +{ + if ( from_isr ) + { + xQueueSendFromISR(_cb_queue, (void*) &cb_data, NULL); + }else + { + xQueueSend(_cb_queue, (void*) &cb_data, CFG_CALLBACK_TIMEOUT); + } +} + +void ada_callback_init(void) +{ + // queue to hold "Pointer to callback data" + _cb_queue = xQueueCreate(CFG_CALLBACK_QUEUE_LENGTH, sizeof(ada_callback_t*)); + + TaskHandle_t callback_task_hdl; + xTaskCreate( adafruit_callback_task, "Callback", CFG_CALLBACK_TASK_STACKSIZE, NULL, TASK_PRIO_NORMAL, &callback_task_hdl); +} diff --git a/arduino/cores/nRF5/utility/AdaCallback.h b/arduino/cores/nRF5/utility/AdaCallback.h new file mode 100755 index 0000000..b6a2708 --- /dev/null +++ b/arduino/cores/nRF5/utility/AdaCallback.h @@ -0,0 +1,112 @@ +/**************************************************************************/ +/*! + @file AdaCallback.h + @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. +*/ +/**************************************************************************/ +#ifndef ADACALLBACK_H_ +#define ADACALLBACK_H_ + +#include "common_inc.h" + +#define CFG_CALLBACK_TASK_STACKSIZE (512*2) +#define CFG_CALLBACK_QUEUE_LENGTH 20 +#define CFG_CALLBACK_TIMEOUT 100 + +//#ifdef __cplusplus +//extern "C"{ +//#endif + +typedef struct +{ + void* malloced_data; + void* callback_func; + + uint8_t arg_count; + bool from_isr; +// uint8_t callback_type; +// uint8_t _reserved[2]; + + uint32_t arguments[1]; // flexible array holder +}ada_callback_t; + +VERIFY_STATIC( sizeof(ada_callback_t) == 16 ); + +/*------------- Defer callback type, determined by number of arguments -------------*/ +typedef void (*adacb_0arg_t) (void); +typedef void (*adacb_1arg_t) (uint32_t); +typedef void (*adacb_2arg_t) (uint32_t, uint32_t); +typedef void (*adacb_3arg_t) (uint32_t, uint32_t, uint32_t); +typedef void (*adacb_4arg_t) (uint32_t, uint32_t, uint32_t, uint32_t); +typedef void (*adacb_5arg_t) (uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + +#ifdef __cplusplus +template<typename Func, typename... Args> +inline void _cb_setup(bool _from_isr, void *_malloced, Func _func, Args... args) +{ + uint8_t const _count = sizeof...(args); + ada_callback_t* cb_data = (ada_callback_t*) rtos_malloc( sizeof(ada_callback_t) + (_count ? (_count-1)*4 : 0) ); + cb_data->malloced_data = _malloced; + cb_data->callback_func = (void*)_func; + cb_data->arg_count = _count; + if ( _count ) { + uint32_t arguments[] = { ((uint32_t)args)... }; + memcpy(cb_data->arguments, arguments, 4*_count); + } + + extern void ada_callback_queue(ada_callback_t* cb_data, bool from_isr); + ada_callback_queue(cb_data, _from_isr); +} +#endif // __cplusplus + +/** + * Schedule an function and parameters to be invoked in Ada Callback Task + * Macro can take at least 2 and at max 7 arguments + * - 1st arg : pointer data that need to be freed with free(pointer) after function is invoked + * - 2nd arg : function to be invoked + * - 3rd-7th arg : function argument, will be cast to uint32_t + */ +#define ada_callback(... ) _cb_setup(false, __VA_ARGS__) + +/** + * Similar to ada_callback() but invoke in ISR-context + */ +#define ada_callback_fromISR(... ) _cb_setup(true , __VA_ARGS__) + +void ada_callback_init(void); +void ada_callback_queue(ada_callback_t* cb_data, bool from_isr); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* ADACALLBACK_H_ */ diff --git a/arduino/cores/nRF5/utility/SoftwareTimer.h b/arduino/cores/nRF5/utility/SoftwareTimer.h new file mode 100755 index 0000000..ac72443 --- /dev/null +++ b/arduino/cores/nRF5/utility/SoftwareTimer.h @@ -0,0 +1,73 @@ +/**************************************************************************/ +/*! + @file SoftwareTimer.h + @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. +*/ +/**************************************************************************/ +#ifndef SOFTWARETIMER_H_ +#define SOFTWARETIMER_H_ + +#include "Arduino.h" + +class SoftwareTimer +{ + private: + TimerHandle_t _handle; + + public: + SoftwareTimer() { _handle = NULL; } + virtual ~SoftwareTimer() { if(_handle != NULL) xTimerDelete(_handle, 0); } + + void begin(uint32_t ms, TimerCallbackFunction_t callback) + { + _handle = xTimerCreate(NULL, ms2tick(ms), true, NULL, callback); + } + + TimerHandle_t getHandle(void) + { + return _handle; + } + + void start(void) { xTimerStart(_handle, 0); } + void stop (void) { xTimerStop (_handle, 0); } + + void setPeriod(uint32_t ms) + { + BaseType_t active = xTimerIsTimerActive(_handle); + xTimerChangePeriod(_handle, ms2tick(ms), 0); + + // Change period of inactive timer will also start it !! + if ( !active ) xTimerStop(_handle, 0); + } +}; + +#endif /* SOFTWARETIMER_H_ */ diff --git a/arduino/cores/nRF5/utility/TimeoutTimer.h b/arduino/cores/nRF5/utility/TimeoutTimer.h new file mode 100755 index 0000000..d0a8d68 --- /dev/null +++ b/arduino/cores/nRF5/utility/TimeoutTimer.h @@ -0,0 +1,56 @@ +/**************************************************************************/ +/*! + @file TimeoutTimer.h + @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. +*/ +/**************************************************************************/ + +#ifndef _TIMEOUT_TIMER_H_ +#define _TIMEOUT_TIMER_H_ + +class TimeoutTimer +{ + private: + uint32_t start; + uint32_t interval; + + public: + TimeoutTimer() { start = millis(); interval = 0; } + TimeoutTimer(uint32_t msec) { set(msec); } + + void set(uint32_t msec) { start = millis(); interval = msec; } + bool expired(void) const { return (millis() - start) >= interval; } + void restart(void) { start = millis(); } + void reset(void) { start += interval; } // used for periodic invoke to prevent drift +}; + +#endif /* _TIMEOUT_TIMER_H_ */ diff --git a/arduino/cores/nRF5/utility/adafruit_fifo.cpp b/arduino/cores/nRF5/utility/adafruit_fifo.cpp new file mode 100755 index 0000000..e20ac1e --- /dev/null +++ b/arduino/cores/nRF5/utility/adafruit_fifo.cpp @@ -0,0 +1,271 @@ +/**************************************************************************/ +/*! + @file adafruit_fifo.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 "adafruit_fifo.h" +#include <string.h> + +/******************************************************************************/ +/*! + @brief Constructor + + @param[in] depth + Maximum number of items can be hold in buffer + @param[in] item_size + Number of bytes of each item +*/ +/******************************************************************************/ +Adafruit_FIFO::Adafruit_FIFO(uint8_t item_size, uint16_t depth) + : _item_size(item_size) +{ + _buffer = NULL; + _mutex = NULL; + _depth = depth; + _overwritable = false; + + _count = _wr_idx = _rd_idx = 0; +} + +void Adafruit_FIFO::begin(void) +{ + _buffer = (uint8_t*) malloc(_item_size*_depth); + _mutex = xSemaphoreCreateMutex(); +} + +void Adafruit_FIFO::begin(uint16_t depth) +{ + _depth = depth; + begin(); +} + +void Adafruit_FIFO::overwriteIfFull(bool enable) +{ + _overwritable = enable; +} + + +/** + * Destructor + * @return + */ +Adafruit_FIFO::~Adafruit_FIFO() +{ + if (_mutex) vSemaphoreDelete(_mutex); + if (_buffer) rtos_free(_buffer); +} + +bool Adafruit_FIFO::_mutex_lock(bool isr) +{ + (void) isr; + return xSemaphoreTake(_mutex, portMAX_DELAY); +} + +bool Adafruit_FIFO::_mutex_unlock(bool isr) +{ + (void) isr; + return xSemaphoreGive(_mutex); +} + + +/******************************************************************************/ +/*! + @brief Clear the FIFO +*/ +/******************************************************************************/ +void Adafruit_FIFO::clear(void) +{ + _mutex_lock(false); + _rd_idx = _wr_idx = _count = 0; + _mutex_unlock(false); +} + +/******************************************************************************/ +/*! + @brief Write an item to the FIFO + + @param[in] item + Memory address of the item +*/ +/******************************************************************************/ +uint16_t Adafruit_FIFO::write(void const* item) +{ + if ( full() && !_overwritable ) return 0; + + _mutex_lock(false); + + memcpy( _buffer + (_wr_idx * _item_size), + item, + _item_size); + + _wr_idx = (_wr_idx + 1) % _depth; + + if ( full() ) + { + _rd_idx = _wr_idx; // keep the full state (rd == wr && len = size) + } + else + { + _count++; + } + + _mutex_unlock(false); + + return 1; +} + +/******************************************************************************/ +/*! + @brief Write array of items to the FIFO + + @param[in] data + Memory address of the item's array + @param[in] n + Number of items to write + + @return Number of written items +*/ +/******************************************************************************/ +uint16_t Adafruit_FIFO::write(void const * data, uint16_t n) +{ + if ( n == 0 ) return 0; + + uint8_t* buf = (uint8_t*) data; + + uint16_t len = 0; + while( (len < n) && write(buf) ) + { + len++; + buf += _item_size; + } + + return len; +} + +/******************************************************************************/ +/*! + @brief Read an item from FIFO + + @param[in] buffer + Memory address to store item +*/ +/******************************************************************************/ +uint16_t Adafruit_FIFO::read(void* buffer) +{ + if( empty() ) return 0; + + _mutex_lock(false); + + memcpy(buffer, + _buffer + (_rd_idx * _item_size), + _item_size); + _rd_idx = (_rd_idx + 1) % _depth; + _count--; + + _mutex_unlock(false); + + return 1; +} + +/******************************************************************************/ +/*! + @brief Read multiple items to an array + + @param[in] buffer + Memory address of the item's array + @param[in] n + Number of items to read + + @return Number of read items +*/ +/******************************************************************************/ +uint16_t Adafruit_FIFO::read(void * buffer, uint16_t n) +{ + if( n == 0 ) return 0; + + uint8_t* buf = (uint8_t*) buffer; + + uint16_t len = 0; + while( (len < n) && read(buf) ) + { + len++; + buf += _item_size; + } + + return len; +} + +/******************************************************************************/ +/*! + @brief Read an item without removing it from the FIFO + + @param[in] buffer + Memory address to store item +*/ +/******************************************************************************/ +bool Adafruit_FIFO::peek(void* buffer) +{ + if( empty() ) return false; + + memcpy(buffer, + _buffer + (_rd_idx * _item_size), + _item_size); + + return true; +} + + +/******************************************************************************/ +/*! + @brief Read an item without removing it from the FIFO at the specific index + + @param[in] position + Position to read from in the FIFO buffer + + @param[in] buffer + Memory address to store item +*/ +/******************************************************************************/ +bool Adafruit_FIFO::peekAt(uint16_t position, void * p_buffer) +{ + if( empty() || (position >= _count) ) return false; + + uint16_t index = (_rd_idx + position) % _depth; // rd_idx is position=0 + memcpy(p_buffer, + _buffer + (index * _item_size), + _item_size); + + return true; +} + diff --git a/arduino/cores/nRF5/utility/adafruit_fifo.h b/arduino/cores/nRF5/utility/adafruit_fifo.h new file mode 100755 index 0000000..bfeb333 --- /dev/null +++ b/arduino/cores/nRF5/utility/adafruit_fifo.h @@ -0,0 +1,87 @@ +/**************************************************************************/ +/*! + @file adafruit_fifo.h + @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. +*/ +/**************************************************************************/ + +#ifndef _Adafruit_FIFO_H_ +#define _Adafruit_FIFO_H_ + +#include <stdint.h> +#include <stdbool.h> +#include <Arduino.h> + +class Adafruit_FIFO +{ + private: + uint8_t* _buffer ; ///< buffer pointer + uint16_t _depth ; ///< max items + const uint8_t _item_size ; ///< size of each item + bool _overwritable ; ///< Overwrite when full + volatile uint16_t _count ; ///< number of items in queue + volatile uint16_t _wr_idx ; ///< write pointer + volatile uint16_t _rd_idx ; ///< read pointer + + SemaphoreHandle_t _mutex; + + bool _mutex_lock(bool isr); + bool _mutex_unlock(bool isr); + + public: + // Constructor + Adafruit_FIFO(uint8_t item_size, uint16_t depth = 0); + + virtual ~Adafruit_FIFO(); + + void begin(void); + void begin(uint16_t depth); + + void clear(void); + void overwriteIfFull(bool enable); + + uint16_t write(void const* item); + uint16_t write(void const * data, uint16_t n); + + uint16_t read(void* buffer); + uint16_t read(void * buffer, uint16_t n); + + bool peek(void* buffer); + bool peekAt(uint16_t position, void * p_buffer); + + inline bool empty(void) { return _count == 0; } + inline bool full(void) { return _count == _depth; } + inline uint16_t count(void) { return _count; } + inline uint16_t remaining(void) { return _depth - _count; } +}; + +#endif /* _Adafruit_FIFO_H_ */ 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 + +} diff --git a/arduino/cores/nRF5/utility/debug.h b/arduino/cores/nRF5/utility/debug.h new file mode 100755 index 0000000..9134389 --- /dev/null +++ b/arduino/cores/nRF5/utility/debug.h @@ -0,0 +1,71 @@ +/**************************************************************************/ +/*! + @file debug.h + @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. +*/ +/**************************************************************************/ + +#ifndef _DEBUG_H +#define _DEBUG_H + +#include "common_inc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#if CFG_DEBUG +const char* dbg_ble_event_str(uint16_t evt_id); +const char* dbg_err_str(int32_t err_id); +#endif + +int dbgHeapTotal(void); +int dbgHeapUsed(void); + +int dbgStackTotal(void); +int dbgStackUsed(void); + +static inline int dbgHeapFree(void) +{ + return dbgHeapTotal() - dbgHeapUsed(); +} + +void dbgMemInfo(void); +void dbgPrintVersion(void); +void dbgDumpMemory(void const *buf, uint8_t size, uint16_t count, bool printOffset); +void dbgDumpMemoryCFormat(const char* str, void const *buf, uint16_t count); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/arduino/cores/nRF5/utility/utilities.c b/arduino/cores/nRF5/utility/utilities.c new file mode 100755 index 0000000..4df2dce --- /dev/null +++ b/arduino/cores/nRF5/utility/utilities.c @@ -0,0 +1,102 @@ +/**************************************************************************/ +/*! + @file utilities.c + @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 <Arduino.h> +#include "utilities.h" +#include <string.h> +#include <stdio.h> + +#include "nrf_sdm.h" +#include "nrf52/nrf_mbr.h" + + +/******************************************************************************/ +/*! + @brief Find the corresponding data from the key + @param +*/ +/******************************************************************************/ +void const * lookup_find(lookup_table_t const* p_table, uint32_t key) +{ + for(uint16_t i=0; i<p_table->count; i++) + { + if (p_table->items[i].key == key) return p_table->items[i].data; + } + + return NULL; +} +/** + * Format: SDname SDverion, bootloader version + * e.g + * "s132 2.0.1, 0.5.0" + * "s132 5.0.0, 5.0.0 single bank" + * "s132 6.1.1 r0" + * @return + */ +const char* getBootloaderVersion(void) +{ + static char fw_str[30+1] = { 0 }; + + // Skip if already created + if ( fw_str[0] == 0 ) + { + uint32_t const sd_id = SD_ID_GET(MBR_SIZE); + uint32_t const sd_version = SD_VERSION_GET(MBR_SIZE); + + uint32_t const ver1 = sd_version / 1000000; + uint32_t const ver2 = (sd_version % 1000000)/1000; + uint32_t const ver3 = sd_version % 1000; + + sprintf(fw_str, "s%d %d.%d.%d r%d", sd_id, + ver1, ver2, ver3, U32_BYTE4(bootloaderVersion) ); + } + + return fw_str; +} + +const char* getMcuUniqueID(void) +{ + static char serial_str[16+1] = { 0 }; + + // Skip if already created + if ( serial_str[0] == 0 ) + { + sprintf(serial_str, "%08lX%08lX", NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0]); + } + + return serial_str; +} + diff --git a/arduino/cores/nRF5/utility/utilities.h b/arduino/cores/nRF5/utility/utilities.h new file mode 100755 index 0000000..3359587 --- /dev/null +++ b/arduino/cores/nRF5/utility/utilities.h @@ -0,0 +1,66 @@ +/**************************************************************************/ +/*! + @file utilities.h + @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. +*/ +/**************************************************************************/ +#ifndef UTILITIES_H_ +#define UTILITIES_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint32_t key; + void const * data; +}lookup_entry_t; + +typedef struct +{ + uint16_t count; + lookup_entry_t const* items; +} lookup_table_t; + +void const * lookup_find(lookup_table_t const* p_table, uint32_t key); + +const char* getBootloaderVersion(void); +const char* getMcuUniqueID(void); + +#ifdef __cplusplus +} +#endif + +#endif /* UTILITIES_H_ */ |