From a2cddd208faa95e5bf18285223fa457c64370116 Mon Sep 17 00:00:00 2001 From: tkl Date: Mon, 1 Aug 2016 16:53:06 +0200 Subject: [PATCH 01/17] initial shell implement --- source/firmware/kernel/interface/shell.h | 14 ++++++++++ source/firmware/kernel/shell.c | 34 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 source/firmware/kernel/interface/shell.h create mode 100644 source/firmware/kernel/shell.c diff --git a/source/firmware/kernel/interface/shell.h b/source/firmware/kernel/interface/shell.h new file mode 100644 index 0000000..ef5cf24 --- /dev/null +++ b/source/firmware/kernel/interface/shell.h @@ -0,0 +1,14 @@ +/* + * shell.h + * + * Created on: Aug 1, 2016 + * Author: tkl + */ + +#ifndef SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ +#define SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ + +int shell_init(const struct driver *shell_device); +int shell_add_command(const char *command, const void *callback, const void *param); + +#endif /* SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ */ diff --git a/source/firmware/kernel/shell.c b/source/firmware/kernel/shell.c new file mode 100644 index 0000000..020adb2 --- /dev/null +++ b/source/firmware/kernel/shell.c @@ -0,0 +1,34 @@ +/* + * shell.c + * + * Created on: Aug 1, 2016 + * Author: tkl + */ + +#include +#include + +#include "stack.h" +#include "queue.h" +#include "driver.h" +#include "kernel.h" + +#define RX_STACK_SIZE 256 +stack_t rx_stack[RX_STACK_SIZE]; +struct thread_context rx_thread; + +void rx_func(void *arg) +{ +} + + +int shell_init(const struct driver *shell_device) +{ + thread_create(&rx_thread, rx_stack, RX_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW); + return -1; +} + +int shell_add_command(const char *command, const void *callback, const void *param) +{ + return -1; +} From 35af737f68e06957daf7e8ed0586654b1f810b43 Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 2 Aug 2016 11:41:47 +0200 Subject: [PATCH 02/17] first shell implementation --- .../kernel/{include => interface}/list.h | 0 source/firmware/kernel/interface/shell.h | 10 +++- source/firmware/kernel/shell.c | 56 +++++++++++++++++-- 3 files changed, 61 insertions(+), 5 deletions(-) rename source/firmware/kernel/{include => interface}/list.h (100%) diff --git a/source/firmware/kernel/include/list.h b/source/firmware/kernel/interface/list.h similarity index 100% rename from source/firmware/kernel/include/list.h rename to source/firmware/kernel/interface/list.h diff --git a/source/firmware/kernel/interface/shell.h b/source/firmware/kernel/interface/shell.h index ef5cf24..81fd032 100644 --- a/source/firmware/kernel/interface/shell.h +++ b/source/firmware/kernel/interface/shell.h @@ -8,7 +8,15 @@ #ifndef SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ #define SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ +typedef void *(*command_callback)(const char*); + +struct command { + const char *command; + const command_callback command_callback; + struct list_node item; +}; + int shell_init(const struct driver *shell_device); -int shell_add_command(const char *command, const void *callback, const void *param); +int shell_add_command(struct command *command); #endif /* SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ */ diff --git a/source/firmware/kernel/shell.c b/source/firmware/kernel/shell.c index 020adb2..1f32d3b 100644 --- a/source/firmware/kernel/shell.c +++ b/source/firmware/kernel/shell.c @@ -7,28 +7,76 @@ #include #include +#include #include "stack.h" #include "queue.h" #include "driver.h" #include "kernel.h" +#include "list.h" +#include "shell.h" + +struct shell_object { + struct list command_list; + const struct driver *shell_device; +}; + +struct shell_object shell_object; #define RX_STACK_SIZE 256 stack_t rx_stack[RX_STACK_SIZE]; struct thread_context rx_thread; -void rx_func(void *arg) +static void parse(const char *buffer, unsigned int len) { + if(NULL == buffer) + return; + struct list_node *it = shell_object.command_list.front; + while(it != NULL) { + struct command *cmd = (struct command *)it->data; + if(strstr(buffer, cmd->command)) { + cmd->command_callback(buffer); + return; + } + it = it->next; + } } +static void rx_func(void *arg) +{ + char buffer[80]; + unsigned int index = 0; + int ret = 0; + open(shell_object.shell_device); + while(1) { + ret = read(shell_object.shell_device, &buffer[index], + sizeof(buffer) / sizeof(buffer[0]) - index); + if(ret) { + if(buffer[index + ret - 1] == '\n') { + parse(buffer, index + ret); + index = 0; + } + else + index += ret; + } + } +} int shell_init(const struct driver *shell_device) { + if(NULL == shell_device) + return -1; + list_init(&shell_object.command_list); + shell_object.shell_device = shell_device; thread_create(&rx_thread, rx_stack, RX_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW); - return -1; + return 0; } -int shell_add_command(const char *command, const void *callback, const void *param) +int shell_add_command(struct command *command) { - return -1; + if(NULL == command) + return -1; + command->item.data = (unsigned int) command; + list_add(&shell_object.command_list, &command->item); + return 1; } From 1859174c9c49760fcf3d56109bb98560f4d66694 Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 2 Aug 2016 14:10:11 +0200 Subject: [PATCH 03/17] test app implementation for os --- .cproject | 31 +++- Makefile | 25 +++ config/linker/stm32_flash.ld | 170 ++++++++++++++++++ config/make/rules.mk | 8 +- config/make/stm32f4xx.mk | 4 +- .../include/stm32f4-discovery.h | 22 ++- source/firmware/kernel/shell.c | 3 +- source/test/shell/main.c | 39 ++++ source/test/shell/shell.mk | 4 + source/test/test.mk | 3 + 10 files changed, 295 insertions(+), 14 deletions(-) create mode 100755 config/linker/stm32_flash.ld create mode 100644 source/test/shell/main.c create mode 100644 source/test/shell/shell.mk create mode 100644 source/test/test.mk diff --git a/.cproject b/.cproject index 91234d7..4507fd4 100755 --- a/.cproject +++ b/.cproject @@ -136,7 +136,6 @@ make - all true true @@ -144,7 +143,6 @@ make - clean true true @@ -152,6 +150,7 @@ make + distclean true false @@ -197,9 +196,16 @@ false true + + make + TEST_APP=shell + test + true + false + true + make - all true true @@ -231,7 +237,6 @@ make - distclean true false @@ -261,6 +266,22 @@ false true + + make + TEST_APP=shell BOARD=stm32f4-discovery DEBUG=y + test + true + false + true + + + make + TEST_APP=shell BOARD=stm32f4-discovery DEBUG=y + install + true + false + true + make APP=example_radio_rx BOARD=msp430-ccrf DEBUG=y @@ -287,7 +308,6 @@ make - all true true @@ -295,7 +315,6 @@ make - clean true true diff --git a/Makefile b/Makefile index d874baa..1fccb67 100755 --- a/Makefile +++ b/Makefile @@ -12,6 +12,11 @@ endif MAINFILE = $(EXE_DIR)/lib$(OS_NAME)-$(ARCH)-$(BOARD)$(VERSION)$(DBG_EXT)$(LIB_EXT) DEPLOY_PACKET = lib$(OS_NAME)-$(ARCH)-$(BOARD)$(VERSION)$(DBG_EXT).tar.xz +TEST_FILE = $(EXE_DIR)/$(TEST_APP)$(ELF_EXT) +BIN_FILE = $(EXE_DIR)/$(TEST_APP)$(BIN_EXT) +HEX_FILE = $(EXE_DIR)/$(TEST_APP)$(HEX_EXT) +SIZE_FILE = $(SIZE_DIR)/$(TEST_APP)$(SIZE_EXT) + INCLUDES += $(SRC_DIR) SUB_FOLDER := @@ -25,6 +30,10 @@ DEPS = $(SOURCES:$(ROOT_DIR)/%.c=$(OBJ_DIR)/%.d) #include subfolders include source/firmware/firmware.mk +ifdef TEST_APP +include source/test/test.mk +CFLAGS += -DTEST_APP +endif SOURCES += $(foreach folder, $(SUB_FOLDER), $(wildcard $(ROOT_DIR)/$(folder)/*.c)) CHECKSOURCES += $(foreach folder, $(CHECK_FOLDER), $(wildcard $(ROOT_DIR)/$(folder)/*.c)) @@ -74,6 +83,22 @@ doc: @$(MKDIR) $(DOC_DIR) (cat $(DOXYFILE) ; echo "INPUT=$(DOC_SRC)" ; echo "OUTPUT_DIRECTORY=$(DOC_DIR)") | doxygen - +test: check $(OBJECTS) $(ASM_OBJECTS) + @$(MKDIR) $(EXE_DIR) + @$(MKDIR) $(MAP_DIR) + @$(MKDIR) $(SIZE_DIR) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(ASM_OBJECTS) -o $(TEST_FILE) + $(OBJCOPY) $(TEST_FILE) -O binary $(BIN_FILE) + $(OBJCOPY) $(TEST_FILE) -O ihex $(HEX_FILE) + $(NM) --size-sort --print-size $(TEST_FILE) > $(SIZE_FILE) + @echo + @$(SIZE) --format=berkeley -x $(TEST_FILE) + @echo + +install: test + $(PRE_PROGRAM) + $(PROGRAM) + ifneq "$(MAKECMDGOALS)" "clean" -include $(DEPS) else diff --git a/config/linker/stm32_flash.ld b/config/linker/stm32_flash.ld new file mode 100755 index 0000000..7cfdc96 --- /dev/null +++ b/config/linker/stm32_flash.ld @@ -0,0 +1,170 @@ +/* +***************************************************************************** +** +** File : stm32_flash.ld +** +** Abstract : Linker script for STM32F407VG Device with +** 1024KByte FLASH, 192KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Environment : Atollic TrueSTUDIO(R) +** +** Distribution: The file is distributed “as is,” without any warranty +** of any kind. +** +** (c)Copyright Atollic AB. +** You may use this file as-is or modify it according to the needs of your +** project. Distribution of this file (unmodified or modified) is not +** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the +** rights to distribute the assembled, compiled & linked contents of this +** file as part of an application binary file, provided that it is built +** using the Atollic TrueSTUDIO(R) toolchain. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of 128K RAM on AHB bus*/ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K + MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = .; + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + /* MEMORY_bank1 section, code must be located here explicitly */ + /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */ + .memory_b1_text : + { + *(.mb1text) /* .mb1text sections (code) */ + *(.mb1text*) /* .mb1text* sections (code) */ + *(.mb1rodata) /* read-only data (constants) */ + *(.mb1rodata*) + } >MEMORY_B1 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/config/make/rules.mk b/config/make/rules.mk index 582a77a..5e9a8ec 100755 --- a/config/make/rules.mk +++ b/config/make/rules.mk @@ -1,14 +1,14 @@ -.PHONY: clean distclean doc +.PHONY: clean distclean doc test ROOT_DIR := $(shell pwd | sed "s/\/source//g") -ifeq ($(BOARD), msp430-ccrf) -include $(ROOT_DIR)/config/make/msp430.mk -endif ifeq ($(BOARD), stm32f4-discovery) include $(ROOT_DIR)/config/make/stm32f4xx.mk endif +OS_LIB = kosmos-$(ARCH)-$(BOARD)$(DBG_EXT) +LIBS += $(OS_LIB) + CFLAGS += \ -Wno-unused-function \ -O$(OPTIM) \ diff --git a/config/make/stm32f4xx.mk b/config/make/stm32f4xx.mk index 563d1b2..4a9e9f3 100644 --- a/config/make/stm32f4xx.mk +++ b/config/make/stm32f4xx.mk @@ -23,7 +23,7 @@ endif CFLAGS += \ -mthumb \ - -T $(ROOT_DIR)/source/firmware/arch/stm32f4xx/linker/stm32_flash.ld \ + -T $(ROOT_DIR)/config/linker/stm32_flash.ld \ -D USE_STDPERIPH_DRIVER\ -D VECT_TAB_FLASH\ -D GCC_ARMCM4\ @@ -54,7 +54,7 @@ LDFLAGS=\ ASFLAGS=-mapcs-32 -g ARFLAGS=rcs -OOCD_IMAGE=$(BINFILE) +OOCD_IMAGE=$(BIN_FILE) OOCD_CFG_FILE=$(EXE_DIR)/openocd.cfg PRE_PROGRAM = echo "telnet_port 4444\ninit\nreset halt\nflash write_image erase $(OOCD_IMAGE) 0x08000000 bin\nreset run\n shutdown\n" > $(OOCD_CFG_FILE) diff --git a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h index d393075..ac1816f 100755 --- a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h +++ b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h @@ -86,7 +86,11 @@ static const struct uart __uart_1 = { &console_buffer, }; +#ifdef TEST_APP +static const struct driver uart_1 = { +#else const struct driver uart_1 = { +#endif DRIVER_TYPE_UART, &__uart_1, }; @@ -109,12 +113,16 @@ static const struct stm32f4_gpio stm32_f4_discovery_led_3 = { NULL }; +#ifdef TEST_APP static const struct gpio __led_3 = { +#else +const struct gpio __led_3 = { +#endif (void*)&stm32_f4_discovery_led_3, &gpio_fp }; -const struct driver led_3 = { +static const struct driver led_3 = { DRIVER_TYPE_GPIO, &__led_3, }; @@ -142,7 +150,11 @@ static const struct gpio __led_4 = { &gpio_fp }; +#ifdef TEST_APP +static const struct driver led_4 = { +#else const struct driver led_4 = { +#endif DRIVER_TYPE_GPIO, &__led_4, }; @@ -170,7 +182,11 @@ static const struct gpio __led_5 = { &gpio_fp }; +#ifdef TEST_APP +static const struct driver led_5 = { +#else const struct driver led_5 = { +#endif DRIVER_TYPE_GPIO, &__led_5, }; @@ -198,7 +214,11 @@ static const struct gpio __led_6 = { &gpio_fp }; +#ifdef TEST_APP +static const struct driver led_6 = { +#else const struct driver led_6 = { +#endif DRIVER_TYPE_GPIO, &__led_6, }; diff --git a/source/firmware/kernel/shell.c b/source/firmware/kernel/shell.c index 1f32d3b..1edfd13 100644 --- a/source/firmware/kernel/shell.c +++ b/source/firmware/kernel/shell.c @@ -52,7 +52,8 @@ static void rx_func(void *arg) ret = read(shell_object.shell_device, &buffer[index], sizeof(buffer) / sizeof(buffer[0]) - index); if(ret) { - if(buffer[index + ret - 1] == '\n') { + if((buffer[index + ret - 1] == '\n') || (buffer[index + ret - 1] == '\r')) { + buffer[index + ret - 1] = '\n'; parse(buffer, index + ret); index = 0; } diff --git a/source/test/shell/main.c b/source/test/shell/main.c new file mode 100644 index 0000000..a1c4210 --- /dev/null +++ b/source/test/shell/main.c @@ -0,0 +1,39 @@ +/* + * main.c + * + * Created on: Aug 2, 2016 + * Author: tkl + */ + +#include + +#include "driver.h" +#include "board.h" +#include "stack.h" +#include "queue.h" +#include "kernel.h" +#include "driver.h" +#include "list.h" +#include "shell.h" + +void *uname_fct(const char *line) +{ + if(NULL == line) + return NULL; + + return NULL; +} + +static struct command cmd = { + .command = "uname", + .command_callback = uname_fct +}; + +int main(void) +{ + shell_init(&uart_1); + shell_add_command(&cmd); + schedule_start(); + + return 0; +} diff --git a/source/test/shell/shell.mk b/source/test/shell/shell.mk new file mode 100644 index 0000000..d07baa2 --- /dev/null +++ b/source/test/shell/shell.mk @@ -0,0 +1,4 @@ +CHECK_FOLDER += source/test/shell +SUB_FOLDER += source/test/shell +INCLUDES += source/test/shell +DOC_SRC += source/test/shell diff --git a/source/test/test.mk b/source/test/test.mk new file mode 100644 index 0000000..910224c --- /dev/null +++ b/source/test/test.mk @@ -0,0 +1,3 @@ +ifeq ($(TEST_APP), shell) +include source/test/shell/shell.mk +endif \ No newline at end of file From 1938cfbd7e08b15a7f3ee269c2d523d29adbdafd Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 2 Aug 2016 14:23:59 +0200 Subject: [PATCH 04/17] echo on shell --- source/firmware/kernel/shell.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/firmware/kernel/shell.c b/source/firmware/kernel/shell.c index 1edfd13..0cfdba2 100644 --- a/source/firmware/kernel/shell.c +++ b/source/firmware/kernel/shell.c @@ -44,17 +44,19 @@ static void parse(const char *buffer, unsigned int len) static void rx_func(void *arg) { - char buffer[80]; + char buffer[81]; unsigned int index = 0; int ret = 0; open(shell_object.shell_device); while(1) { ret = read(shell_object.shell_device, &buffer[index], - sizeof(buffer) / sizeof(buffer[0]) - index); + sizeof(buffer) / sizeof(buffer[0]) - index - 1); if(ret) { + write(shell_object.shell_device, &buffer[index], ret); // echo if((buffer[index + ret - 1] == '\n') || (buffer[index + ret - 1] == '\r')) { buffer[index + ret - 1] = '\n'; parse(buffer, index + ret); + buffer[index + ret] = '\0'; index = 0; } else From c7eaa74c1b17b7574f0f0491d522edf351246c44 Mon Sep 17 00:00:00 2001 From: tkl Date: Wed, 3 Aug 2016 11:36:55 +0200 Subject: [PATCH 05/17] error correction in board file for stm32f4-discovery --- .../board/stm32f4-discovery/include/stm32f4-discovery.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h index ac1816f..81faad3 100755 --- a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h +++ b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h @@ -113,16 +113,16 @@ static const struct stm32f4_gpio stm32_f4_discovery_led_3 = { NULL }; -#ifdef TEST_APP static const struct gpio __led_3 = { -#else -const struct gpio __led_3 = { -#endif (void*)&stm32_f4_discovery_led_3, &gpio_fp }; +#ifdef TEST_APP static const struct driver led_3 = { +#else +const struct driver led_3 = { +#endif DRIVER_TYPE_GPIO, &__led_3, }; From 43d07d71b587135b780e86d82b492a8455c02f8a Mon Sep 17 00:00:00 2001 From: tkl Date: Mon, 8 Aug 2016 11:19:08 +0200 Subject: [PATCH 06/17] pwm test app --- .cproject | 23 +++++++++++++++++++++- Makefile | 2 +- config/make/stm32f4xx.mk | 5 ++--- source/firmware/kernel/shell.c | 8 ++++---- source/test/pwm/main.c | 35 ++++++++++++++++++++++++++++++++++ source/test/pwm/pwm.mk | 4 ++++ source/test/test.mk | 5 ++++- 7 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 source/test/pwm/main.c create mode 100644 source/test/pwm/pwm.mk diff --git a/.cproject b/.cproject index 4507fd4..e426cac 100755 --- a/.cproject +++ b/.cproject @@ -136,6 +136,7 @@ make + all true true @@ -143,6 +144,7 @@ make + clean true true @@ -150,7 +152,6 @@ make - distclean true false @@ -206,6 +207,7 @@ make + all true true @@ -237,6 +239,7 @@ make + distclean true false @@ -282,6 +285,22 @@ false true + + make + TEST_APP=pwm BOARD=stm32f4-discovery DEBUG=y + test + true + false + true + + + make + TEST_APP=pwm BOARD=stm32f4-discovery DEBUG=y + install + true + false + true + make APP=example_radio_rx BOARD=msp430-ccrf DEBUG=y @@ -308,6 +327,7 @@ make + all true true @@ -315,6 +335,7 @@ make + clean true true diff --git a/Makefile b/Makefile index 1fccb67..1f44a67 100755 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ doc: @$(MKDIR) $(DOC_DIR) (cat $(DOXYFILE) ; echo "INPUT=$(DOC_SRC)" ; echo "OUTPUT_DIRECTORY=$(DOC_DIR)") | doxygen - -test: check $(OBJECTS) $(ASM_OBJECTS) +test: $(OBJECTS) $(ASM_OBJECTS) @$(MKDIR) $(EXE_DIR) @$(MKDIR) $(MAP_DIR) @$(MKDIR) $(SIZE_DIR) diff --git a/config/make/stm32f4xx.mk b/config/make/stm32f4xx.mk index 4a9e9f3..252ca65 100644 --- a/config/make/stm32f4xx.mk +++ b/config/make/stm32f4xx.mk @@ -9,8 +9,8 @@ endif CROSS_COMPILE=arm-none-eabi- INCLUDES += \ - /usr/lib/arm-none-eabi/include \ - /usr/lib/gcc/arm-none-eabi/4.8/include + /opt/arm-2011.09/arm-none-eabi/include \ + /opt/arm-2011.09/lib/gcc/arm-none-eabi/4.6.1/include ifeq ($(DEBUG),y) OPTIM = 0 @@ -35,7 +35,6 @@ CFLAGS += \ -mfloat-abi=softfp \ -fdata-sections \ -ffunction-sections -# -D inline= -mthumb\ CPPCHECK_FLAGS += \ -D USE_STDPERIPH_DRIVER\ diff --git a/source/firmware/kernel/shell.c b/source/firmware/kernel/shell.c index 0cfdba2..3a832da 100644 --- a/source/firmware/kernel/shell.c +++ b/source/firmware/kernel/shell.c @@ -23,9 +23,9 @@ struct shell_object { struct shell_object shell_object; -#define RX_STACK_SIZE 256 -stack_t rx_stack[RX_STACK_SIZE]; -struct thread_context rx_thread; +#define TH_STACK_SIZE 256 +stack_t th_stack[TH_STACK_SIZE]; +struct thread_context th_ctx; static void parse(const char *buffer, unsigned int len) { @@ -71,7 +71,7 @@ int shell_init(const struct driver *shell_device) return -1; list_init(&shell_object.command_list); shell_object.shell_device = shell_device; - thread_create(&rx_thread, rx_stack, RX_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW); + thread_create(&th_ctx, th_stack, TH_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW); return 0; } diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c new file mode 100644 index 0000000..343676f --- /dev/null +++ b/source/test/pwm/main.c @@ -0,0 +1,35 @@ +/* + * main.c + * + * Created on: Aug 2, 2016 + * Author: tkl + */ + +#include + +#include "driver.h" +#include "board.h" +#include "stack.h" +#include "queue.h" +#include "kernel.h" +#include "driver.h" +#include "list.h" +#include "shell.h" + +#define TH_STACK_SIZE 256 +stack_t th_stack[TH_STACK_SIZE]; +struct thread_context th_ctx; +static void th_func(void *arg) +{ + while(1) { + } +} + +int main(void) +{ + thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW); + + schedule_start(); + + return 0; +} diff --git a/source/test/pwm/pwm.mk b/source/test/pwm/pwm.mk new file mode 100644 index 0000000..0ce5cc1 --- /dev/null +++ b/source/test/pwm/pwm.mk @@ -0,0 +1,4 @@ +CHECK_FOLDER += source/test/pwm +SUB_FOLDER += source/test/pwm +INCLUDES += source/test/pwm +DOC_SRC += source/test/pwm diff --git a/source/test/test.mk b/source/test/test.mk index 910224c..e16b6ff 100644 --- a/source/test/test.mk +++ b/source/test/test.mk @@ -1,3 +1,6 @@ ifeq ($(TEST_APP), shell) include source/test/shell/shell.mk -endif \ No newline at end of file +endif +ifeq ($(TEST_APP), pwm) +include source/test/pwm/pwm.mk +endif From 969d35919e11faf02c063347532d5995194c3314 Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 10:43:47 +0200 Subject: [PATCH 07/17] wip --- source/test/pwm/main.c | 146 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index 343676f..6e381a3 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -16,17 +16,163 @@ #include "list.h" #include "shell.h" +#include "stm32f4xx.h" + +struct stm32f4_pwm { + TIM_TypeDef *timer; + const TIM_TimeBaseInitTypeDef *timer_cfg; + const TIM_OCInitTypeDef *output_compare_cfg; + const TIM_BDTRInitTypeDef *bdtr_cfg; + GPIO_TypeDef *port; + uint8_t pin_src; + const GPIO_InitTypeDef *port_cfg; +}; + +static const TIM_TimeBaseInitTypeDef timer_4_cfg = { + .TIM_RepetitionCounter = 0x0000, + .TIM_Prescaler = ((168000000 / 2 ) / 1000000) - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = 20000 +}; + +static const TIM_OCInitTypeDef t4_output_compare_cfg = { + .TIM_OutputNState = TIM_OutputNState_Disable, + .TIM_OCNPolarity = TIM_OCPolarity_High, + .TIM_OCIdleState = TIM_OCIdleState_Reset, + .TIM_OCNIdleState = TIM_OCNIdleState_Set, + .TIM_OCMode = TIM_OCMode_PWM1, + .TIM_OCPolarity = TIM_OCPolarity_High, + .TIM_OutputState = TIM_OutputState_Enable, + .TIM_Pulse = 1500 // Initiale Pulsweite in Millisekunden +}; + +static const TIM_BDTRInitTypeDef t4_bdtr_cfg = { + .TIM_OSSRState = TIM_OSSRState_Disable, + .TIM_OSSIState = TIM_OSSIState_Disable, + .TIM_LOCKLevel = TIM_LOCKLevel_OFF, + .TIM_DeadTime = 0x00, + .TIM_Break = TIM_Break_Disable, + .TIM_BreakPolarity = TIM_BreakPolarity_Low, + .TIM_AutomaticOutput = TIM_AutomaticOutput_Disable, + + + .TIM_AutomaticOutput = TIM_AutomaticOutput_Enable, +}; + +static const GPIO_InitTypeDef port_cfg = { + .GPIO_Pin = GPIO_Pin_12, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP, + .GPIO_Speed = GPIO_Speed_50MHz, +}; + +static struct stm32f4_pwm str32f4_pwm = { + .timer = TIM4, + .timer_cfg = &timer_4_cfg, + .output_compare_cfg = &t4_output_compare_cfg, + .bdtr_cfg = &t4_bdtr_cfg, + .port = GPIOD, + .pin_src = GPIO_PinSource12, + .port_cfg = &port_cfg, +}; + +extern uint32_t SystemCoreClock; +void pwm_open(struct stm32f4_pwm *pwm) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + + /* TIM config */ + GPIO_InitTypeDef GPIO_InitStructure; + + /* TIM4 clock enable */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); + + /* LEDs are on GPIOD */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; + GPIO_Init(GPIOD, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); + + /* pwm set up */ + /* Compute the prescaler value */ + uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; + + /* apb1 clock = 84MHz */ + /* period_reg = src_clk / presc / cnt_clk */ + /* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */ + + /* Time base configuration */ + TIM_TimeBaseStructure.TIM_Period = 4199;//665; + TIM_TimeBaseStructure.TIM_Prescaler = 0;//PrescalerValue; + TIM_TimeBaseStructure.TIM_ClockDivision = 1; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); + + /* PWM1 Mode configuration: Channel1 */ + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OC1Init(TIM4, &TIM_OCInitStructure); + TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); + + /* PWM1 Mode configuration: Channel2 */ + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC2Init(TIM4, &TIM_OCInitStructure); + TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); + + /* PWM1 Mode configuration: Channel3 */ + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC3Init(TIM4, &TIM_OCInitStructure); + TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); + + /* PWM1 Mode configuration: Channel4 */ + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC4Init(TIM4, &TIM_OCInitStructure); + TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); + TIM_ARRPreloadConfig(TIM4, ENABLE); + + /* TIM4 enable counter */ + TIM_Cmd(TIM4, ENABLE); +} + #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; struct thread_context th_ctx; static void th_func(void *arg) { + uint32_t brightness = 4200 / 2; + TIM4->CCR4 = brightness; while(1) { + brightness++; + if(brightness == UINT32_MAX) + brightness = 0; +#if 0 + TIM4->CCR3 = 333 - (brightness + 0) % 333; // set brightness + TIM4->CCR4 = 333 - (brightness + 166/2) % 333; // set brightness + TIM4->CCR1 = 333 - (brightness + 333/2) % 333; // set brightness + TIM4->CCR2 = 333 - (brightness + 499/2) % 333; // set brightness +#endif + sleep_ms(1); } } int main(void) { + pwm_open(&str32f4_pwm); thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW); schedule_start(); From c44104b301330df42b0e9eb39e882fd78ddb7bf6 Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 11:20:33 +0200 Subject: [PATCH 08/17] wip --- source/test/pwm/main.c | 133 ++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 81 deletions(-) diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index 6e381a3..fde0061 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -18,6 +18,13 @@ #include "stm32f4xx.h" +enum stm32f4_pwm_channel { + channel_1 = 1, + channel_2, + channel_3, + channel_4 +}; + struct stm32f4_pwm { TIM_TypeDef *timer; const TIM_TimeBaseInitTypeDef *timer_cfg; @@ -26,14 +33,18 @@ struct stm32f4_pwm { GPIO_TypeDef *port; uint8_t pin_src; const GPIO_InitTypeDef *port_cfg; + enum stm32f4_pwm_channel channel; }; +/* apb1 clock = 84MHz */ +/* period_reg = src_clk / presc / cnt_clk */ +/* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */ static const TIM_TimeBaseInitTypeDef timer_4_cfg = { .TIM_RepetitionCounter = 0x0000, - .TIM_Prescaler = ((168000000 / 2 ) / 1000000) - 1, + .TIM_Prescaler = 0, .TIM_ClockDivision = TIM_CKD_DIV1, .TIM_CounterMode = TIM_CounterMode_Up, - .TIM_Period = 20000 + .TIM_Period = 4199 }; static const TIM_OCInitTypeDef t4_output_compare_cfg = { @@ -44,109 +55,69 @@ static const TIM_OCInitTypeDef t4_output_compare_cfg = { .TIM_OCMode = TIM_OCMode_PWM1, .TIM_OCPolarity = TIM_OCPolarity_High, .TIM_OutputState = TIM_OutputState_Enable, - .TIM_Pulse = 1500 // Initiale Pulsweite in Millisekunden -}; - -static const TIM_BDTRInitTypeDef t4_bdtr_cfg = { - .TIM_OSSRState = TIM_OSSRState_Disable, - .TIM_OSSIState = TIM_OSSIState_Disable, - .TIM_LOCKLevel = TIM_LOCKLevel_OFF, - .TIM_DeadTime = 0x00, - .TIM_Break = TIM_Break_Disable, - .TIM_BreakPolarity = TIM_BreakPolarity_Low, - .TIM_AutomaticOutput = TIM_AutomaticOutput_Disable, - - - .TIM_AutomaticOutput = TIM_AutomaticOutput_Enable, + .TIM_Pulse = 0 // Initiale Pulsweite in Millisekunden }; static const GPIO_InitTypeDef port_cfg = { - .GPIO_Pin = GPIO_Pin_12, + .GPIO_Pin = GPIO_Pin_15, .GPIO_Mode = GPIO_Mode_AF, .GPIO_OType = GPIO_OType_PP, .GPIO_PuPd = GPIO_PuPd_UP, - .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Speed = GPIO_Speed_100MHz, }; static struct stm32f4_pwm str32f4_pwm = { .timer = TIM4, .timer_cfg = &timer_4_cfg, .output_compare_cfg = &t4_output_compare_cfg, - .bdtr_cfg = &t4_bdtr_cfg, .port = GPIOD, - .pin_src = GPIO_PinSource12, + .pin_src = GPIO_PinSource15, .port_cfg = &port_cfg, + .channel = channel_4, }; extern uint32_t SystemCoreClock; void pwm_open(struct stm32f4_pwm *pwm) { - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_OCInitTypeDef TIM_OCInitStructure; - - /* TIM config */ - GPIO_InitTypeDef GPIO_InitStructure; - - /* TIM4 clock enable */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); + uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0; + uint8_t gpio_af_timer = 0; + if(pwm->timer == TIM4) { + clk_ahb_timer = RCC_APB1Periph_TIM4; + gpio_af_timer = GPIO_AF_TIM4; + } + RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE); + if(pwm->port == GPIOD) { + clk_ahb_gpio = RCC_AHB1Periph_GPIOD; + } /* LEDs are on GPIOD */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; - GPIO_Init(GPIOD, &GPIO_InitStructure); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); - - /* pwm set up */ - /* Compute the prescaler value */ - uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; - - /* apb1 clock = 84MHz */ - /* period_reg = src_clk / presc / cnt_clk */ - /* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */ + RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE); + GPIO_Init(pwm->port, (GPIO_InitTypeDef *)pwm->port_cfg); + GPIO_PinAFConfig(pwm->port, pwm->pin_src, gpio_af_timer); /* Time base configuration */ - TIM_TimeBaseStructure.TIM_Period = 4199;//665; - TIM_TimeBaseStructure.TIM_Prescaler = 0;//PrescalerValue; - TIM_TimeBaseStructure.TIM_ClockDivision = 1; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); + TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg); - /* PWM1 Mode configuration: Channel1 */ - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OC1Init(TIM4, &TIM_OCInitStructure); - TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* PWM1 Mode configuration: Channel2 */ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OC2Init(TIM4, &TIM_OCInitStructure); - TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* PWM1 Mode configuration: Channel3 */ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OC3Init(TIM4, &TIM_OCInitStructure); - TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); - - /* PWM1 Mode configuration: Channel4 */ - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OC4Init(TIM4, &TIM_OCInitStructure); - TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); - TIM_ARRPreloadConfig(TIM4, ENABLE); - - /* TIM4 enable counter */ - TIM_Cmd(TIM4, ENABLE); + switch(pwm->channel) { + case channel_1: + TIM_OC1Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC1PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + break; + case channel_2: + TIM_OC2Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC2PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + break; + case channel_3: + TIM_OC3Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC3PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + break; + case channel_4: + TIM_OC4Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC4PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + break; + } + TIM_ARRPreloadConfig(pwm->timer, ENABLE); + TIM_Cmd(pwm->timer, ENABLE); } #define TH_STACK_SIZE 256 From d14354e47c046f261bc73fee0931bb2de3b9d931 Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 11:57:54 +0200 Subject: [PATCH 09/17] wip --- .../stm32f4xx/driver/include/stm32f4_pwm.h | 34 +++++++ .../arch/stm32f4xx/driver/stm32f4_pwm.c | 99 +++++++++++++++++++ source/test/pwm/main.c | 82 ++------------- 3 files changed, 141 insertions(+), 74 deletions(-) create mode 100644 source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h create mode 100644 source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c diff --git a/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h b/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h new file mode 100644 index 0000000..2e1dff4 --- /dev/null +++ b/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h @@ -0,0 +1,34 @@ +/* + * stm32f4_pwm.h + * + * Created on: Aug 9, 2016 + * Author: tkl + */ + +#ifndef SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ +#define SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ + +enum stm32f4_pwm_channel { + channel_1 = 1, + channel_2, + channel_3, + channel_4 +}; + +struct stm32f4_pwm { + TIM_TypeDef *timer; + const TIM_TimeBaseInitTypeDef *timer_cfg; + const TIM_OCInitTypeDef *output_compare_cfg; + const TIM_BDTRInitTypeDef *bdtr_cfg; + GPIO_TypeDef *port; + uint8_t pin_src; + const GPIO_InitTypeDef *port_cfg; + enum stm32f4_pwm_channel channel; +}; + + +int stm32f4_pwm_open(struct stm32f4_pwm *pwm); +int stm32f4_pwm_close(struct stm32f4_pwm *pwm); +int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent); + +#endif /* SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ */ diff --git a/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c b/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c new file mode 100644 index 0000000..8b8505d --- /dev/null +++ b/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c @@ -0,0 +1,99 @@ +/* + * stm32f4_pwm.c + * + * Created on: Aug 9, 2016 + * Author: tkl + */ +#include + +#include "stm32f4xx.h" +#include "stm32f4_pwm.h" + +struct stm32f4_pwm_object { + uint8_t used_channels; + uint32_t channel_1_max_period; + uint32_t channel_2_max_period; + uint32_t channel_3_max_period; + uint32_t channel_4_max_period; +}; + +static struct stm32f4_pwm_object stm32f4_pwm_object = { + .used_channels = 0, + .channel_1_max_period = 0, + .channel_2_max_period = 0, + .channel_3_max_period = 0, + .channel_4_max_period = 0, +}; + +int stm32f4_pwm_open(struct stm32f4_pwm *pwm) +{ + uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0; + uint8_t gpio_af_timer = 0; + if(pwm->timer == TIM4) { + clk_ahb_timer = RCC_APB1Periph_TIM4; + gpio_af_timer = GPIO_AF_TIM4; + } + RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE); + if(pwm->port == GPIOD) { + clk_ahb_gpio = RCC_AHB1Periph_GPIOD; + } + RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE); + GPIO_Init(pwm->port, (GPIO_InitTypeDef *)pwm->port_cfg); + GPIO_PinAFConfig(pwm->port, pwm->pin_src, gpio_af_timer); + + TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg); + + switch(pwm->channel) { + case channel_1: + TIM_OC1Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC1PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_1_max_period = pwm->timer_cfg->TIM_Period + 1; + break; + case channel_2: + TIM_OC2Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC2PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_2_max_period = pwm->timer_cfg->TIM_Period + 1; + break; + case channel_3: + TIM_OC3Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC3PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_3_max_period = pwm->timer_cfg->TIM_Period + 1; + break; + case channel_4: + TIM_OC4Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); + TIM_OC4PreloadConfig(pwm->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_4_max_period = pwm->timer_cfg->TIM_Period + 1; + break; + } + TIM_ARRPreloadConfig(pwm->timer, ENABLE); + TIM_Cmd(pwm->timer, ENABLE); + stm32f4_pwm_object.used_channels++; + return 0; +} + +int stm32f4_pwm_close(struct stm32f4_pwm *pwm) +{ + stm32f4_pwm_object.used_channels--; + if(stm32f4_pwm_object.used_channels == 0) { + TIM_Cmd(pwm->timer, DISABLE); + } + return 0; +} + +int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent) +{ + switch(pwm->channel) { + case channel_1: + TIM_SetCompare1(pwm->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100); + break; + case channel_2: + TIM_SetCompare2(pwm->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100); + break; + case channel_3: + TIM_SetCompare3(pwm->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100); + break; + case channel_4: + TIM_SetCompare4(pwm->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100); + break; + } +} diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index fde0061..edcbf59 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -17,24 +17,7 @@ #include "shell.h" #include "stm32f4xx.h" - -enum stm32f4_pwm_channel { - channel_1 = 1, - channel_2, - channel_3, - channel_4 -}; - -struct stm32f4_pwm { - TIM_TypeDef *timer; - const TIM_TimeBaseInitTypeDef *timer_cfg; - const TIM_OCInitTypeDef *output_compare_cfg; - const TIM_BDTRInitTypeDef *bdtr_cfg; - GPIO_TypeDef *port; - uint8_t pin_src; - const GPIO_InitTypeDef *port_cfg; - enum stm32f4_pwm_channel channel; -}; +#include "stm32f4_pwm.h" /* apb1 clock = 84MHz */ /* period_reg = src_clk / presc / cnt_clk */ @@ -76,74 +59,25 @@ static struct stm32f4_pwm str32f4_pwm = { .channel = channel_4, }; -extern uint32_t SystemCoreClock; -void pwm_open(struct stm32f4_pwm *pwm) -{ - - uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0; - uint8_t gpio_af_timer = 0; - if(pwm->timer == TIM4) { - clk_ahb_timer = RCC_APB1Periph_TIM4; - gpio_af_timer = GPIO_AF_TIM4; - } - RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE); - if(pwm->port == GPIOD) { - clk_ahb_gpio = RCC_AHB1Periph_GPIOD; - } - /* LEDs are on GPIOD */ - RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE); - GPIO_Init(pwm->port, (GPIO_InitTypeDef *)pwm->port_cfg); - GPIO_PinAFConfig(pwm->port, pwm->pin_src, gpio_af_timer); - - /* Time base configuration */ - TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg); - - switch(pwm->channel) { - case channel_1: - TIM_OC1Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC1PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - break; - case channel_2: - TIM_OC2Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC2PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - break; - case channel_3: - TIM_OC3Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC3PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - break; - case channel_4: - TIM_OC4Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC4PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - break; - } - TIM_ARRPreloadConfig(pwm->timer, ENABLE); - TIM_Cmd(pwm->timer, ENABLE); -} #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; struct thread_context th_ctx; static void th_func(void *arg) { - uint32_t brightness = 4200 / 2; - TIM4->CCR4 = brightness; + unsigned int duty = 0; while(1) { - brightness++; - if(brightness == UINT32_MAX) - brightness = 0; -#if 0 - TIM4->CCR3 = 333 - (brightness + 0) % 333; // set brightness - TIM4->CCR4 = 333 - (brightness + 166/2) % 333; // set brightness - TIM4->CCR1 = 333 - (brightness + 333/2) % 333; // set brightness - TIM4->CCR2 = 333 - (brightness + 499/2) % 333; // set brightness -#endif - sleep_ms(1); + stm32f4_pwm_set_duty_cycle(&str32f4_pwm, duty); + sleep_ms(100); + duty++; + if(duty > 100) + duty = 0; } } int main(void) { - pwm_open(&str32f4_pwm); + stm32f4_pwm_open(&str32f4_pwm); thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW); schedule_start(); From b80a44a4d9ccfea418be75185383be9ab14b10cc Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 12:28:01 +0200 Subject: [PATCH 10/17] wip --- .../stm32f4xx/driver/include/stm32f4_pwm.h | 12 +++- .../arch/stm32f4xx/driver/stm32f4_pwm.c | 72 +++++++++++-------- source/firmware/kernel/driver/include/pwm.h | 35 +++++++++ source/firmware/kernel/driver/pwm.c | 33 +++++++++ source/test/pwm/main.c | 10 ++- 5 files changed, 128 insertions(+), 34 deletions(-) create mode 100644 source/firmware/kernel/driver/include/pwm.h create mode 100644 source/firmware/kernel/driver/pwm.c diff --git a/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h b/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h index 2e1dff4..c46174f 100644 --- a/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h +++ b/source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h @@ -27,8 +27,14 @@ struct stm32f4_pwm { }; -int stm32f4_pwm_open(struct stm32f4_pwm *pwm); -int stm32f4_pwm_close(struct stm32f4_pwm *pwm); -int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent); +int stm32f4_pwm_open(const void *pwm); +int stm32f4_pwm_close(const void *pwm); +int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent); + +static const struct pwm_fp stm32f4_pwm_fp = { + .open = stm32f4_pwm_open, + .close = stm32f4_pwm_close, + .set_duty_cycle = stm32f4_pwm_set_duty_cycle, +}; #endif /* SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ */ diff --git a/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c b/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c index 8b8505d..80faa5d 100644 --- a/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c +++ b/source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c @@ -5,8 +5,11 @@ * Author: tkl */ #include +#include #include "stm32f4xx.h" + +#include "pwm.h" #include "stm32f4_pwm.h" struct stm32f4_pwm_object { @@ -25,75 +28,86 @@ static struct stm32f4_pwm_object stm32f4_pwm_object = { .channel_4_max_period = 0, }; -int stm32f4_pwm_open(struct stm32f4_pwm *pwm) +int stm32f4_pwm_open(const void *pwm) { + if(NULL == pwm) + return -1; + struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm; uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0; uint8_t gpio_af_timer = 0; - if(pwm->timer == TIM4) { + if(this->timer == TIM4) { clk_ahb_timer = RCC_APB1Periph_TIM4; gpio_af_timer = GPIO_AF_TIM4; } RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE); - if(pwm->port == GPIOD) { + if(this->port == GPIOD) { clk_ahb_gpio = RCC_AHB1Periph_GPIOD; } RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE); - GPIO_Init(pwm->port, (GPIO_InitTypeDef *)pwm->port_cfg); - GPIO_PinAFConfig(pwm->port, pwm->pin_src, gpio_af_timer); + GPIO_Init(this->port, (GPIO_InitTypeDef *)this->port_cfg); + GPIO_PinAFConfig(this->port, this->pin_src, gpio_af_timer); - TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg); + TIM_TimeBaseInit(this->timer, (TIM_TimeBaseInitTypeDef *)this->timer_cfg); - switch(pwm->channel) { + switch(this->channel) { case channel_1: - TIM_OC1Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC1PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - stm32f4_pwm_object.channel_1_max_period = pwm->timer_cfg->TIM_Period + 1; + TIM_OC1Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg); + TIM_OC1PreloadConfig(this->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_1_max_period = this->timer_cfg->TIM_Period + 1; break; case channel_2: - TIM_OC2Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC2PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - stm32f4_pwm_object.channel_2_max_period = pwm->timer_cfg->TIM_Period + 1; + TIM_OC2Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg); + TIM_OC2PreloadConfig(this->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_2_max_period = this->timer_cfg->TIM_Period + 1; break; case channel_3: - TIM_OC3Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC3PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - stm32f4_pwm_object.channel_3_max_period = pwm->timer_cfg->TIM_Period + 1; + TIM_OC3Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg); + TIM_OC3PreloadConfig(this->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_3_max_period = this->timer_cfg->TIM_Period + 1; break; case channel_4: - TIM_OC4Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg); - TIM_OC4PreloadConfig(pwm->timer, TIM_OCPreload_Enable); - stm32f4_pwm_object.channel_4_max_period = pwm->timer_cfg->TIM_Period + 1; + TIM_OC4Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg); + TIM_OC4PreloadConfig(this->timer, TIM_OCPreload_Enable); + stm32f4_pwm_object.channel_4_max_period = this->timer_cfg->TIM_Period + 1; break; } - TIM_ARRPreloadConfig(pwm->timer, ENABLE); - TIM_Cmd(pwm->timer, ENABLE); + TIM_ARRPreloadConfig(this->timer, ENABLE); + TIM_Cmd(this->timer, ENABLE); stm32f4_pwm_object.used_channels++; return 0; } -int stm32f4_pwm_close(struct stm32f4_pwm *pwm) +int stm32f4_pwm_close(const void *pwm) { + if(NULL == pwm) + return -1; + struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm; + stm32f4_pwm_set_duty_cycle(pwm, 0); stm32f4_pwm_object.used_channels--; if(stm32f4_pwm_object.used_channels == 0) { - TIM_Cmd(pwm->timer, DISABLE); + TIM_Cmd(this->timer, DISABLE); } return 0; } -int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent) +int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent) { - switch(pwm->channel) { + if(NULL == pwm) + return -1; + struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm; + switch(this->channel) { case channel_1: - TIM_SetCompare1(pwm->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100); + TIM_SetCompare1(this->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100); break; case channel_2: - TIM_SetCompare2(pwm->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100); + TIM_SetCompare2(this->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100); break; case channel_3: - TIM_SetCompare3(pwm->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100); + TIM_SetCompare3(this->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100); break; case channel_4: - TIM_SetCompare4(pwm->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100); + TIM_SetCompare4(this->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100); break; } + return 0; } diff --git a/source/firmware/kernel/driver/include/pwm.h b/source/firmware/kernel/driver/include/pwm.h new file mode 100644 index 0000000..6d1d883 --- /dev/null +++ b/source/firmware/kernel/driver/include/pwm.h @@ -0,0 +1,35 @@ +/* + * pwm.h + * + * Created on: Aug 9, 2016 + * Author: tkl + */ + +#ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_ +#define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_ + +//! \brief Function pointer to the open function. +typedef int (*pwm_fp_open_t)(const void*); + +//! \brief Function pointer to the close function. +typedef int (*pwm_fp_close_t)(const void*); + +//! \brief Function pointer to the read function. +typedef int (*pwm_fp_set_duty_cycle_t)(const void*, unsigned int duty_cycle_percent); + +struct pwm_fp { + const pwm_fp_open_t open; + const pwm_fp_close_t close; + const pwm_fp_set_duty_cycle_t set_duty_cycle; +}; + +struct pwm { + const void *arch_dep_device; //!< Architecture depended pwm device (i.e. stm32f10x_pwm_t). + const struct pwm_fp *fp; //!< Function pointer for the pwm driver access. +}; + +int pwm_open(const struct pwm *device); +int pwm_close(const struct pwm *device); +int pwm_set_duty_cycle(const struct pwm *device, unsigned int duty_cycle_percent); + +#endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_ */ diff --git a/source/firmware/kernel/driver/pwm.c b/source/firmware/kernel/driver/pwm.c new file mode 100644 index 0000000..a8e733e --- /dev/null +++ b/source/firmware/kernel/driver/pwm.c @@ -0,0 +1,33 @@ +/* + * pwm.c + * + * Created on: Aug 9, 2016 + * Author: tkl + */ + +#include +#include + +int pwm_open(const struct pwm *device) +{ + if(NULL == device) + return -1; + pwm_fp_open_t open = device->fp->open; + return open(device->arch_dep_device); +} + +int pwm_close(const struct pwm *device) +{ + if(NULL == device) + return -1; + pwm_fp_close_t close = device->fp->close; + return close(device->arch_dep_device); +} + +int pwm_set_duty_cycle(const struct pwm *device, unsigned int duty_cycle_percent) +{ + if(NULL == device) + return -1; + pwm_fp_set_duty_cycle_t set = device->fp->set_duty_cycle; + return set(device->arch_dep_device, duty_cycle_percent); +} diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index edcbf59..9ad07bd 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -17,6 +17,8 @@ #include "shell.h" #include "stm32f4xx.h" + +#include "pwm.h" #include "stm32f4_pwm.h" /* apb1 clock = 84MHz */ @@ -59,6 +61,10 @@ static struct stm32f4_pwm str32f4_pwm = { .channel = channel_4, }; +static const struct pwm pwm_ch4 = { + .arch_dep_device = &str32f4_pwm, + .fp = &stm32f4_pwm_fp, +}; #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; @@ -66,8 +72,9 @@ struct thread_context th_ctx; static void th_func(void *arg) { unsigned int duty = 0; + pwm_open(&pwm_ch4); while(1) { - stm32f4_pwm_set_duty_cycle(&str32f4_pwm, duty); + pwm_set_duty_cycle(&pwm_ch4, duty); sleep_ms(100); duty++; if(duty > 100) @@ -77,7 +84,6 @@ static void th_func(void *arg) int main(void) { - stm32f4_pwm_open(&str32f4_pwm); thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW); schedule_start(); From 461f219b085e60a46d1cb614e8a37cfd6938eadc Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 12:32:19 +0200 Subject: [PATCH 11/17] wip --- source/test/pwm/main.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index 9ad07bd..b9150fa 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -74,11 +74,16 @@ static void th_func(void *arg) unsigned int duty = 0; pwm_open(&pwm_ch4); while(1) { - pwm_set_duty_cycle(&pwm_ch4, duty); - sleep_ms(100); - duty++; - if(duty > 100) - duty = 0; + while(duty < 100) { + pwm_set_duty_cycle(&pwm_ch4, duty); + sleep_ms(10); + duty++; + } + while(duty > 0) { + pwm_set_duty_cycle(&pwm_ch4, duty); + sleep_ms(10); + duty--; + } } } From 2f13f30b3d954a646a1384692d9b06189930489b Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 12:35:56 +0200 Subject: [PATCH 12/17] wip --- .../include/stm32f4-discovery.h | 50 +++++++++++++++++++ source/test/pwm/main.c | 50 ------------------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h index 81faad3..e6a7408 100755 --- a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h +++ b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h @@ -13,15 +13,18 @@ #include "driver.h" #include "gpio.h" +#include "pwm.h" #include "timer.h" #include "uart.h" #include "ringbuffer.h" #include "sys_tick.h" #include "stm32f4xx.h" #include "stm32f4_gpio.h" +#include "stm32f4_pwm.h" #include "stm32f4_uart.h" #include "stm32_sys_tick.h" + // SYSTEM TICK static const enum stm32_sys_tick_time_base stm23_sys_tick_time_base = STM32_SYS_TICK_TIME_BASE_MS; @@ -36,6 +39,53 @@ static const struct loki_timer timer_1 = { &timer_fp }; +// PWM CHANNEL 4 +/* apb1 clock = 84MHz */ +/* period_reg = src_clk / presc / cnt_clk */ +/* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */ +static const TIM_TimeBaseInitTypeDef timer_4_cfg = { + .TIM_RepetitionCounter = 0x0000, + .TIM_Prescaler = 0, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = 4199 +}; + +static const TIM_OCInitTypeDef t4_output_compare_cfg = { + .TIM_OutputNState = TIM_OutputNState_Disable, + .TIM_OCNPolarity = TIM_OCPolarity_High, + .TIM_OCIdleState = TIM_OCIdleState_Reset, + .TIM_OCNIdleState = TIM_OCNIdleState_Set, + .TIM_OCMode = TIM_OCMode_PWM1, + .TIM_OCPolarity = TIM_OCPolarity_High, + .TIM_OutputState = TIM_OutputState_Enable, + .TIM_Pulse = 0 // Initiale Pulsweite in Millisekunden +}; + +static const GPIO_InitTypeDef port_cfg = { + .GPIO_Pin = GPIO_Pin_15, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP, + .GPIO_Speed = GPIO_Speed_100MHz, +}; + +static struct stm32f4_pwm str32f4_pwm = { + .timer = TIM4, + .timer_cfg = &timer_4_cfg, + .output_compare_cfg = &t4_output_compare_cfg, + .port = GPIOD, + .pin_src = GPIO_PinSource15, + .port_cfg = &port_cfg, + .channel = channel_4, +}; + +static const struct pwm pwm_ch4 = { + .arch_dep_device = &str32f4_pwm, + .fp = &stm32f4_pwm_fp, +}; + +// UART 1 static char console_linear_buffer[80]; static struct ringbuffer console_buffer = { console_linear_buffer, diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index b9150fa..f0aa726 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -16,55 +16,6 @@ #include "list.h" #include "shell.h" -#include "stm32f4xx.h" - -#include "pwm.h" -#include "stm32f4_pwm.h" - -/* apb1 clock = 84MHz */ -/* period_reg = src_clk / presc / cnt_clk */ -/* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */ -static const TIM_TimeBaseInitTypeDef timer_4_cfg = { - .TIM_RepetitionCounter = 0x0000, - .TIM_Prescaler = 0, - .TIM_ClockDivision = TIM_CKD_DIV1, - .TIM_CounterMode = TIM_CounterMode_Up, - .TIM_Period = 4199 -}; - -static const TIM_OCInitTypeDef t4_output_compare_cfg = { - .TIM_OutputNState = TIM_OutputNState_Disable, - .TIM_OCNPolarity = TIM_OCPolarity_High, - .TIM_OCIdleState = TIM_OCIdleState_Reset, - .TIM_OCNIdleState = TIM_OCNIdleState_Set, - .TIM_OCMode = TIM_OCMode_PWM1, - .TIM_OCPolarity = TIM_OCPolarity_High, - .TIM_OutputState = TIM_OutputState_Enable, - .TIM_Pulse = 0 // Initiale Pulsweite in Millisekunden -}; - -static const GPIO_InitTypeDef port_cfg = { - .GPIO_Pin = GPIO_Pin_15, - .GPIO_Mode = GPIO_Mode_AF, - .GPIO_OType = GPIO_OType_PP, - .GPIO_PuPd = GPIO_PuPd_UP, - .GPIO_Speed = GPIO_Speed_100MHz, -}; - -static struct stm32f4_pwm str32f4_pwm = { - .timer = TIM4, - .timer_cfg = &timer_4_cfg, - .output_compare_cfg = &t4_output_compare_cfg, - .port = GPIOD, - .pin_src = GPIO_PinSource15, - .port_cfg = &port_cfg, - .channel = channel_4, -}; - -static const struct pwm pwm_ch4 = { - .arch_dep_device = &str32f4_pwm, - .fp = &stm32f4_pwm_fp, -}; #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; @@ -90,7 +41,6 @@ static void th_func(void *arg) int main(void) { thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW); - schedule_start(); return 0; From 24770a1266411eba35a66dc16c87d24d050bee0c Mon Sep 17 00:00:00 2001 From: tkl Date: Tue, 9 Aug 2016 12:52:38 +0200 Subject: [PATCH 13/17] done --- .../include/stm32f4-discovery.h | 11 ++++- source/firmware/kernel/driver/driver.c | 41 +++++++++++++++++++ source/firmware/kernel/interface/driver.h | 4 ++ source/test/pwm/main.c | 5 ++- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h index e6a7408..d70a788 100755 --- a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h +++ b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h @@ -59,7 +59,7 @@ static const TIM_OCInitTypeDef t4_output_compare_cfg = { .TIM_OCMode = TIM_OCMode_PWM1, .TIM_OCPolarity = TIM_OCPolarity_High, .TIM_OutputState = TIM_OutputState_Enable, - .TIM_Pulse = 0 // Initiale Pulsweite in Millisekunden + .TIM_Pulse = 0, }; static const GPIO_InitTypeDef port_cfg = { @@ -85,6 +85,15 @@ static const struct pwm pwm_ch4 = { .fp = &stm32f4_pwm_fp, }; +#ifdef TEST_APP +static const struct driver pwm_4 = { +#else +const struct driver pwm_4 = { +#endif + DRIVER_TYPE_PWM, + &pwm_ch4, +}; + // UART 1 static char console_linear_buffer[80]; static struct ringbuffer console_buffer = { diff --git a/source/firmware/kernel/driver/driver.c b/source/firmware/kernel/driver/driver.c index 06b4747..654c647 100644 --- a/source/firmware/kernel/driver/driver.c +++ b/source/firmware/kernel/driver/driver.c @@ -11,6 +11,7 @@ #include "adc.h" #include "gpio.h" #include "i2c.h" +#include "pwm.h" #include "rtc.h" #include "spi.h" #include "uart.h" @@ -30,6 +31,9 @@ int open(const struct driver *driver) case DRIVER_TYPE_I2C: ret = i2c_open((struct i2c *)(driver->device_driver)); break; + case DRIVER_TYPE_PWM: + ret = pwm_open((const struct pwm *)(driver->device_driver)); + break; case DRIVER_TYPE_RTC: ret = rtc_open((const struct rtc *)(driver->device_driver)); break; @@ -58,6 +62,9 @@ int close(const struct driver *driver) case DRIVER_TYPE_I2C: ret = i2c_close((struct i2c *)(driver->device_driver)); break; + case DRIVER_TYPE_PWM: + ret = pwm_close((const struct pwm *)(driver->device_driver)); + break; case DRIVER_TYPE_RTC: ret = rtc_close((const struct rtc *)(driver->device_driver)); break; @@ -88,6 +95,9 @@ int read(const struct driver *driver, char *buffer, int len) break; case DRIVER_TYPE_I2C: break; + case DRIVER_TYPE_PWM: + ret = -1; + break; case DRIVER_TYPE_RTC: break; case DRIVER_TYPE_SPI: @@ -118,6 +128,9 @@ int write(const struct driver *driver, const char *buffer, int len) break; case DRIVER_TYPE_I2C: break; + case DRIVER_TYPE_PWM: + ret = -1; + break; case DRIVER_TYPE_RTC: break; case DRIVER_TYPE_SPI: @@ -128,3 +141,31 @@ int write(const struct driver *driver, const char *buffer, int len) } return ret; } + +int ioctl(const struct driver *driver, unsigned int cmd, const void *data) +{ + int ret = -1; + if(NULL == driver) + return ret; + switch(driver->driver_type) { + case DRIVER_TYPE_ADC: + break; + case DRIVER_TYPE_GPIO: + break; + case DRIVER_TYPE_I2C: + break; + case DRIVER_TYPE_PWM: + if(cmd == IOCTL_PWM_SET_DUTY_CYCLE) { + unsigned int *duty = (unsigned int *)data; + pwm_set_duty_cycle((const struct pwm *)(driver->device_driver), *duty); + } + break; + case DRIVER_TYPE_RTC: + break; + case DRIVER_TYPE_SPI: + break; + case DRIVER_TYPE_UART: + break; + } + return ret; +} diff --git a/source/firmware/kernel/interface/driver.h b/source/firmware/kernel/interface/driver.h index ee82abf..14923d9 100644 --- a/source/firmware/kernel/interface/driver.h +++ b/source/firmware/kernel/interface/driver.h @@ -8,10 +8,13 @@ #ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ #define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ +#define IOCTL_PWM_SET_DUTY_CYCLE 0 + enum driver_type { DRIVER_TYPE_ADC, DRIVER_TYPE_GPIO, DRIVER_TYPE_I2C, + DRIVER_TYPE_PWM, DRIVER_TYPE_RTC, DRIVER_TYPE_SPI, DRIVER_TYPE_UART @@ -26,5 +29,6 @@ int open(const struct driver *driver); int close(const struct driver *driver); int read(const struct driver *driver, char *buffer, int len); int write(const struct driver *driver, const char *buffer, int len); +int ioctl(const struct driver *driver, unsigned int cmd, const void *data); #endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ */ diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index f0aa726..e8b0418 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -23,15 +23,16 @@ struct thread_context th_ctx; static void th_func(void *arg) { unsigned int duty = 0; - pwm_open(&pwm_ch4); + open(&pwm_4); while(1) { while(duty < 100) { + ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); pwm_set_duty_cycle(&pwm_ch4, duty); sleep_ms(10); duty++; } while(duty > 0) { - pwm_set_duty_cycle(&pwm_ch4, duty); + ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); sleep_ms(10); duty--; } From 0e891d545eace0c85e062c98a3244fd96fee75e0 Mon Sep 17 00:00:00 2001 From: tkl Date: Wed, 10 Aug 2016 11:31:49 +0200 Subject: [PATCH 14/17] engine... --- .../include/stm32f4-discovery.h | 374 ++++++++++-------- source/test/pwm/main.c | 70 +++- 2 files changed, 278 insertions(+), 166 deletions(-) diff --git a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h index d70a788..ea87330 100755 --- a/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h +++ b/source/firmware/arch/stm32f4xx/board/stm32f4-discovery/include/stm32f4-discovery.h @@ -62,7 +62,7 @@ static const TIM_OCInitTypeDef t4_output_compare_cfg = { .TIM_Pulse = 0, }; -static const GPIO_InitTypeDef port_cfg = { +static const GPIO_InitTypeDef port_cfg_D15 = { .GPIO_Pin = GPIO_Pin_15, .GPIO_Mode = GPIO_Mode_AF, .GPIO_OType = GPIO_OType_PP, @@ -70,18 +70,18 @@ static const GPIO_InitTypeDef port_cfg = { .GPIO_Speed = GPIO_Speed_100MHz, }; -static struct stm32f4_pwm str32f4_pwm = { +static struct stm32f4_pwm str32f4_pwm_4 = { .timer = TIM4, .timer_cfg = &timer_4_cfg, .output_compare_cfg = &t4_output_compare_cfg, .port = GPIOD, .pin_src = GPIO_PinSource15, - .port_cfg = &port_cfg, + .port_cfg = &port_cfg_D15, .channel = channel_4, }; static const struct pwm pwm_ch4 = { - .arch_dep_device = &str32f4_pwm, + .arch_dep_device = &str32f4_pwm_4, .fp = &stm32f4_pwm_fp, }; @@ -94,6 +94,105 @@ const struct driver pwm_4 = { &pwm_ch4, }; +// PWM Channel 3 +static const GPIO_InitTypeDef port_cfg_D14 = { + .GPIO_Pin = GPIO_Pin_14, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP, + .GPIO_Speed = GPIO_Speed_100MHz, +}; + +static struct stm32f4_pwm str32f4_pwm_3 = { + .timer = TIM4, + .timer_cfg = &timer_4_cfg, + .output_compare_cfg = &t4_output_compare_cfg, + .port = GPIOD, + .pin_src = GPIO_PinSource14, + .port_cfg = &port_cfg_D14, + .channel = channel_3, +}; + +static const struct pwm pwm_ch3 = { + .arch_dep_device = &str32f4_pwm_3, + .fp = &stm32f4_pwm_fp, +}; + +#ifdef TEST_APP +static const struct driver pwm_3 = { +#else +const struct driver pwm_3 = { +#endif + DRIVER_TYPE_PWM, + &pwm_ch3, +}; + +// PWM Channel 2 +static const GPIO_InitTypeDef port_cfg_D13 = { + .GPIO_Pin = GPIO_Pin_13, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP, + .GPIO_Speed = GPIO_Speed_100MHz, +}; + +static struct stm32f4_pwm str32f4_pwm_2 = { + .timer = TIM4, + .timer_cfg = &timer_4_cfg, + .output_compare_cfg = &t4_output_compare_cfg, + .port = GPIOD, + .pin_src = GPIO_PinSource13, + .port_cfg = &port_cfg_D13, + .channel = channel_2, +}; + +static const struct pwm pwm_ch2 = { + .arch_dep_device = &str32f4_pwm_2, + .fp = &stm32f4_pwm_fp, +}; + +#ifdef TEST_APP +static const struct driver pwm_2 = { +#else +const struct driver pwm_2 = { +#endif + DRIVER_TYPE_PWM, + &pwm_ch2, +}; + +// PWM Channel 2 +static const GPIO_InitTypeDef port_cfg_D12 = { + .GPIO_Pin = GPIO_Pin_12, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP, + .GPIO_Speed = GPIO_Speed_100MHz, +}; + +static struct stm32f4_pwm str32f4_pwm_1 = { + .timer = TIM4, + .timer_cfg = &timer_4_cfg, + .output_compare_cfg = &t4_output_compare_cfg, + .port = GPIOD, + .pin_src = GPIO_PinSource12, + .port_cfg = &port_cfg_D12, + .channel = channel_1, +}; + +static const struct pwm pwm_ch1 = { + .arch_dep_device = &str32f4_pwm_1, + .fp = &stm32f4_pwm_fp, +}; + +#ifdef TEST_APP +static const struct driver pwm_1 = { +#else +const struct driver pwm_1 = { +#endif + DRIVER_TYPE_PWM, + &pwm_ch3, +}; + // UART 1 static char console_linear_buffer[80]; static struct ringbuffer console_buffer = { @@ -154,171 +253,134 @@ const struct driver uart_1 = { &__uart_1, }; -// LED 3 -static const GPIO_InitTypeDef stm32_f4_discovery_led_3_gpio = { - GPIO_Pin_12, - GPIO_Mode_OUT, - GPIO_Speed_100MHz, - GPIO_OType_PP, - GPIO_PuPd_NOPULL -}; - -static const struct stm32f4_gpio stm32_f4_discovery_led_3 = { - GPIOD, - &stm32_f4_discovery_led_3_gpio, - NULL, - NULL, - NULL, - NULL -}; - -static const struct gpio __led_3 = { - (void*)&stm32_f4_discovery_led_3, - &gpio_fp -}; - -#ifdef TEST_APP -static const struct driver led_3 = { -#else -const struct driver led_3 = { -#endif - DRIVER_TYPE_GPIO, - &__led_3, -}; - -// LED 4 -static const GPIO_InitTypeDef stm32_f4_discovery_led_4_gpio = { - GPIO_Pin_13, - GPIO_Mode_OUT, - GPIO_Speed_100MHz, - GPIO_OType_PP, - GPIO_PuPd_NOPULL -}; - -static const struct stm32f4_gpio stm32_f4_discovery_led_4 = { - GPIOD, - &stm32_f4_discovery_led_4_gpio, - NULL, - NULL, - NULL, - NULL -}; - -static const struct gpio __led_4 = { - (void*)&stm32_f4_discovery_led_4, - &gpio_fp -}; - -#ifdef TEST_APP -static const struct driver led_4 = { -#else -const struct driver led_4 = { -#endif - DRIVER_TYPE_GPIO, - &__led_4, -}; - -// LED 5 -static const GPIO_InitTypeDef stm32_f4_discovery_led_5_gpio = { - GPIO_Pin_14, - GPIO_Mode_OUT, - GPIO_Speed_100MHz, - GPIO_OType_PP, - GPIO_PuPd_NOPULL -}; - -static const struct stm32f4_gpio stm32_f4_discovery_led_5 = { - GPIOD, - &stm32_f4_discovery_led_5_gpio, - NULL, - NULL, - NULL, - NULL -}; - -static const struct gpio __led_5 = { - (void*)&stm32_f4_discovery_led_5, - &gpio_fp -}; - -#ifdef TEST_APP -static const struct driver led_5 = { -#else -const struct driver led_5 = { -#endif - DRIVER_TYPE_GPIO, - &__led_5, -}; - -// LED 6 -static const GPIO_InitTypeDef stm32_f4_discovery_led_6_gpio = { - GPIO_Pin_15, - GPIO_Mode_OUT, - GPIO_Speed_100MHz, - GPIO_OType_PP, - GPIO_PuPd_NOPULL -}; - -static const struct stm32f4_gpio stm32_f4_discovery_led_6 = { - GPIOD, - &stm32_f4_discovery_led_6_gpio, - NULL, - NULL, - NULL, - NULL -}; - -static const struct gpio __led_6 = { - (void*)&stm32_f4_discovery_led_6, - &gpio_fp -}; - -#ifdef TEST_APP -static const struct driver led_6 = { -#else -const struct driver led_6 = { -#endif - DRIVER_TYPE_GPIO, - &__led_6, -}; - -// BUTTON -static const GPIO_InitTypeDef stm32_f4_discovery_user_button_gpio = { +// GPIOC0 +static const GPIO_InitTypeDef port_cfg_C0 = { GPIO_Pin_0, - GPIO_Mode_IN, + GPIO_Mode_OUT, GPIO_Speed_100MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL }; -static const EXTI_InitTypeDef stm32_f4_discovery_user_button_exti = { - EXTI_Line0, - EXTI_Mode_Interrupt, - EXTI_Trigger_Rising_Falling, - ENABLE -}; - -static const NVIC_InitTypeDef stm32_f4_discovery_user_button_nvic = { - EXTI0_IRQn, - 0x0F, - 0x0F, - ENABLE -}; - -static const struct stm32f4_gpio stm32_f4_discovery_user_button = { - GPIOA, - &stm32_f4_discovery_user_button_gpio, - &stm32_f4_discovery_user_button_exti, - &stm32_f4_discovery_user_button_nvic, +static const struct stm32f4_gpio stm32_f4_gpio_C0 = { + GPIOC, + &port_cfg_C0, + NULL, + NULL, NULL, NULL }; -static const struct gpio user_button = { - (void*)&stm32_f4_discovery_user_button, +static const struct gpio __gpio_c0 = { + (void*)&stm32_f4_gpio_C0, &gpio_fp }; +#ifdef TEST_APP +static const struct driver gpio_c0 = { +#else +const struct driver gpio_c0 = { +#endif + DRIVER_TYPE_GPIO, + &__gpio_c0, +}; + +// GPIO_C1 +static const GPIO_InitTypeDef port_cfg_C1 = { + GPIO_Pin_1, + GPIO_Mode_OUT, + GPIO_Speed_100MHz, + GPIO_OType_PP, + GPIO_PuPd_NOPULL +}; + +static const struct stm32f4_gpio stm32_f4_gpio_C1 = { + GPIOC, + &port_cfg_C1, + NULL, + NULL, + NULL, + NULL +}; + +static const struct gpio __gpio_c1 = { + (void*)&stm32_f4_gpio_C1, + &gpio_fp +}; + +#ifdef TEST_APP +static const struct driver gpio_c1 = { +#else +const struct driver gpio_c1 = { +#endif + DRIVER_TYPE_GPIO, + &__gpio_c1, +}; + +// GPIO_C2 +static const GPIO_InitTypeDef port_cfg_C2 = { + GPIO_Pin_2, + GPIO_Mode_OUT, + GPIO_Speed_100MHz, + GPIO_OType_PP, + GPIO_PuPd_NOPULL +}; + +static const struct stm32f4_gpio stm32_f4_gpio_C2 = { + GPIOC, + &port_cfg_C2, + NULL, + NULL, + NULL, + NULL +}; + +static const struct gpio __gpio_c2 = { + (void*)&stm32_f4_gpio_C2, + &gpio_fp +}; + +#ifdef TEST_APP +static const struct driver gpio_c2 = { +#else +const struct driver gpio_c2 = { +#endif + DRIVER_TYPE_GPIO, + &__gpio_c2, +}; + +// GPIO_C3 +static const GPIO_InitTypeDef port_cfg_C3 = { + GPIO_Pin_1, + GPIO_Mode_OUT, + GPIO_Speed_100MHz, + GPIO_OType_PP, + GPIO_PuPd_NOPULL +}; + +static const struct stm32f4_gpio stm32_f4_gpio_C3 = { + GPIOC, + &port_cfg_C3, + NULL, + NULL, + NULL, + NULL +}; + +static const struct gpio __gpio_c3 = { + (void*)&stm32_f4_gpio_C3, + &gpio_fp +}; + +#ifdef TEST_APP +static const struct driver gpio_c3 = { +#else +const struct driver gpio_c3 = { +#endif + DRIVER_TYPE_GPIO, + &__gpio_c3, +}; + //! \brief Setup the hardware of the stm32f4-discovery board. void board_init(void); diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index e8b0418..22853aa 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -16,6 +16,45 @@ #include "list.h" #include "shell.h" +struct engine_ctrl { + const struct driver *pwm; + const struct driver *enable; +}; + +struct drive_ctrl { + struct engine_ctrl *left_forward; + struct engine_ctrl *left_backward; + struct engine_ctrl *right_forward; + struct engine_ctrl *right_backward; +}; + + +static struct engine_ctrl right_forward = { + .pwm = &pwm_1, + .enable = &gpio_c1, +}; + +static struct engine_ctrl right_backward = { + .pwm = &pwm_2, + .enable = &gpio_c0, +}; + +static struct engine_ctrl left_forward = { + .pwm = &pwm_3, + .enable = &gpio_c3, +}; + +static struct engine_ctrl left_backward = { + .pwm = &pwm_4, + .enable = &gpio_c2, +}; + +static struct drive_ctrl drive_ctrl = { + .left_forward = &left_forward, + .left_backward = &left_backward, + .right_forward = &right_forward, + .right_backward = &right_backward, +}; #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; @@ -23,19 +62,30 @@ struct thread_context th_ctx; static void th_func(void *arg) { unsigned int duty = 0; - open(&pwm_4); + open(drive_ctrl.left_forward->enable); + write(drive_ctrl.left_forward->enable, "0", 1); + open(drive_ctrl.left_forward->pwm); + open(drive_ctrl.left_backward->enable); + write(drive_ctrl.left_backward->enable, "0", 1); + open(drive_ctrl.left_backward->pwm); + + write(drive_ctrl.left_forward->enable, "1", 1); + write(drive_ctrl.left_backward->enable, "1", 1); while(1) { - while(duty < 100) { - ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); - pwm_set_duty_cycle(&pwm_ch4, duty); - sleep_ms(10); - duty++; + duty = 0; + ioctl(drive_ctrl.left_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + for(duty = 0; duty < 100; duty++) { + ioctl(drive_ctrl.left_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + sleep_ms(100); } - while(duty > 0) { - ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); - sleep_ms(10); - duty--; + duty = 0; + ioctl(drive_ctrl.left_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + sleep_ms(100); + for(duty = 0; duty < 100; duty++) { + ioctl(drive_ctrl.left_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + sleep_ms(100); } + sleep_ms(100); } } From 3063445932952b9917ccca9a62e5b2d231221fd2 Mon Sep 17 00:00:00 2001 From: tkl Date: Wed, 10 Aug 2016 12:13:58 +0200 Subject: [PATCH 15/17] engine ctrl example --- source/test/pwm/main.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index 22853aa..482e65e 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -62,27 +62,48 @@ struct thread_context th_ctx; static void th_func(void *arg) { unsigned int duty = 0; + + /* open enable pins */ open(drive_ctrl.left_forward->enable); write(drive_ctrl.left_forward->enable, "0", 1); - open(drive_ctrl.left_forward->pwm); open(drive_ctrl.left_backward->enable); write(drive_ctrl.left_backward->enable, "0", 1); - open(drive_ctrl.left_backward->pwm); + open(drive_ctrl.right_forward->enable); + write(drive_ctrl.right_forward->enable, "0", 1); + open(drive_ctrl.right_backward->enable); + write(drive_ctrl.right_backward->enable, "0", 1); + /* open pwm's*/ + open(drive_ctrl.left_backward->pwm); + ioctl(drive_ctrl.left_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + open(drive_ctrl.left_forward->pwm); + ioctl(drive_ctrl.left_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + open(drive_ctrl.right_backward->pwm); + ioctl(drive_ctrl.right_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + open(drive_ctrl.right_forward->pwm); + ioctl(drive_ctrl.right_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + + /* enable enable pins */ write(drive_ctrl.left_forward->enable, "1", 1); write(drive_ctrl.left_backward->enable, "1", 1); + write(drive_ctrl.right_forward->enable, "1", 1); + write(drive_ctrl.right_backward->enable, "1", 1); while(1) { duty = 0; ioctl(drive_ctrl.left_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + ioctl(drive_ctrl.right_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); for(duty = 0; duty < 100; duty++) { ioctl(drive_ctrl.left_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + ioctl(drive_ctrl.right_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); sleep_ms(100); } duty = 0; ioctl(drive_ctrl.left_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + ioctl(drive_ctrl.right_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); sleep_ms(100); for(duty = 0; duty < 100; duty++) { ioctl(drive_ctrl.left_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); + ioctl(drive_ctrl.right_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty); sleep_ms(100); } sleep_ms(100); From b0fd6c75424a60e0c3353a33305d3243aec3bc81 Mon Sep 17 00:00:00 2001 From: tkl Date: Wed, 10 Aug 2016 12:22:11 +0200 Subject: [PATCH 16/17] fix double devices in board interface --- source/scripts/board_interface.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/scripts/board_interface.py b/source/scripts/board_interface.py index 3fc6c0e..a260ea8 100755 --- a/source/scripts/board_interface.py +++ b/source/scripts/board_interface.py @@ -16,7 +16,8 @@ def parse_board_file(boardfile): if match("^.*struct driver.*$", line): line = sub("^.*struct driver", "", line).strip() line = sub(" .*$","",line).strip() - ret.append(line) + if not line in ret: + ret.append(line) return ret def create_board_interface(device_list, outfile): From 9f2e9aec8da28a19d010788b84f1f3404fed7f0d Mon Sep 17 00:00:00 2001 From: tkl Date: Wed, 10 Aug 2016 13:00:22 +0200 Subject: [PATCH 17/17] numbering for 0.0.2 release --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 80ffa55..00627ca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ variables: SW_KERNEL: "0" SW_MAJOR: "0" - SW_MINOR: "1" + SW_MINOR: "2" before_script: - "echo $CI_BUILD_ID"