summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2013-11-08 14:46:48 +0700
committerhathach <[email protected]>2013-11-08 14:46:48 +0700
commit7ff0dbb64cfcab7256a4b113931c63a4c7efa0d3 (patch)
tree41d92cf1d303d5578a50f7f79c72134534a3d19e
parent15d3a418bd0d109d926ea95c3be1bbc83757734b (diff)
add tusbd_cdc_is_busy
enhance cdc serial device demo refractor fifo.c
-rw-r--r--demos/device/device_os_none/cdcd_app.c42
-rw-r--r--demos/host/host_os_none/host_os_none.uvopt16
-rw-r--r--demos/host/src/cdc_serial_app.c2
-rw-r--r--tinyusb/class/cdc_device.c13
-rw-r--r--tinyusb/class/cdc_device.h2
-rw-r--r--tinyusb/common/fifo.c173
-rw-r--r--tinyusb/common/fifo.h47
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<xferred_bytes; i++)
+ {
+ fifo_write(&fifo_serial, serial_rx_buffer+i);
+ }
osal_semaphore_post(sem_hdl); // notify main task
- break;
+ break;
case TUSB_EVENT_XFER_ERROR:
xferred_bytes = 0; // ignore
@@ -122,14 +125,23 @@ OSAL_TASK_FUNCTION( cdcd_serial_app_task ) (void* p_task_para)
if ( tusbd_cdc_is_configured(0) )
{
- if ( received_bytes )
- { // echo back
- memcpy(cdcd_app_send_buffer, cdcd_app_recv_buffer, received_bytes);
- tusbd_cdc_send(0, cdcd_app_send_buffer, received_bytes, false);
- received_bytes = 0;
+ // echo back data in the fifo
+ if ( !tusbd_cdc_is_busy(0, CDC_PIPE_DATA_IN) )
+ {
+ uint16_t count=0;
+ while( fifo_read(&fifo_serial, &serial_tx_buffer[count]) )
+ {
+ count++;
+ }
+
+ if (count)
+ {
+ tusbd_cdc_send(0, serial_tx_buffer, count, false);
+ }
}
- tusbd_cdc_receive(0, cdcd_app_recv_buffer, CDCD_APP_BUFFER_SIZE, true);
+ // getting next data from host
+ tusbd_cdc_receive(0, serial_rx_buffer, CDCD_APP_BUFFER_SIZE, true);
}
OSAL_TASK_LOOP_END
diff --git a/demos/host/host_os_none/host_os_none.uvopt b/demos/host/host_os_none/host_os_none.uvopt
index 6ef03bde4..c71341024 100644
--- a/demos/host/host_os_none/host_os_none.uvopt
+++ b/demos/host/host_os_none/host_os_none.uvopt
@@ -448,7 +448,7 @@
<Group>
<GroupName>app</GroupName>
- <tvExp>0</tvExp>
+ <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -474,10 +474,10 @@
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
- <ColumnNumber>0</ColumnNumber>
+ <ColumnNumber>3</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>1</TopLine>
- <CurrentLine>1</CurrentLine>
+ <CurrentLine>2</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>..\src\cdc_serial_app.c</PathWithFileName>
<FilenameWithoutPath>cdc_serial_app.c</FilenameWithoutPath>
@@ -736,7 +736,7 @@
<Group>
<GroupName>tinyusb</GroupName>
- <tvExp>0</tvExp>
+ <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
@@ -744,7 +744,7 @@
<GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber>
<FileType>1</FileType>
- <tvExp>0</tvExp>
+ <tvExp>1</tvExp>
<Focus>0</Focus>
<ColumnNumber>64</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -924,8 +924,8 @@
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
- <TopLine>0</TopLine>
- <CurrentLine>0</CurrentLine>
+ <TopLine>54</TopLine>
+ <CurrentLine>62</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\tinyusb\common\fifo.c</PathWithFileName>
<FilenameWithoutPath>fifo.c</FilenameWithoutPath>
@@ -1156,7 +1156,7 @@
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
- <TopLine>1705</TopLine>
+ <TopLine>1688</TopLine>
<CurrentLine>1713</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\vendor\fatfs\ff.c</PathWithFileName>
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 <string.h>
#include "fifo.h"
-/**************************************************************************/
-/*!
- @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)
-// 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
+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_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,16 +59,20 @@ 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);
@@ -132,33 +81,6 @@ bool fifo_read(fifo_t* f, uint8_t *data)
/**************************************************************************/
/*!
- @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.
This function will write one byte into the array index specified by
@@ -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