Loading...
Searching...
No Matches
uartpub.c
1/**************************************************************************************************
2 * @file uartcomm.c *
3 * @brief Implements the FreeRTOS tasks and Interrupt Service Routine (ISR) *
4 * responsible for managing uart communication. *
5 * *
6 * *
7 * @{ *
8 **************************************************************************************************/
9
10#include "AustralisConfig.h"
11#include "uartpub.h"
12
13#include "stm32f439xx.h"
14
15#include "FreeRTOS.h"
16#include "event_groups.h"
17#include "message_buffer.h"
18#include "queue.h"
19
20#include "_topic.h"
21#include "uart.h"
22#include "gpiopin.h"
23#include "devices.h"
24
25// Create publication topic for UART data
26//
27// NOTE:
28// This topic is exposed for reader
29// comments in the public header.
30CREATE_TOPIC(uart, UART_MSG_LENGTH, sizeof(uint8_t))
31Topic *uartTopic = (Topic *)&uart;
32
33static TaskHandle_t vUartTransmitHandle;
34static TaskHandle_t vUartReceiveHandle;
35
36// LoRa transceiver device
37//
38// TODO:
39// Add deviceReady flag to driver API to indicate
40// when a device struct is initialised and populated
41static UART_t *peripheral;
42void UART_setPeripheral(UART_t *peripheral_) {
43 peripheral = peripheral_;
44}
45
46/* ============================================================================================== */
52void vUartTransmit(void *argument) {
53 const TickType_t blockTime = portMAX_DELAY;
54 uint8_t txData;
55
56 vUartTransmitHandle = xTaskGetCurrentTaskHandle();
57
58 for (;;) {
59 // Don't operate unless transceiver is ready
60 if (peripheral == NULL)
61 continue;
62
63 // Wait to receive message to transmit
64 BaseType_t result = WAIT_COMMENT(
65 uart.public.commentInbox, // Read from UART topic comment queue
66 (void *)&txData, // Store data in binary array
67 portMAX_DELAY // Block forever until comment is available
68 );
69
70 if (result == pdTRUE) {
71 // Transmit data if successfully retrieved from queue
72 peripheral->send(peripheral, txData);
73 }
74 }
75}
76
77/* ============================================================================================== */
83void vUartReceive(void *argument) {
84 const TickType_t blockTime = portMAX_DELAY;
85 uint32_t rxData;
86
87 vUartReceiveHandle = xTaskGetCurrentTaskHandle();
88
89 GPIOpin_t indicator = GPIOpin_init(LED2_PORT, LED2_PIN, NULL);
90 indicator.reset(&indicator);
91
92 for (;;) {
93 // Don't operate unless transceiver is ready
94 if (peripheral == NULL)
95 continue;
96
97 // Read byte from UART Rx buffer
98 xTaskNotifyWait(0, 0, &rxData, portMAX_DELAY);
99
100 // Publish packet data to topic
101 Topic_publish((PrivateTopic *)uartTopic, (uint8_t *)&rxData);
102 }
103}
104
105/* ============================================================================================== */
111void pubUartInterrupt() {
112 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
113
114 // Exit if peripheral is not ready
115 if (peripheral == NULL)
116 goto UART_NOT_READY;
117
118 if (peripheral->interface->SR & USART_SR_RXNE) {
119 uint8_t data = peripheral->interface->DR;
120 xTaskNotifyFromISR(vUartReceiveHandle, data, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
121 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
122 }
123
124UART_NOT_READY:
125 return;
126}
127
bool Topic_publish(PrivateTopic *topic, uint8_t *article)
Publish an "article" to all discovered subscribers of a topic.
Definition topic.c:74
#define CREATE_TOPIC(topic, commentInboxSize, messageSize)
Macro to define and initialize a topic instance.
Definition _topic.h:60
Internal representation of a Topic instance.
Definition _topic.h:73
void(* reset)(struct GPIOpin *)
Definition gpiopin.h:156
GPIOpin_t GPIOpin_init(GPIO_TypeDef *, GPIO_Pin, GPIO_Config *)
Initialiser for a GPIO peripheral pin interface.
Definition gpiopin.c:28
Struct definition for a GPIO pin.
Definition gpiopin.h:151
Struct definition for UART interface.
Definition uart.h:132
Public representation of a Topic.
Definition topic.h:71