Program Listing for File tohost_buffer_flx.cpp

Return to documentation for file (tohost_buffer_flx.cpp)

#include "tohost_buffer.hpp"

FlxToHostBuffer::FlxToHostBuffer(int dmaid, std::shared_ptr<Device> d)
    : ToHostBuffer(dmaid, d){}


FlxToHostBuffer::~FlxToHostBuffer()
{
    m_device->dma_stop(m_dmaid);
}

void FlxToHostBuffer::allocate_buffer(size_t size,
                            const std::string& name,
                            bool vmem, bool free_previous_cmem)
{
    m_size = size;
    m_buffer = std::make_unique<CmemBuffer>(size, name, free_previous_cmem);
    m_block_size = m_device->get_block_size();
}


void FlxToHostBuffer::dma_start_continuous()
{
    m_device->dma_to_host(m_buffer.get(), m_dmaid);
    m_device->dma_set_sw_ptr(m_dmaid, m_buffer->paddr);
}


void FlxToHostBuffer::dma_wait_for_data_irq()
{
    m_device->irq_wait(m_irq_on_data);
}


size_t FlxToHostBuffer::dma_bytes_available()
{
    u_long dma_ptr = m_device->dma_get_fw_ptr(m_dmaid);
    if( dma_ptr > m_buffer->pc_ptr ) {
        return dma_ptr - m_buffer->pc_ptr;
    }
    else if( dma_ptr < m_buffer->pc_ptr ) {
        return m_buffer->size + dma_ptr - m_buffer->pc_ptr;
    }
    else { // dma_ptr == buf->pc_ptr
        if( m_device->dma_cmp_even_bits(m_dmaid) ) {
            return 0; // Buffer empty
        } else {
            return m_buffer->size; // Buffer full
        }
    }
}


bool FlxToHostBuffer::dma_is_full()
{
    u_long write_ptr = m_device->dma_get_fw_ptr(m_dmaid);
    u_long read_ptr  = m_buffer->pc_ptr;
    return (write_ptr == read_ptr and not m_device->dma_cmp_even_bits(m_dmaid));
}


size_t FlxToHostBuffer::dma_bytes_available_nowrap()
{
    size_t available = dma_bytes_available();
    return MIN(available, m_buffer->pend - m_buffer->pc_ptr);
}


uint64_t FlxToHostBuffer::dma_get_write_ptr()
{
    u_long dma_ptr = m_device->dma_get_fw_ptr(m_dmaid);
    return (m_buffer->vaddr + (dma_ptr - m_buffer->paddr));
}


uint64_t FlxToHostBuffer::dma_get_read_ptr()
{
    return (m_buffer->vaddr + (m_buffer->pc_ptr - m_buffer->paddr));
}


uint64_t FlxToHostBuffer::dma_get_write_offset()
{
    return ( m_device->dma_get_fw_ptr(m_dmaid) - m_buffer->paddr );
}


uint64_t FlxToHostBuffer::dma_get_read_offset()
{
    return (m_buffer->pc_ptr - m_buffer->paddr);
}


void FlxToHostBuffer::dma_set_read_ptr_vaddr(uint64_t v_addr)
{
    uint64_t pnew = m_buffer->paddr + (v_addr - m_buffer->vaddr);
    m_buffer->pc_ptr = pnew;
    m_device->dma_set_sw_ptr(m_dmaid, pnew);
}


void FlxToHostBuffer::dma_set_read_ptr_paddr(uint64_t p_addr)
{
    m_buffer->pc_ptr = p_addr;
    m_device->dma_set_sw_ptr(m_dmaid, p_addr);
}


void FlxToHostBuffer::dma_advance_read_ptr(size_t bytes)
{
    m_buffer->pc_ptr += bytes;
    if(m_buffer->pc_ptr == m_buffer->pend){
        m_buffer->pc_ptr = m_buffer->paddr;
    }
    m_device->dma_set_sw_ptr(m_dmaid, m_buffer->pc_ptr);
}