Beispiel #1
0
/**
 * \brief Unmap the VD80 operational address space
 *
 * \return 0 on success else 1 on failure
 */
int vd80_exit(void)
{
	int rc = 0;

	if ((rc = vme_unmap(&regs_desc, 1)))
		printf("Failed to return_controler: %s\n", strerror(errno));

	printf("Unmapped VD80 registers\n");
	return rc;
}
Beispiel #2
0
void
vme_a32_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size)
{
	struct vme_softc *sc = (void *)vme_cd.cd_devs[0];
	vaddr_t va = (vaddr_t)handle;
	paddr_t pa;

	if (pmap_extract(pmap_kernel(), va, &pa) == FALSE)
		return;

	return vme_unmap(sc, sc->sc_ext_a32, VME_A32, va, pa, size);
}
Beispiel #3
0
/**
 * \brief Map and initialize the VD80 for operation
 *
 * \return 0 on success else 1 on failure.
 *
 * This functions performs the necessary initializations to prepare the
 * board for sampling:
 *
 * \li map the operational registers into the user address space
 * \li clear any interrupts
 * \li disable interrupts
 * \li configure the sampling clock source to use the internal clock divided
 *     by 2 which yields a 100kHz sampling clock
 * \li configure the trigger source to use the internal trigger
 * \li set the number of post samples to 0
 * \li setup the pretrigger control to clear the pretrigger counter on a
 *     \a START command, to clear the \a PRESAMPLES counter on reading the
 *      pretrigger status register and to unse the sample clock for the
 *      pretrigger counter
 * \li enable generation of the test waveform
 *
 * \note Those settings are \b testing settings and must be adapted for
 *       operational use.
 *
 */
int vd80_init(void)
{
	int rc = 1;

	/* Open a mapping for the VD80 operational registers */
	memset(&regs_desc, 0, sizeof(struct vme_mapping));

	regs_desc.window_num = 0;
	regs_desc.am = VD80_OPER_AM;
	regs_desc.read_prefetch_enabled = 0;
	regs_desc.data_width = VD80_OPER_DW;
	regs_desc.sizeu = 0;
	regs_desc.sizel = VD80_OPER_SIZE;
	regs_desc.vme_addru = 0;
	regs_desc.vme_addrl = VD80_OPER_BASE;

	if ((regs = vme_map(&regs_desc, 1)) == NULL) {
		printf("Failed to map VD80 operational registers: %s\n",
		       strerror(errno));
		printf("  addr: %x size: %x am: %x dw: %d\n", VD80_OPER_BASE,
		       VD80_OPER_SIZE, VD80_OPER_AM, VD80_OPER_DW);
		return 1;
	}

	/* Clear interrupts */
	regs[VD80_GCR1/4] |= swapbe32(VD80_INTCLR | VD80_IOERRCLR);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing GCR1\n");
		goto out;
	}

	/*
	 * Disable interrupts, set little endian mode and disable debug
	 * counter (Clear all bits).
	 */
	regs[VD80_GCR2/4] = 0;

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing GCR2\n");
		goto out;
	}

	/*
	 * Set sampling clock:
	 *    - Internal clock
	 *    - No VXI clock output
	 *    - Divide mode
	 *    - Rising edge
	 *    - No 50 ohm termination
	 *    - Clkdiv = 2 (I want a 100kHz clock from the 200 kHz internal
	 *                  clock - which yields a 10 us sampling period)
	 */
	regs[VD80_CCR/4] = swapbe32(1 << VD80_CLKDIV_SHIFT);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing CCR\n");
		goto out;
	}

	/*
	 * Set trigger:
	 *    - Internal trigger
	 *    - No VXI trigger output
	 *    - No trigger output
	 *    - Rising edge
	 *    - No 50 ohm termination
	 *    - No trigger synchronization
	 */
	regs[VD80_TCR1/4] = 0;

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing TCR1\n");
		goto out;
	}

	/* Set number of post samples to 0 */
	
	if (vd80_set_postsamples(0))
		goto out;

	/*
	 * Setup the Pretrigger Control Register:
	 *    - Clear pretrigger counter on START
	 *    - Clear PRESAMPLES on Pretrigger Status Register read
	 *    - Clock the pretrigger counter on the sample clock
	 */
	regs[VD80_PTCR/4] |= swapbe32(VD80_PSCNTCLRONSTART |
				      VD80_PSREGCLRONREAD |
				      VD80_PSCNTCLKONSMPL);
	

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing PTCR\n");
		goto out;
	}

	/* Enable generation of debug waveform */
	if ((rc = vd80_cmd_setdebug(1)))
		goto out;

	return 0;

