Hi, I have been having some trouble lately using an SD card together with a LoRa radio. I am using separate SPI instances for LoRa and the SD card (SPI1 and SPI2). However, when I initialize the SD card and enable backend logging to it, neither LoRa works properly nor are the logs correctly stored on the SD card (they are usually corrupted).
I have tried multiple approaches to make it work, but my main question is whether there is any incompatibility between them or if this is simply a firmware issue.
Here is my code:
main.c:
#include <zephyr/device.h>#include <zephyr/kernel.h>#include <zephyr/lorawan/lorawan.h>#include <zephyr/logging/log.h>#include <zephyr/sys/reboot.h>#include <string.h>#include "settings.h"#include <zephyr/storage/disk_access.h>#include <zephyr/fs/fs.h>#include <ff.h>LOG_MODULE_REGISTER(MAIN_, CONFIG_LOG_DEFAULT_LEVEL);#define LORA_MSG_MAX_SIZE 32#define LORA_MSG_QUEUE_LEN 5K_MSGQ_DEFINE(lora_msgq, LORA_MSG_MAX_SIZE, LORA_MSG_QUEUE_LEN, 4);K_SEM_DEFINE(lora_start_sem, 0, 1);static void dl_callback(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len, const uint8_t *hex_data) { LOG_INF("Port %d, Pending %d, RSSI %ddB, SNR %ddBm, Time %d", port, flags & LORAWAN_DATA_PENDING, rssi, snr, !!(flags & LORAWAN_TIME_UPDATED)); if (hex_data && len > 0) { LOG_HEXDUMP_INF(hex_data, len, "Payload:"); }}static void lorawan_datarate_changed(enum lorawan_datarate dr) { uint8_t unused, max_size; lorawan_get_payload_sizes(&unused, &max_size); LOG_INF("New Datarate: DR_%d | Max Payload: %d", dr, max_size);}void lora_thread(void) { const struct device *lora_dev; struct lorawan_join_config join_cfg; struct lorawan_downlink_cb downlink_cb; uint8_t dev_eui[] = LORAWAN_DEV_EUI; uint8_t join_eui[] = LORAWAN_JOIN_EUI; uint8_t app_key[] = LORAWAN_APP_KEY; uint8_t tx_buf[LORA_MSG_MAX_SIZE]; int ret; k_sem_take(&lora_start_sem, K_FOREVER); LOG_INF("LoRaWAN thread starting"); lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0)); if (!device_is_ready(lora_dev)) { LOG_ERR("LoRa device not ready"); return; } ret = lorawan_start(); if (ret < 0) { LOG_ERR("lorawan_start failed: %d", ret); return; } downlink_cb.port = LW_RECV_PORT_ANY; downlink_cb.cb = dl_callback; lorawan_register_downlink_callback(&downlink_cb); lorawan_register_dr_changed_callback(lorawan_datarate_changed); join_cfg.mode = LORAWAN_ACT_OTAA; join_cfg.dev_eui = dev_eui; join_cfg.otaa.join_eui = join_eui; join_cfg.otaa.app_key = app_key; join_cfg.otaa.nwk_key = app_key; uint8_t tries = 0; while (tries++ < 5) { LOG_INF("Joining network via OTAA"); if (!lorawan_join(&join_cfg)) { LOG_INF("Successfully joined network"); goto JOINED; } LOG_ERR("Failed to join. Retrying in 10 seconds..."); k_sleep(K_SECONDS(10)); } LOG_ERR("Failed to join network after %d attempts. Reseting board...", 5); k_sleep(K_SECONDS(2)); sys_reboot(SYS_REBOOT_COLD); return;JOINED: while (true) { k_msgq_get(&lora_msgq, tx_buf, K_FOREVER); ret = lorawan_send(2, tx_buf, strlen((char *)tx_buf), LORAWAN_MSG_CONFIRMED); if (ret < 0) { LOG_ERR("lorawan_send failed: %d", ret); } else { LOG_INF("Data sent"); } }}K_THREAD_DEFINE(lora_tid, 8192, lora_thread, NULL, NULL, NULL, 1, 0, 0);FATFS fatfs;#define MOUNT_POINT "/SD:"static struct fs_mount_t fatfs_mnt = { .type = FS_FATFS, .mnt_point = MOUNT_POINT, .fs_data = &fatfs,};int main(void) { static const char *disk_pdrv = "SD"; uint64_t memory_size_mb; uint32_t block_count; uint32_t block_size; char msg[] = "helloworld"; k_sleep(K_SECONDS(5)); LOG_INF("Main started"); if (disk_access_init(disk_pdrv) != 0) { LOG_ERR("Storage init Error!"); return -1; } if (disk_access_ioctl(disk_pdrv, DISK_IOCTL_GET_SECTOR_COUNT, &block_count)) { LOG_ERR("Unable to get sector count"); return -1; } if (disk_access_ioctl(disk_pdrv, DISK_IOCTL_GET_SECTOR_SIZE, &block_size)) { LOG_ERR("Unable to get sector size"); return -1; } memory_size_mb = (uint64_t)block_count * block_size; LOG_INF("Memory Size %uMB", (uint32_t)(memory_size_mb >> 20)); if (fs_mount(&fatfs_mnt) == FR_OK) { LOG_INF("SD Card mounted"); } else { LOG_ERR("Error mounting SD Card"); } k_sem_give(&lora_start_sem); while (true) { if (k_msgq_put(&lora_msgq, msg, K_NO_WAIT) != 0) { LOG_WRN("MSGQ full, dropping message"); } else { LOG_INF("Message queued"); } k_sleep(K_SECONDS(20)); }}proj.conf:
CONFIG_LOG=yCONFIG_LORA=yCONFIG_LORAWAN=yCONFIG_LORAMAC_REGION_EU868=yCONFIG_MAIN_STACK_SIZE=4096CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096CONFIG_REBOOT=y# NVSCONFIG_NVS=yCONFIG_FLASH=yCONFIG_FLASH_MAP=yCONFIG_FLASH_PAGE_LAYOUT=y# SD CardCONFIG_DISK_ACCESS=y CONFIG_FILE_SYSTEM=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_LOG_BACKEND_FS=y CONFIG_LOG_BACKEND_FS_OUTPUT_TEXT=y CONFIG_LOG_BACKEND_FS_DIR="/SD:" CONFIG_LOG_BACKEND_FS_FILE_PREFIX="log" CONFIG_LOG_BACKEND_FS_FILES_LIMIT=100CONFIG_LOG_BACKEND_FS_FILE_SIZE=131072 CONFIG_LOG_BACKEND_FS_OVERWRITE=y/dts-v1/;#include <nordic/nrf52840_qiaa.dtsi>#include <nordic/nrf52840_partition.dtsi>#include "esav01_nrf52840-pinctrl.dtsi"#include <zephyr/dt-bindings/lora/sx126x.h>/ { model = "Board 1"; compatible = "nordic,esav01_nrf52840"; chosen { zephyr,console = &uart1; zephyr,shell-uart = &uart1; zephyr,uart-mcumgr = &uart1; zephyr,bt-mon-uart = &uart1; zephyr,bt-c2h-uart = &uart1; }; aliases { lora0 = &lora; };};®0 { status = "okay";};®1 { regulator-initial-mode = <NRF5X_REG_MODE_DCDC>;};&uicr { gpio-as-nreset; nfct-pins-as-gpios;};&gpiote { status = "okay";};&gpio0 { status = "okay";};&gpio1 { status = "okay";};&uart1 { compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; pinctrl-0 = <&uart1_default>; pinctrl-1 = <&uart1_sleep>; pinctrl-names = "default", "sleep";};&i2c1 { status = "disabled";};&spi0 { status = "disabled";};&spi1 { compatible = "nordic,nrf-spim"; status = "okay"; cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; lora: lora@0 { compatible = "semtech,sx1262"; reg = <0>; reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; busy-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; dio1-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; dio2-tx-enable; dio3-tcxo-voltage = <SX126X_DIO3_TCXO_3V3>; tcxo-power-startup-delay-ms = <5>; spi-max-frequency = <1000000>; };};&spi2 { compatible = "nordic,nrf-spim"; status = "okay"; cs-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; pinctrl-0 = <&spi2_default>; pinctrl-1 = <&spi2_sleep>; pinctrl-names = "default", "sleep"; sdhc0: sdhc@0 { compatible = "zephyr,sdhc-spi-slot"; reg = <0>; status = "okay"; mmc { compatible = "zephyr,sdmmc-disk"; disk-name = "SD"; status = "okay"; }; spi-max-frequency = <25000000>; };};&qspi { status = "disabled";}