/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
 * Copyright (c) 2020 Reinhard Panhuber - rework to unmasked pointers
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * This file is part of the TinyUSB stack.
 */

#include "osal/osal.h"
#include "tusb_fifo.h"

#define TU_FIFO_DBG 0

// Suppress IAR warning
// Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
#if defined(__ICCARM__)
#pragma diag_suppress = Pa082
#endif

#if OSAL_MUTEX_REQUIRED

TU_ATTR_ALWAYS_INLINE static inline void ff_lock(osal_mutex_t mutex) {
  if (mutex != NULL) {
    osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
  }
}

TU_ATTR_ALWAYS_INLINE static inline void ff_unlock(osal_mutex_t mutex) {
  if (mutex != NULL) {
    osal_mutex_unlock(mutex);
  }
}

#else
  #define ff_lock(_mutex)
  #define ff_unlock(_mutex)

#endif

//--------------------------------------------------------------------+
// Setup API
//--------------------------------------------------------------------+
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable) {
  // Limit index space to 2*depth - this allows for a fast "modulo" calculation
  // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
  // only if overflow happens once (important for unsupervised DMA applications)
  if (depth > 0x8000) {
    return false;
  }

  ff_lock(f->mutex_wr);
  ff_lock(f->mutex_rd);

  f->buffer       = (uint8_t *)buffer;
  f->depth        = depth;
  f->overwritable = overwritable;
  f->rd_idx       = 0u;
  f->wr_idx       = 0u;

  ff_unlock(f->mutex_wr);
  ff_unlock(f->mutex_rd);

  return true;
}

// clear fifo by resetting read and write indices
void tu_fifo_clear(tu_fifo_t *f) {
  ff_lock(f->mutex_wr);
  ff_lock(f->mutex_rd);

  f->rd_idx = 0;
  f->wr_idx = 0;

  ff_unlock(f->mutex_wr);
  ff_unlock(f->mutex_rd);
}

// Change the fifo overwritable mode
void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
  if (f->overwritable == overwritable) {
    return;
  }

  ff_lock(f->mutex_wr);
  ff_lock(f->mutex_rd);

  f->overwritable = overwritable;

  ff_unlock(f->mutex_wr);
  ff_unlock(f->mutex_rd);
}

//--------------------------------------------------------------------+
// Pull & Push
// copy data to/from fifo without updating read/write pointers
//--------------------------------------------------------------------+
#if CFG_TUSB_FIFO_HWFIFO_API
  #if CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE
    #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n) _hwfifo = (_const volatile void *)((uintptr_t)(_hwfifo) + _n)
  #else
    #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n)
  #endif

  #define HWFIFO_ADDR_NEXT(_hwfifo, _const) HWFIFO_ADDR_NEXT_N(_hwfifo, _const, CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE)

  #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE
static inline void stride_write(volatile void *hwfifo, const void *src, uint8_t data_stride) {
    #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4
  if (data_stride == 4) {
    *((volatile uint32_t *)hwfifo) = tu_unaligned_read32(src);
  }
  #endif
  #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2
  if (data_stride == 2) {
    *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src);
  }
  #endif
}

// Copy from fifo to fixed address buffer (usually a tx register) with TU_FIFO_FIXED_ADDR_RW32 mode
void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) {
  // Write full available 16/32 bit words to dest
  const uint8_t data_stride = (access_mode != NULL) ? access_mode->data_stride : CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE;
  while (len >= data_stride) {
    stride_write(hwfifo, src, data_stride);
    src += data_stride;
    len -= data_stride;
    HWFIFO_ADDR_NEXT(hwfifo, );
  }

    #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS
  // 16-bit access is allowed for odd bytes
  if (len >= 2) {
    *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src);
    src += 2;
    len -= 2;
    HWFIFO_ADDR_NEXT_N(hwfifo, , 2);
  }
    #endif

    #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS
  // 8-bit access is allowed for odd bytes
  while (len > 0) {
    *((volatile uint8_t *)hwfifo) = *src++;
    len--;
    HWFIFO_ADDR_NEXT_N(hwfifo, , 1);
  }
    #else

  // Write odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit
  if (len > 0) {
    uint32_t tmp = 0u;
    memcpy(&tmp, src, len);
    stride_write(hwfifo, &tmp, data_stride);
    HWFIFO_ADDR_NEXT(hwfifo, );
  }
    #endif
}
  #endif

  #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_READ
static inline void stride_read(const volatile void *hwfifo, void *dest, uint8_t data_stride) {
  (void)data_stride; // possible unused
    #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4
      #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 4
  if (data_stride == 4)
      #endif
  {
    tu_unaligned_write32(dest, *((const volatile uint32_t *)hwfifo));
  }
    #endif

    #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2
      #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 2
  if (data_stride == 2)
      #endif
  {
    tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo));
  }
    #endif
}

void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) {
  // Reading full available 16/32-bit hwfifo and write to fifo
  const uint8_t data_stride = (access_mode != NULL) ? access_mode->data_stride : CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE;
  while (len >= data_stride) {
    stride_read(hwfifo, dest, data_stride);
    dest += data_stride;
    len -= data_stride;
    HWFIFO_ADDR_NEXT(hwfifo, const);
  }

    #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS
  // 16-bit access is allowed for odd bytes
  if (len >= 2) {
    tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo));
    dest += 2;
    len -= 2;
    HWFIFO_ADDR_NEXT_N(hwfifo, const, 2);
  }
    #endif

    #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS
  // 8-bit access is allowed for odd bytes
  while (len > 0) {
    *dest++ = *((const volatile uint8_t *)hwfifo);
    len--;
    HWFIFO_ADDR_NEXT_N(hwfifo, const, 1);
  }
    #else
  // Read odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit
  if (len > 0) {
    uint32_t tmp;
    stride_read(hwfifo, &tmp, data_stride);
    memcpy(dest, &tmp, len);
    HWFIFO_ADDR_NEXT(hwfifo, const);
  }
    #endif
}
  #endif

// push to sw fifo from hwfifo
static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr,
                        const tu_hwfifo_access_t *access_mode) {
  uint16_t lin_bytes  = f->depth - wr_ptr;
  uint16_t wrap_bytes = n - lin_bytes;
  uint8_t *ff_buf     = f->buffer + wr_ptr;

  const volatile void *hwfifo = (const volatile void *)app_buf;
  if (n <= lin_bytes) {
    // Linear only case
    tu_hwfifo_read(hwfifo, ff_buf, n, access_mode);
  } else {
    // Wrap around case

    // Write full words to linear part of buffer
    const uint8_t  data_stride = access_mode->data_stride;
    const uint32_t odd_mask    = data_stride - 1;
    uint16_t       lin_even    = lin_bytes & ~odd_mask;
    tu_hwfifo_read(hwfifo, ff_buf, lin_even, access_mode);
    HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_even);
    ff_buf += lin_even;

    // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
    // combine it with the wrapped part to form a full word for data stride
    const uint8_t lin_odd = lin_bytes & odd_mask;
    if (lin_odd > 0) {
      const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd);
      uint8_t       buf_temp[4];
      tu_hwfifo_read(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode);
      HWFIFO_ADDR_NEXT(hwfifo, const);

      for (uint8_t i = 0; i < lin_odd; ++i) {
        ff_buf[i] = buf_temp[i];
      }
      for (uint8_t i = 0; i < wrap_odd; ++i) {
        f->buffer[i] = buf_temp[lin_odd + i];
      }

      wrap_bytes -= wrap_odd;
      ff_buf = f->buffer + wrap_odd; // wrap around
    } else {
      ff_buf = f->buffer;            // wrap around to beginning
    }

    // Write data wrapped part
    if (wrap_bytes > 0) {
      tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes, access_mode);
    }
  }
}

// pull from sw fifo to hwfifo
static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr,
                        const tu_hwfifo_access_t *access_mode) {
  uint16_t       lin_bytes  = f->depth - rd_ptr;
  uint16_t       wrap_bytes = n - lin_bytes; // only used if wrapped
  const uint8_t *ff_buf     = f->buffer + rd_ptr;

  volatile void *hwfifo = (volatile void *)app_buf;

  if (n <= lin_bytes) {
    // Linear only case
    tu_hwfifo_write(hwfifo, ff_buf, n, access_mode);
  } else {
    // Wrap around case

    // Read full words from linear part
    const uint8_t  data_stride = access_mode->data_stride;
    const uint32_t odd_mask    = data_stride - 1;
    uint16_t       lin_even = lin_bytes & ~odd_mask;
    tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode);
    HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even);
    ff_buf += lin_even;

    // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
    const uint8_t lin_odd = lin_bytes & odd_mask;
    if (lin_odd > 0) {
      const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd);

      uint8_t buf_temp[4];
      for (uint8_t i = 0; i < lin_odd; ++i) {
        buf_temp[i] = ff_buf[i];
      }
      for (uint8_t i = 0; i < wrap_odd; ++i) {
        buf_temp[lin_odd + i] = f->buffer[i];
      }

      tu_hwfifo_write(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode);
      HWFIFO_ADDR_NEXT(hwfifo, );

      wrap_bytes -= wrap_odd;
      ff_buf = f->buffer + wrap_odd; // wrap around
    } else {
      ff_buf = f->buffer;            // wrap around to beginning
    }

    // Read data wrapped part
    if (wrap_bytes > 0) {
      tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes, access_mode);
    }
  }
}
#endif

// send n items to fifo WITHOUT updating write pointer
static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr) {
  uint16_t lin_bytes  = f->depth - wr_ptr;
  uint16_t wrap_bytes = n - lin_bytes;
  uint8_t *ff_buf     = f->buffer + wr_ptr;

  if (n <= lin_bytes) {
    // Linear only case
    memcpy(ff_buf, app_buf, n);
  } else {
    // Wrap around case
    memcpy(ff_buf, app_buf, lin_bytes);                                    // linear part
    memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); // wrapped part
  }
}

// get n items from fifo WITHOUT updating read pointer
static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr) {
  uint16_t       lin_bytes  = f->depth - rd_ptr;
  uint16_t       wrap_bytes = n - lin_bytes; // only used if wrapped
  const uint8_t *ff_buf     = f->buffer + rd_ptr;

  // single byte access
  if (n <= lin_bytes) {
    // Linear only
    memcpy(app_buf, ff_buf, n);
  } else {
    // Wrap around
    memcpy(app_buf, ff_buf, lin_bytes);                            // linear part
    memcpy((uint8_t *)app_buf + lin_bytes, f->buffer, wrap_bytes); // wrapped part
  }
}

//--------------------------------------------------------------------+
// Index Helper
//--------------------------------------------------------------------+

// Advance an absolute index
// "absolute" index is only in the range of [0..2*depth)
static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) {
  // We limit the index space of p such that a correct wrap around happens
  // Check for a wrap around or if we are in unused index space - This has to be checked first!!
  // We are exploiting the wrap around to the correct index
  uint16_t new_idx = (uint16_t)(idx + offset);
  if ((idx > new_idx) || (new_idx >= 2 * depth)) {
    const uint16_t non_used_index_space = (uint16_t)(UINT16_MAX - (2 * depth - 1));
    new_idx                             = (uint16_t)(new_idx + non_used_index_space);
  }

  return new_idx;
}

// index to pointer (0..depth-1), simply a modulo with minus.
TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t idx) {
  // Only run at most 3 times since index is limit in the range of [0..2*depth)
  while (idx >= depth) {
    idx -= depth;
  }
  return idx;
}

// Works on local copies of w
// When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo
static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
  uint16_t rd_idx;
  if (wr_idx >= f->depth) {
    rd_idx = wr_idx - f->depth;
  } else {
    rd_idx = wr_idx + f->depth;
  }

  f->rd_idx = rd_idx;
  return rd_idx;
}

