//
// Set GPIO pins to the right mode
// DEMO GPIO mapping:
//         Function            Mode
// GPIO0=  LED                 Output
// GPIO1=  LED                 Output
// GPIO4=  PWM channel-B       Output
// GPIO7=  SPI chip select B   Funct. 0
// GPIO8=  SPI chip select A   Funct. 0
// GPIO9=  SPI MISO            Funct. 0
// GPIO10= SPI MOSI            Funct. 0
// GPIO11= SPI CLK             Funct. 0
// GPIO14= UART TXD           (Funct. 0)
// GPIO15= UART RXD           (Funct. 0)
// GPIO17= LED                 Output
// GPIO18= PWM channel-A       Funct. 5
// GPIO21= LED                 Output
// GPIO22= LED                 Output
// GPIO23= LED                 Output
// GPIO24= Pushbutton          Input
// GPIO25= Pushbutton          Input
//
// Always call INP_GPIO(x) first
// as that is how the macros work
void setup_gpio()
{
   INP_GPIO(0);  OUT_GPIO(0);
   INP_GPIO(1);  OUT_GPIO(1);
   INP_GPIO(4);  OUT_GPIO(4);
   INP_GPIO(7);  SET_GPIO_ALT(7,0);
   INP_GPIO(8);  SET_GPIO_ALT(8,0);
   INP_GPIO(9);  SET_GPIO_ALT(9,0);
   INP_GPIO(10); SET_GPIO_ALT(10,0);
   INP_GPIO(11); SET_GPIO_ALT(11,0);
   // 14 and 15 are already set to UART mode
   // by Linux. Best if we don't touch them
   // INP_GPIO(14); SET_GPIO_ALT(14,0);
   // INP_GPIO(54); SET_GPIO_ALT(15,0);
   INP_GPIO(17);  OUT_GPIO(17);
   INP_GPIO(18);  SET_GPIO_ALT(18,5);
   INP_GPIO(21);  OUT_GPIO(21);
   INP_GPIO(22);  OUT_GPIO(22);
   INP_GPIO(23);  OUT_GPIO(23);
   INP_GPIO(24);
   INP_GPIO(25);

   // enable pull-up on GPIO24&25
   GPIO_PULL = 2;
   short_wait();
   // clock on GPIO 24 & 25 (bit 24 & 25 set)
   GPIO_PULLCLK0 = 0x03000000;
   short_wait();
   GPIO_PULL = 0;
   GPIO_PULLCLK0 = 0;
} // setup_gpio
Exemple #2
0
void pull_down(int pin) {
    //No overflows!
    int shift = (pin%32);

    // enable pull down
    *(gpio + 37) = 0b001;

    short_wait();
    // clock on GPIO pin
    *(gpio + 38) = 0b001 << shift;

    short_wait();
    // set them back to 0
    *(gpio + 37) = 0b000;
    *(gpio + 38) = 0b000;
}
Exemple #3
0
// Sets a pullup or -down resistor on a GPIO
void
set_pullupdn(int gpio, int pud)
{
    int clk_offset = OFFSET_PULLUPDNCLK + (gpio/32);
    int shift = (gpio%32);

    if (pud == PUD_DOWN)
       *(gpio_map+OFFSET_PULLUPDN) = (*(gpio_map+OFFSET_PULLUPDN) & ~3) | PUD_DOWN;
    else if (pud == PUD_UP)
       *(gpio_map+OFFSET_PULLUPDN) = (*(gpio_map+OFFSET_PULLUPDN) & ~3) | PUD_UP;
    else  // pud == PUD_OFF
       *(gpio_map+OFFSET_PULLUPDN) &= ~3;

    short_wait();
    *(gpio_map+clk_offset) = 1 << shift;
    short_wait();
    *(gpio_map+OFFSET_PULLUPDN) &= ~3;
    *(gpio_map+clk_offset) = 0;
}
Exemple #4
0
void stop_pull(int pin) {
    //No overflows!
    int shift = (pin%32);

    //Clear the pull register.
    *(gpio + 37) = 0b000;

    // clock on GPIO pin
    *(gpio + 38) = 0b001 << shift;

    short_wait();
    // set them back to 0
    *(gpio + 37) = 0b000;
    *(gpio + 38) = 0b000;
}
Exemple #5
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;
			}
		}
Exemple #6
0
/**
 * Create a new private key by reading it from a file.  If the
 * files does not exist, create a new key and write it to the
 * file.  Caller must free return value.  Note that this function
 * can not guarantee that another process might not be trying
 * the same operation on the same file at the same time.
 * If the contents of the file
 * are invalid the old file is deleted and a fresh key is
 * created.
 *
 * @param filename name of file to use to store the key
 * @return new private key, NULL on error (for example,
 *   permission denied)
 */
