Check for the SPI bufsize, and throw a useful error when set too small (#11072)
This commit is contained in:
co-authored by
GitHub
parent
a808e992a1
commit
19ddadf3ff
@@ -120,6 +120,44 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// A kernel SPI transfer is capped by the spidev module's `bufsiz` parameter (4096 by default).
|
||||
// LovyanGFX pushes the framebuffer in large chunks, so a display bigger than that budget fails
|
||||
// deep inside the driver with a bare -EMSGSIZE. Check up front so the user gets told what to fix.
|
||||
static void checkSpidevBufsiz()
|
||||
{
|
||||
if (portduino_config.display_spi_dev == "" || portduino_config.displayWidth == 0 || portduino_config.displayHeight == 0) {
|
||||
return;
|
||||
}
|
||||
switch (portduino_config.displayPanel) {
|
||||
case no_screen:
|
||||
case x11:
|
||||
case fb:
|
||||
case hub75:
|
||||
return; // not driven over spidev
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const long required = (long)portduino_config.displayWidth * portduino_config.displayHeight / 2 * 3;
|
||||
|
||||
std::ifstream bufsizFile("/sys/module/spidev/parameters/bufsiz");
|
||||
long bufsiz = 0;
|
||||
if (!bufsizFile.is_open() || !(bufsizFile >> bufsiz)) {
|
||||
// spidev may be built into the kernel without exposing the parameter; nothing to check.
|
||||
return;
|
||||
}
|
||||
|
||||
if (bufsiz < required) {
|
||||
std::cerr << "SPI display " << portduino_config.displayWidth << "x" << portduino_config.displayHeight
|
||||
<< " needs a spidev buffer of at least " << required << " bytes, but "
|
||||
<< "/sys/module/spidev/parameters/bufsiz is " << bufsiz << "." << std::endl;
|
||||
std::cerr << "Add 'spidev.bufsiz=" << required << "' to your kernel command line "
|
||||
<< "(/boot/firmware/cmdline.txt on Raspberry Pi OS) and reboot." << std::endl;
|
||||
std::cerr << "Or echo that value into /etc/modprobe.d/spidev.conf and reload the spidev module" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void portduinoCustomInit()
|
||||
{
|
||||
static struct argp_option options[] = {{"port", 'p', "PORT", 0, "The TCP port to use."},
|
||||
@@ -559,6 +597,11 @@ void portduinoSetup()
|
||||
}
|
||||
}
|
||||
|
||||
// if we have s SPI display, check /sys/module/spidev/parameters/bufsiz
|
||||
// It needs to be at least width * height / 2 * 3
|
||||
// fail with a more useful error message.
|
||||
checkSpidevBufsiz();
|
||||
|
||||
// if we're using a usermode driver, we need to initialize it here, to get a serial number back for mac address
|
||||
uint8_t dmac[6] = {0};
|
||||
if (portduino_config.lora_spi_dev == "ch341") {
|
||||
|
||||
Reference in New Issue
Block a user