//--------------------------------------------------------------------+
// n-API
//--------------------------------------------------------------------+

// Works on local copies of w and r
// Must be protected by read mutex since in case of an overflow read pointer gets modified
uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx,
                                    const tu_hwfifo_access_t *access_mode) {
  uint16_t count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx);
  if (count == 0) {
    return 0; // nothing to peek
  }

  // Check overflow and correct if required
  if (count > f->depth) {
    rd_idx = correct_read_index(f, wr_idx);
    count  = f->depth;
  }

  if (count < n) {
    n = count; // limit to available count
  }

  const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);

#if CFG_TUSB_FIFO_HWFIFO_API
  if (access_mode != NULL) {
    hwff_pull_n(f, p_buffer, n, rd_ptr, access_mode);
  } else
#endif
  {
    (void)access_mode;
    ff_pull_n(f, p_buffer, n, rd_ptr);
  }

  return n;
}

// Read n items without removing it from the FIFO, correct read pointer if overflowed
uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) {
  ff_lock(f->mutex_rd);
  const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, f->wr_idx, f->rd_idx, NULL);
  ff_unlock(f->mutex_rd);
  return ret;
}

// Read n items from fifo with access mode
uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode) {
  ff_lock(f->mutex_rd);

  // Peek the data: f->rd_idx might get modified in case of an overflow so we can not use a local variable
  n         = tu_fifo_peek_n_access_mode(f, buffer, n, f->wr_idx, f->rd_idx, access_mode);
  f->rd_idx = advance_index(f->depth, f->rd_idx, n);

  ff_unlock(f->mutex_rd);
  return n;
}

// Write n items to fifo with access mode
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
                                     const tu_hwfifo_access_t *access_mode) {
  if (n == 0) {
    return 0;
  }

  ff_lock(f->mutex_wr);

  uint16_t wr_idx = f->wr_idx;
  uint16_t rd_idx = f->rd_idx;

  const uint8_t *buf8 = (const uint8_t *)data;

  TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u:  ", rd_idx, wr_idx,
         tu_ff_overflow_count(f->depth, wr_idx, rd_idx), tu_ff_remaining_local(f->depth, wr_idx, rd_idx), n);

  if (!f->overwritable) {
    // limit up to full
    const uint16_t remain = tu_ff_remaining_local(f->depth, wr_idx, rd_idx);
    n                     = tu_min16(n, remain);
  } else {
    // In over-writable mode, fifo_write() is allowed even when fifo is full. In such case,
    // oldest data in fifo i.e. at read pointer data will be overwritten
    // Note: we can modify read buffer contents however we must not modify the read index itself within a write
    // function! Since it would end up in a race condition with read functions!
    if (n >= f->depth) {
      // Only copy last part
      if (access_mode == NULL) {
        buf8 += (n - f->depth);
      } else {
        // TODO should read from hw fifo to discard data, however reading an odd number could
        // accidentally discard data.
      }

      n = f->depth;

      // We start writing at the read pointer's position since we fill the whole buffer
      wr_idx = rd_idx;
    } else {
      const uint16_t overflowable_count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx);
      if (overflowable_count + n >= 2 * f->depth) {
        // Double overflowed
        // Index is bigger than the allowed range [0,2*depth)
        // re-position write index to have a full fifo after pushed
        wr_idx = advance_index(f->depth, rd_idx, f->depth - n);

        // TODO we should also shift out n bytes from read index since we avoid changing rd index !!
        // However memmove() is expensive due to actual copying + wrapping consideration.
        // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory
        // currently deliberately not implemented --> result in incorrect data read back
      } else {
        // normal + single overflowed:
        // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read()
        // Therefore we just increase write index
        // we will correct (re-position) read index later on in fifo_read() function
      }
    }
  }

  if (n) {
    const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
    TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr);

#if CFG_TUSB_FIFO_HWFIFO_API
    if (access_mode != NULL) {
      hwff_push_n(f, buf8, n, wr_ptr, access_mode);
    } else
