diff --git a/Makefile b/Makefile index ec2da92..c157358 100644 --- a/Makefile +++ b/Makefile @@ -37,23 +37,27 @@ all: @$(MAKE) -C src/kernel @$(MAKE) -C src/fs @$(MAKE) -C src/user - @echo " INITRD" - @tools/rba initrd.img $$(find initrd/*) - @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img \ - initrd.img.o + @$(MAKE) -C src/initrd @echo " LINK " $(OUT) @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -o $(OUT) \ - $$(find src/fs src/kernel src/user -name "*.o") initrd.img.o + $$(find src/fs src/kernel src/user src/initrd -name "*.o") crt: @arm-stmos-$(CC) $(MCUFLAGS) -fsigned-char -Os -fPIE -c src/crt/crt0.c \ -o src/crt/crt0.o +initrd: + @$(MAKE) -C src/initrd + +libgpio: + @$(MAKE) -C src/libgpio + clean: @echo " CLEAN" @$(MAKE) -C src/kernel clean @$(MAKE) -C src/fs clean @$(MAKE) -C src/user clean + @$(MAKE) -C src/initrd clean @rm -f $(OUT) @rm -f initrd.img initrd.img.o diff --git a/initrd/Makefile b/initrd/Makefile deleted file mode 100644 index 5946eee..0000000 --- a/initrd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -## -# A simple Makefile for building executables loadable by stmos. -# - -ARCH = arm-stmos- -CC = gcc -mcpu=cortex-m4 -mthumb -fsigned-char -CFLAGS = -Os -fPIE - -all: - @$(ARCH)$(CC) $(CFLAGS) init.c -o init - @arm-stmos-strip init - diff --git a/src/initrd/Makefile b/src/initrd/Makefile new file mode 100644 index 0000000..82785f4 --- /dev/null +++ b/src/initrd/Makefile @@ -0,0 +1,25 @@ +## +# A simple Makefile for building executables loadable by stmos. +# + +CC = gcc -mcpu=cortex-m4 -mthumb -fsigned-char +CFLAGS = -Os -fPIE -I../libgpio + +CFILES = $(wildcard *.c) +OFILES = $(patsubst %.c, files/%, $(CFILES)) + +all: $(OFILES) + @../../tools/rba initrd.img $$(find files/*) + @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img \ + initrd.img.o + +files/%: %.c + @echo " CC " $< + @$(CROSS)$(CC) $(CFLAGS) $< ../libgpio/libgpio.a -o $@ + @$(CROSS)strip $@ + +clean: + @echo " CLEAN" + @rm -f $(OFILES) + @rm -f initrd.img initrd.img.o + diff --git a/initrd/init b/src/initrd/files/init similarity index 86% rename from initrd/init rename to src/initrd/files/init index 3bc5fd8..13ce410 100755 Binary files a/initrd/init and b/src/initrd/files/init differ diff --git a/initrd/init.c b/src/initrd/init.c similarity index 54% rename from initrd/init.c rename to src/initrd/init.c index 5ff4ae5..dc88ff8 100644 --- a/initrd/init.c +++ b/src/initrd/init.c @@ -4,11 +4,21 @@ */ #include +#include +#include int main(void) { + gpioMode(5, OUTPUT); + printf("Hello, world!\n"); - while (1); + + while (1) { + gpioWrite(5, 1); + delay(1000); + gpioWrite(5, 0); + delay(500); + } return 0; } diff --git a/src/kernel/gpio.c b/src/kernel/gpio.c index 0932e51..33423b9 100644 --- a/src/kernel/gpio.c +++ b/src/kernel/gpio.c @@ -27,7 +27,7 @@ static GPIO_TypeDef *gpio_ports[8] = { void gpio_svc(uint32_t *args) { - GPIO_TypeDef *port = gpio_ports[args[1] / 16]; + GPIO_TypeDef *port = gpio_ports[args[1] >> 4]; uint32_t pin = args[1] & 0xF; switch (args[0]) { @@ -46,6 +46,9 @@ void gpio_svc(uint32_t *args) case 4: gpio_dout(port, pin, args[2]); break; + case 5: + *((int *)args[2]) = gpio_din(port, pin); + break; } } diff --git a/src/kernel/svc.c b/src/kernel/svc.c index 1455841..9044141 100644 --- a/src/kernel/svc.c +++ b/src/kernel/svc.c @@ -59,6 +59,7 @@ void SVC_Handler(void) { * 2 - gpio_pupd * 3 - gpio_speed * 4 - gpio_dout + * 5 - gpio_din */ gpio_svc(args); break; diff --git a/src/libgpio/Makefile b/src/libgpio/Makefile new file mode 100644 index 0000000..a478974 --- /dev/null +++ b/src/libgpio/Makefile @@ -0,0 +1,38 @@ +## +# @file Makefile +# Script to build folder of source files +# +# Copyright (C) 2018 Clyne Sullivan +# +# 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 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +CFILES = $(wildcard *.c) +OFILES = $(patsubst %.c, %.o, $(CFILES)) + +CFLAGS += -fPIC + +all: $(OFILES) + @$(CROSS)ar rcu libgpio.a $(OFILES) + +%.o: %.c + @echo " CC " $< + @$(CROSS)$(CC) $(CFLAGS) -c $< -o $@ + +clean: + @echo " CLEAN" + @rm -f $(OFILES) + @rm -f libgpio.a + + diff --git a/src/libgpio/gpio.c b/src/libgpio/gpio.c new file mode 100644 index 0000000..fdc877c --- /dev/null +++ b/src/libgpio/gpio.c @@ -0,0 +1,78 @@ +#include "gpio.h" + +#include + +void gpioMode(gpio_pin_t pin, int mode) +{ + register uint32_t r1 __asm("r1") = pin; + register uint32_t r2 __asm("r2") = mode; + __asm("\ + mov r0, 0; \ + mov r1, %0; \ + mov r2, %1; \ + svc 1; \ + " :: "r" (r1), "r" (r2)); +} + +void gpioType(gpio_pin_t pin, int type) +{ + register uint32_t r1 __asm("r1") = pin; + register uint32_t r2 __asm("r2") = type; + __asm("\ + mov r0, 1; \ + mov r1, %0; \ + mov r2, %1; \ + svc 1; \ + " :: "r" (r1), "r" (r2)); +} + +void gpioPuPd(gpio_pin_t pin, int pupd) +{ + register uint32_t r1 __asm("r1") = pin; + register uint32_t r2 __asm("r2") = pupd; + __asm("\ + mov r0, 2; \ + mov r1, %0; \ + mov r2, %1; \ + svc 1; \ + " :: "r" (r1), "r" (r2)); +} + +void gpioSpeed(gpio_pin_t pin, int speed) +{ + register uint32_t r1 __asm("r1") = pin; + register uint32_t r2 __asm("r2") = speed; + __asm("\ + mov r0, 3; \ + mov r1, %0; \ + mov r2, %1; \ + svc 1; \ + " :: "r" (r1), "r" (r2)); +} + +void gpioWrite(gpio_pin_t pin, int value) +{ + register uint32_t r1 __asm("r1") = pin; + register uint32_t r2 __asm("r2") = value; + __asm("\ + mov r0, 4; \ + mov r1, %0; \ + mov r2, %1; \ + svc 1; \ + " :: "r" (r1), "r" (r2)); +} + +int gpioRead(gpio_pin_t pin) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = pin; + register uint32_t r2 __asm("r2") = (uint32_t)&ret; + __asm("\ + mov r0, 5; \ + mov r1, %0; \ + mov r2, %1; \ + svc 1; \ + " :: "r" (r1), "r" (r2)); + return ret; +} + diff --git a/src/libgpio/gpio.h b/src/libgpio/gpio.h new file mode 100644 index 0000000..7d7c8f7 --- /dev/null +++ b/src/libgpio/gpio.h @@ -0,0 +1,57 @@ +#ifndef STMOS_GPIO_H_ +#define STMOS_GPIO_H_ + +#define GP(a) ((a - 'A') << 4) + +/** + * Defines possible modes for a gpio pin. + */ +enum GPIO_MODE +{ + INPUT = 0, /**< digital input */ + OUTPUT, /**< digital output */ + ALTERNATE, /**< alternate function */ + ANALOG /**< analog function */ +}; + +/** + * Defines whether to use push-pull or open drain. + */ +enum GPIO_TYPE +{ + PUSHPULL = 0, /**< push-pull */ + OPENDRAIN /**< open drain */ +}; + +/** + * Defines the pin's speed + */ +enum GPIO_SPEED +{ + LOW = 0, /**< low */ + MEDIUM, /**< medium */ + HIGH, /**< high */ + VERYHIGH /**< very high/maximum */ +}; + +/** + * Defines if a pullup or pulldown should be used. + */ +enum GPIO_PUPD +{ + NOPUPD, /**< no pullup/pulldown */ + PULLUP, /**< use pullup */ + PULLDOWN /**< use pulldown */ +}; + + +typedef unsigned int gpio_pin_t; + +void gpioMode(gpio_pin_t pin, int mode); +void gpioType(gpio_pin_t pin, int type); +void gpioPuPd(gpio_pin_t pin, int pupd); +void gpioSpeed(gpio_pin_t pin, int speed); +void gpioWrite(gpio_pin_t pin, int value); +int gpioRead(gpio_pin_t pin); + +#endif // STMOS_GPIO_H_ diff --git a/src/libgpio/libgpio.a b/src/libgpio/libgpio.a new file mode 100644 index 0000000..b8c781d Binary files /dev/null and b/src/libgpio/libgpio.a differ