Author Topic: I am after an low level non-HAL USB implementation for an STM32F407 controller  (Read 2364 times)

0 Members and 1 Guest are viewing this topic.

Offline Pauldg123Topic starter

  • Contributor
  • Posts: 11
  • Country: au
I am after USB OTG CDC (Virtual com port) implementation for STM32F407 controller. The USB device generated via MxCube is working with a set of newer HAL/LL libraries. Unfortunately all the application code is written with older Low Level libraries so the possible solutions are:

A. Appln with older libraries combined with USB running on new libraries (lazy way, short cut. The way I have been working...)
B. Port Appln to newer libraries so everything works together (that's the way you do it but I have limited time)
C. Port USB to older libraries so all works together (that's a fall back and hard to debug plus workarounds)

I have been trying plan A with importing the USB files into the Appln framework and the other way around ( Importing the Appln code into the USB framework (produced by CubeMx application) to avoid spending too much time).

That took a full day with no luck (still 2700 errors), so should I could move on to plan B since that is clearly the way to do it? However I have limited time and resources to do so.
Does any one has a working low level USB implementation for the STM32F4 or any suggestions/ideas?

 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
A. won't work. There are naming conflicts. Tried it, failed.
It might work if one part is compiled to a library. But that will have other problems.

B. Perhaps. Until they change library version again.

C. No.

D. Pull USB into bare metal, remove hal completely.
https://github.com/fcayci/stm32f4-bare-metal/tree/master/projects/usb-vcp-libopencm
 
The following users thanked this post: Siwastaja, Pauldg123

Offline Pauldg123Topic starter

  • Contributor
  • Posts: 11
  • Country: au
Thank you so much, this is really helpful   :-+(Dank je wel!)

Indeed, I tried A for two days and waste all my time because of the myriad of naming collisions.

Fortunately you have (hopefully) a working bare metal USB VCP driver that I was after. Well done and I will try it out first thing tomorrow.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Not mine  ;). i just googled "stm32f4 usb bare metal". There are some more choices.
 

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
What Jeroen3 said.

But I'd propose also A.2: Use CubeMX with the old libraries.


In the package manager you can still install old Cube SW, and then select it by pointing the code generation to the right place.
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: Pauldg123

Offline mark03

  • Frequent Contributor
  • **
  • Posts: 711
  • Country: us
I can recommend dmitrystu's libusb_stm32 stack:  https://github.com/dmitrystu/libusb_stm32
Works great.
 
The following users thanked this post: thm_w, Pauldg123

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
The only problem I see is that mixing libraries might become an irreducible mess - OP's project is already built upon the HAL (for good or bad).
E.g.: ISR and Systick handling, as the HAL relies on a 1ms Systick.

I would check if the used HAL version is still available in CubeMX and go from there...

Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: Pauldg123

Offline zzattack

  • Regular Contributor
  • *
  • Posts: 126
  • Country: nl
I've successfully combined this library STM32_XPD with CubeMX/HAL.
 
The following users thanked this post: Pauldg123

Offline Pauldg123Topic starter

  • Contributor
  • Posts: 11
  • Country: au
hi all, thanks for giving me some leads.

I have looked at a Github repo that does a low level implementation:
https://github.com/RdMaxes/stm32f4_USB_VCP

It does compile with my appln code, so far so good and the appln works as usual.

However when I add the initialize USB driver to my main.c routine,

 
Code: [Select]
USBD_Init(&USB_OTG_dev,USB_OTG_FS_CORE_ID,&USR_desc,&USBD_CDC_cb,&USR_cb);
 I got a compiler error related to instantiation of the USB object.

Code: [Select]
Error[Pe020]: identifier "USB_OTG_dev" is undefined D:\grbl_f405_3\grbl_f405_3\source\main.c 32
In my vector.c interrupt routine, I have stated the object but clearly something is wrong.

Code: [Select]
//-----------------------------------------------------------------------------

typedef void (*intfunc)(void);

typedef union
{
  intfunc __fun;
  void* __ptr;
} intvec_elem;
//-----------------------------------------------------------------------------

#ifdef __cplusplus
  extern "C" {
#endif
//-----------------------------------------------------------------------------

extern u32 __intvec_start__;
//-----------------------------------------------------------------------------
// Added for USB driver by Paul
extern USB_OTG_CORE_HANDLE       USB_OTG_dev;
extern uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
//-----------------------------------------------------------------------------
// Forward declarations
void __iar_program_start(void); // IAR startup code
//-----------------------------------------------------------------------------

#pragma optimize=none
//-----------------------------------------------------------------------------

void reset_handler(void)
{
  SystemInit();

  // Execute IAR startup code and start main()
  __iar_program_start();
}
... etc
//-----------------------------------------------------------------------------

void hardfault_handler(void) etc...

Further down the vector settings...

Code: [Select]
 
  .....
  {default_handler}, // 82 CAN2_SCE
  {OTG_FS_IRQHandler}, // 83 OTG_FS // Added for USB driver Paul OTG_FS_IRQHandler
  {default_handler}, // 84 DMA2_Stream5
  {default_handler}, // 85 DMA2_Stream6 SD-Card
  {default_handler}, // 86 DMA2_Stream7 UART6 Downlink Tx DMA Stream
  {USART6_IRQHandler}, // 87 USART6 UART6 Downlink Rx  USART6_IRQHandler
  .... etc

I believe that USB_OTG_dev need to be assigned with an unique handle id or number so the interrupt can be married to the USB Object... if I make any sense... :-//

Okay any help would be appreciated since I am so close but still not out of the woods. :palm: Of course I can still try other repos but with 1 error to solve it might be just a tiny jump to success.

Thx!
« Last Edit: October 24, 2019, 01:10:08 am by Pauldg123 »
 

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
 
Code: [Select]
USBD_Init(&USB_OTG_dev,USB_OTG_FS_CORE_ID,&USR_desc,&USBD_CDC_cb,&USR_cb);
 I got a compiler error related to instantiation of the USB object.

Code: [Select]
Error[Pe020]: identifier "USB_OTG_dev" is undefined D:\grbl_f405_3\grbl_f405_3\source\main.c 32
Well, I think you should believe your compiler.
USB_OTG_dev is never defined, at least in the code you posted.
In the example, I see its declaration as:
Code: [Select]
__ALIGN_BEGIN USB_OTG_CORE_HANDLE  USB_OTG_dev __ALIGN_END;
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline Pauldg123Topic starter

  • Contributor
  • Posts: 11
  • Country: au
Hi, it's declaration is in the vector.c code,

Code: [Select]
---

 #ifdef __cplusplus
  extern "C" {
 #endif
//-----------------------------------------------------------------------------

extern u32 __intvec_start__;
//-----------------------------------------------------------------------------
// Added for USB driver by Paul
extern USB_OTG_CORE_HANDLE       USB_OTG_dev;
extern uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
//----------------------------------------------------------------------------

But that seems not to work properly. I tried to declare it in main too s=with the same result so it must be the syntax

extern USB_OTG_CORE_HANDLE       USB_OTG_dev;

maybe I need to create the handle: USB_OTG_CORE_HANDLE usbdevice_handle;  ?
 

Online newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
I don't exactly know how your code is organized, but it still seems that you are lacking a definition of that variable (= something telling to reserve the space for the variable, and possibly initialize it).
Your
Code: [Select]
extern USB_OTG_CORE_HANDLE       USB_OTG_dev;is only a declaration, the extern storage-class specifier simply tells the compiler that some translation unit (= source file + its includes) in this program must contain a definition of this identifier.

The line I suggested to add to main.c does just that.
If we ignore the "magic" alignment macros (of no interest for this issue):
Code: [Select]
USB_OTG_CORE_HANDLE       USB_OTG_dev;is just what is needed for a (tentative) external object definition.

A common practice is to have the declarations in an include file, and the definitions in only one source.

inc.h:
Code: [Select]
extern int myvar; /* declaration, makes sure that myvar has external linkage */
src1.c:
Code: [Select]
#include "inc.h"
int myvar = 42; /* External object definition, not tentative, as we have also an initializer */

src2.c:
Code: [Select]
#include "inc.h"

void func(void)
{
    myvar++;  /* refers to myvar defined in src1.c */
}


References in the C99 standard (draft):
  • Chapter 6.2.2: Linkage of identifiers
    tells you that extern declaration will refer to the same object in different translation units.
  • Chapter 6.7.1: Storage-class specifiers
    describe how to use extern.
  • Chapter 6.9.2: External object definitions
    explains the that one external definition is needed (exactly one if not tentative), and the allowed syntax.


Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: thm_w, Siwastaja, Pauldg123

Offline Pauldg123Topic starter

  • Contributor
  • Posts: 11
  • Country: au
After a rebuild all it simply compiled so I must have had some files not being compiled...

After running the code, the USB port does appear on the device manager but the usb descriptors are missing. I will do some more hunting. Thanks all.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf