Line data Source code
1 : #include "fromhost_buffer.hpp" 2 : #include <memory> 3 : 4 0 : FlxFromHostBuffer::FlxFromHostBuffer(std::shared_ptr<Device> d) 5 0 : : FromHostBuffer(d){}; 6 : 7 : 8 0 : FlxFromHostBuffer::~FlxFromHostBuffer() 9 : { 10 0 : m_device->dma_stop(m_dmaid); 11 0 : } 12 : 13 : 14 0 : void FlxFromHostBuffer::allocate_buffer(size_t size, 15 : const std::string& name, 16 : bool vmem, bool free_previous_cmem) 17 : { 18 0 : m_size = size; 19 0 : m_buffer = std::make_unique<CmemBuffer>(size, name, free_previous_cmem); 20 0 : uint8_t* vaddr = reinterpret_cast<uint8_t*>(m_buffer->vaddr); 21 0 : m_encoder.set_destination_parameters(vaddr, m_buffer->size); 22 0 : } 23 : 24 : 25 0 : void FlxFromHostBuffer::dma_start_continuous() 26 : { 27 0 : m_device->dma_from_host(m_buffer.get(), m_dmaid); 28 0 : m_buffer->pc_ptr = m_buffer->paddr; 29 0 : m_device->dma_set_sw_ptr(m_dmaid, m_buffer->pc_ptr); 30 0 : } 31 : 32 0 : void FlxFromHostBuffer::dma_start_circular_trickle_buffer() 33 : { 34 : //This differs from dma_from_host() because it requires the size to be passed 35 0 : m_device->dma_from_host_trickle(m_buffer.get(), m_dmaid, m_trickle_config_size); 36 0 : } 37 : 38 0 : void FlxFromHostBuffer::set_oneshot_trickle_buffer(size_t config_size) 39 : { 40 0 : if(config_size > 0) 41 : { 42 0 : m_device->dma_set_oneshot(m_buffer.get(), m_dmaid, config_size); 43 : 44 0 : auto start = std::chrono::high_resolution_clock::now(); // Start timer 45 : 46 0 : while(m_device->dma_enabled(m_dmaid)){ 47 0 : auto now = std::chrono::high_resolution_clock::now(); 48 0 : auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start); 49 : 50 0 : if(elapsed.count() >= 500){ // 500 milliseconds = 0.5 seconds 51 0 : LOG_ERR("The firmware was not able to read in time DMA %d", m_dmaid); 52 0 : break; // Exit the loop if the DMA is still enabled after 0.5 seconds 53 : } 54 : } 55 : } 56 0 : } 57 : 58 0 : size_t FlxFromHostBuffer::dma_free_bytes() 59 : { 60 0 : bool even = m_device->dma_cmp_even_bits(m_dmaid); 61 0 : uint64_t pc_wr_ptr = m_device->dma_get_sw_ptr(m_dmaid); 62 0 : uint64_t fw_rd_ptr = m_device->dma_get_fw_ptr(m_dmaid); 63 0 : return dma_compute_free_bytes(fw_rd_ptr, pc_wr_ptr, even); 64 : } 65 : 66 : 67 0 : bool FlxFromHostBuffer::dma_is_full() 68 : { 69 0 : u_long read_ptr = m_device->dma_get_fw_ptr(m_dmaid); 70 0 : u_long write_ptr = m_device->dma_get_sw_ptr(m_dmaid); 71 0 : return (write_ptr == read_ptr and not m_device->dma_cmp_even_bits(m_dmaid)); 72 : } 73 : 74 : 75 0 : uint64_t FlxFromHostBuffer::dma_get_read_offset() 76 : { 77 0 : return ( m_device->dma_get_fw_ptr(m_dmaid) - m_buffer->paddr ); 78 : } 79 : 80 : 81 0 : uint64_t FlxFromHostBuffer::dma_get_write_offset() 82 : { 83 0 : return ( m_buffer->pc_ptr - m_buffer->paddr ); 84 : } 85 : 86 : 87 0 : uint64_t FlxFromHostBuffer::dma_get_write_ptr() 88 : { 89 0 : return ( m_buffer->pc_ptr - m_buffer->paddr + m_buffer->vaddr ); 90 : } 91 : 92 : 93 0 : void FlxFromHostBuffer::dma_set_write_offset(uint64_t offset) 94 : { 95 0 : m_buffer->pc_ptr = offset + m_buffer->paddr; 96 0 : m_device->dma_set_sw_ptr(m_dmaid, m_buffer->pc_ptr); 97 0 : } 98 : 99 : 100 0 : void FlxFromHostBuffer::dma_advance_write_ptr(size_t bytes) 101 : { 102 0 : m_buffer->pc_ptr += bytes; 103 0 : if(m_buffer->pc_ptr == m_buffer->pend){ 104 0 : m_buffer->pc_ptr = m_buffer->paddr; 105 : } 106 0 : m_device->dma_set_sw_ptr(m_dmaid, m_buffer->pc_ptr); 107 0 : }