From 03e1a7c19d10d98099fab6293fec4f3d4da8224c Mon Sep 17 00:00:00 2001 From: hugo LAMY Date: Sun, 9 Mar 2025 02:34:11 +0100 Subject: [PATCH] bonus almost working --- .vscode/settings.json | 3 +- module02/ex01/main.c | 2 +- module02/ex03/main.c | 2 +- module02/ex04/main.c | 132 ++++++++++++++++++++++++++++++++++++++++-- module02/ex04/utils.h | 4 ++ 5 files changed, 136 insertions(+), 7 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 01550e4..3f07dc7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "interrupt.h": "c", "timer.h": "c", "usart.h": "c", - "utils.h": "c" + "utils.h": "c", + "bitmanip.h": "c" } } diff --git a/module02/ex01/main.c b/module02/ex01/main.c index 54ca8b1..ef83fbb 100644 --- a/module02/ex01/main.c +++ b/module02/ex01/main.c @@ -18,7 +18,7 @@ // END MACROS void uart_init() { - UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format diff --git a/module02/ex03/main.c b/module02/ex03/main.c index 64d9b0c..d99515d 100644 --- a/module02/ex03/main.c +++ b/module02/ex03/main.c @@ -18,7 +18,7 @@ // END MACROS void uart_init() { - UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format diff --git a/module02/ex04/main.c b/module02/ex04/main.c index 41b68c1..bfe8496 100644 --- a/module02/ex04/main.c +++ b/module02/ex04/main.c @@ -13,11 +13,37 @@ // TIMER #define PERIOD 2000 #define PRESCALE_VALUE 1024 // can be 1, 8, 64, 256, 1024 +#define STRLEN_LITERAL(str) (sizeof(str) / sizeof(str[0]) - 1) // -1 to remove the null terminator, only works with string literals, not with pointers // END MACROS +// FUNCTION PROTOTYPES +void uart_init(); +// char uart_rx(void); +void uart_tx(char c); +void uart_printstr(const char* str); +void check_str(char input, volatile char compare_str[], unsigned int length); +void reset_message(); +void ask_for_username(); +void ask_for_password(); +void on_error(); +void on_success(); + +// GLOBAL VARIABLES +typedef enum { + USERNAME, + PASSWORD +} State; +volatile char username[] = "admin"; +volatile char password[] = "password"; +volatile int input_index = 0; +volatile State state = USERNAME; +volatile int input_match = FALSE; +volatile int username_correct = FALSE; +volatile int password_correct = FALSE; + void uart_init() { - UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format @@ -35,22 +61,120 @@ void uart_tx(char c) { UDR0 = (unsigned char) c; // 20.11.1 : Put data into buffer, UDRn – USART I/O Data Register (read and write) } +void uart_printstr(const char* str) { + while (*str) { + uart_tx(*str); + str++; + } +} + ISR(USART_RX_vect) { // Table 12-7 : we select the code for USART Receive // char received_char = uart_rx(); - char received_char = UDR0; // Read received character - if (received_char == '\b' || received_char == 127) { // If backspace is received + char received_char = UDR0; // read received character + if (received_char == '\b' || received_char == 127) { // if backspace is received + if (input_index <= 0) return; + input_index--; uart_tx('\b'); // Move cursor back uart_tx(' '); // Erase the character on screen uart_tx('\b'); // Move cursor back again + } else if (received_char == '\n' || received_char == '\r') { // if enter is received + if (state == USERNAME) { + if (input_index == STRLEN_LITERAL(username) && input_match) { + username_correct = TRUE; + } else { + username_correct = FALSE; + uart_printstr("(error1)"); + } + input_match = FALSE; + state = PASSWORD; + input_index = 0; + uart_tx('\r'); // Move cursor to next line + uart_tx('\n'); + ask_for_password(); + } else if (state == PASSWORD) { + if (!username_correct) { + uart_printstr("(error2)"); + return reset_message(); + } + if (input_index != STRLEN_LITERAL(password)) { + uart_printstr("(error3)"); + return reset_message(); + } + if (!input_match) { + uart_printstr("(error4)"); + return reset_message(); + } + uart_tx('\r'); // Move cursor to next line + uart_tx('\n'); + on_success(); + } } else { - uart_tx(SWITCH_CASE(received_char)); // Toggle case and send back + if (state == USERNAME) { + check_str(received_char, username, STRLEN_LITERAL(username)); + uart_tx(received_char); + } + else if (state == PASSWORD) { + check_str(received_char, password, STRLEN_LITERAL(password)); + uart_tx('*'); + } + input_index++; } } +void check_str(char input, volatile char compare_str[], unsigned int length) { + if (input_index >= length) { // index has not already been incremented, so we need to compare greater or equal + uart_printstr("(error5)"); + input_match = FALSE; + return; + } + if (input != compare_str[input_index]) { + uart_printstr("(error6)"); + input_match = FALSE; + return; + } + // if we reach this point, the input character matches the compare_str character + if (input_index == 0) { + input_match = TRUE; + return; + } + // if we reach this point, the input character is not the first character of the compare_str + if (input_match == FALSE) { + // if any previous character did not match, we don't need to check the next character + uart_printstr("(error7)"); + return; + } + input_match = TRUE; +} + +void reset_message() { + input_index = 0; + input_match = FALSE; + username_correct = FALSE; + password_correct = FALSE; + state = USERNAME; + uart_tx('\r'); // Move cursor to next line + uart_tx('\n'); + on_error(); + ask_for_username(); +} +void ask_for_username() { + uart_printstr("Enter your login: \r\n username: "); +} +void ask_for_password() { + uart_printstr(" password: "); +} +void on_error() { + uart_printstr("Bad combinaison username/password\r\n\r\n"); +} +void on_success() { + uart_printstr("Hello spectre!\r\nShall we play a game?\r\n"); +} + // ask for username and password // `screen /dev/ttyUSB0 115200` int main() { uart_init(); + ask_for_username(); SREG |= ENABLE_GLOBAL_INTERRUPT; // 7.3.1 : Status Register, bit 7 : I – Global Interrupt Enable diff --git a/module02/ex04/utils.h b/module02/ex04/utils.h index 800e807..1dfefcb 100644 --- a/module02/ex04/utils.h +++ b/module02/ex04/utils.h @@ -16,4 +16,8 @@ // text #define SWITCH_CASE(ch) (((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) +// boolean +#define TRUE 1 +#define FALSE 0 + #endif // UTILS_H \ No newline at end of file