diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..639da93 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/client.c b/client.c new file mode 100644 index 0000000..a456c45 --- /dev/null +++ b/client.c @@ -0,0 +1,125 @@ +#include "client.h" + +#include +#include + +#define START_FLAG 0x7E +#define END_FLAG 0x7E + +void init_Client(Client* client, bool test_is_valid, uint8_t address) { + client->TEST_IS_VALID = test_is_valid; + client->address = address; + client->_send_sequence_number = 0; + client->poll_final = 1; + client->_receive_sequence_number = 0; +} + + +void connect(Client* client) { + UFrame u_frame; + init_UFrame(&u_frame, client->address, client->poll_final, "BP", NULL, 0); + + uint8_t result[256]; + create_frame(&u_frame.base, result); + + + // Wait for acknowledgment frame + bool flag = true; + uint8_t data; + while(flag){ + data = uart_read(); + if (data > 0){ + flag = false; + } + } + + HDLCFrame frame; + init_HDLCFrame(&frame, 0, 0, &data + 3, 256 - 6); + if (validate(&data, 256)) { + return; + } else { + // Connection failed + } +} + +void send(Client* client, uint8_t* data, size_t data_length) { + connect(client); + + IFrame i_frame; + init_IFrame(&i_frame, client->address, client->_receive_sequence_number, client->poll_final, client->_send_sequence_number, data, data_length); + + uint8_t result[256]; + create_frame(&i_frame.base, result); + + uart_send_byte(*i_frame.base.data); + + client->_send_sequence_number++; +} + +void receive_data(uint8_t* recivedData) { + bool flag = true; + while(flag){ + *recivedData = uart_read(); + if (recivedData > 0){ + flag = false; + } + } +} + +#include + +bool validate(const uint8_t* frame, size_t length) { + if (length < 4 || frame[0] != START_FLAG || frame[length - 1] != END_FLAG) { + // Invalid frame length or missing start/end flag + return false; + } + + uint16_t received_fcs = (frame[length - 3] << 8) | frame[length - 2]; + uint16_t calculated_fcs = 0xFFFF; + + for (size_t i = 1; i < length - 3; i++) { + uint8_t byte = frame[i]; + calculated_fcs = (calculated_fcs >> 8) ^ (calculated_fcs << 8) ^ byte; + calculated_fcs &= 0xFFFF; + } + + return received_fcs == calculated_fcs; +} + +int sendSerialData(const char* port, uint8_t* data, size_t length) { + int serial_port = open(port, O_RDWR); + + if (serial_port < 0) { + perror("Error opening the serial port"); + return -1; + } + + ssize_t bytes_written = write(serial_port, data, length); + + if (bytes_written < 0) { + perror("Error writing to the serial port"); + return -1; + } + + close(serial_port); + return bytes_written; +} + +int receiveSerialData(const char* port, uint8_t* data, int length) { + int serial_port = open(port, O_RDWR); // Replace "port" with your serial port device + + if (serial_port < 0) { + perror("Error opening the serial port"); + return -1; + } + + ssize_t bytes_read = read(serial_port, data, length); + + if (bytes_read < 0) { + perror("Error reading from the serial port"); + return -1; + } + + close(serial_port); + return bytes_read; +} \ No newline at end of file diff --git a/client.h b/client.h new file mode 100644 index 0000000..0a19d58 --- /dev/null +++ b/client.h @@ -0,0 +1,24 @@ +#ifndef CLIENT_H +#define CLIENT_H + +#include "hdlc_frame.h" +#include "uart_module.h" +#include +#include // Для использования size_t +#include + +typedef struct { + bool TEST_IS_VALID; + uint8_t address; + uint8_t _send_sequence_number; + uint8_t poll_final; + uint8_t _receive_sequence_number; +} Client; + +void init_Client(Client* client, bool test_is_valid, uint8_t address); +void connect(Client* client); +void send(Client* client, uint8_t* data, size_t data_length); +void receive_data(uint8_t* recivedData); +bool validate(const uint8_t* frame, size_t length); + +#endif diff --git a/hdlc_frame.c b/hdlc_frame.c new file mode 100644 index 0000000..e7965c6 --- /dev/null +++ b/hdlc_frame.c @@ -0,0 +1,108 @@ +#include "hdlc_frame.h" + +#include + +#define START_FLAG 0x7E +#define END_FLAG 0x7E +#define ESCAPE_FLAG 0x7D +#define ESCAPE_XOR 0x20 + +void init_HDLCFrame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { + frame->address = address; + frame->control = control; + frame->data = data; + frame->data_length = data_length; +} + +uint16_t calculate_fcs(const HDLCFrame *frame, size_t i) { + uint16_t fcs = 0xFFFF; + + uint8_t data_bytes[2 + frame->data_length]; + data_bytes[0] = frame->address; + data_bytes[1] = frame->control; + memcpy(data_bytes + 2, frame->data, frame->data_length); + + for (size_t i = 0; i < frame->data_length + 2; i++) { + uint8_t byte = data_bytes[i]; + fcs = (fcs >> 8) ^ (fcs << 8) ^ byte; + fcs &= 0xFFFF; + } + + return fcs; +} + +void create_frame(const HDLCFrame* frame, uint8_t* result) { + size_t index = 0; + + result[index++] = START_FLAG; + result[index++] = frame->address; + result[index++] = frame->control; + + if (frame->data != NULL) { + for (size_t i = 0; i < frame->data_length; i++) { + uint8_t byte = frame->data[i]; + if (byte == START_FLAG || byte == END_FLAG || byte == ESCAPE_FLAG) { + result[index++] = ESCAPE_FLAG; + result[index++] = byte ^ ESCAPE_XOR; + } else { + result[index++] = byte; + } + } + } + + uint16_t fcs = calculate_fcs(frame, 0); + result[index++] = fcs & 0xFF; + result[index++] = (fcs >> 8) & 0xFF; + result[index++] = END_FLAG; +} + +void init_IFrame(IFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + uint8_t send_sequence_number, uint8_t* data, size_t data_length) { + init_HDLCFrame(&frame->base, address, + ((receive_sequence_number & 0b111) << 6) | ((poll_final & 0b1) << 4) | + ((send_sequence_number & 0b111) << 1) | 0, + data, data_length); + frame->receive_sequence_number = receive_sequence_number; + frame->poll_final = poll_final; + frame->send_sequence_number = send_sequence_number; +} + +void init_SFrame(SFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + const char* frame_type) { + uint8_t frame_type_value; + if (strcmp(frame_type, "RR") == 0) { + frame_type_value = 0; + } else if (strcmp(frame_type, "RNR") == 0) { + frame_type_value = 1; + } else if (strcmp(frame_type, "REJ") == 0) { + frame_type_value = 2; + } else if (strcmp(frame_type, "SREJ") == 0) { + frame_type_value = 3; + } else { + // Handle error + return; + } + + init_HDLCFrame(&frame->base, address, + ((receive_sequence_number & 0b111) << 6) | ((poll_final & 0b1) << 5) | + ((frame_type_value & 0b111) << 2) | 1, + NULL, 0); + frame->receive_sequence_number = receive_sequence_number; + frame->poll_final = poll_final; + frame->frame_type = frame_type; +} + +void init_UFrame(UFrame* frame, uint8_t address, uint8_t poll_final, const char* frame_type, + uint8_t* data, size_t data_length) { + uint8_t frame_type_value; + if (strcmp(frame_type, "BP") == 0) { + frame_type_value = 63; + } else { + // Handle error + return; + } + + init_HDLCFrame(&frame->base, address, (frame_type_value << 2) | 3, data, data_length); + frame->poll_final = poll_final; + frame->frame_type = frame_type; +} diff --git a/hdlc_frame.h b/hdlc_frame.h new file mode 100644 index 0000000..c12eaf5 --- /dev/null +++ b/hdlc_frame.h @@ -0,0 +1,45 @@ +#ifndef HDLC_FRAME_H +#define HDLC_FRAME_H + +#include + +typedef struct { + uint8_t address; + uint8_t control; + uint8_t* data; + size_t data_length; +} HDLCFrame; + +void init_HDLCFrame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length); +uint16_t calculate_fcs(const HDLCFrame *frame, size_t i); +void create_frame(const HDLCFrame* frame, uint8_t* result); + +typedef struct { + HDLCFrame base; + uint8_t receive_sequence_number; + uint8_t poll_final; + uint8_t send_sequence_number; +} IFrame; + +void init_IFrame(IFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + uint8_t send_sequence_number, uint8_t* data, size_t data_length); + +typedef struct { + HDLCFrame base; + uint8_t receive_sequence_number; + uint8_t poll_final; + const char* frame_type; +} SFrame; + +void init_SFrame(SFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + const char* frame_type); + +typedef struct { + HDLCFrame base; + uint8_t poll_final; + const char* frame_type; +} UFrame; + +void init_UFrame(UFrame* frame, uint8_t address, uint8_t poll_final, const char* frame_type, uint8_t* data, size_t data_length); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..93e2b83 --- /dev/null +++ b/main.c @@ -0,0 +1,25 @@ +#include +#include "config.h" +#include +#include +#include +#include "uart_hal.h" + + +int main(void) +{ + //example + uint8_t data = 'A'; + + uart_init(9600,0); + uart_send_byte(data); + sei(); + while (1) + { + if(uart_read_count() > 0){ + data = uart_read(); + uart_send_byte(data); + } + + } +} \ No newline at end of file diff --git a/uart_module.c b/uart_module.c new file mode 100644 index 0000000..c4cbc2a --- /dev/null +++ b/uart_module.c @@ -0,0 +1,82 @@ +#include "uart_hal.h" + +volatile static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0}; +volatile static uint16_t rx_count = 0; +volatile static uint8_t uart_tx_busy = 1; +// кольцевой буффер +ISR(USART_RX_vect){ + + volatile static uint16_t rx_write_pos = 0; + + rx_buffer[rx_write_pos] = UDR0; + rx_count++; + rx_write_pos++; + if(rx_write_pos >= RX_BUFFER_SIZE){ + rx_write_pos = 0; + } + +} + + +ISR(USART_TX_vect){ + uart_tx_busy = 1; +} + + +void uart_init(uint32_t baud,uint8_t high_speed){ + + uint8_t speed = 16; + + if(high_speed != 0){ + speed = 8; + UCSR0A |= 1 << U2X0; + } + + baud = (F_CPU/(speed*baud)) - 1; + + UBRR0H = (baud & 0x0F00) >> 8; + UBRR0L = (baud & 0x00FF); + + UCSR0B |= (1 << TXEN0) | (1 << RXEN0) | (1 << TXCIE0) | (1 << RXCIE0); + +} + + +void uart_send_byte(uint8_t c){ + while(uart_tx_busy == 0); + uart_tx_busy = 0; + UDR0 = c; +} + +void uart_send_array(uint8_t *c,uint16_t len){ + for(uint16_t i = 0; i < len;i++){ + uart_send_byte(c[i]); + } +} + +void uart_send_string(uint8_t *c){ + uint16_t i = 0; + do{ + uart_send_byte(c[i]); + i++; + + }while(c[i] != '\0'); + uart_send_byte(c[i]); +} + +uint16_t uart_read_count(void){ + return rx_count; +} + +uint8_t uart_read(void){ + static uint16_t rx_read_pos = 0; + uint8_t data = 0; + + data = rx_buffer[rx_read_pos]; + rx_read_pos++; + rx_count--; + if(rx_read_pos >= RX_BUFFER_SIZE){ + rx_read_pos = 0; + } + return data; +} \ No newline at end of file diff --git a/uart_module.h b/uart_module.h new file mode 100644 index 0000000..284a941 --- /dev/null +++ b/uart_module.h @@ -0,0 +1,20 @@ +#ifndef UART_HAL_H_ +#define UART_HAL_H_ + + +#include +#include "config.h" +#include +#include +#include + +#define RX_BUFFER_SIZE 128 + +void uart_init(uint32_t baud,uint8_t high_speed); +void uart_send_byte(uint8_t c); +void uart_send_array(uint8_t *c,uint16_t len); +void uart_send_string(uint8_t *c); +uint16_t uart_read_count(void); +uint8_t uart_read(void); + +#endif /* UART_HAL_H_ */ \ No newline at end of file