Exemple #1
0
int gpu_fft_get_host_info(struct GPU_FFT_HOST *info)
{
	void *handle;
	unsigned (*bcm_host_get_sdram_address)(void);
	unsigned (*bcm_host_get_peripheral_address)(void);
	unsigned (*bcm_host_get_peripheral_size)(void);

	// Pi 1 defaults
	info->peri_addr = 0x20000000;
	info->peri_size = 0x01000000;
	info->mem_flg = GPU_FFT_USE_VC4_L2_CACHE ? 0xC : 0x4;
	info->mem_map = GPU_FFT_USE_VC4_L2_CACHE ? 0x0 : 0x20000000; // Pi 1 only

	handle = dlopen("libbcm_host.so", RTLD_LAZY);
	if (!handle)
		return -1;

	*(void **)(&bcm_host_get_sdram_address) = dlsym(handle, "bcm_host_get_sdram_address");
	*(void **)(&bcm_host_get_peripheral_address) = dlsym(handle, "bcm_host_get_peripheral_address");
	*(void **)(&bcm_host_get_peripheral_size) = dlsym(handle, "bcm_host_get_peripheral_size");

	if (bcm_host_get_sdram_address && bcm_host_get_sdram_address() != 0x40000000)
	{ // Pi 2?
		info->mem_flg = 0x4; // ARM cannot see VC4 L2 on Pi 2
		info->mem_map = 0x0;
	}

	if (bcm_host_get_peripheral_address)
		info->peri_addr = bcm_host_get_peripheral_address();
	if (bcm_host_get_peripheral_size)
		info->peri_size = bcm_host_get_peripheral_size();

	dlclose(handle);
	return 0;
}
Exemple #2
0
void *blink(int *terminate)
{
	int i, j, k, switchscan, tmp;

	// Find gpio address (different for Pi 2) ----------
	gpio.addr_p = bcm_host_get_peripheral_address() + +0x200000;
	if (gpio.addr_p == 0x20200000)
		printf("RPi Plus detected\n");
	else
		printf("RPi 2 detected\n");

	// printf("Priority max SCHED_FIFO = %u\n",sched_get_priority_max(SCHED_FIFO) );

	// set thread to real time priority -----------------
	struct sched_param sp;
	sp.sched_priority = 98; // maybe 99, 32, 31?
	if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) {
		fprintf(stderr, "warning: failed to set RT priority\n");
	}

	// --------------------------------------------------
	if (map_peripheral(&gpio) == -1) {
		printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
		return (void *) -1;
	}

	// initialise GPIO (all pins used as inputs, with pull-ups enabled on cols)
	//	INSERT CODE HERE TO SET GPIO 14 AND 15 TO I/O INSTEAD OF ALT 0.
	//	AT THE MOMENT, USE "sudo ./gpio mode 14 in" and "sudo ./gpio mode 15 in". "sudo ./gpio readall" to verify.

	for (i = 0; i < 8; i++) { // Define ledrows as input
		INP_GPIO(ledrows[i]);
		GPIO_CLR = 1 << ledrows[i]; // so go to Low when switched to output
	}
	for (i = 0; i < 12; i++) // Define cols as input
			{
		INP_GPIO(cols[i]);
	}
	for (i = 0; i < 3; i++) // Define rows as input
			{
		INP_GPIO(rows[i]);
	}

	// BCM2835 ARM Peripherals PDF p 101 & elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs
	GPIO_PULL = 2; // pull-up
	short_wait(); // must wait 150 cycles
#ifdef SERIALSETUP
	GPIO_PULLCLK0 = 0x03ffc; // selects GPIO pins 2..13 (frees up serial port on 14 & 15)
#else
	GPIO_PULLCLK0 = 0x0fff0; // selects GPIO pins 4..15 (assumes we avoid pins 2 and 3!)