#endif
    {
      ff_push_n(f, buf8, n, wr_ptr);
    }
    f->wr_idx = advance_index(f->depth, wr_idx, n);

    TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx);
  }

  ff_unlock(f->mutex_wr);

  return n;
}

uint16_t tu_fifo_discard_n(tu_fifo_t *f, uint16_t n) {
  const uint16_t count = tu_min16(n, tu_fifo_count(f)); // limit to available count
  ff_lock(f->mutex_rd);
  f->rd_idx = advance_index(f->depth, f->rd_idx, count);
  ff_unlock(f->mutex_rd);

  return count;
}

//--------------------------------------------------------------------+
// One API
//--------------------------------------------------------------------+

// peek() using local write/read index, correct read index if overflowed
// Be careful, caller must not lock mutex, since this Will also try to lock mutex
static bool ff_peek_local(tu_fifo_t *f, void *buf, uint16_t wr_idx, uint16_t rd_idx) {
  const uint16_t ovf_count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx);
  if (ovf_count == 0) {
    return false; // nothing to peek
  }

  // Correct read index if overflow
  if (ovf_count > f->depth) {
    ff_lock(f->mutex_rd);
    rd_idx = correct_read_index(f, wr_idx);
    ff_unlock(f->mutex_rd);
  }

  const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
  memcpy(buf, f->buffer + rd_ptr, 1);

  return true;
}

// Read one element out of the buffer, correct read index if overflowed
bool tu_fifo_read(tu_fifo_t *f, void *buffer) {
  // Peek the data
  // f->rd_idx might get modified in case of an overflow so we can not use a local variable
  const bool ret = ff_peek_local(f, buffer, f->wr_idx, f->rd_idx);
  if (ret) {
    ff_lock(f->mutex_rd);
    f->rd_idx = advance_index(f->depth, f->rd_idx, 1);
    ff_unlock(f->mutex_rd);
  }

  return ret;
}

// Read one item without removing it from the FIFO, correct read index if overflowed
bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer) {
  return ff_peek_local(f, p_buffer, f->wr_idx, f->rd_idx);
}

// Write one element into the buffer
bool tu_fifo_write(tu_fifo_t *f, const void *data) {
  bool ret;
  ff_lock(f->mutex_wr);

  const uint16_t wr_idx = f->wr_idx;

  if (tu_fifo_full(f) && !f->overwritable) {
    ret = false;
  } else {
    const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
    memcpy(f->buffer + wr_ptr, data, 1);
    f->wr_idx = advance_index(f->depth, wr_idx, 1);
    ret       = true;
  }

  ff_unlock(f->mutex_wr);

  return ret;
}

//--------------------------------------------------------------------+
// Index API
//--------------------------------------------------------------------+

/******************************************************************************/
/*!
    @brief Advance write pointer - intended to be used in combination with DMA.
    It is possible to fill the FIFO by use of a DMA in circular mode. Within
    DMA ISRs you may update the write pointer to be able to read from the FIFO.
    As long as the DMA is the only process writing into the FIFO this is safe
    to use.

    USE WITH CARE - WE DO NOT CONDUCT SAFETY CHECKS HERE!

    @param[in]  f
                Pointer to the FIFO buffer to manipulate
    @param[in]  n
                Number of items the write pointer moves forward
 */
/******************************************************************************/
void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n) {
  f->wr_idx = advance_index(f->depth, f->wr_idx, n);
}

// Correct the read index in case tu_fifo_overflow() returned true!
void tu_fifo_correct_read_pointer(tu_fifo_t *f) {
  ff_lock(f->mutex_rd);
  correct_read_index(f, f->wr_idx);
  ff_unlock(f->mutex_rd);
}

/******************************************************************************/
/*!
    @brief Advance read pointer - intended to be used in combination with DMA.
    It is possible to read from the FIFO by use of a DMA in linear mode. Within
    DMA ISRs you may update the read pointer to be able to again write into the
    FIFO. As long as the DMA is the only process reading from the FIFO this is
    safe to use.

    USE WITH CARE - WE DO NOT CONDUCT SAFETY CHECKS HERE!

    @param[in]  f
                Pointer to the FIFO buffer to manipulate
    @param[in]  n
                Number of items the read pointer moves forward
 */
