Pico GPS Teseo I2C
Loading...
Searching...
No Matches
teseo_communicate.cpp
Go to the documentation of this file.
1module;
2
3// for debug messages
4#include <string>
5// for memset
6#include <cstring>
7#include "hardware/gpio.h"
8#include <stdio.h>
9#include "pico/stdlib.h"
10#include <algorithm>
11#include "hardware/regs/intctrl.h"
12
13
14export module port_pico_communicate;
15
16import port_pico_reset;
17
18
19// for the moment, the library restricts how many sattelites it entertains.
20// it influences the size of the read buffer (not a drama, this is a static buffer)
21// it also influences the size of the vector that will accept replies that are "per sattelite"
22// Currently, the code does not allow that the vector that holds these, grows (focus on embedded)
23// later, this can be changed to allow flex, if you accept the dynamic
24// memory growth impact (acceptable for larger systems like PC, processors, ...)
25#define MAX_SATELLITE_REPLIES 7
26
27#include "hardware/uart.h"
28#include <cassert>
29#define UART_PORT (uart1)
30#define UART_BAUD (9600)
31#define UART_TX (4)
32#define UART_RX (5)
33// multiline replies take decent buffer size
34// calculate 70 characters per nmea replies, + 60 for the status line
35// many libraries limit the number of satelites to say 7
36#define BUFFSIZE (70 * MAX_SATELLITE_REPLIES + 60)
37// how long to wait for a single character before timing out
38#define UART_WAITFORREPLY_MS (40)
39// forward declaration
40void on_uart_rx();
41
42// calculate 70 characters per satellite, + 60 for the status line
43// many libraries limit the number of satelites to say 6
45
46uint8_t buf[BUFFSIZE]; // read buffer, intentionally not initialised
47
48volatile bool bWantChars; // explicitely uninitialised
49volatile absolute_time_t fail_at;
50int UART_IRQ = UART1_IRQ;
51uint8_t *pBuf; // explicitely uninitialised
52
53export void initialize() {
54 stdio_init_all();
55 uart_init(UART_PORT, UART_BAUD);
56 uart_set_fifo_enabled(UART_PORT, false);
57 gpio_set_function(UART_TX, GPIO_FUNC_UART);
58 gpio_set_function(UART_RX, GPIO_FUNC_UART);
59 // set up and enable the interrupt handlers
60 irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
61 irq_set_enabled(UART_IRQ, true);
62 // by default all UART interrupts off
63 uart_set_irq_enables(UART_PORT, false, false);
64
66}
67
68void on_uart_rx() {
69 uint8_t letter;
70
71 while (uart_is_readable(UART_PORT)) {
72 letter = uart_getc(UART_PORT);
73 if (bWantChars) {
74 fail_at = delayed_by_ms(get_absolute_time(), UART_WAITFORREPLY_MS);
75 pBuf[0] = letter;
76
77 if (pBuf[0] == 0) {
78 bWantChars = false; // a null read
79 }
80 if ((pBuf - buf) < BUFFSIZE-1) { // if we reach max buffer size, just keep emptying any additional characters in the last position;
81 pBuf++;
82 }
83 assert ((pBuf - buf) < BUFFSIZE);
84 }
85 }
86}
87
88export void write(const ::std::string& s) {
89 uart_write_blocking(UART_PORT, reinterpret_cast<const uint8_t*>(s.c_str()), s.length() +1);
90 return;
91}
92
93export void read(::std::string& s) {
94 memset (buf, 0, BUFFSIZE); // initialise buffer before reading
95 pBuf = buf;
96 bWantChars = true;
97 // enable the UART to send interrupts - RX only
98 uart_set_irq_enables(UART_PORT, true, false);
99 fail_at = delayed_by_ms(get_absolute_time(), UART_WAITFORREPLY_MS);
100 while (bWantChars){
101 if (absolute_time_diff_us(fail_at, get_absolute_time()) >= 0) {
102 bWantChars = false; // timeout
103 }
104 };
105 // disable the UART to send interrupts
106 uart_set_irq_enables(UART_PORT, false, false);
107 s = std::string(reinterpret_cast<const char*>(buf));
108
109 return;
110}
void initialize()
#define BUFFSIZE
void read(::std::string &s)
uint8_t buf[BUFFSIZE]
#define MAX_SATELLITE_REPLIES
void write(const ::std::string &s)
void reset_initialize()
Definition reset.cpp:25
const size_t NMEA_MAX_REPLIES
#define UART_BAUD
int UART_IRQ
volatile bool bWantChars
#define UART_PORT
volatile absolute_time_t fail_at
#define UART_TX
#define UART_WAITFORREPLY_MS
void on_uart_rx()
uint8_t * pBuf
#define UART_RX