[subexp-daq] Report of a possible bug of the CAEN_V560 module

Weber, Guenter Dr. g.weber at hi-jena.gsi.de
Tue Feb 20 15:33:49 CET 2024


Dear friends,


I now had a look at the system where the V560 was running. It was also setup by Bastian. And there the code for the V560 module is slightly different from the one included in the NURDLIB branch that I am using on the test system.


Maybe you can have a look at it.


I also could push the complete NURDLIB from this system, if this helps.




Best greetings

Günter



________________________________
Von: subexp-daq <subexp-daq-bounces at lists.chalmers.se> im Auftrag von Weber, Guenter Dr. <g.weber at hi-jena.gsi.de>
Gesendet: Dienstag, 20. Februar 2024 10:58:27
An: Discuss use of Nurdlib, TRLO II, drasi and UCESB.
Betreff: [subexp-daq] Report of a possible bug of the CAEN_V560 module


Dear friends,


I now grabbed a V560 module that was working fine in another DAQ system and put it into our test system.


The main.cfg looks like this:


log_level=spam # info, verbose, debug, spam

CRATE("MCAL") {
    GSI_VULOM(0x03000000) {
        timestamp = true # needed to get timestamps in the data output
    #   ecl=0..15
    }
    BARRIER
    CAEN_V560(0x333333300) {
        use_veto = true
    }
#   CAEN_V767A(0x03100000) {
#   }
}


Starting the DAQ now results in a freeze of the RIO4. A reset of the crate is necessary to talk to it again.


The problem occurs in the first slow init of the V560 module. To find the exact line, I added some output to CRATE.C:


10: crate/crate.c:923: .Slow-init module[0]=GSI_VULOM.
before push_log_level(module)
before a_crate->module_init_id = module->id
before module->props->init_slow(a_crate, module)
LOG: TRLO: MD5SUM: 0x1409285e (CT: 63bb1d44 = 2023-01-08 19:45:08 UTC)
before module_init_id_mark(a_crate, module)
before pop_log_level(module)
10: crate/crate.c:923: .Slow-init module[1]=CAEN_V560.
before push_log_level(module)
before a_crate->module_init_id = module->id
before module->props->init_slow(a_crate, module)


The CRATE.C code now looks like this:


    TAILQ_FOREACH(module, &a_crate->module_list, next) {
        if (NULL == module->props) {
            continue;
        }
        LOGF(info)(LOGL, "Slow-init module[%u]=%s.", module->id,
            keyword_get_string(module->type));
        printf("before push_log_level(module) \n");
        push_log_level(module);
        printf("before a_crate->module_init_id = module->id \n");
        a_crate->module_init_id = module->id;
        printf("before module->props->init_slow(a_crate, module) \n");
        if (!module->props->init_slow(a_crate, module)) {
            printf("before pop_log_level(module) \n");
            pop_log_level(module);
            printf("before goto crate_init_done \n");
            goto crate_init_done;
        }
        printf("before module_init_id_mark(a_crate, module) \n");
        module_init_id_mark(a_crate, module);
        printf("before pop_log_level(module) \n");
        pop_log_level(module);
    }


Thus, to me it looks like the check "if (!module->props->init_slow(a_crate, module)) ..." is doing something quite horrible to the RIO4.


This is unfortunate, because my original aim was to show that there is also a bug/mistake in readout_dt of the V560 module. But I did not come this far.


Do you have any idea what might cause the freezing of the RIO4?




Best greetings and many thanks

Günter



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.chalmers.se/pipermail/subexp-daq/attachments/20240220/8708cd77/attachment-0001.html>
-------------- next part --------------
#ifndef MODULE_CAEN_V560_INTERNAL_H
#define MODULE_CAEN_V560_INTERNAL_H

#include <module/caen_v560/structs.h>

struct CaenV560Module {
	struct	Module module;
	uint32_t	address;
	struct	Map *sicy_map;
	struct	CaenV560Read volatile const *read;
	struct	CaenV560Write volatile *write;
	unsigned	use_veto;
};

#endif
-------------- next part --------------
#include <module/caen_v560/caen_v560.h>
#include <module/caen_v560/internal.h>
#include <module/map/map.h>
#include <nurdlib/config.h>
#include <nurdlib/log.h>
#include <util/math.h>
#include <util/string.h>

#define NAME "Caen v560"

MODULE_PROTOTYPES(caen_v560);

int
caen_v560_are_distinguishable(enum Keyword a_type)
{
	(void)a_type;
	LOGF(verbose)(LOGL, NAME" are_distinguishable.");
	return 1;
}

uint32_t
caen_v560_check_empty(struct Module *a_module)
{
	(void)a_module;
	return 0;
}

struct Module *
caen_v560_create_(struct Crate *a_crate, struct ConfigBlock const *a_block)
{
	struct CaenV560Module *v560;

	LOGF(verbose)(LOGL, NAME" create {");

	(void)a_crate;
	MODULE_CREATE(v560);
	v560->module.event_max = 32; /* no event buffer, arbitrary > 0 */
	v560->address = config_get_block_param_int32(a_block, 0);
	LOGF(verbose)(LOGL, "Address=%08x.", v560->address);

	LOGF(verbose)(LOGL, NAME" create }");

	return (void *)v560;
}

void
caen_v560_deinit(struct Module *a_module)
{
	struct CaenV560Module *v560;

	LOGF(verbose)(LOGL, NAME" deinit {");
	MODULE_CAST(KW_CAEN_V560, v560, a_module);
	map_unmap(&v560->sicy_map);
	LOGF(verbose)(LOGL, NAME" deinit }");
}

void
caen_v560_destroy(struct Module *a_module)
{
	(void)a_module;
	LOGF(verbose)(LOGL, NAME" destroy.");
}

