Last active
May 3, 2021 21:26
-
-
Save lorsi96/a57ba420d67c1ec4a93e4df10672d1d7 to your computer and use it in GitHub Desktop.
SEOS PONT Example with UART ISR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*============================================================================= | |
* Copyright (c) 2021, Lucas Orsi <lorsi@itba.edu.ar> | |
* All rights reserved. | |
* License: MIT | |
* Date: 2021/05/03 | |
* Version: 1.0 | |
*===========================================================================*/ | |
#include "sapi.h" | |
#include "seos_pont_2014_isr.h" | |
#include "seos_pont_2014_scheduler.h" | |
/*********************************************************************/ | |
/* Mini Queue Pseudo-class */ | |
/*********************************************************************/ | |
#define MINI_QUEUE_SIZE (255) | |
#define T uint8_t | |
typedef struct { | |
T data[MINI_QUEUE_SIZE]; | |
uint8_t index; | |
} MiniQueue; | |
/** | |
* @brief Pushes data into the queue. | |
* | |
* @param[in] queue to send data to. | |
* @param[in] data to be sent. | |
*/ | |
static void MiniQueue_send(MiniQueue* queue, T data) { | |
queue->data[queue->index] = data; | |
queue->index = (queue->index + 1) % MINI_QUEUE_SIZE; | |
} | |
/** | |
* @brief Gets the oldest value available in the queue, | |
* and removes it afterwards. | |
* | |
* @param[in] queue to read data from. | |
* @param[out] data read from the queue. | |
* @return bool_t | |
*/ | |
static bool_t MiniQueue_receive(MiniQueue* queue, T* data) { | |
if(queue->index) { | |
*data = queue->data[--queue->index]; | |
return true; | |
} else { | |
return false; | |
} | |
} | |
/** | |
* @brief Resets all the data in a queue. | |
* | |
* @param queue queue to erase data from. | |
*/ | |
static void MiniQueue_reset(MiniQueue* queue) { | |
queue->index = 0; | |
} | |
/*********************************************************************/ | |
/* State Definitions */ | |
/*********************************************************************/ | |
/** | |
* @brief FSM States. | |
* | |
*/ | |
typedef enum { | |
IDLE, /*< Waiting for the start character "<" to be received.*/ | |
RECEIVING /*< Receiving characters until a ">" is captured. */ | |
} msg_state_t; | |
/*********************************************************************/ | |
/* Private Variables */ | |
/*********************************************************************/ | |
/** | |
* @brief Queue to store values from the uart interrupt. | |
* | |
* This is only relevant if incoming data from UART is faster | |
* than the main loop can handle. | |
*/ | |
static MiniQueue uartBufferQueue = {{0}, 0}; | |
/** | |
* @brief Queue to hold the incoming message to be echoed. | |
* | |
*/ | |
static MiniQueue messageQueue = {{0}, 0}; | |
static msg_state_t currentState = IDLE; | |
/*********************************************************************/ | |
/* Interrupt Handler */ | |
/*********************************************************************/ | |
/** | |
* @brief Uart interrupt handler. | |
* | |
* Reads data and stores it into the #uartBufferQueue. | |
* | |
*/ | |
void onRx(void* _) { | |
MiniQueue_send(&uartBufferQueue, uartRxRead(UART_USB)); | |
} | |
/*************************************************************************/ | |
/* App Constants */ | |
/*************************************************************************/ | |
/* Time between the reception of an end character and the echo response. */ | |
#define RECEIVED_OK_DELAY_MS 1000 | |
/* Characters to delimit the beginning and end of a message. */ | |
#define BEGIN_CHAR '>' | |
#define END_CHAR '<' | |
/*************************************************************************/ | |
/* Tasks Definitions */ | |
/*************************************************************************/ | |
static void ledWitnessTaskOn(void* _) { | |
gpioWrite(LEDG, true); | |
} | |
static void ledWitnessTaskOff(void* _) { | |
gpioWrite(LEDG, false); | |
} | |
void ackEchoTask(void* _) { | |
uartWriteString(UART_USB, "Recibido: "); | |
uartWriteString(UART_USB, (char*)messageQueue.data); | |
uartWriteString(UART_USB, "\n"); | |
MiniQueue_reset(&messageQueue); | |
} | |
void uartCheckerTask(void* _) { | |
uint8_t newChar; | |
if(MiniQueue_receive(&uartBufferQueue, &newChar)) { | |
switch (currentState) { | |
case IDLE: | |
if(newChar == BEGIN_CHAR) { | |
schedulerAddTask(ledWitnessTaskOn, NULL, 0, 0); | |
currentState = RECEIVING; | |
} | |
break; | |
case RECEIVING: | |
if(newChar == END_CHAR) { | |
currentState = IDLE; | |
MiniQueue_send(&messageQueue, '\0'); | |
schedulerAddTask(ledWitnessTaskOff, NULL, 0, 0); | |
schedulerAddTask(ackEchoTask, NULL, RECEIVED_OK_DELAY_MS, 0); | |
} else { | |
MiniQueue_send(&messageQueue, newChar); | |
} | |
default: | |
break; | |
} | |
} | |
} | |
/*********************************************************************/ | |
/* App Main */ | |
/*********************************************************************/ | |
int main(void) { | |
boardConfig(); | |
uartConfig(UART_USB, 115200); | |
uartCallbackSet(UART_USB, UART_RECEIVE, onRx, NULL); | |
schedulerInit(); | |
uartInterrupt(UART_USB, true); | |
schedulerAddTask(uartCheckerTask, NULL, 0, 10); | |
schedulerStart(1); | |
for(;;) { | |
schedulerDispatchTasks(); | |
} | |
return 0; // Should never reach here. | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment