From 7ff0dbb64cfcab7256a4b113931c63a4c7efa0d3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 8 Nov 2013 14:46:48 +0700 Subject: [PATCH] add tusbd_cdc_is_busy enhance cdc serial device demo refractor fifo.c --- demos/device/device_os_none/cdcd_app.c | 42 +++-- demos/host/host_os_none/host_os_none.uvopt | 16 +- demos/host/src/cdc_serial_app.c | 2 +- tinyusb/class/cdc_device.c | 13 +- tinyusb/class/cdc_device.h | 2 + tinyusb/common/fifo.c | 173 +++++++++------------ tinyusb/common/fifo.h | 47 +++--- 7 files changed, 146 insertions(+), 149 deletions(-) diff --git a/demos/device/device_os_none/cdcd_app.c b/demos/device/device_os_none/cdcd_app.c index 43299cd5a..483312975 100644 --- a/demos/device/device_os_none/cdcd_app.c +++ b/demos/device/device_os_none/cdcd_app.c @@ -39,6 +39,9 @@ #include "cdcd_app.h" #if TUSB_CFG_DEVICE_CDC + +#include "common/fifo.h" // TODO refractor + //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ @@ -54,18 +57,16 @@ OSAL_SEM_DEF(cdcd_semaphore); static osal_semaphore_handle_t sem_hdl; -static uint8_t cdcd_app_recv_buffer[CDCD_APP_BUFFER_SIZE] TUSB_CFG_ATTR_USBRAM; -static uint8_t cdcd_app_send_buffer[CDCD_APP_BUFFER_SIZE] TUSB_CFG_ATTR_USBRAM; - -static uint16_t received_bytes; // set by transfer complete callback +static uint8_t serial_rx_buffer[CDCD_APP_BUFFER_SIZE] TUSB_CFG_ATTR_USBRAM; +static uint8_t serial_tx_buffer[CDCD_APP_BUFFER_SIZE] TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +FIFO_DEF(fifo_serial, CDCD_APP_BUFFER_SIZE, uint8_t, true); //--------------------------------------------------------------------+ // IMPLEMENTATION -//--------------------------------------------------------------------+ void cdcd_serial_app_init(void) { sem_hdl = osal_semaphore_create( OSAL_SEM_REF(cdcd_semaphore) ); @@ -78,8 +79,7 @@ void tusbd_cdc_mounted_cb(uint8_t coreid) { osal_semaphore_reset(sem_hdl); - received_bytes = 0; - tusbd_cdc_receive(coreid, cdcd_app_recv_buffer, CDCD_APP_BUFFER_SIZE, true); + tusbd_cdc_receive(coreid, serial_rx_buffer, CDCD_APP_BUFFER_SIZE, true); } void tusbd_cdc_xfer_isr(uint8_t coreid, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) @@ -90,9 +90,12 @@ void tusbd_cdc_xfer_isr(uint8_t coreid, tusb_event_t event, cdc_pipeid_t pipe_id switch(event) { case TUSB_EVENT_XFER_COMPLETE: - received_bytes = min16_of(xferred_bytes, CDCD_APP_BUFFER_SIZE); // discard overflow bytes + for(uint8_t i=0; i app - 0 + 1 0 0 0 @@ -474,10 +474,10 @@ 1 0 0 - 0 + 3 0 1 - 1 + 2 0 ..\src\cdc_serial_app.c cdc_serial_app.c @@ -736,7 +736,7 @@ tinyusb - 0 + 1 0 0 0 @@ -744,7 +744,7 @@ 3 18 1 - 0 + 1 0 64 0 @@ -924,8 +924,8 @@ 0 0 0 - 0 - 0 + 54 + 62 0 ..\..\..\tinyusb\common\fifo.c fifo.c @@ -1156,7 +1156,7 @@ 0 0 0 - 1705 + 1688 1713 0 ..\..\..\vendor\fatfs\ff.c diff --git a/demos/host/src/cdc_serial_app.c b/demos/host/src/cdc_serial_app.c index 13c544703..b86c4869a 100644 --- a/demos/host/src/cdc_serial_app.c +++ b/demos/host/src/cdc_serial_app.c @@ -92,7 +92,7 @@ void tusbh_cdc_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_ break; case TUSB_EVENT_XFER_ERROR: - xferred_bytes = 0; // ignore + received_bytes = 0; // ignore break; case TUSB_EVENT_XFER_STALLED: diff --git a/tinyusb/class/cdc_device.c b/tinyusb/class/cdc_device.c index 18f52d1c0..b96320143 100644 --- a/tinyusb/class/cdc_device.c +++ b/tinyusb/class/cdc_device.c @@ -74,7 +74,7 @@ static inline bool cdcd_is_configured(uint8_t coreid) return cdcd_data[coreid].interface_number != INTERFACE_INVALID_NUMBER; } -tusb_error_t cdcd_xfer(uint8_t coreid, cdc_pipeid_t pipeid, void * p_buffer, uint32_t length, bool is_notify) +static tusb_error_t cdcd_xfer(uint8_t coreid, cdc_pipeid_t pipeid, void * p_buffer, uint32_t length, bool is_notify) { ASSERT(cdcd_is_configured(coreid), TUSB_ERROR_USBD_INTERFACE_NOT_CONFIGURED); @@ -88,13 +88,20 @@ tusb_error_t cdcd_xfer(uint8_t coreid, cdc_pipeid_t pipeid, void * p_buffer, ui } //--------------------------------------------------------------------+ -// APPLICATION API +// APPLICATION API (Parameters requires validation) //--------------------------------------------------------------------+ bool tusbd_cdc_is_configured(uint8_t coreid) { return cdcd_is_configured(coreid); } +bool tusbd_cdc_is_busy(uint8_t coreid, cdc_pipeid_t pipeid) +{ + ASSERT(cdcd_is_configured(coreid) && (pipeid < CDC_PIPE_ERROR), false); + + return dcd_pipe_is_busy( cdcd_data[coreid].edpt_hdl[pipeid] ); +} + tusb_error_t tusbd_cdc_receive(uint8_t coreid, void * p_buffer, uint32_t length, bool is_notify) { return cdcd_xfer(coreid, CDC_PIPE_DATA_OUT, p_buffer, length, is_notify); @@ -208,7 +215,7 @@ tusb_error_t cdcd_control_request(uint8_t coreid, tusb_control_request_t const * case CDC_REQUEST_SET_LINE_CODING: dcd_pipe_control_xfer(coreid, p_request->bmRequestType_bit.direction, &cdcd_line_coding[coreid], min16_of(sizeof(cdc_line_coding_t), p_request->wLength) ); - // TODO notify application + // TODO notify application on xfer complete break; case CDC_REQUEST_SET_CONTROL_LINE_STATE: // TODO extract DTE present diff --git a/tinyusb/class/cdc_device.h b/tinyusb/class/cdc_device.h index a0e8d5bde..e1f298b76 100644 --- a/tinyusb/class/cdc_device.h +++ b/tinyusb/class/cdc_device.h @@ -58,6 +58,7 @@ // APPLICATION API //--------------------------------------------------------------------+ bool tusbd_cdc_is_configured(uint8_t coreid); +bool tusbd_cdc_is_busy(uint8_t coreid, cdc_pipeid_t pipeid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; tusb_error_t tusbd_cdc_send(uint8_t coreid, void * p_data, uint32_t length, bool is_notify); tusb_error_t tusbd_cdc_receive(uint8_t coreid, void * p_buffer, uint32_t length, bool is_notify); @@ -66,6 +67,7 @@ tusb_error_t tusbd_cdc_receive(uint8_t coreid, void * p_buffer, uint32_t length, void tusbd_cdc_mounted_cb(uint8_t coreid); void tusbd_cdc_unmounted_cb(uint8_t coreid); void tusbd_cdc_xfer_isr(uint8_t coreid, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes); +void tusbd_cdc_line_coding_changed_cb(uint8_t coreid, cdc_line_coding_t* p_line_coding); //--------------------------------------------------------------------+ // USBD-CLASS DRIVER API diff --git a/tinyusb/common/fifo.c b/tinyusb/common/fifo.c index d488d4821..c6b6dc449 100644 --- a/tinyusb/common/fifo.c +++ b/tinyusb/common/fifo.c @@ -35,68 +35,13 @@ This file is part of the tinyusb stack. */ /**************************************************************************/ - +#include #include "fifo.h" -/**************************************************************************/ -/*! - @brief Disables the IRQ specified in the FIFO's 'irq' field - to prevent reads/write issues with interrupts +static inline void mutex_lock (fifo_t* f) ATTR_ALWAYS_INLINE; +static inline void mutex_unlock (fifo_t* f) ATTR_ALWAYS_INLINE; +static inline bool is_fifo_initalized(fifo_t* f) ATTR_ALWAYS_INLINE; - @param[in] f - Pointer to the FIFO that should be protected -*/ -/**************************************************************************/ -static inline void mutex_lock (fifo_t* f) -{ -// if (f->irq > 0) -// NVIC_DisableIRQ(f->irq); -} - -/**************************************************************************/ -/*! - @brief Re-enables the IRQ specified in the FIFO's 'irq' field - - @param[in] f - Pointer to the FIFO that should be protected -*/ -/**************************************************************************/ -static inline void mutex_unlock (fifo_t* f) -{ -// if (f->irq > 0) -// NVIC_EnableIRQ(f->irq); -} - -/**************************************************************************/ -/*! - @brief Initialises the FIFO buffer - - @param[in] f - Pointer to the fifo_t object to intiialize - @param[in] buffer - Pointer to the buffer's location in memory - @param[in] size - The buffer size in bytes - @param[in] overwritable - Set to TRUE is the FIFO is overwritable when the FIFO - is full (the first element will be overwritten) - @param[in] irq - The IRQ number to disable for MUTEX protection. - Set the -1 if not required. -*/ -/**************************************************************************/ -bool fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable) //, IRQn_Type irq) -{ - ASSERT(size > 0, false); - - f->buf = buffer; - f->size = size; - f->rd_ptr = f->wr_ptr = f->len = 0; - f->overwritable = overwritable; -// f->irq = irq; - - return true; -} /**************************************************************************/ /*! @@ -114,49 +59,26 @@ bool fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable) //, @returns TRUE if the queue is not empty */ /**************************************************************************/ -bool fifo_read(fifo_t* f, uint8_t *data) +bool fifo_read(fifo_t* f, void * p_buffer) { - if (fifo_is_empty(f)) + if( !is_fifo_initalized(f) || fifo_is_empty(f) ) + { return false; + } mutex_lock(f); - *data = f->buf[f->rd_ptr]; - f->rd_ptr = (f->rd_ptr + 1) % f->size; - f->len--; + memcpy(p_buffer, + f->buffer + (f->rd_idx * f->item_size), + f->item_size); + f->rd_idx = (f->rd_idx + 1) % f->depth; + f->count--; mutex_unlock(f); return true; } -/**************************************************************************/ -/*! - @brief Read a byte array from FIFO - - @param[in] f - Pointer to the FIFO buffer to manipulate - @param[in] rx - Pointer to the place holder for data read from the buffer - @param[in] maxlen - The maximum number of bytes to read from the FIFO - - @returns The actual number of bytes read from the FIFO - */ -/**************************************************************************/ -uint16_t fifo_read_n(fifo_t* f, uint8_t* rx, uint16_t maxlen) -{ - uint16_t len = 0; - - while ( len < maxlen && fifo_read(f, rx) ) - { - len++; - rx++; - } - - return len; -} - /**************************************************************************/ /*! @brief Write one byte into the RX buffer. @@ -174,22 +96,27 @@ uint16_t fifo_read_n(fifo_t* f, uint8_t* rx, uint16_t maxlen) FIFO will always return TRUE) */ /**************************************************************************/ -bool fifo_write(fifo_t* f, uint8_t data) +bool fifo_write(fifo_t* f, void const * p_data) { - if ( fifo_is_full(f) && f->overwritable == false) - return false; + if ( !is_fifo_initalized(f) || (fifo_is_full(f) && !f->overwritable) ) + { + return false; + } mutex_lock(f); - f->buf[f->wr_ptr] = data; - f->wr_ptr = (f->wr_ptr + 1) % f->size; + memcpy( f->buffer + (f->wr_idx * f->item_size), + p_data, + f->item_size); + + f->wr_idx = (f->wr_idx + 1) % f->depth; if (fifo_is_full(f)) { - f->rd_ptr = f->wr_ptr; // keep the full state (rd == wr && len = size) + f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size) }else { - f->len++; + f->count++; } mutex_unlock(f); @@ -209,9 +136,53 @@ void fifo_clear(fifo_t *f) { mutex_lock(f); - f->rd_ptr = 0; - f->wr_ptr = 0; - f->len = 0; + f->rd_idx = f->wr_idx = f->count = 0; mutex_unlock(f); } + +//--------------------------------------------------------------------+ +// HELPER FUNCTIONS +//--------------------------------------------------------------------+ + +/**************************************************************************/ +/*! + @brief Disables the IRQ specified in the FIFO's 'irq' field + to prevent reads/write issues with interrupts + + @param[in] f + Pointer to the FIFO that should be protected +*/ +/**************************************************************************/ +static inline void mutex_lock (fifo_t* f) +{ +// if (f->irq > 0) +// { +// #if !defined (_TEST_) +// NVIC_DisableIRQ(f->irq); +// #endif +// } +} + +/**************************************************************************/ +/*! + @brief Re-enables the IRQ specified in the FIFO's 'irq' field + + @param[in] f + Pointer to the FIFO that should be protected +*/ +/**************************************************************************/ +static inline void mutex_unlock (fifo_t* f) +{ +// if (f->irq > 0) +// { +// #if !defined (_TEST_) +// NVIC_EnableIRQ(f->irq); +// #endif +// } +} + +static inline bool is_fifo_initalized(fifo_t* f) +{ + return !( f->buffer == NULL || f->depth == 0 || f->item_size == 0); +} diff --git a/tinyusb/common/fifo.h b/tinyusb/common/fifo.h index ef33bb956..daef4a84a 100644 --- a/tinyusb/common/fifo.h +++ b/tinyusb/common/fifo.h @@ -36,12 +36,6 @@ */ /**************************************************************************/ -/** \file - * \brief Error Header - * - * \note TBD - */ - /** \ingroup Group_Common * * @{ @@ -59,36 +53,47 @@ /** \struct fifo_t * \brief Simple Circular FIFO */ -typedef struct _fifo_t +typedef struct { - uint8_t* buf ; ///< buffer pointer - uint16_t size ; ///< buffer size - volatile uint16_t len ; ///< bytes in fifo - volatile uint16_t wr_ptr ; ///< write pointer - volatile uint16_t rd_ptr ; ///< read pointer - bool overwritable ; ///< allow overwrite data when full -// IRQn_Type irq ; ///< TODO (abstract later) interrupt used to lock fifo + uint16_t const depth ; ///< max items + uint16_t const item_size ; ///< size of each item + 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 ; + uint8_t buffer[] ; ///< buffer pointer + // IRQn_Type irq; } fifo_t; -bool fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable); //, IRQn_Type irq); -bool fifo_write(fifo_t* f, uint8_t data); -bool fifo_read(fifo_t* f, uint8_t *data); -uint16_t fifo_read_n(fifo_t* f, uint8_t * rx, uint16_t maxlen); +#define FIFO_DEF(name, ff_depth, type, is_overwritable) /*, irq_mutex)*/ \ + fifo_t name = {\ + .depth = ff_depth,\ + .item_size = sizeof(type),\ + .overwritable = is_overwritable,\ + /*.irq = irq_mutex*/\ + .buffer = { [ff_depth*sizeof(type) - 1] = 0 },\ + } + +bool fifo_write(fifo_t* f, void const * p_data); +bool fifo_read(fifo_t* f, void * p_buffer); void fifo_clear(fifo_t *f); +static inline bool fifo_is_empty(fifo_t* f) ATTR_PURE ATTR_ALWAYS_INLINE; static inline bool fifo_is_empty(fifo_t* f) { - return (f->len == 0); + return (f->count == 0); } +static inline bool fifo_is_full(fifo_t* f) ATTR_PURE ATTR_ALWAYS_INLINE; static inline bool fifo_is_full(fifo_t* f) { - return (f->len == f->size); + return (f->count == f->depth); } +static inline uint16_t fifo_get_length(fifo_t* f) ATTR_PURE ATTR_ALWAYS_INLINE; static inline uint16_t fifo_get_length(fifo_t* f) { - return f->len; + return f->count; } #ifdef __cplusplus