out:
	if (vme_unmap(&regs_desc, 1))
		printf("Failed to unmap operational registers: %s\n",
		       strerror(errno));

	return rc;
}
Beispiel #4
0
/**
 * \brief Probe and configure the VD80
 *
 * \return 0 on success else 1 on failure.
 *
 * This function probes and configures the VD80 using the CR/CSR address space.
 *
 * It performs the following operations:
 *
 * \li map the VME CR/CSR address space of the board
 * \li check we're talking to a VD80 board by checking the module ID
 * \li configure the function 0 Address Decode Compare register (\a ADER0) to
 *     map the operational registers on an A24/D32 address space at base
 *     address 0x600000. Used for operational registers access.
 * \li configure the function 1 Address Decode Compare register (\a ADER1) to
 *     map the operational registers on an A24-BLT/D32 address space at base
 *     address 0x600000. Used for DMA reading of the samples memory using
 *     VME block transfer.
 *
 * \note The VME CR/CSR address space is unmapped on function return.
 */
int vd80_map(void)
{
	int rc = 1;
	struct vme_mapping crcsr_desc;
	unsigned int *crcsr;
	int i;
	unsigned int val;
	char cr_sig[2];
	char board_id[5];
	char rev_id[5];
	unsigned int desc_offset;
	char board_desc[512];

	/*
	 * Open a mapping into the VD80 CR/CSR (0x2f) address space for
	 * configuring the board.
	 */
	memset(&crcsr_desc, 0, sizeof(struct vme_mapping));

	crcsr_desc.window_num = 0;
	crcsr_desc.am = VD80_SETUP_AM;
	crcsr_desc.read_prefetch_enabled = 0;
	crcsr_desc.data_width = VD80_SETUP_DW;
	crcsr_desc.sizeu = 0;
	crcsr_desc.sizel = VD80_SETUP_SIZE;
	crcsr_desc.vme_addru = 0;
	crcsr_desc.vme_addrl = VD80_SETUP_BASE;

	if ((crcsr = vme_map(&crcsr_desc, 1)) == NULL) {
		printf("Failed to map CR/CSR: %s\n", strerror(errno));
		return 1;
	}

	/* First check we're accessing a configuration ROM */
	cr_sig[0] = swapbe32(crcsr[VD80_CR_SIG1/4]) & 0xff;

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading CR signature byte 0 at %08x\n",
		       VD80_SETUP_BASE + VD80_CR_SIG1);
		goto out;
	}

	cr_sig[1] = swapbe32(crcsr[VD80_CR_SIG2/4]) & 0xff;

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading CR signature byte 1 at %08x\n",
		       VD80_SETUP_BASE + VD80_CR_SIG2);
		goto out;
	}

	if ((cr_sig[0] != 'C') && (cr_sig[1] != 'R')) {
		printf("Not a Configuration ROM at 0x%x (%08x %08x)\n",
		       VD80_SETUP_BASE, swapbe32(crcsr[VD80_CR_SIG1/4]),
		       swapbe32(crcsr[VD80_CR_SIG2/4]));
		goto out;
	}

	/* Try to read module ID - offset 0x30 */
	for (i = 0; i < VD80_CR_BOARD_ID_LEN; i++) {
		val = swapbe32(crcsr[VD80_CR_BOARD_ID/4 + i]);
		board_id[i] = (char)(val & 0xff);
	}
	board_id[4] = '\0';

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading board ID\n");
		goto out;
	}

	for (i = 0; i < VD80_CR_REV_ID_LEN; i++) {
		val = swapbe32(crcsr[VD80_CR_REV_ID/4 + i]);
		rev_id[i] = (char)(val & 0xff);
	}
	rev_id[4] = '\0';

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading revision ID\n");
		goto out;
	}

	if (strncmp(board_id, "VD80", 4)) {
		printf("No VD80 board found at base address 0x%x\n",
		       VD80_SETUP_BASE);
		goto out;
	}

	printf("Found board ID %s - revision ID: %s\n", board_id, rev_id);

	/* Read board string */
	desc_offset = 0;

	for (i = 0; i < VD80_CR_DESC_PTR_LEN; i++) {
		desc_offset <<= 8;
		desc_offset |= swapbe32(crcsr[VD80_CR_DESC_PTR/4 + i]) & 0xff;
	}

	desc_offset &= ~3;

	if (desc_offset != 0) {
		for (i = 0; i < VD80_UCR_BOARD_DESC_LEN; i++) {
			val = swapbe32(crcsr[0x1040/4 + i]);
			board_desc[i] = (char)(val & 0xff);

			if (board_desc[i] == '\0')
				break;
		}
		board_desc[320] = '\0';
	}

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading board description\n");
		goto out;
	}

	printf("Board name: %s\n", board_desc);
	printf("\n");

	/* Configure ADER0 for A24 USER DATA access (AM=0x39 BA=0x600000) */
	crcsr[VD80_CSR_ADER0/4] = swapbe32((VD80_OPER_BASE >> 24) & 0xff);
	crcsr[VD80_CSR_ADER0/4 + 1] = swapbe32((VD80_OPER_BASE >> 16) & 0xff);
	crcsr[VD80_CSR_ADER0/4 + 2] = swapbe32((VD80_OPER_BASE >> 8) & 0xff);
	crcsr[VD80_CSR_ADER0/4 + 3] = swapbe32(VD80_OPER_AM * 4);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error setting ADER0\n");
		goto out;
	}

	/* Configure ADER1 for A24 USER block transfer (AM=0x3b BA=0x600000) */
	crcsr[VD80_CSR_ADER1/4] = swapbe32((VD80_OPER_BASE >> 24) & 0xff);
	crcsr[VD80_CSR_ADER1/4 + 1] = swapbe32((VD80_OPER_BASE >> 16) & 0xff);
	crcsr[VD80_CSR_ADER1/4 + 2] = swapbe32((VD80_OPER_BASE >> 8) & 0xff);
	crcsr[VD80_CSR_ADER1/4 + 3] = swapbe32(VD80_DMA_AM * 4);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error setting ADER1\n");
		goto out;
	}

	/*
	 * Clear address counter enable for function 1 to use it for block
	 * transfer of the sample memory.
	 */
	val = swapbe32(crcsr[VD80_CSR_FUNC_ACEN/4]) | 0x02;
	crcsr[VD80_CSR_FUNC_ACEN/4] = swapbe32(0);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error setting ACEN\n");
		goto out;
	}

	/* Enable the module */
	crcsr[VD80_CSR_BITSET/4] = swapbe32(VD80_CSR_ENABLE_MODULE);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error enabling module\n");
		goto out;
	}

	rc = 0;

