Hello,
i have two absolute identical applications except the controller because currently i have to change it.
The first application is already running. It is an LPC1778 with Keil RTX and Keil USB CDC device only. I use the Keil USB_CM3.lib and usbd_LPC177x8x.c for USB communication.
I had to change the controller to an STM32F439. Therefore i exchanged the Keil usbd_LPC177x8x.c with the Keil usbd_STM32F4xxFS.c.
My new project has following USB CDC files from Keil RL included:
- SVC_Table - USB_CM3.lib - usb_config_FS.c - usb_lib.c - usbd_STM32F4xx_FS.c - usbd_user_cdc_acm.c
Unfortunately the STM32F439 application is not running correctly. If i plug in the USB cable and connect the applications with my PC both applications seems to work correct. Both USB CDC devices subscribe correctly to the PC. Both USB CDC descriptors and application descriptors are absolutely identical. I checked it with USBlyzer.
My problem ist:
The LPC1778 application communicates almost every 3s with my PC. USBlyzer says: Request : Request Details: Bulk or Interrupt Transfer 18 bytes data Bulk or Interrupt Transfer 18 bytes data Bulk or Interrupt Transfer 18 bytes data Bulk or Interrupt Transfer 4096 bytes data Bulk or Interrupt Transfer 4096 bytes data Bulk or Interrupt Transfer 4096 bytes data
My applications with the LPC1778 executes periodical the function USBD_WriteEP.
After i connected my STM32F4 with my PC there is no further communication after the descriptors. My PC program which can send correctly data to the LPC1778 application can not communicate with the STM32F439 application. Do you have any advices for me ?
I suggest you try latest MDK and middleware.
I used Keil MDK4 for both applications
You can use \ARM\Boards\Keil\MCBSTM32F400\RL\USB\Device\CDC_ACM\ as a reference
Thank you for the advice.
I already checked the example a few days ago. The USB files are identical and my settings too.
Is it possible that there are some mistakes in the Keil usbd_STM32F4xx_FS.c file ?
#define DIEPTSIZ(EPNum) *(&OTG->DIEPTSIZ0 + EPNum * 8) #define DIEPCTL(EPNum) *(&OTG->DIEPCTL0 + EPNum * 8) #define DTXFSTS(EPNum) *(&OTG->DTXFSTS0 + EPNum * 8) #define DOEPTSIZ(EPNum) *(&OTG->DOEPTSIZ0 + EPNum * 8) #define DOEPCTL(EPNum) *(&OTG->DOEPCTL0 + EPNum * 8) #define DIEPINT(EPNum) *(&OTG->DIEPINT0 + EPNum * 8) #define DOEPINT(EPNum) *(&OTG->DOEPINT0 + EPNum * 8)
I guess the defines are not correct. For example:
DOEPINT from Endpoint0 is correct because OTG->DOEPINT0 + EPNum * 0 = the correct register value from DOEPINT0. But all the other addresses are wrong. Because : OTG->DOEPINT0 + 1 * 8 for endpoint 1 is not the correct address from the DOEPINT1 register. It should be OTG->DOEPINT0 + EPNum * 0x20
Correct me please if i am wrong.
I don't work with your processor, and haven't looked at the actual register definitions.
But note that an offset number of 8 may end up being a byte offset of 0x20 (=32) if the pointer points to an object of size 4, like a 32-bit integer.
#define DIEPTSIZ(EPNum) *(&OTG->DIEPTSIZ0 + EPNum * 8)
-> has higher precedence than & so the above is the same as:
#define DIEPTSIZ(EPNum) *(&(OTG->DIEPTSIZ0) + EPNum * 8)
And if DIEPTSIZ0 is a 32-bit integer, then you get a pointer where EPNum*8 will step 32 byte per step of EPNum.
Oh yeah, that´s right. I am embarrassed. I should know that.
Unfortunately i still don´t know why the behaviour of the two USB drivers are not the same.