BTW,
My Github has also a tested T3.6 version on events included (in MTP.cpp)
I would keep event handling outside cores
I did a couple of days ago a PR on teensy3/usb_desc.h to have tx events, but no action by Paul yet
Thanks,
I am having fun and think this will be a nice enhancement for the Teensy platform!
I started off with your Teensy 3.x event code yesterday:
Code:
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#include "usb_mtp.h"
extern "C"
{
usb_packet_t *tx_event_packet=NULL;
int usb_init_events(void)
{
tx_event_packet = usb_malloc();
if(tx_event_packet) return 1; else return 0;
}
int usb_mtp_sendEvent(const void *buffer, uint32_t len, uint32_t timeout)
{
if (!usb_configuration) return -1;
memcpy(tx_event_packet->buf, buffer, len);
tx_event_packet->len = len;
usb_tx(MTP_EVENT_ENDPOINT, tx_event_packet);
return len;
}
}
And I was able to send one event, maybe my understanding is not correct, but my looking at other T3.x Hardware USB code, gives me the impression that,
The usb_malloc will allocate a buffer out of the usb memory pool, which you can use. And then when you call usb_tx, it will put that buffer onto a queue to be transferred and
once that transfer is complete, that usb buffer will be freed. (i.e. the allocation is only good for one send).
So I modeled my version after the suff in usb_keyboard.c...
Code:
static int usb_keymedia_send(void)
{
uint32_t wait_count=0;
usb_packet_t *tx_packet;
const uint16_t *consumer;
while (1) {
if (!usb_configuration) {
return -1;
}
if (usb_tx_packet_count(KEYMEDIA_ENDPOINT) < TX_PACKET_LIMIT) {
tx_packet = usb_malloc();
if (tx_packet) break;
}
if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
transmit_previous_timeout = 1;
return -1;
}
yield();
}
// 44444444 44333333 33332222 22222211 11111111
// 98765432 10987654 32109876 54321098 76543210
consumer = keymedia_consumer_keys;
*(tx_packet->buf + 0) = consumer[0];
*(tx_packet->buf + 1) = (consumer[1] << 2) | ((consumer[0] >> 8) & 0x03);
*(tx_packet->buf + 2) = (consumer[2] << 4) | ((consumer[1] >> 6) & 0x0F);
*(tx_packet->buf + 3) = (consumer[3] << 6) | ((consumer[2] >> 4) & 0x3F);
*(tx_packet->buf + 4) = consumer[3] >> 2;
*(tx_packet->buf + 5) = keymedia_system_keys[0];
*(tx_packet->buf + 6) = keymedia_system_keys[1];
*(tx_packet->buf + 7) = keymedia_system_keys[2];
tx_packet->len = 8;
usb_tx(KEYMEDIA_ENDPOINT, tx_packet);
return 0;
}
Where they check to see how may packets they still have pending to send on their endpoint, and wait until it is under some max value, and then they allocate a new one, fill it in and call the usb_tx.
Which is why mine (minus debug stuff looks like:
Code:
#define EVENT_TX_PACKET_LIMIT 4
int usb_mtp_sendEvent(const void *buffer, uint32_t len, uint32_t timeout)
{
usb_packet_t *event_packet;
elapsedMillis em = 0;
while (1) {
if (!usb_configuration) {
return -1;
}
if (usb_tx_packet_count(MTP_EVENT_ENDPOINT) < EVENT_TX_PACKET_LIMIT) {
event_packet = usb_malloc();
if (event_packet) break;
}
if (em > timeout) {
return -1;
}
yield();
}
memcpy(event_packet->buf, buffer, len);
event_packet->len = len;
usb_tx(MTP_EVENT_ENDPOINT, event_packet);
return len;
}
And then yesterday I was able to run the T3.6 and do events. Where I created a file, and did the F5 and it was there, likewise create a directory... And delete a file.
Likewise am able to do the same events on Windows.
Note: at some point it would be interesting to have the ability for a Teensy sketch that is setup to use MTP to know in their sketch when a file is added or changed from the PC side.
Example the user sends a new configuration file or maybe you are running a python interpreter and want to know if a new python script has been downloaded...
Again having fun!