Implement functions to allow for DMA usage in audio driver.

- Add tud_audio_n_get_ep_out_ff(), tud_audio_n_get_ep_in_ff(),
tud_audio_n_get_rx_support_ff(), and tud_audio_n_get_tx_support_ff()
- Change get_linear_read/write_info() to return linear and wrapped part
at once
- Adjusted affected code in audio_device.c and tested with
audio_4_channel.
This commit is contained in:
Reinhard Panhuber 2021-04-23 10:27:48 +02:00
parent d8fd4352a3
commit 03f974c9b9
5 changed files with 103 additions and 48 deletions

View File

@ -447,27 +447,39 @@ bool tud_audio_n_clear_ep_out_ff(uint8_t func_id)
return tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff); return tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff);
} }
tu_fifo_t* tud_audio_n_get_ep_out_ff(uint8_t func_id)
{
if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) return &_audiod_fct[func_id].ep_out_ff;
return NULL;
}
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_DECODING && CFG_TUD_AUDIO_ENABLE_EP_OUT
// Delete all content in the support RX FIFOs // Delete all content in the support RX FIFOs
bool tud_audio_n_clear_rx_support_ff(uint8_t func_id, uint8_t ff_idx) bool tud_audio_n_clear_rx_support_ff(uint8_t func_id, uint8_t ff_idx)
{ {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL, ff_idx < _audiod_fct[func_id].n_rx_supp_ff); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff);
return tu_fifo_clear(&_audiod_fct[func_id].rx_supp_ff[ff_idx]); return tu_fifo_clear(&_audiod_fct[func_id].rx_supp_ff[ff_idx]);
} }
uint16_t tud_audio_n_available_support_ff(uint8_t func_id, uint8_t ff_idx) uint16_t tud_audio_n_available_support_ff(uint8_t func_id, uint8_t ff_idx)
{ {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL, ff_idx < _audiod_fct[func_id].n_rx_supp_ff); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff);
return tu_fifo_count(&_audiod_fct[func_id].rx_supp_ff[ff_idx]); return tu_fifo_count(&_audiod_fct[func_id].rx_supp_ff[ff_idx]);
} }
uint16_t tud_audio_n_read_support_ff(uint8_t func_id, uint8_t ff_idx, void* buffer, uint16_t bufsize) uint16_t tud_audio_n_read_support_ff(uint8_t func_id, uint8_t ff_idx, void* buffer, uint16_t bufsize)
{ {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL, ff_idx < _audiod_fct[func_id].n_rx_supp_ff); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff);
return tu_fifo_read_n(&_audiod_fct[func_id].rx_supp_ff[ff_idx], buffer, bufsize); return tu_fifo_read_n(&_audiod_fct[func_id].rx_supp_ff[ff_idx], buffer, bufsize);
} }
tu_fifo_t* tud_audio_n_get_rx_support_ff(uint8_t func_id, uint8_t ff_idx)
{
if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_rx_supp_ff) return &_audiod_fct[func_id].rx_supp_ff[ff_idx];
return NULL;
}
#endif #endif
// This function is called once an audio packet is received by the USB and is responsible for putting data from USB memory into EP_OUT_FIFO (or support FIFOs + decoding of received stream into audio channels). // This function is called once an audio packet is received by the USB and is responsible for putting data from USB memory into EP_OUT_FIFO (or support FIFOs + decoding of received stream into audio channels).
@ -635,32 +647,26 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u
uint8_t cnt_ff; uint8_t cnt_ff;
// Decode // Decode
void * dst; void * dst, * dst_wrap;
uint8_t * src; uint8_t * src;
uint8_t * dst_end; uint8_t * dst_end;
uint16_t len; uint16_t len, len_wrap;
for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++)
{ {
src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx];
len = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, nBytesPerFFToRead, &dst, &len_wrap, &dst_wrap);
len = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, &dst, nBytesPerFFToRead);
tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], len);
dst_end = dst + len; dst_end = dst + len;
src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, dst, dst_end, src, n_ff_used); src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, dst, dst_end, src, n_ff_used);
// Handle wrapped part of FIFO // Handle wrapped part of FIFO
if (len < nBytesPerFFToRead) if (len_wrap != 0)
{ {
len = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, &dst, nBytesPerFFToRead - len); dst_end = dst_wrap + len_wrap;
tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], len); audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, dst_wrap, dst_end, src, n_ff_used);
dst_end = dst + len;
audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, dst, dst_end, src, n_ff_used);
} }
tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], len + len_wrap);
} }
// Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it // Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it
@ -699,9 +705,16 @@ bool tud_audio_n_clear_ep_in_ff(uint8_t func_id) // Del
return tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff); return tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff);
} }
tu_fifo_t* tud_audio_n_get_ep_in_ff(uint8_t func_id)
{
if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) return &_audiod_fct[func_id].ep_in_ff;
return NULL;
}
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_EP_IN
uint16_t tud_audio_n_flush_tx_support_ff(uint8_t func_id) // Force all content in the support TX FIFOs to be written into linear buffer and schedule a transmit uint16_t tud_audio_n_flush_tx_support_ff(uint8_t func_id) // Force all content in the support TX FIFOs to be written into linear buffer and schedule a transmit
{ {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL);
@ -719,15 +732,22 @@ uint16_t tud_audio_n_flush_tx_support_ff(uint8_t func_id) // For
bool tud_audio_n_clear_tx_support_ff(uint8_t func_id, uint8_t ff_idx) bool tud_audio_n_clear_tx_support_ff(uint8_t func_id, uint8_t ff_idx)
{ {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL, ff_idx < _audiod_fct[func_id].n_tx_supp_ff); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_tx_supp_ff);
return tu_fifo_clear(&_audiod_fct[func_id].tx_supp_ff[ff_idx]); return tu_fifo_clear(&_audiod_fct[func_id].tx_supp_ff[ff_idx]);
} }
uint16_t tud_audio_n_write_support_ff(uint8_t func_id, uint8_t ff_idx, const void * data, uint16_t len) uint16_t tud_audio_n_write_support_ff(uint8_t func_id, uint8_t ff_idx, const void * data, uint16_t len)
{ {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL, ff_idx < _audiod_fct[func_id].n_tx_supp_ff); TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_tx_supp_ff);
return tu_fifo_write_n(&_audiod_fct[func_id].tx_supp_ff[ff_idx], data, len); return tu_fifo_write_n(&_audiod_fct[func_id].tx_supp_ff[ff_idx], data, len);
} }
tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx)
{
if(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && ff_idx < _audiod_fct[func_id].n_tx_supp_ff) return &_audiod_fct[func_id].tx_supp_ff[ff_idx];
return NULL;
}
#endif #endif
@ -751,6 +771,7 @@ uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint1
return true; return true;
} }
#endif #endif
@ -952,32 +973,28 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
nBytesPerFFToSend = (nBytesPerFFToSend / nBytesToCopy) * nBytesToCopy; nBytesPerFFToSend = (nBytesPerFFToSend / nBytesToCopy) * nBytesToCopy;
// Encode // Encode
void * src; void * src, * src_wrap;
uint8_t * dst; uint8_t * dst;
uint8_t * src_end; uint8_t * src_end;
uint16_t len; uint16_t len, len_wrap;
for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++)
{ {
dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx];
len = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, &src, nBytesPerFFToSend); len = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, nBytesPerFFToSend, &src, &len_wrap, &src_wrap);
tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], len);
src_end = src + len; src_end = src + len;
dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, src, src_end, dst, n_ff_used); dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, src, src_end, dst, n_ff_used);
// Handle wrapped part of FIFO // Handle wrapped part of FIFO
if (len < nBytesPerFFToSend) if (len_wrap != 0)
{ {
len = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, &src, nBytesPerFFToSend - len); src_end = src_wrap + len_wrap;
tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], len); audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, src_wrap, src_end, dst, n_ff_used);
src_end = src + len;
audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, src, src_end, dst, n_ff_used);
} }
tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], len + len_wrap);
} }
return nBytesPerFFToSend * n_ff_used; return nBytesPerFFToSend * n_ff_used;

View File

@ -33,6 +33,7 @@
#include "device/usbd.h" #include "device/usbd.h"
#include "audio.h" #include "audio.h"
#include "tusb_fifo.h"
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Class Driver Configuration // Class Driver Configuration
@ -364,23 +365,27 @@ bool tud_audio_n_mounted (uint8_t func_id);
uint16_t tud_audio_n_available (uint8_t func_id); uint16_t tud_audio_n_available (uint8_t func_id);
uint16_t tud_audio_n_read (uint8_t func_id, void* buffer, uint16_t bufsize); uint16_t tud_audio_n_read (uint8_t func_id, void* buffer, uint16_t bufsize);
bool tud_audio_n_clear_ep_out_ff (uint8_t func_id); // Delete all content in the EP OUT FIFO bool tud_audio_n_clear_ep_out_ff (uint8_t func_id); // Delete all content in the EP OUT FIFO
tu_fifo_t* tud_audio_n_get_ep_out_ff (uint8_t func_id);
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
bool tud_audio_n_clear_rx_support_ff (uint8_t func_id, uint8_t ff_idx); // Delete all content in the support RX FIFOs bool tud_audio_n_clear_rx_support_ff (uint8_t func_id, uint8_t ff_idx); // Delete all content in the support RX FIFOs
uint16_t tud_audio_n_available_support_ff (uint8_t func_id, uint8_t ff_idx); uint16_t tud_audio_n_available_support_ff (uint8_t func_id, uint8_t ff_idx);
uint16_t tud_audio_n_read_support_ff (uint8_t func_id, uint8_t ff_idx, void* buffer, uint16_t bufsize); uint16_t tud_audio_n_read_support_ff (uint8_t func_id, uint8_t ff_idx, void* buffer, uint16_t bufsize);
tu_fifo_t* tud_audio_n_get_rx_support_ff (uint8_t func_id, uint8_t ff_idx);
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
uint16_t tud_audio_n_write (uint8_t func_id, const void * data, uint16_t len); uint16_t tud_audio_n_write (uint8_t func_id, const void * data, uint16_t len);
bool tud_audio_n_clear_ep_in_ff (uint8_t func_id); // Delete all content in the EP IN FIFO bool tud_audio_n_clear_ep_in_ff (uint8_t func_id); // Delete all content in the EP IN FIFO
tu_fifo_t* tud_audio_n_get_ep_in_ff (uint8_t func_id);
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING
uint16_t tud_audio_n_flush_tx_support_ff (uint8_t func_id); // Force all content in the support TX FIFOs to be written into EP SW FIFO uint16_t tud_audio_n_flush_tx_support_ff (uint8_t func_id); // Force all content in the support TX FIFOs to be written into EP SW FIFO
bool tud_audio_n_clear_tx_support_ff (uint8_t func_id, uint8_t ff_idx); bool tud_audio_n_clear_tx_support_ff (uint8_t func_id, uint8_t ff_idx);
uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_idx, const void * data, uint16_t len); uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_idx, const void * data, uint16_t len);
tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_idx);
#endif #endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
@ -399,12 +404,14 @@ static inline bool tud_audio_mounted (void);
static inline uint16_t tud_audio_available (void); static inline uint16_t tud_audio_available (void);
static inline bool tud_audio_clear_ep_out_ff (void); // Delete all content in the EP OUT FIFO static inline bool tud_audio_clear_ep_out_ff (void); // Delete all content in the EP OUT FIFO
static inline uint16_t tud_audio_read (void* buffer, uint16_t bufsize); static inline uint16_t tud_audio_read (void* buffer, uint16_t bufsize);
static inline tu_fifo_t* tud_audio_get_ep_out_ff (void);
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
static inline bool tud_audio_clear_rx_support_ff (uint8_t ff_idx); static inline bool tud_audio_clear_rx_support_ff (uint8_t ff_idx);
static inline uint16_t tud_audio_available_support_ff (uint8_t ff_idx); static inline uint16_t tud_audio_available_support_ff (uint8_t ff_idx);
static inline uint16_t tud_audio_read_support_ff (uint8_t ff_idx, void* buffer, uint16_t bufsize); static inline uint16_t tud_audio_read_support_ff (uint8_t ff_idx, void* buffer, uint16_t bufsize);
static inline tu_fifo_t* tud_audio_get_rx_support_ff (uint8_t ff_idx);
#endif #endif
// TX API // TX API
@ -412,12 +419,14 @@ static inline uint16_t tud_audio_read_support_ff (uint8_t ff_idx, voi
#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
static inline uint16_t tud_audio_write (const void * data, uint16_t len); static inline uint16_t tud_audio_write (const void * data, uint16_t len);
static inline bool tud_audio_clear_ep_in_ff (void); static inline bool tud_audio_clear_ep_in_ff (void);
static inline tu_fifo_t* tud_audio_get_ep_in_ff (void);
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING
static inline uint16_t tud_audio_flush_tx_support_ff (void); static inline uint16_t tud_audio_flush_tx_support_ff (void);
static inline uint16_t tud_audio_clear_tx_support_ff (uint8_t ff_idx); static inline uint16_t tud_audio_clear_tx_support_ff (uint8_t ff_idx);
static inline uint16_t tud_audio_write_support_ff (uint8_t ff_idx, const void * data, uint16_t len); static inline uint16_t tud_audio_write_support_ff (uint8_t ff_idx, const void * data, uint16_t len);
static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx);
#endif #endif
// INT CTR API // INT CTR API
@ -514,6 +523,11 @@ static inline bool tud_audio_clear_ep_out_ff(void)
return tud_audio_n_clear_ep_out_ff(0); return tud_audio_n_clear_ep_out_ff(0);
} }
static inline tu_fifo_t* tud_audio_get_ep_out_ff(void)
{
return tud_audio_n_get_ep_out_ff(0);
}
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
@ -533,6 +547,11 @@ static inline uint16_t tud_audio_read_support_ff(uint8_t ff_idx, void* buffer, u
return tud_audio_n_read_support_ff(0, ff_idx, buffer, bufsize); return tud_audio_n_read_support_ff(0, ff_idx, buffer, bufsize);
} }
static inline tu_fifo_t* tud_audio_get_rx_support_ff(uint8_t ff_idx)
{
return tud_audio_n_get_rx_support_ff(0, ff_idx);
}
#endif #endif
// TX API // TX API
@ -549,6 +568,11 @@ static inline bool tud_audio_clear_ep_in_ff(void)
return tud_audio_n_clear_ep_in_ff(0); return tud_audio_n_clear_ep_in_ff(0);
} }
static inline tu_fifo_t* tud_audio_get_ep_in_ff(void)
{
return tud_audio_n_get_ep_in_ff(0);
}
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING
@ -568,6 +592,11 @@ static inline uint16_t tud_audio_write_support_ff(uint8_t ff_idx, const void * d
return tud_audio_n_write_support_ff(0, ff_idx, data, len); return tud_audio_n_write_support_ff(0, ff_idx, data, len);
} }
static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx)
{
return tud_audio_n_get_tx_support_ff(0, ff_idx);
}
#endif #endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN

