STM32 USB problem summary

Source: Internet
Author: User

The following is my summary when I changed ST's Custom_HID routine to a "Custom USB device" routine, because I just learned about USB development, and some understanding errors are inevitable, please correct me.

1. usb_desc.c File

Modify according to the communication method used by your program. The usb_desc.h file defines the size of the array in the usb_desc.c file, the endpoint to be processed under ConfigDescriptor [SIZ_CONFIG_DESC], and the report Descriptor (mainly used for HID) should be added or deleted as needed) and CDC interface Descriptor (mainly used to implement USB to serial port. You can download an example of "Computer circle" written in D12.

Ii. Usb_conf.h file:

1. Modify the interruptions to be handled

After CNTR_CTRM processes the correct data transmission, such as responding to the host

CNTR_DOVRM/* DMA OVeR/underrun Mask */

CNTR_ERRM/* ERRor Mask */

CNTR_WKUPM 0/* WaKe UP Mask */

CNTR_SUSPM/* SUSPend Mask */

CNTR_RESETM mainly handles some initialization tasks after USB Reset

CNTR_SOFM/* Start Of Frame Mask */

CNTR_ESOFM/* Expected Start Of Frame Mask */

For example:

In usb_conf.h, # define IMR_MSK (CNTR_CTRM | CNTR_SOFM | CNTR_RESETM) determines whether the USB-related interrupt in the USB_CNTR register is enabled or blocked.

 

2. Add the endpoint cache address as needed. Modify the address based on the address in the cache area to prevent data overlap.

Modify the size of each buffer to 64 bytes as follows:

# Define ENDP1_TXADDR (0xC0)

# Define ENDP1_RXADDR (0xD0)

# Define ENDP2_TXADDR (0x100)

# Define ENDP2_RXADDR (0x140)

# Define ENDP3_TXADDR (0x180)

# Define ENDP3_RXADDR (0x1C0)

 

3. Modify EPX_IN_Callback and EPX_OUT_Callback under/* CTR service routines. Comment out the functions to be processed. NOP_Process indicates no processing.

 

File 3: usb_prop.c

1. Modify void XX_Reset (void) (for example, void Joystick_Reset (void ))

Generally, you do not need to modify the value of/* Initialize Endpoint 0 */. The following example shows the initialization of Endpoint 1. The principle of other ports is the same.

SetEPType (ENDP1, EP_INTERRUPT); // you can specify endpoint 1.

/* EP_BULK batch endpoint

EP_CONTROL control endpoint

EP_ISOCHRNOUS synchronization endpoint

EP_INTERRUPT interrupt endpoint */

SetEPTxAddr (ENDP1, ENDP1_TXADDR); // you can specify the buffer base address of endpoint 1.

SetEPTxCount (ENDP1, 64); // configure the Tx buffer counter

SetEPRxStatus (ENDP1, EP_RX_DIS); // you can call this operation to disable endpoint reception.

SetEPTxStatus (ENDP1, EP_TX_NAK); // you can specify endpoint 1 to send no response.

/*

# Define EP_RX_DIS (0x0000) // The EndPoint RX DISabled EndPoint is DISabled.

# Define EP_RX_STALL (0x1000) // EndPoint RX STALLed EndPoint receiving Delay

# Define EP_RX_NAK (0x2000) // The EndPoint RX NAKed EndPoint receives no response

# Define EP_RX_VALID (0x3000) // The EndPoint rx valid EndPoint is VALID

# Define EP_TX_DIS (0x0000) // EndPoint TX DISabled

# Define EP_TX_STALL (0x0010) // EndPoint TX STALLed

# Define EP_TX_NAK (0x0020) // EndPoint TX NAKed

# Define EP_TX_VALID (0x0030) // EndPoint tx valid */

 

2. Delete irrelevant descriptors.

For example, the following struct Initialization is not required for a custom USB device:

ONE_DESCRIPTOR Joystick_Report_Descriptor

ONE_DESCRIPTOR Mouse_Hid_Descriptor

 

3. Modify the data request processing RESULT XX_Data_Setup (u8 RequestNo.

For example, when the Custom_HID routine is changed to a "Custom USB device" routine, you can delete the following code:

If (RequestNo = GET_DESCRIPTOR)

& (Type_Recipient = (STANDARD_REQUEST | INTERFACE_RECIPIENT ))

& (PInformation-> USBwIndex0 = 0 ))

{

 

If (pInformation-> USBwValue1 = REPORT_DESCRIPTOR)

{

CopyRoutine = Joystick_GetReportDescriptor;

}

Else if (pInformation-> USBwValue1 = HID_DESCRIPTOR_TYPE)

{

CopyRoutine = Joystick_GetHIDDescriptor;

}

 

}

 

4. Delete irrelevant get descriptor return functions

For custom USB devices, the following functions are not required:

Joystick_GetReportDescriptor

Joystick_GetHIDDescriptor

 

 

Iv. usb_endp.c File

1. added the previously defined interrupt Data processing function.

For example:

Void EP1_OUT_Callback (void)

{

Write and receive code

}

 

5. data sending and receiving, for example

1. receive data

U8 DataLen;

DataLen = GetEPRxCount (ENDP1 );

PMAToUserBufferCopy (TX1_buffer, ENDP1_RXADDR, DataLen );

SetEPRxValid (ENDP1 );

Usartmediasend (DataLen );

Count_out = 1;

 

2. Data Transmission

UserToPMABufferCopy (InBuffer, GetEPTxAddr (ENDP1), 64 );

SetEPTxCount (ENDP1, 64 );

SetEPTxValid (ENDP1 );

========================================================== ==========================================


Summary 2: After the STM32 USB program changed bulk ep to a dual-buffer mechanism, it went viral to 1 MB/S! From: http://www.powermcu.com/bbs/viewthread.php? Tid = 693


When I tested my own USB driver the day before yesterday, I found that the OUT transmission rate from the host to the STM32 (from the host to the device) was only kb/S, and it was truly dizzy. After research, we found that it is the relationship between the PIPE MaxTransferSize parameter set in the driver. Originally, we set 64 to only 65535 kb/S, and set it to according to the driver values of other USB devices, test the usb out speed, reaching kb/S, and finally solved the bottleneck of the driver. However, the communication rate of USB 2.0 at full speed is 12 Mb/S. How can we eliminate the CRC, Token, SOF, and other overhead by more than kb/S. After checking on the Internet, it should basically be kb/S ~ At a speed above kb/S, I should be able to greatly improve my current speed.
Look at the program and find
Void EP3_OUT_Callback (void) // calls the callback function of EP3 OUT when EP3 receives data.
{
Count_out = GetEPRxCount (ENDP3); // obtain the length of received data
PMAToUserBufferCopy (buffer_out, ENDP3_RXADDR, count_out); // copy data from the buffer zone of USB EP3 RX to the array specified by the user.
SetEPRxValid (ENDP3); // The valid status after the copy is completed, so that EP3 can send the ACK Host to send the next packet
}
Try to comment out the PMAToUserBufferCopy sentence (so that the STM32 will not process the received data) and then test the speed, surprised to find that the speed has reached kb/S! After thinking carefully at night, the data must be used. The time consumed during the data copying process is always indispensable. Generally, the BULK data receiving process of the USB device is as follows: after receiving the data, set NAK to copy the buffer data to the user zone (User processing process) to send an ACK notification to the host to complete the reception and send the next one, according to the above steps, USB reception is performed step by step. As long as STM32 does not complete data processing, the status will always be NAK, and the host will continuously send this data packet, wasting bandwidth, so it will make it difficult for me to increase the maximum speed by kb/S! Unwilling to do so ~~
Last night, I carefully studied the USB content in the STM32 Technical Reference Manual, which mentioned that BULK can use the dual BUFFER MECHANISM (PING-PONG) for processing, which can solve the problem above. The principle of the dual-buffer mechanism is to allocate two receiving buffers. The user processing of STM32 and the USB interface can use two buffers alternately. When the USB endpoint receives data and writes one of the buffers, the user's application can process another buffer at the same time, so that the buffer is exchanged in turn, as long as the user's processing program completes processing within the time segment received by the USB endpoint, the USB communication speed will not be affected at all!
Program modification
1. Modify the settings of EP3_OUT,
// ZYP: Change EP3 to the BULK dual-buffer mode -------------------------
SetEPType (ENDP3, EP_BULK );
SetEPDoubleBuff (ENDP3 );
SetEPDblBuffAddr (ENDP3, ENDP3_BUF0Addr, ENDP3_BUF1Addr );
SetEPDblBuffCount (ENDP3, EP_DBUF_OUT, VIRTUAL_COM_PORT_DATA_SIZE );
ClearDTOG_RX (ENDP3 );
ClearDTOG_TX (ENDP3 );
ToggleDTOG_TX (ENDP3 );
SetEPRxStatus (ENDP3, EP_RX_VALID );
SetEPTxStatus (ENDP3, EP_TX_DIS );
//------------------------------------------------------
Ii. Modify the EP3_OUT callback function
Void EP3_OUT_Callback (void)
{
// ZYP: The following is the processing function modified to EP3 Double Buffer OUT.
If (GetENDPOINT (ENDP3) & EP_DTOG_TX) // first determine the buffer zone in which the received data is stored.
{
FreeUserBuffer (ENDP3, EP_DBUF_OUT); // first releases the user's possession of the buffer. In this way, the next USB receiving process can be performed immediately, and the user performs the following processing in parallel.
Count_out = GetEPDblBuf0Count (ENDP3); // read the number of received bytes
PMAToUserBufferCopy (buffer_out, ENDP3_BUF0Addr, count_out );
}
Else
{
FreeUserBuffer (ENDP3, EP_DBUF_OUT );
Count_out = GetEPDblBuf1Count (ENDP3 );
PMAToUserBufferCopy (buffer_out, ENDP3_BUF1Addr, count_out );
}
}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.