Sorry, I have not totally followed your needs. That is if you have two programs one on PC or the like and another on the Teensy, and you have full control of both programs, than you may have lots of options:
Example: If you are writing 6 10 bit analog reads, you could simply output: the raw data as binary to the other side who converts the values to what that means...
Again depending on needs you could simply write out 12 bytes for the 6 values or if your values are only 10 bits each you could pack that into 60 bits or 8 bytes, but that may be more trouble than it is worth.
Or you can convert your code over to maybe use RAWHID:
https://www.pjrc.com/teensy/rawhid.html
that allows you to send up 1000 64 byte packets per second. In these cases you setup a 64 byte buffer and you tell it to send. You might give it a 0 timeout, which will tell you all buffers are full and then you keep a list of these. Again this could be real simple stuff. Like create a structure that each one holds lets say 5 of these (5*12) + maybe sequence number... You could allocate a lot of these in DMAMEM (upper 512KB) memory, and your query functions, simply have a Pointer to the next one to write to, and when it is full, you increment to next one (wrapping around), and if you have some that have not output yet, when possible you check to see if you have outstanding HID packets to send, and try to resend. If succeeds update that point to next pending one...
Again the above logic can work for either RAWHID or standard Serial. In standard Serial. And simply outputting 16 bit values, I would probably first start off each output maybe with value 0xFFFF as I know that is not a valid 10 bit analog value, so it can help know when you are starting new packet of information...
My quick and dirty code for debug output buffering in the USBHost code is:
Code:
class DebugMemoryStream : public Stream {
public:
DebugMemoryStream(uint8_t *buffer, uint32_t size_buffer) : _buffer(buffer), _size_buffer(size_buffer) {}
void setBuffer(uint8_t *buffer, uint32_t size_buffer) {
_buffer = buffer;
_size_buffer = size_buffer;
}
// From Stream
virtual int available() {
if (_head <= _tail) return _tail - _head;
return (_size_buffer - _head) + _tail;
}
virtual int read() {
if (_head == _tail) return -1;
int return_value = _buffer[_head++];
if (_head == _size_buffer) _head = 0;
return return_value;
}
virtual int peek() {
if (_head == _tail) return -1;
return _buffer[_head];
}
// From Print will use default except for one byte version
using Print::write;
virtual size_t write(uint8_t b) {
if (!_enable_writes) return 0; // not writing now
if (_bypass) return Serial.write(b);
uint32_t tail = _tail;
if (++tail == _size_buffer) tail = 0;
if (tail == _head) {
if (_stop_writes_on_overflow) return 0; // no room - if keep first received data
else if (++_head == _size_buffer) _head = 0;
}
_buffer[_tail] = b;
_tail = tail; //
return 1;
}
virtual int availableForWrite(void) {
return _size_buffer - available();
}
// other specific functions
void enable(bool enable_writes) {_enable_writes = enable_writes;}
void stopWritesOnOverflow(bool fStop) {_stop_writes_on_overflow = fStop;}
void clear() {_head = _tail = 0; }
void byPass(bool bypass=true) {_bypass = true;}
bool bypass() {return _bypass;}
private:
uint8_t *_buffer; // The buffer
uint32_t _size_buffer;
uint32_t _tail = 0; // next plact to write to.
uint32_t _head = 0; // next place to read from.
bool _enable_writes = true; // by default we are enabled
bool _bypass;
bool _stop_writes_on_overflow = false; // If we fill buffer to we keep the first bytes or overwrite those...
};
But again this is not directly what you would need... You may not need to use the Stream class but maybe only the Print class code... Doing the Stream code does allow me to do things like:
Code:
void write_buffered_stuff_to_serial() {
int count = mybufferedSerial.available();
int count_write = Serial.availableForWrite();
if (count > count_write) count = count_write;
while (count--) {
Serial.write( mybufferedSerial.read());
}
}
Which is not the most efficient way of doing this, but for my needs it worked. For faster stuff, I would probably build in method to my Serial class, that would do something similar, but instead of reading and writing one byte at a time, I would: do Serial writes directly from my own queue, with a couple of cases. That is only do writes of continuous stuff, that is if the data has wrapped around in the queue, only output the first part of the output, up through the end of the queue... Next time it should be such that then all of the data should then be contiguous. Hope that makes sense. But again for my debug code, I kept it simple.