LCOV - code coverage report
Current view: top level - felix-star/src - flx_file_tohost_api.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 174 215 80.9 %
Date: 2025-06-10 03:23:28 Functions: 26 37 70.3 %

          Line data    Source code
       1             : #include <sys/types.h>
       2             : #include <sys/stat.h>
       3             : #include <fcntl.h>
       4             : #include <cstdio>
       5             : #include <cstdlib>
       6             : #include <chrono>
       7             : #include <thread>
       8             : 
       9             : #include "block.h"
      10             : #include "fifo.h"
      11             : #include "felix/felix_fid.h"
      12             : 
      13             : extern "C" {
      14             :   #include "flx_api.h"
      15             :   #include "cmem_buffer.h"
      16             :   #include "log.h"
      17             : }
      18             : 
      19          44 : void flx_init_cmem_buffer(struct cmem_buffer* buf, size_t size, char* cmem_name) {
      20          44 :   if (buf->vmem) {
      21          42 :     vmem_buffer_init(buf, size);
      22             :   } else {
      23           2 :     cmem_buffer_init(buf, size, cmem_name);
      24             :   }
      25          44 : }
      26             : 
      27          44 : void flx_close_cmem_buffer(struct cmem_buffer* buf) {
      28          44 :   if (buf->vmem) {
      29          42 :     vmem_buffer_close(buf);
      30             :   } else {
      31           2 :     cmem_buffer_close(buf);
      32             :   }
      33          44 : }
      34             : 
      35             : int
      36          44 : flx_init_card(struct flx* flx, struct config* cfg)
      37             : {
      38          44 :   LOG_INFO("> flx_init_card(file=%s, full_mode=%d)", cfg->file, cfg->full_mode);
      39          44 :   flx->device = cfg->device;
      40          44 :   flx->co = cfg->co;
      41          44 :   flx->vid = cfg->vid;
      42          44 :   flx->did = cfg->did;
      43          44 :   flx->cid = cfg->cid;
      44          44 :   flx->flxcard = NULL;  // card is ignored, it is used in tohost
      45             : 
      46             :   // use open rather than fopen for fifos
      47          44 :   int fd = open(cfg->file, O_RDONLY | O_NONBLOCK);
      48          44 :   flx->fp = fdopen(fd, "r");
      49             :   // flx->fp = fopen(file, "r");
      50          44 :   if (flx->fp == NULL) {
      51           0 :     fprintf(stderr, "felix: error: could not open file %s\n", cfg->file);
      52           0 :     return 1;
      53             :   }
      54             : 
      55          56 :   LOG_INFO("Input from file %s in %s mode", cfg->file, cfg->repeat ? "repeat" : "non-repeat");
      56             : 
      57          44 :   flx->regmap_version = cfg->regmap;
      58          44 :   u_long major = (flx->regmap_version & 0xFF00) >> 8;
      59          44 :   u_long minor = (flx->regmap_version & 0x00FF) >> 0;
      60          44 :   LOG_INFO("  regmap version %lu.%lu", major, minor);
      61          44 :   flx->mode = cfg->full_mode ? FLX_MODE_FULL : FLX_MODE_GBT;
      62          44 :   flx->no_of_channels = 12;
      63             : 
      64          44 :   flx->ttc2h_enable = cfg->ttc2h_enable;
      65          44 :   flx->block_rate = cfg->block_rate;
      66          44 :   if (flx->regmap_version < 0x500){
      67          23 :     flx->trailer_size = 2;
      68          23 :     flx->block_size = 1024;
      69             :   } else {
      70          21 :     flx->block_size = cfg->block_size;
      71          21 :     flx->trailer_size = 4;
      72             :   }
      73             : 
      74             :   // elinks
      75          44 :   flx->num_elinks = cfg->num_elinks;
      76          44 :   flx->has_streams = cfg->has_streams;
      77          44 :   flx->elinks = cfg->elinks;
      78             : 
      79          44 :   flx->repeat = cfg->repeat;
      80             : 
      81          44 :   return 0;
      82             : }
      83             : 
      84           0 : int flx_get_toflx_dmaid(struct config* cfg){
      85           0 :   return cfg->dmaid;
      86             : }
      87             : 
      88             : void
      89          44 : flx_close_card(struct flx* flx)
      90             : {
      91          44 :   LOG_INFO("Closing felix device");
      92          44 :   fclose(flx->fp);
      93          44 : }
      94             : 
      95             : 
      96             : void
      97          44 : flx_start_circular_dma(struct flx* flx, struct cmem_buffer* buf, unsigned dmaid)
      98             : {
      99          44 :   LOG_INFO("> flx_start_circular_dma(dmaid=%d)", dmaid);
     100          44 :   flx->dmaid = dmaid;
     101             : 
     102             :   // flx->flxcard->dma_stop(dmaid);
     103             :   // flx->flxcard->dma_to_host(dmaid, buf->paddr, buf->size, FLX_DMA_WRAPAROUND);
     104             : 
     105          44 :   buf->pstart = buf->paddr;
     106          44 :   buf->pend = buf->pstart + buf->size;
     107          44 :   buf->pc_ptr = buf->pstart; // flx->flxcard->dma_get_read_ptr(dmaid);
     108             : 
     109          44 :   flx->fw_ptr = buf->pstart;
     110             : 
     111          44 :   LOG_INFO("  cmem buffer [0x%x,0x%x] %lu Blocks", buf->pstart, buf->pend, buf->size/1024);
     112          44 :   LOG_INFO("  cmem virtual address 0x%x", buf->vaddr);
     113          44 :   LOG_INFO("  fw_ptr 0x%x", flx->fw_ptr);
     114          44 :   LOG_INFO("  pc_ptr 0x%x", buf->pc_ptr);
     115          44 : }
     116             : 
     117             : void
     118     9073479 : flx_wait_data_available(struct flx* flx, struct cmem_buffer* buf)
     119             : {
     120     9073479 :   LOG_TRACE("flx_wait_data_available");
     121     9073479 :   if (flx->repeat) {
     122             :     // just return after 500 ns, data is always available
     123     6116703 :     std::this_thread::sleep_for(std::chrono::nanoseconds(500));
     124             :   } else {
     125             :     // FIXME for fifo we should rely on inotify, option should be called flx->fifo, which infers no-repeat
     126     2956776 :     std::this_thread::sleep_for(std::chrono::nanoseconds(500));
     127             :     // std::this_thread::sleep_for(std::chrono::seconds(3));
     128             :   }
     129     9073479 : }
     130             : 
     131             : void
     132          44 : flx_cancel_irqs(struct flx* flx)
     133             : {
     134             :   // ignore
     135          44 : }
     136             : 
     137             : 
     138             : int
     139           0 : flx_dma_cmp_even_bits(struct flx* flx)
     140             : {
     141           0 :   LOG_ERR("< flx_check_dma_cmp_even_bits() NOT IMPLEMENTED\n");
     142           0 :   return 0;
     143             : }
     144             : 
     145             : void
     146     5750323 : flx_read_and_update_fw_ptr(struct flx* flx, struct cmem_buffer* buf)
     147             : {
     148     5750323 :   LOG_TRACE("flx_read_and_update_fw_ptr");
     149             :   // File READ
     150     5750323 :   void *ptr = (void*)(buf->vaddr + (flx->fw_ptr - buf->pstart));
     151     5750323 :   size_t block_size = flx->block_size;
     152     5750323 :   size_t max_count;
     153     5750323 :   if (flx->block_rate == 0) {
     154     5748875 :     max_count = (buf->pend - flx->fw_ptr)/block_size;
     155        1448 :   } else if (flx->block_rate < 6000){
     156             :     max_count = 1;
     157           0 :   } else if (flx->block_rate < 12000){
     158             :     max_count = 2;
     159           0 :   } else if (flx->block_rate < 120000){
     160             :     max_count = 10;
     161             :   } else {
     162           0 :     max_count = 32;
     163             :   }
     164     5750323 :   std::chrono::time_point<std::chrono::system_clock> start, end;
     165             : 
     166     5750323 :   start = std::chrono::system_clock::now();
     167     5750323 :   size_t count = fread(ptr, block_size, max_count, flx->fp);
     168     5750323 :   end = std::chrono::system_clock::now();
     169             : 
     170             :   //so reading a block takes
     171     5750323 :   if(flx->block_rate > 0 && count > 0){
     172        1444 :     std::chrono::nanoseconds elapsed_time = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
     173        1444 :     long block_read_time = elapsed_time.count()/count;
     174        1444 :     long target_time = 1.0e9*(1.0/(double)flx->block_rate);
     175        1444 :     long sleep_time = target_time - block_read_time;
     176        1444 :     std::this_thread::sleep_for(std::chrono::nanoseconds(sleep_time));
     177             :   }
     178             : 
     179     5750323 :   if ((count == 0) && (flx->repeat)) {
     180     1401377 :     LOG_TRACE("Reset file");
     181     1401377 :     fseek(flx->fp, 0, SEEK_SET);
     182             :   }
     183     5750323 :   flx->fw_ptr += block_size*count;
     184     5750323 :   if(flx->fw_ptr == buf->pend){
     185        4116 :     flx->fw_ptr = buf->pstart;
     186        4116 :     flx->odd = !flx->odd;
     187        4116 :     LOG_TRACE("Odd %d", flx->odd);
     188             :   }
     189     5750323 : }
     190             : 
     191             : size_t
     192     3082487 : flx_bytes_available(struct flx* flx, struct cmem_buffer* buf)
     193             : {
     194     3082487 :   flx_read_and_update_fw_ptr(flx, buf);
     195             : 
     196     3082487 :   u_long dma_ptr = flx->fw_ptr; // flx->flxcard->dma_get_current_address(flx->dmaid);
     197     3082487 :   size_t available;
     198             : 
     199     3082487 :   if(!flx->odd) // if(flx->flxcard->dma_cmp_even_bits(flx->dmaid))
     200             :   {
     201     3013881 :     LOG_TRACE("< flx_bytes_available(even) %d", dma_ptr - buf->pc_ptr);
     202     3013881 :     available = dma_ptr - buf->pc_ptr;
     203             :   }
     204             :   else
     205             :   {
     206       68606 :     LOG_TRACE("< flx_bytes_available(odd) %d", buf->size + dma_ptr - buf->pc_ptr);
     207       68606 :     available = buf->size + dma_ptr - buf->pc_ptr;
     208             :   }
     209     3082487 :   return available;
     210             : }
     211             : 
     212             : size_t
     213           0 : flx_bytes_available_to_read(struct flx* flx, struct cmem_buffer* buf)
     214             : {
     215           0 :   size_t available = flx_bytes_available(flx, buf);
     216           0 :   available = MIN(available, buf->pend - buf->pc_ptr);
     217           0 :   LOG_TRACE("< flx_bytes_available_to_read() %d", available);
     218           0 :   return available;
     219             : }
     220             : 
     221             : void*
     222     2667836 : flx_get_write_ptr(struct flx* flx, struct cmem_buffer* buf)
     223             : {
     224     2667836 :   flx_read_and_update_fw_ptr(flx, buf);
     225             : 
     226     2667836 :   u_long dma_ptr = flx->fw_ptr; // flx->flxcard->dma_get_current_address(flx->dmaid);
     227     2667836 :   LOG_TRACE("< flx_get_write_ptr() 0x%x", dma_ptr);
     228     2667836 :   return (void*)(buf->vaddr + (dma_ptr - buf->pstart));
     229             : }
     230             : 
     231             : void*
     232     2667836 : flx_get_read_ptr(struct flx* flx, struct cmem_buffer* buf)
     233             : {
     234     2667836 :   u_long dma_ptr = buf->pc_ptr;
     235     2667836 :   LOG_TRACE("< flx_get_read_ptr() 0x%x", dma_ptr);
     236     2667836 :   return (void*)(buf->vaddr + (dma_ptr - buf->pstart));
     237             : }
     238             : 
     239             : void
     240     2668969 : flx_set_read_ptr(struct flx* flx, struct cmem_buffer* buf, void* ptr)
     241             : {
     242     2668969 :   LOG_TRACE("x %x %x %x", ptr, buf->pc_ptr, flx->fw_ptr);
     243     2668969 :   uint64_t pnew = buf->pstart + ((uint64_t)ptr - buf->vaddr);
     244     2668969 :   LOG_TRACE("> flx_set_read_ptr(ptr=0x%x)", pnew);
     245     2668969 :   buf->pc_ptr = pnew; // flx->flxcard->dma_set_ptr(flx->dmaid, pnew);
     246     2668969 : }
     247             : 
     248             : void
     249     3082487 : flx_advance_read_ptr(struct flx* flx, struct cmem_buffer* buf, size_t bytes)
     250             : {
     251     3082487 :   buf->pc_ptr += bytes;
     252     3082487 :   if(buf->pc_ptr == buf->pend){
     253        3367 :     buf->pc_ptr = buf->pstart;
     254             :   }
     255     3082487 :   LOG_TRACE("> flx_advance_read_ptr(bytes=%d) 0x%x", bytes, buf->pc_ptr);
     256             :   // flx->flxcard->dma_set_ptr(flx->dmaid, buf->pc_ptr);
     257     3082487 : }
     258             : 
     259          44 : int flx_get_regmap_version(struct flx* flx) {
     260             :   // 4.10 formatted as 0x040A
     261          44 :   return flx->regmap_version;
     262             : }
     263             : 
     264             : int
     265          88 : flx_get_mode(struct flx* flx)
     266             : {
     267          88 :   LOG_INFO("< flx_get_mode() %d", flx->mode);
     268          88 :   return flx->mode;
     269             : }
     270             : 
     271          27 : int flx_get_number_of_channels(struct flx* flx)
     272             : {
     273          27 :   LOG_INFO("< flx_get_number_of_channels() %d", flx->no_of_channels);
     274          27 :   return flx->no_of_channels;
     275             : }
     276             : 
     277           0 : int flx_get_wide_mode(struct flx* flx)
     278             : {
     279           0 :   LOG_INFO("< flx_get_wide_mode() %d", 0);
     280           0 :   return 0;
     281             : }
     282             : 
     283          44 : uint64_t flx_get_blocksize(struct flx* flx)
     284             : {
     285          44 :   return flx->block_size;
     286             : }
     287             : 
     288          44 : int flx_get_trailer_size(struct flx* flx)
     289             : {
     290          44 :   return flx->trailer_size;
     291             : }
     292             : 
     293           0 : int flx_is_enabled(struct flx* flx, u_int channel, u_int egroup, u_int epath, u_int is_to_flx)
     294             : {
     295           0 :   LOG_INFO("< flx_is_enabled() %d", 1);
     296           0 :   return 1;
     297             : }
     298             : 
     299           0 : int flx_has_stream_id(struct flx* flx, u_int channel, u_int egroup, u_int epath)
     300             : {
     301           0 :   LOG_INFO("< flx_has_stream_id() %d", 1);
     302           0 :   return 1;
     303             : }
     304             : 
     305           0 : void flx_dma_from_host(struct flx* flx, struct cmem_buffer* dma_buffer, uint64_t buffer, size_t size, unsigned int wraparound)
     306             : {
     307           0 :   LOG_ERR("> flx_dma_from_host NOT IMPLEMENTED");
     308             :   // flx->flxcard->dma_from_host(flx->dmaid, buffer, size, 0);
     309           0 :   exit(1);
     310             : }
     311             : 
     312           0 : void flx_dma_wait(struct flx* flx, struct cmem_buffer* buf)
     313             : {
     314           0 :   LOG_ERR("> flx_dma_wait NOT IMPLEMENTED");
     315             :   // flx->flxcard->dma_wait(flx->dmaid);
     316           0 :   exit(1);
     317             : }
     318             : 
     319           0 : int flx_dma_max_tlp_bytes(struct flx* flx)
     320             : {
     321           0 :   LOG_INFO("< flx_dma_max_tlp_bytes() %d", 256);
     322           0 :   return 256; // flx->flxcard->dma_max_tlp_bytes();
     323             : }
     324             : 
     325           0 : void flx_cfg_set_option(struct flx* flx, const char *key, u_long value)
     326             : {
     327           0 :   LOG_ERR("> flx_cfg_set_option NOT IMPLEMENTED %s 0x%x", key, value);
     328             :   // flx->flxcard->cfg_set_option(key, value);
     329           0 :   exit(1);
     330             : }
     331             : 
     332           0 : u_long flx_cfg_get_option(struct flx* flx, const char *key)
     333             : {
     334           0 :   LOG_ERR("< flx_cfg_get_option NOT IMPLEMENTED %s", key);
     335             :   // return flx->flxcard->cfg_get_option(key);
     336           0 :   return 0;
     337             : }
     338             : 
     339         220 : bool flx_cfg_check_option(struct flx* flx, const char *key)
     340             : {
     341         220 :   LOG_ERR("< flx_cfg_get_option NOT IMPLEMENTED %s", key);
     342         220 :   return false;
     343             : }
     344             : 
     345             : uint64_t
     346       64512 : flx_dma_get_read_ptr(struct flx* flx, struct cmem_buffer* buf)
     347             : {
     348       64512 :   u_long dma_ptr = buf->pc_ptr;
     349       64512 :   return dma_ptr;
     350             : }
     351             : 
     352             : uint64_t
     353       64512 : flx_dma_get_current_address(struct flx* flx, struct cmem_buffer* buf)
     354             : {
     355       64512 :   return 0;
     356             :   //return flx->flxcard->dma_get_current_address(flx->dmaid);
     357             : }
     358             : 
     359             : #define BLOCK_EGROUP_MASK      0x0038
     360             : #define BLOCK_EGROUP_SHIFT     3
     361             : 
     362          44 : unsigned int flx_read_elink_config(struct flx* flx, struct elink_descr** elinks, unsigned int is_to_flx) {
     363          44 :   unsigned num_elinks = 0;
     364             : 
     365             :   // plus 1 for the TTC2H
     366          44 :   unsigned number_of_paths = flx->num_elinks + 1;
     367          44 :   *elinks = (struct elink_descr*)malloc(number_of_paths * sizeof(elink_descr));
     368             : 
     369             :   //TTC-to-Host link = #Nchannels group #7 path #3
     370          44 :   if (flx->ttc2h_enable) {
     371           4 :   struct elink_descr* e = *elinks + num_elinks++;
     372           4 :   unsigned no_of_channels = flx_get_number_of_channels(flx);
     373           4 :   e->elink = TTC2HOST_LINK(no_of_channels);
     374           4 :   e->type = elink_type::TTC;
     375           4 :   e->has_streams = 0;
     376           4 :   LOG_INFO("TTC2H E-Link %d:\t 0x%02X", num_elinks-1, e->elink);
     377             :   }
     378             : 
     379             :   uint8_t stream = 0; // NOTE, the full elink, no streams
     380             :   uint8_t virt = 0;
     381             : 
     382         101 :   for (unsigned i=0; i<flx->num_elinks; i++) {
     383          57 :   struct elink_descr* e = *elinks + num_elinks++;
     384          57 :   e->elink = flx->elinks[i];
     385          57 :   e->has_streams = flx->has_streams[i];
     386          57 :   int egroupnr = (flx->elinks[i] & BLOCK_EGROUP_MASK) >> BLOCK_EGROUP_SHIFT;
     387          57 :   if (egroupnr < 7) {
     388          57 :     e->type = elink_type::DAQ;
     389         167 :     LOG_INFO("DAQ E-Link %d: %d 0x%x fid: 0x%lx, has streams: %c", i, e->elink, e->elink, get_fid(flx->co, e->elink, stream, flx->vid, is_to_flx, virt), e->has_streams ? 'y' : 'n');
     390             :   }
     391             :   else {
     392           0 :     e->type = elink_type::DCS;
     393           0 :     LOG_INFO("DCS E-Link %d: %d 0x%x fid: 0x%lx, has streams: %c", i, e->elink, e->elink, get_fid(flx->co, e->elink, stream, flx->vid, is_to_flx, virt), e->has_streams ? 'y' : 'n');
     394             :   }
     395             :   }
     396          44 :   return num_elinks;
     397             : }
     398             : 
     399          44 : void flx_irq_data_enable(struct flx* flx){
     400          44 :   LOG_DBG("Enabling IRQ_DATA_AVAILABLE interrupt");
     401          44 : }
     402             : 
     403          88 : void flx_irq_data_disable(struct flx* flx){
     404          88 :   LOG_DBG("Disabling IRQ_DATA_AVAILABLE interrupt");
     405          88 : }
     406             : 
     407          44 : void flx_irq_busy_enable(struct flx* flx){
     408          44 :   LOG_DBG("Enabling IRQ_BUSY_CHANGE_TO_HOST interrupt");
     409          44 : }
     410             : 
     411          44 : void flx_irq_busy_disable(struct flx* flx){
     412          44 :   LOG_DBG("Disabling IRQ_BUSY_CHANGE_TO_HOST interrupt");
     413          44 : }

Generated by: LCOV version 1.0