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;
|
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()
|
void portduinoCustomInit()
|
||||||
{
|
{
|
||||||
static struct argp_option options[] = {{"port", 'p', "PORT", 0, "The TCP port to use."},
|
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
|
// 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};
|
uint8_t dmac[6] = {0};
|
||||||
if (portduino_config.lora_spi_dev == "ch341") {
|
if (portduino_config.lora_spi_dev == "ch341") {
|
||||||
|
|||||||
Reference in New Issue
Block a user