diff --git a/src/include/piomatter/piomatter.h b/src/include/piomatter/piomatter.h index c43f7ec..1143a18 100644 --- a/src/include/piomatter/piomatter.h +++ b/src/include/piomatter/piomatter.h @@ -26,7 +26,7 @@ struct piomatter_base { piomatter_base &operator=(const piomatter_base &) = delete; virtual ~piomatter_base() {} - virtual void show() = 0; + virtual int show() = 0; double fps; }; @@ -48,7 +48,11 @@ struct piomatter : piomatter_base { show(); } - void show() override { + int show() override { + int err = pending_error_errno.exchange(0); // we're handling this error + if (err != 0) { + return err; + } int buffer_idx = manager.get_free_buffer(); auto &bufseq = buffers[buffer_idx]; bufseq.resize(geometry.schedules.size()); @@ -61,6 +65,7 @@ struct piomatter : piomatter_base { old_active_time = geometry.schedules[i].back().active_time; } manager.put_filled_buffer(buffer_idx); + return 0; } ~piomatter() { @@ -174,7 +179,15 @@ struct piomatter : piomatter_base { const auto &data = cur_buf[seq_idx]; auto datasize = sizeof(uint32_t) * data.size(); auto dataptr = const_cast(&data[0]); - pio_sm_xfer_data(pio, sm, PIO_DIR_TO_SM, datasize, dataptr); + // returns err = rp1_ioctl.... which seems to be a negative + // errno value + int r = + pio_sm_xfer_data(pio, sm, PIO_DIR_TO_SM, datasize, dataptr); + if (r != 0) { + pending_error_errno.store(-r); + printf("xfer_data() returned error %d (%s)\n", r, + strerror(-r)); + } t1 = monotonicns64(); if (t0 != t1) { fps = 1e9 / (t1 - t0); @@ -194,6 +207,7 @@ struct piomatter : piomatter_base { matrix_geometry geometry; colorspace converter; std::thread blitter_thread; + std::atomic pending_error_errno; }; } // namespace piomatter diff --git a/src/pymain.cpp b/src/pymain.cpp index 483b2dc..053aded 100644 --- a/src/pymain.cpp +++ b/src/pymain.cpp @@ -18,7 +18,14 @@ struct PyPiomatter { py::buffer buffer; std::unique_ptr matter; - void show() { matter->show(); } + void show() { + int err = matter->show(); + if (err != 0) { + errno = err; + PyErr_SetFromErrno(PyExc_OSError); + throw py::error_already_set(); + } + } double fps() const { return matter->fps; } };