USB for T4.0

Status
Not open for further replies.

WMXZ

Well-known member
I´m struggling with the T4.0 USB implementation. I try to implement the MTPDISK feature, which I urgently need on T4.0.
So, I try to learn from existing implementation.
At the moment I fail to understand the following snippet
Code:
int usb_rawhid_recv(void *buffer, uint32_t timeout)
{
	uint32_t wait_begin_at = systick_millis_count;
	while (1) {
		if (!usb_configuration) return -1; // usb not enumerated by host
		uint32_t status = usb_transfer_status(rx_transfer);
		if (!(status & 0x80)) break; // transfer descriptor ready
		if (systick_millis_count - wait_begin_at > timeout) return 0;
		yield();
	}
	memcpy(buffer, rx_buffer, RAWHID_RX_SIZE);
	memset(rx_transfer, 0, sizeof(rx_transfer));
	usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0);
	usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0);
	return RAWHID_RX_SIZE;
}
in particular, I do not understand the sequence
Code:
	[B]memcpy(buffer, rx_buffer, RAWHID_RX_SIZE);[/B]
	memset(rx_transfer, 0, sizeof(rx_transfer));
	usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0);
	usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0);
which I thought should read
Code:
	memset(rx_transfer, 0, sizeof(rx_transfer));
	usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0);
	usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0);
        [B]memcpy(buffer, rx_buffer, RAWHID_RX_SIZE);[/B]

Any clarification?
Can someone confirm that RAWHID works for T4.0?
Edit: Maybe because it is interrupt driven receive? Does bulk receive work at all?
 
Any clarification?

usb_prepare_transfer() and usb_receive() set up for the next transfer which will happen at some point in the future, whenever the USB host decides to send another OUT token (or PING then OUT, if Teensy's controller answered the last OUT with a NYET token). The memcpy which gets the data from the just-completed transfer should be done before you set up another transfer. Odds are slim the USB will be fast enough to receive another transfer that fast (overwriting the previously received data before you can copy to the user's buffer), but why risk it?

These very low level USB functions are all non-blocking. usb_transmit() also just sets up the transfer to happen at some point in the future, whenever the USB host controller decides to send an IN token.

You later discover when the transfer has actually happened, either by polling or an interrupt context callback. You choose which way by giving usb_config_tx() and usb_config_rx() a function pointer in the 4th parameter if you want callbacks from that endpoint, or NULL if you intend to poll the status bit.


Can someone confirm that RAWHID works for T4.0?

It definitely works when we test the USB connection on every Teensy 4.0. The test fixture send RawHID messages to tell Teensy 4.0 (and every other Teensy model) to turn its LED on and off, and measures the change in current consumption. The code for that test fixture is published here:

https://github.com/PaulStoffregen/USB_Tester
 
Thanks Paul.
OK, so it is my work now to understand why I cannot get MTP to work.
(I only run into timeout, but after 1 week playing, I may have something screwed up.)
 
I´m now one step further.
I cloned usb_rawhid into usb_mtp
I configured usb_mtp with interrupt context callbacks.
Not sure how to configure MTP_EVENTS (receive ore transmit, bulk or interrupt?)
PC (windows10) created a MTP USB Device without warning sign.

Unfortunately, PC only sends a Open Session command (0x1002; RX_Event fires) to which I respond with OK (TX event fires).
after that no activity anymore on MTP_RX_ENDDPOINT.
Only the ENDPOINT0 gets a 0x67A1 command, to which I (similar to Teensy3) answer with OK.
Strange is that NO GetDeviceInfo cmd (0x1001) is received.

Not sure what is going on
Docu says GetDeviceInfo, may not be called if Device is known. Not sure is this is the case and how to check this.
 
update,
by turning on Paul´s debug printf in usb.c I note that usb isr is called about 1/s with status bits USB_USBSTS_SRI and USB_USBSTS_TI0, which seems to be normal behaviour.

USB is keep running as reprogram request (SEREMU Reboot request) is handled correctly.

No clue yet how to get PC to ask for DeviceInfo and the rest of the disk info.
 
As I run out of ideas, I post the test program as zip file.

Instructions are in Read_me.txt. If in doubt ask.

Maybe someone has more luck and finds the solution to the puzzle.
It should be clear that the MTP responder is not complete, as I only wanted to advance step-by-step and the first step is failing (no GetDeviceInfo request)

for completeness, here is my initial printout
Code:
***********IMXRT Startup**********
test 1 -1234567 3
CCM_ANALOG_PLL_USB1=80003000
  enable USB clocks
CCM_ANALOG_PLL_USB1=80003040
need to switch to alternate clock during reconfigure of ARM PLL
USB PLL is running, so we can use 120 MHz
Freq: 12 MHz * 88 / 2 / 1
ARM PLL=80002042
ARM PLL needs reconfigure
ARM PLL=80002058
New Frequency: ARM=528000000, IPG=132000000
BURSTSIZE=00000808
BURSTSIZE=00000808
USB1_TXFILLTUNING=00000000
USB reset took 4 loops
analogInit
*suspend
*reset
*data 00000001
setup 00000680
complete 00000000
port at 480 Mbit
*data 00000001
setup 00000500
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000900
usb_seremu_configure
usb_mtp_configure
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
**data 00000001
setup 00000A21
complete 00000000
*data 00000001
setup 00000681
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000680
complete 00000000
*data 00000001
setup 00000080
complete 00000000
*data 00000000
complete 00100008
run_callbacks
rx 1 3
run_callbacks
tx_event 1 4
*data 00000000
complete 00000000
RX: 16 1 00001002 0 1
TX: 16 3 00002001 0 1
*data 00000000
complete 00080000
run_callbacks
tx 1 3
*****data 00000000
complete 00140000
run_callbacks
tx_event 1 4
******data 00000000
complete 00140000
run_callbacks
tx_event 1 4
******data 00000000
complete 00140000
run_callbacks
tx_event 1 4
******data 00000000
complete 00140000
run_callbacks
tx_event 1 4
******data 00000000
complete 00140000
run_callbacks
tx_event 1 4
******data 00000000
complete 00140000
run_callbacks
tx_event 1 4
**data 00000001
setup 000067A1
0x67A1 000067A1
complete 00000000
**************************************************************************************************************************************
etc. etc.

In fact, there are two questions,
why is GetDeviceInfo never called and why is sendEvent (every 5 seconds) not working?
 

Attachments

  • mtp-test.zip
    37.4 KB · Views: 55
A heads-up:
Got USB_MTPDISK working on T4.
As soon I have cleaned up SW and generated I library and further tests, I will post on MTP-Responder thread.
I also will suggest to Paul (via PR) mods to core.
 
Status
Not open for further replies.
Back
Top