diff --git a/.cproject b/.cproject
index 1f60e03..9689b1e 100755
--- a/.cproject
+++ b/.cproject
@@ -23,16 +23,22 @@
@@ -64,16 +70,22 @@
diff --git a/source/application/application.mk b/source/application/application.mk
index e8db916..ac11f41 100755
--- a/source/application/application.mk
+++ b/source/application/application.mk
@@ -1,4 +1,4 @@
CHECK_FOLDER += source/application
SUB_FOLDER += source/application
-INCLUDES += source/application
+INCLUDES += source/application/include
DOC_SRC += source/application
diff --git a/source/application/drive_ctrl.c b/source/application/drive_ctrl.c
new file mode 100644
index 0000000..7c951dc
--- /dev/null
+++ b/source/application/drive_ctrl.c
@@ -0,0 +1,125 @@
+/*
+ * drive_ctrl.c
+ *
+ * Created on: Aug 10, 2016
+ * Author: tkl
+ */
+
+#include
+
+#include "driver.h"
+#include "board_devices.h"
+#include "engines.h"
+
+#include "drive_ctrl.h"
+
+struct drive_ctrl {
+ struct engine_ctrl *left_forward;
+ struct engine_ctrl *left_backward;
+ struct engine_ctrl *right_forward;
+ struct engine_ctrl *right_backward;
+};
+
+struct drive_ctrl_object {
+ unsigned int current_speed;
+};
+
+static struct drive_ctrl drive_ctrl = {
+ .left_forward = &left_forward,
+ .left_backward = &left_backward,
+ .right_forward = &right_forward,
+ .right_backward = &right_backward,
+};
+
+static struct drive_ctrl_object drive_ctrl_object = {
+ .current_speed = 50, /* % */
+};
+
+int drive_ctrl_init(void)
+{
+ 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_backward->enable);
+ write(drive_ctrl.left_backward->enable, "0", 1);
+ 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);
+
+ return 0;
+}
+
+static unsigned int calc_speed_front(int speed_percent)
+{
+ unsigned int speed_front = 0;
+ if(speed_percent > 0) {
+ if(speed_percent > 100)
+ speed_front = 100;
+ else
+ speed_front = (unsigned int) speed_percent;
+ }
+ return speed_front;
+}
+
+static unsigned int calc_speed_back(int speed_percent)
+{
+ unsigned int speed_back = 0;
+ if(speed_percent < 0) {
+ if(speed_percent < -100)
+ speed_back = 100;
+ else
+ speed_back = (unsigned int) abs(speed_percent);
+ }
+ return speed_back;
+}
+
+int drive_ctrl_set_speed_left(int speed_percent)
+{
+ unsigned int front_speed = calc_speed_front(speed_percent);
+ unsigned int back_speed = calc_speed_back(speed_percent);
+ int ret = ioctl(drive_ctrl.left_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&back_speed);
+ ret |= ioctl(drive_ctrl.left_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&front_speed);
+
+ return ret;
+}
+
+int drive_ctrl_set_speed_right(int speed_percent)
+{
+ unsigned int front_speed = calc_speed_front(speed_percent);
+ unsigned int back_speed = calc_speed_back(speed_percent);
+ int ret = ioctl(drive_ctrl.right_backward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&back_speed);
+ ret |= ioctl(drive_ctrl.right_forward->pwm, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&front_speed);
+
+ return ret;
+}
+
+int drive_ctrl_set_speed_value(int speed_percent)
+{
+ drive_ctrl_object.current_speed = speed_percent;
+
+ return 0;
+}
+
+int drive_ctrl_get_speed_value(void)
+{
+ return drive_ctrl_object.current_speed;
+}
diff --git a/source/application/include/drive_ctrl.h b/source/application/include/drive_ctrl.h
new file mode 100644
index 0000000..f499a5b
--- /dev/null
+++ b/source/application/include/drive_ctrl.h
@@ -0,0 +1,19 @@
+/*
+ * drive_ctrl.h
+ *
+ * Created on: Aug 10, 2016
+ * Author: tkl
+ */
+
+#ifndef SOURCE_APPLICATION_INCLUDE_DRIVE_CTRL_H_
+#define SOURCE_APPLICATION_INCLUDE_DRIVE_CTRL_H_
+
+int drive_ctrl_init(void);
+
+int drive_ctrl_set_speed_left(int speed_percent);
+int drive_ctrl_set_speed_right(int speed_percent);
+int drive_ctrl_set_speed_value(int speed_percent);
+int drive_ctrl_get_speed_value(void);
+
+
+#endif /* SOURCE_APPLICATION_INCLUDE_DRIVE_CTRL_H_ */
diff --git a/source/application/include/engines.h b/source/application/include/engines.h
new file mode 100644
index 0000000..8957632
--- /dev/null
+++ b/source/application/include/engines.h
@@ -0,0 +1,36 @@
+/*
+ * engines.h
+ *
+ * Created on: Aug 10, 2016
+ * Author: tkl
+ */
+
+#ifndef SOURCE_APPLICATION_INCLUDE_ENGINES_H_
+#define SOURCE_APPLICATION_INCLUDE_ENGINES_H_
+
+struct engine_ctrl {
+ const struct driver *pwm;
+ const struct driver *enable;
+};
+
+static struct engine_ctrl right_forward = {
+ .pwm = &pwm_2,
+ .enable = &gpio_c0,
+};
+
+static struct engine_ctrl right_backward = {
+ .pwm = &pwm_1,
+ .enable = &gpio_c1,
+};
+
+static struct engine_ctrl left_forward = {
+ .pwm = &pwm_4,
+ .enable = &gpio_c2,
+};
+
+static struct engine_ctrl left_backward = {
+ .pwm = &pwm_3,
+ .enable = &gpio_c3,
+};
+
+#endif /* SOURCE_APPLICATION_INCLUDE_ENGINES_H_ */
diff --git a/source/application/include/shell_commands.h b/source/application/include/shell_commands.h
new file mode 100644
index 0000000..4ba9527
--- /dev/null
+++ b/source/application/include/shell_commands.h
@@ -0,0 +1,13 @@
+/*
+ * shell_commands.h
+ *
+ * Created on: Aug 10, 2016
+ * Author: tkl
+ */
+
+#ifndef SOURCE_APPLICATION_SHELL_COMMANDS_H_
+#define SOURCE_APPLICATION_SHELL_COMMANDS_H_
+
+int shell_commands_init(void);
+
+#endif /* SOURCE_APPLICATION_SHELL_COMMANDS_H_ */
diff --git a/source/application/main.c b/source/application/main.c
index 7b3fe36..fc7f263 100644
--- a/source/application/main.c
+++ b/source/application/main.c
@@ -1,55 +1,21 @@
-#include
#include
-#include
-#include
-#include
+#include
-#include "driver.h"
#include "board_devices.h"
#include "stack.h"
#include "queue.h"
#include "kernel.h"
#include "driver.h"
+#include "list.h"
+#include "shell.h"
+#include "shell_commands.h"
+#include "drive_ctrl.h"
-#define STACK_SIZE 256
-stack_t tc_1_stack[STACK_SIZE];
-struct thread_context tc_1;
-
-void task1(void *arg)
-{
- char rd = '0';
- open(&led_4);
- write(&led_4, &rd, 1);
- while(1) {
- sleep_ms(1000);
- read(&led_4, &rd, 1);
- if(rd == '0')
- rd = '1';
- else
- rd = '0';
- write(&led_4, &rd, 1);
- write(&uart_1, "Driver test\r\n", 13);
- }
-}
-
-char rx_buf[80];
-void task2(void *arg)
-{
- while(1) {
- int i = read(&uart_1, rx_buf, 80);
- if(i > 0) {
- write(&uart_1, rx_buf, i);
- }
- }
-}
-
-stack_t tc_2_stack[STACK_SIZE];
-struct thread_context tc_2;
int main(void)
{
- open(&uart_1);
- thread_create(&tc_1, tc_1_stack, STACK_SIZE, task1, NULL, THREAD_PRIO_LOW);
- thread_create(&tc_2, tc_2_stack, STACK_SIZE, task2, NULL, THREAD_PRIO_LOW);
+ drive_ctrl_init();
+ shell_init(&uart_1);
+ shell_commands_init();
schedule_start();
diff --git a/source/application/shell_commands.c b/source/application/shell_commands.c
new file mode 100644
index 0000000..ed5d2d8
--- /dev/null
+++ b/source/application/shell_commands.c
@@ -0,0 +1,152 @@
+/*
+ * shell_commands.c
+ *
+ * Created on: Aug 10, 2016
+ * Author: tkl
+ */
+#include
+#include
+
+#include "list.h"
+#include "driver.h"
+#include "shell.h"
+#include "drive_ctrl.h"
+
+static void *drive_turn_right_cb(const char *param);
+static void *drive_turn_left_cb(const char *param);
+static void *drive_boost_cb(const char *param);
+static void *drive_retard_cb(const char *param);
+static void *drive_halt_cb(const char *param);
+static void *drive_forward_cb(const char *param);
+static void *drive_backward_cb(const char *param);
+
+static struct command drive_forward = {
+ .command = "f",
+ .description = "Start driving forward with preset speed.",
+ .command_callback = drive_forward_cb,
+};
+
+static struct command drive_backward = {
+ .command = "b",
+ .description = "Start driving backward with preset speed.",
+ .command_callback = drive_backward_cb,
+};
+
+static struct command drive_halt = {
+ .command = "h",
+ .description = "Stop driving.",
+ .command_callback = drive_halt_cb,
+};
+
+static struct command drive_boost = {
+ .command = "+",
+ .description = "Boost speed.",
+ .command_callback = drive_boost_cb,
+};
+
+static struct command drive_retard = {
+ .command = "-",
+ .description = "Retard speed",
+ .command_callback = drive_retard_cb,
+};
+
+static struct command drive_turn_left = {
+ .command = "l",
+ .description = "Turn left.",
+ .command_callback = drive_turn_left_cb,
+};
+
+static struct command drive_turn_right = {
+ .command = "r",
+ .description = "Turn right",
+ .command_callback = drive_turn_right_cb,
+};
+
+int shell_commands_init(void)
+{
+ shell_add_command(&drive_forward);
+ shell_add_command(&drive_backward);
+ shell_add_command(&drive_boost);
+ shell_add_command(&drive_retard);
+ shell_add_command(&drive_halt);
+ shell_add_command(&drive_turn_left);
+ shell_add_command(&drive_turn_right);
+
+ return 0;
+}
+
+static void *drive_turn_right_cb(const char *param)
+{
+ int speed = drive_ctrl_get_speed_value();
+ drive_ctrl_set_speed_left(abs(speed));
+ if(speed > 0)
+ speed *= -1;
+ drive_ctrl_set_speed_right(speed);
+
+ return NULL;
+}
+
+static void *drive_turn_left_cb(const char *param)
+{
+ int speed = drive_ctrl_get_speed_value();
+ drive_ctrl_set_speed_right(abs(speed));
+ if(speed > 0)
+ speed *= -1;
+ drive_ctrl_set_speed_left(speed);
+
+ return NULL;
+}
+
+static void *drive_boost_cb(const char *param)
+{
+ int speed = drive_ctrl_get_speed_value();
+ speed += 10;
+ drive_ctrl_set_speed_value(speed);
+ drive_ctrl_set_speed_left(speed);
+ drive_ctrl_set_speed_right(speed);
+
+ return NULL;
+}
+
+static void *drive_retard_cb(const char *param)
+{
+ int speed = drive_ctrl_get_speed_value();
+ speed -= 10;
+ drive_ctrl_set_speed_value(speed);
+ drive_ctrl_set_speed_left(speed);
+ drive_ctrl_set_speed_right(speed);
+
+ return NULL;
+}
+
+static void *drive_halt_cb(const char *param)
+{
+ drive_ctrl_set_speed_left(0);
+ drive_ctrl_set_speed_right(0);
+
+ return NULL;
+}
+
+static void *drive_forward_cb(const char *param)
+{
+ int speed = drive_ctrl_get_speed_value();
+ if(speed < 0)
+ speed = abs(speed);
+ drive_ctrl_set_speed_value(speed);
+ drive_ctrl_set_speed_left(speed);
+ drive_ctrl_set_speed_right(speed);
+
+ return NULL;
+}
+
+static void *drive_backward_cb(const char *param)
+{
+ int speed = drive_ctrl_get_speed_value();
+ if(speed > 0)
+ speed *= -1;
+ drive_ctrl_set_speed_value(speed);
+ drive_ctrl_set_speed_left(speed);
+ drive_ctrl_set_speed_right(speed);
+
+ return NULL;
+}
diff --git a/source/os/debug/include/board_devices.h b/source/os/debug/include/board_devices.h
index 16ace5b..78fc2e8 100644
--- a/source/os/debug/include/board_devices.h
+++ b/source/os/debug/include/board_devices.h
@@ -3,10 +3,14 @@
#ifndef BOARD_DEVICES_H
#define BOARD_DEVICES_H
+extern const struct driver pwm_4;
+extern const struct driver pwm_3;
+extern const struct driver pwm_2;
+extern const struct driver pwm_1;
extern const struct driver uart_1;
-extern const struct driver led_3;
-extern const struct driver led_4;
-extern const struct driver led_5;
-extern const struct driver led_6;
+extern const struct driver gpio_c0;
+extern const struct driver gpio_c1;
+extern const struct driver gpio_c2;
+extern const struct driver gpio_c3;
#endif /* BOARD_DEVICES_H */
diff --git a/source/os/debug/include/driver.h b/source/os/debug/include/driver.h
index ee82abf..14923d9 100644
--- a/source/os/debug/include/driver.h
+++ b/source/os/debug/include/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/os/debug/include/list.h b/source/os/debug/include/list.h
new file mode 100644
index 0000000..f26b4fe
--- /dev/null
+++ b/source/os/debug/include/list.h
@@ -0,0 +1,25 @@
+/*
+ * list.h
+ *
+ * Created on: Jul 27, 2016
+ * Author: tkl
+ */
+
+#ifndef SOURCE_FIRMWARE_KERNEL_LIST_H_
+#define SOURCE_FIRMWARE_KERNEL_LIST_H_
+
+struct list_node {
+ struct list_node *next;
+ unsigned int data;
+};
+
+struct list {
+ struct list_node *front;
+ struct list_node *rear;
+};
+
+int list_init(struct list *head);
+int list_add(struct list *head, struct list_node *node);
+int list_get_len(struct list *head);
+
+#endif /* SOURCE_FIRMWARE_KERNEL_LIST_H_ */
diff --git a/source/os/debug/include/shell.h b/source/os/debug/include/shell.h
new file mode 100644
index 0000000..c242e8d
--- /dev/null
+++ b/source/os/debug/include/shell.h
@@ -0,0 +1,23 @@
+/*
+ * shell.h
+ *
+ * Created on: Aug 1, 2016
+ * Author: tkl
+ */
+
+#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 char *description;
+ const command_callback command_callback;
+ struct list_node item;
+};
+
+int shell_init(const struct driver *shell_device);
+int shell_add_command(struct command *command);
+
+#endif /* SOURCE_FIRMWARE_KERNEL_INTERFACE_SHELL_H_ */
diff --git a/source/os/debug/libkosmos-arm-stm32f4-discovery-0.0.5-dbg.a b/source/os/debug/libkosmos-arm-stm32f4-discovery-0.0.5-dbg.a
new file mode 100644
index 0000000..3620324
Binary files /dev/null and b/source/os/debug/libkosmos-arm-stm32f4-discovery-0.0.5-dbg.a differ
diff --git a/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a b/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a
deleted file mode 100644
index d285e6a..0000000
Binary files a/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a and /dev/null differ
diff --git a/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a b/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a
new file mode 120000
index 0000000..84ac1a0
--- /dev/null
+++ b/source/os/debug/libkosmos-arm-stm32f4-discovery-dbg.a
@@ -0,0 +1 @@
+libkosmos-arm-stm32f4-discovery-0.0.5-dbg.a
\ No newline at end of file
diff --git a/source/os/release/include/board_devices.h b/source/os/release/include/board_devices.h
index 16ace5b..78fc2e8 100644
--- a/source/os/release/include/board_devices.h
+++ b/source/os/release/include/board_devices.h
@@ -3,10 +3,14 @@
#ifndef BOARD_DEVICES_H
#define BOARD_DEVICES_H
+extern const struct driver pwm_4;
+extern const struct driver pwm_3;
+extern const struct driver pwm_2;
+extern const struct driver pwm_1;
extern const struct driver uart_1;
-extern const struct driver led_3;
-extern const struct driver led_4;
-extern const struct driver led_5;
-extern const struct driver led_6;
+extern const struct driver gpio_c0;
+extern const struct driver gpio_c1;
+extern const struct driver gpio_c2;
+extern const struct driver gpio_c3;
#endif /* BOARD_DEVICES_H */
diff --git a/source/os/release/include/driver.h b/source/os/release/include/driver.h
index ee82abf..14923d9 100644
--- a/source/os/release/include/driver.h
+++ b/source/os/release/include/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/os/release/libkosmos-arm-stm32f4-discovery-0.0.5.a b/source/os/release/libkosmos-arm-stm32f4-discovery-0.0.5.a
new file mode 100644
index 0000000..1f12c56
Binary files /dev/null and b/source/os/release/libkosmos-arm-stm32f4-discovery-0.0.5.a differ
diff --git a/source/os/release/libkosmos-arm-stm32f4-discovery.a b/source/os/release/libkosmos-arm-stm32f4-discovery.a
deleted file mode 100644
index 8455371..0000000
Binary files a/source/os/release/libkosmos-arm-stm32f4-discovery.a and /dev/null differ
diff --git a/source/os/release/libkosmos-arm-stm32f4-discovery.a b/source/os/release/libkosmos-arm-stm32f4-discovery.a
new file mode 120000
index 0000000..08e7161
--- /dev/null
+++ b/source/os/release/libkosmos-arm-stm32f4-discovery.a
@@ -0,0 +1 @@
+libkosmos-arm-stm32f4-discovery-0.0.5.a
\ No newline at end of file