Skip to content

Commit 63cf630

Browse files
committed
usb camera bugfix not working on -O3
1 parent a982373 commit 63cf630

1 file changed

Lines changed: 17 additions & 11 deletions

File tree

klib/usb/device/camera.hpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,8 @@ namespace klib::usb::device {
606606
static inline volatile uint8_t alt_mode = 0x00;
607607

608608
// a non owning buffer to the data from the user
609-
static inline std::span<const uint8_t> buffer = {};
609+
static inline const uint8_t *volatile buffer = nullptr;
610+
static inline volatile uint32_t bytes_to_transfer = 0;
610611

611612
template <typename Usb>
612613
static usb::handshake set_current_impl(const klib::usb::setup_packet &packet) {
@@ -740,17 +741,17 @@ namespace klib::usb::device {
740741
Usb::stall(endpoint, mode);
741742

742743
// clear the buffer
743-
buffer = {};
744+
buffer = nullptr;
744745
return;
745746
}
746747

747748
// get the size we can transfer
748-
const uint32_t size = klib::min(sizeof(video_buffer) - 2, buffer.size());
749+
const uint32_t size = klib::min(sizeof(video_buffer) - 2, bytes_to_transfer);
749750

750751
// check if we have any data left to send
751752
if (!size) {
752753
// no data left to send, clear the buffer
753-
buffer = {};
754+
buffer = nullptr;
754755

755756
// get the frame marker from the video buffer
756757
end_of_frame_marker[1] = (end_of_frame_marker[1] & (~0x1)) | (video_buffer[1] & 0x1);
@@ -764,10 +765,11 @@ namespace klib::usb::device {
764765
}
765766

766767
// copy the new data to the buffer
767-
std::copy_n(buffer.begin(), size, &video_buffer[2]);
768+
std::copy_n(buffer, size, &video_buffer[2]);
768769

769770
// move the buffer with the size
770-
buffer = buffer.subspan(size);
771+
buffer += size;
772+
bytes_to_transfer -= size;
771773

772774
// start a new write operation
773775
if constexpr (Async) {
@@ -820,10 +822,14 @@ namespace klib::usb::device {
820822
template <typename Usb, bool Async = true>
821823
static void write(std::span<const uint8_t> data) {
822824
// store the span into our local buffer
823-
buffer = data;
825+
buffer = data.data();
826+
bytes_to_transfer = data.size();
824827

825-
// flip the bits to mark we have a new frame
826-
video_buffer[1] ^= 0x01;
828+
// flip the bits to mark we have a new frame.
829+
// we get a reference to trick the compiler into
830+
// not optimizing this out
831+
volatile uint8_t& marker = video_buffer[1];
832+
marker ^= 0x01;
827833

828834
// check if we are in async mode
829835
if constexpr (Async) {
@@ -836,7 +842,7 @@ namespace klib::usb::device {
836842
}
837843
else {
838844
// not in async mode, write the data directly
839-
while (!buffer.empty()) {
845+
while (!bytes_to_transfer) {
840846
// write using the callback. This is not blocking. We wait in the loop below
841847
// before we continue writing
842848
status_callback<Usb, Async>(
@@ -870,7 +876,7 @@ namespace klib::usb::device {
870876
template <typename Usb>
871877
static bool is_busy() {
872878
// return if the endpoint is busy
873-
return (!buffer.empty()) || Usb::is_pending(
879+
return bytes_to_transfer || Usb::is_pending(
874880
usb::get_endpoint(VideoType::config.endpoint1.bEndpointAddress),
875881
usb::get_endpoint_mode(VideoType::config.endpoint1.bEndpointAddress)
876882
);

0 commit comments

Comments
 (0)