/* * bbl.c - Produce a "Knight Rider" effect on the LED board * * Written 2010 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include #include #define SOC_BASE 0x10000000 #define CGU(n) (*(volatile uint32_t *) (mem+0x00000+(n))) #define GPIO(n) (*(volatile uint32_t *) (mem+0x10000+(n))) #define MSC(n) (*(volatile uint32_t *) (mem+0x21000+(n))) /* * The XBurst CPUs use an interesting concept for setting GPIOs: instead of * writing the value of a pin (0 or 1) directly to an output latch, the latch * is set by writing a 1 to a "set" register and cleared by writing a 1 to a * "clear" register. This way, only an atomic store but no atomic * read-modify-write operations are necessary for changing only part of the * bits on a port. * * The same set/clear mechanism is also used for the other writable registers * affecting GPIOs, e.g., the direction (input/output) and function (GPIO or * MMC) registers. */ #define PDDATS GPIO(0x314) /* port D data set */ #define PDDATC GPIO(0x318) /* port D data clear */ #define PDFUNS GPIO(0x344) /* port D function set */ #define PDFUNC GPIO(0x348) /* port D function clear */ #define PDDIRS GPIO(0x364) /* port D direction set */ #define PDDIRC GPIO(0x368) /* port D direction clear */ #define MSC_STRPCL MSC(0x00) #define MSC_CLKRT MSC(0x08) #define CLKGR CGU(0x0020) #define MSCCDR CGU(0x0068) #define LEDS 10 /* number of LEDs */ #define GROUP_SEL 11 /* PD11, DAT1 - LED group selection */ #define LED_MASK 0x3f00 /* all the LED groups and GROUP_SEL */ #define DELAY_US 50000 #define PAGE_SIZE 4096 static volatile void *mem; int main(int argc, char **argv) { int fd; fd = open("/dev/mem", O_RDWR); if (fd < 0) { perror("/dev/mem"); exit(1); } mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE, MAP_SHARED, fd, SOC_BASE); if (mem == MAP_FAILED) { perror("mmap"); exit(1); } PDFUNC = LED_MASK; /* make all MMC pins GPIOs */ PDDIRC = LED_MASK; PDDIRS = 1 << 9; /* make all MMC pins outputs */ PDFUNS = 1 << 9; MSCCDR = 20; /* MSC clock = 316 MHz / 21 = 16 MHz */ CLKGR &= ~(1 << 7); /* enable MSC clock */ MSC_CLKRT = 0; /* bus clock = CLK_SRC (MSC clock) */ MSC_STRPCL = 2; /* start MMC clock output */ while (1) { sleep(1); // PDDATS = 1 << 9; // PDDATC = 1 << 9; } return 0; }