mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-17 17:42:43 +00:00
add tusbd_cdc_is_busy
enhance cdc serial device demo refractor fifo.c
This commit is contained in:
parent
15d3a418bd
commit
7ff0dbb64c
@ -39,6 +39,9 @@
|
|||||||
#include "cdcd_app.h"
|
#include "cdcd_app.h"
|
||||||
|
|
||||||
#if TUSB_CFG_DEVICE_CDC
|
#if TUSB_CFG_DEVICE_CDC
|
||||||
|
|
||||||
|
#include "common/fifo.h" // TODO refractor
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INCLUDE
|
// INCLUDE
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -54,18 +57,16 @@ OSAL_SEM_DEF(cdcd_semaphore);
|
|||||||
|
|
||||||
static osal_semaphore_handle_t sem_hdl;
|
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 serial_rx_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 uint8_t serial_tx_buffer[CDCD_APP_BUFFER_SIZE] TUSB_CFG_ATTR_USBRAM;
|
||||||
|
|
||||||
static uint16_t received_bytes; // set by transfer complete callback
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
FIFO_DEF(fifo_serial, CDCD_APP_BUFFER_SIZE, uint8_t, true);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// IMPLEMENTATION
|
// IMPLEMENTATION
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
void cdcd_serial_app_init(void)
|
void cdcd_serial_app_init(void)
|
||||||
{
|
{
|
||||||
sem_hdl = osal_semaphore_create( OSAL_SEM_REF(cdcd_semaphore) );
|
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);
|
osal_semaphore_reset(sem_hdl);
|
||||||
|
|
||||||
received_bytes = 0;
|
tusbd_cdc_receive(coreid, serial_rx_buffer, CDCD_APP_BUFFER_SIZE, true);
|
||||||
tusbd_cdc_receive(coreid, cdcd_app_recv_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)
|
void tusbd_cdc_xfer_isr(uint8_t coreid, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes)
|
||||||
@ -90,7 +90,10 @@ void tusbd_cdc_xfer_isr(uint8_t coreid, tusb_event_t event, cdc_pipeid_t pipe_id
|
|||||||
switch(event)
|
switch(event)
|
||||||
{
|
{
|
||||||
case TUSB_EVENT_XFER_COMPLETE:
|
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
|
osal_semaphore_post(sem_hdl); // notify main task
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -122,14 +125,23 @@ OSAL_TASK_FUNCTION( cdcd_serial_app_task ) (void* p_task_para)
|
|||||||
|
|
||||||
if ( tusbd_cdc_is_configured(0) )
|
if ( tusbd_cdc_is_configured(0) )
|
||||||
{
|
{
|
||||||
if ( received_bytes )
|
// echo back data in the fifo
|
||||||
{ // echo back
|
if ( !tusbd_cdc_is_busy(0, CDC_PIPE_DATA_IN) )
|
||||||
memcpy(cdcd_app_send_buffer, cdcd_app_recv_buffer, received_bytes);
|
{
|
||||||
tusbd_cdc_send(0, cdcd_app_send_buffer, received_bytes, false);
|
uint16_t count=0;
|
||||||
received_bytes = 0;
|
while( fifo_read(&fifo_serial, &serial_tx_buffer[count]) )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tusbd_cdc_receive(0, cdcd_app_recv_buffer, CDCD_APP_BUFFER_SIZE, true);
|
if (count)
|
||||||
|
{
|
||||||
|
tusbd_cdc_send(0, serial_tx_buffer, count, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getting next data from host
|
||||||
|
tusbd_cdc_receive(0, serial_rx_buffer, CDCD_APP_BUFFER_SIZE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
OSAL_TASK_LOOP_END
|
OSAL_TASK_LOOP_END
|
||||||
|
@ -448,7 +448,7 @@
|
|||||||
|
|
||||||
<Group>
|
<Group>
|
||||||
<GroupName>app</GroupName>
|
<GroupName>app</GroupName>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>1</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<cbSel>0</cbSel>
|
<cbSel>0</cbSel>
|
||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
@ -474,10 +474,10 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<Focus>0</Focus>
|
<Focus>0</Focus>
|
||||||
<ColumnNumber>0</ColumnNumber>
|
<ColumnNumber>3</ColumnNumber>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<TopLine>1</TopLine>
|
<TopLine>1</TopLine>
|
||||||
<CurrentLine>1</CurrentLine>
|
<CurrentLine>2</CurrentLine>
|
||||||
<bDave2>0</bDave2>
|
<bDave2>0</bDave2>
|
||||||
<PathWithFileName>..\src\cdc_serial_app.c</PathWithFileName>
|
<PathWithFileName>..\src\cdc_serial_app.c</PathWithFileName>
|
||||||
<FilenameWithoutPath>cdc_serial_app.c</FilenameWithoutPath>
|
<FilenameWithoutPath>cdc_serial_app.c</FilenameWithoutPath>
|
||||||
@ -736,7 +736,7 @@
|
|||||||
|
|
||||||
<Group>
|
<Group>
|
||||||
<GroupName>tinyusb</GroupName>
|
<GroupName>tinyusb</GroupName>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>1</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<cbSel>0</cbSel>
|
<cbSel>0</cbSel>
|
||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
@ -744,7 +744,7 @@
|
|||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>18</FileNumber>
|
<FileNumber>18</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>1</tvExp>
|
||||||
<Focus>0</Focus>
|
<Focus>0</Focus>
|
||||||
<ColumnNumber>64</ColumnNumber>
|
<ColumnNumber>64</ColumnNumber>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -924,8 +924,8 @@
|
|||||||
<Focus>0</Focus>
|
<Focus>0</Focus>
|
||||||
<ColumnNumber>0</ColumnNumber>
|
<ColumnNumber>0</ColumnNumber>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<TopLine>0</TopLine>
|
<TopLine>54</TopLine>
|
||||||
<CurrentLine>0</CurrentLine>
|
<CurrentLine>62</CurrentLine>
|
||||||
<bDave2>0</bDave2>
|
<bDave2>0</bDave2>
|
||||||
<PathWithFileName>..\..\..\tinyusb\common\fifo.c</PathWithFileName>
|
<PathWithFileName>..\..\..\tinyusb\common\fifo.c</PathWithFileName>
|
||||||
<FilenameWithoutPath>fifo.c</FilenameWithoutPath>
|
<FilenameWithoutPath>fifo.c</FilenameWithoutPath>
|
||||||
@ -1156,7 +1156,7 @@
|
|||||||
<Focus>0</Focus>
|
<Focus>0</Focus>
|
||||||
<ColumnNumber>0</ColumnNumber>
|
<ColumnNumber>0</ColumnNumber>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
<TopLine>1705</TopLine>
|
<TopLine>1688</TopLine>
|
||||||
<CurrentLine>1713</CurrentLine>
|
<CurrentLine>1713</CurrentLine>
|
||||||
<bDave2>0</bDave2>
|
<bDave2>0</bDave2>
|
||||||
<PathWithFileName>..\..\..\vendor\fatfs\ff.c</PathWithFileName>
|
<PathWithFileName>..\..\..\vendor\fatfs\ff.c</PathWithFileName>
|
||||||
|
@ -92,7 +92,7 @@ void tusbh_cdc_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_EVENT_XFER_ERROR:
|
case TUSB_EVENT_XFER_ERROR:
|
||||||
xferred_bytes = 0; // ignore
|
received_bytes = 0; // ignore
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_EVENT_XFER_STALLED:
|
case TUSB_EVENT_XFER_STALLED:
|
||||||
|
@ -74,7 +74,7 @@ static inline bool cdcd_is_configured(uint8_t coreid)
|
|||||||
return cdcd_data[coreid].interface_number != INTERFACE_INVALID_NUMBER;
|
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);
|
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)
|
bool tusbd_cdc_is_configured(uint8_t coreid)
|
||||||
{
|
{
|
||||||
return cdcd_is_configured(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)
|
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);
|
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:
|
case CDC_REQUEST_SET_LINE_CODING:
|
||||||
dcd_pipe_control_xfer(coreid, p_request->bmRequestType_bit.direction,
|
dcd_pipe_control_xfer(coreid, p_request->bmRequestType_bit.direction,
|
||||||
&cdcd_line_coding[coreid], min16_of(sizeof(cdc_line_coding_t), p_request->wLength) );
|
&cdcd_line_coding[coreid], min16_of(sizeof(cdc_line_coding_t), p_request->wLength) );
|
||||||
// TODO notify application
|
// TODO notify application on xfer complete
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CDC_REQUEST_SET_CONTROL_LINE_STATE: // TODO extract DTE present
|
case CDC_REQUEST_SET_CONTROL_LINE_STATE: // TODO extract DTE present
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
// APPLICATION API
|
// APPLICATION API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool tusbd_cdc_is_configured(uint8_t coreid);
|
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_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);
|
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_mounted_cb(uint8_t coreid);
|
||||||
void tusbd_cdc_unmounted_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_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
|
// USBD-CLASS DRIVER API
|
||||||
|
@ -35,68 +35,13 @@
|
|||||||
This file is part of the tinyusb stack.
|
This file is part of the tinyusb stack.
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
#include <string.h>
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
|
|
||||||
/**************************************************************************/
|
static inline void mutex_lock (fifo_t* f) ATTR_ALWAYS_INLINE;
|
||||||
/*!
|
static inline void mutex_unlock (fifo_t* f) ATTR_ALWAYS_INLINE;
|
||||||
@brief Disables the IRQ specified in the FIFO's 'irq' field
|
static inline bool is_fifo_initalized(fifo_t* f) ATTR_ALWAYS_INLINE;
|
||||||
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
|
|
||||||
|
|
||||||
@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
|
@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( !is_fifo_initalized(f) || fifo_is_empty(f) )
|
||||||
{
|
{
|
||||||
if (fifo_is_empty(f))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(f);
|
mutex_lock(f);
|
||||||
|
|
||||||
*data = f->buf[f->rd_ptr];
|
memcpy(p_buffer,
|
||||||
f->rd_ptr = (f->rd_ptr + 1) % f->size;
|
f->buffer + (f->rd_idx * f->item_size),
|
||||||
f->len--;
|
f->item_size);
|
||||||
|
f->rd_idx = (f->rd_idx + 1) % f->depth;
|
||||||
|
f->count--;
|
||||||
|
|
||||||
mutex_unlock(f);
|
mutex_unlock(f);
|
||||||
|
|
||||||
return true;
|
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.
|
@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)
|
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 ( !is_fifo_initalized(f) || (fifo_is_full(f) && !f->overwritable) )
|
||||||
{
|
{
|
||||||
if ( fifo_is_full(f) && f->overwritable == false)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(f);
|
mutex_lock(f);
|
||||||
|
|
||||||
f->buf[f->wr_ptr] = data;
|
memcpy( f->buffer + (f->wr_idx * f->item_size),
|
||||||
f->wr_ptr = (f->wr_ptr + 1) % f->size;
|
p_data,
|
||||||
|
f->item_size);
|
||||||
|
|
||||||
|
f->wr_idx = (f->wr_idx + 1) % f->depth;
|
||||||
|
|
||||||
if (fifo_is_full(f))
|
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
|
}else
|
||||||
{
|
{
|
||||||
f->len++;
|
f->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(f);
|
mutex_unlock(f);
|
||||||
@ -209,9 +136,53 @@ void fifo_clear(fifo_t *f)
|
|||||||
{
|
{
|
||||||
mutex_lock(f);
|
mutex_lock(f);
|
||||||
|
|
||||||
f->rd_ptr = 0;
|
f->rd_idx = f->wr_idx = f->count = 0;
|
||||||
f->wr_ptr = 0;
|
|
||||||
f->len = 0;
|
|
||||||
|
|
||||||
mutex_unlock(f);
|
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);
|
||||||
|
}
|
||||||
|
@ -36,12 +36,6 @@
|
|||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
/** \file
|
|
||||||
* \brief Error Header
|
|
||||||
*
|
|
||||||
* \note TBD
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** \ingroup Group_Common
|
/** \ingroup Group_Common
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
@ -59,36 +53,47 @@
|
|||||||
/** \struct fifo_t
|
/** \struct fifo_t
|
||||||
* \brief Simple Circular FIFO
|
* \brief Simple Circular FIFO
|
||||||
*/
|
*/
|
||||||
typedef struct _fifo_t
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t* buf ; ///< buffer pointer
|
uint16_t const depth ; ///< max items
|
||||||
uint16_t size ; ///< buffer size
|
uint16_t const item_size ; ///< size of each item
|
||||||
volatile uint16_t len ; ///< bytes in fifo
|
volatile uint16_t count ; ///< number of items in queue
|
||||||
volatile uint16_t wr_ptr ; ///< write pointer
|
volatile uint16_t wr_idx ; ///< write pointer
|
||||||
volatile uint16_t rd_ptr ; ///< read pointer
|
volatile uint16_t rd_idx ; ///< read pointer
|
||||||
bool overwritable ; ///< allow overwrite data when full
|
bool overwritable ;
|
||||||
// IRQn_Type irq ; ///< TODO (abstract later) interrupt used to lock fifo
|
uint8_t buffer[] ; ///< buffer pointer
|
||||||
|
// IRQn_Type irq;
|
||||||
} fifo_t;
|
} fifo_t;
|
||||||
|
|
||||||
bool fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable); //, IRQn_Type irq);
|
#define FIFO_DEF(name, ff_depth, type, is_overwritable) /*, irq_mutex)*/ \
|
||||||
bool fifo_write(fifo_t* f, uint8_t data);
|
fifo_t name = {\
|
||||||
bool fifo_read(fifo_t* f, uint8_t *data);
|
.depth = ff_depth,\
|
||||||
uint16_t fifo_read_n(fifo_t* f, uint8_t * rx, uint16_t maxlen);
|
.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);
|
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)
|
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)
|
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)
|
static inline uint16_t fifo_get_length(fifo_t* f)
|
||||||
{
|
{
|
||||||
return f->len;
|
return f->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
x
Reference in New Issue
Block a user