diff --git a/.clang-format b/.clang-format index beb2561..fd608c9 100644 --- a/.clang-format +++ b/.clang-format @@ -1,57 +1 @@ -BasedOnStyle: Chromium -AccessModifierOffset: 0 -AlignConsecutiveAssignments: - Enabled: true - AcrossEmptyLines: true - AcrossComments: true - AlignCompound: true - AlignFunctionPointers: true - PadOperators: false -AlignConsecutiveBitFields: - Enabled: true - AcrossEmptyLines: true - AcrossComments: true - AlignCompound: true - AlignFunctionPointers: true - PadOperators: true -AlignConsecutiveDeclarations: - Enabled: true - AcrossComments: true - AlignCompound: true - AlignFunctionPointers: true - PadOperators: true -AlignConsecutiveMacros: - Enabled: true - AcrossEmptyLines: true - AcrossComments: true - AlignCompound: true - AlignFunctionPointers: true - PadOperators: true -AlignConsecutiveShortCaseStatements: - Enabled: true - AcrossEmptyLines: true - AcrossComments: true - AlignCaseArrows: true - AlignCaseColons: true -ColumnLimit: 100 -NamespaceIndentation: All -CommentPragmas: "" -IncludeCategories: - - Regex: ^<.*\.h> - Priority: 1 - SortPriority: 0 - CaseSensitive: false - - Regex: ^<.* - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: .* - Priority: 3 - SortPriority: 0 - CaseSensitive: false -IndentPPDirectives: AfterHash -IndentWidth: 4 -TabWidth: 4 -UseTab: Always -Language: Cpp -IndentAccessModifiers: true +git@vogsphere.42paris.fr:vogsphere/intra-uuid-daecd842-c910-4973-b9ff-efcdd4424883-7368496-macaruan diff --git a/ex04/.clang-format b/ex04/.clang-format new file mode 100644 index 0000000..beb2561 --- /dev/null +++ b/ex04/.clang-format @@ -0,0 +1,57 @@ +BasedOnStyle: Chromium +AccessModifierOffset: 0 +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCompound: true + AlignFunctionPointers: true + PadOperators: false +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCompound: true + AlignFunctionPointers: true + PadOperators: true +AlignConsecutiveDeclarations: + Enabled: true + AcrossComments: true + AlignCompound: true + AlignFunctionPointers: true + PadOperators: true +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCompound: true + AlignFunctionPointers: true + PadOperators: true +AlignConsecutiveShortCaseStatements: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCaseArrows: true + AlignCaseColons: true +ColumnLimit: 100 +NamespaceIndentation: All +CommentPragmas: "" +IncludeCategories: + - Regex: ^<.*\.h> + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: ^<.* + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: .* + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IndentPPDirectives: AfterHash +IndentWidth: 4 +TabWidth: 4 +UseTab: Always +Language: Cpp +IndentAccessModifiers: true diff --git a/ex04/.gitignore b/ex04/.gitignore new file mode 100644 index 0000000..3efd3b1 --- /dev/null +++ b/ex04/.gitignore @@ -0,0 +1,8 @@ +*.o +*.hex +*.bin +*.elf +build/ +/avr-libc +compile_commands.json +.cache/ diff --git a/ex04/Makefile b/ex04/Makefile new file mode 100644 index 0000000..add8cae --- /dev/null +++ b/ex04/Makefile @@ -0,0 +1,55 @@ +# Makefile +MCU=atmega328p +F_CPU=16000000 +CC=avr-gcc +OBJCOPY=avr-objcopy +CFLAGS=-std=c99 -Wall -Wextra -g -Os -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Iinclude +IFLAGS= +TARGET=main +SERIAL=-P /dev/ttyUSB0 -b 115200 + + +SRC_DIR=src +OBJ_DIR=build + +SRC_FILES=main.c utils.c uart.c timer.c +OBJ_FILES=$(patsubst %.c,%.o,$(SRC_FILES)) + +SRC=$(addprefix $(SRC_DIR)/,$(SRC_FILES)) +OBJ=$(addprefix $(OBJ_DIR)/,$(OBJ_FILES)) + +ELF_FILE=$(OBJ_DIR)/$(TARGET).elf +HEX_FILE=$(OBJ_DIR)/$(TARGET).hex + +all: flash + +re: fclean all + +fclean: clean + rm -f $(HEX_FILE) + rm -f $(ELF_FILE) +clean: + rm -rf $(OBJ_DIR) + +hex: $(HEX_FILE) + +flash: hex + avrdude -p $(MCU) -c arduino -U flash:w:$(HEX_FILE):i $(SERIAL) + + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c + @mkdir -p $(shell dirname $@) + $(CC) $(CFLAGS) $(IFLAGS) -c $< -o $@ + +$(ELF_FILE): $(OBJ) + $(CC) $(CFLAGS) $(OBJ) -o $@ + +$(HEX_FILE): $(ELF_FILE) + $(OBJCOPY) -j .text -j .data -O ihex $< $@ + +print: + @echo $(SRC) + @echo $(OBJ) + @echo $(ELF_FILE) + @echo $(HEX_FILE) + diff --git a/ex04/include/mystd.h b/ex04/include/mystd.h new file mode 100644 index 0000000..5d880c5 --- /dev/null +++ b/ex04/include/mystd.h @@ -0,0 +1,15 @@ +#ifndef MYSTDINT_H +#define MYSTDINT_H + +typedef unsigned int uint16_t; +typedef signed int int16_t; + +typedef unsigned char uint8_t; +typedef signed char int8_t; + +typedef uint8_t bool; + +#define true (1) +#define false (0) + +#endif /* MYSTDINT_H */ diff --git a/ex04/include/timer.h b/ex04/include/timer.h new file mode 100644 index 0000000..9d97cd8 --- /dev/null +++ b/ex04/include/timer.h @@ -0,0 +1,8 @@ +#ifndef TIMER_H +#define TIMER_H + +#include "mystd.h" + +void timer1_init(void); + +#endif /* TIMER_H */ diff --git a/ex04/include/uart.h b/ex04/include/uart.h new file mode 100644 index 0000000..3462a54 --- /dev/null +++ b/ex04/include/uart.h @@ -0,0 +1,14 @@ +#ifndef UART_H +#define UART_H + +#include "mystd.h" + +void uart_init(void); + +void uart_tx(char data); +void uart_sendstring(const char* str); +void uart_send_u8(uint8_t val); + +char uart_rx(void); + +#endif /* UART_H */ diff --git a/ex04/include/utils.h b/ex04/include/utils.h new file mode 100644 index 0000000..23acca7 --- /dev/null +++ b/ex04/include/utils.h @@ -0,0 +1,11 @@ +#ifndef UTILS_H +#define UTILS_H + +#include "mystd.h" +#include "utils.h" + +void delay_ms(uint16_t count); + +void ft_bzero(void *data, uint16_t size); + +#endif /* UTILS_H */ diff --git a/ex04/src/main.c b/ex04/src/main.c new file mode 100644 index 0000000..a8b6967 --- /dev/null +++ b/ex04/src/main.c @@ -0,0 +1,105 @@ +#include +#include + +#include "mystd.h" +#include "timer.h" +#include "uart.h" +#include "utils.h" + +#define BUFFERSIZE 20 + +enum State { + ASK_USERNAME, + ASK_PASSWORD, + + ASKING_USERNAME, + ASKING_PASSWORD, + + VERIFY_USERNAME, + VERIFY_PASSWORD, + + VALID_PASSWORD, + INVALID_PASSWORD, + + OVERFLOW_INPUT, +}; + +int main(void) { + uart_init(); + // enable the S_REG + // SREG |= _BV(SREG_I); + char buffer[BUFFERSIZE] = {}; + uint8_t cursor = 0; + enum State state = ASK_USERNAME; + while (true) { + switch (state) { + case ASK_USERNAME: { + uart_sendstring("\r\nUsername: "); + state = ASKING_USERNAME; + cursor = 0; + ft_bzero(&buffer, sizeof(buffer)); + break; + } + case ASK_PASSWORD: { + break; + } + + case OVERFLOW_INPUT: { + uart_sendstring("\r\n/!\\OVERFLOW DETECTED /!\\\r\n/!\\RESETING/!\\\r\n"); + ft_bzero(&buffer, sizeof(buffer)); + cursor = 0; + state = ASK_USERNAME; + break; + } + + case ASKING_USERNAME: { + char data = uart_rx(); + if (data == '\r') { + state = VERIFY_USERNAME; + uart_sendstring("\r\n"); + continue; + } + if (data == '\x7F') { + if (cursor) { + uart_sendstring("\b \b"); + cursor--; + } + continue; + } + uart_tx(data); + + if (cursor + 1 >= BUFFERSIZE) { + state = OVERFLOW_INPUT; + continue; + } + + buffer[cursor++] = data; + break; + } + + case ASKING_PASSWORD: { + break; + } + + case VERIFY_USERNAME: { + uart_sendstring("\r\n"); + uart_sendstring(buffer); + cursor = 0; + ft_bzero(buffer, sizeof(buffer)); + state = ASK_USERNAME; + break; + } + case VERIFY_PASSWORD: { + break; + } + + case VALID_PASSWORD: { + break; + } + + case INVALID_PASSWORD: { + break; + } + } + } +} diff --git a/ex04/src/timer.c b/ex04/src/timer.c new file mode 100644 index 0000000..bc35f18 --- /dev/null +++ b/ex04/src/timer.c @@ -0,0 +1,38 @@ + +#include +#include +#include "mystd.h" +#include "utils.h" + +#define PRESCALER 256 +#define TIMER_FREQ (F_CPU / PRESCALER) + +// at a high level: +// Set the OC1B (PB2) pin as output +// set the TIMER1 mode to COMPARE (CTC) +// say to compare against OC1A +// set the value to be compated at X count +// say the presacler for the timer is 512 +// +// all these information are on page ~140 +void timer1_init(void) { + // Set PB1 (OC1A) as output + DDRB |= _BV(PB1); + + // CTC mode (WGM12 = 1) + TCCR1B |= _BV(WGM12); + + // Toggle OC1B on compare match (COM1B0 = 1) + // TCCR1A |= _BV(COM1A0); + + // Set compare values + OCR1A = TIMER_FREQ / 2; + + // Start timer with prescaler 256 (CS12) + TCCR1B |= _BV(CS12); + + // set OCR1A interrupt + TIMSK1 = _BV(1); + + sei(); +} diff --git a/ex04/src/uart.c b/ex04/src/uart.c new file mode 100644 index 0000000..98ba2eb --- /dev/null +++ b/ex04/src/uart.c @@ -0,0 +1,63 @@ +#include "uart.h" +#include +#include "mystd.h" +#include "utils.h" + +#define BAUD_RATE 115200 + +#define UBRR_VALUE ((F_CPU / (8UL * BAUD_RATE)) - 1) + +// uart is 115200 baud rate, 8 bits per word, no parrity and 1 stop bit +// 115200 8N1 +void uart_init(void) { + // Set baud rate + UBRR0H = (uint8_t)(UBRR_VALUE >> 8); + UBRR0L = (uint8_t)(UBRR_VALUE); + + UCSR0A |= _BV(U2X0); + // Enable transmitter + UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); + + // Set frame format: 8 data bits, no parity, 1 stop bit + UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); + + // Set TX (PD1) as output + DDRD |= _BV(PD1); +} + +void uart_tx(char data) { + // wait for transmit buffer to be empty + while (!(UCSR0A & _BV(UDRE0))) + ; + // load data into transmit register + UDR0 = data; +} + +char uart_rx(void) { + while (!(UCSR0A & _BV(RXC0))) + ; + return UDR0; +} + +void uart_sendstring(const char* str) { + if (!str) + return; + while (*str) { + uart_tx(*str); + str++; + } +} + +void uart_send_u8(uint8_t val) { + char buf[4] = {0, 0, 0, 0}; + buf[0] = '0' + val / 100; + val %= 100; + buf[1] = '0' + val / 10; + buf[2] = '0' + val % 10; + if (buf[0] != '0') + uart_sendstring(&buf[0]); + else if (buf[1] != '0') + uart_sendstring(&buf[1]); + else if (buf[2] != '0') + uart_sendstring(&buf[2]); +} diff --git a/ex04/src/utils.c b/ex04/src/utils.c new file mode 100644 index 0000000..25b0d93 --- /dev/null +++ b/ex04/src/utils.c @@ -0,0 +1,28 @@ +#include "utils.h" + +// this just burns cycles. +// the volatile is important, it means that the cpu can't optimize any +// read/writes for the value +static inline void spin_loop(volatile uint16_t counts) { + while (counts) + counts--; +} + +void delay_ms(uint16_t ms) { + while (ms) { + // this value was taken using a delay of 500ms, and just recording the led + // blinking. it seems to be high enough such that each loop of delay_loop + // takes 1ms :D + spin_loop((F_CPU) / 5000); + ms--; + } +} + +void ft_bzero(void* data, uint16_t size) { + char* d = data; + while (size) { + *d = 0; + d++; + size--; + } +}