|
| 1 | +====== |
| 2 | +RN2XX3 |
| 3 | +====== |
| 4 | + |
| 5 | +This driver provides support for the RN2XX3 family of LoRa radio transceivers by |
| 6 | +Microchip. This includes both the RN2903 and RN2483 modules. |
| 7 | + |
| 8 | +.. warning:: |
| 9 | + This driver only contains preliminary support for a few 'radio set' commands |
| 10 | + and raw radio transmit/receive. There is no support for the LoRaWAN stack |
| 11 | + yet. |
| 12 | + |
| 13 | +Application Programming Interface |
| 14 | +================================= |
| 15 | + |
| 16 | +To register the device for use, you will need to enable the standard upper half |
| 17 | +serial drivers (``CONFIG_STANDARD_SERIAL``), since the RN2XX3 driver requires |
| 18 | +the path to the UART interface the module is connected to. |
| 19 | + |
| 20 | +You will also need to ensure that the baud rate of the UART interface is set to |
| 21 | +57600, which is the baud rate of the RN2XX3. |
| 22 | + |
| 23 | +At registration time, the driver will automatically determine if the device is |
| 24 | +the RN2903 or RN2483. |
| 25 | + |
| 26 | +.. code-block:: c |
| 27 | +
|
| 28 | + #include <nuttx/wireless/lpwan/rn2xx3.h> |
| 29 | +
|
| 30 | + #ifdef CONFIG_LPWAN_RN2XX3 |
| 31 | +
|
| 32 | + /* Register the RN2XX3 device driver */ |
| 33 | +
|
| 34 | + ret = rn2xx3_register("/dev/rn2903", "/dev/ttyS1"); |
| 35 | + if (ret < 0) { |
| 36 | + syslog(LOG_ERR, "Failed to register RN2XX3 device driver: %d\n", ret); |
| 37 | + } |
| 38 | + #endif |
| 39 | +
|
| 40 | +This driver uses the standard POSIX character device interface, implementing |
| 41 | +``read()``, ``write()`` and ``ioctl()``. |
| 42 | + |
| 43 | +To transmit, the ``write()`` function can be used. Bytes in the provided buffer |
| 44 | +will be transmitted as a packet. This has the following behaviour: |
| 45 | + |
| 46 | +* If the radio is in FSK modulation mode, packets will only contain up to 64 |
| 47 | + bytes. A buffer of more than 64 bytes will only have 64 bytes transmitted. |
| 48 | +* If the radio is in LoRa modulation mode, packets will only contain up to 255 |
| 49 | + bytes. |
| 50 | +* If the buffer contains less than the current packet size limit (64 or 255 |
| 51 | + bytes), its contents will be transmitted as a single packet. |
| 52 | + |
| 53 | +.. code-block:: c |
| 54 | +
|
| 55 | + int radio = open("/dev/rn2903", O_RDWR); |
| 56 | + if (radio < 0) |
| 57 | + { |
| 58 | + fprintf(stderr, "Couldn't open radio: %d\n", errno); |
| 59 | + return -1; |
| 60 | + } |
| 61 | +
|
| 62 | + char message[] = "Hello, world!"; |
| 63 | + ssize_t b_sent = write(radio, message, sizeof(message)); |
| 64 | + if (b_sent < 0) |
| 65 | + { |
| 66 | + fprintf(stderr, "Couldn't transmit: %d\n", errno); |
| 67 | + return -1; |
| 68 | + } |
| 69 | +
|
| 70 | +To receive, the ``read()`` function can be used. As much of the received packet |
| 71 | +as possible will be stored in the user buffer. This has the following behaviour: |
| 72 | + |
| 73 | +* If the buffer is too small to contain the full received packet, as much of the |
| 74 | + packet as possible will be stored in the buffer. |
| 75 | +* When the packet is fully read, ``read()`` will return ``0``. |
| 76 | +* If only part of the packet has been read and a call to ``write()`` or |
| 77 | + ``ioctl()`` is made, the remainder of the packet is discarded. |
| 78 | + |
| 79 | +.. code-block:: c |
| 80 | +
|
| 81 | + int radio = open("/dev/rn2903", O_RDWR); |
| 82 | + if (radio < 0) |
| 83 | + { |
| 84 | + fprintf(stderr, "Couldn't open radio: %d\n", errno); |
| 85 | + return -1; |
| 86 | + } |
| 87 | +
|
| 88 | + char buffer[16]; |
| 89 | + ssize_t b_read; |
| 90 | +
|
| 91 | + do { |
| 92 | + b_read = read(radio, buffer, sizeof(buffer)); |
| 93 | + if (b_read < 0) |
| 94 | + { |
| 95 | + fprintf(stderr, "Couldn't receive: %d\n", errno); |
| 96 | + return -1; |
| 97 | + } |
| 98 | + write(0, buffer, b_read); /* Print received bytes to stdout */ |
| 99 | + } while (b_read != 0); |
| 100 | +
|
| 101 | +Finally, the ``ioctl()`` interface provides access to some underlying module |
| 102 | +commands. |
| 103 | + |
| 104 | +``WLIOC_GETSNR`` |
| 105 | +---------------- |
| 106 | + |
| 107 | +Gets the signal to noise ration of the last received packet. If no packets have |
| 108 | +been received, it will default to -128. Argument is a pointer to an ``int8_t``. |
| 109 | + |
| 110 | +.. code-block:: c |
| 111 | +
|
| 112 | + int8_t snr; |
| 113 | + err = ioctl(radio, WLIOC_GETSNR, &snr); |
| 114 | +
|
| 115 | +``WLIOC_SETRADIOFREQ`` |
| 116 | +---------------------- |
| 117 | + |
| 118 | +Sets the operating frequency of the radio module. The argument is the desired |
| 119 | +frequency in Hz (``uint32_t``). |
| 120 | + |
| 121 | +.. code-block:: c |
| 122 | +
|
| 123 | + err = ioctl(radio, WLIOC_SETRADIOFREQ, 902400000); |
| 124 | +
|
| 125 | +``WLIOC_GETRADIOFREQ`` |
| 126 | +---------------------- |
| 127 | + |
| 128 | +Gets the current operating frequency of the radio module in Hz. The argument is |
| 129 | +a pointer to a ``uint32_t``. |
| 130 | + |
| 131 | +.. code-block:: c |
| 132 | +
|
| 133 | + uint32_t freq; |
| 134 | + err = ioctl(radio, WLIOC_GETRADIOFREQ, &freq); |
| 135 | +
|
| 136 | +``WLIOC_SETTXPOWER`` |
| 137 | +-------------------- |
| 138 | + |
| 139 | +Sets the transmission power of the radio. Argument is a pointer to a ``float`` |
| 140 | +containing the desired transmission power in dBm. After setting the transmission |
| 141 | +power successfully, this pointer will contain the new transmission power. This |
| 142 | +value may be different from the desired value, but will be the closest available |
| 143 | +setting that is greater than or equal to the desired value. |
| 144 | + |
| 145 | +.. code-block:: c |
| 146 | +
|
| 147 | + float txpower = 12.0; |
| 148 | + err = ioctl(radio, WLIOC_SETTXPOWER, &txpower); |
| 149 | + printf("Actual TX power: %.2f dBm\n", txpower); |
| 150 | +
|
| 151 | +``WLIOC_GETTXPOWER`` |
| 152 | +-------------------- |
| 153 | + |
| 154 | +Gets the current transmission power level, as the integer level that the radio |
| 155 | +uses. The argument is a pointer to an ``int8_t``. |
| 156 | + |
| 157 | +.. code-block:: c |
| 158 | +
|
| 159 | + int8_t txpwr; |
| 160 | + err = ioctl(radio, WLIOC_GETTXPOWER, &txpwr); |
| 161 | +
|
| 162 | +``WLIOC_SETBANDWIDTH`` |
| 163 | +---------------------- |
| 164 | + |
| 165 | +Sets the operating bandwidth of the radio module. The argument is the desired |
| 166 | +bandwidth in kHz (``uint32_t``). The radio only supports exact values of 125, |
| 167 | +250 and 500. |
| 168 | + |
| 169 | +.. code-block:: c |
| 170 | +
|
| 171 | + err = ioctl(radio, WLIOC_SETBANDWIDTH, 250); |
| 172 | +
|
| 173 | +``WLIOC_GETBANDWIDTH`` |
| 174 | +---------------------- |
| 175 | + |
| 176 | +Gets the current operating bandwidth of the radio module in kHz. The argument is |
| 177 | +a pointer to a ``uint32_t``. |
| 178 | + |
| 179 | +.. code-block:: c |
| 180 | +
|
| 181 | + uint32_t bandwidth; |
| 182 | + err = ioctl(radio, WLIOC_GETBANDWIDTH, &bandwidth); |
| 183 | +
|
| 184 | +``WLIOC_SETSPREAD`` |
| 185 | +---------------------- |
| 186 | + |
| 187 | +Sets the operating spread factor of the radio module. The argument is a |
| 188 | +``uint8_t`` containing the desired spread factor between 7 and 12 (inclusive). |
| 189 | + |
| 190 | +.. code-block:: c |
| 191 | +
|
| 192 | + err = ioctl(radio, WLIOC_SETSPREAD, 8); |
| 193 | +
|
| 194 | +``WLIOC_GETSPREAD`` |
| 195 | +---------------------- |
| 196 | + |
| 197 | +Gets the current operating spread factor of the radio module. The argument is a |
| 198 | +pointer to a ``uint8_t``. |
| 199 | + |
| 200 | +.. code-block:: c |
| 201 | +
|
| 202 | + uint8_t spread; |
| 203 | + err = ioctl(radio, WLIOC_GETSPREAD, &spread); |
| 204 | +
|
| 205 | +``WLIOC_SETPRLEN`` |
| 206 | +---------------------- |
| 207 | + |
| 208 | +Sets the operating preamble length of the radio module. The argument is a |
| 209 | +``uint16_t`` containing the desired preamble length. |
| 210 | + |
| 211 | +.. code-block:: c |
| 212 | +
|
| 213 | + err = ioctl(radio, WLIOC_SETPRLEN, 8); |
| 214 | +
|
| 215 | +``WLIOC_GETPRLEN`` |
| 216 | +---------------------- |
| 217 | + |
| 218 | +Gets the current operating preamble length of the radio module. The argument is |
| 219 | +a pointer to a ``uint16_t``. |
| 220 | + |
| 221 | +.. code-block:: c |
| 222 | +
|
| 223 | + uint16_t prlen; |
| 224 | + err = ioctl(radio, WLIOC_GETPRLEN, &prlen); |
| 225 | +
|
| 226 | +``WLIOC_SETMOD`` |
| 227 | +---------------------- |
| 228 | + |
| 229 | +Sets the operating modulation of the radio module. The argument is one of the |
| 230 | +values in ``enum rn2xx3_mod_e``. |
| 231 | + |
| 232 | +.. code-block:: c |
| 233 | +
|
| 234 | + err = ioctl(radio, WLIOC_SETMOD, RN2XX3_MOD_FSK); |
| 235 | +
|
| 236 | +``WLIOC_GETMOD`` |
| 237 | +---------------------- |
| 238 | + |
| 239 | +Gets the current operating modulation of the radio module. The argument is a |
| 240 | +pointer to a string which can store at least 10 characters. |
| 241 | + |
| 242 | +.. code-block:: c |
| 243 | +
|
| 244 | + char modulation[10]; |
| 245 | + err = ioctl(radio, WLIOC_GETMOD, modulation); |
0 commit comments