Пример #1
0
int main()
{
	// Gain access to peripheral memory structures
    if(map_peripheral(&gpio) == -1) {
        printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
        return -1;
    }
    if(map_peripheral(&bsc0) == -1) {
        printf("Failed to map the physical BSC0 (I2C) registers into the virtual memory space.\n");
        return -1;
    }
 
    // I2C initialization
    i2c_init();

	// Initialize Hardware
	PCA9685_Init();

	// Set PWM Frequency to 100Hz
	PCA9685_SetFrequency(100);
	PCA9685_SetDutyCycle(0, 10);
	sleep(2);

	// Catch ctrl+C so that the motors stop then (SAFETY)
	struct sigaction sigIntHandler;

	sigIntHandler.sa_handler = exit_handler;
	sigemptyset(&sigIntHandler.sa_mask);
	sigIntHandler.sa_flags = 0;

	sigaction(SIGINT, &sigIntHandler, NULL);
 
	while(1)
	{
		// Update PWM ; Convert percentage from O -> 100 to 10 -> 20
		PCA9685_SetDutyCycle(0, 10+0.1*10);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*20);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*30);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*40);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*50);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*60);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*70);
		sleep(3);	
		PCA9685_SetDutyCycle(0, 10+0.1*80);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*90);
		sleep(3);
		PCA9685_SetDutyCycle(0, 10+0.1*100);
		sleep(3);	
		PCA9685_SetDutyCycle(0, 0);
		
	}
}  
Пример #2
0
int buzzer_main(int argc, const char* argv[]) {
    if(map_peripheral(&g_gpio) == -1) {
        printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
        return -1;
    }
    s_pin = 4;
    INP_GPIO(s_pin);
    OUT_GPIO(s_pin);
 
    size_t len = 64;
    char* line = (char*)malloc(len);
    int fre = 0;
    int elapsed = 0;
 
    while (getline(&line, &len, stdin) != -1) {
        int r = sscanf(line, "%d %d\n", &fre, &elapsed);
        if (r == 2) {
            if (fre < 20) {
                // no sound
                usleep(elapsed*1000);
            } else {
                playSound(fre, elapsed);
            }
        } else {
            fprintf(stderr, "skip, invalid line: %s", line);
        }
    }
 
    printf("sound count = %lld, high = %lld, low = %lld\n", s_count, s_high, s_low);
    free(line);
    return 0;
}
Пример #3
0
void _CoreSPI::begin() {
    // Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them
//    GPIO.selectFunction(CS0, FSEL_ALT0);
//    GPIO.selectFunction(CS1, FSEL_ALT0);
    GPIO.selectFunction(MISO, FSEL_ALT0);
    GPIO.selectFunction(MOSI, FSEL_ALT0);
    GPIO.selectFunction(SCK, FSEL_ALT0);

    map_peripheral(&spi);
    reg = (bcm2835_spi_registers *)spi.map;
    reg->cs_val = 0;
    sync_peripheral(&spi);
    reg->cs.clear = 0b11;
    reg->cs.cs = 0b11;

    sync_peripheral(&spi);

    setClockDivider(SPI_CLOCK_DIV256);
//    setChipSelectPolarity(SPI_CS0, LOW);
//    setChipSelectPolarity(SPI_CS1, LOW);
//    setChipSelectPolarity(SPI_CS2, LOW);
//    chipSelect(SPI_CS0);
    started = true;

}
Пример #4
0
void rpi_gpio_init()
{
	if(map_peripheral(&gpio) == -1)
	{
		printf("F**k!!\n\rMap Failed\n\r");
	}
}
Пример #5
0
int main()
{
	int ch;
	if (map_peripheral(&gpio) == -1) {
		printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
		return -1;
	}

	// Define pin as output
	INP_GPIO(PIN);
	OUT_GPIO(PIN);

	BIT1();
	while((ch = getchar()) != EOF) {
		short bit;
		usleep(4000);
		BIT0(); // start
		usleep(BITLEN);
		for (bit = 1; bit != 0x100; bit <<= 1) {
			if (bit & ch) BIT1(); else BIT0();
			usleep(BITLEN);
		}
		BIT1(); // stop
		usleep(BITLEN);
	}

	return 0;
}
Пример #6
0
int main()
{
    int value;
  if(map_peripheral(&gpio) == -1) 
  {
    printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
    return -1;
  }
 
  // Define pin 17 as output
  INP_GPIO(2);
  OUT_GPIO(17);
 
  while(1)
  {
    // Toggle pin 17 (blink a led!)
    GPIO_SET = 1 << 17;
    sleep(1);
 
    value = GPIO_READ(2);
    while(!value) {
//        delay(20);
        value = GPIO_READ(2);
    }
    
    GPIO_CLR = 1 << 17;
    sleep(1);
  }
 
  return 0; 
}
Пример #7
0
char InitGpio()
{
	int   rev, mem, maker, overVolted ;
	//printf("*********** Init GPIO *************\n");
	piBoardId(&model,&rev,&mem,&maker,&overVolted);
	if (model==3) printf("Model B+ ");
	if(model<3) printf("Model B ");
	if(model>=4)
	{
		 printf("\n Model 2");
		 BCM2708_PERI_BASE = 0x3F000000 ;
		 dram_phys_base   =  0xc0000000;
		 mem_flag         =  0x04;
	}
	else
	{
		 printf("Model 1");
		 BCM2708_PERI_BASE = 0x20000000 ;
		 dram_phys_base   =  0x40000000;
		 mem_flag         =  0x0c;
	}

	dma_reg = map_peripheral(DMA_BASE, DMA_LEN);
	pwm_reg = map_peripheral(PWM_BASE, PWM_LEN);
	clk_reg = map_peripheral(CLK_BASE, CLK_LEN);

	pcm_reg =  map_peripheral(PCM_BASE, PCM_LEN); 
	gpio_reg = map_peripheral(GPIO_BASE, GPIO_LEN);
	pad_gpios_reg = map_peripheral(PADS_GPIO, PADS_GPIO_LEN);

	return 1;
	
}
Пример #8
0
int main(void) {

    if (map_peripheral(&gpio) == -1) {
        printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
        return -1;
    }
    
    INP_GPIO(TRIGGER);
    OUT_GPIO(TRIGGER);
    INP_GPIO(ECHO);
    
    
    struct timespec 
        pulse   = {0, 10000},     // 0.10 ms
        wait    = {0, 5000},      // 0.05 ms
        loop    = {0, 25000000};  // 25.00 ms
    
    GPIO_CLR = 1 << TRIGGER;
    
    printf("sleeping\n");
    nanosleep(&loop, NULL);


    while(1) {

        // Set the trigger and wait 0.1 ms
        GPIO_SET = 1 << TRIGGER;
        nanosleep(&pulse, NULL);
        GPIO_CLR = 1 << TRIGGER;
        
        // Record the current time, wait for an echo
        struct timespec tstart={0,0}, tend={0,0};
        clock_gettime(CLOCK_MONOTONIC, &tstart);
        while (!GPIO_READ(ECHO))
            nanosleep(&wait, NULL);
        
        // Get the end time and calculate the difference
        clock_gettime(CLOCK_MONOTONIC, &tend);
        int usecs = (tend.tv_sec - tstart.tv_sec) * 1000000 +
                    (tend.tv_nsec - tstart.tv_nsec) / 1000;

        // Convert to meters
        double r = (340.29 * (double) usecs) / 1000000;
        printf("%f meters\n", r);
        nanosleep(&loop, NULL);
    }
}
int main() {

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

    // Define pin 7 as output
    INP_GPIO(4);
    int count = 0;
    while (1) {
        printf("about to read gpio 4..\n");
        int in = GPIO_READ(4);
        printf("%i - in : %i\n", count++,in);
        sleep(1);
    }
    return 0;
}
Пример #10
0
int main() {

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

    // Define pin 7 as output
    INP_GPIO(4);
    OUT_GPIO(4);

    while (1) {
        // Toggle pin 7 (blink a led!)
        GPIO_SET = 1 << 4;
        sleep(1);

        GPIO_CLR = 1 << 4;
        sleep(1);
    }
    return 0;
}
Пример #11
0
int main() {
  //  SetProgramPriority();
  MaxProgramPriority();
  
  struct timespec sleepValue;
  sleepValue.tv_sec = 0;
  sleepValue.tv_nsec = 1L;

  // Never swap this process
  /* struct sched_param sp; */
  /* memset(&sp, 0, sizeof(sp)); */
  /* sp.sched_priority = sched_get_priority_max(SCHED_FIFO); */
  /* sched_setscheduler(0, SCHED_FIFO, &sp); */
  /* mlockall(MCL_CURRENT | MCL_FUTURE); */
  
  if(map_peripheral(&gpio) == -1)
    {
      printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
      return -1;
    }

  // GPIO 4 = RPI Pin 7
  INP_GPIO(4);
  OUT_GPIO(4);

  while(1)
    {
      GPIO_SET = 1 << 4;
      nanosleep(&sleepValue,NULL);
      

      GPIO_CLR = 1 << 4;
      nanosleep(&sleepValue,NULL);

    }

  return 0;
}
Пример #12
0
int main()
{

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

	while(1)
	{
	
		GPIO_SET = 1 <<  10;
		usleep(1055);
		GPIO_CLR = 1 <<  10;
		usleep(1056);
	}

	return(0);
}
Пример #13
0
void init_gpio(void) {
    if(map_peripheral(&g_gpio) == -1) {
        printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
        exit(-1);
    }
}
Пример #14
0
int init_gpio(void)
{
	return map_peripheral(&gpio);
}
Пример #15
0
int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, float ppm, char *control_pipe) {
    // Catch all signals possible - it is vital we kill the DMA engine
    // on process exit!
    for (int i = 0; i < 64; i++) {
        struct sigaction sa;

        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = terminate;
        sigaction(i, &sa, NULL);
    }
        
    dma_reg = map_peripheral(DMA_VIRT_BASE, DMA_LEN);
    pwm_reg = map_peripheral(PWM_VIRT_BASE, PWM_LEN);
    clk_reg = map_peripheral(CLK_VIRT_BASE, CLK_LEN);
    gpio_reg = map_peripheral(GPIO_VIRT_BASE, GPIO_LEN);

    // Use the mailbox interface to the VC to ask for physical memory.
    mbox.handle = mbox_open();
    if (mbox.handle < 0)
        fatal("Failed to open mailbox. Check kernel support for vcio / BCM2708 mailbox.\n");
    printf("Allocating physical memory: size = %d     ", NUM_PAGES * 4096);
    if(! (mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES * 4096, 4096, MEM_FLAG))) {
        fatal("Could not allocate memory.\n");
    }
    // TODO: How do we know that succeeded?
    printf("mem_ref = %u     ", mbox.mem_ref);
    if(! (mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref))) {
        fatal("Could not lock memory.\n");
    }
    printf("bus_addr = %x     ", mbox.bus_addr);
    if(! (mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES * 4096))) {
        fatal("Could not map memory.\n");
    }
    printf("virt_addr = %p\n", mbox.virt_addr);
    

    // GPIO4 needs to be ALT FUNC 0 to output the clock
    gpio_reg[GPFSEL0] = (gpio_reg[GPFSEL0] & ~(7 << 12)) | (4 << 12);

    // Program GPCLK to use MASH setting 1, so fractional dividers work
    clk_reg[GPCLK_CNTL] = 0x5A << 24 | 6;
    udelay(100);
    clk_reg[GPCLK_CNTL] = 0x5A << 24 | 1 << 9 | 1 << 4 | 6;

    ctl = (struct control_data_s *) mbox.virt_addr;
    dma_cb_t *cbp = ctl->cb;
    uint32_t phys_sample_dst = CM_GP0DIV;
    uint32_t phys_pwm_fifo_addr = PWM_PHYS_BASE + 0x18;


    // Calculate the frequency control word
    // The fractional part is stored in the lower 12 bits
    uint32_t freq_ctl = ((float)(PLLFREQ / carrier_freq)) * ( 1 << 12 );


    for (int i = 0; i < NUM_SAMPLES; i++) {
        ctl->sample[i] = 0x5a << 24 | freq_ctl;    // Silence
        // Write a frequency sample
        cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP;
        cbp->src = mem_virt_to_phys(ctl->sample + i);
        cbp->dst = phys_sample_dst;
        cbp->length = 4;
        cbp->stride = 0;
        cbp->next = mem_virt_to_phys(cbp + 1);
        cbp++;
        // Delay
        cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP | BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(5);
        cbp->src = mem_virt_to_phys(mbox.virt_addr);
        cbp->dst = phys_pwm_fifo_addr;
        cbp->length = 4;
        cbp->stride = 0;
        cbp->next = mem_virt_to_phys(cbp + 1);
        cbp++;
    }
    cbp--;
    cbp->next = mem_virt_to_phys(mbox.virt_addr);

    // Here we define the rate at which we want to update the GPCLK control 
    // register.
    //
    // Set the range to 2 bits. PLLD is at 500 MHz, therefore to get 228 kHz
    // we need a divisor of 500000 / 2 / 228 = 1096.491228
    //
    // This is 1096 + 2012*2^-12 theoretically
    //
    // However the fractional part may have to be adjusted to take the actual
    // frequency of your Pi's oscillator into account. For example on my Pi,
    // the fractional part should be 1916 instead of 2012 to get exactly 
    // 228 kHz. However RDS decoding is still okay even at 2012.
    //
    // So we use the 'ppm' parameter to compensate for the oscillator error

    float divider = (500000./(2*228*(1.+ppm/1.e6)));
    uint32_t idivider = (uint32_t) divider;
    uint32_t fdivider = (uint32_t) ((divider - idivider)*pow(2, 12));
    
    printf("ppm corr is %.4f, divider is %.4f (%d + %d*2^-12) [nominal 1096.4912].\n", 
                ppm, divider, idivider, fdivider);

    pwm_reg[PWM_CTL] = 0;
    udelay(10);
    clk_reg[PWMCLK_CNTL] = 0x5A000006;              // Source=PLLD and disable
    udelay(100);
    // theorically : 1096 + 2012*2^-12
    clk_reg[PWMCLK_DIV] = 0x5A000000 | (idivider<<12) | fdivider;
    udelay(100);
    clk_reg[PWMCLK_CNTL] = 0x5A000216;              // Source=PLLD and enable + MASH filter 1
    udelay(100);
    pwm_reg[PWM_RNG1] = 2;
    udelay(10);
    pwm_reg[PWM_DMAC] = PWMDMAC_ENAB | PWMDMAC_THRSHLD;
    udelay(10);
    pwm_reg[PWM_CTL] = PWMCTL_CLRF;
    udelay(10);
    pwm_reg[PWM_CTL] = PWMCTL_USEF1 | PWMCTL_PWEN1;
    udelay(10);
    

    // Initialise the DMA
    dma_reg[DMA_CS] = BCM2708_DMA_RESET;
    udelay(10);
    dma_reg[DMA_CS] = BCM2708_DMA_INT | BCM2708_DMA_END;
    dma_reg[DMA_CONBLK_AD] = mem_virt_to_phys(ctl->cb);
    dma_reg[DMA_DEBUG] = 7; // clear debug error flags
    dma_reg[DMA_CS] = 0x10880001;    // go, mid priority, wait for outstanding writes

    
    uint32_t last_cb = (uint32_t)ctl->cb;

    // Data structures for baseband data
    float data[DATA_SIZE];
    int data_len = 0;
    int data_index = 0;

    // Initialize the baseband generator
    if(fm_mpx_open(audio_file, DATA_SIZE) < 0) return 1;
    
    // Initialize the RDS modulator
    char myps[9] = {0};
    set_rds_pi(pi);
    set_rds_rt(rt);
    uint16_t count = 0;
    uint16_t count2 = 0;
    int varying_ps = 0;
    
    if(ps) {
        set_rds_ps(ps);
        printf("PI: %04X, PS: \"%s\".\n", pi, ps);
    } else {
        printf("PI: %04X, PS: <Varying>.\n", pi);
        varying_ps = 1;
    }
    printf("RT: \"%s\"\n", rt);
    
    // Initialize the control pipe reader
    if(control_pipe) {
        if(open_control_pipe(control_pipe) == 0) {
            printf("Reading control commands on %s.\n", control_pipe);
        } else {
            printf("Failed to open control pipe: %s.\n", control_pipe);
            control_pipe = NULL;
        }
    }
    
    
    printf("Starting to transmit on %3.1f MHz.\n", carrier_freq/1e6);

    for (;;) {
        // Default (varying) PS
        if(varying_ps) {
            if(count == 512) {
                snprintf(myps, 9, "%08d", count2);
                set_rds_ps(myps);
                count2++;
            }
            if(count == 1024) {
                set_rds_ps("RPi-Live");
                count = 0;
            }
            count++;
        }
        
        if(control_pipe && poll_control_pipe() == CONTROL_PIPE_PS_SET) {
            varying_ps = 0;
        }
        
        usleep(5000);

        uint32_t cur_cb = mem_phys_to_virt(dma_reg[DMA_CONBLK_AD]);
        int last_sample = (last_cb - (uint32_t)mbox.virt_addr) / (sizeof(dma_cb_t) * 2);
        int this_sample = (cur_cb - (uint32_t)mbox.virt_addr) / (sizeof(dma_cb_t) * 2);
        int free_slots = this_sample - last_sample;

        if (free_slots < 0)
            free_slots += NUM_SAMPLES;

        while (free_slots >= SUBSIZE) {
            // get more baseband samples if necessary
            if(data_len == 0) {
                if( fm_mpx_get_samples(data) < 0 ) {
                    terminate(0);
                }
                data_len = DATA_SIZE;
                data_index = 0;
            }
            
            float dval = data[data_index] * (DEVIATION / 10.);
            data_index++;
            data_len--;

            int intval = (int)((floor)(dval));
            //int frac = (int)((dval - (float)intval) * SUBSIZE);


            ctl->sample[last_sample++] = (0x5A << 24 | freq_ctl) + intval; //(frac > j ? intval + 1 : intval);
            if (last_sample == NUM_SAMPLES)
                last_sample = 0;

            free_slots -= SUBSIZE;
        }
        last_cb = (uint32_t)mbox.virt_addr + last_sample * sizeof(dma_cb_t) * 2;
    }

    return 0;
}
Пример #16
0
// the main control function
// print help, if needed, setup signal handling for clean daemon exit, setup GPIO
// daemonize, setup fifo and wait for instructions
int main(int argc,char **argv)
{
  // emit help and exit cleanly if they specify any parameters
  if (argc>1) {
    showHelp(argv[0]);
    return 0;
  }

  // prepare signal handling for when we're a daemon (or not)
  struct sigaction new_action, old_action;
  new_action.sa_handler = sigInt;
  sigemptyset (&new_action.sa_mask);
  new_action.sa_flags = 0;
  sigaction (SIGINT, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN) {
    sigaction (SIGINT, &new_action, NULL);
  }
  sigaction (SIGHUP, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN) {
    sigaction (SIGHUP, &new_action, NULL);
  }
  sigaction (SIGTERM, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN) {
    sigaction (SIGTERM, &new_action, NULL);
  }

  // map the gpio area, if we can't do this, there's no point even trying to be a daemon
  if(map_peripheral(&gpio) == -1) 
  {
    printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
    return -1;
  }

  // now the initial setup is done, attempt to make ourselves a daemon before continuing
  // all logging from now on goes to a dedicated log file
  // (from http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html)
  pid_t pid, sid;
  pid = fork();
  if (pid < 0) {
    printf("failed to spawn a daemon (%s)\n",strerror(errno));
    exit(EXIT_FAILURE);
  }
  if (pid > 0) {
    exit(EXIT_SUCCESS);
  }
  umask(0);
  debugFile = fopen(flasherLog, "w+");
  if (!debugFile) {
    perror("failed to create debug log file");
  } else {
    daemonLog("created log file\n");
  }
  sid = setsid();
  if (sid < 0) {
    daemonLog("%s failed to setsid\n",strerror(errno));
    exit(EXIT_FAILURE);
  }
  if ((chdir(flasherPwd)) < 0) {
    daemonLog("%s failed to chdir\n",strerror(errno));
    exit(EXIT_FAILURE);
  }
  close(STDIN_FILENO);  // this is enough to stop the daemon from working
  close(STDOUT_FILENO);
  close(STDERR_FILENO);
  // we are now a daemon, logging to file
  daemonLog("daemon running\n");

  // then create one flasher for each pin we will use
  for (unsigned char pin = MIN_PIN;pin<NUM_PINS;pin++) {
    pins[pin].pin = pin;
  }

  // main loop, open the fifo and wait for messages or for interrupt
  unlink(flasherPipe);
  char buf[CMD_BUF];
  int fifo_create_success = mkfifo(flasherPipe,0777);
  if (fifo_create_success == 0 || errno == EEXIST) {
    daemonLog("Waiting for messages on %s...\n",flasherPipe);
    FILE * flasherfile = fopen(flasherPipe,"r");
    if (flasherfile) {
      while (keepRunning) {
        if (fgets(buf,CMD_BUF,flasherfile)) {
          doControlMessage(buf);
          dumpStatsFile();
        }
        usleep(dutyCycle); // reduce CPU load
      }
      if (fclose(flasherfile)) {
        daemonLog("%s failed to close fifo\n",strerror(errno));
      }
      if (unlink(statsFilePath)) {
        daemonLog("%s failed to cleanup stats\n",strerror(errno));
      }
    } else {
      daemonLog("%s failed to open fifo\n",strerror(errno));
    }
    if (unlink(flasherPipe)) {
      daemonLog("%s failed to cleanup fifo\n",strerror(errno));
    }
  } else {
    daemonLog("%s failed to create fifo\n",strerror(errno));
  }

  // either we couldn't open the fifo or we opened it, ran for a bit and received a shutdown...
  daemonLog("preparing to shut down...\n");
  
  // try to clean up all threads
  for (unsigned char pin = MIN_PIN;pin<NUM_PINS;pin++) {
    if (pins[pin].thread) {
      pthread_join(pins[pin].thread,NULL);
      daemonLog("thread %d done\n",pin);
    }
  }

  return 0; 
}
Пример #17
0
int
main(int argc, char **argv)
{
	parseargs(argc, argv);
	mbox.handle = mbox_open();
	if (mbox.handle < 0)
		fatal("Failed to open mailbox\n");
	unsigned mbox_board_rev = get_board_revision(mbox.handle);
	printf("MBox Board Revision: %#x\n", mbox_board_rev);
	get_model(mbox_board_rev);
	unsigned mbox_dma_channels = get_dma_channels(mbox.handle);
	printf("DMA Channels Info: %#x, using DMA Channel: %d\n", mbox_dma_channels, DMA_CHAN_NUM);

	printf("Using hardware:                 %5s\n", delay_hw == DELAY_VIA_PWM ? "PWM" : "PCM");
	printf("Number of channels:             %5d\n", (int)num_channels);
	printf("PWM frequency:               %5d Hz\n", 1000000/CYCLE_TIME_US);
	printf("PWM steps:                      %5d\n", NUM_SAMPLES);
	printf("Maximum period (100  %%):      %5dus\n", CYCLE_TIME_US);
	printf("Minimum period (%1.3f%%):      %5dus\n", 100.0*SAMPLE_US / CYCLE_TIME_US, SAMPLE_US);
	printf("DMA Base:                  %#010x\n", DMA_BASE);

	setup_sighandlers();

	/* map the registers for all DMA Channels */
	dma_virt_base = map_peripheral(DMA_BASE, (DMA_CHAN_SIZE * (DMA_CHAN_MAX + 1)));
	/* set dma_reg to point to the DMA Channel we are using */
	dma_reg = dma_virt_base + DMA_CHAN_NUM * (DMA_CHAN_SIZE / sizeof(dma_reg));
	pwm_reg = map_peripheral(PWM_BASE, PWM_LEN);
	pcm_reg = map_peripheral(PCM_BASE, PCM_LEN);
	clk_reg = map_peripheral(CLK_BASE, CLK_LEN);
	gpio_reg = map_peripheral(GPIO_BASE, GPIO_LEN);

	/* Use the mailbox interface to the VC to ask for physical memory */
	mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES * PAGE_SIZE, PAGE_SIZE, mem_flag);
	/* TODO: How do we know that succeeded? */
	dprintf("mem_ref %u\n", mbox.mem_ref);
	mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
	dprintf("bus_addr = %#x\n", mbox.bus_addr);
	mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES * PAGE_SIZE);
	dprintf("virt_addr %p\n", mbox.virt_addr);

	if ((unsigned long)mbox.virt_addr & (PAGE_SIZE-1))
		fatal("pi-blaster: Virtual address is not page aligned\n");

	/* we are done with the mbox */
	mbox_close(mbox.handle);
	mbox.handle = -1;
	
	//fatal("TempFatal\n");

	init_ctrl_data();
	init_hardware();
	init_channel_pwm();
	// Init pin2gpio array with 0/false values to avoid locking all of them as PWM.
	init_pin2gpio();
	// Only calls update_pwm after ctrl_data calculates the pin mask to unlock all pins on start.
	init_pwm();
	unlink(DEVFILE);
	if (mkfifo(DEVFILE, 0666) < 0)
		fatal("pi-blaster: Failed to create %s: %m\n", DEVFILE);
	if (chmod(DEVFILE, 0666) < 0)
		fatal("pi-blaster: Failed to set permissions on %s: %m\n", DEVFILE);

	printf("Initialised, ");
	if (daemonize) {
		if (daemon(0,1) < 0) 
			fatal("pi-blaster: Failed to daemonize process: %m\n");
		else
			printf("Daemonized, ");
	}
	printf("Reading %s.\n", DEVFILE);

	go_go_go();

	return 0;
}
Пример #18
0
void gpio_init(){
  if(map_peripheral(&gpio) == -1) 
    {
        printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
    }
}
Пример #19
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;
			}
		}