RadioLib
Universal wireless communication library for Arduino
libtockHal.h
1 /*
2  RadioLib Non-Arduino Tock Library helper functions
3 
4  Licensed under the MIT License
5 
6  Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
7 
8  Permission is hereby granted, free of charge, to any person obtaining a copy
9  of this software and associated documentation files (the "Software"), to deal
10  in the Software without restriction, including without limitation the rights
11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  copies of the Software, and to permit persons to whom the Software is
13  furnished to do so, subject to the following conditions:
14 
15  The above copyright notice and this permission notice shall be included in all
16  copies or substantial portions of the Software.
17 
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  SOFTWARE.
25 */
26 
27 #ifndef TOCK_HAL_H
28 #define TOCK_HAL_H
29 
30 // include RadioLib
31 #include <RadioLib.h>
32 
33 // include all the dependencies
34 #include "libtock/net/lora_phy.h"
35 #include "libtock/net/syscalls/lora_phy_syscalls.h"
36 #include "libtock-sync/net/lora_phy.h"
37 #include "libtock/peripherals/gpio.h"
38 #include "libtock-sync/services/alarm.h"
39 #include "libtock/kernel/read_only_state.h"
40 
41 #define RADIO_BUSY 1
42 #define RADIO_DIO_1 2
43 #define RADIO_DIO_3 3
44 #define RADIO_RESET 4
45 // Skip the chips select as Tock handles this for us
46 #define RADIO_NSS RADIOLIB_NC
47 
48 // define Arduino-style macros
49 #define PIN_LOW (0x0)
50 #define PIN_HIGH (0x1)
51 #define PIN_INPUT (0x01)
52 #define PIN_OUTPUT (0x03)
53 #define PIN_RISING (0x01)
54 #define PIN_FALLING (0x02)
55 
56 typedef void (*gpioIrqFn)(void);
57 
58 gpioIrqFn gpio_funcs[4] = { NULL, NULL, NULL, NULL};
59 uint32_t frequency = 0;
60 
61 /*
62  * Get the the timer frequency in Hz.
63  */
64 int alarm_internal_frequency(uint32_t* frequency) {
65  syscall_return_t rval = command(0x0, 1, 0, 0);
66  return tock_command_return_u32_to_returncode(rval, frequency);
67 }
68 
69 int alarm_internal_read(uint32_t* time) {
70  syscall_return_t rval = command(0x0, 2, 0, 0);
71  return tock_command_return_u32_to_returncode(rval, time);
72 }
73 
74 static void lora_phy_gpio_Callback (int gpioPin,
75  __attribute__ ((unused)) int arg2,
76  __attribute__ ((unused)) int arg3,
77  void* userdata)
78 {
79  gpioIrqFn fn = gpio_funcs[gpioPin - 1];
80 
81  if (fn != NULL ) {
82  fn();
83  }
84 }
85 
86 class TockHal : public RadioLibHal {
87  public:
88  // default constructor - initializes the base HAL and any needed private members
89  TockHal()
90  : RadioLibHal(PIN_INPUT, PIN_OUTPUT, PIN_LOW, PIN_HIGH, PIN_RISING, PIN_FALLING) {
91  }
92 
93  void init() override {
94  }
95 
96  void term() override {
97  }
98 
99  // GPIO-related methods (pinMode, digitalWrite etc.) should check
100  // RADIOLIB_NC as an alias for non-connected pins
101  void pinMode(uint32_t pin, uint32_t mode) override {
102  if(pin == RADIOLIB_NC) {
103  return;
104  }
105 
106  if (mode == PIN_OUTPUT) {
107  libtock_lora_phy_gpio_enable_output(pin);
108  } else if (mode == PIN_INPUT) {
109  libtock_lora_phy_gpio_enable_input(pin, libtock_pull_down);
110  }
111  }
112 
113  void digitalWrite(uint32_t pin, uint32_t value) override {
114  if(pin == RADIOLIB_NC) {
115  return;
116  }
117 
118  if (value) {
119  libtock_lora_phy_gpio_set(pin);
120  } else {
121  libtock_lora_phy_gpio_clear(pin);
122  }
123  }
124 
125  uint32_t digitalRead(uint32_t pin) override {
126  int value;
127 
128  if(pin == RADIOLIB_NC) {
129  return 0;
130  }
131 
132  libtock_lora_phy_gpio_read(pin, &value);
133 
134  return value;
135  }
136 
137  void attachInterrupt(uint32_t interruptNum, gpioIrqFn interruptCb, uint32_t mode) override {
138  if(interruptNum == RADIOLIB_NC) {
139  return;
140  }
141 
142  gpio_funcs[interruptNum - 1] = interruptCb;
143  libtock_lora_phy_gpio_command_interrupt_callback(lora_phy_gpio_Callback, NULL);
144 
145  // set GPIO as input and enable interrupts on it
146  libtock_lora_phy_gpio_enable_input(interruptNum, libtock_pull_down);
147  libtock_lora_phy_gpio_enable_interrupt(interruptNum, libtock_change);
148  }
149 
150  void detachInterrupt(uint32_t interruptNum) override {
151  if(interruptNum == RADIOLIB_NC) {
152  return;
153  }
154 
155  gpio_funcs[interruptNum - 1] = NULL;
156  libtock_lora_phy_gpio_disable_interrupt(interruptNum);
157  }
158 
159  void delay(unsigned long ms) override {
160 #if !defined(RADIOLIB_CLOCK_DRIFT_MS)
161  libtocksync_alarm_delay_ms(ms);
162 #else
163  libtocksync_alarm_delay_ms(ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS));
164 #endif
165  }
166 
167  void delayMicroseconds(unsigned long us) override {
168 #if !defined(RADIOLIB_CLOCK_DRIFT_MS)
169  libtocksync_alarm_delay_ms(us / 1000);
170 #else
171  libtocksync_alarm_delay_ms((us * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS)) / 1000);
172 #endif
173  }
174 
175  unsigned long millis() override {
176  uint32_t now;
177  unsigned long ms;
178 
179  if (frequency == 0) {
180  alarm_internal_frequency(&frequency);
181  }
182 
183  alarm_internal_read(&now);
184 
185  ms = now / (frequency / 1000);
186 
187 #if !defined(RADIOLIB_CLOCK_DRIFT_MS)
188  return ms;
189 #else
190  return ms * 1000 / (1000 + RADIOLIB_CLOCK_DRIFT_MS);
191 #endif
192  }
193 
194  unsigned long micros() override {
195  return millis() / 1000;
196  }
197 
198  long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
199  return 0;
200  }
201 
202  void spiBegin() {
203  }
204 
206  }
207 
208  void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
209  libtocksync_lora_phy_read_write(out, in, len);
210  }
211 
213  }
214 
215  void spiEnd() {
216  }
217 
218  void yield() {
219  ::yield_no_wait();
220  }
221 
222  private:
223 };
224 
225 #endif
Hardware abstraction library base interface.
Definition: Hal.h:13
RadioLibHal(const uint32_t input, const uint32_t output, const uint32_t low, const uint32_t high, const uint32_t rising, const uint32_t falling)
Default constructor.
Definition: Hal.cpp:3
Definition: libtockHal.h:86
void spiBegin()
SPI initialization method.
Definition: libtockHal.h:202
void spiEnd()
SPI termination method.
Definition: libtockHal.h:215
unsigned long millis() override
Get number of milliseconds since start. Must be implemented by the platform-specific hardware abstrac...
Definition: libtockHal.h:175
uint32_t digitalRead(uint32_t pin) override
Digital read method. Must be implemented by the platform-specific hardware abstraction!
Definition: libtockHal.h:125
unsigned long micros() override
Get number of microseconds since start. Must be implemented by the platform-specific hardware abstrac...
Definition: libtockHal.h:194
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override
Measure the length of incoming digital pulse in microseconds. Must be implemented by the platform-spe...
Definition: libtockHal.h:198
void term() override
Module termination method. This will be called by all radio modules when the destructor is called....
Definition: libtockHal.h:96
void spiTransfer(uint8_t *out, size_t len, uint8_t *in)
Method to transfer buffer over SPI.
Definition: libtockHal.h:208
void attachInterrupt(uint32_t interruptNum, gpioIrqFn interruptCb, uint32_t mode) override
Method to attach function to an external interrupt. Must be implemented by the platform-specific hard...
Definition: libtockHal.h:137
void yield()
Yield method, called from long loops in multi-threaded environment (to prevent blocking other threads...
Definition: libtockHal.h:218
void spiBeginTransaction()
Method to start SPI transaction.
Definition: libtockHal.h:205
void delay(unsigned long ms) override
Blocking wait function. Must be implemented by the platform-specific hardware abstraction!
Definition: libtockHal.h:159
void digitalWrite(uint32_t pin, uint32_t value) override
Digital write method. Must be implemented by the platform-specific hardware abstraction!
Definition: libtockHal.h:113
void init() override
Module initialization method. This will be called by all radio modules at the beginning of startup....
Definition: libtockHal.h:93
void detachInterrupt(uint32_t interruptNum) override
Method to detach function from an external interrupt. Must be implemented by the platform-specific ha...
Definition: libtockHal.h:150
void delayMicroseconds(unsigned long us) override
Blocking microsecond wait function. Must be implemented by the platform-specific hardware abstraction...
Definition: libtockHal.h:167
void pinMode(uint32_t pin, uint32_t mode) override
GPIO pin mode (input/output/...) configuration method. Must be implemented by the platform-specific h...
Definition: libtockHal.h:101
void spiEndTransaction()
Method to end SPI transaction.
Definition: libtockHal.h:212