/******************************************************************************/
void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n) {
  f->rd_idx = advance_index(f->depth, f->rd_idx, n);
}

/******************************************************************************/
/*!
   @brief Get read info

   Returns the length and pointer from which bytes can be read in a linear manner.
   This is of major interest for DMA transmissions. If returned length is zero the
   corresponding pointer is invalid.
   The read pointer does NOT get advanced, use tu_fifo_advance_read_pointer() to
   do so!
   @param[in]       f
                    Pointer to FIFO
   @param[out]      *info
                    Pointer to struct which holds the desired infos
 */
/******************************************************************************/
void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) {
  // Operate on temporary values in case they change in between
  uint16_t wr_idx = f->wr_idx;
  uint16_t rd_idx = f->rd_idx;

  uint16_t cnt = tu_ff_overflow_count(f->depth, wr_idx, rd_idx);

  // Check overflow and correct if required - may happen in case a DMA wrote too fast
  if (cnt > f->depth) {
    ff_lock(f->mutex_rd);
    rd_idx = correct_read_index(f, wr_idx);
    ff_unlock(f->mutex_rd);

    cnt = f->depth;
  }

  // Check if fifo is empty
  if (cnt == 0) {
    info->linear.len  = 0;
    info->wrapped.len = 0;
    info->linear.ptr  = NULL;
    info->wrapped.ptr = NULL;
    return;
  }

  // Get relative pointers
  uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
  uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);

  // Copy pointer to buffer to start reading from
  info->linear.ptr = &f->buffer[rd_ptr];

  // Check if there is a wrap around necessary
  if (wr_ptr > rd_ptr) {
    // Non wrapping case
    info->linear.len = cnt;

    info->wrapped.len = 0;
    info->wrapped.ptr = NULL;
  } else {
    info->linear.len = f->depth - rd_ptr; // Also the case if FIFO was full

    info->wrapped.len = cnt - info->linear.len;
    info->wrapped.ptr = f->buffer;
  }
}

/******************************************************************************/
/*!
   @brief Get linear write info

   Returns the length and pointer to which bytes can be written into FIFO in a linear manner.
   This is of major interest for DMA transmissions not using circular mode. If a returned length is zero the
   corresponding pointer is invalid. The returned lengths summed up are the currently free space in the FIFO.
   The write pointer does NOT get advanced, use tu_fifo_advance_write_pointer() to do so!
   TAKE CARE TO NOT OVERFLOW THE BUFFER MORE THAN TWO TIMES THE FIFO DEPTH - IT CAN NOT RECOVERE OTHERWISE!
   @param[in]       f
                    Pointer to FIFO
   @param[out]      *info
                    Pointer to struct which holds the desired infos
 */
/******************************************************************************/
void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info) {
  uint16_t wr_idx = f->wr_idx;
  uint16_t rd_idx = f->rd_idx;
  uint16_t remain = tu_ff_remaining_local(f->depth, wr_idx, rd_idx);

  if (remain == 0) {
    info->linear.len  = 0;
    info->wrapped.len = 0;
    info->linear.ptr  = NULL;
    info->wrapped.ptr = NULL;
    return;
  }

  // Get relative pointers
  uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
  uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);

  // Copy pointer to buffer to start writing to
  info->linear.ptr = &f->buffer[wr_ptr];

  if (wr_ptr < rd_ptr) {
    // Non wrapping case
    info->linear.len  = rd_ptr - wr_ptr;
    info->wrapped.len = 0;
    info->wrapped.ptr = NULL;
  } else {
    info->linear.len  = f->depth - wr_ptr;
    info->wrapped.len = remain - info->linear.len; // Remaining length - n already was limited to remain or FIFO depth
    info->wrapped.ptr = f->buffer;              // Always start of buffer
  }
}
