@@ -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