Blink ===== .. include:: ../substitutions.rst .. include:: ../../common/applicationdevelopment/linux/Blink1.rst **blink.c** .. code-block:: c #include #include #include #include // Setup gpio6_31 (NET X_MMC3_DAT0) #define GPIO6_ADDR_START 0x4805D000 #define GPIO6_ADDR_END 0x4805DFFF #define GPIO6_SIZE (GPIO6_ADDR_END - GPIO6_ADDR_START) #define GPIO6_PORT (1 << 31) #define GPIO_DATA_OFFSET 0x00000013C #define GPIO_DIR_OFFSET 0x000000134 #define GPIO_CLEAR_OFFSET 0x000000190 void *gpioAddress; unsigned int *gpio_setdataout_addr; unsigned int *gpio_direction_addr; unsigned int *gpio_cleardata_addr; void delay(unsigned long ms) { clock_t start_ticks = clock(); unsigned long millis_ticks = CLOCKS_PER_SEC / 1000; while (clock() - start_ticks < ms * millis_ticks){} } int main() { int fd = open("/dev/mem", O_RDWR); gpioAddress = mmap(0, GPIO6_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO6_ADDR_START); close(fd); gpio_setdataout_addr = gpioAddress + GPIO_DATA_OFFSET; gpio_direction_addr = gpioAddress + GPIO_DIR_OFFSET; gpio_cleardata_addr = gpioAddress + GPIO_CLEAR_OFFSET; *gpio_direction_addr &= ~(GPIO6_PORT); while (1) { *gpio_setdataout_addr |= GPIO6_PORT; delay(1000); *gpio_cleardata_addr |= GPIO6_PORT; delay(1000); } } .. include:: ../../common/applicationdevelopment/linux/Blink2.rst Mux the Processor Pin --------------------- In order for this blink executable to work as intended, we will also need to multiplex (AKA mux) the processor pad such that the |blink-signal| signal is enabled and configured as an output on the |blink-pad| processor pad. We can do this easily using the 'devmem2' utility to directly access nd modify the |soc-caps| hardware registers. .. warning:: Use caution when working with the 'devmem2' utility as it gives you direct access to read and write to memory that could render the system unstable if you modify memory that is being actively used. This utility has no error checking and shouldn't be relied upon in production software. PHYTEC recommends working with 'devmem2' only while prototyping and transitioning your pin settings to the linux device tree for production. * First, identify the processor pad that brings out the signal we are targeting. This can be done by following |blink-net| in the carrier board schematic back to the SOM and to the |soc-caps| processor itself. You should find that this signal is accessible at the processor ball number |blink-ballnum|\ , named |blink-pad|\ . * Looking up the |blink-pad| processor pad within the |soc-caps| Datasheet, we can see that this pad is configured within the |blink-padcfg| register which has the memory address |blink-padcfg-addy|. * We can read this register like so: **Target (Linux)** .. parsed-literal:: devmem2 |blink-padcfg-addy| * We should see the following output by default: **Example Output** .. parsed-literal:: root@\ |default-machine-name|\ :~# devmem2 |blink-padcfg-addy| /dev/mem opened. Memory mapped at address 0xffff9fc5f000. Read at address |blink-padcfg-addy| (0xffff9fc5f084): |blink-padcfg-default-val| * |blink-analyze| * Modify the |blink-padcfg| register in order to configure the |blink-pad| as the desired GPIO mux mode we need (\ |blink-signal|\ ): **Target (Linux)** .. parsed-literal:: devmem2 |blink-padcfg-addy| w |blink-padcfg-gpio-val| Writing the value |blink-padcfg-gpio-val| to |blink-padcfg| effectively changes the pad config settings, giving us the signal we want in the mode we need. .. include:: ../../common/applicationdevelopment/linux/Blink3.rst .. image:: ../../images/phycore-am57x/AM5-blink.png :width: 500px :alt: Example circuit for blinking an LED connected to the phyCORE-AM62x Development Kit. .. include:: ../../common/applicationdevelopment/linux/Blink4.rst