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"