Loading...
Searching...
No Matches
gpsacquisition.c
1/**************************************************************************************************
2 * @file gpsacquisition.c *
3 * @brief Implements the FreeRTOS tasks and Interrupt Service Routine (ISR) *
4 * responsible for managing GPS communication. *
5 * *
6 * This file contains the implementation for GPS acuisition. It utilizes a publication topic *
7 * (`gps`) to interface with other parts of the application. *
8 * *
9 * The acuire task waits for notifications from the ISR (indicating a received packet), reads *
10 * the data from the receiver, and publishes it to the topic. *
11 * *
12 * TODO: Update this documentation comment *
13 * The `EXTI1_IRQHandler` handles interrupts from the LoRa module (e.g., Tx Done, Rx Done), *
14 * notifying the appropriate task to proceed. *
15 * *
16 * TODO: Move hardcoded interrupt handler to function that can be called by / aliased to the *
17 * target specific interrupt handler. *
18 * TODO: Replace hardcoded USART device in interrupt handler with device specific UART *
19 * *
20 * @{ *
21 **************************************************************************************************/
22
23#include "gpsacquisition.h"
24
25#include "FreeRTOS.h"
26
27#include "_topic.h"
28#include "devicelist.h"
29
30#include "sam_m10q.h"
31
32// Create publication topic for GPS data
33// NOTE:
34// This topic is not exposed for reader
35// comments in the public header.
36CREATE_TOPIC(gps, 10, sizeof(SAM_M10Q_Data))
37
38static TaskHandle_t vGpsAcquireHandle;
39static SAM_M10Q_t *receiver;
40
41#define GPS_RX_SIZE 128 // TODO: Refactor hardcoded value
42
43static uint8_t gpsRxBuff[GPS_RX_SIZE];
44static uint8_t gpsRxBuffIdx = 0;
45
46/* ============================================================================================== */
53void vGpsAcquire(void *argument) {
54
55 vGpsAcquireHandle = xTaskGetCurrentTaskHandle();
56
57 // TODO:
58 // Add deviceReady flag to driver API to indicate
59 // when a device struct is initialised and populated
60 //
61 // Check if device pointer is NULL
62 if (!receiver)
63 // Initialise receiver if necessary
64 receiver = DeviceList_getDeviceHandle(DEVICE_GPS).device;
65
66 for (;;) {
67 // Block until 500ms interval
68 TickType_t xLastWakeTime = xTaskGetTickCount();
69 vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(500));
70
71 // Send GPS poll message
72 receiver->pollPUBX(receiver);
73
74 // Wait for notification from ISR
75 xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
76
77 // Parse NMEA data to struct
78 SAM_M10Q_Data gpsData;
79 receiver->parsePUBX(receiver, gpsRxBuff, &gpsData);
80
81 // Publish parsed GPS data to topic
82 Topic_publish(&gps, (uint8_t *)&gpsData);
83
84 gpsRxBuffIdx = 0;
85 }
86}
87
88/* ============================================================================================== */
99void USART3_IRQHandler() {
100 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
101
102 // Early exit interrupt if receiver or task is not ready
103 if (receiver == NULL || vGpsAcquireHandle == NULL)
104 return;
105
106 // Read in byte from USART3
107 while ((USART3->SR & USART_SR_RXNE) == 0);
108 uint8_t rxData = USART3->DR & 0xFF;
109
110 // Add byte to circular data buffer
111 gpsRxBuff[gpsRxBuffIdx++] = rxData; // Add data and increment index
112 gpsRxBuffIdx %= GPS_RX_SIZE; // Wrap index on overflow
113
114 // Send message to buffer on carriage return
115 if (rxData == LINE_FEED) {
116 xTaskNotifyFromISR(vGpsAcquireHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
117 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
118 }
119}
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
DeviceHandle_t DeviceList_getDeviceHandle(DeviceKey)
Retrieve device handle from list by key.
Definition devicelist.c:36