uintptr_t
caen_v560_get_module_base(struct Module const *a_module)
{
	struct CaenV560Module *v560;
	uintptr_t base;

	LOGF(verbose)(LOGL, NAME" get_module_base {");
	MODULE_CAST(KW_CAEN_V560, v560, a_module);
	base = (uintptr_t)map_get_mapped_ptr(v560->sicy_map);
	LOGF(verbose)(LOGL, NAME" get_module_base(%p) }", (void *)base);
	return base;
}

int
caen_v560_init_fast(struct Crate *a_crate, struct Module *a_module)
{
	struct CaenV560Module *v560;

	(void)a_crate;
	LOGF(verbose)(LOGL, NAME" init_fast {");

	MODULE_CAST(KW_CAEN_V560, v560, a_module);

	v560->use_veto = config_get_boolean(a_module->config, KW_USE_VETO);
	LOGF(verbose)(LOGL, "use_veto = %s", v560->use_veto ? "yes" : "no");

	v560->write->scale_clear = 1;
	v560->write->vme_veto_reset = 1;

	LOGF(verbose)(LOGL, NAME" init_fast }");
	return 1;
}

int
caen_v560_init_slow(struct Crate *a_crate, struct Module *a_module)
{
	struct CaenV560Module *v560;
	void volatile *mapped_ptr;
	uint16_t id;

	(void)a_crate;
	LOGF(verbose)(LOGL, NAME" init_slow {");

	MODULE_CAST(KW_CAEN_V560, v560, a_module);

	v560->sicy_map = map_map(v560->address, MAP_SIZE_MAX(*v560), KW_NOBLT,
	    0, 0, MAP_POKE_ARGS(*v560->read, fixed_code),
	    MAP_POKE_ARGS(*v560->write, scale_clear));
	mapped_ptr = map_get_mapped_ptr(v560->sicy_map);
	v560->read = mapped_ptr;
	v560->write = mapped_ptr;

	id = v560->read->fixed_code;
	if (0xfaf5 != id) {
		log_die(LOGL, "Fixed code=0x%04x != 0xfaf5, module borked?",
		    id);
	}
	id = v560->read->manufacturer_module_type;
	LOGF(verbose)(LOGL, "Manufacturer=%02x, module type=%03x (0x%04x).",
	    (0xfc00 & id) >> 10, 0x3ff & id, id);
	id = v560->read->version_serial_number;
	LOGF(verbose)(LOGL, "Version=%x, S/N=%03x (0x%04x).",
	    (0xf000 & id) >> 12, 0xfff & id, id);

	LOGF(verbose)(LOGL, NAME" init_slow }");
	return 1;
}

void
caen_v560_memtest(struct Module *a_module, enum Keyword a_mode)
{
	(void)a_module;
	(void)a_mode;
}

uint32_t
caen_v560_parse_data(struct Crate const *a_crate, struct Module *a_module,
    struct EventConstBuffer const *a_event_buffer, int a_do_pedestals)
{
	(void)a_crate;
	(void)a_module;
	(void)a_event_buffer;
	(void)a_do_pedestals;
	return 0;
}

uint32_t
caen_v560_readout(struct Crate *a_crate, struct Module *a_module, struct
    EventBuffer *a_event_buffer)
{
	struct CaenV560Module *v560;
	uint32_t *outp;
	uint32_t result = 0;
	int ch;

	(void)a_crate;
	LOGF(spam)(LOGL, NAME" readout {");

	MODULE_CAST(KW_CAEN_V560, v560, a_module);
	outp = a_event_buffer->ptr;

	if (v560->use_veto) {
		v560->write->vme_veto_set = 1;
	}

	*outp++ = 0xc560c560;
	for (ch = 0; ch < 16; ch++) {
		*outp++ = v560->read->counter[ch];
	}

	if (v560->use_veto) {
		v560->write->vme_veto_reset = 1;
	}

	EVENT_BUFFER_ADVANCE(*a_event_buffer, outp);
	LOGF(spam)(LOGL, NAME" readout(0x%08x) }", result);
	return result;
}

uint32_t
caen_v560_readout_dt(struct Crate *a_crate, struct Module *a_module)
{
	(void)a_crate;
	LOGF(spam)(LOGL, NAME" readout_dt {");
	a_module->event_counter.value++;
	LOGF(spam)(LOGL, NAME" readout_dt(ctr=0x%08x) }",
	    a_module->event_counter.value);
	return 0;
}

void
caen_v560_setup_()
{
	MODULE_SETUP(caen_v560, 0);
}
-------------- next part --------------
#ifndef MODULE_CAEN_V560_CAEN_V560_H
#define MODULE_CAEN_V560_CAEN_V560_H

#include <module/module.h>

MODULE_INTERFACE(caen_v560);

#endif
-------------- next part --------------
nabm

Interrupt Vector   0x0004 16 RW
Interrupt Level    0x0006 16 RW
Enable Interrupt   0x0008 16 RW
Disable Interrupt 0x000A 16 RW
Clear Interrupt    0x000C 16 RW
Request            0x000E 16 RW

Counter            0x0010..0x004C 32 R

Scale clear        0x0050 16 RW
VME VETO set       0x0052 16 RW
VME VETO reset     0x0054 16 RW
Scale Increase     0x0056 16 RW
Scale Status       0x0058 16 R

Fixed code                0x00FA 16 R
Manufacturer Module Type  0x00FC 16 R
Version Serial Number     0x00FE 16 R
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rules.mk
Type: application/octet-stream
Size: 161 bytes
Desc: rules.mk
URL: <http://lists.chalmers.se/pipermail/subexp-daq/attachments/20240220/8708cd77/attachment-0001.obj>


More information about the subexp-daq mailing list