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); } }
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; }
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; }
void rpi_gpio_init() { if(map_peripheral(&gpio) == -1) { printf("F**k!!\n\rMap Failed\n\r"); } }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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); } }
int init_gpio(void) { return map_peripheral(&gpio); }
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; }
// 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; }
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; }
void gpio_init(){ if(map_peripheral(&gpio) == -1) { printf("Failed to map the physical GPIO registers into the virtual memory space.\n"); } }
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; } }