out:
	if (vme_unmap(&crcsr_desc, 1))
		printf("Failed to unmap CR/CSR space: %s\n",
		       strerror(errno));

	return rc;
}
Beispiel #5
0
int main(int argc, char *argv[])
{

	struct vme_mapping map;
	struct vme_mapping *mapp = &map;
	volatile void *ptr;
	unsigned int vmebase, am, data_width, access_width;
	unsigned int offset;
	unsigned int length;
	int i, count;
	int c;
	int write, offsets_on;
	int width;
	uint32_t word, datum;

	/* vme defaults */
	count = 1;
	am = VME_A32_USER_DATA_SCT;
	data_width = access_width = VME_D32;

	write = 0;
	offsets_on = 1;
	offset = 0;
	length = 0x80000;
	while ((c = getopt(argc, argv, "Hv:s:D:d:a:n:w:l:hV")) != -1) {
		switch (c) {
		case 'H':
			offsets_on = 0;
			break;
		case 's':
			offset = strtoul(optarg, NULL, 0);
			break;
		case 'v':
			vmebase = strtoul(optarg, NULL, 0);
			break;
		case 'd':
		case 'D':
			width = strtoul(optarg, NULL, 0);
			if (is_invalid_width(width)) {
				fprintf(stderr, "invalid data width %d\n", width);
				exit(1);
			}
			if (c == 'd')
				data_width = width;
			else
				access_width = width;
			break;
		case 'a':
			am = strtoul(optarg, NULL, 0);
			break;
		case 'n':
			count = strtoul(optarg, NULL, 0);
			break;
		case 'l':
			length = strtoul(optarg, NULL, 0);
			break;
		case 'w':
			write = 1;
			word = strtoul(optarg, NULL, 0);
			break;
		case '?':
		case 'h':
			usage(argv[0]);
			break;
		case 'V':
			print_version();
			exit(1);
		default:
			break;
		}
	}

	/* Prepare mmap description */
	memset(mapp, 0, sizeof(*mapp));
	mapp->am = 		am;
	mapp->data_width = 	(data_width == 8) ? 16 : data_width;
	mapp->sizel = 		length;
	mapp->vme_addrl =	vmebase;

	/* Do mmap */
	ptr = vme_map(mapp, 1);
	if (!ptr) {
		printf("could not map at 0x%08x\n", vmebase);
		exit(1);
	}

	fprintf(stderr, "vme 0x%08x kernel %p user %p\n",
			vmebase, mapp->kernel_va, mapp->user_va);
	for (i = 0; i < count; i++, offset += 4) {
		volatile void *addr = ptr + offset;
		if (!write) {
			datum = vme_mem_read(access_width, addr);
			if (offsets_on)
				printf("%08x: ", vmebase + offset);
			printf("%08x\n", datum);
		} else {
			vme_mem_write(access_width, addr, word);
		}
	}

	vme_unmap(mapp, 1);
	return 0;
}