LCOV - code coverage report
Current view: top level - felix-star/src - flx_file_toflx_api.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 129 213 60.6 %
Date: 2025-06-10 03:23:28 Functions: 14 40 35.0 %

          Line data    Source code
       1             : #include <sys/types.h>
       2             : #include <sys/stat.h>
       3             : #include <algorithm>
       4             : #include <fcntl.h>
       5             : #include <cstdio>
       6             : #include <cstdlib>
       7             : #include <unistd.h>
       8             : #include <errno.h>
       9             : #include <string.h>
      10             : #include <limits.h>
      11             : 
      12             : #include "block.h"
      13             : #include "felix-star/client.h"
      14             : #include "felix/felix_fid.h"
      15             : 
      16             : extern "C" {
      17             :   #include "flx_api.h"
      18             :   #include "cmem_buffer.h"
      19             :   #include "log.h"
      20             :   #include "fifo.h"
      21             : }
      22             : 
      23          39 : void flx_init_cmem_buffer(struct cmem_buffer* buf, size_t size, char* cmem_name) {
      24          39 :   if (buf->vmem) {
      25          37 :     vmem_buffer_init(buf, size);
      26             :   } else {
      27           2 :     cmem_buffer_init(buf, size, cmem_name);
      28             :   }
      29          39 : }
      30             : 
      31          39 : void flx_close_cmem_buffer(struct cmem_buffer* buf) {
      32          39 :   if (buf->vmem) {
      33          37 :     vmem_buffer_close(buf);
      34             :   } else {
      35           2 :     cmem_buffer_close(buf);
      36             :   }
      37          39 : }
      38             : 
      39             : int
      40          39 : flx_init_card(struct flx* flx, struct config* cfg) {
      41          39 :   LOG_INFO("> flx_init_card(toflx)");
      42          39 :   flx->device = cfg->device;
      43          39 :   flx->flxcard = NULL;  // card is ignored, it is used in tohost and toflx
      44          39 :   flx->co = cfg->co;
      45          39 :   flx->vid = cfg->vid;
      46          39 :   flx->did = cfg->did;
      47          39 :   flx->cid = cfg->cid;
      48             : 
      49          39 :   flx->mode = FLX_MODE_GBT;
      50          39 :   flx->no_of_channels = 12;
      51          39 :   flx->regmap_version = cfg->regmap;
      52          39 :   u_long major = (flx->regmap_version & 0xFF00) >> 8;
      53          39 :   u_long minor = (flx->regmap_version & 0x00FF) >> 0;
      54          39 :   LOG_INFO("  regmap version %lu.%lu", major, minor);
      55             : 
      56             :   // elinks
      57          39 :   flx->num_elinks = cfg->num_elinks;
      58          39 :   flx->elinks = cfg->elinks;
      59             : 
      60          39 :   flx->fd = is_fifo(cfg->file) ? open_fifo(cfg->file) : open_file(cfg->file);
      61             : 
      62          39 :   flx->raw = cfg->raw;
      63          66 :   LOG_INFO("Output in %s file %s", cfg->raw ? "raw" : "json", cfg->file);
      64             : 
      65          39 :   return 0;
      66             : }
      67             : 
      68             : void
      69          39 : flx_close_card(struct flx* flx)
      70             : {
      71          39 :   LOG_INFO("> flx_close_card()");
      72          39 :   close(flx->fd);
      73          39 : }
      74             : 
      75          37 : int flx_get_toflx_dmaid(struct config* cfg){
      76          37 :   return cfg->dmaid;
      77             : }
      78             : 
      79             : 
      80             : void
      81           0 : flx_start_circular_dma(struct flx* flx, struct cmem_buffer* buf, unsigned dmaid)
      82             : {
      83           0 :   LOG_INFO("> flx_start_circular_dma(dmaid=%d): NOT TO BE USED in toflx", dmaid);
      84           0 :   exit(1);
      85             :   // flx->dmaid = dmaid;
      86             : 
      87             :   // // flx->flxcard->dma_stop(dmaid);
      88             :   // // flx->flxcard->dma_to_host(dmaid, buf->paddr, buf->size, FLX_DMA_WRAPAROUND);
      89             : 
      90             :   // buf->pstart = buf->paddr;
      91             :   // buf->pend = buf->pstart + buf->size;
      92             :   // buf->pc_ptr = buf->pstart; // flx->flxcard->dma_get_read_ptr(dmaid);
      93             : 
      94             :   // flx->fw_ptr = buf->pstart;
      95             : 
      96             :   // LOG_INFO("  cmem buffer [0x%x,0x%x] %lu Blocks", buf->pstart, buf->pend, buf->size/1024);
      97             :   // LOG_INFO("  cmem virtual address 0x%x", buf->vaddr);
      98             :   // LOG_INFO("  fw_ptr 0x%x", flx->fw_ptr);
      99             :   // LOG_INFO("  pc_ptr 0x%x", buf->pc_ptr);
     100             : }
     101             : 
     102             : void
     103           0 : flx_wait_data_available(struct flx* flx, struct cmem_buffer* buf)
     104             : {
     105           0 :   LOG_ERR("< flx_wait_data_available() NOT IMPLEMENTED\n");
     106             :   // flx->flxcard->irq_wait(IRQ_DATA_AVAILABLE);
     107           0 :   exit(1);
     108             : }
     109             : 
     110             : void
     111           0 : flx_cancel_irqs(struct flx* flx)
     112             : {
     113           0 :   LOG_INFO("< flx_cancel_irqs(), ignored\n");
     114           0 : }
     115             : 
     116             : size_t
     117           0 : flx_bytes_available(struct flx* flx, struct cmem_buffer* buf)
     118             : {
     119           0 :   LOG_ERR("< flx_bytes_available() NOT IMPLEMENTED\n");
     120           0 :   return 0;
     121             : }
     122             : 
     123             : int
     124           0 : flx_dma_cmp_even_bits(struct flx* flx)
     125             : {
     126           0 :   LOG_ERR("< flx_check_dma_cmp_even_bits() NOT IMPLEMENTED\n");
     127           0 :   return 0;
     128             : }
     129             : 
     130             : void
     131           0 : flx_read_and_update_fw_ptr(struct flx* flx, struct cmem_buffer* buf)
     132             : {
     133           0 :   LOG_ERR("< flx_read_and_update_fw_ptr() NOT IMPLEMENTED\n");
     134           0 : }
     135             : 
     136             : size_t
     137           0 : flx_bytes_available_to_read(struct flx* flx, struct cmem_buffer* buf)
     138             : {
     139           0 :   LOG_ERR("< flx_bytes_available_to_read() NOT IMPLEMENTED\n");
     140           0 :   return 0;
     141             : }
     142             : 
     143             : void*
     144           0 : flx_get_write_ptr(struct flx* flx, struct cmem_buffer* buf)
     145             : {
     146           0 :   LOG_ERR("< flx_get_write_ptr() NOT IMPLEMENTED\n");
     147           0 :   return nullptr;
     148             : }
     149             : 
     150             : void*
     151           0 : flx_get_read_ptr(struct flx* flx, struct cmem_buffer* buf)
     152             : {
     153           0 :   LOG_ERR("< flx_get_read_ptr() NOT IMPLEMENTED\n");
     154           0 :   return nullptr;
     155             : }
     156             : 
     157             : void
     158           0 : flx_set_read_ptr(struct flx* flx, struct cmem_buffer* buf, void* ptr)
     159             : {
     160           0 :   LOG_ERR("< flx_set_read_ptr() NOT IMPLEMENTED\n");
     161           0 : }
     162             : 
     163             : void
     164           0 : flx_advance_read_ptr(struct flx* flx, struct cmem_buffer* buf, size_t bytes)
     165             : {
     166           0 :   LOG_ERR("< flx_advance_read_ptr() NOT IMPLEMENTED\n");
     167           0 : }
     168             : 
     169         673 : int flx_get_regmap_version(struct flx* flx) {
     170             :   // 4.10 formatted as 0x040A
     171         673 :   return flx->regmap_version;
     172             : }
     173             : 
     174             : int
     175           0 : flx_get_mode(struct flx* flx)
     176             : {
     177           0 :   LOG_INFO("< flx_get_mode() %d", flx->mode);
     178           0 :   return flx->mode;
     179             : }
     180             : 
     181           0 : int flx_get_number_of_channels(struct flx* flx)
     182             : {
     183           0 :   LOG_INFO("< flx_get_number_of_channels() %d", flx->no_of_channels);
     184           0 :   return flx->no_of_channels;
     185             : }
     186             : 
     187           0 : int flx_get_wide_mode(struct flx* flx)
     188             : {
     189           0 :   LOG_INFO("< flx_get_wide_mode() %d", 0);
     190           0 :   return 0;
     191             : }
     192             : 
     193           0 : uint64_t flx_get_blocksize(struct flx* flx)
     194             : {
     195           0 :   LOG_ERR("> flx_get_blocksize NOT IMPLEMENTED");
     196           0 :   return 0;
     197             : }
     198             : 
     199           0 : int flx_get_trailer_size(struct flx* flx)
     200             : {
     201           0 :   LOG_ERR("> flx_get_trailer_size NOT IMPLEMENTED");
     202           0 :   return 0;
     203             : }
     204             : 
     205           0 : int flx_is_enabled(struct flx* flx, u_int channel, u_int egroup, u_int epath, u_int is_to_flx)
     206             : {
     207           0 :   LOG_INFO("< flx_is_enabled() %d", 1);
     208           0 :   return 1;
     209             : }
     210             : 
     211           0 : int flx_has_stream_id(struct flx* flx, u_int channel, u_int egroup, u_int epath)
     212             : {
     213           0 :   LOG_INFO("< flx_has_stream_id() %d", 1);
     214           0 :   return 1;
     215             : }
     216             : 
     217         162 : void flx_dma_from_host_rm4(struct flx* flx, struct cmem_buffer* dma_buffer, u_long buffer, size_t size)
     218             : {
     219         162 :   LOG_INFO("> flx_dma_from_host_rm4(0x%lx, %d)", buffer, size);
     220         162 :   LOG_INFO("> cmem paddr 0x%lx vaddr 0x%lx",  dma_buffer->paddr, dma_buffer->vaddr);
     221             : 
     222         162 :   if (size > 8192) {
     223           1 :     LOG_ERR("Size %d larger than buffer 8192, output discarded");
     224         152 :     return;
     225             :   }
     226             : 
     227         161 :   uint8_t data[8192];
     228         161 :   uint16_t data_size = 0;
     229         161 :   uint64_t offset = buffer - dma_buffer->paddr;
     230         161 :   uint8_t *ptr = (uint8_t*)(dma_buffer->vaddr + offset);
     231             : 
     232         161 :   if (flx->raw) {
     233         150 :     int result = write(flx->fd, ptr, size);
     234         150 :     if (result < 0) {
     235           0 :     LOG_ERR("errno=%d str=%s", errno, strerror(errno));
     236           0 :     exit(1);
     237             :     }
     238         150 :     fsync(flx->fd);
     239             :   }
     240             : 
     241             :   // decode
     242             :   uint8_t last = 0;
     243             :   uint16_t elink = 0;
     244         326 :   while(!last) {
     245         165 :     uint16_t hdr = (*(ptr + 31) << 8) | (*(ptr + 30));
     246         165 :     uint16_t part_size = hdr & 0x001E;
     247         165 :     elink = ((hdr & 0xFFE0) >> 5);
     248         165 :     last = hdr & 0x0001;
     249             :     // printf("Hdr 0x%x\n", hdr);
     250             :     // printf("elink 0x%x\n", elink);
     251             :     // printf("size %d\n", part_size);
     252             :     // printf("last %d\n", last);
     253             : 
     254             :     // copy bytes in inverted mode
     255         965 :     for (uint16_t i = 0; i < part_size; i++) {
     256         800 :     data[data_size] = *(ptr + 29 - i);
     257         800 :     data_size++;
     258             :     }
     259             : 
     260         165 :     ptr += 32;
     261             :   }
     262             : 
     263         161 :   if (flx->raw) {
     264             :     return;
     265             :   }
     266             : 
     267             :   // add zero so that it writes as string
     268          11 :   data[data_size++] = 0;
     269             : 
     270             :   // write (partial) results as json
     271          11 :   char json[PIPE_BUF];
     272          11 :   int count = snprintf(json, PIPE_BUF, "{\"elink\": \"0x%x\", \"data\": \"%s\"}", elink, data);
     273          11 :   int result = write(flx->fd, json, count);
     274             :   // int result = write(flx->fd, data, data_size);
     275          11 :   if (result < 0) {
     276           0 :     LOG_ERR("errno=%d str=%s", errno, strerror(errno));
     277           0 :     exit(1);
     278             :   }
     279          11 :   fsync(flx->fd);
     280             : }
     281             : 
     282         317 : void flx_dma_from_host(struct flx* flx, struct cmem_buffer* dma_buffer, u_long buffer, size_t size, u_int wraparound)
     283             : {
     284         317 :   LOG_INFO("> flx_dma_from_host(0x%lx, %d, %d)", buffer, size, wraparound);
     285         317 :   LOG_INFO("> regmap 0x%lx", flx_get_regmap_version(flx));
     286         317 :   if (flx_get_regmap_version(flx) < 0x0500) {
     287         162 :     flx_dma_from_host_rm4(flx, dma_buffer, buffer, size);
     288         468 :     return;
     289             :   }
     290             : 
     291         155 :   if (size > 8192) {
     292           1 :     LOG_ERR("Size %d larger than buffer 8192, output discarded");
     293           1 :     return;
     294             :   }
     295             : 
     296             :   // regmap 0x0500 and beyond, see FLX-1355
     297         154 :   uint8_t data[8192];
     298         154 :   uint16_t data_size = 0;
     299         154 :   LOG_INFO("> cmem paddr 0x%lx vaddr 0x%lx",  dma_buffer->paddr, dma_buffer->vaddr);
     300         154 :   uint64_t offset = buffer - dma_buffer->paddr;
     301         154 :   uint8_t *ptr = (uint8_t*)(dma_buffer->vaddr + offset);
     302             : 
     303         154 :   if (flx->raw) {
     304         143 :     int result = write(flx->fd, ptr, size);
     305         143 :     if (result < 0) {
     306           0 :     LOG_ERR("errno=%d str=%s", errno, strerror(errno));
     307           0 :     exit(1);
     308             :     }
     309         143 :     fsync(flx->fd);
     310             :   }
     311             : 
     312             :   // decode
     313             :   uint8_t last = 0;
     314             :   uint16_t elink = 0;
     315         312 :   while(!last) {
     316         158 :     uint16_t hdr = (*(ptr + 31) << 8) | (*(ptr + 30));
     317         158 :     uint16_t part_size = hdr & 0x001F;
     318         158 :     elink = ((hdr & 0xFFE0) >> 5);
     319         158 :     last = part_size != 0x001F;
     320         158 :     part_size = part_size == 0x001F ? 0x001E : part_size;
     321             :     // printf("Hdr 0x%x\n", hdr);
     322             :     // printf("elink 0x%x\n", elink);
     323             :     // printf("size %d\n", part_size);
     324             :     // printf("last %d\n", last);
     325             : 
     326             :     // copy bytes in inverted mode
     327         928 :     for (uint16_t i = 0; i < part_size; i++) {
     328         770 :     data[data_size] = *(ptr + 29 - i);
     329         770 :     data_size++;
     330             :     }
     331             : 
     332         158 :     ptr += 32;
     333             :   }
     334             : 
     335         154 :   if (flx->raw) {
     336             :     return;
     337             :   }
     338             : 
     339             :   // add zero so that it writes as string
     340          11 :   data[data_size++] = 0;
     341             : 
     342             :   // write (partial) results as json
     343          11 :   char json[PIPE_BUF];
     344          11 :   int count = snprintf(json, PIPE_BUF, "{\"elink\": \"0x%x\", \"data\": \"%s\"}", elink, data);
     345          11 :   int result = write(flx->fd, json, count);
     346             :   // int result = write(flx->fd, data, data_size);
     347          11 :   if (result < 0) {
     348           0 :     LOG_ERR("errno=%d str=%s", errno, strerror(errno));
     349           0 :     exit(1);
     350             :   }
     351          11 :   fsync(flx->fd);
     352             : }
     353             : 
     354           0 : void flx_dma_wait(struct flx* flx, struct cmem_buffer* dma_buffer)
     355             : {
     356             :   // LOG_ERR("> flx_dma_wait, ignored");
     357             :   // flx->flxcard->dma_wait(flx->dmaid);
     358           0 : }
     359             : 
     360         313 : bool flx_dma_enabled(struct flx* flx, struct cmem_buffer* dma_buffer)
     361             : {
     362             :   // DMA is done instantly...
     363         313 :   return false;
     364             : }
     365             : 
     366          39 : int flx_dma_max_tlp_bytes(struct flx* flx)
     367             : {
     368          39 :   LOG_INFO("< flx_dma_max_tlp_bytes() %d", 256);
     369          39 :   return 256; // flx->flxcard->dma_max_tlp_bytes();
     370             : }
     371             : 
     372           0 : void flx_cfg_set_option(struct flx* flx, const char *key, u_long value)
     373             : {
     374           0 :   LOG_ERR("> flx_cfg_set_option NOT IMPLEMENTED %s 0x%x", key, value);
     375             :   // flx->flxcard->cfg_set_option(key, value);
     376           0 :   exit(1);
     377             : }
     378             : 
     379           0 : u_long flx_cfg_get_option(struct flx* flx, const char *key)
     380             : {
     381             : 
     382             :   // return flx->flxcard->cfg_get_option(key);
     383           0 :   exit(1);
     384             : }
     385             : 
     386           0 : bool flx_cfg_check_option(struct flx* flx, const char *key)
     387             : {
     388           0 :   LOG_ERR("< flx_cfg_get_option NOT IMPLEMENTED %s", key);
     389           0 :   return false;
     390             : }
     391             : 
     392             : 
     393          39 : unsigned flx_read_elink_config(struct flx* flx, struct elink_descr** elinks, u_int is_to_flx) {
     394          39 :   *elinks = (struct elink_descr*)malloc(flx->num_elinks * sizeof(elink_descr));
     395             : 
     396         105 :   for (unsigned i=0; i<flx->num_elinks; i++) {
     397          66 :   struct elink_descr* e = *elinks + i;
     398          66 :   e->elink = flx->elinks[i];
     399          66 :   e->type = elink_type::DAQ;
     400          66 :   e->has_streams = false;
     401          66 :   uint8_t stream = 0;
     402          66 :   uint8_t virt = 0;
     403         132 :   LOG_INFO("E-Link %d: %d 0x%x fid: 0x%lx, has streams: %c", flx->num_elinks, e->elink, e->elink, get_fid(flx->co, e->elink, stream, flx->vid, is_to_flx, virt), e->has_streams ? 'y' : 'n');
     404             :   }
     405             :   /* TODO */
     406          39 :   return flx->num_elinks;
     407             : }
     408             : 
     409             : uint64_t
     410           2 : flx_dma_get_read_ptr(struct flx* flx, struct cmem_buffer* dma_buffer)
     411             : {
     412           2 :   u_long dma_ptr = dma_buffer->pc_ptr;
     413           2 :   LOG_DBG("< flx_dma_get_read_ptr() 0x%x", dma_ptr);
     414           2 :   return dma_ptr;
     415             : }
     416             : 
     417             : uint64_t
     418           2 : flx_dma_get_current_address(struct flx* flx, struct cmem_buffer* dma_buffer)
     419             : {
     420           2 :   LOG_ERR("< flx_dma_get_current_address() NOT IMPLEMENTED\n");
     421           2 :   return 0;
     422             :   //return flx->flxcard->dma_get_current_address(flx->dmaid);
     423             : }
     424             : 
     425             : void
     426           2 : flx_dma_set_ptr(struct flx* flx, struct cmem_buffer* dma_buffer, uint64_t pnew)
     427             : {
     428             :   // FIXME only correct for one transfer
     429           2 :   flx_dma_from_host(flx, dma_buffer, dma_buffer->paddr, pnew, 0);
     430           2 : }
     431             : 
     432           0 : void flx_irq_data_enable(struct flx* flx){
     433           0 :   LOG_DBG("Enabling IRQ_DATA_AVAILABLE interrupt");
     434           0 : }
     435             : 
     436           0 : void flx_irq_data_disable(struct flx* flx){
     437           0 :   LOG_DBG("Disabling IRQ_DATA_AVAILABLE interrupt");
     438           0 : }
     439             : 
     440           0 : void flx_irq_busy_enable(struct flx* flx){
     441           0 :   LOG_DBG("Enabling IRQ_BUSY_CHANGE_TO_HOST interrupt");
     442           0 : }
     443             : 
     444           0 : void flx_irq_busy_disable(struct flx* flx){
     445           0 :   LOG_DBG("Disabling IRQ_BUSY_CHANGE_TO_HOST interrupt");
     446           0 : }

Generated by: LCOV version 1.0