aboutsummaryrefslogtreecommitdiffstats
path: root/arduino/cores/nRF5/utility
diff options
context:
space:
mode:
Diffstat (limited to 'arduino/cores/nRF5/utility')
-rwxr-xr-xarduino/cores/nRF5/utility/AdaCallback.c93
-rwxr-xr-xarduino/cores/nRF5/utility/AdaCallback.cpp93
-rwxr-xr-xarduino/cores/nRF5/utility/AdaCallback.h112
-rwxr-xr-xarduino/cores/nRF5/utility/SoftwareTimer.h73
-rwxr-xr-xarduino/cores/nRF5/utility/TimeoutTimer.h56
-rwxr-xr-xarduino/cores/nRF5/utility/adafruit_fifo.cpp271
-rwxr-xr-xarduino/cores/nRF5/utility/adafruit_fifo.h87
-rwxr-xr-xarduino/cores/nRF5/utility/debug.cpp444
-rwxr-xr-xarduino/cores/nRF5/utility/debug.h71
-rwxr-xr-xarduino/cores/nRF5/utility/utilities.c102
-rwxr-xr-xarduino/cores/nRF5/utility/utilities.h66
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_ */