#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
// UART
#define UART_PORT UART_NUM_0
#define BAUD_RATE 115200
#define BUFFER_SIZE 256
void uart_setup(void);
void uart_capturaDatosMatriz(uint8_t*, uint8_t*, uint8_t*);
void uart_capturaMatriz(uint16_t*, uint8_t, uint8_t);
void uart_imprimeMatriz(uint16_t*, uint8_t, uint8_t);
void rotaMatriz(uint16_t*, uint8_t, uint8_t, uint8_t);
void removerSubMatriz(uint16_t*, uint8_t, uint8_t, uint16_t*, uint8_t, uint8_t);
void app_main() {
uart_setup();
uint8_t rows, cols, rots;
uart_capturaDatosMatriz(&rows, &cols, &rots);
uint16_t matriz[rows][cols];
uart_capturaMatriz(&matriz[0][0], rows, cols);
uart_imprimeMatriz(&matriz[0][0], rows, cols);
rotaMatriz(&matriz[0][0], rows, cols, rots);
uart_imprimeMatriz(&matriz[0][0], rows, cols);
while (true) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void uart_setup(void) {
const uint8_t uart_port = UART_PORT;
uart_config_t uart_config = {
.baud_rate = BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
int intr_alloc_flags = 0;
ESP_ERROR_CHECK(uart_param_config(uart_port, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(uart_port, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
ESP_ERROR_CHECK(uart_driver_install(uart_port, BUFFER_SIZE * 2, 0, 0, NULL, intr_alloc_flags));
}
void uart_capturaDatosMatriz(uint8_t *rows, uint8_t *cols, uint8_t *rot_num) {
if (rows == NULL || cols == NULL || rot_num == NULL) return;
const char msg_matriz[] = "Datos de la Matriz: \n";
const char msg_rows[] = "Filas: ";
const char msg_cols[] = "Columnas: ";
const char msg_rots[] = "Rotaciones: ";
uint8_t data[BUFFER_SIZE];
// Leer datos de matriz por UART
uart_write_bytes(UART_PORT, msg_matriz, strlen(msg_matriz));
// Leer numero de filas por UART
uart_write_bytes(UART_PORT, msg_rows, strlen(msg_rows));
int len = 0;
while (len < 1) {
len = uart_read_bytes(UART_PORT, data, (BUFFER_SIZE - 1), 20 / portTICK_PERIOD_MS);
}
uart_write_bytes(UART_PORT, (const char *) data, len);
data[len-1] = '\0';
*rows = (uint8_t) atoi((const char *) data);
// Leer numero de columans por UART
uart_write_bytes(UART_PORT, msg_cols, strlen(msg_cols));
len = 0;
while (len < 1) {
len = uart_read_bytes(UART_PORT, data, (BUFFER_SIZE - 1), 20 / portTICK_PERIOD_MS);
}
uart_write_bytes(UART_PORT, (const char *) data, len);
data[len-1] = '\0';
*cols = (uint8_t) atoi((const char *) data);
// Leer numero de rotaciones por UART
uart_write_bytes(UART_PORT, msg_rots, strlen(msg_rots));
len = 0;
while (len < 1) {
// Leer numero de filas por UART
len = uart_read_bytes(UART_PORT, data, (BUFFER_SIZE - 1), 20 / portTICK_PERIOD_MS);
}
uart_write_bytes(UART_PORT, (const char *) data, len);
data[len-1] = '\0';
*rot_num = (uint8_t) atoi((const char *) data);
}
void uart_capturaMatriz(uint16_t *matriz, uint8_t rows, uint8_t cols) {
if (matriz == NULL) return;
for (uint8_t row = 0; row < rows; row++) {
for (uint8_t col = 0; col < cols; col++) {
uint16_t *matriz_idx = matriz + row*cols + col;
uint8_t data[BUFFER_SIZE];
int len = 0;
char msg[100];
snprintf(msg, 100, "Matriz[" "%" PRIu8 "][" "%" PRIu8 "]: ", row, col);
uart_write_bytes(UART_PORT, msg, strlen(msg));
while (len <= 0) {
// Read data from the UART
len = uart_read_bytes(UART_PORT, data, (BUFFER_SIZE - 1), 20 / portTICK_PERIOD_MS);
}
// Write data back to the UART
uart_write_bytes(UART_PORT, (const char *) data, len);
data[len-1] = '\0';
*matriz_idx = (uint16_t) atol((const char *) data);
}
}
}
void uart_imprimeMatriz(uint16_t *matriz, uint8_t rows, uint8_t cols) {
if (matriz == NULL) return;
const char msg_matriz[] = "Matriz: \n";
uart_write_bytes(UART_PORT, msg_matriz, strlen(msg_matriz));
char numero[10];
uint16_t *idx;
for (uint8_t row = 0; row < rows; row++) {
for (uint8_t col = 0; col < cols-1; col++) {
idx = matriz + row*cols + col;
snprintf(numero, sizeof(numero), "%" PRIu16 ", ", *idx);
uart_write_bytes(UART_PORT, numero, strlen(numero));
}
idx = matriz + row*cols + cols-1;
snprintf(numero, sizeof(numero), "%" PRIu16 "\n", *idx);
uart_write_bytes(UART_PORT, numero, strlen(numero));
}
}
/* Esta función rota una matriz rot_num veces en sentido horario
Entrada: Matriz de tamaño rows x cols (como puntero linealizado)
Salida: La matriz se rota en sitio (in-place) rot_num veces */
void rotaMatriz(uint16_t *matriz, uint8_t rows, uint8_t cols, uint8_t rot_num) {
while (rot_num--) {
uint8_t row_inicio = 0, col_inicio = 0;
uint8_t row_final = rows, col_final = cols;
while ((row_inicio < row_final - 1) && (col_inicio < col_final - 1)) {
// Guardar el primer elemento del siguiente anillo
uint16_t prev = matriz[(row_inicio + 1) * cols + col_inicio];
// Mover fila superior
for (uint8_t col = col_inicio; col < col_final; col++) {
uint16_t idx = row_inicio * cols + col;
uint16_t temp = matriz[idx];
matriz[idx] = prev;
prev = temp;
}
// Mover columna derecha
for (uint8_t row = row_inicio + 1; row < row_final; row++) {
uint16_t idx = row * cols + (col_final - 1);
uint16_t temp = matriz[idx];
matriz[idx] = prev;
prev = temp;
}
// Mover fila inferior (si hay más de una fila)
if (row_inicio < row_final - 1) {
for (int8_t col = col_final - 2; col >= col_inicio; col--) {
uint16_t idx = (row_final - 1) * cols + col;
uint16_t temp = matriz[idx];
matriz[idx] = prev;
prev = temp;
}
}
// Mover columna izquierda (si hay más de una columna)
if (col_inicio < col_final - 1) {
for (int8_t row = row_final - 2; row > row_inicio; row--) {
uint16_t idx = row * cols + col_inicio;
uint16_t temp = matriz[idx];
matriz[idx] = prev;
prev = temp;
}
}
row_inicio++;
col_inicio++;
row_final--;
col_final--;
}
}
}
void removerSubMatriz(uint16_t *matriz, uint8_t rows1, uint8_t cols1, uint16_t *subMatriz, uint8_t rows2, uint8_t cols2);