struct GNUNET_CRYPTO_EddsaPrivateKey *
GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename)
{
  struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
  struct GNUNET_DISK_FileHandle *fd;
  unsigned int cnt;
  int ec;
  uint64_t fs;

  if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
    return NULL;
  while (GNUNET_YES != GNUNET_DISK_file_test (filename))
  {
    fd = GNUNET_DISK_file_open (filename,
                                GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE
                                | GNUNET_DISK_OPEN_FAILIFEXISTS,
                                GNUNET_DISK_PERM_USER_READ |
                                GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == fd)
    {
      if (EEXIST == errno)
      {
        if (GNUNET_YES != GNUNET_DISK_file_test (filename))
        {
          /* must exist but not be accessible, fail for good! */
          if (0 != ACCESS (filename, R_OK))
            LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
          else
            GNUNET_break (0);   /* what is going on!? */
          return NULL;
        }
        continue;
      }
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
      return NULL;
    }
    cnt = 0;
    while (GNUNET_YES !=
           GNUNET_DISK_file_lock (fd, 0,
                                  sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                                  GNUNET_YES))
    {
      short_wait ();
      if (0 == ++cnt % 10)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
      }
    }
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Creating a new private key.  This may take a while.\n"));
    priv = GNUNET_CRYPTO_eddsa_key_create ();
    GNUNET_assert (NULL != priv);
    GNUNET_assert (sizeof (*priv) ==
                   GNUNET_DISK_file_write (fd, priv, sizeof (*priv)));
    GNUNET_DISK_file_sync (fd);
    if (GNUNET_YES !=
        GNUNET_DISK_file_unlock (fd, 0,
                                 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
    GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
    return priv;
  }
  /* key file exists already, read it! */
  fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                              GNUNET_DISK_PERM_NONE);
  if (NULL == fd)
  {
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
    return NULL;
  }
  cnt = 0;
  while (1)
  {
    if (GNUNET_YES !=
        GNUNET_DISK_file_lock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                               GNUNET_NO))
    {
      if (0 == ++cnt % 60)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _
             ("This may be ok if someone is currently generating a private key.\n"));
      }
      short_wait ();
      continue;
    }
    if (GNUNET_YES != GNUNET_DISK_file_test (filename))
    {
      /* eh, what!? File we opened is now gone!? */
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));

      return NULL;
    }
    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
      fs = 0;
    if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))
    {
      /* maybe we got the read lock before the key generating
       * process had a chance to get the write lock; give it up! */
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      if (0 == ++cnt % 10)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
             filename, (unsigned int) fs,
             (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("This may be ok if someone is currently generating a key.\n"));
      }
      short_wait ();                /* wait a bit longer! */
      continue;
    }
    break;
  }
  fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey);
  priv = GNUNET_malloc (fs);
  GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs));
  if (GNUNET_YES !=
      GNUNET_DISK_file_unlock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
  GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
  return priv;
}
Exemple #7
0
//
//  Do digital to analogue to digital conversion
//
void main(void)
{ int d, dac_val, v, s, i;

  printf ("These are the connections for the digital to analogue to digital test:\n");
  printf ("jumper connecting GP11 to SCLK\n");
  printf ("jumper connecting GP10 to MOSI\n");
  printf ("jumper connecting GP9 to MISO\n");
  printf ("jumper connecting GP8 to CSnA\n");
  printf ("jumper connecting GP7 to CSnB\n");
  printf ("jumper connecting DA1 on J29 to AD0 on J28\n");
  printf ("When ready hit enter.\n");
  (void) getchar();

  // Map the I/O sections
  setup_io();

  // activate SPI bus pins
  setup_gpio();

  // Setup SPI bus
  setup_spi();

  // The value returned by the A to D can jump around quite a bit, so 
  // simply printing out the value isn't very useful. The bar graph
  // is better because this hides the noise in the signal.

  printf ("dig ana\n");
  for (d=0; d <= 256; d+= 32)
  {
    if (d == 256) 
      dac_val = 255 * 16;
    else 
      dac_val = d * 16;
    write_dac(1, dac_val);
    v= read_adc(0);
    // v should be in range 0-1023
    // map to 0-63
    s = v >> 4;
    printf("%3x %04d ", dac_val, v);
    // show horizontal bar
    for (i = 0; i < s; i++)
      putchar('#');
    for (i = 0; i < 64 - s; i++)
      putchar(' ');
    putchar('\n');
    short_wait();
  } // repeated write/read
  for (d=224; d >= 0; d-= 32)
  {
    dac_val = d * 16;
    write_dac(1, dac_val);
    v= read_adc(0);
    // v should be in range 0-1023
    // map to 0-63
    s = v >> 4;
    printf("%3x %04d ", dac_val, v);
    // show horizontal bar
    for (i = 0; i < s; i++)
      putchar('#');
    for (i = 0; i < 64 - s; i++)
      putchar(' ');
    putchar('\n');
    short_wait();
  } // repeated write/read

  printf("\n");
  restore_io();
} // main