# PDI-KISS Enunciado
[Enunciado del ejercicio](https://docs.google.com/document/d/1IEZb6pdCYwG2lYsVNfKQOlWM0U_pWKRQ/edit?usp=sharing&ouid=110814349318583191439&rtpof=true&sd=true)
# PDI-KISS: Solución ejercicio de autoevaluación
```c=
#include "riscv_types.h"
#include "riscv_uart.h"
#include "dispatch.h"
#include "log.h"
#define GAP_1_DECIMA 1000000 // tick 10 veces por segundo
#define FEND 0xC0 // Valor del delimitador de una trama KISS
// Global variables
// KISS frame array and control variables
uint32_t idx = 0, in_frame = 0, flag = 0;
uint8_t kiss_frame[256];
// Contador para el control del tiempo
uint32_t timer_counter;
// UART RX IRQ handler
void uart_rx_irq_handler (void)
{
uint8_t rec;
rec = (uint8_t)riscv_getchar();
if ( in_frame )
{
// Save received value
kiss_frame[ idx ] = rec;
idx++;
if ( rec == FEND ) // fin de trama, procesar el mensaje
{
flag = 1;
in_frame = 0;
}
}
else
{
if ( rec == FEND ) // comienzo de trama, procesar el mensaje
{
in_frame = 1;
// Save received value
kiss_frame[ idx ] = rec;
idx++;
// La ISR del timer se ejecuta 10 veces por segundo
// Esperaré tres segundos como máximo para la recepción de la cabecera
timer_counter = 30;
}
else
{
printf("Not in frame -> discard data: %02X\n", rec );
}
}
}
void timer_handler(void)
{
if ( in_frame )
{
timer_counter--;
if ( timer_counter == 0)
{
// Descarto lo recibido y reseteo las variables de control
printf("\nTimeout: Not received endding FEND.\nDiscarding data...\n");
in_frame = 0;
idx = 0;
}
}
}
int main()
{
char mensaje[256];
// TX/RX enable
riscv_uart_enable_TX();
riscv_uart_enable_RX();
install_local_timer_handler( timer_handler );
local_timer_set_gap( GAP_1_DECIMA ); // CLINT timer clock is 10Mh
enable_timer_clinc_irq();
// Install UART RX ISR and enable interrupts processing
install_irq_handler( UART_IRQ, uart_rx_irq_handler );
riscv_uart_enable_RI(); // Enable RX irq
plic_irq_unmask( UART_IRQ ); // PLIC UART irq unmask
enable_ext_irq(); // Enable MIE.MEI
enable_irq(); // Global interrupt enable
while (1) // Super loop
{
if ( flag ) // Frame is complete when flag is set
{
// Hay que extraer el mensaje para poder imprimirlo
// El mensaje comienza en la tercera posición, kiss_frame[2]
// La logitud del mensaje es idx - 3
uint32_t lng_mensaje = idx - 3;
for (int i = 0; i < lng_mensaje; i++)
{
mensaje[i] = kiss_frame[i+2];
}
// Para poder imprimir el mensaje hay que poner el fin de cadena al final
mensaje[ lng_mensaje] = '\0';
printf("Mesaje recibido: %s\n", mensaje);
// Send response
riscv_putchar( FEND );
riscv_putchar( 0 );
riscv_putchar( (uint8_t)lng_mensaje);
riscv_putchar( FEND );
// Reset tc_header control variables
flag = 0;
idx = 0;
}
} // while(1)
return 0;
}
```