// // 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
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; }
// 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; }
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; }
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; } }
/** * 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; }
// // 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