{"id":20316130,"url":"https://github.com/lupyuen/lora-sx1262","last_synced_at":"2025-04-11T17:40:33.542Z","repository":{"id":41906848,"uuid":"420273225","full_name":"lupyuen/lora-sx1262","owner":"lupyuen","description":"LoRa Driver for Semtech SX1262 on Apache NuttX OS, Linux (PineDio USB Adapter) and BL602 IoT SDK (PineDio Stack BL604)","archived":false,"fork":false,"pushed_at":"2022-07-12T01:55:49.000Z","size":180,"stargazers_count":20,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-25T13:39:43.664Z","etag":null,"topics":["bl602","bl604","ch341","dkms","linux","lora","pinebookpro","pinedio","riscv","riscv32","spi"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lupyuen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["lupyuen"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["paypal.me/lupyuen"]}},"created_at":"2021-10-23T00:06:46.000Z","updated_at":"2025-01-09T11:10:44.000Z","dependencies_parsed_at":"2022-07-18T22:59:02.720Z","dependency_job_id":null,"html_url":"https://github.com/lupyuen/lora-sx1262","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Flora-sx1262","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Flora-sx1262/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Flora-sx1262/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Flora-sx1262/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lupyuen","download_url":"https://codeload.github.com/lupyuen/lora-sx1262/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248451338,"owners_count":21105852,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bl602","bl604","ch341","dkms","linux","lora","pinebookpro","pinedio","riscv","riscv32","spi"],"created_at":"2024-11-14T18:24:31.354Z","updated_at":"2025-04-11T17:40:33.513Z","avatar_url":"https://github.com/lupyuen.png","language":"C","funding_links":["https://github.com/sponsors/lupyuen","paypal.me/lupyuen"],"categories":[],"sub_categories":[],"readme":"# LoRa Driver for Semtech SX1262 on Linux (PineDio USB Adapter) and BL602 (PineDio Stack BL604)\n\n![PineDio LoRa USB Adapter](https://lupyuen.github.io/images/usb-pinedio.jpg)\n\n[__For SX1262 on Apache NuttX RTOS, see the `lorawan` branch__](https://github.com/lupyuen/lora-sx1262/tree/lorawan)\n\nRead the articles...\n\n-   [\"Build a Linux Driver for PineDio LoRa SX1262 USB Adapter\"](https://lupyuen.github.io/articles/usb)\n\n-   [\"LoRaWAN on PineDio Stack BL604 RISC-V Board\"](https://lupyuen.github.io/articles/lorawan2)\n\n-   [\"PineCone BL602 Talks LoRaWAN\"](https://lupyuen.github.io/articles/lorawan)\n\n-   [\"The Things Network on PineDio Stack BL604 RISC-V Board\"](https://lupyuen.github.io/articles/ttn)\n\n__CAUTION: Sending a LoRa Message on PineDio USB (not BL602) above 29 bytes will cause message corruption!__\n\n__CAUTION: Receiving a LoRa Message on PineDio USB (not BL602) above 28 bytes will cause message corruption!__\n\n(CH341 SPI seems to have trouble transferring a block of 32 bytes)\n\nFor BL602 / BL604: To add this driver to an existing BL602 / BL604 project:\n\n```bash\ncd bl_iot_sdk/components/3rdparty\ngit submodule add https://github.com/lupyuen/lora-sx1262\n```\n\nPorted from Semtech's Reference Implementation of SX1262 Driver...\n\nhttps://github.com/Lora-net/LoRaMac-node/tree/master/src/radio/sx126x\n\n# Build PineDio USB Driver\n\nTo build PineDio USB Driver on Pinebook Pro Manjaro Arm64...\n\n```bash\n## Install DKMS\nsudo pacman -Syu dkms base-devel --needed\n\n## Install Kernel Headers for Manjaro: https://linuxconfig.org/manjaro-linux-kernel-headers-installation\nuname -r \n## Should show \"5.14.12-1-MANJARO-ARM\" or similar\nsudo pacman -S linux-headers\npacman -Q | grep headers\n## Should show \"linux-headers 5.14.12-1\" or similar\n\n## Reboot to be safe\nsudo reboot now\n\n## Install CH341 SPI Driver\ngit clone https://github.com/rogerjames99/spi-ch341-usb.git\npushd spi-ch341-usb\n## TODO: Edit Makefile and change...\n##   KERNEL_DIR  = /usr/src/linux-headers-$(KVERSION)/\n## To...\n##   KERNEL_DIR  = /lib/modules/$(KVERSION)/build\nmake\nsudo make install\npopd\n\n## Unload the module ch341 if it has been automatically loaded\nlsmod | grep ch341\nsudo rmmod ch341\n\n## Load the new module\nsudo modprobe spi-ch341-usb\n\n## Plug in PineDio USB and check that the module has been correctly loaded.\n## See dmesg Log below. This needs to be checked every time we reboot\n## our computer and when we plug in PineDio USB.\ndmesg\n\n## If we see \"spi_ch341_usb: loading out-of-tree module taints kernel\",\n## Unplug PineDio USB, run \"sudo rmmod ch341\", plug in PineDio USB again\n## and recheck dmesg.\n\n## Download PineDio USB Driver\ngit clone --recursive https://github.com/lupyuen/lora-sx1262\ncd lora-sx1262\n\n## TODO: Edit src/main.c and uncomment READ_REGISTERS, SEND_MESSAGE or RECEIVE_MESSAGE.\n## See \"PineDio USB Operations\" below\n\n## Build PineDio USB Driver\nmake\n\n## Run PineDio USB Driver Demo.\n## See Output Log below.\nsudo ./lora-sx1262\n```\n\nMore about PineDio USB and CH341 SPI:\n\nhttps://wiki.pine64.org/wiki/JF%27s_note_on_PineDio_devices#RAW_LoRa_communication_between_USB_LoRa_adapter_and_PineDio_STACK\n\n# PineDio USB Operations\n\nThe PineDio USB Demo supports 3 operations...\n\n1.  Read SX1262 Registers:\n\n    Edit [`src/main.c`](src/main.c) and uncomment...\n\n    ```c\n    #define READ_REGISTERS\n    ```\n\n    (See the Read Register Log below)\n\n1.  Send LoRa Message:\n\n    Edit [`src/main.c`](src/main.c) and uncomment...\n\n    ```c\n    #define SEND_MESSAGE\n    ```\n\n    (See the Send Message Log below)\n\n1.  Receive LoRa Message:\n\n    Edit [`src/main.c`](src/main.c) and uncomment...\n\n    ```c\n    #define RECEIVE_MESSAGE\n    ```\n\n    (See the Receive Message Log below)\n\nNote that the CH341 GPIO programming is incomplete. We need to...\n\n1.  Init the GPIO Pins: `SX126xIoInit`\n    \n    [src/sx126x-linux.c#L65-L77](src/sx126x-linux.c#L65-L77)\n\n1.  Register GPIO Interrupt Handler for DIO1: `SX126xIoIrqInit`\n\n    [src/sx126x-linux.c#L79-L91](src/sx126x-linux.c#L79-L91)\n\n1.  Reset SX1262 via GPIO: `SX126xReset`\n\n    (For now we reset SX1262 by manually unplugging PineDio USB)\n\n    [src/sx126x-linux.c#L149-L169](src/sx126x-linux.c#L149-L169)\n\n1.  Check SX1262 Busy State via GPIO: `SX126xWaitOnBusy`\n\n    (For now we sleep 10 milliseconds)\n\n    [src/sx126x-linux.c#L171-L182](src/sx126x-linux.c#L171-L182)\n\n1.  Get DIO1 Pin State: `SX126xGetDio1PinState`\n\n    [src/sx126x-linux.c#L337-L344](src/sx126x-linux.c#L337-L344)\n\nWe also need Background Threads to receive LoRa Messages in the background...\n\n[src/main.c#L355-L408](src/main.c#L355-L408)\n\nMore about PineDio USB and CH341 GPIO:\n\nhttps://wiki.pine64.org/wiki/JF%27s_note_on_PineDio_devices#RAW_LoRa_communication_between_USB_LoRa_adapter_and_PineDio_STACK\n\n# PineDio USB Output Log\n\nOutput Log from PineDio USB Demo...\n\n## Read Registers\n\nRead SX1262 Registers on PineDio USB:\n\n```text\nread_registers\nSX126xIoInit\nSX126xWakeup\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: c0 00 \nspi rx: a2 22 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 00 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x00 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 01 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x01 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 02 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x02 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 03 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x03 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 04 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x04 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 05 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x05 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 06 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x06 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 07 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x07 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 08 00 00 \nspi rx: a2 a2 a2 a2 80 \nTODO: SX126xWaitOnBusy\nRegister 0x08 = 0x80\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 09 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x09 = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 0a 00 00 \nspi rx: a2 a2 a2 a2 01 \nTODO: SX126xWaitOnBusy\nRegister 0x0a = 0x01\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 0b 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x0b = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 0c 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x0c = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 0d 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x0d = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 0e 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x0e = 0x00\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 00 0f 00 00 \nspi rx: a2 a2 a2 a2 00 \nTODO: SX126xWaitOnBusy\nRegister 0x0f = 0x00\nDone!\n```\n\nSee below for the dmesg Read Registers Log.\n\n## Send Message\n\nTransmit 29-byte LoRa Message on PineDio USB:\n\n__CAUTION: Sending a LoRa Message on PineDio USB (not BL602) above 29 bytes will cause message corruption!__\n\n```text\ngcc -o lora-sx1262 \\\nnpl/linux/src/os_eventq.cc \\\n \\\nsrc/main.o src/radio.o src/sx126x.o src/sx126x-linux.o npl/linux/src/os_callout.o npl/linux/src/os_sem.o npl/linux/src/os_task.o npl/linux/src/os_atomic.o npl/linux/src/os_time.o npl/linux/src/os_mutex.o \\\n-g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -I include -I npl/linux/include -I npl/linux/include/nimble  \\\n-pthread -lrt -lstdc++  \\\n\ncc1plus: warning: command-line option ‘-Wno-old-style-declaration’ is valid for C/ObjC but not for C++\ncreate_task\ninit_driver\nTODO: SX126xReset\nSX126xIoInit\nTODO: SX126X interrupt init\nSX126xWakeup\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: c0 00 \nspi rx: ac 2c \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: ac ac \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 9d 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 96 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 8f 00 00 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetTxParams: power=22, rampTime=7\nSX126xGetDeviceId: SX1262\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 08 d8 00 00 \nspi rx: a2 a2 a2 a2 fe \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 d8 fe \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1 \nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 95 04 07 00 01 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 e7 38 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 8e 16 07 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=9\nspi tx: 1d 02 9f 00 00 00 00 00 00 00 00 00 00 \nspi rx: a2 a2 a2 a2 02 08 ac 08 89 3a a1 65 9a \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=9\nspi tx: 1d 02 9f 00 00 00 00 00 00 00 00 00 00 \nspi rx: a2 a2 a2 a2 02 08 ac 08 89 3a a1 65 9a \nTODO: SX126xWaitOnBusy\nTimerInit\nTimerInit\nRadioSetChannel: freq=923000000\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 98 e1 e9 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 86 39 b0 00 00 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetTxConfig: modem=1, power=14, fdev=0, bandwidth=0, datarate=7, coderate=1, preambleLen=8, fixLen=0, crcOn=1, freqHopOn=0, hopPeriod=0, iqInverted=0, timeout=3000\nRadioSetTxConfig: SpreadingFactor=7, Bandwidth=4, CodingRate=1, LowDatarateOptimize=0, PreambleLength=8, HeaderType=0, PayloadLength=255, CrcMode=1, InvertIQ=0\nRadioStandby\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetModem\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 8a 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 8b 07 04 01 00 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=6\nspi tx: 8c 00 08 00 ff 01 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 08 89 00 00 \nspi rx: a2 a2 a2 a2 04 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 89 04 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetRfTxPower\nSX126xSetTxParams: power=14, rampTime=7\nSX126xGetDeviceId: SX1262\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 08 d8 00 00 \nspi rx: a2 a2 a2 a2 fe \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 d8 fe \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1 \nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 95 04 07 00 01 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 e7 38 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 8e 0e 07 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetRxConfig\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 9f 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nRadioStandby\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetModem\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 8a 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 8b 07 04 01 00 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=6\nspi tx: 8c 00 08 00 ff 01 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: a0 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 07 36 00 00 \nspi rx: a2 a2 a2 a2 0d \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 07 36 0d \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetRxConfig done\nsend_message\nRadioSend: size=29\n50 49 4e 47 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 \nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 02 01 02 01 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSend: PreambleLength=8, HeaderType=0, PayloadLength=29, CrcMode=1, InvertIQ=0\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=6\nspi tx: 8c 00 08 00 1d 01 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=2, data_length=29\nspi tx: 0e 00 50 49 4e 47 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 83 00 00 00 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nDone!\n```\n\nNote that the 29-byte LoRa Message transmitted by PineDio USB is...\n\n```text\nsend_message\nRadioSend: size=29\n50 49 4e 47 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 \n```\n\nSee below for the dmesg Send Message Log.\n\n## Receive Message\n\nWhen we run this LoRa Transmitter on RAKwireless WisBlock...\n\nhttps://github.com/lupyuen/wisblock-lora-transmitter/tree/pinedio\n\n28-byte message transmitted by WisBlock is received OK by PineDio USB.\n\n__CAUTION: Receiving a LoRa Message on PineDio USB (not BL602) above 28 bytes will cause message corruption!__\n\nHere is the PineDio USB Receive Message Log...\n\n(See below for the WisBlock Transmitter Log)\n\n```text\ngcc -o lora-sx1262 \\\nnpl/linux/src/os_eventq.cc \\\n \\\nsrc/main.o src/radio.o src/sx126x.o src/sx126x-linux.o npl/linux/src/os_callout.o npl/linux/src/os_sem.o npl/linux/src/os_task.o npl/linux/src/os_atomic.o npl/linux/src/os_time.o npl/linux/src/os_mutex.o \\\n-g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -I include -I npl/linux/include -I npl/linux/include/nimble  \\\n-pthread -lrt -lstdc++  \\\n\ncc1plus: warning: command-line option ‘-Wno-old-style-declaration’ is valid for C/ObjC but not for C++\ncreate_task\ninit_driver\nTODO: SX126xReset\nSX126xIoInit\nTODO: SX126X interrupt init\nSX126xWakeup\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: c0 00 \nspi rx: d4 54 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: d4 d4 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 9d 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 96 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 8f 00 00 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetTxParams: power=22, rampTime=7\nSX126xGetDeviceId: SX1262\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 08 d8 00 00 \nspi rx: a2 a2 a2 a2 fe \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 d8 fe \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1 \nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 95 04 07 00 01 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 e7 38 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 8e 16 07 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=9\nspi tx: 1d 02 9f 00 00 00 00 00 00 00 00 00 00 \nspi rx: a2 a2 a2 a2 02 08 ac 08 89 aa a9 61 9b \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=9\nspi tx: 1d 02 9f 00 00 00 00 00 00 00 00 00 00 \nspi rx: a2 a2 a2 a2 02 08 ac 08 89 aa a9 61 9b \nTODO: SX126xWaitOnBusy\nTimerInit\nTimerInit\nRadioSetChannel: freq=923000000\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 98 e1 e9 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 86 39 b0 00 00 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetTxConfig: modem=1, power=14, fdev=0, bandwidth=0, datarate=7, coderate=1, preambleLen=8, fixLen=0, crcOn=1, freqHopOn=0, hopPeriod=0, iqInverted=0, timeout=3000\nRadioSetTxConfig: SpreadingFactor=7, Bandwidth=4, CodingRate=1, LowDatarateOptimize=0, PreambleLength=8, HeaderType=0, PayloadLength=255, CrcMode=1, InvertIQ=0\nRadioStandby\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetModem\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 8a 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 8b 07 04 01 00 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=6\nspi tx: 8c 00 08 00 ff 01 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 08 89 00 00 \nspi rx: a2 a2 a2 a2 04 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 89 04 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetRfTxPower\nSX126xSetTxParams: power=14, rampTime=7\nSX126xGetDeviceId: SX1262\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 08 d8 00 00 \nspi rx: a2 a2 a2 a2 fe \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 d8 fe \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nSX126xSetPaConfig: paDutyCycle=4, hpMax=7, deviceSel=0, paLut=1 \nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 95 04 07 00 01 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 e7 38 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 8e 0e 07 \nspi rx: a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetRxConfig\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 9f 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nRadioStandby\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 80 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetModem\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 8a 01 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=4\nspi tx: 8b 07 04 01 00 \nspi rx: a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=6\nspi tx: 8c 00 08 00 ff 01 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: a0 00 \nspi rx: a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=4, data_length=1\nspi tx: 1d 07 36 00 00 \nspi rx: a2 a2 a2 a2 0d \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 07 36 0d \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioSetRxConfig done\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 16 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 16 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nIRQ_RX_DONE\nTimerStop\nSX126xReadCommand: command=0x13, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 13 00 00 00 \nspi rx: d2 d2 1c 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=3, data_length=28\nspi tx: 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \nspi rx: d2 d2 d2 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 48 65 6c 6c 6f 00 01 02 \nTODO: SX126xWaitOnBusy\nSX126xReadCommand: command=0x14, size=3\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=3\nspi tx: 14 00 00 00 00 \nspi rx: d2 d2 1e 30 1e \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nRx done: \nRadioSleep\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 84 04 \nspi rx: d2 d2 \n03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 48 65 6c 6c 6f 00 01 02 \nIRQ_PREAMBLE_DETECTED\nIRQ_HEADER_VALID\nreceive_message\nRadioRx\nSX126xWakeup\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: c0 00 \nspi rx: 80 80 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: d2 d2 d2 d2 d2 d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: d4 d4 d4 d4 d4 d4 d4 d4 d4 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: d4 d4 d4 d4 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: d4 d4 d4 d4 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 16 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 16 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nIRQ_RX_DONE\nTimerStop\nSX126xReadCommand: command=0x13, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 13 00 00 00 \nspi rx: d2 d2 1c 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=3, data_length=28\nspi tx: 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \nspi rx: d2 d2 d2 48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nTODO: SX126xWaitOnBusy\nSX126xReadCommand: command=0x14, size=3\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=3\nspi tx: 14 00 00 00 00 \nspi rx: d2 d2 1e 2f 1e \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nRx done: \nRadioSleep\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 84 04 \nspi rx: d2 d2 \n48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nIRQ_PREAMBLE_DETECTED\nIRQ_HEADER_VALID\nreceive_message\nRadioRx\nSX126xWakeup\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: c0 00 \nspi rx: 80 80 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: d2 d2 d2 d2 d2 d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: d2 d2 d2 d2 d2 d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: d4 d4 d4 d4 d4 d4 d4 d4 d4 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: d4 d4 d4 d4 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: d4 d4 d4 d4 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 16 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 16 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nIRQ_RX_DONE\nTimerStop\nSX126xReadCommand: command=0x13, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 13 00 00 00 \nspi rx: d2 d2 1c 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=3, data_length=28\nspi tx: 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \nspi rx: d2 d2 d2 48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nTODO: SX126xWaitOnBusy\nSX126xReadCommand: command=0x14, size=3\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=3\nspi tx: 14 00 00 00 00 \nspi rx: d2 d2 1c 30 1e \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nRx done: \nRadioSleep\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: 84 04 \nspi rx: d2 d2 \n48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nIRQ_PREAMBLE_DETECTED\nIRQ_HEADER_VALID\nreceive_message\nRadioRx\nSX126xWakeup\nsx126x_hal_write: command_length=1, data_length=1\nspi tx: c0 00 \nspi rx: 80 80 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: a2 a2 a2 a2 a2 a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: a2 a2 a2 a2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nreceive_message\nRadioRx\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=8\nspi tx: 08 ff ff ff ff 00 00 00 00 \nspi rx: d2 d2 d2 d2 d2 d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTimerStart\nTimerStop\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=3, data_length=1\nspi tx: 0d 08 ac 94 \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=3\nspi tx: 82 ff ff ff \nspi rx: d2 d2 d2 d2 \nTODO: SX126xWaitOnBusy\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand: command=0x12, size=2\nTODO: SX126xWaitOnBusy\nsx126x_hal_read: command_length=2, data_length=2\nspi tx: 12 00 00 00 \nspi rx: d2 d2 00 00 \nstatus=0xd2\nTODO: SX126xWaitOnBusy\nTODO: SX126xWaitOnBusy\nsx126x_hal_write: command_length=1, data_length=2\nspi tx: 02 00 00 \nspi rx: d2 d2 d2 \nTODO: SX126xWaitOnBusy\nTODO: SX126xGetDio1PinState\nDone!\n```\n\nNote that the 28-byte LoRa Message received by PineDio USB is...\n\n```text\nRx done: \n48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nIRQ_PREAMBLE_DETECTED\nIRQ_HEADER_VALID\n```\n\nSee below for the dmesg Receive Message Log.\n\n# WisBlock Receiver Log\n\nWhen we run this LoRa Receiver on RAKwireless WisBlock...\n\nhttps://github.com/lupyuen/wisblock-lora-receiver\n\n29-byte message transmitted by PineDio USB is received OK by WisBlock...\n\n```text\n\u003e Executing task: platformio device monitor \u003c\n\n--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time\n--- More details at http://bit.ly/pio-monitor-filters\n--- Miniterm on /dev/cu.usbmodem14201  9600,8,N,1 ---\n--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---\n=====================================\nLoRaP2P Rx Test\n=====================================\nStarting Radio.Rx\nOnRxDone: Timestamp=18, RssiValue=-28 dBm, SnrValue=13, Data=50 49 4E 47 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 \n```\n\n__CAUTION: Sending a LoRa Message on PineDio USB (not BL602) above 29 bytes will cause message corruption!__\n\nWhen we run the [`sdk_app_lora`](https://github.com/lupyuen/bl_iot_sdk/tree/tsen/customer_app/sdk_app_lora) firmware on PineDio Stack BL604, WisBlock receives the 64-byte message OK.\n\nBut 64-byte messages sent by PineDio USB are consistently garbled when received by WisBlock.\n\n(CH341 SPI seems to have trouble transferring a block of 32 bytes)\n\n# WisBlock Transmitter Log\n\nWhen we run this LoRa Transmitter on RAKwireless WisBlock...\n\nhttps://github.com/lupyuen/wisblock-lora-transmitter/tree/pinedio\n\n28-byte message transmitted by WisBlock is received OK by PineDio USB.\n\nHere's the WisBlock Transmitter Log...\n\n```text\n\u003e Executing task: platformio device monitor \u003c\n\n--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time\n--- More details at http://bit.ly/pio-monitor-filters\n--- Miniterm on /dev/cu.usbmodem14201  9600,8,N,1 ---\n--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---\n=====================================\nLoRap2p Tx Test\n=====================================\nsend: 48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nOnTxDone\nsend: 48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nOnTxDone\nsend: 48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nOnTxDone\nsend: 48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 \nOnTxDone\n```\n\n__CAUTION: Receiving a LoRa Message on PineDio USB (not BL602) above 28 bytes will cause message corruption!__\n\n(CH341 SPI seems to have trouble transferring a block of 32 bytes)\n\n# PineDio USB dmesg Log\n\n## Connect USB\n\ndmesg Log when plugging PineDio USB to Pinebook Pro...\n\n```text\nusb 3-1:\nnew full-speed USB device number 2 using xhci-hcd\nNew USB device found, idVendor=1a86, idProduct=5512, bcdDevice= 3.04\nNew USB device strings: Mfr=0, Product=2, SerialNumber=0\nProduct: USB UART-LPT\n\nspi-ch341-usb 3-1:1.0:\n  ch341_usb_probe:\n    connect device\n    bNumEndpoints=3\n      endpoint=0 type=2 dir=1 addr=2\n      endpoint=1 type=2 dir=0 addr=2\n      endpoint=2 type=3 dir=1 addr=1\n\n  ch341_cfg_probe:\n    output cs0 SPI slave with cs=0\n    output cs0    gpio=0  irq=0 \n    output cs1 SPI slave with cs=1\n    output cs1    gpio=1  irq=1 \n    output cs2 SPI slave with cs=2\n    output cs2    gpio=2  irq=2 \n    input  gpio4  gpio=3  irq=3 \n    input  gpio6  gpio=4  irq=4 \n    input  err    gpio=5  irq=5 \n    input  pemp   gpio=6  irq=6 \n    input  int    gpio=7  irq=7 (hwirq)\n    input  slct   gpio=8  irq=8 \n    input  wait   gpio=9  irq=9 \n    input  autofd gpio=10 irq=10 \n    input  addr   gpio=11 irq=11 \n    output ini    gpio=12 irq=12 \n    output write  gpio=13 irq=13 \n    output scl    gpio=14 irq=14 \n    output sda    gpio=15 irq=15 \n\n  ch341_spi_probe:\n    start\n    SPI master connected to SPI bus 1\n    SPI device /dev/spidev1.0 created\n    SPI device /dev/spidev1.1 created\n    SPI device /dev/spidev1.2 created\n    done\n\n  ch341_irq_probe:\n    start\n    irq_base=94\n    done\n\n  ch341_gpio_probe: \n    start\n\n  ch341_gpio_get_direction:\n    gpio=cs0    dir=0\n    gpio=cs1    dir=0\n    gpio=cs2    dir=0\n    gpio=gpio4  dir=1\n    gpio=gpio6  dir=1\n    gpio=err    dir=1\n    gpio=pemp   dir=1\n    gpio=int    dir=1\n    gpio=slct   dir=1\n    gpio=wait   dir=1\n    gpio=autofd dir=1\n    gpio=addr   dir=1\n    gpio=ini    dir=0\n    gpio=write  dir=0\n    gpio=scl    dir=0\n    gpio=sda    dir=0\n\n  ch341_gpio_probe:\n    registered GPIOs from 496 to 511\n    done\n    connected\n\n  ch341_gpio_poll_function:\n    start\n\nusbcore: registered new interface driver ch341\nusbserial: USB Serial support registered for ch341-uart\n```\n\nThis means that the newer CH341 SPI Driver has been loaded.\n\n## Connect USB Failed\n\nIf we see this instead...\n\n```text\nusb 3-1: new full-speed USB device number 2 using xhci-hcd\nusb 3-1: New USB device found, idVendor=1a86, idProduct=5512, bcdDevice= 3.04\nusb 3-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0\nusb 3-1: Product: USB UART-LPT\nusbcore: registered new interface driver ch341\nusbserial: USB Serial support registered for ch341-uart\nch341 3-1:1.0: ch341-uart converter detected\nusb 3-1: ch341-uart converter now attached to ttyUSB0\nspi_ch341_usb: loading out-of-tree module taints kernel.\nusbcore: registered new interface driver spi-ch341-usb\n```\n\nIt means the older CH341 Non-SPI Driver has been loaded.\n\nTo fix this...\n\n1.  Unplug PineDio USB\n\n1.  Enter...\n\n    ```bash\n    sudo rmmod ch341\n    ```\n\n1.  Plug in PineDio USB\n\n1.  Enter...\n\n    ```bash\n    dmesg\n    ```\n\n    And recheck the messages.\n\n## Read Registers\n\ndmesg Log when PineDio USB is reading SX1262 registers...\n\n```text\naudit: type=1105 audit(1635493969.129:144): pid=3122 uid=1000 auid=1000 ses=4 subj==unconfined msg='op=PAM:session_open grantors=pam_limits,pam_unix,pam_permit acct=\"root\" exe=\"/usr/bin/sudo\" hostname=? addr=? terminal=/dev/pts/3 res=success'\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 1-1.1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\naudit: type=1106 audit(1635493969.499:145): pid=3122 uid=1000 auid=1000 ses=4 subj==unconfined msg='op=PAM:session_close grantors=pam_limits,pam_unix,pam_permit acct=\"root\" exe=\"/usr/bin/sudo\" hostname=? addr=? terminal=/dev/pts/3 res=success'\n```\n\n## Send Message\n\ndmesg Log when PineDio USB is transmitting a 29-byte LoRa Packet...\n\n__CAUTION: Sending a LoRa Message on PineDio USB (not BL602) above 29 bytes will cause message corruption!__\n\n```text\naudit: type=1105 audit(1634994194.295:1270): pid=72110 uid=1000 auid=1000 ses=4 subj==unconfined msg='op=PAM:session_open grantors=pam_limits,pam_unix,pam_permit acct=\"root\" exe=\"/usr/bin/sudo\" hostname=? addr=? terminal=/dev/pts/3 res=success'\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=13, csChange=1, result=13\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=13, csChange=1, result=13\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=7, csChange=1, result=7\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=7, csChange=1, result=7\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=7, csChange=1, result=7\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=31, csChange=1, result=31\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\naudit: type=1701 audit(1634994203.075:1271): auid=1000 uid=0 gid=0 ses=4 subj==unconfined pid=72111 comm=\"lora-sx1262\" exe=\"/home/luppy/lora-sx1262/lora-sx1262\" sig=6 res=1\n```\n\nNote that if we try to transmit a 64-byte packet, it won't appear in the dmesg Log.\n\n## Receive Message\n\ndmesg Log when PineDio USB is receiving a 28-byte LoRa Packet...\n\n__CAUTION: Receiving a LoRa Message on PineDio USB (not BL602) above 28 bytes will cause message corruption!__\n\n```text\naudit: type=1105 audit(1635046697.907:371): pid=29045 uid=1000 auid=1000 ses=7 subj==unconfined msg='op=PAM:session_open grantors=pam_limits,pam_unix,pam_permit acct=\"root\" exe=\"/usr/bin/sudo\" hostname=? addr=? terminal=/dev/pts/5 res=success'\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=13, csChange=1, result=13\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=13, csChange=1, result=13\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=7, csChange=1, result=7\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=7, csChange=1, result=7\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=31, csChange=1, result=31\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=31, csChange=1, result=31\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=31, csChange=1, result=31\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=5, csChange=1, result=5\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=2, csChange=1, result=2\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=9, csChange=1, result=9\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=4, csChange=1, result=4\nspi-ch341-usb 3-1:1.0: ch341_spi_transfer_low: len=3, csChange=1, result=3\naudit: type=1106 audit(1635046711.037:372): pid=29045 uid=1000 auid=1000 ses=7 subj==unconfined msg='op=PAM:session_close grantors=pam_limits,pam_unix,pam_permit acct=\"root\" exe=\"/usr/bin/sudo\" hostname=? addr=? terminal=/dev/pts/5 res=success'\n```\n\n# Connect BL602 to SX1262\n\nThe pins are defined here in [`include/sx126x-board.h`](include/sx126x-board.h)\n\nFrom [`include/sx126x-board.h`](include/sx126x-board.h):\n\n```c\n//  Below are the pin numbers for PineDio Stack BL604 with onboard SX1262.\n//  TODO: Change the pin numbers for your SX1262 connection to BL602 / BL604\n#define SX126X_SPI_IDX           0  //  SPI Port 0\n#define SX126X_SPI_SDI_PIN       0  //  SPI Serial Data In Pin  (formerly MISO)\n#define SX126X_SPI_SDO_PIN      17  //  SPI Serial Data Out Pin (formerly MOSI)\n#define SX126X_SPI_CLK_PIN      11  //  SPI Clock Pin\n#define SX126X_SPI_CS_PIN       15  //  SPI Chip Select Pin\n#define SX126X_SPI_CS_OLD        8  //  Unused SPI Chip Select Pin\n#define SX126X_NRESET           18  //  Reset Pin\n#define SX126X_DIO1             19  //  DIO1\n#define SX126X_BUSY_PIN         10  //  Busy Pin\n#define SX126X_DEBUG_CS_PIN      5  //  Debug Chip Select Pin, mirrors the High / Low State of SX1262 Chip Select Pin. Set to -1 if not needed.\n#define SX126X_TCXO_WAKEUP_TIME  5  //  Time required for the TCXO to wakeup (milliseconds)\n#define SX126X_SPI_BAUDRATE  (200 * 1000)  //  SPI Frequency (200 kHz)\n```\n\n# BL602 Demo Firmware\n\nTo transmit and receive LoRa packets with the driver, run the `sdk_app_lora` BL602 Demo Firmware...\n\n- [`sdk_app_lora`: BL602 Demo Firmware for LoRa SX1262 / SX1276 ](https://github.com/lupyuen/bl_iot_sdk/tree/master/customer_app/sdk_app_lora)\n\nHere's a sample log...\n\n```text\n# create_task\n\n# init_driver\nSX126xReset\nSX126xIoInit\nSX126X interrupt init\nSX126X register handler: GPIO 11\nSX126xWakeup\nSX126xGetDeviceId: SX1262\nSX126xSetRfTxPower\nSX126xGetDeviceId: SX1262\n\n# send_message\n\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_TX_DONE\nTx done\n\n# send_message\nSX126xWakeup\n\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_TX_DONE\nTx done\n\n# send_message\nSX126xWakeup\n\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_TX_DONE\nTx done\n\n# receive_message\nSX126xWakeup\n\n# RadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_PREAMBLE_DETECTED\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_HEADER_VALID\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_RX_DONE\nSX126xReadCommand\nSX126xReadCommand\nRx done: \n48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a \n\n# receive_message\nSX126xWakeup\n\n# RadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_PREAMBLE_DETECTED\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_HEADER_VALID\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_RX_DONE\nSX126xReadCommand\nSX126xReadCommand\nRx done: \n48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a \n\n# receive_message\nSX126xWakeup\n\n# RadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_PREAMBLE_DETECTED\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_HEADER_VALID\nRadioOnDioIrq\nRadioIrqProcess\nSX126xReadCommand\nIRQ_RX_DONE\nSX126xReadCommand\nSX126xReadCommand\nRx done: \n48 65 6c 6c 6f 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a \n\n# receive_message\nSX126xWakeup\nRadioOnRxTimeoutIrq\nRx timeout\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupyuen%2Flora-sx1262","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flupyuen%2Flora-sx1262","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupyuen%2Flora-sx1262/lists"}