From 424735d44041fc478b572f973d997829b402153d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 18 Jun 2018 14:05:24 +0700 Subject: rename subfolder source to src --- src/osal/osal.c | 54 +++++++++++ src/osal/osal.h | 96 ++++++++++++++++++ src/osal/osal_freeRTOS.h | 200 ++++++++++++++++++++++++++++++++++++++ src/osal/osal_none.h | 247 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 597 insertions(+) create mode 100644 src/osal/osal.c create mode 100644 src/osal/osal.h create mode 100644 src/osal/osal_freeRTOS.h create mode 100644 src/osal/osal_none.h (limited to 'src/osal') diff --git a/src/osal/osal.c b/src/osal/osal.c new file mode 100644 index 000000000..f2078b09c --- /dev/null +++ b/src/osal/osal.c @@ -0,0 +1,54 @@ +/**************************************************************************/ +/*! + @file osal.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#include "tusb_option.h" +#include "osal.h" + + +//--------------------------------------------------------------------+ +// TICK API +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +uint32_t tusb_hal_millis(void) +{ + return ( ( ((uint64_t) xTaskGetTickCount()) * 1000) / configTICK_RATE_HZ ); +} + +#endif + diff --git a/src/osal/osal.h b/src/osal/osal.h new file mode 100644 index 000000000..669159607 --- /dev/null +++ b/src/osal/osal.h @@ -0,0 +1,96 @@ +/**************************************************************************/ +/*! + @file osal.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#ifndef _TUSB_OSAL_H_ +#define _TUSB_OSAL_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +/** \addtogroup group_osal + * @{ */ + +#include "tusb_option.h" +#include "common/tusb_common.h" + +enum +{ + OSAL_TIMEOUT_NOTIMEOUT = 0, // return immediately + OSAL_TIMEOUT_NORMAL = 10, // default timeout + OSAL_TIMEOUT_WAIT_FOREVER = 0xFFFFFFFFUL +}; + +#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER + + +#if CFG_TUSB_OS == OPT_OS_NONE + #include "osal_none.h" + +#else + #if CFG_TUSB_OS == OPT_OS_FREERTOS + #include "osal_freeRTOS.h" + #else + #error CFG_TUSB_OS is not defined or OS is not supported yet + #endif + + #define OSAL_TASK_BEGIN while(1) { + #define OSAL_TASK_END } + + //------------- Sub Task -------------// + #define OSAL_SUBTASK_BEGIN + #define OSAL_SUBTASK_END return TUSB_ERROR_NONE; + + #define STASK_RETURN(_error) return _error; + #define STASK_INVOKE(_subtask, _status) (_status) = _subtask + + //------------- Sub Task Assert -------------// + #define STASK_ASSERT_ERR(_err) VERIFY_ERR(_err) + #define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, _func) + + #define STASK_ASSERT(_cond) VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) + #define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, _func) +#endif + +#ifdef __cplusplus + } +#endif + +/** @} */ + +#endif /* _TUSB_OSAL_H_ */ diff --git a/src/osal/osal_freeRTOS.h b/src/osal/osal_freeRTOS.h new file mode 100644 index 000000000..6e6535da3 --- /dev/null +++ b/src/osal/osal_freeRTOS.h @@ -0,0 +1,200 @@ +/**************************************************************************/ +/*! + @file osal_freeRTOS.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +/** \ingroup group_osal + * @{ + * \defgroup Group_FreeRTOS FreeRTOS + * @{ */ + +#ifndef _TUSB_OSAL_FREERTOS_H_ +#define _TUSB_OSAL_FREERTOS_H_ + +//------------- FreeRTOS Headers -------------// +#include "FreeRTOS.h" +#include "semphr.h" +#include "queue.h" +#include "task.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +// Helper to determine if we are in ISR to use ISR API (only cover ARM Cortex) +static inline bool in_isr(void) +{ + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk); +} +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) \ + uint8_t _name##_##buf[_stack_sz*sizeof(StackType_t)]; \ + osal_task_def_t _name = { .func = _func, .prio = _prio, .stack_sz = _stack_sz, .buf = _name##_##buf, .strname = _str }; + +typedef struct +{ + void (*func)(void *param); + + uint16_t prio; + uint16_t stack_sz; + void* buf; + const char* strname; + + StaticTask_t stask; +}osal_task_def_t; + +typedef TaskHandle_t osal_task_t; + +static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) +{ + return xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, taskdef->buf, &taskdef->stask); +} + +static inline void osal_task_delay(uint32_t msec) +{ + vTaskDelay( pdMS_TO_TICKS(msec) ); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#define OSAL_QUEUE_DEF(_name, _depth, _type) \ + uint8_t _name##_##buf[_depth*sizeof(_type)];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + + StaticQueue_t sq; +}osal_queue_def_t; + +typedef QueueHandle_t osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + return xQueueCreateStatic(qdef->depth, qdef->item_sz, qdef->buf, &qdef->sq); +} + +static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + +static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) +{ + return xQueueSendToBackFromISR(queue_hdl, data, NULL); +} + +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) +{ + return xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER) == pdTRUE; +} + +static inline void osal_queue_flush(osal_queue_t const queue_hdl) +{ + // TODO move to thread context +// xQueueReset(queue_hdl); +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef StaticSemaphore_t osal_semaphore_def_t; +typedef SemaphoreHandle_t osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + return xSemaphoreCreateBinaryStatic(semdef); +} + +static inline bool osal_semaphore_post_isr(osal_semaphore_t sem_hdl) +{ + return xSemaphoreGiveFromISR(sem_hdl, NULL) == pdTRUE; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +{ + return xSemaphoreGive(sem_hdl) == pdTRUE; +} + +static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + +static inline void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) +{ + xSemaphoreTakeFromISR(sem_hdl, NULL); +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef SemaphoreHandle_t osal_mutex_t; + +#define osal_mutex_create(x) xSemaphoreCreateMutex() + +static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) +{ + return xSemaphoreGive(mutex_hdl); +} + +static inline void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = (xSemaphoreTake(mutex_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_FREERTOS_H_ */ + +/** @} */ +/** @} */ + diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h new file mode 100644 index 000000000..5b13fcbfa --- /dev/null +++ b/src/osal/osal_none.h @@ -0,0 +1,247 @@ +/**************************************************************************/ +/*! + @file osal_none.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +/** \ingroup group_osal + * \defgroup Group_OSNone None OS + * @{ */ + +#ifndef _TUSB_OSAL_NONE_H_ +#define _TUSB_OSAL_NONE_H_ + +#include "common/tusb_fifo.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +// NOTES: Each blocking OSAL_NONE services such as semaphore wait, +// queue receive embedded return statement, therefore local variable +// retain value before/after such services needed to declare as static +// OSAL_TASK_LOOP +// { +// OSAL_TASK_BEGIN +// +// task body statements +// +// OSAL_TASK_LOOP_ENG +// } +// +// NOTE: no switch statement is allowed in Task and subtask +//--------------------------------------------------------------------+ +#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) osal_task_def_t _name; + +typedef uint8_t osal_task_def_t; +typedef void* osal_task_t; + +static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) +{ + (void) taskdef; + return (osal_task_t) 1; // return non zero +} + +#define TASK_RESTART \ + _state = 0 + +#define OSAL_TASK_BEGIN \ + static uint16_t _state = 0; \ + ATTR_UNUSED static uint32_t _timeout = 0; \ + (void) _timeout; \ + switch(_state) { \ + case 0: { + +#define OSAL_TASK_END \ + default: TASK_RESTART; break; \ + }} \ + return; + +#define osal_task_delay(msec) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if ( _timeout + msec > tusb_hal_millis() ) \ + return TUSB_ERROR_OSAL_WAITING; \ + }while(0) + +//--------------------------------------------------------------------+ +// SUBTASK (a sub function that uses OS blocking services & called by a task +//--------------------------------------------------------------------+ +#define OSAL_SUBTASK_BEGIN OSAL_TASK_BEGIN + +#define OSAL_SUBTASK_END \ + default: TASK_RESTART; break; \ + }} \ + return TUSB_ERROR_NONE; + +#define STASK_INVOKE(_subtask, _status) \ + do { \ + _state = __LINE__; case __LINE__: \ + { \ + (_status) = _subtask; /* invoke sub task */ \ + if (TUSB_ERROR_OSAL_WAITING == (_status)) return TUSB_ERROR_OSAL_WAITING; \ + } \ + }while(0) + +//------------- Sub Task Assert -------------// +#define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0) + +#define STASK_ASSERT_ERR(_err) VERIFY_ERR_HDLR(_err, verify_breakpoint(); TASK_RESTART) +#define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, verify_breakpoint(); _func; TASK_RESTART ) + +#define STASK_ASSERT(_cond) VERIFY_HDLR(_cond, verify_breakpoint(); TASK_RESTART) +#define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, verify_breakpoint(); _func; TASK_RESTART) + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#define OSAL_QUEUE_DEF(_name, _depth, _type) FIFO_DEF(_name, _depth, _type, false) + +typedef fifo_t osal_queue_def_t; +typedef fifo_t* osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + fifo_clear(qdef); + return (osal_queue_t) qdef; +} + +static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) +{ + return fifo_write( (fifo_t*) queue_hdl, data); +} + +static inline void osal_queue_flush(osal_queue_t const queue_hdl) +{ + queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; +} + +#define osal_queue_receive(queue_hdl, p_data, msec, p_error) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if( queue_hdl->count == 0 ) { \ + if ( (msec != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + msec <= tusb_hal_millis()) ) \ + *(p_error) = TUSB_ERROR_OSAL_TIMEOUT; \ + else \ + return TUSB_ERROR_OSAL_WAITING; \ + } else{ \ + /*tusb_hal_int_disable_all();*/ \ + fifo_read(queue_hdl, p_data); \ + /*tusb_hal_int_enable_all();*/ \ + *(p_error) = TUSB_ERROR_NONE; \ + } \ + }while(0) + + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef struct +{ + volatile uint16_t count; + uint16_t max_count; +}osal_semaphore_def_t; + +typedef osal_semaphore_def_t* osal_semaphore_t; + + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + semdef->count = 0; + semdef->max_count = 1; + return semdef; +} + +#define osal_semaphore_post_isr osal_semaphore_post + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +{ + if (sem_hdl->count < sem_hdl->max_count ) sem_hdl->count++; + return true; +} + +static inline void osal_semaphore_reset_isr(osal_semaphore_t sem_hdl) +{ + sem_hdl->count = 0; +} + +#define osal_semaphore_wait(sem_hdl, msec, p_error) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if( sem_hdl->count == 0 ) { \ + if ( (msec != OSAL_TIMEOUT_WAIT_FOREVER) && (_timeout + msec <= tusb_hal_millis()) ) \ + *(p_error) = TUSB_ERROR_OSAL_TIMEOUT; \ + else \ + return TUSB_ERROR_OSAL_WAITING; \ + } else{ \ + /*tusb_hal_int_disable_all();*/ \ + sem_hdl->count--; \ + /*tusb_hal_int_enable_all();*/ \ + *(p_error) = TUSB_ERROR_NONE; \ + } \ + }while(0) + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +#if 0 +typedef osal_semaphore_t osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(void) +{ + return osal_semaphore_create(1, 0); +} + +static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) +{ + return osal_semaphore_post(mutex_hdl); +} + +#define osal_mutex_wait osal_semaphore_wait +#endif + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_NONE_H_ */ + +/** @} */ -- cgit v1.3.1 From e3591ac682b403c1a3a7c4426056c9c37b1a9088 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Jun 2018 12:53:13 +0700 Subject: enhance usbd: add usbd_defer_func() --- src/device/usbd.c | 50 +++++++++++++++++++++++++++++++++++++++----------- src/device/usbd_pvt.h | 17 +++++++++++------ src/osal/osal_none.h | 2 ++ 3 files changed, 52 insertions(+), 17 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index 59aa93c82..4332c2925 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -161,23 +161,30 @@ typedef enum USBD_EVT_XFER_DONE, USBD_EVT_SOF, - + USBD_EVT_FUNC_CALL }usbd_eventid_t; typedef struct ATTR_ALIGNED(4) { uint8_t rhport; uint8_t event_id; - uint8_t sub_event_id; - uint8_t reserved; union { + // USBD_EVT_SETUP_RECEIVED tusb_control_request_t setup_received; - struct { // USBD_EVENTID_XFER_DONE + // USBD_EVT_XFER_DONE + struct { uint8_t ep_addr; + uint8_t result; uint32_t xferred_byte; }xfer_done; + + // USBD_EVT_FUNC_CALL + struct { + void (*func)(void*); + void* param; + }func_call; }; } usbd_task_event_t; @@ -287,7 +294,7 @@ static tusb_error_t usbd_main_st(void) { if ( usbd_class_drivers[i].xfer_cb ) { - usbd_class_drivers[i].xfer_cb( event.rhport, event.xfer_done.ep_addr, (tusb_event_t) event.sub_event_id, event.xfer_done.xferred_byte); + usbd_class_drivers[i].xfer_cb( event.rhport, event.xfer_done.ep_addr, (tusb_event_t) event.xfer_done.result, event.xfer_done.xferred_byte); } } } @@ -582,24 +589,24 @@ void dcd_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, if (xferred_bytes) osal_semaphore_post_isr( _usbd_ctrl_sem ); }else { - usbd_task_event_t task_event = + usbd_task_event_t event = { .rhport = rhport, .event_id = USBD_EVT_XFER_DONE, - .sub_event_id = succeeded ? TUSB_EVENT_XFER_COMPLETE : TUSB_EVENT_XFER_ERROR }; - task_event.xfer_done.ep_addr = ep_addr; - task_event.xfer_done.xferred_byte = xferred_bytes; + event.xfer_done.ep_addr = ep_addr; + event.xfer_done.xferred_byte = xferred_bytes; + event.xfer_done.result = succeeded ? TUSB_EVENT_XFER_COMPLETE : TUSB_EVENT_XFER_ERROR; - osal_queue_send_isr(_usbd_q, &task_event); + osal_queue_send_isr(_usbd_q, &event); } TU_ASSERT(succeeded, ); } //--------------------------------------------------------------------+ -// HELPER +// Helper //--------------------------------------------------------------------+ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) { @@ -623,4 +630,25 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_d return TUSB_ERROR_NONE; } + +void usbd_defer_func(void (*func)(void*), void* param, bool isr ) +{ + usbd_task_event_t event = + { + .rhport = 0, + .event_id = USBD_EVT_FUNC_CALL, + }; + + event.func_call.func = func; + event.func_call.param = param; + + if ( isr ) + { + osal_queue_send_isr(_usbd_q, &event); + }else + { + osal_queue_send(_usbd_q, &event); + } +} + #endif diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 067d7e937..4632fc52b 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -36,6 +36,7 @@ #ifndef USBD_PVT_H_ #define USBD_PVT_H_ +#include "osal/osal.h" #ifdef __cplusplus extern "C" { @@ -45,17 +46,17 @@ extern osal_semaphore_t _usbd_ctrl_sem; //--------------------------------------------------------------------+ -// INTERNAL API +// INTERNAL API for stack management //--------------------------------------------------------------------+ -tusb_error_t usbd_init(void); -void usbd_task( void* param); +tusb_error_t usbd_init (void); +void usbd_task (void* param); +/*------------------------------------------------------------------*/ +/* Endpoint helper + *------------------------------------------------------------------*/ // helper to parse an pair of In and Out endpoint descriptors. They must be consecutive tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); -// Carry out Data and Status stage of control transfer -//tusb_error_t usbd_control_xfer_st(uint8_t rhport, tusb_dir_t dir, uint8_t * buffer, uint16_t length); - // Carry out Data and Status stage of control transfer // Must be call in a subtask (_st) function #define usbd_control_xfer_st(_rhport, _dir, _buffer, _len) \ @@ -72,6 +73,10 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_d }while(0) +/*------------------------------------------------------------------*/ +/* Other Helpers + *------------------------------------------------------------------*/ +void usbd_defer_func( void (*func)(void*), void* param, bool isr ); #ifdef __cplusplus diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 5b13fcbfa..0e29d110e 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -146,6 +146,8 @@ static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const return fifo_write( (fifo_t*) queue_hdl, data); } +#define osal_queue_send osal_queue_send_isr + static inline void osal_queue_flush(osal_queue_t const queue_hdl) { queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; -- cgit v1.3.1 From d438000b99a5dbd5357d042fa48d0d87f180f032 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Jun 2018 16:01:55 +0700 Subject: clean up --- src/device/usbd.c | 8 ++++++-- src/device/usbd_pvt.h | 2 +- src/osal/osal.h | 1 + src/osal/osal_freeRTOS.h | 2 +- src/osal/osal_none.h | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index 4332c2925..0f6cebc6c 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -182,7 +182,7 @@ typedef struct ATTR_ALIGNED(4) // USBD_EVT_FUNC_CALL struct { - void (*func)(void*); + osal_task_func_t func; void* param; }func_call; }; @@ -308,6 +308,10 @@ static tusb_error_t usbd_main_st(void) } } } + else if ( USBD_EVT_FUNC_CALL == event.event_id ) + { + if ( event.func_call.func ) event.func_call.func(event.func_call.param); + } else { STASK_ASSERT(false); @@ -631,7 +635,7 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_d return TUSB_ERROR_NONE; } -void usbd_defer_func(void (*func)(void*), void* param, bool isr ) +void usbd_defer_func(osal_task_func_t func, void* param, bool isr ) { usbd_task_event_t event = { diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 4632fc52b..8189d5811 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -76,7 +76,7 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_d /*------------------------------------------------------------------*/ /* Other Helpers *------------------------------------------------------------------*/ -void usbd_defer_func( void (*func)(void*), void* param, bool isr ); +void usbd_defer_func( osal_task_func_t func, void* param, bool isr ); #ifdef __cplusplus diff --git a/src/osal/osal.h b/src/osal/osal.h index 669159607..7a8e6ecbf 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -58,6 +58,7 @@ enum #define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER +typedef void (*osal_task_func_t)( void * ); #if CFG_TUSB_OS == OPT_OS_NONE #include "osal_none.h" diff --git a/src/osal/osal_freeRTOS.h b/src/osal/osal_freeRTOS.h index 6e6535da3..b14ed3100 100644 --- a/src/osal/osal_freeRTOS.h +++ b/src/osal/osal_freeRTOS.h @@ -71,7 +71,7 @@ static inline bool in_isr(void) typedef struct { - void (*func)(void *param); + osal_task_func_t func; uint16_t prio; uint16_t stack_sz; diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 0e29d110e..9bdb047b4 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -68,7 +68,7 @@ #define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) osal_task_def_t _name; typedef uint8_t osal_task_def_t; -typedef void* osal_task_t; +typedef void* osal_task_t; static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) { -- cgit v1.3.1 From 3e66d2d31e21d1ce91bcc4728c929b9bdf3421e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 4 Jul 2018 00:22:15 +0700 Subject: rename fifo * to tu_fifo to avoid conflict with other module --- src/class/cdc/cdc_device.c | 22 +++++++-------- src/common/tusb_fifo.c | 44 ++++++++++++++--------------- src/common/tusb_fifo.h | 56 ++++++++++++++++++------------------- src/osal/osal_none.h | 12 ++++---- tests/lpc18xx_43xx/test/test_fifo.c | 20 ++++++------- 5 files changed, 77 insertions(+), 77 deletions(-) (limited to 'src/osal') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 583180fcc..585c8c685 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -71,8 +71,8 @@ typedef struct { CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_rx_buf[64]; CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_tx_buf[64]; -FIFO_DEF(_rx_ff, CFG_TUD_CDC_RX_BUFSIZE, uint8_t, true); -FIFO_DEF(_tx_ff, CFG_TUD_CDC_TX_BUFSIZE, uint8_t, false); +TU_FIFO_DEF(_rx_ff, CFG_TUD_CDC_RX_BUFSIZE, uint8_t, true); +TU_FIFO_DEF(_tx_ff, CFG_TUD_CDC_TX_BUFSIZE, uint8_t, false); //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -104,18 +104,18 @@ void tud_n_cdc_get_line_coding (uint8_t rhport, cdc_line_coding_t* coding) //--------------------------------------------------------------------+ uint32_t tud_n_cdc_available(uint8_t rhport) { - return fifo_count(&_rx_ff); + return tu_fifo_count(&_rx_ff); } int8_t tud_n_cdc_read_char(uint8_t rhport) { int8_t ch; - return fifo_read(&_rx_ff, &ch) ? ch : (-1); + return tu_fifo_read(&_rx_ff, &ch) ? ch : (-1); } uint32_t tud_n_cdc_read(uint8_t rhport, void* buffer, uint32_t bufsize) { - return fifo_read_n(&_rx_ff, buffer, bufsize); + return tu_fifo_read_n(&_rx_ff, buffer, bufsize); } //--------------------------------------------------------------------+ @@ -124,12 +124,12 @@ uint32_t tud_n_cdc_read(uint8_t rhport, void* buffer, uint32_t bufsize) uint32_t tud_n_cdc_write_char(uint8_t rhport, char ch) { - return fifo_write(&_tx_ff, &ch) ? 1 : 0; + return tu_fifo_write(&_tx_ff, &ch) ? 1 : 0; } uint32_t tud_n_cdc_write(uint8_t rhport, void const* buffer, uint32_t bufsize) { - return fifo_write_n(&_tx_ff, buffer, bufsize); + return tu_fifo_write_n(&_tx_ff, buffer, bufsize); } bool tud_n_cdc_flush (uint8_t rhport) @@ -137,7 +137,7 @@ bool tud_n_cdc_flush (uint8_t rhport) uint8_t edpt = _cdcd_itf[rhport].ep_in; VERIFY( !dcd_edpt_busy(rhport, edpt) ); // skip if previous transfer not complete - uint16_t count = fifo_read_n(&_tx_ff, _tmp_tx_buf, sizeof(_tmp_tx_buf)); + uint16_t count = tu_fifo_read_n(&_tx_ff, _tmp_tx_buf, sizeof(_tmp_tx_buf)); VERIFY( tud_n_cdc_connected(rhport) ); // fifo is empty if not connected @@ -230,8 +230,8 @@ void cdcd_close(uint8_t rhport) // no need to close opened pipe, dcd bus reset will put controller's endpoints to default state memclr_(&_cdcd_itf[rhport], sizeof(cdcd_interface_t)); - fifo_clear(&_rx_ff); - fifo_clear(&_tx_ff); + tu_fifo_clear(&_rx_ff); + tu_fifo_clear(&_tx_ff); } tusb_error_t cdcd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request) @@ -282,7 +282,7 @@ tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u if ( ep_addr == p_cdc->ep_out ) { - fifo_write_n(&_rx_ff, _tmp_rx_buf, xferred_bytes); + tu_fifo_write_n(&_rx_ff, _tmp_rx_buf, xferred_bytes); // preparing for next TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, _tmp_rx_buf, sizeof(_tmp_rx_buf)), TUSB_ERROR_DCD_EDPT_XFER ); diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index d6f34f33f..03c0b63ab 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -1,6 +1,6 @@ /**************************************************************************/ /*! - @file fifo.c + @file tusb_fifo.c @author hathach (tinyusb.org) @section LICENSE @@ -44,8 +44,8 @@ *------------------------------------------------------------------*/ #if CFG_FIFO_MUTEX -#define mutex_lock_if_needed(_ff) if (_ff->mutex) fifo_mutex_lock(_ff->mutex) -#define mutex_unlock_if_needed(_ff) if (_ff->mutex) fifo_mutex_unlock(_ff->mutex) +#define mutex_lock_if_needed(_ff) if (_ff->mutex) tu_fifo_mutex_lock(_ff->mutex) +#define mutex_unlock_if_needed(_ff) if (_ff->mutex) tu_fifo_mutex_unlock(_ff->mutex) #else @@ -59,13 +59,13 @@ static inline uint16_t min16_of(uint16_t x, uint16_t y) return (x < y) ? x : y; } -static inline bool fifo_initalized(fifo_t* f) +static inline bool tu_fifo_initalized(tu_fifo_t* f) { return (f->buffer != NULL) && (f->depth > 0) && (f->item_size > 0); } -void fifo_config(fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) +void tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) { mutex_lock_if_needed(f); @@ -96,10 +96,10 @@ void fifo_config(fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bo @returns TRUE if the queue is not empty */ /******************************************************************************/ -bool fifo_read(fifo_t* f, void * p_buffer) +bool tu_fifo_read(tu_fifo_t* f, void * p_buffer) { - if( !fifo_initalized(f) ) return false; - if( fifo_empty(f) ) return false; + if( !tu_fifo_initalized(f) ) return false; + if( tu_fifo_empty(f) ) return false; mutex_lock_if_needed(f); @@ -130,10 +130,10 @@ bool fifo_read(fifo_t* f, void * p_buffer) @returns number of items read from the FIFO */ /******************************************************************************/ -uint16_t fifo_read_n (fifo_t* f, void * p_buffer, uint16_t count) +uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t count) { - if( !fifo_initalized(f) ) return 0; - if( fifo_empty(f) ) return 0; + if( !tu_fifo_initalized(f) ) return 0; + if( tu_fifo_empty(f) ) return 0; /* Limit up to fifo's count */ count = min16_of(count, f->count); @@ -149,7 +149,7 @@ uint16_t fifo_read_n (fifo_t* f, void * p_buffer, uint16_t count) uint8_t* p_buf = (uint8_t*) p_buffer; uint16_t len = 0; - while( (len < count) && fifo_read(f, p_buf) ) + while( (len < count) && tu_fifo_read(f, p_buf) ) { len++; p_buf += f->item_size; @@ -174,9 +174,9 @@ uint16_t fifo_read_n (fifo_t* f, void * p_buffer, uint16_t count) @returns TRUE if the queue is not empty */ /******************************************************************************/ -bool fifo_peek_at(fifo_t* f, uint16_t position, void * p_buffer) +bool tu_fifo_peek_at(tu_fifo_t* f, uint16_t position, void * p_buffer) { - if ( !fifo_initalized(f) ) return false; + if ( !tu_fifo_initalized(f) ) return false; if ( position >= f->count ) return false; // rd_idx is position=0 @@ -205,12 +205,12 @@ bool fifo_peek_at(fifo_t* f, uint16_t position, void * p_buffer) FIFO will always return TRUE) */ /******************************************************************************/ -bool fifo_write(fifo_t* f, void const * p_data) +bool tu_fifo_write(tu_fifo_t* f, void const * p_data) { - if ( !fifo_initalized(f) ) return false; + if ( !tu_fifo_initalized(f) ) return false; -// if ( fifo_full(f) && !f->overwritable ) return false; - TU_ASSERT( !(fifo_full(f) && !f->overwritable) ); +// if ( tu_fifo_full(f) && !f->overwritable ) return false; + TU_ASSERT( !(tu_fifo_full(f) && !f->overwritable) ); mutex_lock_if_needed(f); @@ -220,7 +220,7 @@ bool fifo_write(fifo_t* f, void const * p_data) f->wr_idx = (f->wr_idx + 1) % f->depth; - if (fifo_full(f)) + if (tu_fifo_full(f)) { f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size) } @@ -249,14 +249,14 @@ bool fifo_write(fifo_t* f, void const * p_data) @return Number of written elements */ /******************************************************************************/ -uint16_t fifo_write_n(fifo_t* f, void const * p_data, uint16_t count) +uint16_t tu_fifo_write_n(tu_fifo_t* f, void const * p_data, uint16_t count) { if ( count == 0 ) return 0; uint8_t* p_buf = (uint8_t*) p_data; uint16_t len = 0; - while( (len < count) && fifo_write(f, p_buf) ) + while( (len < count) && tu_fifo_write(f, p_buf) ) { len++; p_buf += f->item_size; @@ -273,7 +273,7 @@ uint16_t fifo_write_n(fifo_t* f, void const * p_data, uint16_t count) Pointer to the FIFO buffer to manipulate */ /******************************************************************************/ -void fifo_clear(fifo_t *f) +void tu_fifo_clear(tu_fifo_t *f) { mutex_lock_if_needed(f); diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 452b1f35f..d87b32395 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -1,6 +1,6 @@ /**************************************************************************/ /*! - @file fifo.h + @file tusb_fifo.h @author hathach (tinyusb.org) @section LICENSE @@ -65,10 +65,10 @@ #define _ff_mutex_def(mutex) #else -#define fifo_mutex_t struct os_mutex +#define tu_fifo_mutex_t struct os_mutex -#define fifo_mutex_lock(m) os_mutex_pend(m, OS_TIMEOUT_NEVER) -#define fifo_mutex_unlock(m) os_mutex_release(m) +#define tu_fifo_mutex_lock(m) os_mutex_pend(m, OS_TIMEOUT_NEVER) +#define tu_fifo_mutex_unlock(m) os_mutex_release(m) /* Internal use only */ #define _mutex_declare(m) .mutex = m @@ -82,7 +82,7 @@ #endif -/** \struct fifo_t +/** \struct tu_fifo_t * \brief Simple Circular FIFO */ typedef struct @@ -98,59 +98,59 @@ typedef struct bool overwritable ; #if CFG_FIFO_MUTEX - fifo_mutex_t * const mutex; + tu_fifo_mutex_t * const mutex; #endif -} fifo_t; +} tu_fifo_t; -#define FIFO_DEF(name, ff_depth, type, is_overwritable) /*, irq_mutex)*/ \ - uint8_t name##_buffer[ff_depth*sizeof(type)];\ - fifo_t name = {\ - .buffer = name##_buffer,\ - .depth = ff_depth,\ - .item_size = sizeof(type),\ - .overwritable = is_overwritable,\ +#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) /*, irq_mutex)*/ \ + uint8_t _name##_buf[_depth*sizeof(_type)];\ + tu_fifo_t _name = {\ + .buffer = _name##_buf,\ + .depth = _depth,\ + .item_size = sizeof(_type),\ + .overwritable = _overwritable,\ /*.irq = irq_mutex*/\ _mutex_declare(_mutex)\ } -void fifo_clear(fifo_t *f); -void fifo_config(fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); +void tu_fifo_clear(tu_fifo_t *f); +void tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); -bool fifo_write (fifo_t* f, void const * p_data); -uint16_t fifo_write_n (fifo_t* f, void const * p_data, uint16_t count); +bool tu_fifo_write (tu_fifo_t* f, void const * p_data); +uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * p_data, uint16_t count); -bool fifo_read (fifo_t* f, void * p_buffer); -uint16_t fifo_read_n (fifo_t* f, void * p_buffer, uint16_t count); +bool tu_fifo_read (tu_fifo_t* f, void * p_buffer); +uint16_t tu_fifo_read_n (tu_fifo_t* f, void * p_buffer, uint16_t count); -bool fifo_peek_at (fifo_t* f, uint16_t position, void * p_buffer); +bool tu_fifo_peek_at (tu_fifo_t* f, uint16_t position, void * p_buffer); -static inline bool fifo_peek(fifo_t* f, void * p_buffer) +static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) { - return fifo_peek_at(f, 0, p_buffer); + return tu_fifo_peek_at(f, 0, p_buffer); } -static inline bool fifo_empty(fifo_t* f) +static inline bool tu_fifo_empty(tu_fifo_t* f) { return (f->count == 0); } -static inline bool fifo_full(fifo_t* f) +static inline bool tu_fifo_full(tu_fifo_t* f) { return (f->count == f->depth); } -static inline uint16_t fifo_count(fifo_t* f) +static inline uint16_t tu_fifo_count(tu_fifo_t* f) { return f->count; } -static inline uint16_t fifo_remaining(fifo_t* f) +static inline uint16_t tu_fifo_remaining(tu_fifo_t* f) { return f->depth - f->count; } -static inline uint16_t fifo_depth(fifo_t* f) +static inline uint16_t tu_fifo_depth(tu_fifo_t* f) { return f->depth; } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 9bdb047b4..1328d1753 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -130,20 +130,20 @@ static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ -#define OSAL_QUEUE_DEF(_name, _depth, _type) FIFO_DEF(_name, _depth, _type, false) +#define OSAL_QUEUE_DEF(_name, _depth, _type) TU_FIFO_DEF(_name, _depth, _type, false) -typedef fifo_t osal_queue_def_t; -typedef fifo_t* osal_queue_t; +typedef tu_fifo_t osal_queue_def_t; +typedef tu_fifo_t* osal_queue_t; static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { - fifo_clear(qdef); + tu_fifo_clear(qdef); return (osal_queue_t) qdef; } static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) { - return fifo_write( (fifo_t*) queue_hdl, data); + return tu_fifo_write( (tu_fifo_t*) queue_hdl, data); } #define osal_queue_send osal_queue_send_isr @@ -164,7 +164,7 @@ static inline void osal_queue_flush(osal_queue_t const queue_hdl) return TUSB_ERROR_OSAL_WAITING; \ } else{ \ /*tusb_hal_int_disable_all();*/ \ - fifo_read(queue_hdl, p_data); \ + tu_fifo_read(queue_hdl, p_data); \ /*tusb_hal_int_enable_all();*/ \ *(p_error) = TUSB_ERROR_NONE; \ } \ diff --git a/tests/lpc18xx_43xx/test/test_fifo.c b/tests/lpc18xx_43xx/test/test_fifo.c index 2729644ff..0441680f7 100644 --- a/tests/lpc18xx_43xx/test/test_fifo.c +++ b/tests/lpc18xx_43xx/test/test_fifo.c @@ -40,11 +40,11 @@ #include "fifo.h" #define FIFO_SIZE 10 -FIFO_DEF(ff, FIFO_SIZE, uint8_t, false); +TU_FIFO_DEF(ff, FIFO_SIZE, uint8_t, false); void setUp(void) { - fifo_clear(&ff); + tu_fifo_clear(&ff); } void tearDown(void) @@ -57,13 +57,13 @@ void test_normal(void) for(i=0; i < FIFO_SIZE; i++) { - fifo_write(&ff, &i); + tu_fifo_write(&ff, &i); } for(i=0; i < FIFO_SIZE; i++) { uint8_t c; - fifo_read(&ff, &c); + tu_fifo_read(&ff, &c); TEST_ASSERT_EQUAL(i, c); } } @@ -71,21 +71,21 @@ void test_normal(void) void test_is_empty(void) { uint8_t temp; - TEST_ASSERT_TRUE(fifo_is_empty(&ff)); - fifo_write(&ff, &temp); - TEST_ASSERT_FALSE(fifo_is_empty(&ff)); + TEST_ASSERT_TRUE(tu_fifo_is_empty(&ff)); + tu_fifo_write(&ff, &temp); + TEST_ASSERT_FALSE(tu_fifo_is_empty(&ff)); } void test_is_full(void) { uint8_t i; - TEST_ASSERT_FALSE(fifo_is_full(&ff)); + TEST_ASSERT_FALSE(tu_fifo_is_full(&ff)); for(i=0; i < FIFO_SIZE; i++) { - fifo_write(&ff, &i); + tu_fifo_write(&ff, &i); } - TEST_ASSERT_TRUE(fifo_is_full(&ff)); + TEST_ASSERT_TRUE(tu_fifo_is_full(&ff)); } -- cgit v1.3.1 From cd5b5d3a53adb465ac614b6027e16c8ec987b09e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Jul 2018 16:52:22 +0700 Subject: change mapping interface to driver instead of class code --- src/device/usbd.c | 58 +++++++++++++++++++++------------------------------- src/osal/osal_none.h | 8 ++++---- 2 files changed, 27 insertions(+), 39 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index 450f8b485..504cdf77b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -64,7 +64,9 @@ //--------------------------------------------------------------------+ typedef struct { uint8_t config_num; - uint8_t itf2class[16]; // determine interface number belongs to which class + + // map interface number to driver (0xff is invalid) + uint8_t itf2drv[16]; }usbd_device_t; CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_CTRL_BUFSIZE]; @@ -225,14 +227,8 @@ tusb_error_t usbd_init (void) osal_task_create(&_usbd_task_def); - //------------- Core init -------------// - varclr_(&_usbd_dev); - //------------- class init -------------// - for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) - { - usbd_class_drivers[i].init(); - } + for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) usbd_class_drivers[i].init(); return TUSB_ERROR_NONE; } @@ -300,6 +296,17 @@ static tusb_error_t usbd_main_st(void) OSAL_SUBTASK_END } +static void usbd_reset(uint8_t rhport) +{ + varclr_(&_usbd_dev); + memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping + + for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) + { + if ( usbd_class_drivers[i].reset ) usbd_class_drivers[i].reset( rhport ); + } +} + //--------------------------------------------------------------------+ // CONTROL REQUEST //--------------------------------------------------------------------+ @@ -321,7 +328,7 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request if ( len ) { - TU_ASSERT( len <= CFG_TUD_CTRL_BUFSIZE, TUSB_ERROR_NOT_ENOUGH_MEMORY); + STASK_ASSERT( len <= CFG_TUD_CTRL_BUFSIZE ); memcpy(_usbd_ctrl_buf, buffer, len); usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, len ); }else @@ -356,17 +363,9 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request //------------- Class/Interface Specific Request -------------// else if ( TUSB_REQ_RCPT_INTERFACE == p_request->bmRequestType_bit.recipient) { - static uint8_t drid; - uint8_t const class_code = _usbd_dev.itf2class[ u16_low_u8(p_request->wIndex) ]; - - for (drid = 0; drid < USBD_CLASS_DRIVER_COUNT; drid++) - { - if ( usbd_class_drivers[drid].class_code == class_code ) break; - } - - if ( (drid < USBD_CLASS_DRIVER_COUNT) && usbd_class_drivers[drid].control_req_st ) + if (_usbd_dev.itf2drv[ u16_low_u8(p_request->wIndex) ] < USBD_CLASS_DRIVER_COUNT) { - STASK_INVOKE( usbd_class_drivers[drid].control_req_st(rhport, p_request), error ); + STASK_INVOKE( usbd_class_drivers[ _usbd_dev.itf2drv[ u16_low_u8(p_request->wIndex) ] ].control_req_st(rhport, p_request), error ); }else { dcd_control_stall(rhport); // Stall unsupported request @@ -437,11 +436,9 @@ static tusb_error_t proc_set_config_req(uint8_t rhport, uint8_t config_number) } TU_ASSERT( drid < USBD_CLASS_DRIVER_COUNT, TUSB_ERROR_NOT_SUPPORTED_YET ); - // Check duplicate interface number -> alternate setting - if( 0 == _usbd_dev.itf2class[p_desc_itf->bInterfaceNumber]) - { - _usbd_dev.itf2class[p_desc_itf->bInterfaceNumber] = class_code; - } + // Interface number must not be used + TU_ASSERT( 0xff == _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber], TUSB_ERROR_FAILED); + _usbd_dev.itf2drv[p_desc_itf->bInterfaceNumber] = drid; uint16_t length=0; TU_ASSERT_ERR( usbd_class_drivers[drid].open( rhport, p_desc_itf, &length ) ); @@ -525,11 +522,7 @@ void dcd_bus_event(uint8_t rhport, usbd_bus_event_type_t bus_event) switch(bus_event) { case USBD_BUS_EVENT_RESET: - varclr_(&_usbd_dev); - for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) - { - if ( usbd_class_drivers[i].reset ) usbd_class_drivers[i].reset( rhport ); - } + usbd_reset(rhport); osal_queue_flush(_usbd_q); osal_semaphore_reset_isr(_usbd_ctrl_sem); @@ -549,12 +542,7 @@ void dcd_bus_event(uint8_t rhport, usbd_bus_event_type_t bus_event) break; case USBD_BUS_EVENT_UNPLUGGED: - varclr_(&_usbd_dev); - for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) - { - if ( usbd_class_drivers[i].reset ) usbd_class_drivers[i].reset( rhport ); - } - + usbd_reset(rhport); tud_umount_cb(); // invoke callback break; diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 1328d1753..b8cd2893c 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -121,11 +121,11 @@ static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) //------------- Sub Task Assert -------------// #define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0) -#define STASK_ASSERT_ERR(_err) VERIFY_ERR_HDLR(_err, verify_breakpoint(); TASK_RESTART) -#define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, verify_breakpoint(); _func; TASK_RESTART ) +#define STASK_ASSERT_ERR(_err) VERIFY_ERR_HDLR(_err, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED ) -#define STASK_ASSERT(_cond) VERIFY_HDLR(_cond, verify_breakpoint(); TASK_RESTART) -#define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, verify_breakpoint(); _func; TASK_RESTART) +#define STASK_ASSERT(_cond) VERIFY_HDLR(_cond, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED) //--------------------------------------------------------------------+ // QUEUE API -- cgit v1.3.1 From e07b1acbed02fff395c91b421b7fdf6c7cda61a4 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 13 Aug 2018 18:10:23 +0700 Subject: rename VERIFY to TU_VERIFY to avoid conflict with application --- examples/obsolete/host/src/cdc_serial_host_app.c | 2 +- examples/obsolete/host/src/keyboard_host_app.c | 2 +- examples/obsolete/host/src/mouse_host_app.c | 2 +- src/class/cdc/cdc.h | 6 +- src/class/cdc/cdc_device.c | 4 +- src/class/cdc/cdc_rndis.h | 4 +- src/class/cdc/cdc_rndis_host.c | 2 +- src/class/hid/hid_device.c | 12 ++-- src/class/hid/hid_host.c | 2 +- src/class/msc/msc.h | 32 ++++----- src/class/msc/msc_device.c | 2 +- src/class/msc/msc_device.h | 2 +- src/common/tusb_compiler.h | 6 +- src/common/tusb_types.h | 2 +- src/common/tusb_verify.h | 78 +++++++++++----------- src/device/usbd.c | 8 +-- src/host/ehci/ehci.c | 4 +- src/host/ehci/ehci.h | 10 +-- src/host/hub.h | 6 +- src/host/ohci/ohci.h | 10 +-- src/osal/osal.h | 8 +-- src/osal/osal_none.h | 8 +-- .../nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c | 2 +- src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c | 6 +- src/portable/nxp/lpc17xx/dcd_lpc175x_6x.h | 2 +- src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c | 8 +-- src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h | 4 +- src/portable/nxp/lpc43xx_lpc18xx/hal_lpc43xx.c | 2 +- src/tusb.c | 2 +- 29 files changed, 119 insertions(+), 119 deletions(-) (limited to 'src/osal') diff --git a/examples/obsolete/host/src/cdc_serial_host_app.c b/examples/obsolete/host/src/cdc_serial_host_app.c index 0782d0518..e21a3a67d 100644 --- a/examples/obsolete/host/src/cdc_serial_host_app.c +++ b/examples/obsolete/host/src/cdc_serial_host_app.c @@ -115,7 +115,7 @@ void cdc_serial_host_app_init(void) sem_hdl = osal_semaphore_create(1, 0); TU_ASSERT( sem_hdl, VOID_RETURN); - VERIFY( osal_task_create(cdc_serial_host_app_task, "cdc", 128, NULL, CDC_SERIAL_APP_TASK_PRIO), ); + TU_VERIFY( osal_task_create(cdc_serial_host_app_task, "cdc", 128, NULL, CDC_SERIAL_APP_TASK_PRIO), ); } //------------- main task -------------// diff --git a/examples/obsolete/host/src/keyboard_host_app.c b/examples/obsolete/host/src/keyboard_host_app.c index 130df0feb..26b1a0800 100644 --- a/examples/obsolete/host/src/keyboard_host_app.c +++ b/examples/obsolete/host/src/keyboard_host_app.c @@ -105,7 +105,7 @@ void keyboard_host_app_init(void) queue_kbd_hdl = osal_queue_create( QUEUE_KEYBOARD_REPORT_DEPTH, sizeof(hid_keyboard_report_t) ); TU_ASSERT( queue_kbd_hdl, VOID_RETURN ); - VERIFY( osal_task_create(keyboard_host_app_task, "kbd", 128, NULL, KEYBOARD_APP_TASK_PRIO), ); + TU_VERIFY( osal_task_create(keyboard_host_app_task, "kbd", 128, NULL, KEYBOARD_APP_TASK_PRIO), ); } //------------- main task -------------// diff --git a/examples/obsolete/host/src/mouse_host_app.c b/examples/obsolete/host/src/mouse_host_app.c index e9ee482d8..c326becb8 100644 --- a/examples/obsolete/host/src/mouse_host_app.c +++ b/examples/obsolete/host/src/mouse_host_app.c @@ -106,7 +106,7 @@ void mouse_host_app_init(void) queue_mouse_hdl = osal_queue_create( QUEUE_MOUSE_REPORT_DEPTH, sizeof(hid_mouse_report_t) ); TU_ASSERT( queue_mouse_hdl, VOID_RETURN); - VERIFY( osal_task_create(mouse_host_app_task, "mouse", 128, NULL, MOUSE_APP_TASK_PRIO), ); + TU_VERIFY( osal_task_create(mouse_host_app_task, "mouse", 128, NULL, MOUSE_APP_TASK_PRIO), ); } //------------- main task -------------// diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index b0c4f90d4..1b127ad28 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -300,7 +300,7 @@ typedef struct ATTR_PACKED uint8_t : 0; }cdc_acm_capability_t; -VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); +TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); /// \brief Abstract Control Management Functional Descriptor /// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL @@ -390,7 +390,7 @@ typedef struct ATTR_PACKED uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 } cdc_line_coding_t; -VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); +TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); typedef struct ATTR_PACKED { @@ -399,7 +399,7 @@ typedef struct ATTR_PACKED uint16_t : 14; } cdc_line_control_state_t; -VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); +TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); /** @} */ diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index bbf1c8ceb..175e78d2f 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -157,11 +157,11 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) bool tud_cdc_n_write_flush (uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - VERIFY( !dcd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in) ); // skip if previous transfer not complete + TU_VERIFY( !dcd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in) ); // skip if previous transfer not complete uint16_t count = tu_fifo_read_n(&_cdcd_itf[itf].tx_ff, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE); - VERIFY( tud_cdc_n_connected(itf) ); // fifo is empty if not connected + TU_VERIFY( tud_cdc_n_connected(itf) ); // fifo is empty if not connected if ( count ) TU_ASSERT( dcd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_in, p_cdc->epout_buf, count) ); diff --git a/src/class/cdc/cdc_rndis.h b/src/class/cdc/cdc_rndis.h index 460477eb0..20da5660b 100644 --- a/src/class/cdc/cdc_rndis.h +++ b/src/class/cdc/cdc_rndis.h @@ -142,7 +142,7 @@ typedef struct { uint8_t oid_buffer[] ; ///< Flexible array contains the input data supplied by the host, required for the OID query request processing by the device, as per the host NDIS specification. } rndis_msg_query_t, rndis_msg_set_t; -VERIFY_STATIC(sizeof(rndis_msg_query_t) == 28, "Make sure flexible array member does not affect layout"); +TU_VERIFY_STATIC(sizeof(rndis_msg_query_t) == 28, "Make sure flexible array member does not affect layout"); /// \brief Query Complete Message /// \details This message MUST be sent by the device in response to a query OID message. @@ -156,7 +156,7 @@ typedef struct { uint8_t oid_buffer[] ; ///< Flexible array member contains the response data to the OID query request as specified by the host. } rndis_msg_query_cmplt_t; -VERIFY_STATIC(sizeof(rndis_msg_query_cmplt_t) == 24, "Make sure flexible array member does not affect layout"); +TU_VERIFY_STATIC(sizeof(rndis_msg_query_cmplt_t) == 24, "Make sure flexible array member does not affect layout"); //------------- Reset -------------// /// \brief Reset Message diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index 62361feb4..4d28b0e0c 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -75,7 +75,7 @@ static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_da tusb_error_t tusbh_cdc_rndis_get_mac_addr(uint8_t dev_addr, uint8_t mac_address[6]) { TU_ASSERT( tusbh_cdc_rndis_is_mounted(dev_addr), TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED); - VERIFY( mac_address, TUSB_ERROR_INVALID_PARA); + TU_VERIFY( mac_address, TUSB_ERROR_INVALID_PARA); memcpy(mac_address, rndish_data[dev_addr-1].mac_address, 6); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 0527c14bf..410359e6d 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -125,7 +125,7 @@ bool tud_hid_generic_ready(void) bool tud_hid_generic_report(uint8_t report_id, void const* report, uint8_t len) { - VERIFY( tud_hid_generic_ready() && (len < REPORT_BUFSIZE) ); + TU_VERIFY( tud_hid_generic_ready() && (len < REPORT_BUFSIZE) ); hidd_interface_t * p_hid = &_hidd_itf[ITF_IDX_GENERIC]; @@ -159,7 +159,7 @@ bool tud_hid_keyboard_is_boot_protocol(void) static bool hidd_kbd_report(hid_keyboard_report_t const *p_report) { - VERIFY( tud_hid_keyboard_ready() ); + TU_VERIFY( tud_hid_keyboard_ready() ); hidd_interface_t * p_hid = _kbd_rpt.itf; @@ -253,7 +253,7 @@ bool tud_hid_mouse_is_boot_protocol(void) static bool hidd_mouse_report(hid_mouse_report_t const *p_report) { - VERIFY( tud_hid_mouse_ready() ); + TU_VERIFY( tud_hid_mouse_ready() ); hidd_interface_t * p_hid = _mse_rpt.itf; memcpy(p_hid->report_buf, p_report, sizeof(hid_mouse_report_t)); @@ -277,7 +277,7 @@ bool tud_hid_mouse_data(uint8_t buttons, int8_t x, int8_t y, int8_t scroll, int8 bool tud_hid_mouse_move(int8_t x, int8_t y) { - VERIFY( tud_hid_mouse_ready() ); + TU_VERIFY( tud_hid_mouse_ready() ); hidd_interface_t * p_hid = _mse_rpt.itf; uint8_t prev_buttons = p_hid->report_buf[0]; @@ -287,7 +287,7 @@ bool tud_hid_mouse_move(int8_t x, int8_t y) bool tud_hid_mouse_scroll(int8_t vertical, int8_t horizontal) { - VERIFY( tud_hid_mouse_ready() ); + TU_VERIFY( tud_hid_mouse_ready() ); hidd_interface_t * p_hid = _mse_rpt.itf; uint8_t prev_buttons = p_hid->report_buf[0]; @@ -390,7 +390,7 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR); } - VERIFY(p_hid->desc_report, ERR_TUD_INVALID_DESCRIPTOR); + TU_VERIFY(p_hid->desc_report, ERR_TUD_INVALID_DESCRIPTOR); TU_ASSERT( dcd_edpt_open(rhport, desc_edpt), ERR_TUD_EDPT_OPEN_FAILED ); p_hid->itf_num = desc_itf->bInterfaceNumber; diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index fa617c5b0..369dad638 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -77,7 +77,7 @@ tusb_error_t hidh_interface_get_report(uint8_t dev_addr, void * report, hidh_int //------------- parameters validation -------------// // TODO change to use is configured function TU_ASSERT (TUSB_DEVICE_STATE_CONFIGURED == tuh_device_get_state(dev_addr), TUSB_ERROR_DEVICE_NOT_READY); - VERIFY (report, TUSB_ERROR_INVALID_PARA); + TU_VERIFY (report, TUSB_ERROR_INVALID_PARA); TU_ASSSERT (!hcd_pipe_is_busy(p_hid->pipe_hdl), TUSB_ERROR_INTERFACE_IS_BUSY); TU_ASSERT_ERR( hcd_pipe_xfer(p_hid->pipe_hdl, report, p_hid->report_size, true) ) ; diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h index ab8f066b3..ca5615055 100644 --- a/src/class/msc/msc.h +++ b/src/class/msc/msc.h @@ -109,7 +109,7 @@ typedef struct ATTR_PACKED uint8_t command[16] ; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block }msc_cbw_t; -VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct"); +TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct"); /// Command Status Wrapper typedef struct ATTR_PACKED @@ -120,7 +120,7 @@ typedef struct ATTR_PACKED uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t }msc_csw_t; -VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct"); +TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Constant @@ -173,7 +173,7 @@ typedef struct ATTR_PACKED uint8_t control ; } scsi_test_unit_ready_t; -VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct"); /// SCSI Inquiry Command typedef struct ATTR_PACKED @@ -186,7 +186,7 @@ typedef struct ATTR_PACKED uint8_t control ; } scsi_inquiry_t, scsi_request_sense_t; -VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct"); /// SCSI Inquiry Response Data typedef struct ATTR_PACKED @@ -232,7 +232,7 @@ typedef struct ATTR_PACKED uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor. } scsi_inquiry_resp_t; -VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct"); typedef struct ATTR_PACKED @@ -259,7 +259,7 @@ typedef struct ATTR_PACKED } scsi_sense_fixed_resp_t; -VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct"); typedef struct ATTR_PACKED { @@ -277,7 +277,7 @@ typedef struct ATTR_PACKED uint8_t control; } scsi_mode_sense6_t; -VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct"); +TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct"); typedef struct ATTR_PACKED { @@ -287,7 +287,7 @@ typedef struct ATTR_PACKED uint8_t block_descriptor_len; } scsi_mode_sense6_resp_t; -VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct"); +TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct"); typedef struct ATTR_PACKED { @@ -297,7 +297,7 @@ typedef struct ATTR_PACKED uint8_t control; } scsi_prevent_allow_medium_removal_t; -VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct"); +TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct"); typedef struct ATTR_PACKED { @@ -320,7 +320,7 @@ typedef struct ATTR_PACKED uint8_t control; } scsi_start_stop_unit_t; -VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct"); +TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct"); //--------------------------------------------------------------------+ // SCSI MMC @@ -334,7 +334,7 @@ typedef struct ATTR_PACKED uint8_t control; } scsi_read_format_capacity_t; -VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct"); +TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct"); typedef struct ATTR_PACKED{ uint8_t reserved[3]; @@ -348,7 +348,7 @@ typedef struct ATTR_PACKED{ } scsi_read_format_capacity_data_t; -VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct"); +TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Block Command (SBC-3) @@ -366,7 +366,7 @@ typedef struct ATTR_PACKED uint8_t control ; } scsi_read_capacity10_t; -VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct"); /// SCSI Read Capacity 10 Response Data typedef struct { @@ -374,7 +374,7 @@ typedef struct { uint32_t block_size ; ///< Block size in bytes } scsi_read_capacity10_resp_t; -VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct"); /// SCSI Read 10 Command typedef struct ATTR_PACKED @@ -387,8 +387,8 @@ typedef struct ATTR_PACKED uint8_t control ; } scsi_read10_t, scsi_write10_t; -VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct"); -VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct"); +TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct"); #ifdef __cplusplus } diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 27762805c..a11212c4b 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -152,7 +152,7 @@ void mscd_reset(uint8_t rhport) tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len) { // only support SCSI's BOT protocol - VERIFY( ( MSC_SUBCLASS_SCSI == p_desc_itf->bInterfaceSubClass && + TU_VERIFY( ( MSC_SUBCLASS_SCSI == p_desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == p_desc_itf->bInterfaceProtocol ), TUSB_ERROR_MSC_UNSUPPORTED_PROTOCOL ); mscd_interface_t * p_msc = &_mscd_itf; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 6080b10df..8403dfed9 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -47,7 +47,7 @@ //--------------------------------------------------------------------+ // Class Driver Configuration //--------------------------------------------------------------------+ -VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct"); +TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct"); #ifndef CFG_TUD_MSC_MAXLUN #define CFG_TUD_MSC_MAXLUN 1 diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 35a4cc928..09cc59633 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -56,12 +56,12 @@ #endif //--------------------------------------------------------------------+ -// Compile-time Assert (use VERIFY_STATIC to avoid name conflict) +// Compile-time Assert (use TU_VERIFY_STATIC to avoid name conflict) //--------------------------------------------------------------------+ #if defined(__ICCARM__) || (__STDC_VERSION__ >= 201112L ) - #define VERIFY_STATIC static_assert + #define TU_VERIFY_STATIC static_assert #else - #define VERIFY_STATIC(const_expr, _mess) enum { XSTRING_CONCAT_(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } + #define TU_VERIFY_STATIC(const_expr, _mess) enum { XSTRING_CONCAT_(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) } #endif // allow debugger to watch any module-wide variables anywhere diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 1e8a5ef27..c3ed4f2bd 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -369,7 +369,7 @@ typedef struct ATTR_PACKED{ uint16_t wLength; } tusb_control_request_t; -VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "mostly compiler option issue"); +TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "mostly compiler option issue"); // TODO move to somewhere suitable static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t recipient) diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index adcdfc97f..41c2b5be1 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -50,8 +50,8 @@ * * e.g * - * - VERIFY( cond ) will return false if cond is false - * - VERIFY( cond, err) will return err instead if cond is false + * - TU_VERIFY( cond ) will return false if cond is false + * - TU_VERIFY( cond, err) will return err instead if cond is false *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -60,7 +60,7 @@ //--------------------------------------------------------------------+ -// VERIFY Helper +// TU_VERIFY Helper //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= 1 #include @@ -88,21 +88,21 @@ /* Macro Generator *------------------------------------------------------------------*/ -// Helper to implement optional parameter for VERIFY Macro family +// Helper to implement optional parameter for TU_VERIFY Macro family #define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 #define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 -/*------------- Generator for VERIFY and VERIFY_HDLR -------------*/ -#define VERIFY_DEFINE(_cond, _handler, _ret) do { if ( !(_cond) ) { _handler; return _ret; } } while(0) +/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/ +#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do { if ( !(_cond) ) { _handler; return _ret; } } while(0) -/*------------- Generator for VERIFY_ERR and VERIFY_ERR_HDLR -------------*/ -#define VERIFY_ERR_DEF2(_error, _handler) \ +/*------------- Generator for TU_VERIFY_ERR and TU_VERIFY_ERR_HDLR -------------*/ +#define TU_VERIFY_ERR_DEF2(_error, _handler) \ do { \ uint32_t _err = (uint32_t)(_error); \ if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _err; }\ } while(0) -#define VERIFY_ERR_DEF3(_error, _handler, _ret) \ +#define TU_VERIFY_ERR_DEF3(_error, _handler, _ret) \ do { \ uint32_t _err = (uint32_t)(_error); \ if ( 0 != _err ) { _MESS_ERR(_err); _handler; return _ret; }\ @@ -112,66 +112,66 @@ /*------------------------------------------------------------------*/ -/* VERIFY - * - VERIFY_1ARGS : return false if failed - * - VERIFY_2ARGS : return provided value if failed +/* TU_VERIFY + * - TU_VERIFY_1ARGS : return false if failed + * - TU_VERIFY_2ARGS : return provided value if failed *------------------------------------------------------------------*/ -#define VERIFY_1ARGS(_cond) VERIFY_DEFINE(_cond, , false) -#define VERIFY_2ARGS(_cond, _ret) VERIFY_DEFINE(_cond, , _ret) +#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false) +#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret) -#define VERIFY(...) GET_3RD_ARG(__VA_ARGS__, VERIFY_2ARGS, VERIFY_1ARGS)(__VA_ARGS__) +#define TU_VERIFY(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS)(__VA_ARGS__) /*------------------------------------------------------------------*/ -/* VERIFY WITH HANDLER - * - VERIFY_HDLR_2ARGS : execute handler, return false if failed - * - VERIFY_HDLR_3ARGS : execute handler, return provided error if failed +/* TU_VERIFY WITH HANDLER + * - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed + * - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed *------------------------------------------------------------------*/ -#define VERIFY_HDLR_2ARGS(_cond, _handler) VERIFY_DEFINE(_cond, _handler, false) -#define VERIFY_HDLR_3ARGS(_cond, _handler, _ret) VERIFY_DEFINE(_cond, _handler, _ret) +#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false) +#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret) -#define VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, VERIFY_HDLR_3ARGS, VERIFY_HDLR_2ARGS)(__VA_ARGS__) +#define TU_VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS)(__VA_ARGS__) /*------------------------------------------------------------------*/ -/* VERIFY STATUS - * - VERIFY_ERR_1ARGS : return status of condition if failed - * - VERIFY_ERR_2ARGS : return provided status code if failed +/* TU_VERIFY STATUS + * - TU_VERIFY_ERR_1ARGS : return status of condition if failed + * - TU_VERIFY_ERR_2ARGS : return provided status code if failed *------------------------------------------------------------------*/ -#define VERIFY_ERR_1ARGS(_error) VERIFY_ERR_DEF2(_error, ) -#define VERIFY_ERR_2ARGS(_error, _ret) VERIFY_ERR_DEF3(_error, ,_ret) +#define TU_VERIFY_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, ) +#define TU_VERIFY_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, ,_ret) -#define VERIFY_ERR(...) GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__) +#define TU_VERIFY_ERR(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_ERR_2ARGS, TU_VERIFY_ERR_1ARGS)(__VA_ARGS__) /*------------------------------------------------------------------*/ -/* VERIFY STATUS WITH HANDLER - * - VERIFY_ERR_HDLR_2ARGS : execute handler, return status if failed - * - VERIFY_ERR_HDLR_3ARGS : execute handler, return provided error if failed +/* TU_VERIFY STATUS WITH HANDLER + * - TU_VERIFY_ERR_HDLR_2ARGS : execute handler, return status if failed + * - TU_VERIFY_ERR_HDLR_3ARGS : execute handler, return provided error if failed *------------------------------------------------------------------*/ -#define VERIFY_ERR_HDLR_2ARGS(_error, _handler) VERIFY_ERR_DEF2(_error, _handler) -#define VERIFY_ERR_HDLR_3ARGS(_error, _handler, _ret) VERIFY_ERR_DEF3(_error, _handler, _ret) +#define TU_VERIFY_ERR_HDLR_2ARGS(_error, _handler) TU_VERIFY_ERR_DEF2(_error, _handler) +#define TU_VERIFY_ERR_HDLR_3ARGS(_error, _handler, _ret) TU_VERIFY_ERR_DEF3(_error, _handler, _ret) -#define VERIFY_ERR_HDLR(...) GET_4TH_ARG(__VA_ARGS__, VERIFY_ERR_HDLR_3ARGS, VERIFY_ERR_HDLR_2ARGS)(__VA_ARGS__) +#define TU_VERIFY_ERR_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_ERR_HDLR_3ARGS, TU_VERIFY_ERR_HDLR_2ARGS)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT - * basically VERIFY with verify_breakpoint() as handler + * basically TU_VERIFY with verify_breakpoint() as handler * - 1 arg : return false if failed * - 2 arg : return error if failed *------------------------------------------------------------------*/ -#define ASSERT_1ARGS(_cond) VERIFY_DEFINE(_cond, _MESS_FAILED(); verify_breakpoint(), false) -#define ASSERT_2ARGS(_cond, _ret) VERIFY_DEFINE(_cond, _MESS_FAILED(); verify_breakpoint(), _ret) +#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); verify_breakpoint(), false) +#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); verify_breakpoint(), _ret) #define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT Error - * basically VERIFY Error with verify_breakpoint() as handler + * basically TU_VERIFY Error with verify_breakpoint() as handler *------------------------------------------------------------------*/ -#define ASERT_ERR_1ARGS(_error) VERIFY_ERR_DEF2(_error, verify_breakpoint()) -#define ASERT_ERR_2ARGS(_error, _ret) VERIFY_ERR_DEF3(_error, verify_breakpoint(), _ret) +#define ASERT_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, verify_breakpoint()) +#define ASERT_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, verify_breakpoint(), _ret) #define TU_ASSERT_ERR(...) GET_3RD_ARG(__VA_ARGS__, ASERT_ERR_2ARGS, ASERT_ERR_1ARGS)(__VA_ARGS__) diff --git a/src/device/usbd.c b/src/device/usbd.c index 219562fa6..79ad8ffa2 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -189,7 +189,7 @@ typedef struct ATTR_ALIGNED(4) }; } usbd_task_event_t; -VERIFY_STATIC(sizeof(usbd_task_event_t) <= 12, "size is not correct"); +TU_VERIFY_STATIC(sizeof(usbd_task_event_t) <= 12, "size is not correct"); OSAL_TASK_DEF(_usbd_task_def, "usbd", usbd_task, CFG_TUD_TASK_PRIO, CFG_TUD_TASK_STACK_SZ); @@ -234,10 +234,10 @@ tusb_error_t usbd_init (void) //------------- Task init -------------// _usbd_q = osal_queue_create(&_usbd_qdef); - VERIFY(_usbd_q, TUSB_ERROR_OSAL_QUEUE_FAILED); + TU_VERIFY(_usbd_q, TUSB_ERROR_OSAL_QUEUE_FAILED); _usbd_ctrl_sem = osal_semaphore_create(&_usbd_sem_def); - VERIFY(_usbd_q, TUSB_ERROR_OSAL_SEMAPHORE_FAILED); + TU_VERIFY(_usbd_q, TUSB_ERROR_OSAL_SEMAPHORE_FAILED); osal_task_create(&_usbd_task_def); @@ -507,7 +507,7 @@ static uint16_t get_descriptor(uint8_t rhport, tusb_control_request_t const * co if ( desc_index < tud_desc_set.string_count ) { desc_data = tud_desc_set.string_arr[desc_index]; - VERIFY( desc_data != NULL, 0 ); + TU_VERIFY( desc_data != NULL, 0 ); len = desc_data[0]; // first byte of descriptor is its size }else diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 09f2f573a..32fcc8140 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -64,7 +64,7 @@ CFG_TUSB_ATTR_USBRAM STATIC_VAR ehci_data_t ehci_data; CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(4096) STATIC_VAR ehci_link_t period_frame_list0[EHCI_FRAMELIST_SIZE]; #ifndef __ICCARM__ // IAR cannot able to determine the alignment with datalignment pragma - VERIFY_STATIC( ALIGN_OF(period_frame_list0) == 4096, "Period Framelist must be 4k alginment"); // validation + TU_VERIFY_STATIC( ALIGN_OF(period_frame_list0) == 4096, "Period Framelist must be 4k alginment"); // validation #endif #endif @@ -72,7 +72,7 @@ CFG_TUSB_ATTR_USBRAM STATIC_VAR ehci_data_t ehci_data; CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(4096) STATIC_VAR ehci_link_t period_frame_list1[EHCI_FRAMELIST_SIZE]; #ifndef __ICCARM__ // IAR cannot able to determine the alignment with datalignment pragma - VERIFY_STATIC( ALIGN_OF(period_frame_list1) == 4096, "Period Framelist must be 4k alginment"); // validation + TU_VERIFY_STATIC( ALIGN_OF(period_frame_list1) == 4096, "Period Framelist must be 4k alginment"); // validation #endif #endif #endif diff --git a/src/host/ehci/ehci.h b/src/host/ehci/ehci.h index 250023ee5..f5180402b 100644 --- a/src/host/ehci/ehci.h +++ b/src/host/ehci/ehci.h @@ -81,7 +81,7 @@ enum { }; //------------- Validation -------------// -VERIFY_STATIC(EHCI_CFG_FRAMELIST_SIZE_BITS <= 7, "incorrect value"); +TU_VERIFY_STATIC(EHCI_CFG_FRAMELIST_SIZE_BITS <= 7, "incorrect value"); //--------------------------------------------------------------------+ // EHCI Data Structure @@ -150,7 +150,7 @@ typedef struct { uint32_t buffer[5]; } ehci_qtd_t; // XXX qtd is used to declare overlay in ehci_qhd_t -> cannot be declared with ATTR_ALIGNED(32) -VERIFY_STATIC( sizeof(ehci_qtd_t) == 32, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ehci_qtd_t) == 32, "size is not correct" ); /// Queue Head (section 3.6) typedef struct ATTR_ALIGNED(32) { @@ -202,7 +202,7 @@ typedef struct ATTR_ALIGNED(32) { ehci_qtd_t * volatile p_qtd_list_tail; // tail of the scheduled TD list } ehci_qhd_t; -VERIFY_STATIC( sizeof(ehci_qhd_t) == 64, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ehci_qhd_t) == 64, "size is not correct" ); /// Highspeed Isochronous Transfer Descriptor (section 3.3) typedef struct ATTR_ALIGNED(32) { @@ -234,7 +234,7 @@ typedef struct ATTR_ALIGNED(32) { // uint32_t reserved[6]; } ehci_itd_t; -VERIFY_STATIC( sizeof(ehci_itd_t) == 64, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ehci_itd_t) == 64, "size is not correct" ); /// Split (Full-Speed) Isochronous Transfer Descriptor typedef struct ATTR_ALIGNED(32) { @@ -298,7 +298,7 @@ typedef struct ATTR_ALIGNED(32) { uint8_t reserved2[2]; } ehci_sitd_t; -VERIFY_STATIC( sizeof(ehci_sitd_t) == 32, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ehci_sitd_t) == 32, "size is not correct" ); //--------------------------------------------------------------------+ // EHCI Operational Register diff --git a/src/host/hub.h b/src/host/hub.h index b8499275c..67c02f2e3 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -104,7 +104,7 @@ typedef struct ATTR_PACKED{ uint8_t PortPwrCtrlMask; // just for compatibility, should be 0xff } descriptor_hub_desc_t; -VERIFY_STATIC( sizeof(descriptor_hub_desc_t) == 9, "size is not correct"); +TU_VERIFY_STATIC( sizeof(descriptor_hub_desc_t) == 9, "size is not correct"); enum { HUB_REQUEST_GET_STATUS = 0 , @@ -157,7 +157,7 @@ typedef struct { } status, status_change; } hub_status_response_t; -VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct"); +TU_VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct"); // data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num typedef struct { @@ -182,7 +182,7 @@ typedef struct { } status_current, status_change; } hub_port_status_response_t; -VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); +TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); tusb_error_t hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port); tusb_error_t hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature); diff --git a/src/host/ohci/ohci.h b/src/host/ohci/ohci.h index f49d85261..c407b8ac1 100644 --- a/src/host/ohci/ohci.h +++ b/src/host/ohci/ohci.h @@ -79,7 +79,7 @@ typedef struct { uint8_t reserved[116+4]; // TODO try to make use of this area if possible, extra 4 byte to make the whole struct size = 256 }ohci_hcca_t; // ATTR_ALIGNED(256) -VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" ); typedef struct { uint32_t reserved[2]; @@ -112,7 +112,7 @@ typedef struct ATTR_ALIGNED(16) { uint8_t* buffer_end; } ohci_gtd_t; -VERIFY_STATIC( sizeof(ohci_gtd_t) == 16, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ohci_gtd_t) == 16, "size is not correct" ); typedef struct ATTR_ALIGNED(16) { //------------- Word 0 -------------// @@ -153,7 +153,7 @@ typedef struct ATTR_ALIGNED(16) { uint32_t next_ed; // 4 lsb bits are free to use } ohci_ed_t; -VERIFY_STATIC( sizeof(ohci_ed_t) == 16, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ohci_ed_t) == 16, "size is not correct" ); typedef struct ATTR_ALIGNED(32) { /*---------- Word 1 ----------*/ @@ -178,7 +178,7 @@ typedef struct ATTR_ALIGNED(32) { volatile uint16_t offset_packetstatus[8]; } ochi_itd_t; -VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(ochi_itd_t) == 32, "size is not correct" ); // structure with member alignment required from large to small typedef struct ATTR_ALIGNED(256) { @@ -298,7 +298,7 @@ typedef volatile struct }; }ohci_registers_t; -VERIFY_STATIC( sizeof(ohci_registers_t) == 0x5c, "size is not correct"); +TU_VERIFY_STATIC( sizeof(ohci_registers_t) == 0x5c, "size is not correct"); #ifdef __cplusplus } diff --git a/src/osal/osal.h b/src/osal/osal.h index 7a8e6ecbf..3e0d9d5f1 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -81,11 +81,11 @@ typedef void (*osal_task_func_t)( void * ); #define STASK_INVOKE(_subtask, _status) (_status) = _subtask //------------- Sub Task Assert -------------// - #define STASK_ASSERT_ERR(_err) VERIFY_ERR(_err) - #define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, _func) + #define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR(_err) + #define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, _func) - #define STASK_ASSERT(_cond) VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) - #define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, _func) + #define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED) + #define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, _func) #endif #ifdef __cplusplus diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index b8cd2893c..3531686b4 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -121,11 +121,11 @@ static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) //------------- Sub Task Assert -------------// #define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0) -#define STASK_ASSERT_ERR(_err) VERIFY_ERR_HDLR(_err, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) -#define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED ) +#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR_HDLR(_err, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED ) -#define STASK_ASSERT(_cond) VERIFY_HDLR(_cond, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) -#define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT(_cond) TU_VERIFY_HDLR(_cond, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED) //--------------------------------------------------------------------+ // QUEUE API diff --git a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c index 68eef47e1..0eaecf1b8 100644 --- a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c +++ b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c @@ -104,7 +104,7 @@ typedef struct ATTR_PACKED volatile uint16_t active : 1 ; ///< The buffer is enabled. HW can use the buffer to store received OUT data or to transmit data on the IN endpoint. Software can only set this bit to ‘1’. As long as this bit is set to one, software is not allowed to update any of the values in this 32-bit word. In case software wants to deactivate the buffer, it must write a one to the corresponding “skip” bit in the USB Endpoint skip register. Hardware can only write this bit to zero. It will do this when it receives a short packet or when the NBytes field transitions to zero or when software has written a one to the “skip” bit. }dcd_11u_13u_qhd_t; -VERIFY_STATIC( sizeof(dcd_11u_13u_qhd_t) == 4, "size is not correct" ); +TU_VERIFY_STATIC( sizeof(dcd_11u_13u_qhd_t) == 4, "size is not correct" ); // NOTE data will be transferred as soon as dcd get request by dcd_pipe(_queue)_xfer using double buffering. // If there is another dcd_edpt_xfer request, the new request will be saved and executed when the first is done. diff --git a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c index 948572129..a87e7d899 100644 --- a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c +++ b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c @@ -384,7 +384,7 @@ bool dcd_control_xfer(uint8_t rhport, tusb_dir_t dir, uint8_t * p_buffer, uint16 { (void) rhport; - VERIFY( !(length != 0 && p_buffer == NULL) ); + TU_VERIFY( !(length != 0 && p_buffer == NULL) ); // determine Endpoint where Data & Status phase occurred (IN or OUT) uint8_t const ep_data = (dir == TUSB_DIR_IN) ? 1 : 0; @@ -399,13 +399,13 @@ bool dcd_control_xfer(uint8_t rhport, tusb_dir_t dir, uint8_t * p_buffer, uint16 dcd_data.control_dma.remaining_bytes = length; // lpc17xx already received the first DATA OUT packet by now - VERIFY_ERR ( pipe_control_xfer(ep_data, p_buffer, length), false ); + TU_VERIFY_ERR ( pipe_control_xfer(ep_data, p_buffer, length), false ); } //------------- Status Phase (opposite direct to Data) -------------// if (dir == TUSB_DIR_OUT) { // only write for CONTROL OUT, CONTROL IN data will be retrieved in hal_dcd_isr // TODO ???? - VERIFY_ERR ( pipe_control_write(NULL, 0), false ); + TU_VERIFY_ERR ( pipe_control_write(NULL, 0), false ); } return true; diff --git a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.h b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.h index 1df1fcd30..4746b4acf 100644 --- a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.h +++ b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.h @@ -80,7 +80,7 @@ typedef struct ATTR_ALIGNED(4) // uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso }dcd_dma_descriptor_t; -VERIFY_STATIC( sizeof(dcd_dma_descriptor_t) == 16, "size is not correct"); // TODO not support ISO for now +TU_VERIFY_STATIC( sizeof(dcd_dma_descriptor_t) == 16, "size is not correct"); // TODO not support ISO for now //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c index 0b48ad1e6..61f829713 100644 --- a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c +++ b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c @@ -244,7 +244,7 @@ bool dcd_control_xfer(uint8_t rhport, tusb_dir_t dir, uint8_t * p_buffer, uint16 // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out while(lpc_usb->ENDPTSETUPSTAT & BIT_(0)) {} - VERIFY( !qhd->qtd_overlay.active ); + TU_VERIFY( !qhd->qtd_overlay.active ); dcd_qtd_t* qtd = &p_dcd->qtd[0]; qtd_init(qtd, p_buffer, length); @@ -295,7 +295,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { // TODO USB1 only has 4 non-control enpoint (USB0 has 5) // TODO not support ISO yet - VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); tusb_dir_t dir = (p_endpoint_desc->bEndpointAddress & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; @@ -313,7 +313,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) volatile uint32_t * reg_control = get_reg_control_addr(rhport, ep_idx); // endpoint must not be already enabled - VERIFY( !( (*reg_control) & (ENDPTCTRL_MASK_ENABLE << (dir ? 16 : 0)) ) ); + TU_VERIFY( !( (*reg_control) & (ENDPTCTRL_MASK_ENABLE << (dir ? 16 : 0)) ) ); (*reg_control) |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0); @@ -363,7 +363,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t { uint8_t ep_idx = edpt_addr2phy(ep_addr); - VERIFY ( pipe_add_xfer(rhport, ep_idx, buffer, total_bytes, true) ); + TU_VERIFY ( pipe_add_xfer(rhport, ep_idx, buffer, total_bytes, true) ); dcd_qhd_t* p_qhd = &dcd_data_ptr[rhport]->qhd[ ep_idx ]; dcd_qtd_t* p_qtd = &dcd_data_ptr[rhport]->qtd[ p_qhd->list_qtd_idx[0] ]; diff --git a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h index 92e24c1fb..1476c0d30 100644 --- a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h +++ b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.h @@ -122,7 +122,7 @@ typedef struct uint8_t reserved; } dcd_qtd_t; -VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); +TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); typedef struct { @@ -153,7 +153,7 @@ typedef struct uint8_t reserved[16-DCD_QTD_PER_QHD_MAX]; } dcd_qhd_t; -VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); +TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); #ifdef __cplusplus diff --git a/src/portable/nxp/lpc43xx_lpc18xx/hal_lpc43xx.c b/src/portable/nxp/lpc43xx_lpc18xx/hal_lpc43xx.c index 18745d03e..213b8dd99 100644 --- a/src/portable/nxp/lpc43xx_lpc18xx/hal_lpc43xx.c +++ b/src/portable/nxp/lpc43xx_lpc18xx/hal_lpc43xx.c @@ -86,7 +86,7 @@ bool tusb_hal_init(void) //------------- USB0 -------------// #if CFG_TUSB_RHPORT0_MODE CGU_EnableEntity(CGU_CLKSRC_PLL0, DISABLE); /* Disable PLL first */ - VERIFY( CGU_ERROR_SUCCESS == CGU_SetPLL0()); /* the usb core require output clock = 480MHz */ + TU_VERIFY( CGU_ERROR_SUCCESS == CGU_SetPLL0()); /* the usb core require output clock = 480MHz */ CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_CLKSRC_PLL0); CGU_EnableEntity(CGU_CLKSRC_PLL0, ENABLE); /* Enable PLL after all setting is done */ diff --git a/src/tusb.c b/src/tusb.c index 0ef1301a4..b064d03f9 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -49,7 +49,7 @@ tusb_error_t tusb_init(void) // skip if already initialized if (_initialized) return TUSB_ERROR_NONE; - VERIFY( tusb_hal_init(), TUSB_ERROR_FAILED ) ; // hardware init + TU_VERIFY( tusb_hal_init(), TUSB_ERROR_FAILED ) ; // hardware init #if MODE_HOST_SUPPORTED TU_ASSERT_ERR( usbh_init() ); // host stack init -- cgit v1.3.1 From 23c7c2102b8b5b34fb11481803b61c961e82a583 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 23 Aug 2018 20:54:51 +0700 Subject: fix compiler warnings --- src/device/dcd.h | 4 ++-- src/osal/osal_freeRTOS.h | 4 ++-- src/portable/nordic/nrf5x/dcd_nrf5x.c | 4 ++-- src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c | 2 +- src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c | 2 +- src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/osal') diff --git a/src/device/dcd.h b/src/device/dcd.h index cbce366cc..e246f0521 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -96,10 +96,10 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr); //------------- Control Endpoint -------------// -bool dcd_control_xfer (uint8_t rhport, tusb_dir_t dir, uint8_t * buffer, uint16_t length); +bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length); // Note input dir is value of direction bit in setup packet (i.e DATA stage direction) -static inline bool dcd_control_status(uint8_t rhport, tusb_dir_t dir) +static inline bool dcd_control_status(uint8_t rhport, uint8_t dir) { // status direction is reversed to one in the setup packet return dcd_control_xfer(rhport, 1-dir, NULL, 0); diff --git a/src/osal/osal_freeRTOS.h b/src/osal/osal_freeRTOS.h index b14ed3100..321b00ac7 100644 --- a/src/osal/osal_freeRTOS.h +++ b/src/osal/osal_freeRTOS.h @@ -85,7 +85,7 @@ typedef TaskHandle_t osal_task_t; static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) { - return xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, taskdef->buf, &taskdef->stask); + return xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, (StackType_t*) taskdef->buf, &taskdef->stask); } static inline void osal_task_delay(uint32_t msec) @@ -113,7 +113,7 @@ typedef QueueHandle_t osal_queue_t; static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { - return xQueueCreateStatic(qdef->depth, qdef->item_sz, qdef->buf, &qdef->sq); + return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); } static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 1c91779a7..b27d6c0ae 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -200,7 +200,7 @@ static void xact_control_start(void) _dcd.control.actual_len += xact_len; } -bool dcd_control_xfer (uint8_t rhport, tusb_dir_t dir, uint8_t * buffer, uint16_t length) +bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length) { (void) rhport; @@ -210,7 +210,7 @@ bool dcd_control_xfer (uint8_t rhport, tusb_dir_t dir, uint8_t * buffer, uint16_ _dcd.control.total_len = length; _dcd.control.actual_len = 0; _dcd.control.buffer = buffer; - _dcd.control.dir = (uint8_t) dir; + _dcd.control.dir = dir; xact_control_start(); }else diff --git a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c index 3e536312a..292d1fa6d 100644 --- a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c +++ b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c @@ -381,7 +381,7 @@ void dcd_control_stall(uint8_t rhport) dcd_data.qhd[0][0].stall = dcd_data.qhd[1][0].stall = 1; } -bool dcd_control_xfer(uint8_t rhport, tusb_dir_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) +bool dcd_control_xfer(uint8_t rhport, uint8_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) { (void) rhport; diff --git a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c index 8c87984e8..4d3687830 100644 --- a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c +++ b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c @@ -380,7 +380,7 @@ void dcd_control_stall(uint8_t rhport) sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK); } -bool dcd_control_xfer(uint8_t rhport, tusb_dir_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) +bool dcd_control_xfer(uint8_t rhport, uint8_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete) { (void) rhport; diff --git a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c index 792a009f2..7368542b8 100644 --- a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c +++ b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c @@ -232,7 +232,7 @@ static inline uint8_t qtd_find_free(uint8_t rhport) // control transfer does not need to use qtd find function // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism -bool dcd_control_xfer(uint8_t rhport, tusb_dir_t dir, uint8_t * p_buffer, uint16_t length) +bool dcd_control_xfer(uint8_t rhport, uint8_t dir, uint8_t * p_buffer, uint16_t length) { LPC_USB0_Type* const lpc_usb = LPC_USB[rhport]; dcd_data_t* const p_dcd = dcd_data_ptr[rhport]; -- cgit v1.3.1 From 4ef01d721ad6b49775f067d89faa5545d918f32f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 30 Aug 2018 15:21:15 +0700 Subject: clean up osal task and subtask --- src/device/usbd.c | 9 ++++++--- src/osal/osal.h | 4 +++- src/osal/osal_none.h | 25 +++++++++---------------- 3 files changed, 18 insertions(+), 20 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index 8f1f6be90..2f760808b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -107,7 +107,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = .open = cdcd_open, .control_req_st = cdcd_control_request_st, .xfer_cb = cdcd_xfer_cb, - .sof = cdcd_sof, + .sof = NULL, .reset = cdcd_reset }, #endif @@ -250,6 +250,9 @@ tusb_error_t usbd_init (void) // To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper // and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with // forever loop cannot have any return at all. + +// Within tinyusb stack, all task's code must be placed in subtask to be able to support multiple RTOS +// including none. void usbd_task( void* param) { (void) param; @@ -306,7 +309,7 @@ static tusb_error_t usbd_main_st(void) } else { - STASK_ASSERT(false); + verify_breakpoint(); } } @@ -577,7 +580,7 @@ void dcd_bus_event(uint8_t rhport, usbd_bus_event_type_t bus_event) case USBD_BUS_EVENT_SOF: { - #if CFG_TUD_CDC_FLUSH_ON_SOF + #if 0 usbd_task_event_t task_event = { .rhport = rhport, diff --git a/src/osal/osal.h b/src/osal/osal.h index 3e0d9d5f1..16dc8da27 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -61,8 +61,10 @@ enum typedef void (*osal_task_func_t)( void * ); #if CFG_TUSB_OS == OPT_OS_NONE - #include "osal_none.h" + #define OSAL_TASK_BEGIN + #define OSAL_TASK_END + #include "osal_none.h" #else #if CFG_TUSB_OS == OPT_OS_FREERTOS #include "osal_freeRTOS.h" diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 3531686b4..012de9c78 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -79,18 +79,6 @@ static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) #define TASK_RESTART \ _state = 0 -#define OSAL_TASK_BEGIN \ - static uint16_t _state = 0; \ - ATTR_UNUSED static uint32_t _timeout = 0; \ - (void) _timeout; \ - switch(_state) { \ - case 0: { - -#define OSAL_TASK_END \ - default: TASK_RESTART; break; \ - }} \ - return; - #define osal_task_delay(msec) \ do { \ _timeout = tusb_hal_millis(); \ @@ -102,11 +90,16 @@ static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) //--------------------------------------------------------------------+ // SUBTASK (a sub function that uses OS blocking services & called by a task //--------------------------------------------------------------------+ -#define OSAL_SUBTASK_BEGIN OSAL_TASK_BEGIN +#define OSAL_SUBTASK_BEGIN \ + static uint16_t _state = 0; \ + ATTR_UNUSED static uint32_t _timeout = 0; \ + (void) _timeout; \ + switch(_state) { \ + case 0: { -#define OSAL_SUBTASK_END \ - default: TASK_RESTART; break; \ - }} \ +#define OSAL_SUBTASK_END \ + default: TASK_RESTART; break; \ + }} \ return TUSB_ERROR_NONE; #define STASK_INVOKE(_subtask, _status) \ -- cgit v1.3.1 From e6fdfe8ac722a8b3ba89e47e827e7297195f9a99 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 2 Sep 2018 20:37:02 +0700 Subject: rename file --- src/osal/osal.h | 2 +- src/osal/osal_freeRTOS.h | 200 ----------------------------------------------- src/osal/osal_freertos.h | 200 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 201 deletions(-) delete mode 100644 src/osal/osal_freeRTOS.h create mode 100644 src/osal/osal_freertos.h (limited to 'src/osal') diff --git a/src/osal/osal.h b/src/osal/osal.h index 16dc8da27..8af1d5b31 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -67,7 +67,7 @@ typedef void (*osal_task_func_t)( void * ); #include "osal_none.h" #else #if CFG_TUSB_OS == OPT_OS_FREERTOS - #include "osal_freeRTOS.h" + #include "osal_freertos.h" #else #error CFG_TUSB_OS is not defined or OS is not supported yet #endif diff --git a/src/osal/osal_freeRTOS.h b/src/osal/osal_freeRTOS.h deleted file mode 100644 index 321b00ac7..000000000 --- a/src/osal/osal_freeRTOS.h +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************/ -/*! - @file osal_freeRTOS.h - @author hathach (tinyusb.org) - - @section LICENSE - - Software License Agreement (BSD License) - - Copyright (c) 2013, hathach (tinyusb.org) - 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. - - This file is part of the tinyusb stack. -*/ -/**************************************************************************/ - -/** \ingroup group_osal - * @{ - * \defgroup Group_FreeRTOS FreeRTOS - * @{ */ - -#ifndef _TUSB_OSAL_FREERTOS_H_ -#define _TUSB_OSAL_FREERTOS_H_ - -//------------- FreeRTOS Headers -------------// -#include "FreeRTOS.h" -#include "semphr.h" -#include "queue.h" -#include "task.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if 0 -// Helper to determine if we are in ISR to use ISR API (only cover ARM Cortex) -static inline bool in_isr(void) -{ - return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk); -} -#endif - -//--------------------------------------------------------------------+ -// TASK API -//--------------------------------------------------------------------+ -#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) \ - uint8_t _name##_##buf[_stack_sz*sizeof(StackType_t)]; \ - osal_task_def_t _name = { .func = _func, .prio = _prio, .stack_sz = _stack_sz, .buf = _name##_##buf, .strname = _str }; - -typedef struct -{ - osal_task_func_t func; - - uint16_t prio; - uint16_t stack_sz; - void* buf; - const char* strname; - - StaticTask_t stask; -}osal_task_def_t; - -typedef TaskHandle_t osal_task_t; - -static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) -{ - return xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, (StackType_t*) taskdef->buf, &taskdef->stask); -} - -static inline void osal_task_delay(uint32_t msec) -{ - vTaskDelay( pdMS_TO_TICKS(msec) ); -} - -//--------------------------------------------------------------------+ -// QUEUE API -//--------------------------------------------------------------------+ -#define OSAL_QUEUE_DEF(_name, _depth, _type) \ - uint8_t _name##_##buf[_depth*sizeof(_type)];\ - osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; - -typedef struct -{ - uint16_t depth; - uint16_t item_sz; - void* buf; - - StaticQueue_t sq; -}osal_queue_def_t; - -typedef QueueHandle_t osal_queue_t; - -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ - return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); -} - -static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) -{ - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*p_error) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); -} - -static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) -{ - return xQueueSendToBackFromISR(queue_hdl, data, NULL); -} - -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) -{ - return xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER) == pdTRUE; -} - -static inline void osal_queue_flush(osal_queue_t const queue_hdl) -{ - // TODO move to thread context -// xQueueReset(queue_hdl); -} - -//--------------------------------------------------------------------+ -// Semaphore API -//--------------------------------------------------------------------+ -typedef StaticSemaphore_t osal_semaphore_def_t; -typedef SemaphoreHandle_t osal_semaphore_t; - -static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ - return xSemaphoreCreateBinaryStatic(semdef); -} - -static inline bool osal_semaphore_post_isr(osal_semaphore_t sem_hdl) -{ - return xSemaphoreGiveFromISR(sem_hdl, NULL) == pdTRUE; -} - -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) -{ - return xSemaphoreGive(sem_hdl) == pdTRUE; -} - -static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) -{ - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*p_error) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); -} - -static inline void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) -{ - xSemaphoreTakeFromISR(sem_hdl, NULL); -} - -//--------------------------------------------------------------------+ -// MUTEX API (priority inheritance) -//--------------------------------------------------------------------+ -typedef SemaphoreHandle_t osal_mutex_t; - -#define osal_mutex_create(x) xSemaphoreCreateMutex() - -static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) -{ - return xSemaphoreGive(mutex_hdl); -} - -static inline void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) -{ - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*p_error) = (xSemaphoreTake(mutex_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); -} - - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_OSAL_FREERTOS_H_ */ - -/** @} */ -/** @} */ - diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h new file mode 100644 index 000000000..321b00ac7 --- /dev/null +++ b/src/osal/osal_freertos.h @@ -0,0 +1,200 @@ +/**************************************************************************/ +/*! + @file osal_freeRTOS.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +/** \ingroup group_osal + * @{ + * \defgroup Group_FreeRTOS FreeRTOS + * @{ */ + +#ifndef _TUSB_OSAL_FREERTOS_H_ +#define _TUSB_OSAL_FREERTOS_H_ + +//------------- FreeRTOS Headers -------------// +#include "FreeRTOS.h" +#include "semphr.h" +#include "queue.h" +#include "task.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +// Helper to determine if we are in ISR to use ISR API (only cover ARM Cortex) +static inline bool in_isr(void) +{ + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk); +} +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) \ + uint8_t _name##_##buf[_stack_sz*sizeof(StackType_t)]; \ + osal_task_def_t _name = { .func = _func, .prio = _prio, .stack_sz = _stack_sz, .buf = _name##_##buf, .strname = _str }; + +typedef struct +{ + osal_task_func_t func; + + uint16_t prio; + uint16_t stack_sz; + void* buf; + const char* strname; + + StaticTask_t stask; +}osal_task_def_t; + +typedef TaskHandle_t osal_task_t; + +static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) +{ + return xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, (StackType_t*) taskdef->buf, &taskdef->stask); +} + +static inline void osal_task_delay(uint32_t msec) +{ + vTaskDelay( pdMS_TO_TICKS(msec) ); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#define OSAL_QUEUE_DEF(_name, _depth, _type) \ + uint8_t _name##_##buf[_depth*sizeof(_type)];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + + StaticQueue_t sq; +}osal_queue_def_t; + +typedef QueueHandle_t osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); +} + +static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + +static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) +{ + return xQueueSendToBackFromISR(queue_hdl, data, NULL); +} + +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) +{ + return xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER) == pdTRUE; +} + +static inline void osal_queue_flush(osal_queue_t const queue_hdl) +{ + // TODO move to thread context +// xQueueReset(queue_hdl); +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef StaticSemaphore_t osal_semaphore_def_t; +typedef SemaphoreHandle_t osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + return xSemaphoreCreateBinaryStatic(semdef); +} + +static inline bool osal_semaphore_post_isr(osal_semaphore_t sem_hdl) +{ + return xSemaphoreGiveFromISR(sem_hdl, NULL) == pdTRUE; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +{ + return xSemaphoreGive(sem_hdl) == pdTRUE; +} + +static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + +static inline void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) +{ + xSemaphoreTakeFromISR(sem_hdl, NULL); +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef SemaphoreHandle_t osal_mutex_t; + +#define osal_mutex_create(x) xSemaphoreCreateMutex() + +static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) +{ + return xSemaphoreGive(mutex_hdl); +} + +static inline void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = (xSemaphoreTake(mutex_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_FREERTOS_H_ */ + +/** @} */ +/** @} */ + -- cgit v1.3.1 From 8600c4b6168c652347cab9a6b82aaabcf0e481eb Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 4 Sep 2018 14:20:30 +0700 Subject: adding mynewt to osal --- src/device/usbd.c | 2 +- src/osal/osal.c | 7 ++ src/osal/osal.h | 39 ++++++++- src/osal/osal_freertos.h | 10 +-- src/osal/osal_mynewt.h | 215 +++++++++++++++++++++++++++++++++++++++++++++++ src/osal/osal_none.h | 5 +- src/tusb_option.h | 5 +- 7 files changed, 269 insertions(+), 14 deletions(-) create mode 100644 src/osal/osal_mynewt.h (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index 2f760808b..89dd4b722 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -335,7 +335,7 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request { OSAL_SUBTASK_BEGIN - tusb_error_t error; + ATTR_UNUSED tusb_error_t error; error = TUSB_ERROR_NONE; //------------- Standard Request e.g in enumeration -------------// diff --git a/src/osal/osal.c b/src/osal/osal.c index f2078b09c..4507b0b8f 100644 --- a/src/osal/osal.c +++ b/src/osal/osal.c @@ -50,5 +50,12 @@ uint32_t tusb_hal_millis(void) return ( ( ((uint64_t) xTaskGetTickCount()) * 1000) / configTICK_RATE_HZ ); } +#elif CFG_TUSB_OS == OPT_OS_MYNEWT + +uint32_t tusb_hal_millis(void) +{ + return os_time_ticks_to_ms32( os_time_get() ); +} + #endif diff --git a/src/osal/osal.h b/src/osal/osal.h index 8af1d5b31..d64837205 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -61,13 +61,48 @@ enum typedef void (*osal_task_func_t)( void * ); #if CFG_TUSB_OS == OPT_OS_NONE + #include "osal_none.h" + #define OSAL_TASK_BEGIN #define OSAL_TASK_END - #include "osal_none.h" #else - #if CFG_TUSB_OS == OPT_OS_FREERTOS + /* RTOS Porting API + * + * uint32_t tusb_hal_millis(void) + * + * Task + * osal_task_def_t + * bool osal_task_create(osal_task_def_t* taskdef) + * void osal_task_delay(uint32_t msec) + * + * Queue + * osal_queue_def_t, osal_queue_t + * osal_queue_t osal_queue_create(osal_queue_def_t* qdef) + * osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) + * bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) + * bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) + * osal_queue_flush() TODO remove + * + * Semaphore + * osal_semaphore_def_t, osal_semaphore_t + * osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) + * bool osal_semaphore_post_isr(osal_semaphore_t sem_hdl) + * bool osal_semaphore_post(osal_semaphore_t sem_hdl) + * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) + * void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) + * + * Mutex + * osal_mutex_t + * osal_mutex_create() + * bool osal_mutex_release(osal_mutex_t mutex_hdl) + * void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) + */ + + #if CFG_TUSB_OS == OPT_OS_FREERTOS #include "osal_freertos.h" + #elif CFG_TUSB_OS == OPT_OS_MYNEWT + #include "osal_mynewt.h" #else #error CFG_TUSB_OS is not defined or OS is not supported yet #endif diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 321b00ac7..52d34c187 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -66,7 +66,7 @@ static inline bool in_isr(void) // TASK API //--------------------------------------------------------------------+ #define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) \ - uint8_t _name##_##buf[_stack_sz*sizeof(StackType_t)]; \ + static uint8_t _name##_##buf[_stack_sz*sizeof(StackType_t)]; \ osal_task_def_t _name = { .func = _func, .prio = _prio, .stack_sz = _stack_sz, .buf = _name##_##buf, .strname = _str }; typedef struct @@ -81,11 +81,9 @@ typedef struct StaticTask_t stask; }osal_task_def_t; -typedef TaskHandle_t osal_task_t; - -static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) +static inline bool osal_task_create(osal_task_def_t* taskdef) { - return xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, (StackType_t*) taskdef->buf, &taskdef->stask); + return NULL != xTaskCreateStatic(taskdef->func, taskdef->strname, taskdef->stack_sz, NULL, taskdef->prio, (StackType_t*) taskdef->buf, &taskdef->stask); } static inline void osal_task_delay(uint32_t msec) @@ -97,7 +95,7 @@ static inline void osal_task_delay(uint32_t msec) // QUEUE API //--------------------------------------------------------------------+ #define OSAL_QUEUE_DEF(_name, _depth, _type) \ - uint8_t _name##_##buf[_depth*sizeof(_type)];\ + static _type _name##_##buf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; typedef struct diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h new file mode 100644 index 000000000..db65ac553 --- /dev/null +++ b/src/osal/osal_mynewt.h @@ -0,0 +1,215 @@ +/**************************************************************************/ +/*! + @file osal_mynewt.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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 OSAL_MYNEWT_H_ +#define OSAL_MYNEWT_H_ + +#include "os/os.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +#define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) \ + static os_stack_t _name##_##buf[_stack_sz]; \ + osal_task_def_t _name = { .func = _func, .prio = _prio, .stack_sz = _stack_sz, .buf = _name##_##buf, .strname = _str }; + +typedef struct +{ + struct os_task mynewt_task; + osal_task_func_t func; + + uint16_t prio; + uint16_t stack_sz; + void* buf; + const char* strname; +}osal_task_def_t; + +static inline bool osal_task_create(osal_task_def_t* taskdef) +{ + return OS_OK == os_task_init(&taskdef->mynewt_task, taskdef->strname, taskdef->func, NULL, taskdef->prio, OS_WAIT_FOREVER, + (os_stack_t*) taskdef->buf, taskdef->stack_sz); +} + +static inline void osal_task_delay(uint32_t msec) +{ + os_time_delay( os_time_ms_to_ticks32(msec) ); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#define OSAL_QUEUE_DEF(_name, _depth, _type) \ + static _type _name##_##buf[_depth];\ + static struct os_event* _name##_##evbuf[_depth];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + void* evbuf; + + struct os_mempool mpool; + struct os_mempool epool; + + struct os_eventq evq; +}osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL; + if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL; + + os_eventq_init(&qdef->evq); + return (osal_queue_t) qdef; +} + +static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) +{ + (void) msec; + struct os_event* ev; + + if ( msec == 0 ) + { + ev = os_eventq_get_no_wait(&queue_hdl->evq); + if ( !ev ) + { + *p_error = TUSB_ERROR_OSAL_TIMEOUT; + return; + } + }else + { + ev = os_eventq_get(&queue_hdl->evq); + } + + memcpy(p_data, ev->ev_arg, queue_hdl->item_sz); // copy message + os_memblock_put(&queue_hdl->mpool, ev->ev_arg); // put back mem block + os_memblock_put(&queue_hdl->epool, ev); // put back ev block + + *p_error = TUSB_ERROR_NONE; +} + +#define osal_queue_send_isr osal_queue_send + +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) +{ + // get a block from mem pool for data + void* ptr = os_memblock_get(&queue_hdl->mpool); + if (!ptr) return false; + memcpy(ptr, data, queue_hdl->item_sz); + + // get a block from event pool to put into queue + struct os_event* ev = (struct os_event*) os_memblock_get(&queue_hdl->epool); + if (!ev) + { + os_memblock_put(&queue_hdl->mpool, ptr); + return false; + } + memclr_(ev, sizeof(struct os_event)); + ev->ev_arg = ptr; + + os_eventq_put(&queue_hdl->evq, ev); + + return true; +} + +static inline void osal_queue_flush(osal_queue_t const queue_hdl) +{ + +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef struct os_sem osal_semaphore_def_t; +typedef struct os_sem* osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; +} + +#define osal_semaphore_post_isr osal_semaphore_post + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +{ + return os_sem_release(sem_hdl) == OS_OK; +} + +static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); + (*p_error) = ( (os_sem_pend(sem_hdl, ticks) == OS_OK) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT ); +} + +static inline void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) +{ +// xSemaphoreTakeFromISR(sem_hdl, NULL); +} + +#if 0 +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef struct os_mutex osal_mutex_t; + +#define osal_mutex_create(x) xSemaphoreCreateMutex() + +static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) +{ + return xSemaphoreGive(mutex_hdl); +} + +static inline void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*p_error) = (xSemaphoreTake(mutex_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} +#endif + + +#ifdef __cplusplus + } +#endif + +#endif /* OSAL_MYNEWT_H_ */ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 012de9c78..22c89868a 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -68,12 +68,11 @@ #define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) osal_task_def_t _name; typedef uint8_t osal_task_def_t; -typedef void* osal_task_t; -static inline osal_task_t osal_task_create(osal_task_def_t* taskdef) +static inline bool osal_task_create(osal_task_def_t* taskdef) { (void) taskdef; - return (osal_task_t) 1; // return non zero + return true; } #define TASK_RESTART \ diff --git a/src/tusb_option.h b/src/tusb_option.h index 22b78453c..846367129 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -62,8 +62,9 @@ /** \defgroup group_supported_os Supported RTOS * \ref CFG_TUSB_OS must be defined to one of these * @{ */ -#define OPT_OS_NONE 1 ///< No RTOS is used -#define OPT_OS_FREERTOS 2 ///< FreeRTOS is used +#define OPT_OS_NONE 1 ///< No RTOS +#define OPT_OS_FREERTOS 2 ///< FreeRTOS +#define OPT_OS_MYNEWT 3 ///< Mynewt OS /** @} */ -- cgit v1.3.1 From c7340f4b0eb8dcf15fa93f6bf6589a94fb59dc95 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Oct 2018 12:19:32 +0700 Subject: clean up helper func --- examples/obsolete/device/src/mouse_device_app.c | 2 +- examples/obsolete/host/src/cdc_serial_host_app.c | 4 +-- examples/obsolete/host/src/keyboard_host_app.c | 2 +- examples/obsolete/host/src/mouse_host_app.c | 2 +- examples/obsolete/host/src/msc_cli.c | 6 ++-- src/class/cdc/cdc_device.c | 4 +-- src/class/cdc/cdc_host.c | 4 +-- src/class/cdc/cdc_rndis_host.c | 8 ++--- src/class/custom/custom_device.c | 2 +- src/class/custom/custom_host.c | 4 +-- src/class/hid/hid_device.c | 8 ++--- src/class/hid/hid_host.c | 6 ++-- src/class/msc/msc_device.c | 12 ++++---- src/class/msc/msc_host.c | 4 +-- src/common/tusb_common.h | 34 +++------------------- src/device/usbd.c | 4 +-- src/host/ehci/ehci.c | 8 ++--- src/host/hub.c | 4 +-- src/host/ohci/ohci.c | 6 ++-- src/host/usbh.c | 2 +- src/osal/osal_mynewt.h | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 +- .../nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c | 4 +-- src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c | 6 ++-- src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c | 8 ++--- tests/lpc175x_6x/test/test_dcd_lpc175x_6x.c | 8 ++--- tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c | 2 +- .../test/host/ehci/test_pipe_bulk_open.c | 2 +- .../test/host/ehci/test_pipe_bulk_xfer.c | 4 +-- .../test/host/ehci/test_pipe_control_open.c | 2 +- .../test/host/ehci/test_pipe_control_xfer.c | 4 +-- .../test/host/ehci/test_pipe_interrupt_open.c | 4 +-- .../test/host/ehci/test_pipe_interrupt_xfer.c | 4 +-- .../test/host/ehci/test_pipe_isochronous_open.c | 2 +- .../test/host/hid/test_hidh_keyboard.c | 2 +- tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c | 2 +- tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c | 2 +- tests/support/ehci_controller_fake.c | 4 +-- tests/support/type_helper.h | 4 +-- 39 files changed, 83 insertions(+), 111 deletions(-) (limited to 'src/osal') diff --git a/examples/obsolete/device/src/mouse_device_app.c b/examples/obsolete/device/src/mouse_device_app.c index d6145026a..077cecc7c 100644 --- a/examples/obsolete/device/src/mouse_device_app.c +++ b/examples/obsolete/device/src/mouse_device_app.c @@ -126,7 +126,7 @@ void mouse_app_subtask(void) enum { MOUSE_RESOLUTION = 5 }; uint32_t button_mask = board_buttons(); - memclr_(&mouse_report, sizeof(hid_mouse_report_t)); + tu_memclr(&mouse_report, sizeof(hid_mouse_report_t)); if ( BIT_TEST_(button_mask, BUTTON_UP ) ) mouse_report.y = -MOUSE_RESOLUTION; if ( BIT_TEST_(button_mask, BUTTON_DOWN ) ) mouse_report.y = MOUSE_RESOLUTION; diff --git a/examples/obsolete/host/src/cdc_serial_host_app.c b/examples/obsolete/host/src/cdc_serial_host_app.c index e21a3a67d..30ed6698e 100644 --- a/examples/obsolete/host/src/cdc_serial_host_app.c +++ b/examples/obsolete/host/src/cdc_serial_host_app.c @@ -61,8 +61,8 @@ void tuh_cdc_mounted_cb(uint8_t dev_addr) { // application set-up printf("\na CDC device (address %d) is mounted\n", dev_addr); - memclr_(serial_in_buffer, sizeof(serial_in_buffer)); - memclr_(serial_out_buffer, sizeof(serial_out_buffer)); + tu_memclr(serial_in_buffer, sizeof(serial_in_buffer)); + tu_memclr(serial_out_buffer, sizeof(serial_out_buffer)); received_bytes = 0; osal_semaphore_reset(sem_hdl); diff --git a/examples/obsolete/host/src/keyboard_host_app.c b/examples/obsolete/host/src/keyboard_host_app.c index 26b1a0800..21ace3bbf 100644 --- a/examples/obsolete/host/src/keyboard_host_app.c +++ b/examples/obsolete/host/src/keyboard_host_app.c @@ -100,7 +100,7 @@ void tuh_hid_keyboard_isr(uint8_t dev_addr, tusb_event_t event) //--------------------------------------------------------------------+ void keyboard_host_app_init(void) { - memclr_(&usb_keyboard_report, sizeof(hid_keyboard_report_t)); + tu_memclr(&usb_keyboard_report, sizeof(hid_keyboard_report_t)); queue_kbd_hdl = osal_queue_create( QUEUE_KEYBOARD_REPORT_DEPTH, sizeof(hid_keyboard_report_t) ); TU_ASSERT( queue_kbd_hdl, VOID_RETURN ); diff --git a/examples/obsolete/host/src/mouse_host_app.c b/examples/obsolete/host/src/mouse_host_app.c index c326becb8..e242c7caa 100644 --- a/examples/obsolete/host/src/mouse_host_app.c +++ b/examples/obsolete/host/src/mouse_host_app.c @@ -101,7 +101,7 @@ void tuh_hid_mouse_isr(uint8_t dev_addr, tusb_event_t event) //--------------------------------------------------------------------+ void mouse_host_app_init(void) { - memclr_(&usb_mouse_report, sizeof(hid_mouse_report_t)); + tu_memclr(&usb_mouse_report, sizeof(hid_mouse_report_t)); queue_mouse_hdl = osal_queue_create( QUEUE_MOUSE_REPORT_DEPTH, sizeof(hid_mouse_report_t) ); TU_ASSERT( queue_mouse_hdl, VOID_RETURN); diff --git a/examples/obsolete/host/src/msc_cli.c b/examples/obsolete/host/src/msc_cli.c index 0182a6df9..1f7b1f5ec 100644 --- a/examples/obsolete/host/src/msc_cli.c +++ b/examples/obsolete/host/src/msc_cli.c @@ -176,12 +176,12 @@ void cli_command_prompt(void) (volume_label[0] !=0) ? volume_label : "No Label", cli_buffer); - memclr_(cli_buffer, CLI_MAX_BUFFER); + tu_memclr(cli_buffer, CLI_MAX_BUFFER); } void cli_init(void) { - memclr_(cli_buffer, CLI_MAX_BUFFER); + tu_memclr(cli_buffer, CLI_MAX_BUFFER); f_getlabel(NULL, volume_label, NULL); cli_command_prompt(); } @@ -197,7 +197,7 @@ void cli_poll(char ch) }else { puts("cli buffer overflows"); - memclr_(cli_buffer, CLI_MAX_BUFFER); + tu_memclr(cli_buffer, CLI_MAX_BUFFER); } } else if ( ch == ASCII_BACKSPACE && strlen(cli_buffer)) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 70d51c258..06530bc7a 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -185,7 +185,7 @@ bool tud_cdc_n_write_flush (uint8_t itf) //--------------------------------------------------------------------+ void cdcd_init(void) { - arrclr_( _cdcd_itf ); + tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for(uint8_t i=0; ipipe_in); (void) hcd_pipe_close(p_cdc->pipe_out); - memclr_(p_cdc, sizeof(cdch_data_t)); + tu_memclr(p_cdc, sizeof(cdch_data_t)); tuh_cdc_unmounted_cb(dev_addr); diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index 4d28b0e0c..9b7684f77 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -117,7 +117,7 @@ static tusb_error_t rndis_body_subtask(void) //--------------------------------------------------------------------+ void rndish_init(void) { - memclr_(rndish_data, sizeof(rndish_data_t)*CFG_TUSB_HOST_DEVICE_MAX); + tu_memclr(rndish_data, sizeof(rndish_data_t)*CFG_TUSB_HOST_DEVICE_MAX); //------------- Task creation -------------// @@ -131,7 +131,7 @@ void rndish_init(void) void rndish_close(uint8_t dev_addr) { osal_semaphore_reset( rndish_data[dev_addr-1].sem_notification_hdl ); -// memclr_(&rndish_data[dev_addr-1], sizeof(rndish_data_t)); TODO need to move semaphore & its handle out before memclr +// tu_memclr(&rndish_data[dev_addr-1], sizeof(rndish_data_t)); TODO need to move semaphore & its handle out before memclr } @@ -189,7 +189,7 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) //------------- Message Query 802.3 Permanent Address -------------// memcpy(msg_payload, &msg_query_permanent_addr, sizeof(rndis_msg_query_t)); - memclr_(msg_payload + sizeof(rndis_msg_query_t), 6); // 6 bytes for MAC address + tu_memclr(msg_payload + sizeof(rndis_msg_query_t), 6); // 6 bytes for MAC address STASK_INVOKE( send_message_get_response_subtask( dev_addr, p_cdc, @@ -205,7 +205,7 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) //------------- Set OID_GEN_CURRENT_PACKET_FILTER to (DIRECTED | MULTICAST | BROADCAST) -------------// memcpy(msg_payload, &msg_set_packet_filter, sizeof(rndis_msg_set_t)); - memclr_(msg_payload + sizeof(rndis_msg_set_t), 4); // 4 bytes for filter flags + tu_memclr(msg_payload + sizeof(rndis_msg_set_t), 4); // 4 bytes for filter flags ((rndis_msg_set_t*) msg_payload)->oid_buffer[0] = (RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_MULTICAST | RNDIS_PACKET_TYPE_BROADCAST); STASK_INVOKE( diff --git a/src/class/custom/custom_device.c b/src/class/custom/custom_device.c index 2c3783e35..d43a86b14 100644 --- a/src/class/custom/custom_device.c +++ b/src/class/custom/custom_device.c @@ -68,7 +68,7 @@ static cusd_interface_t _cusd_itf; *------------------------------------------------------------------*/ void cusd_init(void) { - varclr_(&_cusd_itf); + tu_varclr(&_cusd_itf); } tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len) diff --git a/src/class/custom/custom_host.c b/src/class/custom/custom_host.c index ad3315980..329012fda 100644 --- a/src/class/custom/custom_host.c +++ b/src/class/custom/custom_host.c @@ -104,7 +104,7 @@ tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t p //--------------------------------------------------------------------+ void cush_init(void) { - memclr_(&custom_interface, sizeof(custom_interface_info_t) * CFG_TUSB_HOST_DEVICE_MAX); + tu_memclr(&custom_interface, sizeof(custom_interface_info_t) * CFG_TUSB_HOST_DEVICE_MAX); } tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) @@ -152,7 +152,7 @@ void cush_close(uint8_t dev_addr) err2 = hcd_pipe_close( p_interface->pipe_out ); } - memclr_(p_interface, sizeof(custom_interface_info_t)); + tu_memclr(p_interface, sizeof(custom_interface_info_t)); TU_ASSERT(err1 == TUSB_ERROR_NONE && err2 == TUSB_ERROR_NONE, (void) 0 ); } diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index b1cd1d1bd..d8696f137 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -188,7 +188,7 @@ bool tud_hid_keyboard_keycode(uint8_t modifier, uint8_t keycode[6]) memcpy(report.keycode, keycode, 6); }else { - memclr_(report.keycode, 6); + tu_memclr(report.keycode, 6); } return hidd_kbd_report(&report); @@ -307,14 +307,14 @@ void hidd_init(void) void hidd_reset(uint8_t rhport) { - arrclr_(_hidd_itf); + tu_memclr(_hidd_itf, sizeof(_hidd_itf)); #if CFG_TUD_HID_KEYBOARD - varclr_(&_kbd_rpt); + tu_varclr(&_kbd_rpt); #endif #if CFG_TUD_HID_MOUSE - varclr_(&_mse_rpt); + tu_varclr(&_mse_rpt); #endif } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 369dad638..518297eec 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -68,7 +68,7 @@ static inline tusb_error_t hidh_interface_open(uint8_t dev_addr, uint8_t interfa static inline void hidh_interface_close(hidh_interface_info_t *p_hid) { (void) hcd_pipe_close(p_hid->pipe_hdl); - memclr_(p_hid, sizeof(hidh_interface_info_t)); + tu_memclr(p_hid, sizeof(hidh_interface_info_t)); } // called from public API need to validate parameters @@ -164,11 +164,11 @@ tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void * report) void hidh_init(void) { #if CFG_TUSB_HOST_HID_KEYBOARD - memclr_(&keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX); + tu_memclr(&keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX); #endif #if CFG_TUSB_HOST_HID_MOUSE - memclr_(&mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX); + tu_memclr(&mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX); #endif #if CFG_TUSB_HOST_HID_GENERIC diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 3335ad9b3..830ce85b7 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -62,9 +62,9 @@ enum typedef struct { CFG_TUSB_MEM_ALIGN msc_cbw_t cbw; -#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13UXX) - uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member -#endif +//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13UXX) +// uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member +//#endif CFG_TUSB_MEM_ALIGN msc_csw_t csw; @@ -141,12 +141,12 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u //--------------------------------------------------------------------+ void mscd_init(void) { - memclr_(&_mscd_itf, sizeof(mscd_interface_t)); + tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } void mscd_reset(uint8_t rhport) { - memclr_(&_mscd_itf, sizeof(mscd_interface_t)); + tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); } tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len) @@ -302,7 +302,6 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u { case MSC_STAGE_CMD: //------------- new CBW received -------------// - // Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it if(ep_addr != p_msc->ep_out) return TUSB_ERROR_NONE; @@ -332,7 +331,6 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u // 1. Zero : Invoke app callback, skip DATA and move to STATUS stage // 2. OUT : queue transfer (invoke app callback after done) // 3. IN : invoke app callback to get response - if ( p_cbw->xfer_bytes == 0) { int32_t const cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, NULL, 0); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 7e6396389..9250b8df7 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -288,7 +288,7 @@ tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffe //--------------------------------------------------------------------+ void msch_init(void) { - memclr_(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX); + tu_memclr(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX); msch_sem_hdl = osal_semaphore_create(1, 0); } @@ -416,7 +416,7 @@ void msch_close(uint8_t dev_addr) (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_in); (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_out); - memclr_(&msch_data[dev_addr-1], sizeof(msch_interface_t)); + tu_memclr(&msch_data[dev_addr-1], sizeof(msch_interface_t)); osal_semaphore_reset(msch_sem_hdl); tuh_msc_unmounted_cb(dev_addr); // invoke Application Callback diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 778e70676..85bd15d43 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -73,8 +73,7 @@ //--------------------------------------------------------------------+ // MACROS //--------------------------------------------------------------------+ -#define MAX_OF(a, b) ( (a) > (b) ? (a) : (b) ) -#define MIN_OF(a, b) ( (a) < (b) ? (a) : (b) ) +#define TU_ARRAY_SZIE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define U16_HIGH_U8(u16) ((uint8_t) (((u16) >> 8) & 0x00ff)) #define U16_LOW_U8(u16) ((uint8_t) ((u16) & 0x00ff)) @@ -137,12 +136,10 @@ //--------------------------------------------------------------------+ // INLINE FUNCTION //--------------------------------------------------------------------+ -#define memclr_(buffer, size) memset((buffer), 0, (size)) -#define varclr_(_var) memclr_(_var, sizeof(*(_var))) -#define arrclr_(_arr) memclr_(_arr, sizeof(_arr)) -#define arrcount_(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) +#define tu_memclr(buffer, size) memset((buffer), 0, (size)) +#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) -static inline bool mem_all_zero(void const* buffer, uint32_t size) +static inline bool tu_mem_test_zero (void const* buffer, uint32_t size) { uint8_t const* p_mem = (uint8_t const*) buffer; for(uint32_t i=0; i y) ? x : y; } -static inline uint16_t tu_max16(uint16_t x, uint16_t y) -{ - return (x > y) ? x : y; -} - //------------- Align -------------// static inline uint32_t tu_align32 (uint32_t value) { @@ -249,24 +241,6 @@ static inline uint8_t tu_log2(uint32_t value) return result; } -// return the number of set bits in value -static inline uint8_t tu_cardof(uint32_t value) -{ - // Brian Kernighan's method goes through as many iterations as there are set bits. So if we have a 32-bit word with only - // the high bit set, then it will only go once through the loop - // Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie) - // mentions this in exercise 2-9. On April 19, 2006 Don Knuth pointed out to me that this method - // "was first published by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by Derrick Lehmer and - // published in 1964 in a book edited by Beckenbach.)" - uint8_t count; - for (count = 0; value; count++) - { - value &= value - 1; // clear the least significant bit set - } - - return count; -} - #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 89dd4b722..146f8ec89 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -274,7 +274,7 @@ static tusb_error_t usbd_main_st(void) tusb_error_t err; err = TUSB_ERROR_NONE; - memclr_(&event, sizeof(usbd_task_event_t)); + tu_memclr(&event, sizeof(usbd_task_event_t)); osal_queue_receive(_usbd_q, &event, OSAL_TIMEOUT_WAIT_FOREVER, &err); @@ -318,7 +318,7 @@ static tusb_error_t usbd_main_st(void) static void usbd_reset(uint8_t rhport) { - varclr_(&_usbd_dev); + tu_varclr(&_usbd_dev); memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping memset(_usbd_dev.ep2drv , 0xff, sizeof(_usbd_dev.ep2drv )); // invalid mapping diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 84821e3f5..99e7fdb65 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -130,7 +130,7 @@ static tusb_error_t hcd_controller_stop(uint8_t hostid) ATTR_WARN_UNUSED_RESULT tusb_error_t hcd_init(void) { //------------- Data Structure init -------------// - memclr_(&ehci_data, sizeof(ehci_data_t)); + tu_memclr(&ehci_data, sizeof(ehci_data_t)); #if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) TU_ASSERT_ERR (hcd_controller_init(0)); @@ -192,7 +192,7 @@ static tusb_error_t hcd_controller_init(uint8_t hostid) //------------- Asynchronous List -------------// ehci_qhd_t * const async_head = get_async_head(hostid); - memclr_(async_head, sizeof(ehci_qhd_t)); + tu_memclr(async_head, sizeof(ehci_qhd_t)); async_head->next.address = (uint32_t) async_head; // circular list, next is itself async_head->next.type = EHCI_QUEUE_ELEMENT_QHD; @@ -938,7 +938,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_si // address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise) if (dev_addr != 0) { - memclr_(p_qhd, sizeof(ehci_qhd_t)); + tu_memclr(p_qhd, sizeof(ehci_qhd_t)); } p_qhd->device_address = dev_addr; @@ -1004,7 +1004,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_si static void qtd_init(ehci_qtd_t* p_qtd, uint32_t data_ptr, uint16_t total_bytes) { - memclr_(p_qtd, sizeof(ehci_qtd_t)); + tu_memclr(p_qtd, sizeof(ehci_qtd_t)); p_qtd->used = 1; diff --git a/src/host/hub.c b/src/host/hub.c index 063cef61a..624e43563 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -152,7 +152,7 @@ tusb_speed_t hub_port_get_speed(void) //--------------------------------------------------------------------+ void hub_init(void) { - memclr_(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof(usbh_hub_t)); + tu_memclr(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof(usbh_hub_t)); // hub_enum_sem_hdl = osal_semaphore_create( OSAL_SEM_REF(hub_enum_semaphore) ); } @@ -237,7 +237,7 @@ void hub_isr(pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes) void hub_close(uint8_t dev_addr) { (void) hcd_pipe_close(hub_data[dev_addr-1].pipe_status); - memclr_(&hub_data[dev_addr-1], sizeof(usbh_hub_t)); + tu_memclr(&hub_data[dev_addr-1], sizeof(usbh_hub_t)); // osal_semaphore_reset(hub_enum_sem_hdl); } diff --git a/src/host/ohci/ohci.c b/src/host/ohci/ohci.c index 1c9f3f293..b9183a025 100644 --- a/src/host/ohci/ohci.c +++ b/src/host/ohci/ohci.c @@ -164,7 +164,7 @@ static ohci_ed_t * ed_list_find_previous(ohci_ed_t const * p_head, ohci_ed_t con tusb_error_t hcd_init(void) { //------------- Data Structure init -------------// - memclr_(&ohci_data, sizeof(ohci_data_t)); + tu_memclr(&ohci_data, sizeof(ohci_data_t)); for(uint8_t i=0; i<32; i++) { // assign all interrupt pointes to period head ed ohci_data.hcca.interrupt_table[i] = (uint32_t) &ohci_data.period_head_ed; @@ -245,7 +245,7 @@ static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t max_packet_size, // address 0 is used as async head, which always on the list --> cannot be cleared if (dev_addr != 0) { - memclr_(p_ed, sizeof(ohci_ed_t)); + tu_memclr(p_ed, sizeof(ohci_ed_t)); } p_ed->device_address = dev_addr; @@ -261,7 +261,7 @@ static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t max_packet_size, static void gtd_init(ohci_gtd_t* p_td, void* data_ptr, uint16_t total_bytes) { - memclr_(p_td, sizeof(ohci_gtd_t)); + tu_memclr(p_td, sizeof(ohci_gtd_t)); p_td->used = 1; p_td->expected_bytes = total_bytes; diff --git a/src/host/usbh.c b/src/host/usbh.c index 8b858b2de..b849de9b9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -142,7 +142,7 @@ uint32_t tuh_device_get_mounted_class_flag(uint8_t dev_addr) //--------------------------------------------------------------------+ tusb_error_t usbh_init(void) { - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); TU_ASSERT_ERR( hcd_init() ); diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index db65ac553..59cd1b821 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -145,7 +145,7 @@ static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * da os_memblock_put(&queue_hdl->mpool, ptr); return false; } - memclr_(ev, sizeof(struct os_event)); + tu_memclr(ev, sizeof(struct os_event)); ev->ev_arg = ptr; os_eventq_put(&queue_hdl->evq, ev); diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 01926c76e..371c291a3 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -108,7 +108,7 @@ void bus_reset(void) NRF_USBD->TASKS_STARTISOIN = 0; NRF_USBD->TASKS_STARTISOOUT = 0; - varclr_(&_dcd); + tu_varclr(&_dcd); } /*------------------------------------------------------------------*/ diff --git a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c index 292d1fa6d..8e5a4d1aa 100644 --- a/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c +++ b/src/portable/nxp/lpc11xx_lpc13xx/dcd_lpc_11uxx_13uxx.c @@ -201,7 +201,7 @@ bool dcd_init(uint8_t rhport) static void bus_reset(void) { - memclr_(&dcd_data, sizeof(dcd_11u_13u_data_t)); + tu_memclr(&dcd_data, sizeof(dcd_11u_13u_data_t)); for(uint8_t ep_id = 2; ep_id < DCD_11U_13U_QHD_COUNT; ep_id++) { // disable all non-control endpoints on bus reset dcd_data.qhd[ep_id][0].disable = dcd_data.qhd[ep_id][1].disable = 1; @@ -473,7 +473,7 @@ edpt_hdl_t dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint TU_ASSERT( dcd_data.qhd[ep_id][0].disable && dcd_data.qhd[ep_id][1].disable, null_handle ); // endpoint must not previously opened, normally this means running out of endpoints - memclr_(dcd_data.qhd[ep_id], 2*sizeof(dcd_11u_13u_qhd_t)); + tu_memclr(dcd_data.qhd[ep_id], 2*sizeof(dcd_11u_13u_qhd_t)); dcd_data.qhd[ep_id][0].is_isochronous = dcd_data.qhd[ep_id][1].is_isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); dcd_data.class_code[ep_id] = class_code; diff --git a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c index 4d3687830..189521d25 100644 --- a/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c +++ b/src/portable/nxp/lpc17xx/dcd_lpc175x_6x.c @@ -119,7 +119,7 @@ static void bus_reset(void) LPC_USB->USBNDDRIntClr = 0xFFFFFFFF; LPC_USB->USBSysErrIntClr = 0xFFFFFFFF; - memclr_(&dcd_data, sizeof(dcd_data_t)); + tu_memclr(&dcd_data, sizeof(dcd_data_t)); } bool dcd_init(uint8_t rhport) @@ -432,7 +432,7 @@ edpt_hdl_t dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint //------------- first DD prepare -------------// dcd_dma_descriptor_t* const p_dd = &dcd_data.dd[ep_id][0]; - memclr_(p_dd, sizeof(dcd_dma_descriptor_t)); + tu_memclr(p_dd, sizeof(dcd_dma_descriptor_t)); p_dd->is_isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0; p_dd->max_packet_size = p_endpoint_desc->wMaxPacketSize.size; @@ -498,7 +498,7 @@ tusb_error_t dcd_edpt_xfer(edpt_hdl_t edpt_hdl, uint8_t* buffer, uint16_t total_ { // setup new dd dcd_dma_descriptor_t* const p_dd = &dcd_data.dd[ edpt_hdl.index ][1]; - memclr_(p_dd, sizeof(dcd_dma_descriptor_t)); + tu_memclr(p_dd, sizeof(dcd_dma_descriptor_t)); dd_xfer_init(p_dd, buffer, total_bytes); diff --git a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c index 7368542b8..5a7d61004 100644 --- a/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c +++ b/src/portable/nxp/lpc43xx_lpc18xx/dcd_lpc43xx.c @@ -133,7 +133,7 @@ static void bus_reset(uint8_t rhport) //------------- Queue Head & Queue TD -------------// dcd_data_t* p_dcd = dcd_data_ptr[rhport]; - memclr_(p_dcd, sizeof(dcd_data_t)); + tu_memclr(p_dcd, sizeof(dcd_data_t)); //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// p_dcd->qhd[0].zero_length_termination = p_dcd->qhd[1].zero_length_termination = 1; @@ -149,7 +149,7 @@ bool dcd_init(uint8_t rhport) LPC_USB0_Type* const lpc_usb = LPC_USB[rhport]; dcd_data_t* p_dcd = dcd_data_ptr[rhport]; - memclr_(p_dcd, sizeof(dcd_data_t)); + tu_memclr(p_dcd, sizeof(dcd_data_t)); lpc_usb->ENDPOINTLISTADDR = (uint32_t) p_dcd->qhd; // Endpoint List Address has to be 2K alignment lpc_usb->USBSTS_D = lpc_usb->USBSTS_D; @@ -196,7 +196,7 @@ static inline uint8_t edpt_phy2log(uint8_t physical_endpoint) static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) { - memclr_(p_qtd, sizeof(dcd_qtd_t)); + tu_memclr(p_qtd, sizeof(dcd_qtd_t)); p_qtd->used = 1; @@ -303,7 +303,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) uint8_t ep_idx = edpt_addr2phy(p_endpoint_desc->bEndpointAddress); dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx]; - memclr_(p_qhd, sizeof(dcd_qhd_t)); + tu_memclr(p_qhd, sizeof(dcd_qhd_t)); p_qhd->zero_length_termination = 1; p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size; diff --git a/tests/lpc175x_6x/test/test_dcd_lpc175x_6x.c b/tests/lpc175x_6x/test/test_dcd_lpc175x_6x.c index ef084fc77..31baa5f5c 100644 --- a/tests/lpc175x_6x/test/test_dcd_lpc175x_6x.c +++ b/tests/lpc175x_6x/test/test_dcd_lpc175x_6x.c @@ -51,9 +51,9 @@ extern dcd_dma_descriptor_t dcd_dd[DCD_MAX_DD]; void setUp(void) { - memclr_(dcd_udca, 32*4); - memclr_(dcd_dd, sizeof(dcd_dma_descriptor_t)*DCD_MAX_DD); - memclr_(&lpc_usb, sizeof(LPC_USB_TypeDef)); + tu_memclr(dcd_udca, 32*4); + tu_memclr(dcd_dd, sizeof(dcd_dma_descriptor_t)*DCD_MAX_DD); + tu_memclr(&lpc_usb, sizeof(LPC_USB_TypeDef)); } void tearDown(void) @@ -129,7 +129,7 @@ void test_dcd_configure_endpoint_in(void) }; dcd_init(); - memclr_(&lpc_usb, sizeof(LPC_USB_TypeDef)); // clear to examine register after CUT + tu_memclr(&lpc_usb, sizeof(LPC_USB_TypeDef)); // clear to examine register after CUT //------------- Code Under Test -------------// dcd_pipe_open(0, &desc_endpoint); diff --git a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c index a74270e8b..5077eea93 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c @@ -71,7 +71,7 @@ void setUp(void) length = 0; dev_addr = 1; - memclr_(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX); + tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX); } void tearDown(void) diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_open.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_open.c index a26b990d3..581488d7d 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_open.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_open.c @@ -70,7 +70,7 @@ void setUp(void) dev_addr = 1; hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX; - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH); async_head = get_async_head( hostid ); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c index a52c721fe..2e9e29fdc 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c @@ -90,8 +90,8 @@ tusb_desc_endpoint_t const desc_ept_bulk_out = void setUp(void) { ehci_controller_init(); - memclr_(xfer_data, sizeof(xfer_data)); - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(xfer_data, sizeof(xfer_data)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); TEST_ASSERT_STATUS( hcd_init() ); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_open.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_open.c index 22cbf7569..426fed9f2 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_open.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_open.c @@ -67,7 +67,7 @@ static ehci_qhd_t *p_control_qhd; //--------------------------------------------------------------------+ void setUp(void) { - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); TEST_ASSERT_STATUS( hcd_init() ); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c index 286aae113..ffd7ffb67 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c @@ -74,8 +74,8 @@ void setUp(void) { ehci_controller_init(); - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); - memclr_(xfer_data, sizeof(xfer_data)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(xfer_data, sizeof(xfer_data)); TEST_ASSERT_STATUS( hcd_init() ); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_open.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_open.c index f39021ef2..b243a468e 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_open.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_open.c @@ -67,7 +67,7 @@ static pipe_handle_t pipe_hdl; //--------------------------------------------------------------------+ void setUp(void) { - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); hcd_init(); @@ -78,7 +78,7 @@ void setUp(void) period_head_arr = get_period_head( hostid, 1 ); p_int_qhd = NULL; - memclr_(&pipe_hdl, sizeof(pipe_handle_t)); + tu_memclr(&pipe_hdl, sizeof(pipe_handle_t)); } void tearDown(void) diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c index aeb094932..827db2897 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c @@ -91,8 +91,8 @@ void setUp(void) { ehci_controller_init(); - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); - memclr_(xfer_data, sizeof(xfer_data)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(xfer_data, sizeof(xfer_data)); TEST_ASSERT_STATUS( hcd_init() ); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_isochronous_open.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_isochronous_open.c index 584c44471..1feff94e5 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_isochronous_open.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_isochronous_open.c @@ -63,7 +63,7 @@ static ehci_qhd_t *period_head_arr; //--------------------------------------------------------------------+ void setUp(void) { - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); hcd_init(); diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c index 75c8f8a90..b3b49c172 100644 --- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c +++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c @@ -73,7 +73,7 @@ tusb_desc_endpoint_t const *p_kdb_endpoint_desc = &desc_configuration.keyboard void setUp(void) { hidh_init(); - memclr_(&report, sizeof(hid_keyboard_report_t)); + tu_memclr(&report, sizeof(hid_keyboard_report_t)); dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1; p_hidh_kbd = &keyboardh_data[dev_addr-1]; diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c index 741f54428..b1a3558e6 100644 --- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c +++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c @@ -62,7 +62,7 @@ void setUp(void) { hidh_init(); - memclr_(&report, sizeof(hid_mouse_report_t)); + tu_memclr(&report, sizeof(hid_mouse_report_t)); dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1; p_hidh_mouse = &mouseh_data[dev_addr-1]; diff --git a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c index 7aeba21a0..a85c3c48a 100644 --- a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c +++ b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c @@ -73,7 +73,7 @@ enum { void setUp(void) { - memclr_(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); osal_queue_receive_StubWithCallback(queue_recv_stub); osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub); diff --git a/tests/support/ehci_controller_fake.c b/tests/support/ehci_controller_fake.c index 041e1dbb5..acd40cc0b 100644 --- a/tests/support/ehci_controller_fake.c +++ b/tests/support/ehci_controller_fake.c @@ -61,8 +61,8 @@ extern usbh_device_info_t usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1]; //--------------------------------------------------------------------+ void ehci_controller_init(void) { - memclr_(&lpc_usb0, sizeof(LPC_USB0_Type)); - memclr_(&lpc_usb1, sizeof(LPC_USB1_Type)); + tu_memclr(&lpc_usb0, sizeof(LPC_USB0_Type)); + tu_memclr(&lpc_usb1, sizeof(LPC_USB1_Type)); } void ehci_controller_control_xfer_proceed(uint8_t dev_addr, uint8_t p_data[]) diff --git a/tests/support/type_helper.h b/tests/support/type_helper.h index 3e27cef2e..36502ba35 100644 --- a/tests/support/type_helper.h +++ b/tests/support/type_helper.h @@ -75,7 +75,7 @@ ({\ uint32_t value=0;\ struct_type str;\ - memclr_((void*)&str, sizeof(struct_type));\ + tu_memclr((void*)&str, sizeof(struct_type));\ str.member.bitfield_member = 1;\ memcpy(&value, (void*)&str.member, sizeof(str.member));\ tu_log2( value );\ @@ -84,7 +84,7 @@ #define BITFIELD_OFFSET_OF_UINT32(struct_type, offset, bitfield_member) \ ({\ struct_type str;\ - memclr_(&str, sizeof(struct_type));\ + tu_memclr(&str, sizeof(struct_type));\ str.bitfield_member = 1;\ tu_log2( ((uint32_t*) &str)[offset] );\ }) -- cgit v1.3.1 From 3dd635f4c14c6e23ed1a3d2254ecf58b7398e2d7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Oct 2018 15:53:29 +0700 Subject: merge osal_queue_send_isr to osal_queue_send, osal_semaphore_post_isr to osal_semaphore_post --- src/osal/osal.h | 6 ++---- src/osal/osal_freertos.h | 18 ++++-------------- src/osal/osal_mynewt.h | 11 +++++------ src/osal/osal_none.h | 10 ++++------ 4 files changed, 15 insertions(+), 30 deletions(-) (limited to 'src/osal') diff --git a/src/osal/osal.h b/src/osal/osal.h index d64837205..93ac48b13 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -80,15 +80,13 @@ typedef void (*osal_task_func_t)( void * ); * osal_queue_def_t, osal_queue_t * osal_queue_t osal_queue_create(osal_queue_def_t* qdef) * osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) - * bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) - * bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) + * bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) * osal_queue_flush() TODO remove * * Semaphore * osal_semaphore_def_t, osal_semaphore_t * osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) - * bool osal_semaphore_post_isr(osal_semaphore_t sem_hdl) - * bool osal_semaphore_post(osal_semaphore_t sem_hdl) + * bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) * void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) * diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 52d34c187..be7e6b38b 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -120,14 +120,9 @@ static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_dat (*p_error) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); } -static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) { - return xQueueSendToBackFromISR(queue_hdl, data, NULL); -} - -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) -{ - return xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER) == pdTRUE; + return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER); } static inline void osal_queue_flush(osal_queue_t const queue_hdl) @@ -147,14 +142,9 @@ static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semde return xSemaphoreCreateBinaryStatic(semdef); } -static inline bool osal_semaphore_post_isr(osal_semaphore_t sem_hdl) -{ - return xSemaphoreGiveFromISR(sem_hdl, NULL) == pdTRUE; -} - -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { - return xSemaphoreGive(sem_hdl) == pdTRUE; + return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl); } static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index 59cd1b821..cb09680e0 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -129,10 +129,10 @@ static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_dat *p_error = TUSB_ERROR_NONE; } -#define osal_queue_send_isr osal_queue_send - -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data) +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) { + (void) in_isr; + // get a block from mem pool for data void* ptr = os_memblock_get(&queue_hdl->mpool); if (!ptr) return false; @@ -169,10 +169,9 @@ static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semde return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; } -#define osal_semaphore_post_isr osal_semaphore_post - -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; return os_sem_release(sem_hdl) == OS_OK; } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 22c89868a..91848f221 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -133,13 +133,12 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return (osal_queue_t) qdef; } -static inline bool osal_queue_send_isr(osal_queue_t const queue_hdl, void const * data) +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) { + (void) in_isr; return tu_fifo_write( (tu_fifo_t*) queue_hdl, data); } -#define osal_queue_send osal_queue_send_isr - static inline void osal_queue_flush(osal_queue_t const queue_hdl) { queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; @@ -182,10 +181,9 @@ static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semde return semdef; } -#define osal_semaphore_post_isr osal_semaphore_post - -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl) +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; if (sem_hdl->count < sem_hdl->max_count ) sem_hdl->count++; return true; } -- cgit v1.3.1 From bfa10016ae353779f7b94da31156ac997062322a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Oct 2018 12:37:43 +0700 Subject: rename verify_breakpoint to TU_BREAKPOINT --- src/class/msc/msc_device.c | 2 +- src/common/tusb_verify.h | 16 ++++++++-------- src/device/usbd.c | 2 +- src/host/ehci/ehci.c | 2 +- src/osal/osal_none.h | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/osal') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index b050ea705..5a047b016 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -468,7 +468,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u }else { // No other command take more than one transfer yet -> unlikely error - verify_breakpoint(); + TU_BREAKPOINT(); } } break; diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 41c2b5be1..1cb8443bc 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -74,14 +74,14 @@ // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) -#define verify_breakpoint() \ +#define TU_BREAKPOINT() \ do {\ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */\ } while(0) #else -#define verify_breakpoint() +#define TU_BREAKPOINT() #endif /*------------------------------------------------------------------*/ @@ -157,21 +157,21 @@ /*------------------------------------------------------------------*/ /* ASSERT - * basically TU_VERIFY with verify_breakpoint() as handler + * basically TU_VERIFY with TU_BREAKPOINT() as handler * - 1 arg : return false if failed * - 2 arg : return error if failed *------------------------------------------------------------------*/ -#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); verify_breakpoint(), false) -#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); verify_breakpoint(), _ret) +#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false) +#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret) #define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT Error - * basically TU_VERIFY Error with verify_breakpoint() as handler + * basically TU_VERIFY Error with TU_BREAKPOINT() as handler *------------------------------------------------------------------*/ -#define ASERT_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, verify_breakpoint()) -#define ASERT_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, verify_breakpoint(), _ret) +#define ASERT_ERR_1ARGS(_error) TU_VERIFY_ERR_DEF2(_error, TU_BREAKPOINT()) +#define ASERT_ERR_2ARGS(_error, _ret) TU_VERIFY_ERR_DEF3(_error, TU_BREAKPOINT(), _ret) #define TU_ASSERT_ERR(...) GET_3RD_ARG(__VA_ARGS__, ASERT_ERR_2ARGS, ASERT_ERR_1ARGS)(__VA_ARGS__) diff --git a/src/device/usbd.c b/src/device/usbd.c index f35671f17..1e96983b1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -274,7 +274,7 @@ static tusb_error_t usbd_main_st(void) } else { - verify_breakpoint(); + TU_BREAKPOINT(); } } diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 99e7fdb65..c7ff70d70 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -646,7 +646,7 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes; -// if ( TUSB_EVENT_XFER_ERROR == error_event ) verify_breakpoint(); // TODO skip unplugged device +// if ( TUSB_EVENT_XFER_ERROR == error_event ) TU_BREAKPOINT(); // TODO skip unplugged device p_qhd->p_qtd_list_head->used = 0; // free QTD qtd_remove_1st_from_qhd(p_qhd); diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 91848f221..783e4fd2e 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -113,11 +113,11 @@ static inline bool osal_task_create(osal_task_def_t* taskdef) //------------- Sub Task Assert -------------// #define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0) -#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR_HDLR(_err, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) -#define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED ) +#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR_HDLR(_err, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED ) -#define STASK_ASSERT(_cond) TU_VERIFY_HDLR(_cond, verify_breakpoint(); TASK_RESTART, TUSB_ERROR_FAILED) -#define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, verify_breakpoint(); _func; TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT(_cond) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED) +#define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED) //--------------------------------------------------------------------+ // QUEUE API -- cgit v1.3.1 From 4683dc1e680bbed3909b2b1dc519886b2cee0107 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Nov 2018 15:45:27 +0700 Subject: add osal_mutex --- src/osal/osal.h | 10 ++--- src/osal/osal_freertos.h | 31 +++++++------ src/osal/osal_none.h | 113 +++++++++++++++++++++++++---------------------- 3 files changed, 80 insertions(+), 74 deletions(-) (limited to 'src/osal') diff --git a/src/osal/osal.h b/src/osal/osal.h index 93ac48b13..c40ab661d 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -81,20 +81,20 @@ typedef void (*osal_task_func_t)( void * ); * osal_queue_t osal_queue_create(osal_queue_def_t* qdef) * osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) * bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) - * osal_queue_flush() TODO remove + * osal_queue_reset() * * Semaphore * osal_semaphore_def_t, osal_semaphore_t * osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) * bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) - * void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) + * void osal_semaphore_reset(osal_semaphore_t const sem_hdl) * * Mutex * osal_mutex_t - * osal_mutex_create() - * bool osal_mutex_release(osal_mutex_t mutex_hdl) - * void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) + * osal_mutex_create(osal_mutex_def_t* mdef) + * bool osal_mutex_unlock(osal_mutex_t mutex_hdl) + * void osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) */ #if CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index be7e6b38b..f41e91c67 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -114,10 +114,10 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); } -static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) +static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *err) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*p_error) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); + (*err) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); } static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) @@ -125,10 +125,9 @@ static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * da return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER); } -static inline void osal_queue_flush(osal_queue_t const queue_hdl) +static inline void osal_queue_reset(osal_queue_t const queue_hdl) { - // TODO move to thread context -// xQueueReset(queue_hdl); + xQueueReset(queue_hdl); } //--------------------------------------------------------------------+ @@ -147,33 +146,33 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl); } -static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) +static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *err) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*p_error) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); + (*err) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); } -static inline void osal_semaphore_reset_isr(osal_semaphore_t const sem_hdl) +static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { - xSemaphoreTakeFromISR(sem_hdl, NULL); + xQueueReset(sem_hdl); } //--------------------------------------------------------------------+ // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ +typedef StaticSemaphore_t osal_mutex_def_t; typedef SemaphoreHandle_t osal_mutex_t; -#define osal_mutex_create(x) xSemaphoreCreateMutex() - -static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { - return xSemaphoreGive(mutex_hdl); + return xSemaphoreCreateMutexStatic(mdef); } -static inline void osal_mutex_wait(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) +#define osal_mutex_lock osal_semaphore_wait + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*p_error) = (xSemaphoreTake(mutex_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); + return xSemaphoreGive(mutex_hdl); } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 783e4fd2e..39748800b 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -78,12 +78,12 @@ static inline bool osal_task_create(osal_task_def_t* taskdef) #define TASK_RESTART \ _state = 0 -#define osal_task_delay(msec) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if ( _timeout + msec > tusb_hal_millis() ) \ - return TUSB_ERROR_OSAL_WAITING; \ +#define osal_task_delay(_msec) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if ( _timeout + (_msec) > tusb_hal_millis() ) \ + return TUSB_ERROR_OSAL_WAITING; \ }while(0) //--------------------------------------------------------------------+ @@ -139,26 +139,26 @@ static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * da return tu_fifo_write( (tu_fifo_t*) queue_hdl, data); } -static inline void osal_queue_flush(osal_queue_t const queue_hdl) +static inline void osal_queue_reset(osal_queue_t const queue_hdl) { queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; } -#define osal_queue_receive(queue_hdl, p_data, msec, p_error) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if( queue_hdl->count == 0 ) { \ - if ( (msec != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + msec <= tusb_hal_millis()) ) \ - *(p_error) = TUSB_ERROR_OSAL_TIMEOUT; \ - else \ - return TUSB_ERROR_OSAL_WAITING; \ - } else{ \ - /*tusb_hal_int_disable_all();*/ \ - tu_fifo_read(queue_hdl, p_data); \ - /*tusb_hal_int_enable_all();*/ \ - *(p_error) = TUSB_ERROR_NONE; \ - } \ +#define osal_queue_receive(_q_hdl, p_data, _msec, _err) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if( (_q_hdl)->count == 0 ) { \ + if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + (_msec) <= tusb_hal_millis()) ) \ + *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \ + else \ + return TUSB_ERROR_OSAL_WAITING; \ + } else{ \ + /* Enter critical ? */ \ + tu_fifo_read(queue_hdl, p_data); \ + /* Exit critical ? */ \ + *(_err) = TUSB_ERROR_NONE; \ + } \ }while(0) @@ -168,67 +168,74 @@ static inline void osal_queue_flush(osal_queue_t const queue_hdl) typedef struct { volatile uint16_t count; - uint16_t max_count; }osal_semaphore_def_t; typedef osal_semaphore_def_t* osal_semaphore_t; - static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) { - semdef->count = 0; - semdef->max_count = 1; + semdef->count = 0; return semdef; } -static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { (void) in_isr; - if (sem_hdl->count < sem_hdl->max_count ) sem_hdl->count++; + sem_hdl->count++; return true; } -static inline void osal_semaphore_reset_isr(osal_semaphore_t sem_hdl) +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { sem_hdl->count = 0; } -#define osal_semaphore_wait(sem_hdl, msec, p_error) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if( sem_hdl->count == 0 ) { \ - if ( (msec != OSAL_TIMEOUT_WAIT_FOREVER) && (_timeout + msec <= tusb_hal_millis()) ) \ - *(p_error) = TUSB_ERROR_OSAL_TIMEOUT; \ - else \ - return TUSB_ERROR_OSAL_WAITING; \ - } else{ \ - /*tusb_hal_int_disable_all();*/ \ - sem_hdl->count--; \ - /*tusb_hal_int_enable_all();*/ \ - *(p_error) = TUSB_ERROR_NONE; \ - } \ +#define osal_semaphore_wait(_sem_hdl, _msec, _err) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if( (_sem_hdl)->count == 0 ) { \ + if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && (_timeout + (_msec) <= tusb_hal_millis()) ) \ + *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \ + else \ + return TUSB_ERROR_OSAL_WAITING; \ + } else{ \ + /* Enter critical ? */ \ + (_sem_hdl)->count--; \ + /* Exit critical ? */ \ + *(_err) = TUSB_ERROR_NONE; \ + } \ }while(0) //--------------------------------------------------------------------+ -// MUTEX API (priority inheritance) +// MUTEX API +// Within tinyusb, mutex is never used in ISR context //--------------------------------------------------------------------+ -#if 0 +typedef osal_semaphore_def_t osal_mutex_def_t; typedef osal_semaphore_t osal_mutex_t; -static inline osal_mutex_t osal_mutex_create(void) +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) { - return osal_semaphore_create(1, 0); + mdef->count = 1; + return mdef; } -static inline bool osal_mutex_release(osal_mutex_t mutex_hdl) +#define osal_mutex_unlock(_mutex_hdl) osal_semaphore_post(_mutex_hdl, false) +#define osal_mutex_lock osal_semaphore_wait + +// check if mutex is available for non-thread/substask usage in some cases +static inline bool osal_mutex_lock_notask(osal_mutex_t mutex_hdl) { - return osal_semaphore_post(mutex_hdl); + if (mutex_hdl->count) + { + mutex_hdl->count--; + return true; + }else + { + return false; + } } -#define osal_mutex_wait osal_semaphore_wait -#endif - #ifdef __cplusplus } -- cgit v1.3.1 From 2708632a6a65e467cae131ce38082d6a45a837d0 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Nov 2018 17:26:35 +0700 Subject: clean up osal --- src/device/usbd_pvt.h | 3 +- src/osal/osal.c | 1 - src/osal/osal.h | 6 ++-- src/osal/osal_freertos.h | 79 +++++++++++++++++++++---------------------- src/osal/osal_none.h | 88 +++++++++++++++++++++++------------------------- src/tusb.h | 1 + 6 files changed, 88 insertions(+), 90 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index d7e014cb1..0b6b56d7d 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -39,6 +39,7 @@ #define USBD_PVT_H_ #include "osal/osal.h" +#include "common/tusb_fifo.h" #ifdef __cplusplus extern "C" { @@ -68,7 +69,7 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_d #define usbd_control_xfer_st(_rhport, _dir, _buffer, _len) \ do { \ if (_len) { \ - tusb_error_t err; \ + uint32_t err; \ dcd_control_xfer(_rhport, _dir, (uint8_t*) _buffer, _len); \ osal_semaphore_wait( _usbd_ctrl_sem, OSAL_TIMEOUT_CONTROL_XFER, &err ); \ STASK_ASSERT_ERR( err ); \ diff --git a/src/osal/osal.c b/src/osal/osal.c index 4507b0b8f..f5105d4d1 100644 --- a/src/osal/osal.c +++ b/src/osal/osal.c @@ -39,7 +39,6 @@ #include "tusb_option.h" #include "osal.h" - //--------------------------------------------------------------------+ // TICK API //--------------------------------------------------------------------+ diff --git a/src/osal/osal.h b/src/osal/osal.h index c40ab661d..2ca06f66e 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -79,7 +79,7 @@ typedef void (*osal_task_func_t)( void * ); * Queue * osal_queue_def_t, osal_queue_t * osal_queue_t osal_queue_create(osal_queue_def_t* qdef) - * osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) + * osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *p_error) * bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) * osal_queue_reset() * @@ -87,14 +87,14 @@ typedef void (*osal_task_func_t)( void * ); * osal_semaphore_def_t, osal_semaphore_t * osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) * bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) - * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *p_error) + * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, uint32_t *p_error) * void osal_semaphore_reset(osal_semaphore_t const sem_hdl) * * Mutex * osal_mutex_t * osal_mutex_create(osal_mutex_def_t* mdef) * bool osal_mutex_unlock(osal_mutex_t mutex_hdl) - * void osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec, tusb_error_t *p_error) + * void osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec, uint32_t *p_error) */ #if CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index f41e91c67..ae988ec1f 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -91,45 +91,6 @@ static inline void osal_task_delay(uint32_t msec) vTaskDelay( pdMS_TO_TICKS(msec) ); } -//--------------------------------------------------------------------+ -// QUEUE API -//--------------------------------------------------------------------+ -#define OSAL_QUEUE_DEF(_name, _depth, _type) \ - static _type _name##_##buf[_depth];\ - osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; - -typedef struct -{ - uint16_t depth; - uint16_t item_sz; - void* buf; - - StaticQueue_t sq; -}osal_queue_def_t; - -typedef QueueHandle_t osal_queue_t; - -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ - return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); -} - -static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *err) -{ - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*err) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); -} - -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) -{ - return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER); -} - -static inline void osal_queue_reset(osal_queue_t const queue_hdl) -{ - xQueueReset(queue_hdl); -} - //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ @@ -146,7 +107,7 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl); } -static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, tusb_error_t *err) +static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, uint32_t *err) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); (*err) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); @@ -175,6 +136,44 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) return xSemaphoreGive(mutex_hdl); } +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#define OSAL_QUEUE_DEF(_name, _depth, _type) \ + static _type _name##_##buf[_depth];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + + StaticQueue_t sq; +}osal_queue_def_t; + +typedef QueueHandle_t osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); +} + +static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *err) +{ + uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); + (*err) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); +} + +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) +{ + return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER); +} + +static inline void osal_queue_reset(osal_queue_t const queue_hdl) +{ + xQueueReset(queue_hdl); +} #ifdef __cplusplus } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 39748800b..796ddc15f 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -43,8 +43,6 @@ #ifndef _TUSB_OSAL_NONE_H_ #define _TUSB_OSAL_NONE_H_ -#include "common/tusb_fifo.h" - #ifdef __cplusplus extern "C" { #endif @@ -119,49 +117,6 @@ static inline bool osal_task_create(osal_task_def_t* taskdef) #define STASK_ASSERT(_cond) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED) #define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED) -//--------------------------------------------------------------------+ -// QUEUE API -//--------------------------------------------------------------------+ -#define OSAL_QUEUE_DEF(_name, _depth, _type) TU_FIFO_DEF(_name, _depth, _type, false) - -typedef tu_fifo_t osal_queue_def_t; -typedef tu_fifo_t* osal_queue_t; - -static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ - tu_fifo_clear(qdef); - return (osal_queue_t) qdef; -} - -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) -{ - (void) in_isr; - return tu_fifo_write( (tu_fifo_t*) queue_hdl, data); -} - -static inline void osal_queue_reset(osal_queue_t const queue_hdl) -{ - queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; -} - -#define osal_queue_receive(_q_hdl, p_data, _msec, _err) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if( (_q_hdl)->count == 0 ) { \ - if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + (_msec) <= tusb_hal_millis()) ) \ - *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \ - else \ - return TUSB_ERROR_OSAL_WAITING; \ - } else{ \ - /* Enter critical ? */ \ - tu_fifo_read(queue_hdl, p_data); \ - /* Exit critical ? */ \ - *(_err) = TUSB_ERROR_NONE; \ - } \ - }while(0) - - //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ @@ -236,6 +191,49 @@ static inline bool osal_mutex_lock_notask(osal_mutex_t mutex_hdl) } } +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#include "common/tusb_fifo.h" + +#define OSAL_QUEUE_DEF(_name, _depth, _type) TU_FIFO_DEF(_name, _depth, _type, false) + +typedef tu_fifo_t osal_queue_def_t; +typedef tu_fifo_t* osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + tu_fifo_clear(qdef); + return (osal_queue_t) qdef; +} + +static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) +{ + (void) in_isr; + return tu_fifo_write( (tu_fifo_t*) queue_hdl, data); +} + +static inline void osal_queue_reset(osal_queue_t const queue_hdl) +{ + queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; +} + +#define osal_queue_receive(_q_hdl, p_data, _msec, _err) \ + do { \ + _timeout = tusb_hal_millis(); \ + _state = __LINE__; case __LINE__: \ + if( (_q_hdl)->count == 0 ) { \ + if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + (_msec) <= tusb_hal_millis()) ) \ + *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \ + else \ + return TUSB_ERROR_OSAL_WAITING; \ + } else{ \ + /* Enter critical ? */ \ + tu_fifo_read(_q_hdl, p_data); \ + /* Exit critical ? */ \ + *(_err) = TUSB_ERROR_NONE; \ + } \ + }while(0) #ifdef __cplusplus } diff --git a/src/tusb.h b/src/tusb.h index 01fdf5ed3..c0246ccc8 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -49,6 +49,7 @@ #include "common/tusb_common.h" #include "tusb_hal.h" #include "osal/osal.h" +#include "common/tusb_fifo.h" //------------- HOST -------------// #if MODE_HOST_SUPPORTED -- cgit v1.3.1 From c582c0fda972eb90d5d617436e75182ea0235542 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 24 Oct 2018 23:55:10 -0700 Subject: Add SAMD21 and SAMD51 support for CircuitPython. The ProtoThreads style subtasks were removed because it led to extremely unclear control flow. RTOSes can be used if threading is needed. Also added some additional functionality to MSC to support dynamic LUNs and read-only LUNs. --- src/class/cdc/cdc_device.c | 7 +- src/class/hid/hid_device.c | 9 +- src/class/msc/msc.h | 4 +- src/class/msc/msc_device.c | 83 ++++---- src/class/msc/msc_device.h | 43 +++- src/device/dcd.h | 27 +-- src/device/usbd.c | 82 +++++--- src/device/usbd_pvt.h | 15 +- src/osal/osal_freertos.h | 1 - src/osal/osal_none.h | 103 +++------- src/portable/microchip/samd21/dcd.c | 341 ++++++++++++++++++++++++++++++++ src/portable/microchip/samd21/hal.c | 82 ++++++++ src/portable/microchip/samd51/dcd.c | 360 ++++++++++++++++++++++++++++++++++ src/portable/microchip/samd51/hal.c | 88 +++++++++ src/portable/nordic/nrf5x/dcd_nrf5x.c | 10 +- src/tusb_option.h | 2 + 16 files changed, 1050 insertions(+), 207 deletions(-) create mode 100644 src/portable/microchip/samd21/dcd.c create mode 100644 src/portable/microchip/samd21/hal.c create mode 100644 src/portable/microchip/samd51/dcd.c create mode 100644 src/portable/microchip/samd51/hal.c (limited to 'src/osal') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index a6f1f1fbb..f3d4622f8 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -289,8 +289,6 @@ tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface tusb_error_t cdcd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request) { - OSAL_SUBTASK_BEGIN - //------------- Class Specific Request -------------// if (p_request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; @@ -301,7 +299,7 @@ tusb_error_t cdcd_control_request_st(uint8_t rhport, tusb_control_request_t cons if ( (CDC_REQUEST_GET_LINE_CODING == p_request->bRequest) || (CDC_REQUEST_SET_LINE_CODING == p_request->bRequest) ) { uint16_t len = tu_min16(sizeof(cdc_line_coding_t), p_request->wLength); - usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, &p_cdc->line_coding, len); + usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, (uint8_t*) &p_cdc->line_coding, len); // Invoke callback if (CDC_REQUEST_SET_LINE_CODING == p_request->bRequest) @@ -327,8 +325,7 @@ tusb_error_t cdcd_control_request_st(uint8_t rhport, tusb_control_request_t cons { dcd_control_stall(rhport); // stall unsupported request } - - OSAL_SUBTASK_END + return TUSB_ERROR_NONE; } tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index d8696f137..3e74950e6 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -407,8 +407,6 @@ tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t cons hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex ); TU_ASSERT(p_hid, TUSB_ERROR_FAILED); - OSAL_SUBTASK_BEGIN - //------------- STD Request -------------// if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { @@ -419,7 +417,7 @@ tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t cons if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { // use device control buffer - STASK_ASSERT ( p_hid->desc_len <= CFG_TUD_CTRL_BUFSIZE ); + TU_ASSERT ( p_hid->desc_len <= CFG_TUD_CTRL_BUFSIZE ); memcpy(_usbd_ctrl_buf, p_hid->desc_report, p_hid->desc_len); usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, p_hid->desc_len); @@ -447,7 +445,7 @@ tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t cons xferlen = p_request->wLength; } - STASK_ASSERT( xferlen > 0 ); + TU_ASSERT( xferlen > 0 ); usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, p_hid->report_buf, xferlen); } else if ( HID_REQ_CONTROL_SET_REPORT == p_request->bRequest ) @@ -492,8 +490,7 @@ tusb_error_t hidd_control_request_st(uint8_t rhport, tusb_control_request_t cons { dcd_control_stall(rhport); } - - OSAL_SUBTASK_END + return TUSB_ERROR_NONE; } tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes) diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h index 59df6bed6..a0abc2501 100644 --- a/src/class/msc/msc.h +++ b/src/class/msc/msc.h @@ -279,11 +279,13 @@ typedef struct ATTR_PACKED TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct"); +// This is only a Mode parameter header(6). typedef struct ATTR_PACKED { uint8_t data_len; uint8_t medium_type; - uint8_t device_specific_para; + bool write_protected : 1; + uint8_t reserved : 7; uint8_t block_descriptor_len; } scsi_mode_sense6_resp_t; diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 5a047b016..aa9ebbbc9 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -59,31 +59,7 @@ enum MSC_STAGE_STATUS }; -typedef struct { - CFG_TUSB_MEM_ALIGN msc_cbw_t cbw; - -//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13UXX) -// uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member -//#endif - - CFG_TUSB_MEM_ALIGN msc_csw_t csw; - - uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; - - // Bulk Only Transfer (BOT) Protocol - uint8_t stage; - uint32_t total_len; - uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage - - // Sense Response Data - uint8_t sense_key; - uint8_t add_sense_code; - uint8_t add_sense_qualifier; -}mscd_interface_t; - -CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf; +CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN mscd_interface_t _mscd_itf; CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN static uint8_t _mscd_buf[CFG_TUD_MSC_BUFSIZE]; //--------------------------------------------------------------------+ @@ -172,8 +148,6 @@ tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, tusb_error_t mscd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request) { - OSAL_SUBTASK_BEGIN - TU_ASSERT(p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS, TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT); if(MSC_REQ_RESET == p_request->bRequest) @@ -189,9 +163,18 @@ tusb_error_t mscd_control_request_st(uint8_t rhport, tusb_control_request_t cons { dcd_control_stall(rhport); // stall unsupported request } + return TUSB_ERROR_NONE; +} - OSAL_SUBTASK_END +// For backwards compatibility we support static block counts. +#if defined(CFG_TUD_MSC_BLOCK_NUM) && defined(CFG_TUD_MSC_BLOCK_SZ) +ATTR_WEAK bool tud_lun_capacity_cb(uint8_t lun, uint32_t* last_valid_sector, uint16_t* block_size) { + (void) lun; + *last_valid_sector = CFG_TUD_MSC_BLOCK_NUM-1; + *block_size = CFG_TUD_MSC_BLOCK_SZ; + return true; } +#endif // return length of response (copied to buffer), -1 if it is not an built-in commands int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize) @@ -202,11 +185,13 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf { case SCSI_CMD_READ_CAPACITY_10: { - scsi_read_capacity10_resp_t read_capa10 = - { - .last_lba = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM-1), // read capacity - .block_size = ENDIAN_BE(CFG_TUD_MSC_BLOCK_SZ) - }; + scsi_read_capacity10_resp_t read_capa10; + + uint32_t last_valid_sector; + uint16_t block_size; + tud_lun_capacity_cb(p_cbw->lun, &last_valid_sector, &block_size); + read_capa10.last_lba = ENDIAN_BE(last_valid_sector); // read capacity + read_capa10.block_size = ENDIAN_BE(block_size); ret = sizeof(read_capa10); memcpy(buffer, &read_capa10, ret); @@ -218,11 +203,17 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf scsi_read_format_capacity_data_t read_fmt_capa = { .list_length = 8, - .block_num = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM), // write capacity + .block_num = 0, .descriptor_type = 2, // formatted media - .block_size_u16 = ENDIAN_BE16(CFG_TUD_MSC_BLOCK_SZ) + .block_size_u16 = 0 }; + uint32_t last_valid_sector; + uint16_t block_size; + tud_lun_capacity_cb(p_cbw->lun, &last_valid_sector, &block_size); + read_fmt_capa.block_num = ENDIAN_BE(last_valid_sector+1); + read_fmt_capa.block_size_u16 = ENDIAN_BE16(block_size); + ret = sizeof(read_fmt_capa); memcpy(buffer, &read_fmt_capa, ret); } @@ -251,13 +242,21 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf case SCSI_CMD_MODE_SENSE_6: { - scsi_mode_sense6_resp_t const mode_resp = { - .data_len = 3, - .medium_type = 0, - .device_specific_para = 0, - .block_descriptor_len = 0 // no block descriptor are included + scsi_mode_sense6_resp_t mode_resp = + { + .data_len = 3, + .medium_type = 0, + .write_protected = false, + .reserved = 0, + .block_descriptor_len = 0 // no block descriptor are included }; + bool writable = true; + if (tud_msc_is_writable_cb) { + writable = tud_msc_is_writable_cb(p_cbw->lun); + } + mode_resp.write_protected = !writable; + ret = sizeof(mode_resp); memcpy(buffer, &mode_resp, ret); } @@ -291,7 +290,7 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf return ret; } -tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes) +tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, uint8_t event, uint32_t xferred_bytes) { mscd_interface_t* p_msc = &_mscd_itf; msc_cbw_t const * p_cbw = &p_msc->cbw; @@ -425,7 +424,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u }else { // Application consume less than what we got (including zero) - if ( nbytes < xferred_bytes ) + if ( nbytes < (int32_t) xferred_bytes ) { if ( nbytes > 0 ) { diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 8403dfed9..92ab4dde0 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -55,14 +55,6 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct"); #error MSC Device: Incorrect setting of MAX LUN #endif -#ifndef CFG_TUD_MSC_BLOCK_NUM - #error CFG_TUD_MSC_BLOCK_NUM must be defined -#endif - -#ifndef CFG_TUD_MSC_BLOCK_SZ - #error CFG_TUD_MSC_BLOCK_SZ must be defined -#endif - #ifndef CFG_TUD_MSC_BUFSIZE #error CFG_TUD_MSC_BUFSIZE must be defined, value of CFG_TUD_MSC_BLOCK_SZ should work well, the more the better #endif @@ -89,6 +81,32 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct"); extern "C" { #endif +typedef struct { + CFG_TUSB_MEM_ALIGN msc_cbw_t cbw; + +//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13UXX) +// uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member +//#endif + + CFG_TUSB_MEM_ALIGN msc_csw_t csw; + + uint8_t itf_num; + uint8_t ep_in; + uint8_t ep_out; + + // Bulk Only Transfer (BOT) Protocol + uint8_t stage; + uint32_t total_len; + uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage + + // Sense Response Data + uint8_t sense_key; + uint8_t add_sense_code; + uint8_t add_sense_qualifier; +}mscd_interface_t; + +extern mscd_interface_t _mscd_itf; + /** \addtogroup ClassDriver_MSC * @{ * \defgroup MSC_Device Device @@ -138,7 +156,7 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf * \retval negative Indicate error writing disk I/O. Tinyusb will \b STALL the corresponding * endpoint and return failed status in command status wrapper phase. */ -int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize); +int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize); /** * Callback invoked when received an SCSI command not in built-in list below. @@ -164,6 +182,12 @@ ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun); ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun); ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]); +// Hook to make a mass storage device read-only. +ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); + +// Override for dynamic LUN sizes. +ATTR_WEAK bool tud_lun_capacity_cb(uint8_t lun, uint32_t* last_valid_sector, uint16_t* block_size); + /** @} */ /** @} */ @@ -185,4 +209,3 @@ void mscd_reset(uint8_t rhport); #endif #endif /* _TUSB_MSC_DEVICE_H_ */ - diff --git a/src/device/dcd.h b/src/device/dcd.h index 87837df20..c1715a5b7 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -113,32 +113,13 @@ void dcd_disconnect (uint8_t rhport) ATTR_WEAK; void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event -static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) -{ - dcd_event_t event = { .rhport = 0, .event_id = eid, }; - dcd_event_handler(&event, in_isr); -} +void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); // helper to send setup received -static inline void dcd_event_setup_recieved(uint8_t rhport, uint8_t const * setup, bool in_isr) -{ - dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_SETUP_RECEIVED }; - memcpy(&event.setup_received, setup, 8); - - dcd_event_handler(&event, true); -} +void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); // helper to send transfer complete event -static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) -{ - dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_XFER_COMPLETE }; - - event.xfer_complete.ep_addr = ep_addr; - event.xfer_complete.len = xferred_bytes; - event.xfer_complete.result = result; - - dcd_event_handler(&event, in_isr); -} +void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); /*------------------------------------------------------------------*/ @@ -167,7 +148,7 @@ static inline bool dcd_control_status(uint8_t rhport, uint8_t dir) static inline void dcd_control_stall(uint8_t rhport) { - dcd_edpt_stall(rhport, 0); + dcd_edpt_stall(rhport, 0 | TUSB_DIR_IN_MASK); } #ifdef __cplusplus diff --git a/src/device/usbd.c b/src/device/usbd.c index 1c2fa5d5d..8155b585f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -239,25 +239,25 @@ void usbd_task( void* param) OSAL_TASK_END } +extern uint32_t setup_count; + static tusb_error_t usbd_main_st(void) { - static dcd_event_t event; - - OSAL_SUBTASK_BEGIN - + dcd_event_t event; + tusb_error_t err = TUSB_ERROR_NONE; // Loop until there is no more events in the queue - while (1) + while (_usbd_q->count > 0) { - uint32_t err; - - err = TUSB_ERROR_NONE; tu_memclr(&event, sizeof(dcd_event_t)); - osal_queue_receive(_usbd_q, &event, OSAL_TIMEOUT_WAIT_FOREVER, &err); + err = osal_queue_receive(_usbd_q, &event); + if (err != TUSB_ERROR_NONE) { + break; + } if ( DCD_EVENT_SETUP_RECEIVED == event.event_id ) { - STASK_INVOKE( proc_control_request_st(event.rhport, &event.setup_received), err ); + proc_control_request_st(event.rhport, &event.setup_received); } else if (DCD_EVENT_XFER_COMPLETE == event.event_id) { @@ -267,7 +267,7 @@ static tusb_error_t usbd_main_st(void) if (drv_id < USBD_CLASS_DRIVER_COUNT) { - usbd_class_drivers[drv_id].xfer_cb( event.rhport, ep_addr, (tusb_event_t) event.xfer_complete.result, event.xfer_complete.len); + usbd_class_drivers[drv_id].xfer_cb( event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); } } else if (DCD_EVENT_BUS_RESET == event.event_id) @@ -304,7 +304,7 @@ static tusb_error_t usbd_main_st(void) } } - OSAL_SUBTASK_END + return err; } //--------------------------------------------------------------------+ @@ -312,10 +312,7 @@ static tusb_error_t usbd_main_st(void) //--------------------------------------------------------------------+ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request_t const * const p_request) { - OSAL_SUBTASK_BEGIN - - ATTR_UNUSED tusb_error_t error; - error = TUSB_ERROR_NONE; + tusb_error_t error = TUSB_ERROR_NONE; //------------- Standard Request e.g in enumeration -------------// if( TUSB_REQ_RCPT_DEVICE == p_request->bmRequestType_bit.recipient && @@ -326,9 +323,10 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request uint8_t const * buffer = NULL; uint16_t const len = get_descriptor(rhport, p_request, &buffer); + if ( len ) { - STASK_ASSERT( len <= CFG_TUD_CTRL_BUFSIZE ); + TU_ASSERT( len <= CFG_TUD_CTRL_BUFSIZE ); memcpy(_usbd_ctrl_buf, buffer, len); usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, _usbd_ctrl_buf, len); }else @@ -365,7 +363,7 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request { if (_usbd_dev.itf2drv[ tu_u16_low(p_request->wIndex) ] < USBD_CLASS_DRIVER_COUNT) { - STASK_INVOKE( usbd_class_drivers[ _usbd_dev.itf2drv[ tu_u16_low(p_request->wIndex) ] ].control_req_st(rhport, p_request), error ); + error = usbd_class_drivers[ _usbd_dev.itf2drv[ tu_u16_low(p_request->wIndex) ] ].control_req_st(rhport, p_request); }else { dcd_control_stall(rhport); // Stall unsupported request @@ -406,8 +404,10 @@ static tusb_error_t proc_control_request_st(uint8_t rhport, tusb_control_request { dcd_control_stall(rhport); // Stall unsupported request } - - OSAL_SUBTASK_END + if (error != TUSB_ERROR_NONE) { + dcd_control_stall(rhport); // Stall errored requests + } + return error; } // Process Set Configure Request @@ -548,8 +548,6 @@ static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, ui //--------------------------------------------------------------------+ void dcd_event_handler(dcd_event_t const * event, bool in_isr) { - uint8_t const rhport = event->rhport; - switch (event->event_id) { case DCD_EVENT_BUS_RESET: @@ -590,9 +588,49 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) } } +void dcd_event_handler(dcd_event_t const * event, bool in_isr); + +// helper to send bus signal event +void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) +{ + dcd_event_t event = { .rhport = 0, .event_id = eid, }; + dcd_event_handler(&event, in_isr); +} + +// helper to send setup received +void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) +{ + dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_SETUP_RECEIVED }; + memcpy(&event.setup_received, setup, 8); + + dcd_event_handler(&event, true); +} + +// helper to send transfer complete event +void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) +{ + dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_XFER_COMPLETE }; + + event.xfer_complete.ep_addr = ep_addr; + event.xfer_complete.len = xferred_bytes; + event.xfer_complete.result = result; + + dcd_event_handler(&event, in_isr); +} + //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ +uint32_t usbd_control_xfer_st(uint8_t _rhport, uint8_t _dir, uint8_t* _buffer, uint16_t _len) { + uint32_t err = TUSB_ERROR_NONE; + if (_len) { + dcd_control_xfer(_rhport, _dir, (uint8_t*) _buffer, _len); + } + + dcd_control_status(_rhport, _dir); + return err; +} + tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) { for(int i=0; i<2; i++) diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 0b6b56d7d..ecb71f771 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -64,20 +64,7 @@ void usbd_task (void* param); // helper to parse an pair of In and Out endpoint descriptors. They must be consecutive tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); -// Carry out Data and Status stage of control transfer -// Must be call in a subtask (_st) function -#define usbd_control_xfer_st(_rhport, _dir, _buffer, _len) \ - do { \ - if (_len) { \ - uint32_t err; \ - dcd_control_xfer(_rhport, _dir, (uint8_t*) _buffer, _len); \ - osal_semaphore_wait( _usbd_ctrl_sem, OSAL_TIMEOUT_CONTROL_XFER, &err ); \ - STASK_ASSERT_ERR( err ); \ - } \ - dcd_control_status(_rhport, _dir); \ - /* No need to wait for status phase to complete */ \ - }while(0) - +uint32_t usbd_control_xfer_st(uint8_t _rhport, uint8_t _dir, uint8_t* _buffer, uint16_t _len); /*------------------------------------------------------------------*/ /* Other Helpers diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index ae988ec1f..f29759225 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -183,4 +183,3 @@ static inline void osal_queue_reset(osal_queue_t const queue_hdl) /** @} */ /** @} */ - diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 796ddc15f..6e67c8ea6 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -60,8 +60,6 @@ // // OSAL_TASK_LOOP_ENG // } -// -// NOTE: no switch statement is allowed in Task and subtask //--------------------------------------------------------------------+ #define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) osal_task_def_t _name; @@ -73,52 +71,8 @@ static inline bool osal_task_create(osal_task_def_t* taskdef) return true; } -#define TASK_RESTART \ - _state = 0 - -#define osal_task_delay(_msec) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if ( _timeout + (_msec) > tusb_hal_millis() ) \ - return TUSB_ERROR_OSAL_WAITING; \ - }while(0) - //--------------------------------------------------------------------+ -// SUBTASK (a sub function that uses OS blocking services & called by a task -//--------------------------------------------------------------------+ -#define OSAL_SUBTASK_BEGIN \ - static uint16_t _state = 0; \ - ATTR_UNUSED static uint32_t _timeout = 0; \ - (void) _timeout; \ - switch(_state) { \ - case 0: { - -#define OSAL_SUBTASK_END \ - default: TASK_RESTART; break; \ - }} \ - return TUSB_ERROR_NONE; - -#define STASK_INVOKE(_subtask, _status) \ - do { \ - _state = __LINE__; case __LINE__: \ - { \ - (_status) = _subtask; /* invoke sub task */ \ - if (TUSB_ERROR_OSAL_WAITING == (_status)) return TUSB_ERROR_OSAL_WAITING; \ - } \ - }while(0) - -//------------- Sub Task Assert -------------// -#define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0) - -#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR_HDLR(_err, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED) -#define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED ) - -#define STASK_ASSERT(_cond) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); TASK_RESTART, TUSB_ERROR_FAILED) -#define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, TU_BREAKPOINT(); _func; TASK_RESTART, TUSB_ERROR_FAILED) - -//--------------------------------------------------------------------+ -// Semaphore API +// Binary Semaphore API //--------------------------------------------------------------------+ typedef struct { @@ -135,7 +89,6 @@ static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semde static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { - (void) in_isr; sem_hdl->count++; return true; } @@ -145,22 +98,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) sem_hdl->count = 0; } -#define osal_semaphore_wait(_sem_hdl, _msec, _err) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if( (_sem_hdl)->count == 0 ) { \ - if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && (_timeout + (_msec) <= tusb_hal_millis()) ) \ - *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \ - else \ - return TUSB_ERROR_OSAL_WAITING; \ - } else{ \ - /* Enter critical ? */ \ - (_sem_hdl)->count--; \ - /* Exit critical ? */ \ - *(_err) = TUSB_ERROR_NONE; \ - } \ - }while(0) +static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { + (void) msec; + while (true) { + while (sem_hdl->count == 0) { + } + // tusb_hal_int_disable_all(); + if (sem_hdl->count == 0) { + sem_hdl->count--; + // tusb_hal_int_enable_all(); + break; + } + // tusb_hal_int_enable_all(); + } + return TUSB_ERROR_NONE; +} //--------------------------------------------------------------------+ // MUTEX API @@ -218,22 +170,13 @@ static inline void osal_queue_reset(osal_queue_t const queue_hdl) queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; } -#define osal_queue_receive(_q_hdl, p_data, _msec, _err) \ - do { \ - _timeout = tusb_hal_millis(); \ - _state = __LINE__; case __LINE__: \ - if( (_q_hdl)->count == 0 ) { \ - if ( ((_msec) != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + (_msec) <= tusb_hal_millis()) ) \ - *(_err) = TUSB_ERROR_OSAL_TIMEOUT; \ - else \ - return TUSB_ERROR_OSAL_WAITING; \ - } else{ \ - /* Enter critical ? */ \ - tu_fifo_read(_q_hdl, p_data); \ - /* Exit critical ? */ \ - *(_err) = TUSB_ERROR_NONE; \ - } \ - }while(0) +static inline tusb_error_t osal_queue_receive(osal_queue_t const queue_hdl, void* data) { + if (!tu_fifo_read(queue_hdl, data)) { + return TUSB_ERROR_OSAL_WAITING; + } + return TUSB_ERROR_NONE; +} + #ifdef __cplusplus } diff --git a/src/portable/microchip/samd21/dcd.c b/src/portable/microchip/samd21/dcd.c new file mode 100644 index 000000000..c9e88ad17 --- /dev/null +++ b/src/portable/microchip/samd21/dcd.c @@ -0,0 +1,341 @@ +/**************************************************************************/ +/*! + @file dcd_nrf5x.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Scott Shawcroft for Adafruit Industries + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMD51 + +#include "device/dcd.h" + +#include "device/usbd.h" +#include "device/usbd_pvt.h" // to use defer function helper + +#include "class/msc/msc_device.h" + +#include "sam.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +enum +{ + // Max allowed by USB specs + MAX_PACKET_SIZE = 64, +}; + +UsbDeviceDescBank sram_registers[8][2]; +ATTR_ALIGNED(4) uint8_t control_out_buffer[64]; +ATTR_ALIGNED(4) uint8_t control_in_buffer[64]; + +volatile uint32_t setup_count = 0; + +// Setup the control endpoint 0. +static void bus_reset(void) { + // Max size of packets is 64 bytes. + UsbDeviceDescBank* bank_out = &sram_registers[0][TUSB_DIR_OUT]; + bank_out->PCKSIZE.bit.SIZE = 0x3; + UsbDeviceDescBank* bank_in = &sram_registers[0][TUSB_DIR_IN]; + bank_in->PCKSIZE.bit.SIZE = 0x3; + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[0]; + ep->EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0x1) | USB_DEVICE_EPCFG_EPTYPE1(0x1); + ep->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1 | USB_DEVICE_EPINTENSET_RXSTP; + + dcd_edpt_xfer(0, 0, control_out_buffer, 64); + setup_count = 0; +} + + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +bool dcd_init (uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.DESCADD.reg = (uint32_t) &sram_registers; + USB->DEVICE.CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_FS; + USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE; + USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST; + + return true; +} + +void dcd_connect (uint8_t rhport) +{ + +} +void dcd_disconnect (uint8_t rhport) +{ + +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + dcd_edpt_xfer (0, TUSB_DIR_IN_MASK, NULL, 0); + // Wait for EP0 to finish before switching the address. + while (USB->DEVICE.DeviceEndpoint[0].EPSTATUS.bit.BK1RDY == 1) {} + USB->DEVICE.DADD.reg = USB_DEVICE_DADD_DADD(dev_addr) | USB_DEVICE_DADD_ADDEN; +} + +void dcd_set_config (uint8_t rhport, uint8_t config_num) +{ + (void) rhport; + (void) config_num; + // Nothing to do +} + +/*------------------------------------------------------------------*/ +/* Control + *------------------------------------------------------------------*/ + +bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length) +{ + (void) rhport; + uint8_t ep_addr = 0; + if (dir == TUSB_DIR_IN) { + ep_addr |= TUSB_DIR_IN_MASK; + } + + return dcd_edpt_xfer (rhport, ep_addr, buffer, length); +} + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress); + + UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; + uint32_t size_value = 0; + while (size_value < 7) { + if (1 << (size_value + 3) == desc_edpt->wMaxPacketSize.size) { + break; + } + size_value++; + } + bank->PCKSIZE.bit.SIZE = size_value; + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if ( dir == TUSB_DIR_OUT ) + { + ep->EPCFG.bit.EPTYPE0 = desc_edpt->bmAttributes.xfer + 1; + ep->EPINTENSET.bit.TRCPT0 = true; + }else + { + ep->EPCFG.bit.EPTYPE1 = desc_edpt->bmAttributes.xfer + 1; + ep->EPINTENSET.bit.TRCPT1 = true; + } + __ISB(); __DSB(); + + return true; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + uint8_t const dir = edpt_dir(ep_addr); + + UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + bank->ADDR.reg = (uint32_t) buffer; + if ( dir == TUSB_DIR_OUT ) + { + bank->PCKSIZE.bit.MULTI_PACKET_SIZE = total_bytes; + bank->PCKSIZE.bit.BYTE_COUNT = 0; + ep->EPSTATUSCLR.reg |= USB_DEVICE_EPSTATUSCLR_BK0RDY; + ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL0; + } else + { + bank->PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + bank->PCKSIZE.bit.BYTE_COUNT = total_bytes; + // bank->PCKSIZE.bit.AUTO_ZLP = 1; + ep->EPSTATUSSET.reg |= USB_DEVICE_EPSTATUSSET_BK1RDY; + ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL1; + } + + return true; +} + +bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // control is never got halted + if ( ep_addr == 0 ) { + return false; + } + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + return (edpt_dir(ep_addr) == TUSB_DIR_IN ) ? ep->EPINTFLAG.bit.STALL1 : ep->EPINTFLAG.bit.STALL0; +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + } else { + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + } + + __ISB(); __DSB(); +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; + } else { + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; + } +} + +bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // USBD shouldn't check control endpoint state + if ( 0 == ep_addr ) return false; + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (edpt_dir(ep_addr) == TUSB_DIR_IN) { + return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1; + } + return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1; +} + +/*------------------------------------------------------------------*/ + +static bool maybe_handle_setup_packet(void) { + if (USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP) + { + USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; + + // This copies the data elsewhere so we can reuse the buffer. + dcd_event_setup_received(0, (uint8_t*) sram_registers[0][0].ADDR.reg, true); + dcd_edpt_xfer(0, 0, control_out_buffer, 64); + setup_count += 1; + return true; + } + return false; +} + +void maybe_transfer_complete(void) { + uint32_t epints = USB->DEVICE.EPINTSMRY.reg; + for (uint8_t epnum = 0; epnum < USB_EPT_NUM; epnum++) { + if ((epints & (1 << epnum)) == 0) { + continue; + } + + if (maybe_handle_setup_packet()) { + continue; + } + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + uint32_t epintflag = ep->EPINTFLAG.reg; + + // Handle IN completions + if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT1) != 0) { + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + + UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_IN]; + uint16_t total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; + + uint8_t ep_addr = epnum | TUSB_DIR_IN_MASK; + dcd_event_xfer_complete(0, ep_addr, total_transfer_size, DCD_XFER_SUCCESS, true); + } + + // Handle OUT completions + if ((epintflag & USB_DEVICE_EPINTFLAG_TRCPT0) != 0) { + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + + UsbDeviceDescBank* bank = &sram_registers[epnum][TUSB_DIR_OUT]; + uint16_t total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; + + uint8_t ep_addr = epnum; + dcd_event_xfer_complete(0, ep_addr, total_transfer_size, DCD_XFER_SUCCESS, true); + if (epnum == 0) { + dcd_edpt_xfer(0, 0, control_out_buffer, 64); + } + } + } +} + +void USB_Handler(void) { + uint32_t int_status = USB->DEVICE.INTFLAG.reg; + + /*------------- Interrupt Processing -------------*/ + if ( int_status & USB_DEVICE_INTFLAG_EORST ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTENCLR_EORST; + bus_reset(); + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + } + + if ( int_status & USB_DEVICE_INTFLAG_SOF ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + } + + // Setup packet received. + maybe_handle_setup_packet(); + + // Handle complete transfer + maybe_transfer_complete(); +} + +#endif diff --git a/src/portable/microchip/samd21/hal.c b/src/portable/microchip/samd21/hal.c new file mode 100644 index 000000000..524840be2 --- /dev/null +++ b/src/portable/microchip/samd21/hal.c @@ -0,0 +1,82 @@ +/**************************************************************************/ +/*! + @file hal_nrf5x.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMD21 + +#include "sam.h" + +#include "tusb_hal.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +#define USB_NVIC_PRIO 7 + +void tusb_hal_nrf_power_event(uint32_t event); + +/*------------------------------------------------------------------*/ +/* TUSB HAL + *------------------------------------------------------------------*/ +bool tusb_hal_init(void) +{ + USB->DEVICE.PADCAL.bit.TRANSP = (*((uint32_t*) USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; + USB->DEVICE.PADCAL.bit.TRANSN = (*((uint32_t*) USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; + USB->DEVICE.PADCAL.bit.TRIM = (*((uint32_t*) USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; + + USB->DEVICE.QOSCTRL.bit.CQOS = USB_QOSCTRL_CQOS_HIGH_Val; + USB->DEVICE.QOSCTRL.bit.DQOS = USB_QOSCTRL_DQOS_HIGH_Val; + + tusb_hal_int_enable(0); + return true; +} + +void tusb_hal_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void tusb_hal_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +#endif diff --git a/src/portable/microchip/samd51/dcd.c b/src/portable/microchip/samd51/dcd.c new file mode 100644 index 000000000..e67fbd295 --- /dev/null +++ b/src/portable/microchip/samd51/dcd.c @@ -0,0 +1,360 @@ +/**************************************************************************/ +/*! + @file dcd_nrf5x.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, Scott Shawcroft for Adafruit Industries + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMD51 + +#include "device/dcd.h" + +#include "device/usbd.h" +#include "device/usbd_pvt.h" // to use defer function helper + +#include "sam.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +enum +{ + // Max allowed by USB specs + MAX_PACKET_SIZE = 64, +}; + +UsbDeviceDescBank sram_registers[8][2]; +ATTR_ALIGNED(4) uint8_t control_out_buffer[64]; +ATTR_ALIGNED(4) uint8_t control_in_buffer[64]; + +volatile uint32_t setup_count = 0; + +// Setup the control endpoint 0. +static void bus_reset(void) { + // Max size of packets is 64 bytes. + UsbDeviceDescBank* bank_out = &sram_registers[0][TUSB_DIR_OUT]; + bank_out->PCKSIZE.bit.SIZE = 0x3; + UsbDeviceDescBank* bank_in = &sram_registers[0][TUSB_DIR_IN]; + bank_in->PCKSIZE.bit.SIZE = 0x3; + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[0]; + ep->EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0x1) | USB_DEVICE_EPCFG_EPTYPE1(0x1); + ep->EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1 | USB_DEVICE_EPINTENSET_RXSTP; + + dcd_edpt_xfer(0, 0, control_out_buffer, 64); + setup_count = 0; +} + + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +bool dcd_init (uint8_t rhport) +{ + (void) rhport; + USB->DEVICE.DESCADD.reg = (uint32_t) &sram_registers; + USB->DEVICE.CTRLB.reg = USB_DEVICE_CTRLB_SPDCONF_FS; + USB->DEVICE.CTRLA.reg = USB_CTRLA_MODE_DEVICE | USB_CTRLA_ENABLE; + USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST; + + return true; +} + +void dcd_connect (uint8_t rhport) +{ + +} +void dcd_disconnect (uint8_t rhport) +{ + +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + dcd_edpt_xfer (0, TUSB_DIR_IN_MASK, NULL, 0); + // Wait for EP0 to finish before switching the address. + while (USB->DEVICE.DeviceEndpoint[0].EPSTATUS.bit.BK1RDY == 1) {} + USB->DEVICE.DADD.reg = USB_DEVICE_DADD_DADD(dev_addr) | USB_DEVICE_DADD_ADDEN; +} + +void dcd_set_config (uint8_t rhport, uint8_t config_num) +{ + (void) rhport; + (void) config_num; + // Nothing to do +} + +/*------------------------------------------------------------------*/ +/* Control + *------------------------------------------------------------------*/ + +bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length) +{ + (void) rhport; + uint8_t ep_addr = 0; + if (dir == TUSB_DIR_IN) { + ep_addr |= TUSB_DIR_IN_MASK; + } + + return dcd_edpt_xfer (rhport, ep_addr, buffer, length); +} + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress); + + UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; + uint32_t size_value = 0; + while (size_value < 7) { + if (1 << (size_value + 3) == desc_edpt->wMaxPacketSize.size) { + break; + } + size_value++; + } + bank->PCKSIZE.bit.SIZE = size_value; + + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if ( dir == TUSB_DIR_OUT ) + { + ep->EPCFG.bit.EPTYPE0 = desc_edpt->bmAttributes.xfer + 1; + ep->EPINTENSET.bit.TRCPT0 = true; + }else + { + ep->EPCFG.bit.EPTYPE1 = desc_edpt->bmAttributes.xfer + 1; + ep->EPINTENSET.bit.TRCPT1 = true; + } + __ISB(); __DSB(); + + return true; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + uint8_t const dir = edpt_dir(ep_addr); + + UsbDeviceDescBank* bank = &sram_registers[epnum][dir]; + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + bank->ADDR.reg = (uint32_t) buffer; + if ( dir == TUSB_DIR_OUT ) + { + bank->PCKSIZE.bit.MULTI_PACKET_SIZE = total_bytes; + bank->PCKSIZE.bit.BYTE_COUNT = 0; + ep->EPSTATUSCLR.reg |= USB_DEVICE_EPSTATUSCLR_BK0RDY; + ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL0; + } else + { + bank->PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + bank->PCKSIZE.bit.BYTE_COUNT = total_bytes; + ep->EPSTATUSSET.reg |= USB_DEVICE_EPSTATUSSET_BK1RDY; + ep->EPINTFLAG.reg |= USB_DEVICE_EPINTFLAG_TRFAIL1; + } + + return true; +} + +bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // control is never got halted + if ( ep_addr == 0 ) { + return false; + } + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + return (edpt_dir(ep_addr) == TUSB_DIR_IN ) ? ep->EPINTFLAG.bit.STALL1 : ep->EPINTFLAG.bit.STALL0; +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + } else { + ep->EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + } + + __ISB(); __DSB(); +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (edpt_dir(ep_addr) == TUSB_DIR_IN) { + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; + } else { + ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; + } +} + +bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // USBD shouldn't check control endpoint state + if ( 0 == ep_addr ) return false; + + uint8_t const epnum = edpt_number(ep_addr); + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + if (edpt_dir(ep_addr) == TUSB_DIR_IN) { + return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1; + } + return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1; +} + +/*------------------------------------------------------------------*/ + +static bool maybe_handle_setup_packet(void) { + if (USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP) + { + USB->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; + // uint8_t* buf = (uint8_t*) sram_registers[0][0].ADDR.reg; + // + // if (buf[6] == 0x12) asm("bkpt"); + // This copies the data elsewhere so we can reuse the buffer. + dcd_event_setup_received(0, (uint8_t*) sram_registers[0][0].ADDR.reg, true); + dcd_edpt_xfer(0, 0, control_out_buffer, 64); + setup_count += 1; + return true; + } + return false; +} +/* + *------------------------------------------------------------------*/ +/* USB_EORSM_DNRSM, USB_EORST_RST, USB_LPMSUSP_DDISC, USB_LPM_DCONN, +USB_MSOF, USB_RAMACER, USB_RXSTP_TXSTP_0, USB_RXSTP_TXSTP_1, +USB_RXSTP_TXSTP_2, USB_RXSTP_TXSTP_3, USB_RXSTP_TXSTP_4, +USB_RXSTP_TXSTP_5, USB_RXSTP_TXSTP_6, USB_RXSTP_TXSTP_7, +USB_STALL0_STALL_0, USB_STALL0_STALL_1, USB_STALL0_STALL_2, +USB_STALL0_STALL_3, USB_STALL0_STALL_4, USB_STALL0_STALL_5, +USB_STALL0_STALL_6, USB_STALL0_STALL_7, USB_STALL1_0, USB_STALL1_1, +USB_STALL1_2, USB_STALL1_3, USB_STALL1_4, USB_STALL1_5, USB_STALL1_6, +USB_STALL1_7, USB_SUSPEND, USB_TRFAIL0_TRFAIL_0, USB_TRFAIL0_TRFAIL_1, +USB_TRFAIL0_TRFAIL_2, USB_TRFAIL0_TRFAIL_3, USB_TRFAIL0_TRFAIL_4, +USB_TRFAIL0_TRFAIL_5, USB_TRFAIL0_TRFAIL_6, USB_TRFAIL0_TRFAIL_7, +USB_TRFAIL1_PERR_0, USB_TRFAIL1_PERR_1, USB_TRFAIL1_PERR_2, +USB_TRFAIL1_PERR_3, USB_TRFAIL1_PERR_4, USB_TRFAIL1_PERR_5, +USB_TRFAIL1_PERR_6, USB_TRFAIL1_PERR_7, USB_UPRSM, USB_WAKEUP */ +void USB_0_Handler(void) { + uint32_t int_status = USB->DEVICE.INTFLAG.reg; + + /*------------- Interrupt Processing -------------*/ + if ( int_status & USB_DEVICE_INTFLAG_EORST ) + { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTENCLR_EORST; + bus_reset(); + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + } + + // Setup packet received. + maybe_handle_setup_packet(); +} +/* USB_SOF_HSOF */ +void USB_1_Handler(void) { + USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); +} + +void transfer_complete(uint8_t direction) { + // uint8_t* buf = (uint8_t*) sram_registers[0][0].ADDR.reg; + // + // if (buf[6] == 0x12 || setup_count == 2) asm("bkpt"); + uint32_t epints = USB->DEVICE.EPINTSMRY.reg; + for (uint8_t epnum = 0; epnum < USB_EPT_NUM; epnum++) { + if ((epints & (1 << epnum)) == 0) { + continue; + } + + if (direction == TUSB_DIR_OUT && maybe_handle_setup_packet()) { + continue; + } + UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; + + UsbDeviceDescBank* bank = &sram_registers[epnum][direction]; + uint16_t total_transfer_size = bank->PCKSIZE.bit.BYTE_COUNT; + + uint8_t ep_addr = epnum; + if (direction == TUSB_DIR_IN) { + ep_addr |= TUSB_DIR_IN_MASK; + } + dcd_event_xfer_complete(0, ep_addr, total_transfer_size, DCD_XFER_SUCCESS, true); + if (epnum == 0 && direction == TUSB_DIR_OUT) { + dcd_edpt_xfer(0, 0, control_out_buffer, 64); + } + if (direction == TUSB_DIR_IN) { + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + } else { + ep->EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + } + } +} + +// Bank zero is for OUT and SETUP transactions. +/* USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2, +USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5, +USB_TRCPT0_6, USB_TRCPT0_7 */ +void USB_2_Handler(void) { + transfer_complete(TUSB_DIR_OUT); +} + +// Bank one is used for IN transactions. +/* USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2, +USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5, +USB_TRCPT1_6, USB_TRCPT1_7 */ +void USB_3_Handler(void) { + transfer_complete(TUSB_DIR_IN); +} + +#endif diff --git a/src/portable/microchip/samd51/hal.c b/src/portable/microchip/samd51/hal.c new file mode 100644 index 000000000..d8c71a7fe --- /dev/null +++ b/src/portable/microchip/samd51/hal.c @@ -0,0 +1,88 @@ +/**************************************************************************/ +/*! + @file hal_nrf5x.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, hathach (tinyusb.org) + 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. + + This file is part of the tinyusb stack. +*/ +/**************************************************************************/ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_SAMD51 + +#include "sam.h" + +#include "tusb_hal.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +#define USB_NVIC_PRIO 7 + +void tusb_hal_nrf_power_event(uint32_t event); + +/*------------------------------------------------------------------*/ +/* TUSB HAL + *------------------------------------------------------------------*/ +bool tusb_hal_init(void) +{ + USB->DEVICE.PADCAL.bit.TRANSP = (*((uint32_t*) USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; + USB->DEVICE.PADCAL.bit.TRANSN = (*((uint32_t*) USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; + USB->DEVICE.PADCAL.bit.TRIM = (*((uint32_t*) USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; + + USB->DEVICE.QOSCTRL.bit.CQOS = 3; + USB->DEVICE.QOSCTRL.bit.DQOS = 3; + + tusb_hal_int_enable(0); + return true; +} + +void tusb_hal_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_0_IRQn); + NVIC_EnableIRQ(USB_1_IRQn); + NVIC_EnableIRQ(USB_2_IRQn); + NVIC_EnableIRQ(USB_3_IRQn); +} + +void tusb_hal_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_3_IRQn); + NVIC_DisableIRQ(USB_2_IRQn); + NVIC_DisableIRQ(USB_1_IRQn); + NVIC_DisableIRQ(USB_0_IRQn); +} + +#endif diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 69e001240..7eeab1306 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -203,7 +203,9 @@ static void xact_control_start(void) bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t length) { + (void) rhport; + osal_semaphore_wait( _usbd_ctrl_sem, OSAL_TIMEOUT_CONTROL_XFER); if ( length ) { @@ -216,9 +218,11 @@ bool dcd_control_xfer (uint8_t rhport, uint8_t dir, uint8_t * buffer, uint16_t l xact_control_start(); }else { + NRF_USBD->EPIN[0].PTR = 0; + NRF_USBD->EPIN[0].MAXCNT = 0; // Status Phase also require Easy DMA has to be free as well !!!! - edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); - edpt_dma_end(); + NRF_USBD->TASKS_EP0STATUS = 1; + osal_semaphore_post(_usbd_ctrl_sem, false); } return true; @@ -434,7 +438,7 @@ void USBD_IRQHandler(void) NRF_USBD->BMREQUESTTYPE , NRF_USBD->BREQUEST, NRF_USBD->WVALUEL , NRF_USBD->WVALUEH, NRF_USBD->WINDEXL , NRF_USBD->WINDEXH , NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH }; - dcd_event_setup_recieved(0, setup, true); + dcd_event_setup_received(0, setup, true); } if ( int_status & USBD_INTEN_EP0DATADONE_Msk ) diff --git a/src/tusb_option.h b/src/tusb_option.h index 846367129..d7a6c6fe0 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -147,6 +147,8 @@ #ifndef CFG_TUD_ENUM_BUFFER_SIZE #define CFG_TUD_CTRL_BUFSIZE 256 + #else + #define CFG_TUD_CTRL_BUFSIZE CFG_TUD_ENUM_BUFFER_SIZE #endif #ifndef CFG_TUD_DESC_AUTO -- cgit v1.3.1 From 3fe7cd165902948240ecc40468b3610686f579c3 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Nov 2018 15:34:50 +0700 Subject: added tud_cdc_write_str, tu_fifo only use mutex for RTOS config --- examples/device/nrf52840/segger/SEGGER_RTT.c | 1329 -------------------- examples/device/nrf52840/segger/SEGGER_RTT.h | 234 ---- examples/device/nrf52840/segger/SEGGER_RTT_Conf.h | 242 ---- examples/device/nrf52840/segger/SEGGER_RTT_SES.c | 76 -- examples/device/nrf52840/segger/nrf52840.emProject | 12 +- examples/device/nrf52840/src/main.c | 83 +- .../device/nrf52840/src/segger_rtt/SEGGER_RTT.c | 1329 ++++++++++++++++++++ .../device/nrf52840/src/segger_rtt/SEGGER_RTT.h | 234 ++++ .../nrf52840/src/segger_rtt/SEGGER_RTT_Conf.h | 242 ++++ .../nrf52840/src/segger_rtt/SEGGER_RTT_SES.c | 76 ++ .../device/nrf52840_freertos/segger/SEGGER_RTT.c | 1329 -------------------- .../device/nrf52840_freertos/segger/SEGGER_RTT.h | 234 ---- .../nrf52840_freertos/segger/SEGGER_RTT_Conf.h | 242 ---- .../nrf52840_freertos/segger/SEGGER_RTT_SES.c | 76 -- .../segger/nrf5x_freertos.emProject | 12 +- examples/device/nrf52840_freertos/src/main.c | 26 +- .../nrf52840_freertos/src/segger_rtt/SEGGER_RTT.c | 1329 ++++++++++++++++++++ .../nrf52840_freertos/src/segger_rtt/SEGGER_RTT.h | 234 ++++ .../src/segger_rtt/SEGGER_RTT_Conf.h | 242 ++++ .../src/segger_rtt/SEGGER_RTT_SES.c | 76 ++ .../device/nrf52840_freertos/src/tusb_config.h | 2 +- hw/bsp/pca10056/board_pca10056.c | 5 + src/class/cdc/cdc_device.c | 13 +- src/class/cdc/cdc_device.h | 2 + src/common/tusb_fifo.c | 21 +- src/common/tusb_fifo.h | 4 +- src/osal/osal_none.h | 13 - 27 files changed, 3872 insertions(+), 3845 deletions(-) delete mode 100644 examples/device/nrf52840/segger/SEGGER_RTT.c delete mode 100644 examples/device/nrf52840/segger/SEGGER_RTT.h delete mode 100644 examples/device/nrf52840/segger/SEGGER_RTT_Conf.h delete mode 100644 examples/device/nrf52840/segger/SEGGER_RTT_SES.c create mode 100644 examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.c create mode 100644 examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.h create mode 100644 examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_Conf.h create mode 100644 examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_SES.c delete mode 100644 examples/device/nrf52840_freertos/segger/SEGGER_RTT.c delete mode 100644 examples/device/nrf52840_freertos/segger/SEGGER_RTT.h delete mode 100644 examples/device/nrf52840_freertos/segger/SEGGER_RTT_Conf.h delete mode 100644 examples/device/nrf52840_freertos/segger/SEGGER_RTT_SES.c create mode 100644 examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.c create mode 100644 examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.h create mode 100644 examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_Conf.h create mode 100644 examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_SES.c (limited to 'src/osal') diff --git a/examples/device/nrf52840/segger/SEGGER_RTT.c b/examples/device/nrf52840/segger/SEGGER_RTT.c deleted file mode 100644 index aee5bd21e..000000000 --- a/examples/device/nrf52840/segger/SEGGER_RTT.c +++ /dev/null @@ -1,1329 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 5.12e * -* * -********************************************************************** ----------------------------END-OF-HEADER------------------------------ -File : SEGGER_RTT.c -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support - debugger memory accesses while the CPU is running. - -Additional information: - Type "int" is assumed to be 32-bits in size - H->T Host to target communication - T->H Target to host communication - - RTT channel 0 is always present and reserved for Terminal usage. - Name is fixed to "Terminal" - - Effective buffer size: SizeOfBuffer - 1 - - WrOff == RdOff: Buffer is empty - WrOff == (RdOff - 1): Buffer is full - WrOff > RdOff: Free space includes wrap-around - WrOff < RdOff: Used space includes wrap-around - (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): - Buffer full and wrap-around after next byte - - ----------------------------------------------------------------------- -*/ - -#include "SEGGER_RTT.h" - -#include // for memcpy - -/********************************************************************* -* -* Configuration, default values -* -********************************************************************** -*/ - -#ifndef BUFFER_SIZE_UP - #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host -#endif - -#ifndef BUFFER_SIZE_DOWN - #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) -#endif - -#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS - #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target -#endif - -#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS - #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target -#endif - -#ifndef SEGGER_RTT_BUFFER_SECTION - #if defined SEGGER_RTT_SECTION - #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION - #endif -#endif - -#ifndef SEGGER_RTT_MODE_DEFAULT - #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP -#endif - -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK() -#endif - -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK() -#endif - -#ifndef STRLEN - #define STRLEN(a) strlen((a)) -#endif - -#ifndef MEMCPY - #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) -#endif - -#ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef MAX - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif -// -// For some environments, NULL may not be defined until certain headers are included -// -#ifndef NULL - #define NULL 0 -#endif - -/********************************************************************* -* -* Static const data -* -********************************************************************** -*/ - -static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - -/********************************************************************* -* -* Static data -* -********************************************************************** -*/ -// -// RTT Control Block and allocate buffers for channel 0 -// -#ifdef SEGGER_RTT_SECTION - #if (defined __GNUC__) - __attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT; - #elif (defined __ICCARM__) || (defined __ICCRX__) - #pragma location=SEGGER_RTT_SECTION - SEGGER_RTT_CB _SEGGER_RTT; - #elif (defined __CC_ARM__) - __attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT; - #else - SEGGER_RTT_CB _SEGGER_RTT; - #endif -#else - SEGGER_RTT_CB _SEGGER_RTT; -#endif - -#ifdef SEGGER_RTT_BUFFER_SECTION - #if (defined __GNUC__) - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP]; - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #elif (defined __ICCARM__) || (defined __ICCRX__) - #pragma location=SEGGER_RTT_BUFFER_SECTION - static char _acUpBuffer [BUFFER_SIZE_UP]; - #pragma location=SEGGER_RTT_BUFFER_SECTION - static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #elif (defined __CC_ARM__) - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP]; - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #else - static char _acUpBuffer [BUFFER_SIZE_UP]; - static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #endif -#else - static char _acUpBuffer [BUFFER_SIZE_UP]; - static char _acDownBuffer[BUFFER_SIZE_DOWN]; -#endif - -static char _ActiveTerminal; - -/********************************************************************* -* -* Static functions -* -********************************************************************** -*/ - -/********************************************************************* -* -* _DoInit() -* -* Function description -* Initializes the control block an buffers. -* May only be called via INIT() to avoid overriding settings. -* -*/ -#define INIT() do { \ - if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ - } while (0) -static void _DoInit(void) { - SEGGER_RTT_CB* p; - // - // Initialize control block - // - p = &_SEGGER_RTT; - p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; - p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; - // - // Initialize up buffer 0 - // - p->aUp[0].sName = "Terminal"; - p->aUp[0].pBuffer = _acUpBuffer; - p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); - p->aUp[0].RdOff = 0u; - p->aUp[0].WrOff = 0u; - p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; - // - // Initialize down buffer 0 - // - p->aDown[0].sName = "Terminal"; - p->aDown[0].pBuffer = _acDownBuffer; - p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); - p->aDown[0].RdOff = 0u; - p->aDown[0].WrOff = 0u; - p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; - // - // Finish initialization of the control block. - // Copy Id string in three steps to make sure "SEGGER RTT" is not found - // in initializer memory (usually flash) by J-Link - // - strcpy(&p->acID[7], "RTT"); - strcpy(&p->acID[0], "SEGGER"); - p->acID[6] = ' '; -} - -/********************************************************************* -* -* _WriteBlocking() -* -* Function description -* Stores a specified number of characters in SEGGER RTT ring buffer -* and updates the associated write pointer which is periodically -* read by the host. -* The caller is responsible for managing the write chunk sizes as -* _WriteBlocking() will block until all data has been posted successfully. -* -* Parameters -* pRing Ring buffer to post to. -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* >= 0 - Number of bytes written into buffer. -*/ -static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { - unsigned NumBytesToWrite; - unsigned NumBytesWritten; - unsigned RdOff; - unsigned WrOff; - // - // Write data to buffer and handle wrap-around if necessary - // - NumBytesWritten = 0u; - WrOff = pRing->WrOff; - do { - RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime - if (RdOff > WrOff) { - NumBytesToWrite = RdOff - WrOff - 1u; - } else { - NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); - } - NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around - NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); - memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); - NumBytesWritten += NumBytesToWrite; - pBuffer += NumBytesToWrite; - NumBytes -= NumBytesToWrite; - WrOff += NumBytesToWrite; - if (WrOff == pRing->SizeOfBuffer) { - WrOff = 0u; - } - pRing->WrOff = WrOff; - } while (NumBytes); - // - return NumBytesWritten; -} - -/********************************************************************* -* -* _WriteNoCheck() -* -* Function description -* Stores a specified number of characters in SEGGER RTT ring buffer -* and updates the associated write pointer which is periodically -* read by the host. -* It is callers responsibility to make sure data actually fits in buffer. -* -* Parameters -* pRing Ring buffer to post to. -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Notes -* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking -*/ -static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { - unsigned NumBytesAtOnce; - unsigned WrOff; - unsigned Rem; - - WrOff = pRing->WrOff; - Rem = pRing->SizeOfBuffer - WrOff; - if (Rem > NumBytes) { - // - // All data fits before wrap around - // - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - } else { - // - // We reach the end of the buffer, so need to wrap around - // - NumBytesAtOnce = Rem; - memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); - NumBytesAtOnce = NumBytes - Rem; - memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); - pRing->WrOff = NumBytesAtOnce; - } -} - -/********************************************************************* -* -* _PostTerminalSwitch() -* -* Function description -* Switch terminal to the given terminal ID. It is the caller's -* responsibility to ensure the terminal ID is correct and there is -* enough space in the buffer for this to complete successfully. -* -* Parameters -* pRing Ring buffer to post to. -* TerminalId Terminal ID to switch to. -*/ -static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { - char ac[2]; - - ac[0] = 0xFFu; - ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit - _WriteBlocking(pRing, ac, 2u); -} - -/********************************************************************* -* -* _GetAvailWriteSpace() -* -* Function description -* Returns the number of bytes that can be written to the ring -* buffer without blocking. -* -* Parameters -* pRing Ring buffer to check. -* -* Return value -* Number of bytes that are free in the buffer. -*/ -static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { - unsigned RdOff; - unsigned WrOff; - unsigned r; - // - // Avoid warnings regarding volatile access order. It's not a problem - // in this case, but dampen compiler enthusiasm. - // - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - if (RdOff <= WrOff) { - r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; - } else { - r = RdOff - WrOff - 1u; - } - return r; -} - -/********************************************************************* -* -* Public code -* -********************************************************************** -*/ -/********************************************************************* -* -* SEGGER_RTT_ReadNoLock() -* -* Function description -* Reads characters from SEGGER real-time-terminal control block -* which have been previously stored by the host. -* Do not lock against interrupts and multiple access. -* -* Parameters -* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. -* BufferSize Size of the target application buffer. -* -* Return value -* Number of bytes that have been read. -*/ -unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { - unsigned NumBytesRem; - unsigned NumBytesRead; - unsigned RdOff; - unsigned WrOff; - unsigned char* pBuffer; - SEGGER_RTT_BUFFER_DOWN* pRing; - // - INIT(); - pRing = &_SEGGER_RTT.aDown[BufferIndex]; - pBuffer = (unsigned char*)pData; - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - NumBytesRead = 0u; - // - // Read from current read position to wrap-around of buffer, first - // - if (RdOff > WrOff) { - NumBytesRem = pRing->SizeOfBuffer - RdOff; - NumBytesRem = MIN(NumBytesRem, BufferSize); - memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); - NumBytesRead += NumBytesRem; - pBuffer += NumBytesRem; - BufferSize -= NumBytesRem; - RdOff += NumBytesRem; - // - // Handle wrap-around of buffer - // - if (RdOff == pRing->SizeOfBuffer) { - RdOff = 0u; - } - } - // - // Read remaining items of buffer - // - NumBytesRem = WrOff - RdOff; - NumBytesRem = MIN(NumBytesRem, BufferSize); - if (NumBytesRem > 0u) { - memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); - NumBytesRead += NumBytesRem; - pBuffer += NumBytesRem; - BufferSize -= NumBytesRem; - RdOff += NumBytesRem; - } - if (NumBytesRead) { - pRing->RdOff = RdOff; - } - // - return NumBytesRead; -} - -/********************************************************************* -* -* SEGGER_RTT_Read -* -* Function description -* Reads characters from SEGGER real-time-terminal control block -* which have been previously stored by the host. -* -* Parameters -* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. -* BufferSize Size of the target application buffer. -* -* Return value -* Number of bytes that have been read. -*/ -unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { - unsigned NumBytesRead; - // - SEGGER_RTT_LOCK(); - // - // Call the non-locking read function - // - NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - // - return NumBytesRead; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteWithOverwriteNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block. -* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application -* and overwrites data if the data does not fit into the buffer. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, data is overwritten. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link -* connection reads RTT data. -*/ -void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer and copy some elements into local variables. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - // - // Check if we will overwrite data and need to adjust the RdOff. - // - if (pRing->WrOff == pRing->RdOff) { - Avail = pRing->SizeOfBuffer - 1u; - } else if ( pRing->WrOff < pRing->RdOff) { - Avail = pRing->RdOff - pRing->WrOff - 1u; - } else { - Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; - } - if (NumBytes > Avail) { - pRing->RdOff += (NumBytes - Avail); - while (pRing->RdOff >= pRing->SizeOfBuffer) { - pRing->RdOff -= pRing->SizeOfBuffer; - } - } - // - // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds - // - Avail = pRing->SizeOfBuffer - pRing->WrOff; - do { - if (Avail > NumBytes) { - // - // Last round - // -#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. - char* pDst; - pDst = pRing->pBuffer + pRing->WrOff; - pRing->WrOff += NumBytes; - do { - *pDst++ = *pData++; - } while (--NumBytes); -#else - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff += NumBytes; -#endif - break; //Alternatively: NumBytes = 0; - } else { - // - // Wrap-around necessary, write until wrap-around and reset WrOff - // - memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail); - pData += Avail; - pRing->WrOff = 0; - NumBytes -= Avail; - Avail = (pRing->SizeOfBuffer - 1); - } - } while (NumBytes); -} - -/********************************************************************* -* -* SEGGER_RTT_WriteSkipNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* SEGGER_RTT_WriteSkipNoLock does not lock the application and -* skips all data, if the data does not fit into the buffer. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, all data is dropped. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -*/ -unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - unsigned RdOff; - unsigned WrOff; - unsigned Rem; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer and copy some elements into local variables. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - // - // Handle the most common cases fastest. - // Which is: - // RdOff <= WrOff -> Space until wrap around is free. - // AND - // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. - // - // OR - // - // RdOff > WrOff -> Space until RdOff - 1 is free. - // AND - // WrOff + NumBytes < RdOff -> Data fits into buffer - // - if (RdOff <= WrOff) { - // - // Get space until WrOff will be at wrap around. - // - Avail = pRing->SizeOfBuffer - 1u - WrOff ; - if (Avail >= NumBytes) { -#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. - char* pDst; - pDst = pRing->pBuffer + WrOff; - WrOff += NumBytes; - do { - *pDst++ = *pData++; - } while (--NumBytes); - pRing->WrOff = WrOff + NumBytes; -#else - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; -#endif - return 1; - } - // - // If data did not fit into space until wrap around calculate complete space in buffer. - // - Avail += RdOff; - // - // If there is still no space for the whole of this output, don't bother. - // - if (Avail >= NumBytes) { - // - // OK, we have enough space in buffer. Copy in one or 2 chunks - // - Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer - if (Rem > NumBytes) { - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - } else { - // - // We reach the end of the buffer, so need to wrap around - // - memcpy(pRing->pBuffer + WrOff, pData, Rem); - memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); - pRing->WrOff = NumBytes - Rem; - } - return 1; - } - } else { - Avail = RdOff - WrOff - 1u; - if (Avail >= NumBytes) { - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - return 1; - } - } - // - // If we reach this point no data has been written - // - return 0; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* SEGGER_RTT_WriteNoLock does not lock the application. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -*/ -unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - unsigned Status; - unsigned Avail; - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - // - // How we output depends upon the mode... - // - switch (pRing->Flags) { - case SEGGER_RTT_MODE_NO_BLOCK_SKIP: - // - // If we are in skip mode and there is no space for the whole - // of this output, don't bother. - // - Avail = _GetAvailWriteSpace(pRing); - if (Avail < NumBytes) { - Status = 0u; - } else { - Status = NumBytes; - _WriteNoCheck(pRing, pData, NumBytes); - } - break; - case SEGGER_RTT_MODE_NO_BLOCK_TRIM: - // - // If we are in trim mode, trim to what we can output without blocking. - // - Avail = _GetAvailWriteSpace(pRing); - Status = Avail < NumBytes ? Avail : NumBytes; - _WriteNoCheck(pRing, pData, Status); - break; - case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: - // - // If we are in blocking mode, output everything. - // - Status = _WriteBlocking(pRing, pData, NumBytes); - break; - default: - Status = 0u; - break; - } - // - // Finish up. - // - return Status; -} - -/********************************************************************* -* -* SEGGER_RTT_Write -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. -*/ -unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - unsigned Status; - // - INIT(); - SEGGER_RTT_LOCK(); - // - // Call the non-locking write function - // - Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - // - return Status; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteString -* -* Function description -* Stores string in SEGGER RTT control block. -* This data is read by the host. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* s Pointer to string. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, depending on configuration, -* remaining characters may be dropped or RTT module waits until there is more space in the buffer. -* (2) String passed to this function has to be \0 terminated -* (3) \0 termination character is *not* stored in RTT buffer -*/ -unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { - unsigned Len; - - Len = STRLEN(s); - return SEGGER_RTT_Write(BufferIndex, s, Len); -} - -/********************************************************************* -* -* SEGGER_RTT_GetKey -* -* Function description -* Reads one character from the SEGGER RTT buffer. -* Host has previously stored data there. -* -* Return value -* < 0 - No character available (buffer empty). -* >= 0 - Character which has been read. (Possible values: 0 - 255) -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0. -*/ -int SEGGER_RTT_GetKey(void) { - char c; - int r; - - r = (int)SEGGER_RTT_Read(0u, &c, 1u); - if (r == 1) { - r = (int)(unsigned char)c; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_WaitKey -* -* Function description -* Waits until at least one character is avaible in the SEGGER RTT buffer. -* Once a character is available, it is read and this function returns. -* -* Return value -* >=0 - Character which has been read. -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0 -* (2) This function is blocking if no character is present in RTT buffer -*/ -int SEGGER_RTT_WaitKey(void) { - int r; - - do { - r = SEGGER_RTT_GetKey(); - } while (r < 0); - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_HasKey -* -* Function description -* Checks if at least one character for reading is available in the SEGGER RTT buffer. -* -* Return value -* == 0 - No characters are available to read. -* == 1 - At least one character is available. -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0 -*/ -int SEGGER_RTT_HasKey(void) { - unsigned RdOff; - int r; - - INIT(); - RdOff = _SEGGER_RTT.aDown[0].RdOff; - if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { - r = 1; - } else { - r = 0; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_HasData -* -* Function description -* Check if there is data from the host in the given buffer. -* -* Return value: -* ==0: No data -* !=0: Data in buffer -* -*/ -unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { - SEGGER_RTT_BUFFER_DOWN* pRing; - unsigned v; - - pRing = &_SEGGER_RTT.aDown[BufferIndex]; - v = pRing->WrOff; - return v - pRing->RdOff; -} - -/********************************************************************* -* -* SEGGER_RTT_AllocDownBuffer -* -* Function description -* Run-time configuration of the next down-buffer (H->T). -* The next buffer, which is not used yet is configured. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. Buffer Index -* < 0 - Error -*/ -int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int BufferIndex; - - INIT(); - SEGGER_RTT_LOCK(); - BufferIndex = 0; - do { - if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { - break; - } - BufferIndex++; - } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); - if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - } else { - BufferIndex = -1; - } - SEGGER_RTT_UNLOCK(); - return BufferIndex; -} - -/********************************************************************* -* -* SEGGER_RTT_AllocUpBuffer -* -* Function description -* Run-time configuration of the next up-buffer (T->H). -* The next buffer, which is not used yet is configured. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. Buffer Index -* < 0 - Error -*/ -int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int BufferIndex; - - INIT(); - SEGGER_RTT_LOCK(); - BufferIndex = 0; - do { - if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { - break; - } - BufferIndex++; - } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); - if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - } else { - BufferIndex = -1; - } - SEGGER_RTT_UNLOCK(); - return BufferIndex; -} - -/********************************************************************* -* -* SEGGER_RTT_ConfigUpBuffer -* -* Function description -* Run-time configuration of a specific up-buffer (T->H). -* Buffer to be configured is specified by index. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* BufferIndex Index of the buffer to configure. -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. -* < 0 - Error -*/ -int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; - } - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_ConfigDownBuffer -* -* Function description -* Run-time configuration of a specific down-buffer (H->T). -* Buffer to be configured is specified by index. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* BufferIndex Index of the buffer to configure. -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; - } - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetNameUpBuffer -* -* Function description -* Run-time configuration of a specific up-buffer name (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* sName Pointer to a constant name string. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetNameDownBuffer -* -* Function description -* Run-time configuration of a specific Down-buffer name (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* sName Pointer to a constant name string. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_Init -* -* Function description -* Initializes the RTT Control Block. -* Should be used in RAM targets, at start of the application. -* -*/ -void SEGGER_RTT_Init (void) { - _DoInit(); -} - -/********************************************************************* -* -* SEGGER_RTT_SetTerminal -* -* Function description -* Sets the terminal to be used for output on channel 0. -* -* Parameters -* TerminalId Index of the terminal. -* -* Return value -* >= 0 O.K. -* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) -*/ -int SEGGER_RTT_SetTerminal (char TerminalId) { - char ac[2]; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - int r; - // - INIT(); - // - r = 0; - ac[0] = 0xFFU; - if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels - ac[1] = _aTerminalId[(unsigned char)TerminalId]; - pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed - SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing - if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { - _ActiveTerminal = TerminalId; - _WriteBlocking(pRing, ac, 2u); - } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes - Avail = _GetAvailWriteSpace(pRing); - if (Avail >= 2) { - _ActiveTerminal = TerminalId; // Only change active terminal in case of success - _WriteNoCheck(pRing, ac, 2u); - } else { - r = -1; - } - } - SEGGER_RTT_UNLOCK(); - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_TerminalOut -* -* Function description -* Writes a string to the given terminal -* without changing the terminal for channel 0. -* -* Parameters -* TerminalId Index of the terminal. -* s String to be printed on the terminal. -* -* Return value -* >= 0 - Number of bytes written. -* < 0 - Error. -* -*/ -int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { - int Status; - unsigned FragLen; - unsigned Avail; - SEGGER_RTT_BUFFER_UP* pRing; - // - INIT(); - // - // Validate terminal ID. - // - if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels - // - // Get "to-host" ring buffer. - // - pRing = &_SEGGER_RTT.aUp[0]; - // - // Need to be able to change terminal, write data, change back. - // Compute the fixed and variable sizes. - // - FragLen = strlen(s); - // - // How we output depends upon the mode... - // - SEGGER_RTT_LOCK(); - Avail = _GetAvailWriteSpace(pRing); - switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { - case SEGGER_RTT_MODE_NO_BLOCK_SKIP: - // - // If we are in skip mode and there is no space for the whole - // of this output, don't bother switching terminals at all. - // - if (Avail < (FragLen + 4u)) { - Status = 0; - } else { - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, FragLen); - _PostTerminalSwitch(pRing, _ActiveTerminal); - } - break; - case SEGGER_RTT_MODE_NO_BLOCK_TRIM: - // - // If we are in trim mode and there is not enough space for everything, - // trim the output but always include the terminal switch. If no room - // for terminal switch, skip that totally. - // - if (Avail < 4u) { - Status = -1; - } else { - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); - _PostTerminalSwitch(pRing, _ActiveTerminal); - } - break; - case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: - // - // If we are in blocking mode, output everything. - // - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, FragLen); - _PostTerminalSwitch(pRing, _ActiveTerminal); - break; - default: - Status = -1; - break; - } - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - } else { - Status = -1; - } - return Status; -} - - -/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840/segger/SEGGER_RTT.h b/examples/device/nrf52840/segger/SEGGER_RTT.h deleted file mode 100644 index d3cac44dd..000000000 --- a/examples/device/nrf52840/segger/SEGGER_RTT.h +++ /dev/null @@ -1,234 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 5.12e * -* * -********************************************************************** ----------------------------END-OF-HEADER------------------------------ -File : SEGGER_RTT.h -Purpose : Implementation of SEGGER real-time transfer which allows - real-time communication on targets which support debugger - memory accesses while the CPU is running. ----------------------------------------------------------------------- -*/ - -#ifndef SEGGER_RTT_H -#define SEGGER_RTT_H - -#include "SEGGER_RTT_Conf.h" - -/********************************************************************* -* -* Defines, fixed -* -********************************************************************** -*/ - -/********************************************************************* -* -* Types -* -********************************************************************** -*/ - -// -// Description for a circular buffer (also called "ring buffer") -// which is used as up-buffer (T->H) -// -typedef struct { - const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" - char* pBuffer; // Pointer to start of buffer - unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. - unsigned WrOff; // Position of next item to be written by either target. - volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. - unsigned Flags; // Contains configuration flags -} SEGGER_RTT_BUFFER_UP; - -// -// Description for a circular buffer (also called "ring buffer") -// which is used as down-buffer (H->T) -// -typedef struct { - const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" - char* pBuffer; // Pointer to start of buffer - unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. - volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. - unsigned RdOff; // Position of next item to be read by target (down-buffer). - unsigned Flags; // Contains configuration flags -} SEGGER_RTT_BUFFER_DOWN; - -// -// RTT control block which describes the number of buffers available -// as well as the configuration for each buffer -// -// -typedef struct { - char acID[16]; // Initialized to "SEGGER RTT" - int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) - int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) - SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host - SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target -} SEGGER_RTT_CB; - -/********************************************************************* -* -* Global data -* -********************************************************************** -*/ -extern SEGGER_RTT_CB _SEGGER_RTT; - -/********************************************************************* -* -* RTT API functions -* -********************************************************************** -*/ -#ifdef __cplusplus - extern "C" { -#endif -int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_GetKey (void); -unsigned SEGGER_RTT_HasData (unsigned BufferIndex); -int SEGGER_RTT_HasKey (void); -void SEGGER_RTT_Init (void); -unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); -unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); -int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName); -int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); -int SEGGER_RTT_WaitKey (void); -unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); -void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -// -// Function macro for performance optimization -// -#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) - -/********************************************************************* -* -* RTT "Terminal" API functions -* -********************************************************************** -*/ -int SEGGER_RTT_SetTerminal (char TerminalId); -int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); - -/********************************************************************* -* -* RTT printf functions (require SEGGER_RTT_printf.c) -* -********************************************************************** -*/ -int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); -#ifdef __cplusplus - } -#endif - -/********************************************************************* -* -* Defines -* -********************************************************************** -*/ - -// -// Operating modes. Define behavior if buffer is full (not enough space for entire message) -// -#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) -#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. -#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. -#define SEGGER_RTT_MODE_MASK (3U) - -// -// Control sequences, based on ANSI. -// Can be used to control color, and clear the screen -// -#define RTT_CTRL_RESET "" // Reset to default colors -#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left - -#define RTT_CTRL_TEXT_BLACK "" -#define RTT_CTRL_TEXT_RED "" -#define RTT_CTRL_TEXT_GREEN "" -#define RTT_CTRL_TEXT_YELLOW "" -#define RTT_CTRL_TEXT_BLUE "" -#define RTT_CTRL_TEXT_MAGENTA "" -#define RTT_CTRL_TEXT_CYAN "" -#define RTT_CTRL_TEXT_WHITE "" - -#define RTT_CTRL_TEXT_BRIGHT_BLACK "" -#define RTT_CTRL_TEXT_BRIGHT_RED "" -#define RTT_CTRL_TEXT_BRIGHT_GREEN "" -#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" -#define RTT_CTRL_TEXT_BRIGHT_BLUE "" -#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" -#define RTT_CTRL_TEXT_BRIGHT_CYAN "" -#define RTT_CTRL_TEXT_BRIGHT_WHITE "" - -#define RTT_CTRL_BG_BLACK "" -#define RTT_CTRL_BG_RED "" -#define RTT_CTRL_BG_GREEN "" -#define RTT_CTRL_BG_YELLOW "" -#define RTT_CTRL_BG_BLUE "" -#define RTT_CTRL_BG_MAGENTA "" -#define RTT_CTRL_BG_CYAN "" -#define RTT_CTRL_BG_WHITE "" - -#define RTT_CTRL_BG_BRIGHT_BLACK "" -#define RTT_CTRL_BG_BRIGHT_RED "" -#define RTT_CTRL_BG_BRIGHT_GREEN "" -#define RTT_CTRL_BG_BRIGHT_YELLOW "" -#define RTT_CTRL_BG_BRIGHT_BLUE "" -#define RTT_CTRL_BG_BRIGHT_MAGENTA "" -#define RTT_CTRL_BG_BRIGHT_CYAN "" -#define RTT_CTRL_BG_BRIGHT_WHITE "" - - -#endif - -/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840/segger/SEGGER_RTT_Conf.h b/examples/device/nrf52840/segger/SEGGER_RTT_Conf.h deleted file mode 100644 index aef3b4053..000000000 --- a/examples/device/nrf52840/segger/SEGGER_RTT_Conf.h +++ /dev/null @@ -1,242 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 5.12e * -* * -********************************************************************** ----------------------------------------------------------------------- -File : SEGGER_RTT_Conf.h -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support - debugger memory accesses while the CPU is running. ----------------------------END-OF-HEADER------------------------------ -*/ - -#ifndef SEGGER_RTT_CONF_H -#define SEGGER_RTT_CONF_H - -#ifdef __ICCARM__ - #include -#endif - -/********************************************************************* -* -* Defines, configurable -* -********************************************************************** -*/ - -#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) -#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) - -#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) -#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) - -#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) - -#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) - -// -// Target is not allowed to perform other RTT operations while string still has not been stored completely. -// Otherwise we would probably end up with a mixed string in the buffer. -// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. -// -// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. -// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. -// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. -// (Higher priority = lower priority number) -// Default value for embOS: 128u -// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) -// In case of doubt mask all interrupts: 0u -// - -#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) - -/********************************************************************* -* -* RTT lock configuration for SEGGER Embedded Studio, -* Rowley CrossStudio and GCC -*/ -#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) - #ifdef __ARM_ARCH_6M__ - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs %0, primask \n\t" \ - "mov r1, $1 \n\t" \ - "msr primask, r1 \n\t" \ - : "=r" (LockState) \ - : \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ - : \ - : "r" (LockState) \ - : \ - ); \ - } - - #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs %0, basepri \n\t" \ - "mov r1, %1 \n\t" \ - "msr basepri, r1 \n\t" \ - : "=r" (LockState) \ - : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ - : \ - : "r" (LockState) \ - : \ - ); \ - } - - #elif defined(__ARM_ARCH_7A__) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs r1, CPSR \n\t" \ - "mov %0, r1 \n\t" \ - "orr r1, r1, #0xC0 \n\t" \ - "msr CPSR_c, r1 \n\t" \ - : "=r" (LockState) \ - : \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ - "mrs r1, CPSR \n\t" \ - "bic r1, r1, #0xC0 \n\t" \ - "and r0, r0, #0xC0 \n\t" \ - "orr r1, r1, r0 \n\t" \ - "msr CPSR_c, r1 \n\t" \ - : \ - : "r" (LockState) \ - : "r0", "r1" \ - ); \ - } -#else - #define SEGGER_RTT_LOCK() - #define SEGGER_RTT_UNLOCK() - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for IAR EWARM -*/ -#ifdef __ICCARM__ - #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - LockState = __get_PRIMASK(); \ - __set_PRIMASK(1); - - #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ - } - #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - LockState = __get_BASEPRI(); \ - __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); - - #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ - } - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for KEIL ARM -*/ -#ifdef __CC_ARM - #if (defined __TARGET_ARCH_6S_M) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - register unsigned char PRIMASK __asm( "primask"); \ - LockState = PRIMASK; \ - PRIMASK = 1u; \ - __schedule_barrier(); - - #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ - __schedule_barrier(); \ - } - #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - register unsigned char BASEPRI __asm( "basepri"); \ - LockState = BASEPRI; \ - BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ - __schedule_barrier(); - - #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ - __schedule_barrier(); \ - } - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration fallback -*/ -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) -#endif - -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) -#endif - -#endif -/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840/segger/SEGGER_RTT_SES.c b/examples/device/nrf52840/segger/SEGGER_RTT_SES.c deleted file mode 100644 index e6634147c..000000000 --- a/examples/device/nrf52840/segger/SEGGER_RTT_SES.c +++ /dev/null @@ -1,76 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** --------- END-OF-HEADER --------------------------------------------- -File : SEGGER_RTT_Syscalls_SES.c -Purpose : Reimplementation of printf, puts and - implementation of __putchar and __getchar using RTT in SES. - To use RTT for printf output, include this file in your - application. ----------------------------------------------------------------------- -*/ -#include "SEGGER_RTT.h" -#include "__libc.h" -#include -#include - -int printf(const char *fmt,...) { - char buffer[128]; - va_list args; - va_start (args, fmt); - int n = vsnprintf(buffer, sizeof(buffer), fmt, args); - SEGGER_RTT_Write(0, buffer, n); - va_end(args); - return n; -} - -int puts(const char *s) { - return SEGGER_RTT_WriteString(0, s); -} - -int __putchar(int x, __printf_tag_ptr ctx) { - (void)ctx; - SEGGER_RTT_Write(0, (char *)&x, 1); - return x; -} - -int __getchar() { - return SEGGER_RTT_WaitKey(); -} - -/****** End Of File *************************************************/ diff --git a/examples/device/nrf52840/segger/nrf52840.emProject b/examples/device/nrf52840/segger/nrf52840.emProject index 8775d1bca..5851c33d6 100644 --- a/examples/device/nrf52840/segger/nrf52840.emProject +++ b/examples/device/nrf52840/segger/nrf52840.emProject @@ -32,12 +32,6 @@ target_reset_script="Reset();" target_script_file="$(ProjectDir)/nRF_Target.js" target_trace_initialize_script="EnableTrace("$(TraceInterfaceType)")" /> - - - - - - @@ -61,6 +55,12 @@ + + + + + + diff --git a/examples/device/nrf52840/src/main.c b/examples/device/nrf52840/src/main.c index 58ac1ad21..11b73ebf9 100644 --- a/examples/device/nrf52840/src/main.c +++ b/examples/device/nrf52840/src/main.c @@ -55,56 +55,51 @@ //--------------------------------------------------------------------+ void print_greeting(void); void led_blinking_task(void); -void virtual_com_task(void); -void usb_hid_task(void); - -/*------------- MAIN -------------*/ -int main(void) -{ - board_init(); - print_greeting(); - - tusb_init(); - - while (1) - { - tusb_task(); - - led_blinking_task(); - virtual_com_task(); - - usb_hid_task(); - } - - return 0; -} //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ +#if CFG_TUD_CDC void virtual_com_task(void) { -#if CFG_TUD_CDC // connected and there are data available - if ( tud_mounted() && tud_cdc_available() ) + if ( tud_cdc_connected() ) { - uint8_t buf[64]; + if ( tud_cdc_available() ) + { + uint8_t buf[64]; + + // read and echo back + uint32_t count = tud_cdc_read(buf, sizeof(buf)); - // read and echo back - uint32_t count = tud_cdc_read(buf, sizeof(buf)); + tud_cdc_write(buf, count); + } - tud_cdc_write(buf, count); tud_cdc_write_flush(); } -#endif } +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) +{ + (void) itf; + + // connected + if ( dtr && rts ) + { + // print greeting + tud_cdc_write_str("tinyusb usb cdc\n"); + } +} +#else +#define virtual_com_task() +#endif + //--------------------------------------------------------------------+ // USB HID //--------------------------------------------------------------------+ +#if CFG_TUD_HID void usb_hid_task(void) { -#if CFG_TUD_HID // Poll every 10ms static tu_timeout_t tm = { .start = 0, .interval = 10 }; @@ -144,10 +139,8 @@ void usb_hid_task(void) if ( btn & 0x04 ) tud_hid_mouse_move( 0 , -DELTA); // up if ( btn & 0x08 ) tud_hid_mouse_move( 0 , DELTA); // down } -#endif } -#if CFG_TUD_HID uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented @@ -158,8 +151,32 @@ void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_t { // TODO not Implemented } + +#else +#define usb_hid_task() #endif + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + print_greeting(); + + tusb_init(); + + while (1) + { + tusb_task(); + + led_blinking_task(); + virtual_com_task(); + usb_hid_task(); + } + + return 0; +} + //--------------------------------------------------------------------+ // tinyusb callbacks //--------------------------------------------------------------------+ diff --git a/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.c b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.c new file mode 100644 index 000000000..aee5bd21e --- /dev/null +++ b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.c @@ -0,0 +1,1329 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 5.12e * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined SEGGER_RTT_SECTION + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef MEMCPY + #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +#ifdef SEGGER_RTT_SECTION + #if (defined __GNUC__) + __attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT; + #elif (defined __ICCARM__) || (defined __ICCRX__) + #pragma location=SEGGER_RTT_SECTION + SEGGER_RTT_CB _SEGGER_RTT; + #elif (defined __CC_ARM__) + __attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT; + #else + SEGGER_RTT_CB _SEGGER_RTT; + #endif +#else + SEGGER_RTT_CB _SEGGER_RTT; +#endif + +#ifdef SEGGER_RTT_BUFFER_SECTION + #if (defined __GNUC__) + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP]; + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #elif (defined __ICCARM__) || (defined __ICCRX__) + #pragma location=SEGGER_RTT_BUFFER_SECTION + static char _acUpBuffer [BUFFER_SIZE_UP]; + #pragma location=SEGGER_RTT_BUFFER_SECTION + static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #elif (defined __CC_ARM__) + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP]; + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #else + static char _acUpBuffer [BUFFER_SIZE_UP]; + static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #endif +#else + static char _acUpBuffer [BUFFER_SIZE_UP]; + static char _acDownBuffer[BUFFER_SIZE_DOWN]; +#endif + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + NumBytesAtOnce = Rem; + memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. + char* pDst; + pDst = pRing->pBuffer + pRing->WrOff; + pRing->WrOff += NumBytes; + do { + *pDst++ = *pData++; + } while (--NumBytes); +#else + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; //Alternatively: NumBytes = 0; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // + memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { +#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. + char* pDst; + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + do { + *pDst++ = *pData++; + } while (--NumBytes); + pRing->WrOff = WrOff + NumBytes; +#else + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, Rem); + memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, depending on configuration, +* remaining characters may be dropped or RTT module waits until there is more space in the buffer. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFU; + if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(unsigned char)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = strlen(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + + +/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.h b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.h new file mode 100644 index 000000000..d3cac44dd --- /dev/null +++ b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT.h @@ -0,0 +1,234 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 5.12e * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); +#ifdef __cplusplus + } +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "" // Reset to default colors +#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "" +#define RTT_CTRL_TEXT_RED "" +#define RTT_CTRL_TEXT_GREEN "" +#define RTT_CTRL_TEXT_YELLOW "" +#define RTT_CTRL_TEXT_BLUE "" +#define RTT_CTRL_TEXT_MAGENTA "" +#define RTT_CTRL_TEXT_CYAN "" +#define RTT_CTRL_TEXT_WHITE "" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "" +#define RTT_CTRL_TEXT_BRIGHT_RED "" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + +#define RTT_CTRL_BG_BLACK "" +#define RTT_CTRL_BG_RED "" +#define RTT_CTRL_BG_GREEN "" +#define RTT_CTRL_BG_YELLOW "" +#define RTT_CTRL_BG_BLUE "" +#define RTT_CTRL_BG_MAGENTA "" +#define RTT_CTRL_BG_CYAN "" +#define RTT_CTRL_BG_WHITE "" + +#define RTT_CTRL_BG_BRIGHT_BLACK "" +#define RTT_CTRL_BG_BRIGHT_RED "" +#define RTT_CTRL_BG_BRIGHT_GREEN "" +#define RTT_CTRL_BG_BRIGHT_YELLOW "" +#define RTT_CTRL_BG_BRIGHT_BLUE "" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "" +#define RTT_CTRL_BG_BRIGHT_CYAN "" +#define RTT_CTRL_BG_BRIGHT_WHITE "" + + +#endif + +/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_Conf.h b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_Conf.h new file mode 100644 index 000000000..aef3b4053 --- /dev/null +++ b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_Conf.h @@ -0,0 +1,242 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 5.12e * +* * +********************************************************************** +---------------------------------------------------------------------- +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __ICCARM__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 0u +// + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } +#else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_SES.c b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_SES.c new file mode 100644 index 000000000..e6634147c --- /dev/null +++ b/examples/device/nrf52840/src/segger_rtt/SEGGER_RTT_SES.c @@ -0,0 +1,76 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +-------- END-OF-HEADER --------------------------------------------- +File : SEGGER_RTT_Syscalls_SES.c +Purpose : Reimplementation of printf, puts and + implementation of __putchar and __getchar using RTT in SES. + To use RTT for printf output, include this file in your + application. +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "__libc.h" +#include +#include + +int printf(const char *fmt,...) { + char buffer[128]; + va_list args; + va_start (args, fmt); + int n = vsnprintf(buffer, sizeof(buffer), fmt, args); + SEGGER_RTT_Write(0, buffer, n); + va_end(args); + return n; +} + +int puts(const char *s) { + return SEGGER_RTT_WriteString(0, s); +} + +int __putchar(int x, __printf_tag_ptr ctx) { + (void)ctx; + SEGGER_RTT_Write(0, (char *)&x, 1); + return x; +} + +int __getchar() { + return SEGGER_RTT_WaitKey(); +} + +/****** End Of File *************************************************/ diff --git a/examples/device/nrf52840_freertos/segger/SEGGER_RTT.c b/examples/device/nrf52840_freertos/segger/SEGGER_RTT.c deleted file mode 100644 index aee5bd21e..000000000 --- a/examples/device/nrf52840_freertos/segger/SEGGER_RTT.c +++ /dev/null @@ -1,1329 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 5.12e * -* * -********************************************************************** ----------------------------END-OF-HEADER------------------------------ -File : SEGGER_RTT.c -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support - debugger memory accesses while the CPU is running. - -Additional information: - Type "int" is assumed to be 32-bits in size - H->T Host to target communication - T->H Target to host communication - - RTT channel 0 is always present and reserved for Terminal usage. - Name is fixed to "Terminal" - - Effective buffer size: SizeOfBuffer - 1 - - WrOff == RdOff: Buffer is empty - WrOff == (RdOff - 1): Buffer is full - WrOff > RdOff: Free space includes wrap-around - WrOff < RdOff: Used space includes wrap-around - (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): - Buffer full and wrap-around after next byte - - ----------------------------------------------------------------------- -*/ - -#include "SEGGER_RTT.h" - -#include // for memcpy - -/********************************************************************* -* -* Configuration, default values -* -********************************************************************** -*/ - -#ifndef BUFFER_SIZE_UP - #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host -#endif - -#ifndef BUFFER_SIZE_DOWN - #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) -#endif - -#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS - #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target -#endif - -#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS - #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target -#endif - -#ifndef SEGGER_RTT_BUFFER_SECTION - #if defined SEGGER_RTT_SECTION - #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION - #endif -#endif - -#ifndef SEGGER_RTT_MODE_DEFAULT - #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP -#endif - -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK() -#endif - -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK() -#endif - -#ifndef STRLEN - #define STRLEN(a) strlen((a)) -#endif - -#ifndef MEMCPY - #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) -#endif - -#ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef MAX - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif -// -// For some environments, NULL may not be defined until certain headers are included -// -#ifndef NULL - #define NULL 0 -#endif - -/********************************************************************* -* -* Static const data -* -********************************************************************** -*/ - -static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - -/********************************************************************* -* -* Static data -* -********************************************************************** -*/ -// -// RTT Control Block and allocate buffers for channel 0 -// -#ifdef SEGGER_RTT_SECTION - #if (defined __GNUC__) - __attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT; - #elif (defined __ICCARM__) || (defined __ICCRX__) - #pragma location=SEGGER_RTT_SECTION - SEGGER_RTT_CB _SEGGER_RTT; - #elif (defined __CC_ARM__) - __attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT; - #else - SEGGER_RTT_CB _SEGGER_RTT; - #endif -#else - SEGGER_RTT_CB _SEGGER_RTT; -#endif - -#ifdef SEGGER_RTT_BUFFER_SECTION - #if (defined __GNUC__) - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP]; - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #elif (defined __ICCARM__) || (defined __ICCRX__) - #pragma location=SEGGER_RTT_BUFFER_SECTION - static char _acUpBuffer [BUFFER_SIZE_UP]; - #pragma location=SEGGER_RTT_BUFFER_SECTION - static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #elif (defined __CC_ARM__) - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP]; - __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #else - static char _acUpBuffer [BUFFER_SIZE_UP]; - static char _acDownBuffer[BUFFER_SIZE_DOWN]; - #endif -#else - static char _acUpBuffer [BUFFER_SIZE_UP]; - static char _acDownBuffer[BUFFER_SIZE_DOWN]; -#endif - -static char _ActiveTerminal; - -/********************************************************************* -* -* Static functions -* -********************************************************************** -*/ - -/********************************************************************* -* -* _DoInit() -* -* Function description -* Initializes the control block an buffers. -* May only be called via INIT() to avoid overriding settings. -* -*/ -#define INIT() do { \ - if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ - } while (0) -static void _DoInit(void) { - SEGGER_RTT_CB* p; - // - // Initialize control block - // - p = &_SEGGER_RTT; - p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; - p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; - // - // Initialize up buffer 0 - // - p->aUp[0].sName = "Terminal"; - p->aUp[0].pBuffer = _acUpBuffer; - p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); - p->aUp[0].RdOff = 0u; - p->aUp[0].WrOff = 0u; - p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; - // - // Initialize down buffer 0 - // - p->aDown[0].sName = "Terminal"; - p->aDown[0].pBuffer = _acDownBuffer; - p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); - p->aDown[0].RdOff = 0u; - p->aDown[0].WrOff = 0u; - p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; - // - // Finish initialization of the control block. - // Copy Id string in three steps to make sure "SEGGER RTT" is not found - // in initializer memory (usually flash) by J-Link - // - strcpy(&p->acID[7], "RTT"); - strcpy(&p->acID[0], "SEGGER"); - p->acID[6] = ' '; -} - -/********************************************************************* -* -* _WriteBlocking() -* -* Function description -* Stores a specified number of characters in SEGGER RTT ring buffer -* and updates the associated write pointer which is periodically -* read by the host. -* The caller is responsible for managing the write chunk sizes as -* _WriteBlocking() will block until all data has been posted successfully. -* -* Parameters -* pRing Ring buffer to post to. -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* >= 0 - Number of bytes written into buffer. -*/ -static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { - unsigned NumBytesToWrite; - unsigned NumBytesWritten; - unsigned RdOff; - unsigned WrOff; - // - // Write data to buffer and handle wrap-around if necessary - // - NumBytesWritten = 0u; - WrOff = pRing->WrOff; - do { - RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime - if (RdOff > WrOff) { - NumBytesToWrite = RdOff - WrOff - 1u; - } else { - NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); - } - NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around - NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); - memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); - NumBytesWritten += NumBytesToWrite; - pBuffer += NumBytesToWrite; - NumBytes -= NumBytesToWrite; - WrOff += NumBytesToWrite; - if (WrOff == pRing->SizeOfBuffer) { - WrOff = 0u; - } - pRing->WrOff = WrOff; - } while (NumBytes); - // - return NumBytesWritten; -} - -/********************************************************************* -* -* _WriteNoCheck() -* -* Function description -* Stores a specified number of characters in SEGGER RTT ring buffer -* and updates the associated write pointer which is periodically -* read by the host. -* It is callers responsibility to make sure data actually fits in buffer. -* -* Parameters -* pRing Ring buffer to post to. -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Notes -* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking -*/ -static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { - unsigned NumBytesAtOnce; - unsigned WrOff; - unsigned Rem; - - WrOff = pRing->WrOff; - Rem = pRing->SizeOfBuffer - WrOff; - if (Rem > NumBytes) { - // - // All data fits before wrap around - // - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - } else { - // - // We reach the end of the buffer, so need to wrap around - // - NumBytesAtOnce = Rem; - memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); - NumBytesAtOnce = NumBytes - Rem; - memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); - pRing->WrOff = NumBytesAtOnce; - } -} - -/********************************************************************* -* -* _PostTerminalSwitch() -* -* Function description -* Switch terminal to the given terminal ID. It is the caller's -* responsibility to ensure the terminal ID is correct and there is -* enough space in the buffer for this to complete successfully. -* -* Parameters -* pRing Ring buffer to post to. -* TerminalId Terminal ID to switch to. -*/ -static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { - char ac[2]; - - ac[0] = 0xFFu; - ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit - _WriteBlocking(pRing, ac, 2u); -} - -/********************************************************************* -* -* _GetAvailWriteSpace() -* -* Function description -* Returns the number of bytes that can be written to the ring -* buffer without blocking. -* -* Parameters -* pRing Ring buffer to check. -* -* Return value -* Number of bytes that are free in the buffer. -*/ -static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { - unsigned RdOff; - unsigned WrOff; - unsigned r; - // - // Avoid warnings regarding volatile access order. It's not a problem - // in this case, but dampen compiler enthusiasm. - // - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - if (RdOff <= WrOff) { - r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; - } else { - r = RdOff - WrOff - 1u; - } - return r; -} - -/********************************************************************* -* -* Public code -* -********************************************************************** -*/ -/********************************************************************* -* -* SEGGER_RTT_ReadNoLock() -* -* Function description -* Reads characters from SEGGER real-time-terminal control block -* which have been previously stored by the host. -* Do not lock against interrupts and multiple access. -* -* Parameters -* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. -* BufferSize Size of the target application buffer. -* -* Return value -* Number of bytes that have been read. -*/ -unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { - unsigned NumBytesRem; - unsigned NumBytesRead; - unsigned RdOff; - unsigned WrOff; - unsigned char* pBuffer; - SEGGER_RTT_BUFFER_DOWN* pRing; - // - INIT(); - pRing = &_SEGGER_RTT.aDown[BufferIndex]; - pBuffer = (unsigned char*)pData; - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - NumBytesRead = 0u; - // - // Read from current read position to wrap-around of buffer, first - // - if (RdOff > WrOff) { - NumBytesRem = pRing->SizeOfBuffer - RdOff; - NumBytesRem = MIN(NumBytesRem, BufferSize); - memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); - NumBytesRead += NumBytesRem; - pBuffer += NumBytesRem; - BufferSize -= NumBytesRem; - RdOff += NumBytesRem; - // - // Handle wrap-around of buffer - // - if (RdOff == pRing->SizeOfBuffer) { - RdOff = 0u; - } - } - // - // Read remaining items of buffer - // - NumBytesRem = WrOff - RdOff; - NumBytesRem = MIN(NumBytesRem, BufferSize); - if (NumBytesRem > 0u) { - memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); - NumBytesRead += NumBytesRem; - pBuffer += NumBytesRem; - BufferSize -= NumBytesRem; - RdOff += NumBytesRem; - } - if (NumBytesRead) { - pRing->RdOff = RdOff; - } - // - return NumBytesRead; -} - -/********************************************************************* -* -* SEGGER_RTT_Read -* -* Function description -* Reads characters from SEGGER real-time-terminal control block -* which have been previously stored by the host. -* -* Parameters -* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. -* BufferSize Size of the target application buffer. -* -* Return value -* Number of bytes that have been read. -*/ -unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { - unsigned NumBytesRead; - // - SEGGER_RTT_LOCK(); - // - // Call the non-locking read function - // - NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - // - return NumBytesRead; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteWithOverwriteNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block. -* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application -* and overwrites data if the data does not fit into the buffer. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, data is overwritten. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link -* connection reads RTT data. -*/ -void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer and copy some elements into local variables. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - // - // Check if we will overwrite data and need to adjust the RdOff. - // - if (pRing->WrOff == pRing->RdOff) { - Avail = pRing->SizeOfBuffer - 1u; - } else if ( pRing->WrOff < pRing->RdOff) { - Avail = pRing->RdOff - pRing->WrOff - 1u; - } else { - Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; - } - if (NumBytes > Avail) { - pRing->RdOff += (NumBytes - Avail); - while (pRing->RdOff >= pRing->SizeOfBuffer) { - pRing->RdOff -= pRing->SizeOfBuffer; - } - } - // - // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds - // - Avail = pRing->SizeOfBuffer - pRing->WrOff; - do { - if (Avail > NumBytes) { - // - // Last round - // -#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. - char* pDst; - pDst = pRing->pBuffer + pRing->WrOff; - pRing->WrOff += NumBytes; - do { - *pDst++ = *pData++; - } while (--NumBytes); -#else - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff += NumBytes; -#endif - break; //Alternatively: NumBytes = 0; - } else { - // - // Wrap-around necessary, write until wrap-around and reset WrOff - // - memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail); - pData += Avail; - pRing->WrOff = 0; - NumBytes -= Avail; - Avail = (pRing->SizeOfBuffer - 1); - } - } while (NumBytes); -} - -/********************************************************************* -* -* SEGGER_RTT_WriteSkipNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* SEGGER_RTT_WriteSkipNoLock does not lock the application and -* skips all data, if the data does not fit into the buffer. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, all data is dropped. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -*/ -unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - unsigned RdOff; - unsigned WrOff; - unsigned Rem; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer and copy some elements into local variables. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - RdOff = pRing->RdOff; - WrOff = pRing->WrOff; - // - // Handle the most common cases fastest. - // Which is: - // RdOff <= WrOff -> Space until wrap around is free. - // AND - // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. - // - // OR - // - // RdOff > WrOff -> Space until RdOff - 1 is free. - // AND - // WrOff + NumBytes < RdOff -> Data fits into buffer - // - if (RdOff <= WrOff) { - // - // Get space until WrOff will be at wrap around. - // - Avail = pRing->SizeOfBuffer - 1u - WrOff ; - if (Avail >= NumBytes) { -#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. - char* pDst; - pDst = pRing->pBuffer + WrOff; - WrOff += NumBytes; - do { - *pDst++ = *pData++; - } while (--NumBytes); - pRing->WrOff = WrOff + NumBytes; -#else - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; -#endif - return 1; - } - // - // If data did not fit into space until wrap around calculate complete space in buffer. - // - Avail += RdOff; - // - // If there is still no space for the whole of this output, don't bother. - // - if (Avail >= NumBytes) { - // - // OK, we have enough space in buffer. Copy in one or 2 chunks - // - Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer - if (Rem > NumBytes) { - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - } else { - // - // We reach the end of the buffer, so need to wrap around - // - memcpy(pRing->pBuffer + WrOff, pData, Rem); - memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); - pRing->WrOff = NumBytes - Rem; - } - return 1; - } - } else { - Avail = RdOff - WrOff - 1u; - if (Avail >= NumBytes) { - memcpy(pRing->pBuffer + WrOff, pData, NumBytes); - pRing->WrOff = WrOff + NumBytes; - return 1; - } - } - // - // If we reach this point no data has been written - // - return 0; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteNoLock -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* SEGGER_RTT_WriteNoLock does not lock the application. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. -* (2) For performance reasons this function does not call Init() -* and may only be called after RTT has been initialized. -* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. -*/ -unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - unsigned Status; - unsigned Avail; - const char* pData; - SEGGER_RTT_BUFFER_UP* pRing; - - pData = (const char *)pBuffer; - // - // Get "to-host" ring buffer. - // - pRing = &_SEGGER_RTT.aUp[BufferIndex]; - // - // How we output depends upon the mode... - // - switch (pRing->Flags) { - case SEGGER_RTT_MODE_NO_BLOCK_SKIP: - // - // If we are in skip mode and there is no space for the whole - // of this output, don't bother. - // - Avail = _GetAvailWriteSpace(pRing); - if (Avail < NumBytes) { - Status = 0u; - } else { - Status = NumBytes; - _WriteNoCheck(pRing, pData, NumBytes); - } - break; - case SEGGER_RTT_MODE_NO_BLOCK_TRIM: - // - // If we are in trim mode, trim to what we can output without blocking. - // - Avail = _GetAvailWriteSpace(pRing); - Status = Avail < NumBytes ? Avail : NumBytes; - _WriteNoCheck(pRing, pData, Status); - break; - case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: - // - // If we are in blocking mode, output everything. - // - Status = _WriteBlocking(pRing, pData, NumBytes); - break; - default: - Status = 0u; - break; - } - // - // Finish up. - // - return Status; -} - -/********************************************************************* -* -* SEGGER_RTT_Write -* -* Function description -* Stores a specified number of characters in SEGGER RTT -* control block which is then read by the host. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. -* NumBytes Number of bytes to be stored in the SEGGER RTT control block. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. -*/ -unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { - unsigned Status; - // - INIT(); - SEGGER_RTT_LOCK(); - // - // Call the non-locking write function - // - Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - // - return Status; -} - -/********************************************************************* -* -* SEGGER_RTT_WriteString -* -* Function description -* Stores string in SEGGER RTT control block. -* This data is read by the host. -* -* Parameters -* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). -* s Pointer to string. -* -* Return value -* Number of bytes which have been stored in the "Up"-buffer. -* -* Notes -* (1) If there is not enough space in the "Up"-buffer, depending on configuration, -* remaining characters may be dropped or RTT module waits until there is more space in the buffer. -* (2) String passed to this function has to be \0 terminated -* (3) \0 termination character is *not* stored in RTT buffer -*/ -unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { - unsigned Len; - - Len = STRLEN(s); - return SEGGER_RTT_Write(BufferIndex, s, Len); -} - -/********************************************************************* -* -* SEGGER_RTT_GetKey -* -* Function description -* Reads one character from the SEGGER RTT buffer. -* Host has previously stored data there. -* -* Return value -* < 0 - No character available (buffer empty). -* >= 0 - Character which has been read. (Possible values: 0 - 255) -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0. -*/ -int SEGGER_RTT_GetKey(void) { - char c; - int r; - - r = (int)SEGGER_RTT_Read(0u, &c, 1u); - if (r == 1) { - r = (int)(unsigned char)c; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_WaitKey -* -* Function description -* Waits until at least one character is avaible in the SEGGER RTT buffer. -* Once a character is available, it is read and this function returns. -* -* Return value -* >=0 - Character which has been read. -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0 -* (2) This function is blocking if no character is present in RTT buffer -*/ -int SEGGER_RTT_WaitKey(void) { - int r; - - do { - r = SEGGER_RTT_GetKey(); - } while (r < 0); - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_HasKey -* -* Function description -* Checks if at least one character for reading is available in the SEGGER RTT buffer. -* -* Return value -* == 0 - No characters are available to read. -* == 1 - At least one character is available. -* -* Notes -* (1) This function is only specified for accesses to RTT buffer 0 -*/ -int SEGGER_RTT_HasKey(void) { - unsigned RdOff; - int r; - - INIT(); - RdOff = _SEGGER_RTT.aDown[0].RdOff; - if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { - r = 1; - } else { - r = 0; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_HasData -* -* Function description -* Check if there is data from the host in the given buffer. -* -* Return value: -* ==0: No data -* !=0: Data in buffer -* -*/ -unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { - SEGGER_RTT_BUFFER_DOWN* pRing; - unsigned v; - - pRing = &_SEGGER_RTT.aDown[BufferIndex]; - v = pRing->WrOff; - return v - pRing->RdOff; -} - -/********************************************************************* -* -* SEGGER_RTT_AllocDownBuffer -* -* Function description -* Run-time configuration of the next down-buffer (H->T). -* The next buffer, which is not used yet is configured. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. Buffer Index -* < 0 - Error -*/ -int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int BufferIndex; - - INIT(); - SEGGER_RTT_LOCK(); - BufferIndex = 0; - do { - if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { - break; - } - BufferIndex++; - } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); - if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - } else { - BufferIndex = -1; - } - SEGGER_RTT_UNLOCK(); - return BufferIndex; -} - -/********************************************************************* -* -* SEGGER_RTT_AllocUpBuffer -* -* Function description -* Run-time configuration of the next up-buffer (T->H). -* The next buffer, which is not used yet is configured. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. Buffer Index -* < 0 - Error -*/ -int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int BufferIndex; - - INIT(); - SEGGER_RTT_LOCK(); - BufferIndex = 0; - do { - if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { - break; - } - BufferIndex++; - } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); - if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - } else { - BufferIndex = -1; - } - SEGGER_RTT_UNLOCK(); - return BufferIndex; -} - -/********************************************************************* -* -* SEGGER_RTT_ConfigUpBuffer -* -* Function description -* Run-time configuration of a specific up-buffer (T->H). -* Buffer to be configured is specified by index. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* BufferIndex Index of the buffer to configure. -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 - O.K. -* < 0 - Error -*/ -int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; - } - _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_ConfigDownBuffer -* -* Function description -* Run-time configuration of a specific down-buffer (H->T). -* Buffer to be configured is specified by index. -* This includes: Buffer address, size, name, flags, ... -* -* Parameters -* BufferIndex Index of the buffer to configure. -* sName Pointer to a constant name string. -* pBuffer Pointer to a buffer to be used. -* BufferSize Size of the buffer. -* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - if (BufferIndex > 0u) { - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; - _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; - _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; - _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; - } - _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetNameUpBuffer -* -* Function description -* Run-time configuration of a specific up-buffer name (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* sName Pointer to a constant name string. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aUp[BufferIndex].sName = sName; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_SetNameDownBuffer -* -* Function description -* Run-time configuration of a specific Down-buffer name (T->H). -* Buffer to be configured is specified by index. -* -* Parameters -* BufferIndex Index of the buffer to renamed. -* sName Pointer to a constant name string. -* -* Return value -* >= 0 O.K. -* < 0 Error -*/ -int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { - int r; - - INIT(); - if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { - SEGGER_RTT_LOCK(); - _SEGGER_RTT.aDown[BufferIndex].sName = sName; - SEGGER_RTT_UNLOCK(); - r = 0; - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_Init -* -* Function description -* Initializes the RTT Control Block. -* Should be used in RAM targets, at start of the application. -* -*/ -void SEGGER_RTT_Init (void) { - _DoInit(); -} - -/********************************************************************* -* -* SEGGER_RTT_SetTerminal -* -* Function description -* Sets the terminal to be used for output on channel 0. -* -* Parameters -* TerminalId Index of the terminal. -* -* Return value -* >= 0 O.K. -* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) -*/ -int SEGGER_RTT_SetTerminal (char TerminalId) { - char ac[2]; - SEGGER_RTT_BUFFER_UP* pRing; - unsigned Avail; - int r; - // - INIT(); - // - r = 0; - ac[0] = 0xFFU; - if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels - ac[1] = _aTerminalId[(unsigned char)TerminalId]; - pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed - SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing - if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { - _ActiveTerminal = TerminalId; - _WriteBlocking(pRing, ac, 2u); - } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes - Avail = _GetAvailWriteSpace(pRing); - if (Avail >= 2) { - _ActiveTerminal = TerminalId; // Only change active terminal in case of success - _WriteNoCheck(pRing, ac, 2u); - } else { - r = -1; - } - } - SEGGER_RTT_UNLOCK(); - } else { - r = -1; - } - return r; -} - -/********************************************************************* -* -* SEGGER_RTT_TerminalOut -* -* Function description -* Writes a string to the given terminal -* without changing the terminal for channel 0. -* -* Parameters -* TerminalId Index of the terminal. -* s String to be printed on the terminal. -* -* Return value -* >= 0 - Number of bytes written. -* < 0 - Error. -* -*/ -int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { - int Status; - unsigned FragLen; - unsigned Avail; - SEGGER_RTT_BUFFER_UP* pRing; - // - INIT(); - // - // Validate terminal ID. - // - if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels - // - // Get "to-host" ring buffer. - // - pRing = &_SEGGER_RTT.aUp[0]; - // - // Need to be able to change terminal, write data, change back. - // Compute the fixed and variable sizes. - // - FragLen = strlen(s); - // - // How we output depends upon the mode... - // - SEGGER_RTT_LOCK(); - Avail = _GetAvailWriteSpace(pRing); - switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { - case SEGGER_RTT_MODE_NO_BLOCK_SKIP: - // - // If we are in skip mode and there is no space for the whole - // of this output, don't bother switching terminals at all. - // - if (Avail < (FragLen + 4u)) { - Status = 0; - } else { - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, FragLen); - _PostTerminalSwitch(pRing, _ActiveTerminal); - } - break; - case SEGGER_RTT_MODE_NO_BLOCK_TRIM: - // - // If we are in trim mode and there is not enough space for everything, - // trim the output but always include the terminal switch. If no room - // for terminal switch, skip that totally. - // - if (Avail < 4u) { - Status = -1; - } else { - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); - _PostTerminalSwitch(pRing, _ActiveTerminal); - } - break; - case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: - // - // If we are in blocking mode, output everything. - // - _PostTerminalSwitch(pRing, TerminalId); - Status = (int)_WriteBlocking(pRing, s, FragLen); - _PostTerminalSwitch(pRing, _ActiveTerminal); - break; - default: - Status = -1; - break; - } - // - // Finish up. - // - SEGGER_RTT_UNLOCK(); - } else { - Status = -1; - } - return Status; -} - - -/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840_freertos/segger/SEGGER_RTT.h b/examples/device/nrf52840_freertos/segger/SEGGER_RTT.h deleted file mode 100644 index d3cac44dd..000000000 --- a/examples/device/nrf52840_freertos/segger/SEGGER_RTT.h +++ /dev/null @@ -1,234 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 5.12e * -* * -********************************************************************** ----------------------------END-OF-HEADER------------------------------ -File : SEGGER_RTT.h -Purpose : Implementation of SEGGER real-time transfer which allows - real-time communication on targets which support debugger - memory accesses while the CPU is running. ----------------------------------------------------------------------- -*/ - -#ifndef SEGGER_RTT_H -#define SEGGER_RTT_H - -#include "SEGGER_RTT_Conf.h" - -/********************************************************************* -* -* Defines, fixed -* -********************************************************************** -*/ - -/********************************************************************* -* -* Types -* -********************************************************************** -*/ - -// -// Description for a circular buffer (also called "ring buffer") -// which is used as up-buffer (T->H) -// -typedef struct { - const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" - char* pBuffer; // Pointer to start of buffer - unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. - unsigned WrOff; // Position of next item to be written by either target. - volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. - unsigned Flags; // Contains configuration flags -} SEGGER_RTT_BUFFER_UP; - -// -// Description for a circular buffer (also called "ring buffer") -// which is used as down-buffer (H->T) -// -typedef struct { - const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" - char* pBuffer; // Pointer to start of buffer - unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. - volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. - unsigned RdOff; // Position of next item to be read by target (down-buffer). - unsigned Flags; // Contains configuration flags -} SEGGER_RTT_BUFFER_DOWN; - -// -// RTT control block which describes the number of buffers available -// as well as the configuration for each buffer -// -// -typedef struct { - char acID[16]; // Initialized to "SEGGER RTT" - int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) - int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) - SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host - SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target -} SEGGER_RTT_CB; - -/********************************************************************* -* -* Global data -* -********************************************************************** -*/ -extern SEGGER_RTT_CB _SEGGER_RTT; - -/********************************************************************* -* -* RTT API functions -* -********************************************************************** -*/ -#ifdef __cplusplus - extern "C" { -#endif -int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); -int SEGGER_RTT_GetKey (void); -unsigned SEGGER_RTT_HasData (unsigned BufferIndex); -int SEGGER_RTT_HasKey (void); -void SEGGER_RTT_Init (void); -unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); -unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); -int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName); -int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); -int SEGGER_RTT_WaitKey (void); -unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); -void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); -// -// Function macro for performance optimization -// -#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) - -/********************************************************************* -* -* RTT "Terminal" API functions -* -********************************************************************** -*/ -int SEGGER_RTT_SetTerminal (char TerminalId); -int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); - -/********************************************************************* -* -* RTT printf functions (require SEGGER_RTT_printf.c) -* -********************************************************************** -*/ -int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); -#ifdef __cplusplus - } -#endif - -/********************************************************************* -* -* Defines -* -********************************************************************** -*/ - -// -// Operating modes. Define behavior if buffer is full (not enough space for entire message) -// -#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) -#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. -#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. -#define SEGGER_RTT_MODE_MASK (3U) - -// -// Control sequences, based on ANSI. -// Can be used to control color, and clear the screen -// -#define RTT_CTRL_RESET "" // Reset to default colors -#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left - -#define RTT_CTRL_TEXT_BLACK "" -#define RTT_CTRL_TEXT_RED "" -#define RTT_CTRL_TEXT_GREEN "" -#define RTT_CTRL_TEXT_YELLOW "" -#define RTT_CTRL_TEXT_BLUE "" -#define RTT_CTRL_TEXT_MAGENTA "" -#define RTT_CTRL_TEXT_CYAN "" -#define RTT_CTRL_TEXT_WHITE "" - -#define RTT_CTRL_TEXT_BRIGHT_BLACK "" -#define RTT_CTRL_TEXT_BRIGHT_RED "" -#define RTT_CTRL_TEXT_BRIGHT_GREEN "" -#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" -#define RTT_CTRL_TEXT_BRIGHT_BLUE "" -#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" -#define RTT_CTRL_TEXT_BRIGHT_CYAN "" -#define RTT_CTRL_TEXT_BRIGHT_WHITE "" - -#define RTT_CTRL_BG_BLACK "" -#define RTT_CTRL_BG_RED "" -#define RTT_CTRL_BG_GREEN "" -#define RTT_CTRL_BG_YELLOW "" -#define RTT_CTRL_BG_BLUE "" -#define RTT_CTRL_BG_MAGENTA "" -#define RTT_CTRL_BG_CYAN "" -#define RTT_CTRL_BG_WHITE "" - -#define RTT_CTRL_BG_BRIGHT_BLACK "" -#define RTT_CTRL_BG_BRIGHT_RED "" -#define RTT_CTRL_BG_BRIGHT_GREEN "" -#define RTT_CTRL_BG_BRIGHT_YELLOW "" -#define RTT_CTRL_BG_BRIGHT_BLUE "" -#define RTT_CTRL_BG_BRIGHT_MAGENTA "" -#define RTT_CTRL_BG_BRIGHT_CYAN "" -#define RTT_CTRL_BG_BRIGHT_WHITE "" - - -#endif - -/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840_freertos/segger/SEGGER_RTT_Conf.h b/examples/device/nrf52840_freertos/segger/SEGGER_RTT_Conf.h deleted file mode 100644 index aef3b4053..000000000 --- a/examples/device/nrf52840_freertos/segger/SEGGER_RTT_Conf.h +++ /dev/null @@ -1,242 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* SEGGER RTT * Real Time Transfer for embedded targets * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** -* * -* RTT version: 5.12e * -* * -********************************************************************** ----------------------------------------------------------------------- -File : SEGGER_RTT_Conf.h -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support - debugger memory accesses while the CPU is running. ----------------------------END-OF-HEADER------------------------------ -*/ - -#ifndef SEGGER_RTT_CONF_H -#define SEGGER_RTT_CONF_H - -#ifdef __ICCARM__ - #include -#endif - -/********************************************************************* -* -* Defines, configurable -* -********************************************************************** -*/ - -#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) -#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) - -#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) -#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) - -#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) - -#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) - -// -// Target is not allowed to perform other RTT operations while string still has not been stored completely. -// Otherwise we would probably end up with a mixed string in the buffer. -// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. -// -// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. -// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. -// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. -// (Higher priority = lower priority number) -// Default value for embOS: 128u -// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) -// In case of doubt mask all interrupts: 0u -// - -#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) - -/********************************************************************* -* -* RTT lock configuration for SEGGER Embedded Studio, -* Rowley CrossStudio and GCC -*/ -#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) - #ifdef __ARM_ARCH_6M__ - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs %0, primask \n\t" \ - "mov r1, $1 \n\t" \ - "msr primask, r1 \n\t" \ - : "=r" (LockState) \ - : \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ - : \ - : "r" (LockState) \ - : \ - ); \ - } - - #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs %0, basepri \n\t" \ - "mov r1, %1 \n\t" \ - "msr basepri, r1 \n\t" \ - : "=r" (LockState) \ - : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ - : \ - : "r" (LockState) \ - : \ - ); \ - } - - #elif defined(__ARM_ARCH_7A__) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - __asm volatile ("mrs r1, CPSR \n\t" \ - "mov %0, r1 \n\t" \ - "orr r1, r1, #0xC0 \n\t" \ - "msr CPSR_c, r1 \n\t" \ - : "=r" (LockState) \ - : \ - : "r1" \ - ); - - #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ - "mrs r1, CPSR \n\t" \ - "bic r1, r1, #0xC0 \n\t" \ - "and r0, r0, #0xC0 \n\t" \ - "orr r1, r1, r0 \n\t" \ - "msr CPSR_c, r1 \n\t" \ - : \ - : "r" (LockState) \ - : "r0", "r1" \ - ); \ - } -#else - #define SEGGER_RTT_LOCK() - #define SEGGER_RTT_UNLOCK() - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for IAR EWARM -*/ -#ifdef __ICCARM__ - #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - LockState = __get_PRIMASK(); \ - __set_PRIMASK(1); - - #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ - } - #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - LockState = __get_BASEPRI(); \ - __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); - - #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ - } - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for KEIL ARM -*/ -#ifdef __CC_ARM - #if (defined __TARGET_ARCH_6S_M) - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - register unsigned char PRIMASK __asm( "primask"); \ - LockState = PRIMASK; \ - PRIMASK = 1u; \ - __schedule_barrier(); - - #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ - __schedule_barrier(); \ - } - #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) - #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY - #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) - #endif - #define SEGGER_RTT_LOCK() { \ - unsigned int LockState; \ - register unsigned char BASEPRI __asm( "basepri"); \ - LockState = BASEPRI; \ - BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ - __schedule_barrier(); - - #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ - __schedule_barrier(); \ - } - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration fallback -*/ -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) -#endif - -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) -#endif - -#endif -/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840_freertos/segger/SEGGER_RTT_SES.c b/examples/device/nrf52840_freertos/segger/SEGGER_RTT_SES.c deleted file mode 100644 index e6634147c..000000000 --- a/examples/device/nrf52840_freertos/segger/SEGGER_RTT_SES.c +++ /dev/null @@ -1,76 +0,0 @@ -/********************************************************************* -* SEGGER MICROCONTROLLER GmbH & Co. KG * -* Solutions for real time microcontroller applications * -********************************************************************** -* * -* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * -* * -* www.segger.com Support: support@segger.com * -* * -********************************************************************** -* * -* All rights reserved. * -* * -* * This software may in its unmodified form be freely redistributed * -* in source form. * -* * The source code may be modified, provided the source code * -* retains the above copyright notice, this list of conditions and * -* the following disclaimer. * -* * Modified versions of this software in source or linkable form * -* may not be distributed without prior consent of SEGGER. * -* * This software may only be used for communication with SEGGER * -* J-Link debug probes. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * -* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * -* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * -* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * -* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * -* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * -* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * -* DAMAGE. * -* * -********************************************************************** --------- END-OF-HEADER --------------------------------------------- -File : SEGGER_RTT_Syscalls_SES.c -Purpose : Reimplementation of printf, puts and - implementation of __putchar and __getchar using RTT in SES. - To use RTT for printf output, include this file in your - application. ----------------------------------------------------------------------- -*/ -#include "SEGGER_RTT.h" -#include "__libc.h" -#include -#include - -int printf(const char *fmt,...) { - char buffer[128]; - va_list args; - va_start (args, fmt); - int n = vsnprintf(buffer, sizeof(buffer), fmt, args); - SEGGER_RTT_Write(0, buffer, n); - va_end(args); - return n; -} - -int puts(const char *s) { - return SEGGER_RTT_WriteString(0, s); -} - -int __putchar(int x, __printf_tag_ptr ctx) { - (void)ctx; - SEGGER_RTT_Write(0, (char *)&x, 1); - return x; -} - -int __getchar() { - return SEGGER_RTT_WaitKey(); -} - -/****** End Of File *************************************************/ diff --git a/examples/device/nrf52840_freertos/segger/nrf5x_freertos.emProject b/examples/device/nrf52840_freertos/segger/nrf5x_freertos.emProject index f01207bab..661dc12a6 100644 --- a/examples/device/nrf52840_freertos/segger/nrf5x_freertos.emProject +++ b/examples/device/nrf52840_freertos/segger/nrf5x_freertos.emProject @@ -32,12 +32,6 @@ target_reset_script="Reset();" target_script_file="$(ProjectDir)/nRF_Target.js" target_trace_initialize_script="EnableTrace("$(TraceInterfaceType)")" /> - - - - - - @@ -60,6 +54,12 @@ + + + + + + diff --git a/examples/device/nrf52840_freertos/src/main.c b/examples/device/nrf52840_freertos/src/main.c index 6fb76a84d..d5a5d0c2c 100644 --- a/examples/device/nrf52840_freertos/src/main.c +++ b/examples/device/nrf52840_freertos/src/main.c @@ -101,18 +101,32 @@ void cdc_task(void* params) while ( 1 ) { // connected and there are data available - if ( tud_mounted() && tud_cdc_available() ) + if ( tud_cdc_connected() ) { - uint8_t buf[64]; + if ( tud_cdc_available() ) + { + uint8_t buf[64]; + + // read and echo back + uint32_t count = tud_cdc_read(buf, sizeof(buf)); - // read and echo back - uint32_t count = tud_cdc_read(buf, sizeof(buf)); + tud_cdc_write(buf, count); + } - tud_cdc_write(buf, count); tud_cdc_write_flush(); } + } +} + +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) +{ + (void) itf; - taskYIELD(); + // connected + if ( dtr && rts ) + { + // print greeting + tud_cdc_write_str("tinyusb usb cdc\n"); } } #endif diff --git a/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.c b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.c new file mode 100644 index 000000000..aee5bd21e --- /dev/null +++ b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.c @@ -0,0 +1,1329 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 5.12e * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined SEGGER_RTT_SECTION + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef MEMCPY + #define MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +#ifdef SEGGER_RTT_SECTION + #if (defined __GNUC__) + __attribute__ ((section (SEGGER_RTT_SECTION))) SEGGER_RTT_CB _SEGGER_RTT; + #elif (defined __ICCARM__) || (defined __ICCRX__) + #pragma location=SEGGER_RTT_SECTION + SEGGER_RTT_CB _SEGGER_RTT; + #elif (defined __CC_ARM__) + __attribute__ ((section (SEGGER_RTT_SECTION), zero_init)) SEGGER_RTT_CB _SEGGER_RTT; + #else + SEGGER_RTT_CB _SEGGER_RTT; + #endif +#else + SEGGER_RTT_CB _SEGGER_RTT; +#endif + +#ifdef SEGGER_RTT_BUFFER_SECTION + #if (defined __GNUC__) + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acUpBuffer [BUFFER_SIZE_UP]; + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION))) static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #elif (defined __ICCARM__) || (defined __ICCRX__) + #pragma location=SEGGER_RTT_BUFFER_SECTION + static char _acUpBuffer [BUFFER_SIZE_UP]; + #pragma location=SEGGER_RTT_BUFFER_SECTION + static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #elif (defined __CC_ARM__) + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acUpBuffer [BUFFER_SIZE_UP]; + __attribute__ ((section (SEGGER_RTT_BUFFER_SECTION), zero_init)) static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #else + static char _acUpBuffer [BUFFER_SIZE_UP]; + static char _acDownBuffer[BUFFER_SIZE_DOWN]; + #endif +#else + static char _acUpBuffer [BUFFER_SIZE_UP]; + static char _acDownBuffer[BUFFER_SIZE_DOWN]; +#endif + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); + memcpy(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + NumBytesAtOnce = Rem; + memcpy(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + memcpy(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { + memcpy(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. + char* pDst; + pDst = pRing->pBuffer + pRing->WrOff; + pRing->WrOff += NumBytes; + do { + *pDst++ = *pData++; + } while (--NumBytes); +#else + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; //Alternatively: NumBytes = 0; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // + memcpy(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { +#if 1 // memcpy() is good for large amounts of data, but the overhead is too big for small amounts. Use a simple byte loop instead. + char* pDst; + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + do { + *pDst++ = *pData++; + } while (--NumBytes); + pRing->WrOff = WrOff + NumBytes; +#else + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + } else { + // + // We reach the end of the buffer, so need to wrap around + // + memcpy(pRing->pBuffer + WrOff, pData, Rem); + memcpy(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { + memcpy(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, remaining characters of pBuffer are dropped. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, depending on configuration, +* remaining characters may be dropped or RTT module waits until there is more space in the buffer. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFU; + if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(unsigned char)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = strlen(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + + +/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.h b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.h new file mode 100644 index 000000000..d3cac44dd --- /dev/null +++ b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT.h @@ -0,0 +1,234 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 5.12e * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); +#ifdef __cplusplus + } +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "" // Reset to default colors +#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "" +#define RTT_CTRL_TEXT_RED "" +#define RTT_CTRL_TEXT_GREEN "" +#define RTT_CTRL_TEXT_YELLOW "" +#define RTT_CTRL_TEXT_BLUE "" +#define RTT_CTRL_TEXT_MAGENTA "" +#define RTT_CTRL_TEXT_CYAN "" +#define RTT_CTRL_TEXT_WHITE "" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "" +#define RTT_CTRL_TEXT_BRIGHT_RED "" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + +#define RTT_CTRL_BG_BLACK "" +#define RTT_CTRL_BG_RED "" +#define RTT_CTRL_BG_GREEN "" +#define RTT_CTRL_BG_YELLOW "" +#define RTT_CTRL_BG_BLUE "" +#define RTT_CTRL_BG_MAGENTA "" +#define RTT_CTRL_BG_CYAN "" +#define RTT_CTRL_BG_WHITE "" + +#define RTT_CTRL_BG_BRIGHT_BLACK "" +#define RTT_CTRL_BG_BRIGHT_RED "" +#define RTT_CTRL_BG_BRIGHT_GREEN "" +#define RTT_CTRL_BG_BRIGHT_YELLOW "" +#define RTT_CTRL_BG_BRIGHT_BLUE "" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "" +#define RTT_CTRL_BG_BRIGHT_CYAN "" +#define RTT_CTRL_BG_BRIGHT_WHITE "" + + +#endif + +/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_Conf.h b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_Conf.h new file mode 100644 index 000000000..aef3b4053 --- /dev/null +++ b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_Conf.h @@ -0,0 +1,242 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2016 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 5.12e * +* * +********************************************************************** +---------------------------------------------------------------------- +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __ICCARM__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) + +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 0u +// + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } +#else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ diff --git a/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_SES.c b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_SES.c new file mode 100644 index 000000000..e6634147c --- /dev/null +++ b/examples/device/nrf52840_freertos/src/segger_rtt/SEGGER_RTT_SES.c @@ -0,0 +1,76 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +-------- END-OF-HEADER --------------------------------------------- +File : SEGGER_RTT_Syscalls_SES.c +Purpose : Reimplementation of printf, puts and + implementation of __putchar and __getchar using RTT in SES. + To use RTT for printf output, include this file in your + application. +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "__libc.h" +#include +#include + +int printf(const char *fmt,...) { + char buffer[128]; + va_list args; + va_start (args, fmt); + int n = vsnprintf(buffer, sizeof(buffer), fmt, args); + SEGGER_RTT_Write(0, buffer, n); + va_end(args); + return n; +} + +int puts(const char *s) { + return SEGGER_RTT_WriteString(0, s); +} + +int __putchar(int x, __printf_tag_ptr ctx) { + (void)ctx; + SEGGER_RTT_Write(0, (char *)&x, 1); + return x; +} + +int __getchar() { + return SEGGER_RTT_WaitKey(); +} + +/****** End Of File *************************************************/ diff --git a/examples/device/nrf52840_freertos/src/tusb_config.h b/examples/device/nrf52840_freertos/src/tusb_config.h index 96d851f90..9641f7bde 100644 --- a/examples/device/nrf52840_freertos/src/tusb_config.h +++ b/examples/device/nrf52840_freertos/src/tusb_config.h @@ -55,7 +55,7 @@ /*------------- RTOS -------------*/ #define CFG_TUSB_OS OPT_OS_FREERTOS -#define CFG_TUD_TASK_PRIO (configMAX_PRIORITIES-3) +#define CFG_TUD_TASK_PRIO (configMAX_PRIORITIES-1) //#define CFG_TUD_TASK_QUEUE_SZ 16 //#define CFG_TUD_TASK_STACK_SZ 150 diff --git a/hw/bsp/pca10056/board_pca10056.c b/hw/bsp/pca10056/board_pca10056.c index 928c39acf..54b1488a8 100644 --- a/hw/bsp/pca10056/board_pca10056.c +++ b/hw/bsp/pca10056/board_pca10056.c @@ -98,6 +98,11 @@ void board_init(void) nrf_gpio_cfg_output(BOARD_LED2); nrf_gpio_cfg_output(BOARD_LED3); + board_led_control(BOARD_LED0, false); + board_led_control(BOARD_LED1, false); + board_led_control(BOARD_LED2, false); + board_led_control(BOARD_LED3, false); + // Button for(uint8_t i=0; irx_ff, ser->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, 1, true); - tu_fifo_config_mutex(&ser->rx_ff, osal_mutex_create(&ser->rx_ff_mutex)); - tu_fifo_config(&ser->tx_ff, ser->tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, 1, false); + +#if CFG_FIFO_MUTEX + tu_fifo_config_mutex(&ser->rx_ff, osal_mutex_create(&ser->rx_ff_mutex)); tu_fifo_config_mutex(&ser->tx_ff, osal_mutex_create(&ser->tx_ff_mutex)); +#endif } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 2e03793a9..f1bd33953 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -77,6 +77,7 @@ char tud_cdc_n_peek (uint8_t itf, int pos); uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); bool tud_cdc_n_write_flush (uint8_t itf); //--------------------------------------------------------------------+ @@ -95,6 +96,7 @@ static inline char tud_cdc_peek (int pos) static inline uint32_t tud_cdc_write_char (char ch) { return tud_cdc_n_write_char(0, ch); } static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); } +static inline uint32_t tud_cdc_write_str (char const* str) { return tud_cdc_n_write_str(0, str); } static inline bool tud_cdc_write_flush (void) { return tud_cdc_n_write_flush(0); } //--------------------------------------------------------------------+ diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index e0b3d0aa0..2acd4b696 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -42,25 +42,16 @@ #include "tusb_fifo.h" // implement mutex lock and unlock -// For OSAL_NONE: if mutex is locked by other, function return immediately (since there is no task context) -// For Real RTOS: fifo lock is a blocking API #if CFG_FIFO_MUTEX -static bool tu_fifo_lock(tu_fifo_t *f) +static void tu_fifo_lock(tu_fifo_t *f) { if (f->mutex) { -#if CFG_TUSB_OS == OPT_OS_NONE - // There is no subtask context for blocking mutex, we will check and return if cannot lock the mutex - if ( !osal_mutex_lock_notask(f->mutex) ) return false; -#else uint32_t err; (void) err; osal_mutex_lock(f->mutex, OSAL_TIMEOUT_WAIT_FOREVER, &err); -#endif } - - return true; } static void tu_fifo_unlock(tu_fifo_t *f) @@ -73,14 +64,14 @@ static void tu_fifo_unlock(tu_fifo_t *f) #else -#define tu_fifo_lock(_ff) true +#define tu_fifo_lock(_ff) #define tu_fifo_unlock(_ff) #endif bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable) { - if ( !tu_fifo_lock(f) ) return false; + tu_fifo_lock(f); f->buffer = (uint8_t*) buffer; f->depth = depth; @@ -115,7 +106,7 @@ bool tu_fifo_read(tu_fifo_t* f, void * p_buffer) { if( tu_fifo_empty(f) ) return false; - if ( !tu_fifo_lock(f) ) return false; + tu_fifo_lock(f); memcpy(p_buffer, f->buffer + (f->rd_idx * f->item_size), @@ -216,7 +207,7 @@ bool tu_fifo_write (tu_fifo_t* f, const void * p_data) { if ( tu_fifo_full(f) && !f->overwritable ) return false; - if ( !tu_fifo_lock(f) ) return false; + tu_fifo_lock(f); memcpy( f->buffer + (f->wr_idx * f->item_size), p_data, @@ -279,7 +270,7 @@ uint16_t tu_fifo_write_n (tu_fifo_t* f, const void * p_data, uint16_t count) /******************************************************************************/ bool tu_fifo_clear(tu_fifo_t *f) { - if ( !tu_fifo_lock(f) ) return false; + tu_fifo_lock(f); f->rd_idx = f->wr_idx = f->count = 0; diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 70dc087c2..61d92b602 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -43,7 +43,9 @@ #ifndef _TUSB_FIFO_H_ #define _TUSB_FIFO_H_ -#define CFG_FIFO_MUTEX 1 +// mutex is only needed for RTOS +// for OS None, we don't get preempted +#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) #include #include diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 796ddc15f..f70c99c7f 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -178,19 +178,6 @@ static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) #define osal_mutex_unlock(_mutex_hdl) osal_semaphore_post(_mutex_hdl, false) #define osal_mutex_lock osal_semaphore_wait -// check if mutex is available for non-thread/substask usage in some cases -static inline bool osal_mutex_lock_notask(osal_mutex_t mutex_hdl) -{ - if (mutex_hdl->count) - { - mutex_hdl->count--; - return true; - }else - { - return false; - } -} - //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ -- cgit v1.3.1 From 10bf41f718ea867a3621e11b4c49e72605bbcc89 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Nov 2018 16:31:28 +0700 Subject: change osal_queue_receive() signature - fix build issue with freertos --- .gitignore | 16 +++++++++++++++ .../device/nrf52840_freertos/src/msc_flash_qspi.c | 2 +- src/device/dcd.h | 2 -- src/device/usbd.c | 23 +++++++++++----------- src/host/usbh.c | 10 ++++++++-- src/osal/osal.h | 7 +------ src/osal/osal_freertos.h | 5 ++--- src/osal/osal_none.h | 11 ++++++----- 8 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 .gitignore (limited to 'src/osal') diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..266cbe08f --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +/.metadata +html +latex +test_old +tests/build +*.d +*.o +*.mk +*.ld +*.launch +*.map +*.axf +/tests/lpc175x_6x/build/ +/tests/lpc18xx_43xx/build/ +/demos/*/*/Board_* +/demos/*/*/KeilBuild/ diff --git a/examples/device/nrf52840_freertos/src/msc_flash_qspi.c b/examples/device/nrf52840_freertos/src/msc_flash_qspi.c index 53bdc5a71..30adf1d92 100644 --- a/examples/device/nrf52840_freertos/src/msc_flash_qspi.c +++ b/examples/device/nrf52840_freertos/src/msc_flash_qspi.c @@ -61,7 +61,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes -int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { uint32_t addr = lba * CFG_TUD_MSC_BLOCK_SZ + offset; diff --git a/src/device/dcd.h b/src/device/dcd.h index 0c976edec..ff836f405 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -125,8 +125,6 @@ void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_ /*------------------------------------------------------------------*/ /* Endpoint API *------------------------------------------------------------------*/ - -//------------- Non-control Endpoints -------------// bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr); diff --git a/src/device/usbd.c b/src/device/usbd.c index c9d5e5642..4a9b13a25 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -245,24 +245,25 @@ void usbd_task( void* param) { (void) param; - OSAL_TASK_BEGIN +#if CFG_TUSB_OS != OPT_OS_NONE + while (1) { +#endif + usbd_main_st(); - OSAL_TASK_END + +#if CFG_TUSB_OS != OPT_OS_NONE + } +#endif } static tusb_error_t usbd_main_st(void) { dcd_event_t event; - tusb_error_t err = TUSB_ERROR_NONE; + // Loop until there is no more events in the queue - while (_usbd_q->count > 0) + while (1) { - tu_memclr(&event, sizeof(dcd_event_t)); - - err = osal_queue_receive(_usbd_q, &event); - if (err != TUSB_ERROR_NONE) { - break; - } + if ( !osal_queue_receive(_usbd_q, &event) ) return TUSB_ERROR_NONE; if ( DCD_EVENT_SETUP_RECEIVED == event.event_id ) { @@ -312,7 +313,7 @@ static tusb_error_t usbd_main_st(void) } } - return err; + return TUSB_ERROR_NONE; } void tud_control_interface_control_complete_cb(uint8_t rhport, uint8_t interface, tusb_control_request_t const * const p_request) { diff --git a/src/host/usbh.c b/src/host/usbh.c index b849de9b9..f996d7a70 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -361,9 +361,15 @@ void usbh_enumeration_task(void* param) { (void) param; - OSAL_TASK_BEGIN +#if CFG_TUSB_OS != OPT_OS_NONE + while (1) { +#endif + enumeration_body_subtask(); - OSAL_TASK_END + +#if CFG_TUSB_OS != OPT_OS_NONE + } +#endif } tusb_error_t enumeration_body_subtask(void) diff --git a/src/osal/osal.h b/src/osal/osal.h index 2ca06f66e..6846b5757 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -62,10 +62,6 @@ typedef void (*osal_task_func_t)( void * ); #if CFG_TUSB_OS == OPT_OS_NONE #include "osal_none.h" - - #define OSAL_TASK_BEGIN - #define OSAL_TASK_END - #else /* RTOS Porting API * @@ -105,8 +101,7 @@ typedef void (*osal_task_func_t)( void * ); #error CFG_TUSB_OS is not defined or OS is not supported yet #endif - #define OSAL_TASK_BEGIN while(1) { - #define OSAL_TASK_END } + // TODO remove subtask related macros later //------------- Sub Task -------------// #define OSAL_SUBTASK_BEGIN diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index f29759225..52cadd798 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -159,10 +159,9 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); } -static inline void osal_queue_receive (osal_queue_t const queue_hdl, void *p_data, uint32_t msec, uint32_t *err) +static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) { - uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*err) = ( xQueueReceive(queue_hdl, p_data, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); + return xQueueReceive(queue_hdl, data, portMAX_DELAY); } static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 383809180..5ba246d5f 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -89,6 +89,7 @@ static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semde static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; sem_hdl->count++; return true; } @@ -157,11 +158,11 @@ static inline void osal_queue_reset(osal_queue_t const queue_hdl) queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; } -static inline tusb_error_t osal_queue_receive(osal_queue_t const queue_hdl, void* data) { - if (!tu_fifo_read(queue_hdl, data)) { - return TUSB_ERROR_OSAL_WAITING; - } - return TUSB_ERROR_NONE; + +static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) +{ + // osal none return immediately without blocking + return tu_fifo_read(queue_hdl, data); } -- cgit v1.3.1 From ff26c5c6b13b1ae1dc306ed8baeabb18c2b95ac7 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Nov 2018 16:40:07 +0700 Subject: clean up --- src/device/usbd.c | 1 - src/osal/osal_none.h | 16 +--------------- 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index 4a9b13a25..ed4c565e6 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -475,7 +475,6 @@ void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_ //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ - tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) { for(int i=0; i<2; i++) diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 5ba246d5f..02483055c 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -49,20 +49,9 @@ //--------------------------------------------------------------------+ // TASK API -// NOTES: Each blocking OSAL_NONE services such as semaphore wait, -// queue receive embedded return statement, therefore local variable -// retain value before/after such services needed to declare as static -// OSAL_TASK_LOOP -// { -// OSAL_TASK_BEGIN -// -// task body statements -// -// OSAL_TASK_LOOP_ENG -// } +// Virtually do nothing in osal none //--------------------------------------------------------------------+ #define OSAL_TASK_DEF(_name, _str, _func, _prio, _stack_sz) osal_task_def_t _name; - typedef uint8_t osal_task_def_t; static inline bool osal_task_create(osal_task_def_t* taskdef) @@ -104,13 +93,10 @@ static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_ while (true) { while (sem_hdl->count == 0) { } - // tusb_hal_int_disable_all(); if (sem_hdl->count == 0) { sem_hdl->count--; - // tusb_hal_int_enable_all(); break; } - // tusb_hal_int_enable_all(); } return TUSB_ERROR_NONE; } -- cgit v1.3.1 From 5757918df4a3cc4561775db61d9f720df8b23c31 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Nov 2018 17:40:29 +0700 Subject: usbd clean up --- src/device/usbd.c | 128 +++++++++++++++++++++++++-------------------------- src/osal/osal_none.h | 20 ++++++-- 2 files changed, 80 insertions(+), 68 deletions(-) (limited to 'src/osal') diff --git a/src/device/usbd.c b/src/device/usbd.c index ed4c565e6..451494633 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -196,8 +196,6 @@ bool tud_mounted(void) //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ -static tusb_error_t usbd_main_st(void); - tusb_error_t usbd_init (void) { #if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) @@ -235,85 +233,87 @@ static void usbd_reset(uint8_t rhport) } } -// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper -// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with -// forever loop cannot have any return at all. - -// Within tinyusb stack, all task's code must be placed in subtask to be able to support multiple RTOS -// including none. -void usbd_task( void* param) -{ - (void) param; - -#if CFG_TUSB_OS != OPT_OS_NONE - while (1) { -#endif - - usbd_main_st(); - -#if CFG_TUSB_OS != OPT_OS_NONE - } -#endif -} - -static tusb_error_t usbd_main_st(void) +static void usbd_task_body(void) { dcd_event_t event; // Loop until there is no more events in the queue while (1) { - if ( !osal_queue_receive(_usbd_q, &event) ) return TUSB_ERROR_NONE; + if ( !osal_queue_receive(_usbd_q, &event) ) return; - if ( DCD_EVENT_SETUP_RECEIVED == event.event_id ) + switch ( event.event_id ) { - // Setup tokens are unique to the Control endpointso we delegate to it directly. - controld_process_setup_request(event.rhport, &event.setup_received); - } - else if (DCD_EVENT_XFER_COMPLETE == event.event_id) - { - // Invoke the class callback associated with the endpoint address - uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const drv_id = _usbd_dev.ep2drv[ edpt_dir(ep_addr) ][ edpt_number(ep_addr) ]; + case DCD_EVENT_SETUP_RECEIVED: + // Setup tokens are unique to the Control endpoint so we delegate to it directly. + controld_process_setup_request(event.rhport, &event.setup_received); + break; - if (drv_id < USBD_CLASS_DRIVER_COUNT) + case DCD_EVENT_XFER_COMPLETE: { - usbd_class_drivers[drv_id].xfer_cb( event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); - } - } - else if (DCD_EVENT_BUS_RESET == event.event_id) - { - usbd_reset(event.rhport); - osal_queue_reset(_usbd_q); - } - else if (DCD_EVENT_UNPLUGGED == event.event_id) - { - usbd_reset(event.rhport); - osal_queue_reset(_usbd_q); + // Invoke the class callback associated with the endpoint address + uint8_t const ep_addr = event.xfer_complete.ep_addr; + uint8_t const drv_id = _usbd_dev.ep2drv[edpt_dir(ep_addr)][edpt_number(ep_addr)]; - tud_umount_cb(); // invoke callback - } - else if (DCD_EVENT_SOF == event.event_id) - { - for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) - { - if ( usbd_class_drivers[i].sof ) + if ( drv_id < USBD_CLASS_DRIVER_COUNT ) { - usbd_class_drivers[i].sof( event.rhport ); + usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); } } - } - else if ( USBD_EVT_FUNC_CALL == event.event_id ) - { - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - } - else - { - TU_BREAKPOINT(); + break; + + case DCD_EVENT_BUS_RESET: + // note: if task is too slow, we could clear the event of the new attached + usbd_reset(event.rhport); + osal_queue_reset(_usbd_q); + break; + + case DCD_EVENT_UNPLUGGED: + // note: if task is too slow, we could clear the event of the new attached + usbd_reset(event.rhport); + osal_queue_reset(_usbd_q); + + tud_umount_cb(); // invoke callback + break; + + case DCD_EVENT_SOF: + for ( uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++ ) + { + if ( usbd_class_drivers[i].sof ) + { + usbd_class_drivers[i].sof(event.rhport); + } + } + break; + + case USBD_EVT_FUNC_CALL: + if ( event.func_call.func ) event.func_call.func(event.func_call.param); + break; + + default: + TU_BREAKPOINT(); + break; } } +} - return TUSB_ERROR_NONE; +/* USB device task + * Thread that handles all device events. With an real RTOS, the task must be a forever loop and never return. + * For codign convenience with no RTOS, we use wrapped sub-function for processing to easily return at any time. + */ +void usbd_task( void* param) +{ + (void) param; + +#if CFG_TUSB_OS != OPT_OS_NONE + while (1) { +#endif + + usbd_task_body(); + +#if CFG_TUSB_OS != OPT_OS_NONE + } +#endif } void tud_control_interface_control_complete_cb(uint8_t rhport, uint8_t interface, tusb_control_request_t const * const p_request) { diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 02483055c..46930aeda 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -136,21 +136,33 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) { (void) in_isr; - return tu_fifo_write( (tu_fifo_t*) queue_hdl, data); +// if (!in_isr) tusb_hal_int_disable_all(); + + bool rc = tu_fifo_write( (tu_fifo_t*) queue_hdl, data); + +// if (!in_isr) tusb_hal_int_enable_all(); + + return rc; } static inline void osal_queue_reset(osal_queue_t const queue_hdl) { - queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0; + // tusb_hal_int_disable_all(); + tu_fifo_clear( (tu_fifo_t*) queue_hdl); + // tusb_hal_int_enable_all(); } static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) { // osal none return immediately without blocking - return tu_fifo_read(queue_hdl, data); -} + // tusb_hal_int_disable_all(); + bool rc = tu_fifo_read(queue_hdl, data); + // tusb_hal_int_enable_all(); + + return rc; +} #ifdef __cplusplus } -- cgit v1.3.1 From a619ff88a36e4b841cb5901135b1811b06c3c843 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 23 Nov 2018 15:17:43 +0700 Subject: rename xfer complete enum --- examples/obsolete/device/src/keyboard_device_app.c | 6 +++--- examples/obsolete/device/src/mouse_device_app.c | 6 +++--- examples/obsolete/host/src/cdc_serial_host_app.c | 6 +++--- examples/obsolete/host/src/keyboard_host_app.c | 4 ++-- examples/obsolete/host/src/mouse_host_app.c | 4 ++-- src/class/cdc/cdc_host.h | 6 +++--- src/class/hid/hid_host.h | 12 ++++++------ src/class/msc/msc_host.h | 6 +++--- src/common/tusb_types.h | 6 +++--- src/host/ehci/ehci.c | 6 +++--- src/host/hub.c | 2 +- src/host/ohci/ohci.c | 10 +++++----- src/host/usbh.c | 8 ++++---- src/osal/osal_none.h | 6 ++++-- tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c | 12 ++++++------ tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c | 2 +- tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c | 2 +- tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c | 6 +++--- tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c | 6 +++--- tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c | 4 ++-- tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c | 8 ++++---- tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c | 2 +- 22 files changed, 66 insertions(+), 64 deletions(-) (limited to 'src/osal') diff --git a/examples/obsolete/device/src/keyboard_device_app.c b/examples/obsolete/device/src/keyboard_device_app.c index 6c413464e..5e14c56c9 100644 --- a/examples/obsolete/device/src/keyboard_device_app.c +++ b/examples/obsolete/device/src/keyboard_device_app.c @@ -70,9 +70,9 @@ void tud_hid_keyboard_cb(uint8_t rhport, xfer_result_t event, uint32_t xferred_b { switch(event) { - case TUSB_EVENT_XFER_COMPLETE: - case TUSB_EVENT_XFER_ERROR: - case TUSB_EVENT_XFER_STALLED: + case XFER_RESULT_SUCCESS: + case XFER_RESULT_FAILED: + case XFER_RESULT_STALLED: default: break; } } diff --git a/examples/obsolete/device/src/mouse_device_app.c b/examples/obsolete/device/src/mouse_device_app.c index 4c4d322d7..6869f1a05 100644 --- a/examples/obsolete/device/src/mouse_device_app.c +++ b/examples/obsolete/device/src/mouse_device_app.c @@ -70,9 +70,9 @@ void tud_hid_mouse_cb(uint8_t rhport, xfer_result_t event, uint32_t xferred_byte { switch(event) { - case TUSB_EVENT_XFER_COMPLETE: - case TUSB_EVENT_XFER_ERROR: - case TUSB_EVENT_XFER_STALLED: + case XFER_RESULT_SUCCESS: + case XFER_RESULT_FAILED: + case XFER_RESULT_STALLED: default: break; } } diff --git a/examples/obsolete/host/src/cdc_serial_host_app.c b/examples/obsolete/host/src/cdc_serial_host_app.c index afb2b8937..85604dcdf 100644 --- a/examples/obsolete/host/src/cdc_serial_host_app.c +++ b/examples/obsolete/host/src/cdc_serial_host_app.c @@ -84,17 +84,17 @@ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_i case CDC_PIPE_DATA_IN: switch(event) { - case TUSB_EVENT_XFER_COMPLETE: + case XFER_RESULT_SUCCESS: received_bytes = xferred_bytes; osal_semaphore_post(sem_hdl); // notify main task break; - case TUSB_EVENT_XFER_ERROR: + case XFER_RESULT_FAILED: received_bytes = 0; // ignore tuh_cdc_receive(dev_addr, serial_in_buffer, SERIAL_BUFFER_SIZE, true); // waiting for next data break; - case TUSB_EVENT_XFER_STALLED: + case XFER_RESULT_STALLED: default : break; } diff --git a/examples/obsolete/host/src/keyboard_host_app.c b/examples/obsolete/host/src/keyboard_host_app.c index 27d10b9e7..fd51548c3 100644 --- a/examples/obsolete/host/src/keyboard_host_app.c +++ b/examples/obsolete/host/src/keyboard_host_app.c @@ -81,12 +81,12 @@ void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event) { switch(event) { - case TUSB_EVENT_XFER_COMPLETE: + case XFER_RESULT_SUCCESS: osal_queue_send(queue_kbd_hdl, &usb_keyboard_report); tuh_hid_keyboard_get_report(dev_addr, (uint8_t*) &usb_keyboard_report); break; - case TUSB_EVENT_XFER_ERROR: + case XFER_RESULT_FAILED: tuh_hid_keyboard_get_report(dev_addr, (uint8_t*) &usb_keyboard_report); // ignore & continue break; diff --git a/examples/obsolete/host/src/mouse_host_app.c b/examples/obsolete/host/src/mouse_host_app.c index 05135693b..819c2b290 100644 --- a/examples/obsolete/host/src/mouse_host_app.c +++ b/examples/obsolete/host/src/mouse_host_app.c @@ -80,12 +80,12 @@ void tuh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event) { switch(event) { - case TUSB_EVENT_XFER_COMPLETE: + case XFER_RESULT_SUCCESS: osal_queue_send(queue_mouse_hdl, &usb_mouse_report); (void) tuh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); break; - case TUSB_EVENT_XFER_ERROR: + case XFER_RESULT_FAILED: (void) tuh_hid_mouse_get_report(dev_addr, (uint8_t*) &usb_mouse_report); // ignore & continue break; diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 8cfe6e5b7..0b863bb61 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -122,9 +122,9 @@ void tuh_cdc_unmounted_cb(uint8_t dev_addr); * \param[in] pipe_id value from \ref cdc_pipeid_t indicate the pipe * \param[in] xferred_bytes Number of bytes transferred via USB bus * \note event can be one of following - * - TUSB_EVENT_XFER_COMPLETE : previously scheduled transfer completes successfully. - * - TUSB_EVENT_XFER_ERROR : previously scheduled transfer encountered a transaction error. - * - TUSB_EVENT_XFER_STALLED : previously scheduled transfer is stalled by device. + * - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully. + * - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error. + * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. * \note */ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes); diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index fb10a614f..cb0230e8a 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -95,9 +95,9 @@ tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void * p_report) /*A * \param[in] dev_addr Address of device * \param[in] event an value from \ref xfer_result_t * \note event can be one of following - * - TUSB_EVENT_XFER_COMPLETE : previously scheduled transfer completes successfully. - * - TUSB_EVENT_XFER_ERROR : previously scheduled transfer encountered a transaction error. - * - TUSB_EVENT_XFER_STALLED : previously scheduled transfer is stalled by device. + * - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully. + * - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error. + * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. * \note Application should schedule the next report by calling \ref tuh_hid_keyboard_get_report within this callback */ void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event); @@ -160,9 +160,9 @@ tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void* p_report) /*ATTR_ * \param[in] dev_addr Address of device * \param[in] event an value from \ref xfer_result_t * \note event can be one of following - * - TUSB_EVENT_XFER_COMPLETE : previously scheduled transfer completes successfully. - * - TUSB_EVENT_XFER_ERROR : previously scheduled transfer encountered a transaction error. - * - TUSB_EVENT_XFER_STALLED : previously scheduled transfer is stalled by device. + * - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully. + * - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error. + * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. * \note Application should schedule the next report by calling \ref tuh_hid_mouse_get_report within this callback */ void tuh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event); diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 0afe5c515..a408bbeaf 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -174,9 +174,9 @@ void tuh_msc_unmounted_cb(uint8_t dev_addr); * \param[in] event an value from \ref xfer_result_t * \param[in] xferred_bytes Number of bytes transferred via USB bus * \note event can be one of following - * - TUSB_EVENT_XFER_COMPLETE : previously scheduled transfer completes successfully. - * - TUSB_EVENT_XFER_ERROR : previously scheduled transfer encountered a transaction error. - * - TUSB_EVENT_XFER_STALLED : previously scheduled transfer is stalled by device. + * - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully. + * - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error. + * - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device. * \note */ void tuh_msc_isr(uint8_t dev_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 7b5268d4f..9c3c21b88 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -197,9 +197,9 @@ typedef enum typedef enum { - TUSB_EVENT_XFER_COMPLETE, - TUSB_EVENT_XFER_ERROR, - TUSB_EVENT_XFER_STALLED, + XFER_RESULT_SUCCESS, + XFER_RESULT_FAILED, + XFER_RESULT_STALLED, }xfer_result_t; enum diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 2fc99ffcd..27808d59b 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -570,7 +570,7 @@ static void qhd_xfer_complete_isr(ehci_qhd_t * p_qhd) if (is_ioc) // end of request { // call USBH callback usbh_xfer_isr( qhd_create_pipe_handle(p_qhd, xfer_type), - p_qhd->class_code, TUSB_EVENT_XFER_COMPLETE, + p_qhd->class_code, XFER_RESULT_SUCCESS, p_qhd->total_xferred_bytes - (xfer_type == TUSB_XFER_CONTROL ? 8 : 0) ); // subtract setup packet size if control, p_qhd->total_xferred_bytes = 0; } @@ -641,12 +641,12 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) xfer_result_t error_event; // no error bits are set, endpoint is halted due to STALL - error_event = qhd_has_xact_error(p_qhd) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_STALLED; + error_event = qhd_has_xact_error(p_qhd) ? XFER_RESULT_FAILED : XFER_RESULT_STALLED; p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes; -// if ( TUSB_EVENT_XFER_ERROR == error_event ) TU_BREAKPOINT(); // TODO skip unplugged device +// if ( XFER_RESULT_FAILED == error_event ) TU_BREAKPOINT(); // TODO skip unplugged device p_qhd->p_qtd_list_head->used = 0; // free QTD qtd_remove_1st_from_qhd(p_qhd); diff --git a/src/host/hub.c b/src/host/hub.c index 9635bcc0b..55c8597ad 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -215,7 +215,7 @@ void hub_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes usbh_hub_t * p_hub = &hub_data[pipe_hdl.dev_addr-1]; - if ( event == TUSB_EVENT_XFER_COMPLETE ) + if ( event == XFER_RESULT_SUCCESS ) { for (uint8_t port=1; port <= p_hub->port_number; port++) { // TODO HUB ignore bit0 hub_status_change diff --git a/src/host/ohci/ohci.c b/src/host/ohci/ohci.c index 58738a236..91d9b6243 100644 --- a/src/host/ohci/ohci.c +++ b/src/host/ohci/ohci.c @@ -617,11 +617,11 @@ static void done_queue_isr(uint8_t hostid) // TODO check if td_head is iso td //------------- Non ISO transfer -------------// ohci_gtd_t * const p_qtd = (ohci_gtd_t *) td_head; - xfer_result_t const event = (p_qtd->condition_code == OHCI_CCODE_NO_ERROR) ? TUSB_EVENT_XFER_COMPLETE : - (p_qtd->condition_code == OHCI_CCODE_STALL) ? TUSB_EVENT_XFER_STALLED : TUSB_EVENT_XFER_ERROR; + xfer_result_t const event = (p_qtd->condition_code == OHCI_CCODE_NO_ERROR) ? XFER_RESULT_SUCCESS : + (p_qtd->condition_code == OHCI_CCODE_STALL) ? XFER_RESULT_STALLED : XFER_RESULT_FAILED; p_qtd->used = 0; // free TD - if ( (p_qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != TUSB_EVENT_XFER_COMPLETE) ) + if ( (p_qtd->delay_interrupt == OHCI_INT_ON_COMPLETE_YES) || (event != XFER_RESULT_SUCCESS) ) { ohci_ed_t * const p_ed = gtd_get_ed(p_qtd); @@ -634,11 +634,11 @@ static void done_queue_isr(uint8_t hostid) // --> HC will not process Control list (due to service ratio when Bulk list not empty) // To walk-around this, the halted ED will have TailP = HeadP (empty list condition), when clearing halt // the TailP must be set back to NULL for processing remaining TDs - if ((event != TUSB_EVENT_XFER_COMPLETE)) + if ((event != XFER_RESULT_SUCCESS)) { p_ed->td_tail.address &= 0x0Ful; p_ed->td_tail.address |= tu_align16(p_ed->td_head.address); // mark halted EP as empty queue - if ( event == TUSB_EVENT_XFER_STALLED ) p_ed->is_stalled = 1; + if ( event == XFER_RESULT_STALLED ) p_ed->is_stalled = 1; } pipe_handle_t pipe_hdl = diff --git a/src/host/usbh.c b/src/host/usbh.c index ed21bf3da..a0aab3b96 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -199,7 +199,7 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, #ifndef _TEST_ usbh_devices[dev_addr].control.pipe_status = 0; #else - usbh_devices[dev_addr].control.pipe_status = TUSB_EVENT_XFER_COMPLETE; // in Test project, mark as complete immediately + usbh_devices[dev_addr].control.pipe_status = XFER_RESULT_SUCCESS; // in Test project, mark as complete immediately #endif error = hcd_pipe_control_xfer(dev_addr, &usbh_devices[dev_addr].control.request, data); @@ -207,11 +207,11 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl); STASK_ASSERT_ERR(error); - if (TUSB_EVENT_XFER_STALLED == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_STALLED); - if (TUSB_EVENT_XFER_ERROR == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_FAILED); + if (XFER_RESULT_STALLED == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_STALLED); + if (XFER_RESULT_FAILED == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_FAILED); // STASK_ASSERT_HDLR(TUSB_ERROR_NONE == error && -// TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status, +// XFER_RESULT_SUCCESS == usbh_devices[dev_addr].control.pipe_status, // tuh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) ); OSAL_SUBTASK_END diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 46930aeda..b21c3332a 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -156,10 +156,12 @@ static inline void osal_queue_reset(osal_queue_t const queue_hdl) static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) { // osal none return immediately without blocking + // extern void tusb_hal_int_disable(uint8_t rhport); + // extern void tusb_hal_int_enable(uint8_t rhport); - // tusb_hal_int_disable_all(); +// tusb_hal_int_disable(0); bool rc = tu_fifo_read(queue_hdl, data); - // tusb_hal_int_enable_all(); +// tusb_hal_int_enable(0); return rc; } diff --git a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c index 5077eea93..12dce0528 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_host.c @@ -251,10 +251,10 @@ void test_cdc_xfer_notification_pipe(void) cdch_data[dev_addr-1].pipe_out = pipe_out; cdch_data[dev_addr-1].pipe_in = pipe_in; - tusbh_cdc_xfer_isr_Expect(dev_addr, TUSB_EVENT_XFER_COMPLETE, CDC_PIPE_NOTIFICATION, 10); + tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_SUCCESS, CDC_PIPE_NOTIFICATION, 10); //------------- CUT -------------// - cdch_isr(pipe_notification, TUSB_EVENT_XFER_COMPLETE, 10); + cdch_isr(pipe_notification, XFER_RESULT_SUCCESS, 10); } void test_cdc_xfer_pipe_out(void) @@ -267,10 +267,10 @@ void test_cdc_xfer_pipe_out(void) cdch_data[dev_addr-1].pipe_out = pipe_out; cdch_data[dev_addr-1].pipe_in = pipe_in; - tusbh_cdc_xfer_isr_Expect(dev_addr, TUSB_EVENT_XFER_ERROR, CDC_PIPE_DATA_OUT, 20); + tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_FAILED, CDC_PIPE_DATA_OUT, 20); //------------- CUT -------------// - cdch_isr(pipe_out, TUSB_EVENT_XFER_ERROR, 20); + cdch_isr(pipe_out, XFER_RESULT_FAILED, 20); } void test_cdc_xfer_pipe_in(void) @@ -283,8 +283,8 @@ void test_cdc_xfer_pipe_in(void) cdch_data[dev_addr-1].pipe_out = pipe_out; cdch_data[dev_addr-1].pipe_in = pipe_in; - tusbh_cdc_xfer_isr_Expect(dev_addr, TUSB_EVENT_XFER_STALLED, CDC_PIPE_DATA_IN, 0); + tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_STALLED, CDC_PIPE_DATA_IN, 0); //------------- CUT -------------// - cdch_isr(pipe_in, TUSB_EVENT_XFER_STALLED, 0); + cdch_isr(pipe_in, XFER_RESULT_STALLED, 0); } diff --git a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c index a493c3b79..86d6c2890 100644 --- a/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c +++ b/tests/lpc18xx_43xx/test/host/cdc/test_cdc_rndis_host.c @@ -188,7 +188,7 @@ static tusb_error_t stub_pipe_notification_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[0] = 1; // response available - cdch_isr(pipe_hdl, TUSB_EVENT_XFER_COMPLETE, 8); + cdch_isr(pipe_hdl, XFER_RESULT_SUCCESS, 8); return TUSB_ERROR_NONE; } diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c index 2e9e29fdc..c4037c596 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_bulk_xfer.c @@ -208,7 +208,7 @@ void test_bulk_xfer_complete_isr(void) ehci_qtd_t* p_head = p_qhd_bulk->p_qtd_list_head; ehci_qtd_t* p_tail = p_qhd_bulk->p_qtd_list_tail; - usbh_xfer_isr_Expect(pipe_hdl_bulk, TUSB_CLASS_MSC, TUSB_EVENT_XFER_COMPLETE, sizeof(data2)+sizeof(xfer_data)); + usbh_xfer_isr_Expect(pipe_hdl_bulk, TUSB_CLASS_MSC, XFER_RESULT_SUCCESS, sizeof(data2)+sizeof(xfer_data)); //------------- Code Under Test -------------// ehci_controller_run(hostid); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c index ffd7ffb67..4f8cdb4c8 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c @@ -228,7 +228,7 @@ void test_control_xfer_complete_isr(void) { TEST_ASSERT_STATUS( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) ); - usbh_xfer_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, TUSB_EVENT_XFER_COMPLETE, 18); + usbh_xfer_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_SUCCESS, 18); //------------- Code Under TEST -------------// ehci_controller_run(hostid); @@ -247,7 +247,7 @@ void test_control_xfer_error_isr(void) { TEST_ASSERT_STATUS( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) ); - usbh_xfer_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, TUSB_EVENT_XFER_ERROR, 0); + usbh_xfer_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_FAILED, 0); //------------- Code Under TEST -------------// ehci_controller_run_error(hostid); @@ -266,7 +266,7 @@ void test_control_xfer_error_stall(void) { TEST_ASSERT_STATUS( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) ); - usbh_xfer_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, TUSB_EVENT_XFER_STALLED, 0); + usbh_xfer_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_STALLED, 0); //------------- Code Under TEST -------------// ehci_controller_run_stall(hostid); diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c index 827db2897..bf7ad352a 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_interrupt_xfer.c @@ -201,7 +201,7 @@ void test_interrupt_xfer_complete_isr_interval_less_than_1ms(void) TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, data2, sizeof(data2), true) ); - usbh_xfer_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, TUSB_EVENT_XFER_COMPLETE, sizeof(xfer_data)+sizeof(data2)); + usbh_xfer_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_SUCCESS, sizeof(xfer_data)+sizeof(data2)); ehci_qtd_t* p_head = p_qhd_interrupt->p_qtd_list_head; ehci_qtd_t* p_tail = p_qhd_interrupt->p_qtd_list_tail; @@ -242,7 +242,7 @@ void test_interrupt_xfer_error_isr(void) { TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) ); - usbh_xfer_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, TUSB_EVENT_XFER_ERROR, 0); + usbh_xfer_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_FAILED, 0); //------------- Code Under TEST -------------// ehci_controller_run_error(hostid); @@ -254,7 +254,7 @@ void test_interrupt_xfer_error_stall(void) { TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) ); - usbh_xfer_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, TUSB_EVENT_XFER_STALLED, 0); + usbh_xfer_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_STALLED, 0); //------------- Code Under TEST -------------// ehci_controller_run_stall(hostid); diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c index b3b49c172..de3581423 100644 --- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c +++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c @@ -216,10 +216,10 @@ void test_keyboard_get_ok() void test_keyboard_isr_event_complete(void) { - tusbh_hid_keyboard_isr_Expect(dev_addr, TUSB_EVENT_XFER_COMPLETE); + tusbh_hid_keyboard_isr_Expect(dev_addr, XFER_RESULT_SUCCESS); //------------- Code Under TEST -------------// - hidh_isr(p_hidh_kbd->pipe_hdl, TUSB_EVENT_XFER_COMPLETE, 8); + hidh_isr(p_hidh_kbd->pipe_hdl, XFER_RESULT_SUCCESS, 8); // tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED); // TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_COMPLETE, tusbh_hid_keyboard_status(dev_addr)); diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c index b1a3558e6..541c2caef 100644 --- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c +++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c @@ -189,10 +189,10 @@ void test_mouse_get_ok() void test_mouse_isr_event_xfer_complete(void) { - tusbh_hid_mouse_isr_Expect(dev_addr, TUSB_EVENT_XFER_COMPLETE); + tusbh_hid_mouse_isr_Expect(dev_addr, XFER_RESULT_SUCCESS); //------------- Code Under TEST -------------// - hidh_isr(p_hidh_mouse->pipe_hdl, TUSB_EVENT_XFER_COMPLETE, 8); + hidh_isr(p_hidh_mouse->pipe_hdl, XFER_RESULT_SUCCESS, 8); tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED); // TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_COMPLETE, tusbh_hid_mouse_status(dev_addr)); @@ -200,10 +200,10 @@ void test_mouse_isr_event_xfer_complete(void) void test_mouse_isr_event_xfer_error(void) { - tusbh_hid_mouse_isr_Expect(dev_addr, TUSB_EVENT_XFER_ERROR); + tusbh_hid_mouse_isr_Expect(dev_addr, XFER_RESULT_FAILED); //------------- Code Under TEST -------------// - hidh_isr(p_hidh_mouse->pipe_hdl, TUSB_EVENT_XFER_ERROR, 0); + hidh_isr(p_hidh_mouse->pipe_hdl, XFER_RESULT_FAILED, 0); tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED); // TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_ERROR, tusbh_hid_mouse_status(dev_addr)); diff --git a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c index a85c3c48a..eba3fbcc3 100644 --- a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c +++ b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c @@ -181,7 +181,7 @@ tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_control_request_t * usbh_xfer_isr( (pipe_handle_t) { .dev_addr = (num_call > 1 ? 1 : 0), .xfer_type = TUSB_XFER_CONTROL }, - 0, TUSB_EVENT_XFER_COMPLETE, 0); + 0, XFER_RESULT_SUCCESS, 0); return TUSB_ERROR_NONE; } -- cgit v1.3.1 From 246c28db1a2bc2a2c0d21c62789bcc72e3fadeae Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Nov 2018 09:47:22 -0800 Subject: Turn off interrupts when working with the event queue. --- src/osal/osal_none.h | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'src/osal') diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index b21c3332a..40ecb9c37 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -43,6 +43,8 @@ #ifndef _TUSB_OSAL_NONE_H_ #define _TUSB_OSAL_NONE_H_ +#include "tusb_hal.h" + #ifdef __cplusplus extern "C" { #endif @@ -135,14 +137,14 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) { - (void) in_isr; -// if (!in_isr) tusb_hal_int_disable_all(); - - bool rc = tu_fifo_write( (tu_fifo_t*) queue_hdl, data); - -// if (!in_isr) tusb_hal_int_enable_all(); - - return rc; + if (!in_isr) { + tusb_hal_int_disable_all(); + } + bool success = tu_fifo_write( (tu_fifo_t*) queue_hdl, data); + if (!in_isr) { + tusb_hal_int_enable_all(); + } + return success; } static inline void osal_queue_reset(osal_queue_t const queue_hdl) @@ -152,18 +154,11 @@ static inline void osal_queue_reset(osal_queue_t const queue_hdl) // tusb_hal_int_enable_all(); } - -static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) -{ - // osal none return immediately without blocking - // extern void tusb_hal_int_disable(uint8_t rhport); - // extern void tusb_hal_int_enable(uint8_t rhport); - -// tusb_hal_int_disable(0); - bool rc = tu_fifo_read(queue_hdl, data); -// tusb_hal_int_enable(0); - - return rc; +static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) { + tusb_hal_int_disable_all(); + bool success = tu_fifo_read(queue_hdl, data); + tusb_hal_int_enable_all(); + return success; } #ifdef __cplusplus -- cgit v1.3.1 From 6f3898572d6f8eb04587f057b74f4f86e8a18856 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 5 Dec 2018 17:01:19 +0700 Subject: add role to OSAL_QUEUE_DEF() to disable correct dcd/hcd isr --- .../device/cdc_msc_hid/ses/samd21/samd21.emProject | 1 + src/common/tusb_fifo.h | 3 +- src/device/usbd.c | 32 ++++---- src/osal/osal_freertos.h | 4 +- src/osal/osal_mynewt.h | 4 +- src/osal/osal_none.h | 89 +++++++++++++++++----- src/tusb_hal.h | 32 -------- src/tusb_option.h | 1 - 8 files changed, 94 insertions(+), 72 deletions(-) (limited to 'src/osal') diff --git a/examples/device/cdc_msc_hid/ses/samd21/samd21.emProject b/examples/device/cdc_msc_hid/ses/samd21/samd21.emProject index d61b82cfa..fbb8841b7 100644 --- a/examples/device/cdc_msc_hid/ses/samd21/samd21.emProject +++ b/examples/device/cdc_msc_hid/ses/samd21/samd21.emProject @@ -22,6 +22,7 @@ c_user_include_directories="../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(asf4Dir);$(asf4Dir)/include;$(asf4Dir)/config;$(asf4Dir)/hri;$(asf4Dir)/hal/include;$(asf4Dir)/hal/utils/include;$(asf4Dir)/hpl/port;$(asf4Dir)/hpl/gclk;$(asf4Dir)/hpl/pm" debug_register_definition_file="ATSAMD21G18A_Registers.xml" debug_target_connection="J-Link" + gcc_enable_all_warnings="Yes" gcc_entry_point="Reset_Handler" link_use_linker_script_file="No" linker_memory_map_file="$(ProjectDir)/ATSAMD21G18A_MemoryMap.xml" diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index 61d92b602..e88c2ac6d 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -67,13 +67,12 @@ typedef struct uint8_t* buffer ; ///< buffer pointer uint16_t depth ; ///< max items uint16_t item_size ; ///< size of each item + bool overwritable ; volatile uint16_t count ; ///< number of items in queue volatile uint16_t wr_idx ; ///< write pointer volatile uint16_t rd_idx ; ///< read pointer - bool overwritable ; - #if CFG_FIFO_MUTEX tu_fifo_mutex_t mutex; #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index ddb63cebb..206b663c0 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -161,8 +161,9 @@ enum { USBD_CLASS_DRIVER_COUNT = sizeof(usbd_class_drivers) / sizeof(usbd_class_ //--------------------------------------------------------------------+ OSAL_TASK_DEF(_usbd_task_def, "usbd", usbd_task, CFG_TUD_TASK_PRIO, CFG_TUD_TASK_STACK_SZ); -/*------------- event queue -------------*/ -OSAL_QUEUE_DEF(_usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); +// Event queue +// role device/host is used by OS NONE for mutex (disable usb isr) only +OSAL_QUEUE_DEF(OPT_MODE_DEVICE, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); static osal_queue_t _usbd_q; //--------------------------------------------------------------------+ @@ -200,15 +201,8 @@ tusb_error_t usbd_init (void) for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) usbd_class_drivers[i].init(); // Init device controller driver - #if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) - dcd_init(0); - dcd_int_enable(0); - #endif - - #if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) - dcd_init(1); - dcd_int_enable(1); - #endif + dcd_init(TUD_OPT_RHPORT); + dcd_int_enable(TUD_OPT_RHPORT); return TUSB_ERROR_NONE; } @@ -268,14 +262,14 @@ static void usbd_task_body(void) break; case DCD_EVENT_BUS_RESET: - // note: if task is too slow, we could clear the event of the new attached usbd_reset(event.rhport); + // TODO remove since if task is too slow, we could clear the event of the new attached osal_queue_reset(_usbd_q); break; case DCD_EVENT_UNPLUGGED: - // note: if task is too slow, we could clear the event of the new attached usbd_reset(event.rhport); + // TODO remove since if task is too slow, we could clear the event of the new attached osal_queue_reset(_usbd_q); tud_umount_cb(); // invoke callback @@ -587,6 +581,11 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) TU_ASSERT(event->xfer_complete.result == XFER_RESULT_SUCCESS,); break; + // Not an DCD event, just a convenient way to defer ISR function should we need + case USBD_EVT_FUNC_CALL: + osal_queue_send(_usbd_q, event, in_isr); + break; + default: break; } } @@ -622,6 +621,8 @@ void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_ //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ + +// Helper to parse an pair of endpoint descriptors (IN & OUT) tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in) { for(int i=0; i<2; i++) @@ -645,7 +646,8 @@ tusb_error_t usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_d return TUSB_ERROR_NONE; } -void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr ) +// Helper to defer an isr function +void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { dcd_event_t event = { @@ -656,7 +658,7 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr ) event.func_call.func = func; event.func_call.param = param; - osal_queue_send(_usbd_q, &event, in_isr); + dcd_event_handler(&event, in_isr); } #endif diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 52cadd798..704aafd64 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -139,7 +139,9 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ -#define OSAL_QUEUE_DEF(_name, _depth, _type) \ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index cb09680e0..62b5b45e8 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -75,7 +75,9 @@ static inline void osal_task_delay(uint32_t msec) //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ -#define OSAL_QUEUE_DEF(_name, _depth, _type) \ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ static struct os_event* _name##_##evbuf[_depth];\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 40ecb9c37..115c50bdb 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -93,12 +93,11 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { (void) msec; while (true) { - while (sem_hdl->count == 0) { - } - if (sem_hdl->count == 0) { - sem_hdl->count--; - break; - } + while (sem_hdl->count == 0) { } + if (sem_hdl->count == 0) { + sem_hdl->count--; + break; + } } return TUSB_ERROR_NONE; } @@ -124,40 +123,90 @@ static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" -#define OSAL_QUEUE_DEF(_name, _depth, _type) TU_FIFO_DEF(_name, _depth, _type, false) +typedef struct +{ + uint8_t role; // device or host + tu_fifo_t ff; +}osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ + uint8_t _name##_buf[_depth*sizeof(_type)]; \ + osal_queue_def_t _name = { \ + .role = _role, \ + .ff = { \ + .buffer = _name##_buf, \ + .depth = _depth, \ + .item_size = sizeof(_type), \ + .overwritable = false, \ + }\ + } + +// lock queue by disable usb isr +static inline void _osal_q_lock(osal_queue_t qhdl) +{ +#if TUSB_OPT_DEVICE_ENABLED + extern void dcd_int_disable(uint8_t rhport); + if (qhdl->role == OPT_MODE_DEVICE) dcd_int_disable(TUD_OPT_RHPORT); +#endif -typedef tu_fifo_t osal_queue_def_t; -typedef tu_fifo_t* osal_queue_t; +#if MODE_HOST_SUPPORTED + extern void hcd_int_disable(uint8_t rhport); + if (qhdl->role == OPT_MODE_HOST) hcd_int_disable(TUH_OPT_RHPORT); +#endif +} + +// unlock queue +static inline void _osal_q_unlock(osal_queue_t qhdl) +{ +#if TUSB_OPT_DEVICE_ENABLED + extern void dcd_int_enable(uint8_t rhport); + if (qhdl->role == OPT_MODE_DEVICE) dcd_int_enable(TUD_OPT_RHPORT); +#endif + +#if MODE_HOST_SUPPORTED + extern void hcd_int_enable(uint8_t rhport); + if (qhdl->role == OPT_MODE_HOST) hcd_int_enable(TUH_OPT_RHPORT); +#endif +} static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { - tu_fifo_clear(qdef); + tu_fifo_clear(&qdef->ff); return (osal_queue_t) qdef; } -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) +static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr) { if (!in_isr) { - tusb_hal_int_disable_all(); + _osal_q_lock(qhdl); } - bool success = tu_fifo_write( (tu_fifo_t*) queue_hdl, data); + + bool success = tu_fifo_write(&qhdl->ff, data); + if (!in_isr) { - tusb_hal_int_enable_all(); + _osal_q_unlock(qhdl); } + return success; } -static inline void osal_queue_reset(osal_queue_t const queue_hdl) +static inline void osal_queue_reset(osal_queue_t const qhdl) { // tusb_hal_int_disable_all(); - tu_fifo_clear( (tu_fifo_t*) queue_hdl); + tu_fifo_clear(&qhdl->ff); // tusb_hal_int_enable_all(); } -static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) { - tusb_hal_int_disable_all(); - bool success = tu_fifo_read(queue_hdl, data); - tusb_hal_int_enable_all(); +// non blocking +static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data) +{ + _osal_q_lock(qhdl); + bool success = tu_fifo_read(&qhdl->ff, data); + _osal_q_unlock(qhdl); + return success; } diff --git a/src/tusb_hal.h b/src/tusb_hal.h index 301e8c2f2..804196ad2 100644 --- a/src/tusb_hal.h +++ b/src/tusb_hal.h @@ -55,38 +55,6 @@ extern "C" { // Only required to implement if using No RTOS (osal_none) uint32_t tusb_hal_millis(void); -// TODO remove -extern void dcd_int_enable (uint8_t rhport); -extern void dcd_int_disable(uint8_t rhport); - -// Enable all ports' interrupt -// TODO remove -static inline void tusb_hal_int_enable_all(void) -{ -#ifdef CFG_TUSB_RHPORT0_MODE - dcd_int_enable(0); -#endif - -#ifdef CFG_TUSB_RHPORT0_MODE - dcd_int_enable(1); -#endif -} - -// Disable all ports' interrupt -// TODO remove -static inline void tusb_hal_int_disable_all(void) -{ -#ifdef CFG_TUSB_RHPORT0_MODE - dcd_int_disable(0); -#endif - -#ifdef CFG_TUSB_RHPORT0_MODE - dcd_int_disable(1); -#endif -} - - - #ifdef __cplusplus } #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index c558b30ff..6b84db21c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -123,7 +123,6 @@ // Which roothub port is configured as device #define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) ) - #if TUD_OPT_RHPORT == 0 #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) #else -- cgit v1.3.1 From 27793cbd3dba550f9a7124d5e539325904b795e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 5 Dec 2018 17:43:09 +0700 Subject: fix travis build --- src/osal/osal_none.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/osal') diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 115c50bdb..4d5a4dd57 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -123,6 +123,17 @@ static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) //--------------------------------------------------------------------+ #include "common/tusb_fifo.h" +// extern to avoid including dcd.h and hcd.h +#if TUSB_OPT_DEVICE_ENABLED +extern void dcd_int_disable(uint8_t rhport); +extern void dcd_int_enable(uint8_t rhport); +#endif + +#if MODE_HOST_SUPPORTED +extern void hcd_int_disable(uint8_t rhport); +extern void hcd_int_enable(uint8_t rhport); +#endif + typedef struct { uint8_t role; // device or host @@ -148,12 +159,10 @@ typedef osal_queue_def_t* osal_queue_t; static inline void _osal_q_lock(osal_queue_t qhdl) { #if TUSB_OPT_DEVICE_ENABLED - extern void dcd_int_disable(uint8_t rhport); if (qhdl->role == OPT_MODE_DEVICE) dcd_int_disable(TUD_OPT_RHPORT); #endif #if MODE_HOST_SUPPORTED - extern void hcd_int_disable(uint8_t rhport); if (qhdl->role == OPT_MODE_HOST) hcd_int_disable(TUH_OPT_RHPORT); #endif } @@ -162,12 +171,10 @@ static inline void _osal_q_lock(osal_queue_t qhdl) static inline void _osal_q_unlock(osal_queue_t qhdl) { #if TUSB_OPT_DEVICE_ENABLED - extern void dcd_int_enable(uint8_t rhport); if (qhdl->role == OPT_MODE_DEVICE) dcd_int_enable(TUD_OPT_RHPORT); #endif #if MODE_HOST_SUPPORTED - extern void hcd_int_enable(uint8_t rhport); if (qhdl->role == OPT_MODE_HOST) hcd_int_enable(TUH_OPT_RHPORT); #endif } -- cgit v1.3.1 From 4537ba66e536eb1d40c73f80ab150d92c2393397 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 5 Dec 2018 18:58:30 +0700 Subject: fixing build error with host stack --- examples/host/cdc_msc_hid/src/tusb_config.h | 33 ++------ src/device/usbd.c | 2 +- src/host/ehci/ehci.c | 1 - src/host/usbh.c | 117 +++++++++++++++------------- src/host/usbh.h | 2 +- src/host/usbh_hcd.h | 3 + src/osal/osal_freertos.h | 4 +- src/tusb.c | 9 ++- 8 files changed, 82 insertions(+), 89 deletions(-) (limited to 'src/osal') diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 22e67cbda..9fef03af8 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -56,7 +56,7 @@ #endif #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_NONE | OPT_MODE_HIGH_SPEED) +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) #else #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #endif @@ -82,32 +82,15 @@ //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUD_ENDOINT0_SIZE 64 -/*------------- Descriptors -------------*/ +#define CFG_TUSB_HOST_HUB 0 +#define CFG_TUSB_HOST_HID_KEYBOARD 0 +#define CFG_TUSB_HOST_HID_MOUSE 0 +#define CFG_TUSB_HOST_HID_GENERIC 0 // (not yet supported) +#define CFG_TUSB_HOST_MSC 0 +#define CFG_TUSB_HOST_CDC 0 -/* Enable auto generated descriptor, tinyusb will try its best to create - * descriptor ( device, configuration, hid ) that matches enabled CFG_* in this file - * - * Note: All CFG_TUD_DESC_* are relevant only if CFG_TUD_DESC_AUTO is enabled - */ -#define CFG_TUD_DESC_AUTO 1 - -/* If USB VID/PID is not defined, tinyusb will use default value - * Note: different class combination e.g CDC and (CDC + MSC) should have different - * PID since Host OS will "remembered" device driver after the first plug */ -// #define CFG_TUD_DESC_VID 0xCAFE -// #define CFG_TUD_DESC_PID 0x0001 - -// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number -// Therefor we need to force endpoint number to correct type on lpc17xx -#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX -#define CFG_TUD_DESC_CDC_EPNUM_NOTIF 1 -#define CFG_TUD_DESC_CDC_EPNUM 2 -#define CFG_TUD_DESC_MSC_EPNUM 5 -#define CFG_TUD_DESC_HID_KEYBOARD_EPNUM 4 -#define CFG_TUD_DESC_HID_MOUSE_EPNUM 7 -#endif +#define CFG_TUSB_HOST_DEVICE_MAX (CFG_TUSB_HOST_HUB ? 5 : 1) // normal hub has 4 ports //------------- CLASS -------------// #define CFG_TUD_CDC 0 diff --git a/src/device/usbd.c b/src/device/usbd.c index 78eebf76b..121ee3da9 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -298,7 +298,7 @@ static void usbd_task_body(void) /* USB device task * Thread that handles all device events. With an real RTOS, the task must be a forever loop and never return. - * For codign convenience with no RTOS, we use wrapped sub-function for processing to easily return at any time. + * For coding convenience with no RTOS, we use wrapped sub-function for processing to easily return at any time. */ void usbd_task( void* param) { diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 27808d59b..491651f5c 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -42,7 +42,6 @@ //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#include "hal/hal.h" #include "osal/osal.h" #include "../hcd.h" diff --git a/src/host/usbh.c b/src/host/usbh.c index a0aab3b96..3bb90e71d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -42,10 +42,19 @@ #define _TINY_USB_SOURCE_FILE_ -#ifndef CFG_TUD_TASK_PRIO -#define CFG_TUD_TASK_PRIO 0 +#ifndef CFG_TUH_TASK_QUEUE_SZ +#define CFG_TUH_TASK_QUEUE_SZ 16 #endif +#ifndef CFG_TUH_TASK_STACK_SZ +#define CFG_TUH_TASK_STACK_SZ 200 +#endif + +#ifndef CFG_TUH_TASK_PRIO +#define CFG_TUH_TASK_PRIO 0 +#endif + + //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ @@ -111,10 +120,13 @@ enum { USBH_CLASS_DRIVER_COUNT = sizeof(usbh_class_drivers) / sizeof(host_class_ //--------------------------------------------------------------------+ CFG_TUSB_MEM_SECTION usbh_device_info_t usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1]; // including zero-address -//------------- Enumeration Task Data -------------/ -enum { ENUM_QUEUE_DEPTH = 16 }; +OSAL_TASK_DEF(_usbh_task_def, "usbh", usbh_task, CFG_TUH_TASK_PRIO, CFG_TUH_TASK_STACK_SZ); + +// Event queue +// role device/host is used by OS NONE for mutex (disable usb isr) only +OSAL_QUEUE_DEF(OPT_MODE_HOST, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, uint32_t); +static osal_queue_t _usbh_q; -STATIC_VAR osal_queue_t enum_queue_hdl; CFG_TUSB_MEM_SECTION ATTR_ALIGNED(4) STATIC_VAR uint8_t enum_data_buffer[CFG_TUSB_HOST_ENUM_BUFFER_SIZE]; //------------- Reporter Task Data -------------// @@ -144,23 +156,21 @@ tusb_error_t usbh_init(void) { tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); - TU_ASSERT_ERR( hcd_init() ); - //------------- Enumeration & Reporter Task init -------------// - enum_queue_hdl = osal_queue_create( ENUM_QUEUE_DEPTH, sizeof(uint32_t) ); - TU_ASSERT(enum_queue_hdl, TUSB_ERROR_OSAL_QUEUE_FAILED); + _usbh_q = osal_queue_create( &_usbh_qdef ); + TU_ASSERT(_usbh_q, TUSB_ERROR_OSAL_QUEUE_FAILED); - osal_task_create(usbh_enumeration_task, "usbh", 200, NULL, CFG_TUD_TASK_PRIO); + osal_task_create(&_usbh_task_def); //------------- Semaphore, Mutex for Control Pipe -------------// for(uint8_t i=0; icontrol.sem_hdl = osal_semaphore_create(1, 0); + p_device->control.sem_hdl = osal_semaphore_create(&p_device->control.sem_def); TU_ASSERT(p_device->control.sem_hdl, TUSB_ERROR_OSAL_SEMAPHORE_FAILED); - p_device->control.mutex_hdl = osal_mutex_create(); + p_device->control.mutex_hdl = osal_mutex_create(&p_device->control.mutex_def); TU_ASSERT(p_device->control.mutex_hdl, TUSB_ERROR_OSAL_MUTEX_FAILED); } @@ -173,6 +183,8 @@ tusb_error_t usbh_init(void) } } + TU_ASSERT_ERR( hcd_init() ); + return TUSB_ERROR_NONE; } @@ -181,12 +193,13 @@ tusb_error_t usbh_init(void) tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data) { - static tusb_error_t error; // FIXME [CMSIS-RTX] use svc for OS API, error value changed after mutex release at the end of function + // FIXME [CMSIS-RTX] use svc for OS API, error value changed after mutex release at the end of function + static tusb_error_t error; - OSAL_SUBTASK_BEGIN +// OSAL_SUBTASK_BEGIN - osal_mutex_wait(usbh_devices[dev_addr].control.mutex_hdl, OSAL_TIMEOUT_NORMAL, &error); - STASK_ASSERT_ERR_HDLR(error, osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl)); + error = osal_mutex_lock(usbh_devices[dev_addr].control.mutex_hdl, OSAL_TIMEOUT_NORMAL); + STASK_ASSERT_ERR_HDLR(error, osal_mutex_unlock(usbh_devices[dev_addr].control.mutex_hdl)); usbh_devices[dev_addr].control.request = (tusb_control_request_t) { {.bmRequestType = bmRequestType}, @@ -195,16 +208,11 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, .wIndex = wIndex, .wLength = wLength }; - -#ifndef _TEST_ usbh_devices[dev_addr].control.pipe_status = 0; -#else - usbh_devices[dev_addr].control.pipe_status = XFER_RESULT_SUCCESS; // in Test project, mark as complete immediately -#endif error = hcd_pipe_control_xfer(dev_addr, &usbh_devices[dev_addr].control.request, data); - if ( TUSB_ERROR_NONE == error ) osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL, &error); - osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl); + if ( TUSB_ERROR_NONE == error ) error = osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL); + osal_mutex_unlock(usbh_devices[dev_addr].control.mutex_hdl); STASK_ASSERT_ERR(error); if (XFER_RESULT_STALLED == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_STALLED); @@ -214,10 +222,9 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, // XFER_RESULT_SUCCESS == usbh_devices[dev_addr].control.pipe_status, // tuh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) ); - OSAL_SUBTASK_END +// OSAL_SUBTASK_END } -tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) ATTR_ALWAYS_INLINE; tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) { osal_semaphore_reset( usbh_devices[dev_addr].control.sem_hdl ); @@ -228,7 +235,6 @@ tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) return TUSB_ERROR_NONE; } -static inline tusb_error_t usbh_pipe_control_close(uint8_t dev_addr) ATTR_ALWAYS_INLINE; static inline tusb_error_t usbh_pipe_control_close(uint8_t dev_addr) { TU_ASSERT_ERR( hcd_pipe_control_close(dev_addr) ); @@ -263,13 +269,13 @@ void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, xfer_result_t eve { usbh_devices[ pipe_hdl.dev_addr ].control.pipe_status = event; // usbh_devices[ pipe_hdl.dev_addr ].control.xferred_bytes = xferred_bytes; not yet neccessary - osal_semaphore_post( usbh_devices[ pipe_hdl.dev_addr ].control.sem_hdl ); + osal_semaphore_post( usbh_devices[ pipe_hdl.dev_addr ].control.sem_hdl, true ); }else if (usbh_class_drivers[class_index].isr) { usbh_class_drivers[class_index].isr(pipe_hdl, event, xferred_bytes); }else { - TU_ASSERT(false); // something wrong, no one claims the isr's source + TU_ASSERT(false, ); // something wrong, no one claims the isr's source } } @@ -282,7 +288,7 @@ void usbh_hub_port_plugged_isr(uint8_t hub_addr, uint8_t hub_port) .hub_port = hub_port }; - osal_queue_send(enum_queue_hdl, &enum_entry); + osal_queue_send(_usbh_q, &enum_entry, true); } void usbh_hcd_rhport_plugged_isr(uint8_t hostid) @@ -294,7 +300,7 @@ void usbh_hcd_rhport_plugged_isr(uint8_t hostid) .hub_port = 0 }; - osal_queue_send(enum_queue_hdl, &enum_entry); + osal_queue_send(_usbh_q, &enum_entry, true); } // a device unplugged on hostid, hub_addr, hub_port @@ -346,33 +352,13 @@ void usbh_hcd_rhport_unplugged_isr(uint8_t hostid) .hub_port = 0 }; - osal_queue_send(enum_queue_hdl, &enum_entry); + osal_queue_send(_usbh_q, &enum_entry, true); } //--------------------------------------------------------------------+ // ENUMERATION TASK //--------------------------------------------------------------------+ -static tusb_error_t enumeration_body_subtask(void); - -// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper -// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with -// forever loop cannot have any return at all. -void usbh_enumeration_task(void* param) -{ - (void) param; - -#if CFG_TUSB_OS != OPT_OS_NONE - while (1) { -#endif - - enumeration_body_subtask(); - -#if CFG_TUSB_OS != OPT_OS_NONE - } -#endif -} - -tusb_error_t enumeration_body_subtask(void) +tusb_error_t usbh_task_body(void) { enum { POWER_STABLE_DELAY = 500, @@ -387,10 +373,9 @@ tusb_error_t enumeration_body_subtask(void) static uint8_t configure_selected = 1; // TODO move static uint8_t *p_desc = NULL; // TODO move - OSAL_SUBTASK_BEGIN +// OSAL_SUBTASK_BEGIN - osal_queue_receive(enum_queue_hdl, &enum_entry, OSAL_TIMEOUT_WAIT_FOREVER, &error); - STASK_ASSERT_ERR(error); + if ( !osal_queue_receive(_usbh_q, &enum_entry) ) return; usbh_devices[0].core_id = enum_entry.core_id; // TODO refractor integrate to device_pool usbh_devices[0].hub_addr = enum_entry.hub_addr; @@ -617,7 +602,27 @@ tusb_error_t enumeration_body_subtask(void) tuh_device_mount_succeed_cb(new_addr); - OSAL_SUBTASK_END +// OSAL_SUBTASK_END +} + + +/* USB Host task + * Thread that handles all device events. With an real RTOS, the task must be a forever loop and never return. + * For coding convenience with no RTOS, we use wrapped sub-function for processing to easily return at any time. + */ +void usbh_task(void* param) +{ + (void) param; + +#if CFG_TUSB_OS != OPT_OS_NONE + while (1) { +#endif + + usbh_task_body(); + +#if CFG_TUSB_OS != OPT_OS_NONE + } +#endif } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.h b/src/host/usbh.h index 56efb6ff7..22c85a5d0 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -97,7 +97,7 @@ ATTR_WEAK void tuh_device_mount_failed_cb(tusb_error_t error, tusb_desc_devic //--------------------------------------------------------------------+ #ifdef _TINY_USB_SOURCE_FILE_ -void usbh_enumeration_task(void* param); +void usbh_task(void* param); tusb_error_t usbh_init(void); tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest, diff --git a/src/host/usbh_hcd.h b/src/host/usbh_hcd.h index f6b72273a..cd2a712e4 100644 --- a/src/host/usbh_hcd.h +++ b/src/host/usbh_hcd.h @@ -91,7 +91,10 @@ typedef struct { // uint8_t xferred_bytes; TODO not yet necessary tusb_control_request_t request; + osal_semaphore_def_t sem_def; osal_semaphore_t sem_hdl; // used to synchronize with HCD when control xfer complete + + osal_mutex_def_t mutex_def; osal_mutex_t mutex_hdl; // used to exclusively occupy control pipe } control; } usbh_device_info_t; diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 704aafd64..458e54b5c 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -107,10 +107,10 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl); } -static inline void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, uint32_t *err) +static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - (*err) = (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); + return (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); } static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) diff --git a/src/tusb.c b/src/tusb.c index fe4dbb2c1..6d2b92dc8 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -39,14 +39,17 @@ #include "tusb_option.h" #if TUSB_OPT_HOST_ENABLED || TUSB_OPT_DEVICE_ENABLED - #define _TINY_USB_SOURCE_FILE_ #include "tusb.h" -#include "device/usbd_pvt.h" static bool _initialized = false; +// TODO clean up +#if TUSB_OPT_DEVICE_ENABLED +#include "device/usbd_pvt.h" +#endif + bool tusb_init(void) { // skip if already initialized @@ -69,7 +72,7 @@ bool tusb_init(void) void tusb_task(void) { #if MODE_HOST_SUPPORTED - usbh_enumeration_task(NULL); + usbh_task(NULL); #endif #if TUSB_OPT_DEVICE_ENABLED -- cgit v1.3.1 From 5a7493ed42d4aa2519e7e3377ed7168a2ceca373 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 5 Dec 2018 21:12:10 +0700 Subject: fix more host build error --- examples/host/cdc_msc_hid/src/main.c | 4 ++-- src/host/ehci/ehci.c | 3 +-- src/host/usbh.c | 25 +++++++++++++------------ src/host/usbh.h | 2 +- src/osal/osal_none.h | 6 ++++++ src/tusb.c | 2 +- 6 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/osal') diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index a8a34ef8f..2459ec329 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -58,11 +58,11 @@ int main(void) board_init(); print_greeting(); - //tusb_init(); + tusb_init(); while (1) { - //tusb_task(); + tusb_task(); led_blinking_task(); diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 1dbf03682..abf5e5613 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -180,9 +180,8 @@ static tusb_error_t hcd_controller_init(uint8_t hostid) //------------- CTRLDSSEGMENT Register (skip) -------------// //------------- USB INT Register -------------// regs->usb_int_enable = 0; // 1. disable all the interrupt -#ifndef _TEST_ // the fake controller does not have write-to-clear behavior regs->usb_sts = EHCI_INT_MASK_ALL; // 2. clear all status -#endif + regs->usb_int_enable = EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | #if EHCI_PERIODIC_LIST EHCI_INT_MASK_NXP_PERIODIC | diff --git a/src/host/usbh.c b/src/host/usbh.c index a0df57657..80e59037f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -152,13 +152,13 @@ uint32_t tuh_device_get_mounted_class_flag(uint8_t dev_addr) //--------------------------------------------------------------------+ // CLASS-USBD API (don't require to verify parameters) //--------------------------------------------------------------------+ -tusb_error_t usbh_init(void) +bool usbh_init(void) { tu_memclr(usbh_devices, sizeof(usbh_device_info_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); //------------- Enumeration & Reporter Task init -------------// _usbh_q = osal_queue_create( &_usbh_qdef ); - TU_ASSERT(_usbh_q, TUSB_ERROR_OSAL_QUEUE_FAILED); + TU_ASSERT(_usbh_q != NULL); osal_task_create(&_usbh_task_def); @@ -168,10 +168,10 @@ tusb_error_t usbh_init(void) usbh_device_info_t * const p_device = &usbh_devices[i]; p_device->control.sem_hdl = osal_semaphore_create(&p_device->control.sem_def); - TU_ASSERT(p_device->control.sem_hdl, TUSB_ERROR_OSAL_SEMAPHORE_FAILED); + TU_ASSERT(p_device->control.sem_hdl != NULL); p_device->control.mutex_hdl = osal_mutex_create(&p_device->control.mutex_def); - TU_ASSERT(p_device->control.mutex_hdl, TUSB_ERROR_OSAL_MUTEX_FAILED); + TU_ASSERT(p_device->control.mutex_hdl != NULL); } //------------- class init -------------// @@ -183,9 +183,10 @@ tusb_error_t usbh_init(void) } } - TU_ASSERT_ERR( hcd_init() ); + TU_ASSERT( hcd_init() == TUSB_ERROR_NONE ); + hcd_int_enable(TUH_OPT_RHPORT); - return TUSB_ERROR_NONE; + return true; } //------------- USBH control transfer -------------// @@ -199,7 +200,7 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, // OSAL_SUBTASK_BEGIN error = osal_mutex_lock(usbh_devices[dev_addr].control.mutex_hdl, OSAL_TIMEOUT_NORMAL); - STASK_ASSERT_ERR_HDLR(error, osal_mutex_unlock(usbh_devices[dev_addr].control.mutex_hdl)); + TU_VERIFY_ERR_HDLR(error, osal_mutex_unlock(usbh_devices[dev_addr].control.mutex_hdl)); usbh_devices[dev_addr].control.request = (tusb_control_request_t) { {.bmRequestType = bmRequestType}, @@ -214,9 +215,9 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, if ( TUSB_ERROR_NONE == error ) error = osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL); osal_mutex_unlock(usbh_devices[dev_addr].control.mutex_hdl); - STASK_ASSERT_ERR(error); - if (XFER_RESULT_STALLED == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_STALLED); - if (XFER_RESULT_FAILED == usbh_devices[dev_addr].control.pipe_status) STASK_RETURN(TUSB_ERROR_USBH_XFER_FAILED); + TU_ASSERT_ERR(error); + if (XFER_RESULT_STALLED == usbh_devices[dev_addr].control.pipe_status) return (TUSB_ERROR_USBH_XFER_STALLED); + if (XFER_RESULT_FAILED == usbh_devices[dev_addr].control.pipe_status) return (TUSB_ERROR_USBH_XFER_FAILED); // STASK_ASSERT_HDLR(TUSB_ERROR_NONE == error && // XFER_RESULT_SUCCESS == usbh_devices[dev_addr].control.pipe_status, @@ -228,7 +229,7 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) { osal_semaphore_reset( usbh_devices[dev_addr].control.sem_hdl ); - osal_mutex_reset( usbh_devices[dev_addr].control.mutex_hdl ); + //osal_mutex_reset( usbh_devices[dev_addr].control.mutex_hdl ); TU_ASSERT_ERR( hcd_pipe_control_open(dev_addr, max_packet_size) ); @@ -373,7 +374,7 @@ tusb_error_t usbh_task_body(void) static uint8_t configure_selected = 1; // TODO move static uint8_t *p_desc = NULL; // TODO move - if ( !osal_queue_receive(_usbh_q, &enum_entry) ) return; + if ( !osal_queue_receive(_usbh_q, &enum_entry) ) return TUSB_ERROR_NONE; usbh_devices[0].core_id = enum_entry.core_id; // TODO refractor integrate to device_pool usbh_devices[0].hub_addr = enum_entry.hub_addr; diff --git a/src/host/usbh.h b/src/host/usbh.h index 22c85a5d0..f4433ae31 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -97,8 +97,8 @@ ATTR_WEAK void tuh_device_mount_failed_cb(tusb_error_t error, tusb_desc_devic //--------------------------------------------------------------------+ #ifdef _TINY_USB_SOURCE_FILE_ +bool usbh_init(void); void usbh_task(void* param); -tusb_error_t usbh_init(void); tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data); diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 4d5a4dd57..042c7a6e8 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -62,6 +62,12 @@ static inline bool osal_task_create(osal_task_def_t* taskdef) return true; } +static inline void osal_task_delay(uint32_t msec) +{ + uint32_t start = tusb_hal_millis(); + while ( ( tusb_hal_millis() - start ) < msec ) {} +} + //--------------------------------------------------------------------+ // Binary Semaphore API //--------------------------------------------------------------------+ diff --git a/src/tusb.c b/src/tusb.c index 6d2b92dc8..931cc0ebe 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -56,7 +56,7 @@ bool tusb_init(void) if (_initialized) return true; #if MODE_HOST_SUPPORTED - TU_VERIFY( usbh_init() == TUSB_ERROR_NONE ); // init host stack + TU_VERIFY( usbh_init() ); // init host stack #endif #if TUSB_OPT_DEVICE_ENABLED -- cgit v1.3.1 From 5f7d7a34f576dabd94c10fad05fe5fa85d4ef1e0 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Dec 2018 00:38:00 +0700 Subject: able to complete enumeration with os none blocking --- examples/host/cdc_msc_hid/src/main.c | 23 +++++++++++++++++++++-- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- src/class/cdc/cdc_host.c | 4 ++-- src/osal/osal_none.h | 15 +++++++-------- 4 files changed, 31 insertions(+), 13 deletions(-) (limited to 'src/osal') diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 2459ec329..c888f7bf7 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -66,7 +66,7 @@ int main(void) led_blinking_task(); -#if CFG_TUD_CDC +#if CFG_TUSB_HOST_CDC virtual_com_task(); #endif @@ -81,7 +81,26 @@ int main(void) //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -#if CFG_TUD_CDC +#if CFG_TUSB_HOST_CDC + +void tuh_cdc_mounted_cb(uint8_t dev_addr) +{ + // application set-up + printf("\na CDC device (address %d) is mounted\n", dev_addr); +} + +void tuh_cdc_unmounted_cb(uint8_t dev_addr) +{ + // application tear-down + printf("\na CDC device (address %d) is unmounted \n", dev_addr); +} + +// invoked ISR context +void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) +{ + +} + void virtual_com_task(void) { diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 9fef03af8..4b39d6d18 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -88,7 +88,7 @@ #define CFG_TUSB_HOST_HID_MOUSE 0 #define CFG_TUSB_HOST_HID_GENERIC 0 // (not yet supported) #define CFG_TUSB_HOST_MSC 0 -#define CFG_TUSB_HOST_CDC 0 +#define CFG_TUSB_HOST_CDC 1 #define CFG_TUSB_HOST_DEVICE_MAX (CFG_TUSB_HOST_HUB ? 5 : 1) // normal hub has 4 ports diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 0a3661878..27ef502e0 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -144,7 +144,7 @@ void cdch_init(void) tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) { - OSAL_SUBTASK_BEGIN + //OSAL_SUBTASK_BEGIN // TODO change following assert to subtask_assert if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS; @@ -218,7 +218,7 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_ tuh_cdc_mounted_cb(dev_addr); } - OSAL_SUBTASK_END + //OSAL_SUBTASK_END } void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes) diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 042c7a6e8..61ed0d45e 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -96,15 +96,14 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) sem_hdl->count = 0; } -static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { +static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) +{ (void) msec; - while (true) { - while (sem_hdl->count == 0) { } - if (sem_hdl->count == 0) { - sem_hdl->count--; - break; - } - } + + // TODO blocking for now + while (sem_hdl->count == 0) { } + sem_hdl->count--; + return TUSB_ERROR_NONE; } -- cgit v1.3.1 From 1d3583785f9f890da2e6ac720d1327ab0452f974 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 6 Dec 2018 17:31:25 +0700 Subject: change osal_semaphore_wait to return bool --- src/osal/osal.h | 2 +- src/osal/osal_freertos.h | 4 ++-- src/osal/osal_none.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/osal') diff --git a/src/osal/osal.h b/src/osal/osal.h index 6846b5757..55e3e077c 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -83,7 +83,7 @@ typedef void (*osal_task_func_t)( void * ); * osal_semaphore_def_t, osal_semaphore_t * osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) * bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) - * void osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec, uint32_t *p_error) + * bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) * void osal_semaphore_reset(osal_semaphore_t const sem_hdl) * * Mutex diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 458e54b5c..acec4a95d 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -107,10 +107,10 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl); } -static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec); - return (xSemaphoreTake(sem_hdl, ticks) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT); + return xSemaphoreTake(sem_hdl, ticks); } static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 61ed0d45e..4da5cffc8 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -96,15 +96,15 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) sem_hdl->count = 0; } -static inline tusb_error_t osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) +// TODO blocking for now +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) { (void) msec; - // TODO blocking for now while (sem_hdl->count == 0) { } sem_hdl->count--; - return TUSB_ERROR_NONE; + return true; } //--------------------------------------------------------------------+ -- cgit v1.3.1 From 607658d047a3c27a096b9f6a25ea0a76f3d8735d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 7 Dec 2018 23:38:52 +0700 Subject: rename MODE_HOST_SUPPORTED to TUSB_OPT_HOST_ENABLED --- hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c | 2 +- src/class/cdc/cdc_host.c | 2 +- src/class/cdc/cdc_rndis_host.c | 2 +- src/class/custom/custom_host.c | 2 +- src/class/hid/hid_host.c | 2 +- src/class/msc/msc_host.c | 2 +- src/host/ehci/ehci.c | 2 +- src/host/hcd.h | 2 +- src/host/hub.c | 2 +- src/host/ohci/ohci.c | 2 +- src/host/usbh.c | 2 +- src/osal/osal_none.h | 6 +++--- src/portable/nxp/lpc17_40/hal_lpc17_40.c | 2 +- src/portable/nxp/lpc18_43/hal_lpc18_43.c | 4 ++-- src/tusb.c | 4 ++-- src/tusb.h | 2 +- src/tusb_option.h | 11 ++--------- 17 files changed, 22 insertions(+), 29 deletions(-) (limited to 'src/osal') diff --git a/hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c b/hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c index 0c5f5189c..427e8733c 100644 --- a/hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c +++ b/hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c @@ -148,7 +148,7 @@ void board_init(void) LPC_USB->OTGClkCtrl = clk_en; while ( (LPC_USB->OTGClkSt & clk_en) != clk_en ); -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED // set portfunc to host !!! LPC_USB->StCtrl = 0x3; // should be 1 #endif diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index c4ec88416..8d7c2bd40 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -38,7 +38,7 @@ #include "tusb_option.h" -#if (MODE_HOST_SUPPORTED && CFG_TUH_CDC) +#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC) #define _TINY_USB_SOURCE_FILE_ diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index df4a29938..ae61bf8b5 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -38,7 +38,7 @@ #include "tusb_option.h" -#if (MODE_HOST_SUPPORTED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS) +#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS) #define _TINY_USB_SOURCE_FILE_ diff --git a/src/class/custom/custom_host.c b/src/class/custom/custom_host.c index 9f0b70afb..2a8206e36 100644 --- a/src/class/custom/custom_host.c +++ b/src/class/custom/custom_host.c @@ -38,7 +38,7 @@ #include "tusb_option.h" -#if (MODE_HOST_SUPPORTED && CFG_TUSB_HOST_CUSTOM_CLASS) +#if (TUSB_OPT_HOST_ENABLED && CFG_TUSB_HOST_CUSTOM_CLASS) #define _TINY_USB_SOURCE_FILE_ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 14398aa67..980381bf5 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -38,7 +38,7 @@ #include "tusb_option.h" -#if (MODE_HOST_SUPPORTED && HOST_CLASS_HID) +#if (TUSB_OPT_HOST_ENABLED && HOST_CLASS_HID) #define _TINY_USB_SOURCE_FILE_ //--------------------------------------------------------------------+ diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 0c52011df..57a409ffd 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -38,7 +38,7 @@ #include "tusb_option.h" -#if MODE_HOST_SUPPORTED & CFG_TUH_MSC +#if TUSB_OPT_HOST_ENABLED & CFG_TUH_MSC #define _TINY_USB_SOURCE_FILE_ diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index 8e40804d5..d18f19195 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -38,7 +38,7 @@ #include "common/tusb_common.h" -#if MODE_HOST_SUPPORTED && (CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX) +#if TUSB_OPT_HOST_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ diff --git a/src/host/hcd.h b/src/host/hcd.h index db80994c0..387fbcf1c 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -79,7 +79,7 @@ typedef struct } hcd_event_t; -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED // Max number of endpoints per device enum { HCD_MAX_ENDPOINT = CFG_TUH_HUB + CFG_TUH_HID_KEYBOARD + CFG_TUH_HID_MOUSE + CFG_TUSB_HOST_HID_GENERIC + diff --git a/src/host/hub.c b/src/host/hub.c index 28814ebd7..04618d448 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -38,7 +38,7 @@ #include "tusb_option.h" -#if (MODE_HOST_SUPPORTED && CFG_TUH_HUB) +#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB) #define _TINY_USB_SOURCE_FILE_ diff --git a/src/host/ohci/ohci.c b/src/host/ohci/ohci.c index 3944d72d0..2c22a3c98 100644 --- a/src/host/ohci/ohci.c +++ b/src/host/ohci/ohci.c @@ -38,7 +38,7 @@ #include -#if MODE_HOST_SUPPORTED && (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) +#if TUSB_OPT_HOST_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index 4c4fd5319..d97b4b0d3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -38,7 +38,7 @@ #include "common/tusb_common.h" -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED #define _TINY_USB_SOURCE_FILE_ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 4da5cffc8..ff37113c6 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -134,7 +134,7 @@ extern void dcd_int_disable(uint8_t rhport); extern void dcd_int_enable(uint8_t rhport); #endif -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED extern void hcd_int_disable(uint8_t rhport); extern void hcd_int_enable(uint8_t rhport); #endif @@ -167,7 +167,7 @@ static inline void _osal_q_lock(osal_queue_t qhdl) if (qhdl->role == OPT_MODE_DEVICE) dcd_int_disable(TUD_OPT_RHPORT); #endif -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED if (qhdl->role == OPT_MODE_HOST) hcd_int_disable(TUH_OPT_RHPORT); #endif } @@ -179,7 +179,7 @@ static inline void _osal_q_unlock(osal_queue_t qhdl) if (qhdl->role == OPT_MODE_DEVICE) dcd_int_enable(TUD_OPT_RHPORT); #endif -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED if (qhdl->role == OPT_MODE_HOST) hcd_int_enable(TUH_OPT_RHPORT); #endif } diff --git a/src/portable/nxp/lpc17_40/hal_lpc17_40.c b/src/portable/nxp/lpc17_40/hal_lpc17_40.c index 2acd19f6e..04aebf920 100644 --- a/src/portable/nxp/lpc17_40/hal_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/hal_lpc17_40.c @@ -47,7 +47,7 @@ extern void hal_dcd_isr(uint8_t rhport); void USB_IRQHandler(void) { - #if MODE_HOST_SUPPORTED + #if TUSB_OPT_HOST_ENABLED hal_hcd_isr(0); #endif diff --git a/src/portable/nxp/lpc18_43/hal_lpc18_43.c b/src/portable/nxp/lpc18_43/hal_lpc18_43.c index 48a25f99a..ef3977995 100644 --- a/src/portable/nxp/lpc18_43/hal_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/hal_lpc18_43.c @@ -48,7 +48,7 @@ extern void hal_hcd_isr(uint8_t hostid); #if CFG_TUSB_RHPORT0_MODE void USB0_IRQHandler(void) { - #if MODE_HOST_SUPPORTED + #if TUSB_OPT_HOST_ENABLED hal_hcd_isr(0); #endif @@ -61,7 +61,7 @@ void USB0_IRQHandler(void) #if CFG_TUSB_RHPORT1_MODE void USB1_IRQHandler(void) { - #if MODE_HOST_SUPPORTED + #if TUSB_OPT_HOST_ENABLED hal_hcd_isr(1); #endif diff --git a/src/tusb.c b/src/tusb.c index 931cc0ebe..4f7996664 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -55,7 +55,7 @@ bool tusb_init(void) // skip if already initialized if (_initialized) return true; -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED TU_VERIFY( usbh_init() ); // init host stack #endif @@ -71,7 +71,7 @@ bool tusb_init(void) #if CFG_TUSB_OS == OPT_OS_NONE void tusb_task(void) { - #if MODE_HOST_SUPPORTED + #if TUSB_OPT_HOST_ENABLED usbh_task(NULL); #endif diff --git a/src/tusb.h b/src/tusb.h index e31513f87..4d65c80e1 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -52,7 +52,7 @@ #include "common/tusb_fifo.h" //------------- HOST -------------// -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED #include "host/usbh.h" #if HOST_CLASS_HID diff --git a/src/tusb_option.h b/src/tusb_option.h index ad5025235..e8baf4149 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -109,13 +109,6 @@ #error "tinyusb does not support same modes on more than 1 roothub port" #endif -// TODO remove -#define CONTROLLER_HOST_NUMBER (\ - ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 1 : 0) + \ - ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : 0)) - -#define MODE_HOST_SUPPORTED (CONTROLLER_HOST_NUMBER > 0) - // Which roothub port is configured as host #define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) ) #define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) @@ -206,7 +199,7 @@ //-------------------------------------------------------------------- // HOST OPTIONS //-------------------------------------------------------------------- -#if MODE_HOST_SUPPORTED +#if TUSB_OPT_HOST_ENABLED #ifndef CFG_TUSB_HOST_DEVICE_MAX #define CFG_TUSB_HOST_DEVICE_MAX 1 #warning CFG_TUSB_HOST_DEVICE_MAX is not defined, default value is 1 @@ -228,7 +221,7 @@ #endif //------------- CLASS -------------// -#endif // MODE_HOST_SUPPORTED +#endif // TUSB_OPT_HOST_ENABLED //------------------------------------------------------------------ -- cgit v1.3.1