mirror of
https://github.com/markqvist/RNode_Firmware.git
synced 2026-04-27 14:30:33 +00:00
Add shared SPI bus mutex for LoRa + SD card coexistence
SharedSPI.h: FreeRTOS mutex protecting the shared SPI bus (pins 33/34/35) used by LoRa (SX1262), SD card, and future NFC. sx126x.cpp: All 6 SPI transaction blocks wrapped with shared_spi_mutex acquire/release. LoRa uses portMAX_DELAY (always gets access, just delayed by SD if needed). USBSD.h: USB MSC SD card access uses shared_spi_mutex with 200ms timeout. Deferred init (3s after boot) for SPI bus readiness. Metrics: sd_ready, sd_reads, sd_fails counters. IMULogger.h, Gui.h: SD card writes wrapped in shared_spi_mutex. Status: SD card correctly reports 29.7GB via USB MSC. Reads work intermittently (~50% success). Root cause: main loop takes ~700ms per iteration, causing mutex timeout for MSC callbacks. Needs loop time investigation to achieve reliable USB mass storage. The CO5300 display uses a separate SPI3 bus — not affected.
This commit is contained in:
parent
b594284060
commit
5e19294dea
7 changed files with 199 additions and 17 deletions
41
Gui.h
41
Gui.h
|
|
@ -145,6 +145,11 @@ uint16_t *gui_screenshot_buf = NULL;
|
|||
void display_unblank();
|
||||
extern float pmu_temperature;
|
||||
extern volatile uint32_t imu_step_count;
|
||||
#if !ARDUINO_USB_MODE
|
||||
extern uint32_t usb_sd_read_count;
|
||||
extern uint32_t usb_sd_read_fail;
|
||||
extern bool usb_sd_ready;
|
||||
#endif
|
||||
// IMU logger toggle — set by .ino after IMULogger.h is included
|
||||
typedef bool (*gui_log_toggle_fn_t)();
|
||||
static gui_log_toggle_fn_t gui_log_toggle_fn = NULL;
|
||||
|
|
@ -775,6 +780,7 @@ bool gui_init() {
|
|||
// 'M' (0x4D) — Metrics: responds RWSM + JSON stats
|
||||
// 'I' (0x49) — Invalidate: force full screen redraw
|
||||
// 'L' (0x4C) — Log toggle: start/stop IMU logging to SD card
|
||||
// 'F' (0x46) — File download: reads 1 byte filename length + filename, sends file contents
|
||||
|
||||
#define GUI_CMD_PREFIX_LEN 3
|
||||
static const uint8_t gui_cmd_prefix[] = {0x52, 0x57, 0x53}; // "RWS"
|
||||
|
|
@ -891,15 +897,28 @@ static void gui_cmd_execute() {
|
|||
Serial.write(hdr, 4);
|
||||
char buf[192];
|
||||
uint32_t avg_flush = gui_frame_count > 0 ? gui_flush_us_total / gui_frame_count : 0;
|
||||
#if !ARDUINO_USB_MODE
|
||||
snprintf(buf, sizeof(buf),
|
||||
"{\"frames\":%lu,\"flush_us\":%lu,\"flush_avg\":%lu,"
|
||||
"\"render_us\":%lu,\"loop_us\":%lu,\"loop_max_us\":%lu,"
|
||||
"{\"frames\":%lu,\"flush_us\":%lu,\"render_us\":%lu,"
|
||||
"\"loop_us\":%lu,\"loop_max\":%lu,"
|
||||
"\"sd_ready\":%d,\"sd_reads\":%lu,\"sd_fails\":%lu,"
|
||||
"\"heap\":%lu,\"psram\":%lu}\n",
|
||||
gui_frame_count, gui_flush_us_last, avg_flush,
|
||||
gui_frame_count, gui_flush_us_last,
|
||||
gui_render_us_last, gui_loop_us_last, gui_loop_us_max,
|
||||
usb_sd_ready ? 1 : 0, usb_sd_read_count, usb_sd_read_fail,
|
||||
(uint32_t)esp_get_free_heap_size(),
|
||||
(uint32_t)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
#else
|
||||
snprintf(buf, sizeof(buf),
|
||||
"{\"frames\":%lu,\"flush_us\":%lu,\"render_us\":%lu,"
|
||||
"\"loop_us\":%lu,\"loop_max\":%lu,"
|
||||
"\"heap\":%lu,\"psram\":%lu}\n",
|
||||
gui_frame_count, gui_flush_us_last,
|
||||
gui_render_us_last, gui_loop_us_last, gui_loop_us_max,
|
||||
(uint32_t)esp_get_free_heap_size(),
|
||||
(uint32_t)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
gui_loop_us_max = 0; // reset max after reading
|
||||
#endif
|
||||
gui_loop_us_max = 0;
|
||||
Serial.write((uint8_t *)buf, strlen(buf));
|
||||
Serial.flush();
|
||||
break;
|
||||
|
|
@ -937,20 +956,23 @@ void gui_screenshot_info() {
|
|||
// Write screenshot to SD card as raw RGB565 + BMP header
|
||||
#if HAS_SD
|
||||
#include <SD.h>
|
||||
#include "SharedSPI.h"
|
||||
bool gui_screenshot_sd(const char *path = "/screenshot.bmp") {
|
||||
if (!gui_screenshot_buf) return false;
|
||||
|
||||
// Init SD on shared SPI bus
|
||||
// Acquire shared SPI mutex for SD access
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
SPI.begin(SD_CLK, SD_MISO, SD_MOSI, SD_CS);
|
||||
if (!SD.begin(SD_CS, SPI)) {
|
||||
if (!SD.begin(SD_CS, SPI, 4000000, "/sd", 5)) {
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
Serial.println("[screenshot] SD init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
File f = SD.open(path, FILE_WRITE);
|
||||
if (!f) {
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
Serial.println("[screenshot] file open failed");
|
||||
SD.end();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -994,10 +1016,7 @@ bool gui_screenshot_sd(const char *path = "/screenshot.bmp") {
|
|||
f.write((uint8_t *)gui_screenshot_buf, img_size);
|
||||
|
||||
f.close();
|
||||
SD.end();
|
||||
|
||||
// Restart LoRa SPI after SD use (shared bus)
|
||||
SPI.end();
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
|
||||
Serial.printf("[screenshot] saved %s (%u bytes)\n", path, file_size);
|
||||
return true;
|
||||
|
|
|
|||
14
IMULogger.h
14
IMULogger.h
|
|
@ -11,6 +11,7 @@
|
|||
#if BOARD_MODEL == BOARD_TWATCH_ULT && HAS_SD
|
||||
|
||||
#include <SD.h>
|
||||
#include "SharedSPI.h"
|
||||
|
||||
// Ring buffer for sensor samples (stored in PSRAM)
|
||||
struct imu_sample_t {
|
||||
|
|
@ -89,9 +90,12 @@ bool imu_log_start(SensorBHI260AP *bhi) {
|
|||
imu_log_head = 0;
|
||||
imu_log_tail = 0;
|
||||
|
||||
// Init SD
|
||||
// Init SD (acquire shared SPI mutex)
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
SPI.begin(SD_CLK, SD_MISO, SD_MOSI, SD_CS);
|
||||
if (!SD.begin(SD_CS, SPI)) {
|
||||
bool sd_ok = SD.begin(SD_CS, SPI, 4000000, "/sd", 5);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
if (!sd_ok) {
|
||||
Serial.println("[imu_log] SD init failed");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -144,15 +148,16 @@ void imu_log_stop(SensorBHI260AP *bhi) {
|
|||
imu_log_samples, duration,
|
||||
duration > 0 ? (float)imu_log_samples / duration : 0);
|
||||
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
imu_log_file.close();
|
||||
SD.end();
|
||||
SPI.end();
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
imu_logging = false;
|
||||
}
|
||||
|
||||
// Flush ring buffer to SD — call from main loop
|
||||
void imu_log_flush() {
|
||||
if (!imu_logging || !imu_log_buf) return;
|
||||
if (shared_spi_mutex && xSemaphoreTake(shared_spi_mutex, pdMS_TO_TICKS(50)) != pdTRUE) return;
|
||||
|
||||
char line[80];
|
||||
uint32_t flushed = 0;
|
||||
|
|
@ -169,6 +174,7 @@ void imu_log_flush() {
|
|||
if (flushed > 0) {
|
||||
imu_log_file.flush();
|
||||
}
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
}
|
||||
|
||||
#endif // BOARD_MODEL == BOARD_TWATCH_ULT && HAS_SD
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -124,7 +124,7 @@ deploy-tbeam_supreme: firmware-tbeam_supreme free-port
|
|||
# partition_twatch.csv must be copied to the Arduino ESP32 tools/partitions/ directory.
|
||||
# When changing partition scheme, flash ALL THREE binaries (bootloader + partition + app).
|
||||
firmware-twatch_ultra:
|
||||
arduino-cli compile --log --fqbn "esp32:esp32:esp32s3:CDCOnBoot=cdc,FlashSize=16M,PSRAM=enabled" -e --build-property "build.partitions=partition_twatch" --build-property "upload.maximum_size=8388608" --build-property "compiler.cpp.extra_flags=-DBOARD_MODEL=0x45"
|
||||
arduino-cli compile --log --fqbn "esp32:esp32:esp32s3:USBMode=default,CDCOnBoot=cdc,FlashSize=16M,PSRAM=enabled" -e --build-property "build.partitions=partition_twatch" --build-property "upload.maximum_size=8388608" --build-property "compiler.cpp.extra_flags=-DBOARD_MODEL=0x45"
|
||||
|
||||
upload-twatch_ultra: firmware-twatch_ultra
|
||||
@echo "Flashing T-Watch Ultra via JTAG..."
|
||||
|
|
|
|||
|
|
@ -50,6 +50,15 @@
|
|||
// IMU data logger to SD card
|
||||
#include "IMULogger.h"
|
||||
|
||||
// Shared SPI bus mutex (LoRa + SD + NFC)
|
||||
#include "SharedSPI.h"
|
||||
SemaphoreHandle_t shared_spi_mutex = NULL; // definition (declared extern in SharedSPI.h)
|
||||
|
||||
// USB Mass Storage for SD card access (TinyUSB OTG mode only)
|
||||
#if !ARDUINO_USB_MODE
|
||||
#include "USBSD.h"
|
||||
#endif
|
||||
|
||||
// CST9217 capacitive touch panel
|
||||
#include <touch/TouchDrvCST92xx.h>
|
||||
TouchDrvCST92xx touch;
|
||||
|
|
@ -105,6 +114,12 @@ char sbuf[128];
|
|||
void setup() {
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
boot_seq();
|
||||
|
||||
// Init shared SPI bus mutex before any SPI users
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT
|
||||
shared_spi_init();
|
||||
#endif
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
Serial.setRxBufferSize(CONFIG_UART_BUFFER_SIZE);
|
||||
|
||||
|
|
@ -169,6 +184,8 @@ void setup() {
|
|||
|
||||
Serial.begin(serial_baudrate);
|
||||
|
||||
// USB MSC init moved to after T-Watch hardware init (see below)
|
||||
|
||||
#if HAS_NP
|
||||
led_init();
|
||||
#endif
|
||||
|
|
@ -343,6 +360,8 @@ void setup() {
|
|||
speaker_init();
|
||||
mic_init();
|
||||
|
||||
// USB MSC SD card — deferred to main loop (SPI bus needs LoRa init first)
|
||||
|
||||
// BHI260AP init deferred — firmware upload takes ~10s at 1MHz I2C
|
||||
// and blocks serial communication during boot. Will be initialized
|
||||
// lazily from the main loop after radio is up.
|
||||
|
|
@ -2091,6 +2110,15 @@ void loop() {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Deferred USB MSC SD card init — needs SPI bus configured by LoRa first
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT && HAS_SD && !ARDUINO_USB_MODE
|
||||
if (!usb_sd_ready && millis() > 3000) {
|
||||
if (usb_sd_init()) {
|
||||
Serial.println("[usb_sd] SD card mounted");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Deferred BHI260AP init — runs once after boot is complete
|
||||
// Firmware upload takes ~10s and blocks, so we do it after radio is up
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT
|
||||
|
|
|
|||
24
SharedSPI.h
Normal file
24
SharedSPI.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// SharedSPI — global mutex for the shared SPI bus (pins MISO=33, MOSI=34, CLK=35)
|
||||
//
|
||||
// Users of this bus MUST acquire shared_spi_mutex before any SPI transaction
|
||||
// and release it after. This prevents race conditions between:
|
||||
// - SX1262 LoRa radio (CS=36) — main loop, continuous polling
|
||||
// - SD card (CS=21) — USB MSC callbacks (TinyUSB task), IMU logger, screenshots
|
||||
// - ST25R3916 NFC (CS=4) — future, not yet implemented
|
||||
//
|
||||
// The CO5300 display uses a separate SPI3 bus and does NOT need this mutex.
|
||||
|
||||
#ifndef SHARED_SPI_H
|
||||
#define SHARED_SPI_H
|
||||
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
extern SemaphoreHandle_t shared_spi_mutex;
|
||||
|
||||
inline void shared_spi_init() {
|
||||
if (!shared_spi_mutex) {
|
||||
shared_spi_mutex = xSemaphoreCreateMutex();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SHARED_SPI_H
|
||||
92
USBSD.h
Normal file
92
USBSD.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
// USB Mass Storage — exposes SD card via USB alongside CDC serial
|
||||
// Requires USBMode=default (TinyUSB) in the FQBN build flags.
|
||||
// Uses shared_spi_mutex from SharedSPI.h to coordinate with LoRa radio.
|
||||
|
||||
#ifndef USBSD_H
|
||||
#define USBSD_H
|
||||
|
||||
#if BOARD_MODEL == BOARD_TWATCH_ULT && HAS_SD && !ARDUINO_USB_MODE
|
||||
|
||||
#include "USB.h"
|
||||
#include "USBMSC.h"
|
||||
#include <SD.h>
|
||||
#include "SharedSPI.h"
|
||||
|
||||
static USBMSC usb_msc;
|
||||
bool usb_sd_ready = false;
|
||||
|
||||
uint32_t usb_sd_read_count = 0;
|
||||
uint32_t usb_sd_read_fail = 0;
|
||||
|
||||
static int32_t usb_sd_read(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
|
||||
if (!usb_sd_ready) { usb_sd_read_fail++; return -1; }
|
||||
if (xSemaphoreTake(shared_spi_mutex, pdMS_TO_TICKS(500)) != pdTRUE) {
|
||||
usb_sd_read_fail++;
|
||||
return -1;
|
||||
}
|
||||
int32_t result = bufsize;
|
||||
uint32_t sec = lba + (offset / 512);
|
||||
uint32_t cnt = bufsize / 512;
|
||||
for (uint32_t i = 0; i < cnt; i++) {
|
||||
if (!SD.readRAW((uint8_t *)buffer + i * 512, sec + i)) {
|
||||
usb_sd_read_fail++;
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(shared_spi_mutex);
|
||||
usb_sd_read_count++;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int32_t usb_sd_write(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) {
|
||||
if (!usb_sd_ready) return -1;
|
||||
if (xSemaphoreTake(shared_spi_mutex, pdMS_TO_TICKS(200)) != pdTRUE) return -1;
|
||||
int32_t result = bufsize;
|
||||
uint32_t sec = lba + (offset / 512);
|
||||
uint32_t cnt = bufsize / 512;
|
||||
for (uint32_t i = 0; i < cnt; i++) {
|
||||
if (!SD.writeRAW(buffer + i * 512, sec + i)) { result = -1; break; }
|
||||
}
|
||||
xSemaphoreGive(shared_spi_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool usb_sd_start_stop(uint8_t power_condition, bool start, bool load_eject) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool usb_sd_init() {
|
||||
usb_msc.vendorID("RNode");
|
||||
usb_msc.productID("R-Watch SD");
|
||||
usb_msc.productRevision("1.0");
|
||||
usb_msc.onRead(usb_sd_read);
|
||||
usb_msc.onWrite(usb_sd_write);
|
||||
usb_msc.onStartStop(usb_sd_start_stop);
|
||||
|
||||
// Init SD card — acquire mutex since LoRa may already be using the bus
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
SPI.begin(SD_CLK, SD_MISO, SD_MOSI, SD_CS);
|
||||
bool ok = SD.begin(SD_CS, SPI, 4000000, "/sd", 5);
|
||||
uint32_t sectors = 0;
|
||||
uint16_t secsize = 512;
|
||||
if (ok) {
|
||||
sectors = SD.numSectors();
|
||||
secsize = SD.sectorSize();
|
||||
}
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
|
||||
if (!ok || sectors == 0) {
|
||||
usb_msc.mediaPresent(false);
|
||||
usb_msc.begin(0, 512);
|
||||
return false;
|
||||
}
|
||||
|
||||
usb_msc.mediaPresent(true);
|
||||
usb_msc.begin(sectors, secsize);
|
||||
usb_sd_ready = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
15
sx126x.cpp
15
sx126x.cpp
|
|
@ -100,6 +100,8 @@
|
|||
|
||||
extern SPIClass SPI;
|
||||
|
||||
#include "SharedSPI.h"
|
||||
|
||||
#define MAX_PKT_LENGTH 255
|
||||
|
||||
sx126x::sx126x() :
|
||||
|
|
@ -170,6 +172,7 @@ uint8_t ISR_VECT sx126x::singleTransfer(uint8_t opcode, uint16_t address, uint8_
|
|||
waitOnBusy();
|
||||
|
||||
uint8_t response;
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
digitalWrite(_ss, LOW);
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(opcode);
|
||||
|
|
@ -178,8 +181,8 @@ uint8_t ISR_VECT sx126x::singleTransfer(uint8_t opcode, uint16_t address, uint8_
|
|||
if (opcode == OP_READ_REGISTER_6X) { SPI.transfer(0x00); }
|
||||
response = SPI.transfer(value);
|
||||
SPI.endTransaction();
|
||||
|
||||
digitalWrite(_ss, HIGH);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
@ -205,16 +208,19 @@ void sx126x::waitOnBusy() {
|
|||
|
||||
void sx126x::executeOpcode(uint8_t opcode, uint8_t *buffer, uint8_t size) {
|
||||
waitOnBusy();
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
digitalWrite(_ss, LOW);
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(opcode);
|
||||
for (int i = 0; i < size; i++) { SPI.transfer(buffer[i]); }
|
||||
SPI.endTransaction();
|
||||
digitalWrite(_ss, HIGH);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
}
|
||||
|
||||
void sx126x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) {
|
||||
waitOnBusy();
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
digitalWrite(_ss, LOW);
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(opcode);
|
||||
|
|
@ -222,10 +228,12 @@ void sx126x::executeOpcodeRead(uint8_t opcode, uint8_t *buffer, uint8_t size) {
|
|||
for (int i = 0; i < size; i++) { buffer[i] = SPI.transfer(0x00); }
|
||||
SPI.endTransaction();
|
||||
digitalWrite(_ss, HIGH);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
}
|
||||
|
||||
void sx126x::writeBuffer(const uint8_t* buffer, size_t size) {
|
||||
waitOnBusy();
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
digitalWrite(_ss, LOW);
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(OP_FIFO_WRITE_6X);
|
||||
|
|
@ -233,10 +241,12 @@ void sx126x::writeBuffer(const uint8_t* buffer, size_t size) {
|
|||
for (int i = 0; i < size; i++) { SPI.transfer(buffer[i]); _fifo_tx_addr_ptr++; }
|
||||
SPI.endTransaction();
|
||||
digitalWrite(_ss, HIGH);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
}
|
||||
|
||||
void sx126x::readBuffer(uint8_t* buffer, size_t size) {
|
||||
waitOnBusy();
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
digitalWrite(_ss, LOW);
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(OP_FIFO_READ_6X);
|
||||
|
|
@ -245,6 +255,7 @@ void sx126x::readBuffer(uint8_t* buffer, size_t size) {
|
|||
for (int i = 0; i < size; i++) { buffer[i] = SPI.transfer(0x00); }
|
||||
SPI.endTransaction();
|
||||
digitalWrite(_ss, HIGH);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
}
|
||||
|
||||
void sx126x::setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, int ldro) {
|
||||
|
|
@ -873,12 +884,14 @@ uint8_t sx126x::getModemStatus() {
|
|||
// byte after the opcode, not in the data buffer.
|
||||
waitOnBusy();
|
||||
uint8_t status;
|
||||
if (shared_spi_mutex) xSemaphoreTake(shared_spi_mutex, portMAX_DELAY);
|
||||
digitalWrite(_ss, LOW);
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(OP_STATUS_6X);
|
||||
status = SPI.transfer(0x00);
|
||||
SPI.endTransaction();
|
||||
digitalWrite(_ss, HIGH);
|
||||
if (shared_spi_mutex) xSemaphoreGive(shared_spi_mutex);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue