diff --git a/firmware/Makefile b/firmware/Makefile
index 31526f9..cec1d84 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -5,6 +5,7 @@ ifndef BUILD_DIR
endif
PARTNUMBER=stm32f103c8t6
+OPENCM3_FAMILY=STM32F1
CC=arm-none-eabi-gcc
CPP=arm-none-eabi-g++
@@ -23,7 +24,7 @@ INC=.
CFLAGS=--static -nostartfiles -g3 -Os -fno-common -ffunction-sections -fdata-sections -I. -mcpu=cortex-m3 -mthumb -msoft-float
.PHONY: all
-all: libopencm3_stm32f1.a crt.o main.o
+all: libopencm3_stm32f1.a libs_rule drivers_rule crt.o main.o
$(LD) -T$(PARTNUMBER).ld $(BUILD_DIR)/*.o -o $(BUILD_DIR)/$(TARGET).elf -L$(BUILD_DIR)/ -lopencm3_stm32f1
$(OBJCOPY) -O binary $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin
$(SIZE) $(BUILD_DIR)/$(TARGET).elf
@@ -37,7 +38,7 @@ clean:
rm $(BUILD_DIR)/*.o $(BUILD_DIR)/*.a $(BUILD_DIR)/*.elf $(BUILD_DIR)/*.bin
main.o: main.c
- $(CC) -c $(CFLAGS) -Ihal/include/ -DSTM32F1 $< -o $(BUILD_DIR)/$@
+ $(CC) -c $(CFLAGS) -Ihal/include/ -D$(OPENCM3_FAMILY) $< -o $(BUILD_DIR)/$@
crt.o: crt.s
$(AS) -o $@ $<
@@ -49,10 +50,9 @@ libopencm3_stm32f1.a: hal/Makefile
devices: devices/Makefile
$(MAKE) BUILD_DIR=$(BUILD_DIR) -C devices
-drivers: drivers/Makefile
- $(MAKE) BUILD_DIR=$(BUILD_DIR) -C drivers
-
-libs: libs/Makefile
+drivers_rule : drivers/Makefile
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) OPENCM3_FAMILY=$(OPENCM3_FAMILY) -C drivers
+libs_rule: libs/Makefile
$(MAKE) BUILD_DIR=$(BUILD_DIR) -C libs
os: os/Makefile
diff --git a/firmware/config/errno.h b/firmware/config/errno.h
new file mode 100644
index 0000000..04c6f64
--- /dev/null
+++ b/firmware/config/errno.h
@@ -0,0 +1,53 @@
+/*
+ * errno.h
+ *
+ * Copyright The SLCam Contributors.
+ *
+ * This file is part of SLCam.
+ *
+ * SLCam is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SLCam is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SLCam. If not, see .
+ *
+ */
+
+/**
+ * \brief Errors definition.
+ *
+ * \author Miguel Boing
+ *
+ * \version 0.1.3
+ *
+ * \date 2023/02/16
+ *
+ * \defgroup errno Error Codes
+ * \{
+ */
+
+#ifndef ERRNO_H
+#define ERRNO_H
+
+/* No error ocurred */
+#define ERRNO_SUCCESS 0x00U /** No errors found */
+
+/* Driver Level errors */
+#define ERRNO_DRIVER_NO_PORT 0x11U /** No port found */
+#define ERRNO_DRIVER_NO_PARAMETER 0x12U /** Invalid parameter value */
+#define ERRNO_DRIVER_FAILED 0x13U /** Failed to execute HAL function */
+
+/* Device Level errors */
+#define ERRNO_DEVICE_FAILED_CONFIG 0x21U /** Failed to configure driver */
+#define ERRNO_DEVICE_FAILED_COM 0x22U /** Failed to communicate */
+
+#endif /*ERRNO_H */
+
+/** \} End of errno group */
diff --git a/firmware/drivers/Makefile b/firmware/drivers/Makefile
index 55c1d26..8afbf26 100644
--- a/firmware/drivers/Makefile
+++ b/firmware/drivers/Makefile
@@ -4,8 +4,9 @@ endif
.PHONY: all
all:
- $(MAKE) BUILD_DIR=$(BUILD_DIR) -C ov2640
- $(MAKE) BUILD_DIR=$(BUILD_DIR) -C w25qxxx
+# $(MAKE) BUILD_DIR=$(BUILD_DIR) -C ov2640
+# $(MAKE) BUILD_DIR=$(BUILD_DIR) -C w25qxxx
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) OPENCM3_FAMILY=$(OPENCM3_FAMILY) -C uart
.PHONY: clean
clean:
diff --git a/firmware/drivers/uart/Makefile b/firmware/drivers/uart/Makefile
new file mode 100644
index 0000000..ea2aaba
--- /dev/null
+++ b/firmware/drivers/uart/Makefile
@@ -0,0 +1,29 @@
+TARGET=uart
+
+ifndef BUILD_DIR
+ BUILD_DIR=$(CURDIR)
+endif
+
+PARTNUMBER=stm32f103c8t6
+
+CC=arm-none-eabi-gcc
+CPP=arm-none-eabi-g++
+AS=arm-none-eabi-as
+LD=arm-none-eabi-ld
+OBJCOPY=arm-none-eabi-objcopy
+OBJDUMP=arm-none-eabi-objdump
+READELF=arm-none-eabi-readelf
+NM=arm-none-eabi-nm
+SIZE=arm-none-eabi-size
+GDB=arm-none-eabi-gdb
+
+LIBS= -I../../ -I../../hal/include/
+CFLAGS=-c -mcpu=cortex-m3 -mthumb -O0 $(LIBS) -D$(OPENCM3_FAMILY)
+
+.PHONY: all
+all:
+ $(CC) $(CFLAGS) $(TARGET).c -o $(BUILD_DIR)/$(TARGET).o
+
+.PHONY: clean
+clean:
+ rm $(BUILD_DIR)/*.o
diff --git a/firmware/drivers/uart/uart.c b/firmware/drivers/uart/uart.c
new file mode 100644
index 0000000..bfb12fd
--- /dev/null
+++ b/firmware/drivers/uart/uart.c
@@ -0,0 +1,335 @@
+/*
+ * uart.c
+ *
+ * Copyright The SLCam Contributors.
+ *
+ * This file is part of SLCam.
+ *
+ * SLCam is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SLCam is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SLCam. If not, see .
+ *
+ */
+
+/**
+ * \brief UART driver implementation.
+ *
+ * \author Miguel Boing
+ * \author Gabriel Mariano Marcelino
+ *
+ * \version 0.2.1
+ *
+ * \date 2023/02/17
+ *
+ * \addtogroup uart
+ * \{
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "uart.h"
+
+static queue_t uart_port_1_rx_buffer;
+static queue_t uart_port_2_rx_buffer;
+static queue_t uart_port_3_rx_buffer;
+static queue_t uart_port_4_rx_buffer;
+static queue_t uart_port_5_rx_buffer;
+
+static inline int uart_send_byte(uart_config_t config, uint16_t c);
+
+static inline int uart_read_byte(uart_config_t config, uint16_t *c);
+
+static inline uint16_t uart_read_mtu(queue_t *uart_rx_buffer);
+
+static inline int uart_select_port_buffer(uart_config_t config, queue_t *uart_rx_buffer);
+
+static inline int uart_select_port_address(uart_config_t config, uint32_t *uart_address);
+
+int uart_init(uart_config_t config)
+{
+ uint32_t usart;
+ uint32_t baud;
+ uint32_t stopbits;
+ uint32_t parity;
+ uint32_t mode;
+ uint32_t bits;
+ uint32_t flowcontrol;
+
+ switch(config.port)
+ {
+ case UART_PORT_1:
+ usart = USART1_BASE;
+ rcc_periph_clock_enable(RCC_GPIOA);
+ rcc_periph_clock_enable(RCC_USART1);
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
+ break;
+ case UART_PORT_2:
+ usart = USART2_BASE;
+ /* TODO */
+ break;
+ case UART_PORT_3:
+ usart = USART3_BASE;
+ /* TODO */
+ break;
+ case UART_PORT_4:
+ usart = UART4_BASE;
+ /* TODO */
+ break;
+ case UART_PORT_5:
+ usart = UART5_BASE;
+ /* TODO */
+ break;
+ default:
+ /* TODO Add error log system */
+ break;
+ }
+
+ baud = (uint32_t)config.baudrate;
+
+ switch(config.stop_bits)
+ {
+ case UART_SB_0_5: stopbits = USART_STOPBITS_0_5; break;
+ case UART_SB_1: stopbits = USART_STOPBITS_1; break;
+ case UART_SB_1_5: stopbits = USART_STOPBITS_1_5; break;
+ case UART_SB_2: stopbits = USART_STOPBITS_2; break;
+ default: break;
+ }
+
+ switch(config.parity)
+ {
+ case UART_NO_PARITY: parity = USART_PARITY_NONE; break;
+ case UART_ODD_PARITY: parity = USART_PARITY_ODD; break;
+ case UART_EVEN_PARITY: parity = USART_PARITY_EVEN; break;
+ default:
+ /* TODO Add error log system. */
+ break;
+ }
+
+ switch(config.mode)
+ {
+ case UART_MODE_TX: mode = USART_MODE_TX; break;
+ case UART_MODE_RX: mode = USART_MODE_RX; break;
+ case UART_MODE_TX_RX: mode = USART_MODE_TX_RX; break;
+ default:
+ /* TODO Add error log system. */
+ break;
+ }
+
+ switch(config.word_length)
+ {
+ case UART_WL_8: bits = 8; break;
+ case UART_WL_9: bits = 9; break;
+ default:
+ /* TODO Add error log system. */
+ break;
+ }
+
+ switch(config.flow_control)
+ {
+ case UART_FC_NONE: flowcontrol = USART_FLOWCONTROL_NONE; break;
+ case UART_FC_RTS: flowcontrol = USART_FLOWCONTROL_RTS; break;
+ case UART_FC_CTS: flowcontrol = USART_FLOWCONTROL_CTS; break;
+ case UART_FC_RTS_CTS: flowcontrol = USART_FLOWCONTROL_RTS_CTS; break;
+ default:
+ /* TODO Add error log system. */
+ break;
+ }
+
+ /* Setup UART parameters. */
+ usart_set_baudrate(usart, baud);
+ usart_set_databits(usart, bits);
+ usart_set_stopbits(usart, stopbits);
+ usart_set_mode(usart, mode);
+ usart_set_parity(usart, parity);
+ usart_set_flow_control(usart, flowcontrol);
+
+ /* Enable UART. */
+ usart_enable(usart);
+
+ return 0;
+}
+
+int uart_write(uart_config_t config, uint16_t *data, uint16_t len)
+{
+ int err = ERRNO_SUCCESS;
+
+ uint16_t i = 0U;
+ for(i = 0U; i < len; i++)
+ {
+ err = uart_send_byte(config, data[i]);
+ }
+
+ return err;
+}
+
+int uart_read(uart_config_t config, uint16_t *data, uint16_t len)
+{
+ int err = ERRNO_SUCCESS;
+ uint16_t num_bytes = len;
+ uint16_t i = 0U;
+ queue_t *uart_rx_buffer;
+
+ err = uart_select_port_buffer(config, uart_rx_buffer);
+
+ if (err == ERRNO_SUCCESS)
+ {
+ /* Check if read size isn't bigger than mtu */
+ if (num_bytes > uart_read_mtu(uart_rx_buffer))
+ {
+ num_bytes = uart_read_mtu(uart_rx_buffer);
+ }
+
+ for(i = 0U; i < num_bytes; i++)
+ {
+ data[i] = queue_pop_front(uart_rx_buffer);
+ }
+ }
+
+ return err;
+}
+
+int uart_rx_enable(uart_config_t config)
+{
+ int err = -1;
+ uint32_t usart;
+
+ err = uart_select_port_address(config, &usart);
+ usart_enable_rx_interrupt(usart);
+
+ return err;
+}
+
+int uart_rx_disable(uart_config_t config)
+{
+ int err = -1;
+ uint32_t usart = UINT32_MAX;
+
+ err = uart_select_port_address(config, &usart);
+ usart_disable_rx_interrupt(usart);
+
+ return err;
+}
+
+uint16_t uart_read_available(uart_config_t config)
+{
+ uint16_t available_bytes = 0U;
+ queue_t *uart_rx_buffer;
+
+ if (uart_select_port_buffer(config, uart_rx_buffer) == ERRNO_SUCCESS)
+ {
+ available_bytes = queue_size(uart_rx_buffer);
+ }
+
+ return available_bytes;
+}
+
+int uart_flush(uart_config_t config)
+{
+ int err = ERRNO_SUCCESS;
+
+ queue_t *uart_rx_buffer;
+
+ if (uart_select_port_buffer(config, uart_rx_buffer) == ERRNO_SUCCESS)
+ {
+ queue_clear(uart_rx_buffer);
+ }
+ else
+ {
+ err = -1;
+ }
+
+ return err;
+}
+
+static inline int uart_send_byte(uart_config_t config, uint16_t c)
+{
+ int err = ERRNO_SUCCESS;
+
+ uint32_t usart;
+
+ if (uart_select_port_address(config, &usart) == ERRNO_SUCCESS)
+ {
+ usart_send_blocking(usart, c);
+ }
+ else
+ {
+ err = -1;
+ }
+
+ return err;
+}
+
+static inline int uart_read_byte(uart_config_t config, uint16_t *c)
+{
+ int err;
+
+ uint32_t usart;
+
+ err = uart_select_port_address(config, &usart);
+
+ if (err = ERRNO_SUCCESS)
+ {
+ *c = usart_recv_blocking(usart);
+ }
+
+ return err;
+}
+
+static inline uint16_t uart_read_mtu(queue_t *uart_rx_buffer)
+{
+ return queue_length(uart_rx_buffer);
+}
+
+static inline int uart_select_port_buffer(uart_config_t config, queue_t *uart_rx_buffer)
+{
+ int err = ERRNO_SUCCESS;
+
+ switch(config.port)
+ {
+ case UART_PORT_1: uart_rx_buffer = &uart_port_1_rx_buffer; break;
+ case UART_PORT_2: uart_rx_buffer = &uart_port_2_rx_buffer; break;
+ case UART_PORT_3: uart_rx_buffer = &uart_port_3_rx_buffer; break;
+ case UART_PORT_4: uart_rx_buffer = &uart_port_4_rx_buffer; break;
+ case UART_PORT_5: uart_rx_buffer = &uart_port_5_rx_buffer; break;
+ default:
+ err = ERRNO_DRIVER_NO_PORT;
+ /* Add error log system */
+ break;
+ }
+
+ return err;
+}
+
+static inline int uart_select_port_address(uart_config_t config, uint32_t *usart)
+{
+ int err = ERRNO_SUCCESS;
+
+ switch(config.port)
+ {
+ case UART_PORT_1: *usart = USART1_BASE; break;
+ case UART_PORT_2: *usart = USART2_BASE; break;
+ case UART_PORT_3: *usart = USART3_BASE; break;
+ case UART_PORT_4: *usart = UART4_BASE; break;
+ case UART_PORT_5: *usart = UART5_BASE; break;
+ default:
+ err = ERRNO_DRIVER_NO_PORT;
+ /* Add error log system */
+ break;
+ }
+}
+
+/** \} End of uart group */
diff --git a/firmware/drivers/uart/uart.h b/firmware/drivers/uart/uart.h
new file mode 100644
index 0000000..c679f83
--- /dev/null
+++ b/firmware/drivers/uart/uart.h
@@ -0,0 +1,199 @@
+/*
+ * uart.h
+ *
+ * Copyright The SLCam Contributors.
+ *
+ * This file is part of SLCam.
+ *
+ * SLCam is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SLCam is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with SLCam. If not, see .
+ *
+ */
+
+/**
+ * \brief UART driver definition.
+ *
+ * \author Miguel Boing
+ * \author Gabriel Mariano Marcelino
+ *
+ * \version 0.2.1
+ *
+ * \date 2023/02/17
+ *
+ * \defgroup uart UART
+ * \ingroup drivers
+ * \{
+ */
+
+#ifndef UART_H_
+#define UART_H_
+
+#include
+
+/**
+ * \brief UART ports.
+ */
+typedef enum
+{
+ UART_PORT_1=0, /**< UART port 1. */
+ UART_PORT_2, /**< UART port 2. */
+ UART_PORT_3, /**< UART port 3. */
+ UART_PORT_4, /**< UART port 4. */
+ UART_PORT_5 /**< UART port 5. */
+} uart_port_t;
+
+/**
+ * \brief UART modes.
+ */
+typedef enum
+{
+ UART_MODE_TX=0, /**< TX mode. */
+ UART_MODE_RX, /**< RX mode. */
+ UART_MODE_TX_RX /**< TX/RX mode. */
+} uart_mode_t;
+
+/**
+ * \brief Parity configuration.
+ */
+typedef enum
+{
+ UART_NO_PARITY=0, /**< No parity. */
+ UART_ODD_PARITY, /**< Odd parity. */
+ UART_EVEN_PARITY /**< Even parity. */
+} uart_parity_t;
+
+/**
+ * \brief Stop bits configuration.
+ */
+typedef enum
+{
+ UART_SB_0_5=0, /**< 0.5 stop bit. */
+ UART_SB_1, /**< 1 stop bit. */
+ UART_SB_1_5, /**< 1.5 stop bit. */
+ UART_SB_2 /**< 2 stop bits. */
+} uart_sb_t;
+
+/**
+ * \brief Word length configuration.
+ */
+typedef enum
+{
+ UART_WL_8=0, /**< 8-bits. */
+ UART_WL_9 /**< 9-bits. */
+} uart_wl_t;
+
+
+/**
+ * \brief Hardware Flow Control.
+ */
+typedef enum
+{
+ UART_FC_NONE=0, /**< No flow control. */
+ UART_FC_RTS, /**< RTS. */
+ UART_FC_CTS, /**< CTS. */
+ UART_FC_RTS_CTS /**< RTS and CTS. */
+} uart_fc_t;
+
+/**
+ * \brief Baud rate configuration.
+ */
+typedef uint32_t uart_br_t;
+
+/**
+ * \brief Configuration structure.
+ */
+typedef struct
+{
+ uart_port_t port; /**< Port. */
+ uart_mode_t mode; /**< Mode. */
+ uart_parity_t parity; /**< Parity. */
+ uart_sb_t stop_bits; /**< Stop bits. */
+ uart_wl_t word_length; /**< Word lenght. */
+ uart_fc_t flow_control; /**< Flow control. */
+ uart_br_t baudrate; /**< Baudrate in bits per second. */
+} uart_config_t;
+
+/**
+ * \brief Initializes a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \return The status/error code.
+ */
+int uart_init(uart_config_t config);
+
+/**
+ * \brief Writes data to a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \param[in] data is the array of bytes to be written.
+ *
+ * \param[in] len is the number of bytes to be written.
+ *
+ * \return The status/error code.
+ */
+int uart_write(uart_config_t config, uint16_t *data, uint16_t len);
+
+/**
+ * \brief Reads data from a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \param[in,out] data is a pointer to store the read data.
+ *
+ * \param[in] len is the number of bytes to read.
+ *
+ * \return The status/error code.
+ */
+int uart_read(uart_config_t config, uint16_t *data, uint16_t len);
+
+/**
+ * \brief Enables the RX of a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \return The status/error code.
+ */
+int uart_rx_enable(uart_config_t config);
+
+/**
+ * \brief Disables the RX of a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \return The status/error code.
+ */
+int uart_rx_disable(uart_config_t config);
+
+/**
+ * \brief Checks if there is available data to read from a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \return The status/error code.
+ */
+uint16_t uart_read_available(uart_config_t config);
+
+/**
+ * \brief Flushes the RX buffer of a given UART port.
+ *
+ * \param[in] config are the configuration parameters of the given UART port.
+ *
+ * \return The status/error code.
+ */
+int uart_flush(uart_config_t config);
+
+#endif /* UART_H_ */
+
+/** \} End of uart group */
diff --git a/firmware/libs/Makefile b/firmware/libs/Makefile
new file mode 100644
index 0000000..c3c38ff
--- /dev/null
+++ b/firmware/libs/Makefile
@@ -0,0 +1,11 @@
+ifndef BUILD_DIR
+ BUILD_DIR=$(CURDIR)
+endif
+
+.PHONY: all
+all:
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C containers
+
+.PHONY: clean
+clean:
+ rm $(BUILD_DIR)/*.o
diff --git a/firmware/libs/containers/Makefile b/firmware/libs/containers/Makefile
new file mode 100644
index 0000000..60727c2
--- /dev/null
+++ b/firmware/libs/containers/Makefile
@@ -0,0 +1,33 @@
+TARGET=containers
+
+ifndef BUILD_DIR
+ BUILD_DIR=$(CURDIR)
+endif
+
+PARTNUMBER=stm32f103c8t6
+
+CC=arm-none-eabi-gcc
+AS=arm-none-eabi-as
+LD=arm-none-eabi-ld
+OBJCOPY=arm-none-eabi-objcopy
+OBJDUMP=arm-none-eabi-objdump
+READELF=arm-none-eabi-readelf
+NM=arm-none-eabi-nm
+SIZE=arm-none-eabi-size
+GDB=arm-none-eabi-gdb
+
+CFLAGS=-c -mcpu=cortex-m3 -mthumb -O0
+
+.PHONY: all
+all: queue buffer
+
+queue: queue.c
+ $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@.o
+
+buffer: buffer.c
+ $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@.o
+
+.PHONY: clean
+
+clean:
+ rm $(BUILD_DIR)/*.o
diff --git a/firmware/libs/containers/README.md b/firmware/libs/containers/README.md
new file mode 100644
index 0000000..136ce1a
--- /dev/null
+++ b/firmware/libs/containers/README.md
@@ -0,0 +1,6 @@
+# Data containers library
+
+Supported containers:
+
+* Buffer
+* Queue
diff --git a/firmware/libs/containers/buffer.c b/firmware/libs/containers/buffer.c
new file mode 100644
index 0000000..37213a3
--- /dev/null
+++ b/firmware/libs/containers/buffer.c
@@ -0,0 +1,132 @@
+/*
+ * buffer.c
+ *
+ * Copyright The TTC 2.0 Contributors.
+ *
+ * This file is part of TTC 2.0.
+ *
+ * TTC 2.0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * TTC 2.0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TTC 2.0. If not, see .
+ *
+ */
+
+/**
+ * \brief Buffer implementation.
+ *
+ * \author Gabriel Mariano Marcelino
+ *
+ * \version 0.1.14
+ *
+ * \date 2017/11/09
+ *
+ * \addtogroup buffer
+ * \{
+ */
+
+#include "buffer.h"
+
+void buffer_init(buffer_t *buffer)
+{
+ buffer->mtu = BUFFER_LENGTH;
+
+ buffer_clear(buffer);
+}
+
+uint16_t buffer_length(buffer_t *buffer)
+{
+ return buffer->mtu;
+}
+
+bool buffer_fill(buffer_t *buffer, uint8_t *data, uint16_t len)
+{
+ bool res = false;
+
+ if (len <= buffer_length(buffer))
+ {
+ buffer_clear(buffer);
+
+ uint16_t i = 0;
+ for(i = 0; i < len; i++)
+ {
+ buffer->data[i] = data[i];
+ }
+
+ buffer->size = len;
+
+ res = true;
+ }
+
+ return res;
+}
+
+bool buffer_append(buffer_t *buffer, uint8_t *data, uint16_t len)
+{
+ bool res = false;
+
+ if ((buffer->size + len) <= buffer_length(buffer))
+ {
+ uint16_t i = 0U;
+ for(i = 0U; i < len; i++)
+ {
+ buffer->data[buffer->size + i] = data[i];
+ }
+
+ buffer->size += len;
+
+ res = true;
+ }
+
+ return res;
+}
+
+void buffer_clear(buffer_t *buffer)
+{
+ uint16_t i = 0U;
+ for(i = 0U; i < buffer_length(buffer); i++)
+ {
+ buffer->data[i] = BUFFER_DEFAULT_BYTE;
+ }
+
+ buffer->size = 0U;
+}
+
+bool buffer_empty(buffer_t *buffer)
+{
+ bool res = false;
+
+ if (buffer_size(buffer) == 0U)
+ {
+ res = true;
+ }
+
+ return res;
+}
+
+bool buffer_full(buffer_t *buffer)
+{
+ bool res = false;
+
+ if (buffer_size(buffer) == buffer_length(buffer))
+ {
+ res = true;
+ }
+
+ return res;
+}
+
+uint16_t buffer_size(buffer_t *buffer)
+{
+ return buffer->size;
+}
+
+/**< \} End of buffer group */
diff --git a/firmware/libs/containers/buffer.h b/firmware/libs/containers/buffer.h
new file mode 100644
index 0000000..b1901bf
--- /dev/null
+++ b/firmware/libs/containers/buffer.h
@@ -0,0 +1,139 @@
+/*
+ * buffer.h
+ *
+ * Copyright The TTC 2.0 Contributors.
+ *
+ * This file is part of TTC 2.0.
+ *
+ * TTC 2.0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * TTC 2.0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TTC 2.0. If not, see .
+ *
+ */
+
+/**
+ * \brief Buffer definition.
+ *
+ * \author Gabriel Mariano Marcelino
+ *
+ * \version 0.1.14
+ *
+ * \date 2017/11/09
+ *
+ * \defgroup buffer Buffer
+ * \ingroup containers
+ * \{
+ */
+
+#ifndef BUFFER_H_
+#define BUFFER_H_
+
+#include
+#include
+
+#define BUFFER_LENGTH 300U /**< Buffer length in bytes. */
+
+#define BUFFER_DEFAULT_BYTE 0xFFU /**< Buffer length in bytes. */
+
+/**
+ * \brief Buffer implementation as a struct.
+ */
+typedef struct
+{
+ uint8_t data[BUFFER_LENGTH]; /**< Data of the buffer. */
+ uint16_t size; /**< Number of elements into the buffer. */
+ uint16_t mtu; /**< Maximum transmission unit. */
+} buffer_t;
+
+/**
+ * \brief Buffer initialization.
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \return None.
+ */
+void buffer_init(buffer_t *buffer);
+
+/**
+ * \brief Returns the length (capacity) of a buffer.
+ *
+ * \param buffer is a pointer to a Buffer struct.
+ *
+ * \return The length of the buffer (or capacity).
+ */
+uint16_t buffer_length(buffer_t *buffer);
+
+/**
+ * \brief Fills the buffer with data.
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \param[in,out] data is a pointer to an array with the data to store in the buffer.
+ *
+ * \param[in] len is the length of data.
+ *
+ * \return True/False if the length of the data fits into the buffer.
+ */
+bool buffer_fill(buffer_t *buffer, uint8_t *data, uint16_t len);
+
+/**
+ * \brief Append data to a buffer.
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \param[in,out] data is a pointer to an array with the data to append in the buffer.
+ *
+ * \param[in] len is the length of data.
+ *
+ * \return True/False if the length of the data fits into the buffer.
+ */
+bool buffer_append(buffer_t *buffer, uint8_t *data, uint16_t len);
+
+/**
+ * \brief Clear a buffer filling it with the dafult byte (\b BUFFER_DEFAULT_BYTE).
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \return None
+ */
+void buffer_clear(buffer_t *buffer);
+
+/**
+ * \brief Verifies if the a buffer is empty or not.
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \return True/False if the buffer is empty or not.
+ */
+bool buffer_empty(buffer_t *buffer);
+
+/**
+ * \brief Verifies if the a buffer is full or not.
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \return True/False if the buffer is full or not.
+ */
+bool buffer_full(buffer_t *buffer);
+
+/**
+ * \brief Returns the size of a buffer.
+ *
+ * \param[in,out] buffer is a pointer to a Buffer struct.
+ *
+ * \return The size of the buffer.
+ */
+uint16_t buffer_size(buffer_t *buffer);
+
+#endif /* BUFFER_H_ */
+
+/**< \} End of buffer group */
diff --git a/firmware/libs/containers/queue.c b/firmware/libs/containers/queue.c
new file mode 100644
index 0000000..7892c89
--- /dev/null
+++ b/firmware/libs/containers/queue.c
@@ -0,0 +1,138 @@
+/*
+ * queue.c
+ *
+ * Copyright The TTC 2.0 Contributors.
+ *
+ * This file is part of TTC 2.0.
+ *
+ * TTC 2.0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * TTC 2.0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TTC 2.0. If not, see .
+ *
+ */
+
+/**
+ * \brief Queue implementation.
+ *
+ * \author Gabriel Mariano Marcelino
+ * \author Miguel Boing
+ *
+ * \version 0.1.16
+ *
+ * \date 2017/11/08
+ *
+ * \addtogroup queue
+ * \{
+ */
+
+#include "queue.h"
+
+void queue_init(queue_t *queue)
+{
+ queue->head = 0U;
+ queue->tail = 0U;
+ queue->size = 0U;
+ queue->mtu = QUEUE_LENGTH;
+
+ uint16_t i = 0U;
+ for(i = 0U; i < queue_length(queue); i++)
+ {
+ queue->data[i] = QUEUE_DEFAULT_BYTE;
+ }
+}
+
+uint16_t queue_length(queue_t *queue)
+{
+ return queue->mtu;
+}
+
+bool queue_push_back(queue_t *queue, uint16_t byte)
+{
+ bool res = false;
+
+ if (!queue_full(queue))
+ {
+ queue->data[queue->tail] = byte;
+ queue->tail++;
+ queue->size++;
+
+ if (queue->tail == queue_length(queue))
+ {
+ queue->tail = 0U;
+ }
+
+ res = true;
+ }
+
+ return res;
+}
+
+uint8_t queue_pop_front(queue_t *queue)
+{
+ uint8_t res = 0U;
+
+ if (queue_empty(queue))
+ {
+ res = QUEUE_DEFAULT_BYTE;
+ }
+ else
+ {
+ uint8_t byte = queue->data[queue->head];
+ queue->head++;
+
+ if (queue->head == queue_length(queue))
+ {
+ queue->head = 0U;
+ }
+
+ res = byte;
+ queue->size--;
+ }
+
+ return res;
+}
+
+bool queue_empty(queue_t *queue)
+{
+ bool res = false;
+
+ if (queue->head == queue->tail)
+ {
+ res = true;
+ }
+
+ return res;
+}
+
+bool queue_full(queue_t *queue)
+{
+ bool res = false;
+
+ if (((queue->tail + 1U) == queue->head) || (((queue->tail + 1U) == queue_length(queue)) && (queue->head == 0U)))
+ {
+ res = true;
+ }
+
+ return res;
+}
+
+uint16_t queue_size(queue_t *queue)
+{
+ return queue->size;
+}
+
+void queue_clear(queue_t *queue)
+{
+ queue_init(queue);
+}
+
+/**< \} End of queue group */
diff --git a/firmware/libs/containers/queue.h b/firmware/libs/containers/queue.h
new file mode 100644
index 0000000..62c2ec4
--- /dev/null
+++ b/firmware/libs/containers/queue.h
@@ -0,0 +1,135 @@
+/*
+ * queue.h
+ *
+ * Copyright The TTC 2.0 Contributors.
+ *
+ * This file is part of TTC 2.0.
+ *
+ * TTC 2.0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * TTC 2.0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TTC 2.0. If not, see .
+ *
+ */
+
+/**
+ * \brief Queue definition.
+ *
+ * \author Gabriel Mariano Marcelino
+ *
+ * \version 0.1.16
+ *
+ * \date 2017/11/08
+ *
+ * \defgroup queue Queue
+ * \ingroup containers
+ * \{
+ */
+
+#ifndef QUEUE_H_
+#define QUEUE_H_
+
+#include
+#include
+
+#define QUEUE_LENGTH 300U /**< Queue length in bytes. */
+
+#define QUEUE_DEFAULT_BYTE 0xFFU /**< Queue default byte (empty position). */
+
+/**
+ * \brief Queue representation as a struct.
+ */
+typedef struct
+{
+ uint16_t data[QUEUE_LENGTH]; /**< Data buffer. */
+ uint16_t head; /**< Head position of the data array. */
+ uint16_t tail; /**< Tail position of the data array. */
+ uint16_t size; /**< Length, in bytes, of the data. */
+ uint16_t mtu; /**< Maximum transmission unit. */
+} queue_t;
+
+/**
+ * \brief Queue initialization.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return None.
+ */
+void queue_init(queue_t *queue);
+
+/**
+ * \brief Returns the length (capacity) of a queue.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return The length of the queue (or capacity).
+ */
+uint16_t queue_length(queue_t *queue);
+
+/**
+ * \brief Puts an element into the back position of an queue.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \param[in] byte is the byte to be pushed to the queue.
+ *
+ * \return True/False if the element was pushed or not.
+ */
+bool queue_push_back(queue_t *queue, uint16_t byte);
+
+/**
+ * \brief Grabs an element from the front position of an queue.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return The byte grabbed from the queue.
+ */
+uint8_t queue_pop_front(queue_t *queue);
+
+/**
+ * \brief Verifies if the a queue is empty or not.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return True/False if the queue is empty or not.
+ */
+bool queue_empty(queue_t *queue);
+
+/**
+ * \brief Verifies if the a queue is full or not.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return True/False if the queue is full or not.
+ */
+bool queue_full(queue_t *queue);
+
+/**
+ * \brief Returns the size of a queue.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return The size of the queue.
+ */
+uint16_t queue_size(queue_t *queue);
+
+/**
+ * \brief Resets queue size to zero.
+ *
+ * \param[in,out] queue is a pointer to a queue_t struct.
+ *
+ * \return None.
+ */
+void queue_clear(queue_t *queue);
+
+#endif /* QUEUE_H_ */
+
+/**< \} End of queue group */
diff --git a/firmware/main.cpp b/firmware/main.cpp
deleted file mode 100644
index e474b70..0000000
--- a/firmware/main.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * main.cpp
- *
- * Copyright The SLCam Contributors.
- *
- * This file is part of SLCam.
- *
- * SLCam is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * SLCam is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with SLCam. If not, see .
- *
- */
-
-/**
- * \brief Main file.
- *
- * \author Gabriel Mariano Marcelino
- * \author Miguel Boing
- *
- * \version 0.1.3
- *
- * \date 2022/07/10
- *
- * \defgroup main Main file
- * \{
- */
-
-#include
-#include
-
-int main(void)
-{
- rcc_periph_clock_enable(RCC_GPIOC);
-
- gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
-
- while(1)
- {
- for (int i = 0; i < 1000000; i++)
- {
- __asm__("nop");
- }
-
- gpio_toggle(GPIOC, GPIO13);
- }
-
- return 0;
-}
-
-/** \} End of main group */
diff --git a/firmware/version.h b/firmware/version.h
index 9739df7..e64149b 100644
--- a/firmware/version.h
+++ b/firmware/version.h
@@ -25,7 +25,7 @@
*
* \author Gabriel Mariano Marcelino
*
- * \version 0.2.0
+ * \version 0.2.1
*
* \date 2022/07/10
*
@@ -36,7 +36,7 @@
#ifndef VERSION_H_
#define VERSION_H_
-#define FIRMWARE_VERSION "0.2.0"
+#define FIRMWARE_VERSION "0.2.1"
#define FIRMWARE_STATUS "Development"