Add Core1 refresh recovery and shared SPI arbitration
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "sd_card.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "board_config.h"
|
||||
#include "shared_spi_bus.h"
|
||||
#include "ff.h" // FatFS
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -430,7 +431,10 @@ bool sd_card_init_with_board_config(void) {
|
||||
|
||||
uint sd_card_set_spi_speed(void) {
|
||||
if (!g_config) return 0;
|
||||
|
||||
|
||||
// SD file operations run with exclusive ownership of shared SPI bus.
|
||||
shared_spi_bus_lock();
|
||||
|
||||
// Save current speed and set to SD card speed
|
||||
uint current_speed = spi_get_baudrate(g_config->spi);
|
||||
spi_set_baudrate(g_config->spi, 12500 * 1000); // 12.5 MHz for SD card
|
||||
@@ -438,8 +442,18 @@ uint sd_card_set_spi_speed(void) {
|
||||
}
|
||||
|
||||
void sd_card_restore_spi_speed(uint baudrate) {
|
||||
if (!g_config || baudrate == 0) return;
|
||||
spi_set_baudrate(g_config->spi, baudrate);
|
||||
if (!g_config) {
|
||||
shared_spi_bus_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (baudrate != 0) {
|
||||
spi_set_baudrate(g_config->spi, baudrate);
|
||||
}
|
||||
|
||||
// Leave SD deselected before releasing bus.
|
||||
gpio_put(g_config->gpio_cs, 1);
|
||||
shared_spi_bus_unlock();
|
||||
}
|
||||
|
||||
bool sd_card_test_fatfs(void) {
|
||||
|
||||
65
lib/shared_spi_bus.c
Normal file
65
lib/shared_spi_bus.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "shared_spi_bus.h"
|
||||
#include "pico/mutex.h"
|
||||
#include "pico/multicore.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
static mutex_t g_spi_bus_mutex;
|
||||
static bool g_spi_bus_initialized = false;
|
||||
static uint32_t g_core_depth[2] = {0, 0};
|
||||
|
||||
void shared_spi_bus_init(void) {
|
||||
if (g_spi_bus_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_init(&g_spi_bus_mutex);
|
||||
g_spi_bus_initialized = true;
|
||||
}
|
||||
|
||||
void shared_spi_bus_lock(void) {
|
||||
if (!g_spi_bus_initialized) {
|
||||
shared_spi_bus_init();
|
||||
}
|
||||
|
||||
int core = get_core_num();
|
||||
if (core < 0 || core > 1) {
|
||||
core = 0;
|
||||
}
|
||||
|
||||
// Re-entrant lock on same core (needed for nested SD helpers).
|
||||
if (g_core_depth[core] > 0) {
|
||||
g_core_depth[core]++;
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_enter_blocking(&g_spi_bus_mutex);
|
||||
g_core_depth[core] = 1;
|
||||
}
|
||||
|
||||
void shared_spi_bus_unlock(void) {
|
||||
if (!g_spi_bus_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
int core = get_core_num();
|
||||
if (core < 0 || core > 1) {
|
||||
core = 0;
|
||||
}
|
||||
|
||||
if (g_core_depth[core] == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_core_depth[core]--;
|
||||
if (g_core_depth[core] == 0) {
|
||||
mutex_exit(&g_spi_bus_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void shared_spi_bus_force_recover(void) {
|
||||
// Used after Core1 reset to avoid stale mutex/depth state.
|
||||
mutex_init(&g_spi_bus_mutex);
|
||||
g_core_depth[0] = 0;
|
||||
g_core_depth[1] = 0;
|
||||
g_spi_bus_initialized = true;
|
||||
}
|
||||
18
lib/shared_spi_bus.h
Normal file
18
lib/shared_spi_bus.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef SHARED_SPI_BUS_H
|
||||
#define SHARED_SPI_BUS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Cross-core SPI bus lock for shared SD/display SPI usage.
|
||||
void shared_spi_bus_init(void);
|
||||
void shared_spi_bus_lock(void);
|
||||
void shared_spi_bus_unlock(void);
|
||||
void shared_spi_bus_force_recover(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SHARED_SPI_BUS_H
|
||||
Reference in New Issue
Block a user