The protocol stack of usb msd host has been transplanted to the customer in recent days. I found that porting 100 + k code from one m3 to another m3 is really not simple, mainly because of the m3 of different manufacturers. The difference between peripherals is too great. After describing the underlying hardware layer, it is found that the USB protocol is too different. I have to make some modifications to it. Let's take a look at the protocol stack framework of the MSD host of efm32.
1. hardware schematic design
Refer to the schematic diagram of the host section in the USB section of reference manual. As shown in:
In this figure, a boost chip with a power supply management of 3 V to 5 V is used as the power supply for managing vbus. If the Board has 5 V, you can directly input it to the power management chip.
In addition, you need to select a crystal oscillator with a fundamental frequency of 48 MHz to provide the USB with a reference clock source.
2. Software Framework:
/* USB related data */
Static_ubuf (tmpbuf, 1024); // defines a buffer for USB. # Define static_ubuf (x, y) efm32_align (4) Static uint8_t X [(y) + 3 )&~ 3];
Usbh_init_typedef is = usbh_init_default;
Usbh_init (& IS); // initialize the USB protocol stack
For (;;)
{
// Wait for ever on device attachment, waiting for USB flash drive to be inserted
// The second parameter is timeout in seconds, 0 means for ever
If (usbh_waitfordeviceconnectionb (tmpbuf, 0) = usb_status_ OK)
{
// Device is now connected and ready for enumeration! // The USB flash disk is detected.
If (msdh_init (tmpbuf, sizeof (tmpbuf )))
{
/* Initialize filesystem */
Fileresult = f_mount (0, & fatfs );
If (fileresult = fr_ OK)
{
// Perform the FAT file operation
// FileResult = f_open ();
// FileResult = f_read ();
}
}
}
// Wait for disconnection
While (USBH_DeviceConnected ()){}
// Disable USB peripheral, power down USB port.
USBH_Stop ();
}
A single view of the above framework is actually relatively simple, but you need to pay attention to the following points:
1. You can configure the macro definition DEBUG_USB_API and USB_USE_PRINTF to determine whether to enable the USB debugging switch. Generally, you do not need to enable this function during debugging. The default USB config. h header file contains the following definitions:
# Ifndef NDEBUG
/* Debug usb api functions (illegal input parameters etc .)*/
# Define debug_usb_api/* uncomment to turn on */
# Define usb_use_printf/* uncomment to enable */
# Endif
Therefore, ndebug is pre-defined in IAR to disable USB debugging output.
2. timer0 is used as the benchmark clock by default in the USB protocol stack. Modify em_usbtimer.c if necessary. It is at the beginning of the file. In this file, the corresponding interrupt response function is also implemented.
3. If you need overcurrent protection, you also need to define the gpio port for overcurrent detection in usbconfig. h.
# Define usb_vbusovrcur_port gpioporta
# Define usb_vbusovrcur_pin 14
# Define usb_vbusovrcur_polarity usb_vbusovrcur_polarity_low
If there is no overcurrent protection function, you need to define usb_vbusovrcur_port as usb_vbusovrcur_port_none.
4. interrupt handling
In the USB protocol stack, the Guanzhong and open interrupt functions, int_disable () and int_enable () in emlib are widely used (). Instead of directly using _ disable_irq () and _ enable_irq ().
So pay attention to it in the main function.
The above is the current experience, and there may be errors in understanding. You are also welcome to point out.