#endif
	short_wait();
	GPIO_PULL = 0; // reset GPPUD register
	short_wait();
	GPIO_PULLCLK0 = 0; // remove clock
	short_wait(); // probably unnecessary

	// BCM2835 ARM Peripherals PDF p 101 & elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs
	GPIO_PULL = 0; // no pull-up no pull-down just float
	short_wait(); // must wait 150 cycles
	GPIO_PULLCLK0 = 0x0ff00000; // selects GPIO pins 20..27
	short_wait();
	GPIO_PULL = 0; // reset GPPUD register
	short_wait();
	GPIO_PULLCLK0 = 0; // remove clock
	short_wait(); // probably unnecessary

	// BCM2835 ARM Peripherals PDF p 101 & elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs
	GPIO_PULL = 0; // no pull-up no pull down just float
// not the reason for flashes it seems:
//GPIO_PULL = 2;	// pull-up - letf in but does not the reason for flashes
	short_wait(); // must wait 150 cycles
	GPIO_PULLCLK0 = 0x070000; // selects GPIO pins 16..18
	short_wait();
	GPIO_PULL = 0; // reset GPPUD register
	short_wait();
	GPIO_PULLCLK0 = 0; // remove clock
	short_wait(); // probably unnecessary
	// --------------------------------------------------

	printf("\nFP on\n");


	while (*terminate == 0) {
		unsigned phase;
//		if ((loopcount++ % 500) == 0)	printf("1\n"); // visual heart beat


		// display all phases circular
		for (phase = 0; phase < GPIOPATTERN_LED_BRIGHTNESS_PHASES; phase++) {
			// each phase must be eact same duration, so include switch scanning here

			// the original gpio_ledstatus[8] runs trough all phases
			volatile uint32_t *gpio_ledstatus =
					gpiopattern_ledstatus_phases[gpiopattern_ledstatus_phases_readidx][phase];

			// prepare for lighting LEDs by setting col pins to output
			for (i = 0; i < 12; i++) {
				INP_GPIO(cols[i]); //
				OUT_GPIO(cols[i]); // Define cols as output
			}

			// light up 8 rows of 12 LEDs each
			for (i = 0; i < 8; i++) {

				// Toggle columns for this ledrow (which LEDs should be on (CLR = on))
				for (k = 0; k < 12; k++) {
					if ((gpio_ledstatus[i] & (1 << k)) == 0)
						GPIO_SET = 1 << cols[k];
					else
						GPIO_CLR = 1 << cols[k];
				}

				// Toggle this ledrow on
				INP_GPIO(ledrows[i]);
				GPIO_SET = 1 << ledrows[i]; // test for flash problem
				OUT_GPIO(ledrows[i]);
				/*test* /			GPIO_SET = 1 << ledrows[i]; /**/

				nanosleep((struct timespec[]
				) {	{	0, intervl}}, NULL);

				// Toggle ledrow off
				GPIO_CLR = 1 << ledrows[i]; // superstition
				INP_GPIO(ledrows[i]);
				usleep(10); // waste of cpu cycles but may help against udn2981 ghosting, not flashes though
			}

//nanosleep ((struct timespec[]){{0, intervl}}, NULL); // test

			// prepare for reading switches
			for (i = 0; i < 12; i++)
				INP_GPIO(cols[i]); // flip columns to input. Need internal pull-ups enabled.

			// read three rows of switches
			for (i = 0; i < 3; i++) {
				INP_GPIO(rows[i]); //			GPIO_CLR = 1 << rows[i];	// and output 0V to overrule built-in pull-up from column input pin
				OUT_GPIO(rows[i]); // turn on one switch row
				GPIO_CLR = 1 << rows[i]; // and output 0V to overrule built-in pull-up from column input pin

				nanosleep((struct timespec[]
				)
				{
					{	0, intervl / 100}}, NULL); // probably unnecessary long wait, maybe put above this loop also

				switchscan = 0;
				for (j = 0; j < 12; j++) // 12 switches in each row
						{
					tmp = GPIO_READ(cols[j]);
					if (tmp != 0)
						switchscan += 1 << j;
				}
				INP_GPIO(rows[i]); // stop sinking current from this row of switches

				gpio_switchstatus[i] = switchscan;
			}
		}