View File

@ -905,7 +905,7 @@ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n)
Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid
*/ */
/******************************************************************************/ /******************************************************************************/
uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, void **ptr, uint16_t n) uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap)
{ {
// Operate on temporary values in case they change in between // Operate on temporary values in case they change in between
uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t w = f->wr_idx, r = f->rd_idx;
@ -933,23 +933,26 @@ uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, void **ptr,
w = get_relative_pointer(f, w, 0); w = get_relative_pointer(f, w, 0);
r = get_relative_pointer(f, r, offset); r = get_relative_pointer(f, r, offset);
// Copy pointer to buffer to start reading from
*ptr_lin = &f->buffer[r];
*ptr_wrap = f->buffer;
// Check if there is a wrap around necessary // Check if there is a wrap around necessary
uint16_t len; uint16_t len;
if (w > r) { if (w > r) {
// Non wrapping case
len = w - r; len = w - r;
len = tu_min16(n, len); // Limit to required length
*len_wrap = 0;
} }
else else
{ {
len = f->depth - r; // Also the case if FIFO was full len = f->depth - r; // Also the case if FIFO was full
len = tu_min16(n, len);
*len_wrap = n-len; // n was already limited to what is available
} }
// Limit to required length
len = tu_min16(n, len);
// Copy pointer to buffer to start reading from
*ptr = &f->buffer[r];
return len; return len;
} }
@ -976,7 +979,7 @@ uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, void **ptr,
Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid
*/ */
/******************************************************************************/ /******************************************************************************/
uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, void **ptr, uint16_t n) uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap)
{ {
uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t w = f->wr_idx, r = f->rd_idx;
uint16_t free = _tu_fifo_remaining(f, w, r); uint16_t free = _tu_fifo_remaining(f, w, r);
@ -1004,22 +1007,26 @@ uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, void **ptr
// Get relative pointers // Get relative pointers
w = get_relative_pointer(f, w, offset); w = get_relative_pointer(f, w, offset);
r = get_relative_pointer(f, r, 0); r = get_relative_pointer(f, r, 0);
// Copy pointer to buffer to start writing to
*ptr_lin = &f->buffer[w];
*ptr_wrap = f->buffer; // Always start of buffer
uint16_t len; uint16_t len;
if (w < r) if (w < r)
{ {
// Non wrapping case
len = r-w; len = r-w;
len = tu_min16(n, len); // Limit to required length
*len_wrap = 0;
} }
else else
{ {
len = f->depth - w; len = f->depth - w;
len = tu_min16(n, len); // Limit to required length
*len_wrap = n-len; // Remaining length - n already was limited to free or FIFO depth
} }
// Limit to required length
len = tu_min16(n, len);
// Copy pointer to buffer to start reading from
*ptr = &f->buffer[w];
return len; return len;
} }

View File

@ -134,8 +134,10 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n);
// This functions deliver a pointer to start reading/writing from/to and a valid linear length along which no wrap occurs. // This functions deliver a pointer to start reading/writing from/to and a valid linear length along which no wrap occurs.
// In case not all of your data is available within one read/write, update the read/write pointer by // In case not all of your data is available within one read/write, update the read/write pointer by
// tu_fifo_advance_read_pointer()/tu_fifo_advance_write_pointer and conduct a second read/write operation // tu_fifo_advance_read_pointer()/tu_fifo_advance_write_pointer and conduct a second read/write operation
uint16_t tu_fifo_get_linear_read_info (tu_fifo_t *f, uint16_t offset, void **ptr, uint16_t n); // TODO - update comments
uint16_t tu_fifo_get_linear_write_info (tu_fifo_t *f, uint16_t offset, void **ptr, uint16_t n);
uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap);
uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap);
static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer)
{ {

View File

@ -993,7 +993,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN
// Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
// Check for first linear part // Check for first linear part
void * src; void * src;
uint16_t len = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes); // We want to read from the FIFO uint16_t len = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes); // We want to read from the FIFO - THIS FUNCTION CHANGED!!!
TU_VERIFY(len && dcd_write_packet_memory(dst, src, len)); // and write it into the PMA TU_VERIFY(len && dcd_write_packet_memory(dst, src, len)); // and write it into the PMA
tu_fifo_advance_read_pointer(ff, len); tu_fifo_advance_read_pointer(ff, len);
@ -1075,7 +1075,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB
// Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
// Check for first linear part // Check for first linear part
void * dst; void * dst;
uint16_t len = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes); uint16_t len = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes); // THIS FUNCTION CHANGED!!!!
TU_VERIFY(len && dcd_read_packet_memory(dst, src, len)); TU_VERIFY(len && dcd_read_packet_memory(dst, src, len));
tu_fifo_advance_write_pointer(ff, len); tu_fifo_advance_write_pointer(ff, len);