Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

probably USBD_reenumerate have issue after update #1029

Closed
stas2z opened this issue Apr 6, 2020 · 16 comments · Fixed by #1048
Closed

probably USBD_reenumerate have issue after update #1029

stas2z opened this issue Apr 6, 2020 · 16 comments · Fixed by #1048

Comments

@stas2z
Copy link
Contributor

stas2z commented Apr 6, 2020

after updating local repo to the latest changes found my f405ve custom board (no special detaching/attaching pins, generic usb schematic like black f407) USB CDC stopped working properly

reverting e1d409f fixes it

i had no time to investigate it, but seems like reenumerate is not working properly after NVIC_SystemReset but i faced it a few times after detaching/attaching usb cable also
ive only tried to make CDC_deInit/CDC_Init to check if it come back to life, but it doesn't

@matthijskooijman
can you check it?

if it will be ok from your side, i will try to find a time to sit with debugger to investigate

@fpistm
Copy link
Member

fpistm commented Apr 6, 2020

Hi @stas2z
I will test on F407.
I guess you have this message during build?

#warning "No USB attach/detach method, USB might not be reliable through system resets"

@stas2z
Copy link
Contributor Author

stas2z commented Apr 6, 2020

Hi @stas2z
I will test on F407.
I guess you have this message during build?

#warning "No USB attach/detach method, USB might not be reliable through system resets"

oh, haven't seen it, project im working on atm have alot of warnings, cuz i always compile with -Wall)) so it's possible i missed it)
will check it a bit later

@fpistm
Copy link
Member

fpistm commented Apr 6, 2020

No worries 😉
Probably in that case we should do also a toggling like before.

@matthijskooijman
Copy link
Contributor

The F407 has built-in USB pullups and an SDIS bit, so the commit will have changed behaviour to no longer apply the force-DP-low-trick, since that should not be needed anymore.

However, it seems the Black F407 actually has an external fixed pullup:

image

@stas2z, can you confirm that you have the same on your board?

It's a bit weird to see a board like this, which actually reduces flexibility by fixing the pullup externally (and might actually also violate the USB spec since the two pullups combine to an effective 750Ω rather than the specified 1.5k). @stas2z if possible, you might want to consider removing the external pullup.

So I guess for boards like this, we need to apply the force low trick even when they have internal pullups. This needs some kind of define in the variant. We might also need to actually disable the internal pullup entirely (by keeping SDIS set, I think) to keep the pullup value proper, but I'm not sure how reliable that will be.

@stas2z
Copy link
Contributor Author

stas2z commented Apr 7, 2020

yes, my board and black f407 have this pullup

@fpistm
Copy link
Member

fpistm commented Apr 8, 2020

I've made some experiment with my Black F407.
By default, the COM port is not recognized but if we plug/unplug the USB cable it works.

Adding this in variant.h allows to get it working without plug/unplug. Anyway as @matthijskooijman mentioned this is not reliable, the main issue is that the hardware is not correct.
Note, that I did not handle SDIS part.

I will try with R21 removed.

@matthijskooijman
Copy link
Contributor

Adding this in variant.h allows to get it working without plug/unplug. Anyway as @matthijskooijman mentioned this is not reliable, the main issue is that the hardware is not correct.

Do note that this unreliability was already present in the original code before my refactor. So we're not losing much by reintroducing this. We could add a big warning to the define in the variant file to encourage people to fix their hardware rather than enable the define, but I guess that's not always feasible.

@stas2z
Copy link
Contributor Author

stas2z commented Apr 8, 2020

@matthijskooijman
don't add warnings, most ppl got finished boards and not be able to fix their hardware, it will be an annoying and usless stuff only

@matthijskooijman
Copy link
Contributor

don't add warnings, most ppl got finished boards and not be able to fix their hardware, it will be an annoying and usless stuff only

Sorry, I meant a warning in a comment in the template variant.h, to be looked at by anyone adding a variant. Indeed, compile-time warnings that are unfixable are only noise :-)

@fpistm
Copy link
Member

fpistm commented Apr 8, 2020

I guess the best would be to add needed definition to all impacted variants (for now Black F407, don't know it there are other impacted).
Anyway, as I said I've only added :

#define USBD_ATTACH_PIN         PA12 //USB_OTG_FS_DP
#define USBD_ATTACH_LEVEL       HIGH

which leads to do this:

  /* Detach */
  pin_function(USBD_PULLUP_CONTROL_PINNAME, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
  digitalWriteFast(USBD_PULLUP_CONTROL_PINNAME, USBD_DETACH_LEVEL);

  /* Wait */
  delay(USBD_ENUM_DELAY);

  /* Attach */
  digitalWriteFast(USBD_PULLUP_CONTROL_PINNAME, USBD_ATTACH_LEVEL);

Before we made this:

pin_function(USB_OTG_FS_DP, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
digitalWriteFast(USB_OTG_FS_DP, LOW);
delay(10);
pin_function(USB_OTG_FS_DP, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));

which is not exactly the same.
To have exactly the same way, the D+trick should be defined also:
#define USBD_DP_TRICK

@matthijskooijman what would you suggest ?

@lyusupov
Copy link
Contributor

lyusupov commented Apr 8, 2020

AN2606 does not prohibit from soldering a 1.5KOhm pull-up onto D+.
It just specifies for some MCU models that external pull-up is required.
Or, otherwise, it specifies "not required" when an MCU has built-in D+ pull-up contol feature.

This is example of AN2606 section for L07/8:
image (1)

Thus, it is not a violation of any rule for a board designer to solder 1.5K pull-up on D+
It could be excessive , but definitely not a bug.

@matthijskooijman
Copy link
Contributor

Thus, it is not a violation of any rule for a board designer to solder 1.5K pull-up on D+

I think it violates the USB specification, which requires having a 1.5k +/- 5% pullup on the DP/DM line. The MCU probably does not care, and in practice I suspect that most USB hosts won't care either (they would have to source twice as much current, but that is probably well within their margin), so it probably just works, but it does violate the spec.

@matthijskooijman what would you suggest ?

I would think maybe adding something like this in the variant.h template:

// This indicates that there is an external and fixed 1.5k pullup
// on the D+ line. This define is not normally needed, since a
// fixed pullup is assumed by default. It is only required when
// the USB peripheral has an internal pullup *and* an external
// fixed pullup is present (which is not recommended, since just
// the internal pullup is sufficient and having two pullups
// violates the USB specification).
// #define USBD_FIXED_PULLUP

And then replace

#elif !defined(USBD_HAVE_INTERNAL_PULLUPS)

with

#elif !defined(USBD_HAVE_INTERNAL_PULLUPS) || defined(USBD_FIXED_PULLUP)

The code that figures out what the DP pin is for the OTG_FS and OTG_HS peripherals should also be restored (I removed that, because these always have internal pullups, but that is no longer enough).

I would prepare a PR for this, but I'm quite busy atm, so I'll do it quickly like this for now. I might be able to look more closely next week, if you have not already.

Writing this, I realize that all of the code we have now is geared towards USB full speed devices with a pullup on D+. I think low-speed could be supported if needed, but I guess that as long as there are no boards with fixed or controllable pullups on D-, there's not much point in adding more defines for that now, we can always add additional defines (and rename the existing ones) later.

@lyusupov
Copy link
Contributor

lyusupov commented Apr 9, 2020

Why would not read D+ pull-up status by before applying MCU's pull-up ?

pinMode (PA12, INPUT_PULLDOWN);
pu_state = digitalRead(PA12);
pinMode (PA12, INPUT);

then to act correspondingly...

Internal MCU GPIO pull-up and pull-down resistors are typically having much greater value that 1.5K, so this measurement should give pretty much realistic answer on question if an external PU resistor is soldered to D+ or not.

@matthijskooijman
Copy link
Contributor

Why would not read D+ pull-up status by before applying MCU's pull-up ?

I would rather keep the startup as simple and fast as possible, especially since as part of #710 this code might run in really, really early startup.

Also, it is the job of the variant file to describe the hardware you're building for, so making this explicit there would IMHO be the better place for this.

@fpistm
Copy link
Member

fpistm commented Apr 9, 2020

I would prepare a PR for this, but I'm quite busy atm, so I'll do it quickly like this for now. I might be able to look more closely next week, if you have not already.

I'm agree with your proposal. I'm currently working on validating all Cube update to release the 1.9.0. So If you are able to provide the PR that would be fine and really appreciated.
Thanks in advance.

matthijskooijman added a commit to matthijskooijman/STM32-base.github.io that referenced this issue Apr 27, 2020
This is suboptimal hardware design, which might need some special care
on the software side. This noticed in the Arduino_Core_STM32, see
stm32duino/Arduino_Core_STM32#1029

For these boards, a schematic is available to confirm the resistor:
 - STM32F407VET6-STM32-F4VE-V2.0
 - STM32F407ZGT6-VCC-GND-Large
 - STM32F407VET6-VCC-GND-Small

These boards have not schematic, but there is a 1.5kΩ resistor clearly
visible in the USB data path that is almost certainly a pullup:
 - STM32F401RCT6-STM32F-Core-Board
 - STM32F407VET6-Euse-M4-DEMO-Medium
 - STM32F407ZGT6-STM32F-Core-Board
 - STM32F407VGT6-SR-Board

All other F4 boards have no such resistor in the schematic or visible in
the images. Other series might also have this problem, but were not
checked.
matthijskooijman added a commit to matthijskooijman/STM32-base.github.io that referenced this issue Apr 28, 2020
This is suboptimal hardware design, which might need some special care
on the software side. This noticed in the Arduino_Core_STM32, see
stm32duino/Arduino_Core_STM32#1029

For these boards, a schematic is available to confirm the resistor:
 - STM32F407VET6-STM32-F4VE-V2.0
 - STM32F407ZGT6-VCC-GND-Large
 - STM32F407VET6-VCC-GND-Small

These boards have not schematic, but there is a 1.5kΩ resistor clearly
visible in the USB data path that is almost certainly a fixed pullup:
 - STM32F407VET6-Euse-M4-DEMO-Medium
 - STM32F407VGT6-SR-Board

These boards have a pullup, but it is switched by a transistor. Since
there are also internal pullups, a warning is still in order, but using
slightly different wording:
 - STM32F401RCT6-STM32F-Core-Board
 - STM32F407ZGT6-STM32F-Core-Board

All other F4 boards have no such resistor in the schematic or visible in
the images. Other series might also have this problem, but were not
checked.
matthijskooijman added a commit to matthijskooijman/Arduino_Core_STM32 that referenced this issue Apr 28, 2020
These boards were broken in commit e1d409f Refactor USB pullup
handling. Before that commit, all boards without external controllable
pullups were assumed to have fixed external pullups and use the DP write
trick. Since that commit, boards that have internal pullups are assumed
to *not* have any external pullups and the internal pullups are
automatically used.

It turns out there exist some boards that have internal pullups in the
chips, but also have an external fixed pullup. This can probably be
considered a hardware bug, but since the boards exist, we should support
them.

This commit allows variants to define USBD_FIXED_PULLUP to explicitly
state they have a fixed pullup on the D+ line. This will cause the D+
output trick to be applied even when internal pullups are present,
fixing these boards.

This define is only needed on these specific boards, but it can also be
defined on boards with a fixed external pullup without internal pullups.

This problem was prompted by the "Black F407VE" board, which has the
problematic pullup. All other F4 boards were checked and one other was
found to have the pullup, all others seem ok. None of the other series
have been checked, so there might still be board broken.

See also STM32-base/STM32-base.github.io#26 for
some additional inventarisation of this problem.

This fixes stm32duino#1029.
matthijskooijman added a commit to matthijskooijman/Arduino_Core_STM32 that referenced this issue Apr 28, 2020
This board also has internal pullups, so the external one is not
actually needed (and will even violate the USB spec when both are used
together). This commit disabled the external pullups, but leaves the
defines in comments, as future documentation.

See also stm32duino#1029.
@matthijskooijman
Copy link
Contributor

I created a fix, see #1048. Testing welcome :-)

matthijskooijman added a commit to matthijskooijman/Arduino_Core_STM32 that referenced this issue Apr 28, 2020
These boards were broken in commit e1d409f Refactor USB pullup
handling. Before that commit, all boards without external controllable
pullups were assumed to have fixed external pullups and use the DP write
trick. Since that commit, boards that have internal pullups are assumed
to *not* have any external pullups and the internal pullups are
automatically used.

It turns out there exist some boards that have internal pullups in the
chips, but also have an external fixed pullup. This can probably be
considered a hardware bug, but since the boards exist, we should support
them.

This commit allows variants to define USBD_FIXED_PULLUP to explicitly
state they have a fixed pullup on the D+ line. This will cause the D+
output trick to be applied even when internal pullups are present,
fixing these boards.

This define is only needed on these specific boards, but it can also be
defined on boards with a fixed external pullup without internal pullups.

This problem was prompted by the "Black F407VE" board, which has the
problematic pullup. All other F4 boards were checked and one other was
found to have the pullup, all others seem ok. None of the other series
have been checked, so there might still be board broken.

See also STM32-base/STM32-base.github.io#26 for
some additional inventarisation of this problem.

This fixes stm32duino#1029.
matthijskooijman added a commit to matthijskooijman/Arduino_Core_STM32 that referenced this issue Apr 28, 2020
This board also has internal pullups, so the external one is not
actually needed (and will even violate the USB spec when both are used
together). This commit disabled the external pullups, but leaves the
defines in comments, as future documentation.

See also stm32duino#1029.
matthijskooijman added a commit to matthijskooijman/STM32-base.github.io that referenced this issue Apr 29, 2020
This is suboptimal hardware design, which might need some special care
on the software side. This noticed in the Arduino_Core_STM32, see
stm32duino/Arduino_Core_STM32#1029

For these boards, a schematic is available to confirm the resistor:
 - STM32F407VET6-STM32-F4VE-V2.0
 - STM32F407ZGT6-VCC-GND-Large
 - STM32F407VET6-VCC-GND-Small

These boards have not schematic, but there is a 1.5kΩ resistor clearly
visible in the USB data path that is almost certainly a fixed pullup:
 - STM32F407VET6-Euse-M4-DEMO-Medium
 - STM32F407VGT6-SR-Board

These boards have a pullup, but it is switched by a transistor. Since
there are also internal pullups, a warning is still in order, but using
slightly different wording:
 - STM32F401RCT6-STM32F-Core-Board
 - STM32F407ZGT6-STM32F-Core-Board

All other F4 boards have no such resistor in the schematic or visible in
the images. Other series might also have this problem, but were not
checked.
@fpistm fpistm linked a pull request Apr 29, 2020 that will close this issue
ThomasGravekamp pushed a commit to STM32-base/STM32-base.github.io that referenced this issue Apr 29, 2020
This is suboptimal hardware design, which might need some special care
on the software side. This noticed in the Arduino_Core_STM32, see
stm32duino/Arduino_Core_STM32#1029

For these boards, a schematic is available to confirm the resistor:
 - STM32F407VET6-STM32-F4VE-V2.0
 - STM32F407ZGT6-VCC-GND-Large
 - STM32F407VET6-VCC-GND-Small

These boards have not schematic, but there is a 1.5kΩ resistor clearly
visible in the USB data path that is almost certainly a fixed pullup:
 - STM32F407VET6-Euse-M4-DEMO-Medium
 - STM32F407VGT6-SR-Board

These boards have a pullup, but it is switched by a transistor. Since
there are also internal pullups, a warning is still in order, but using
slightly different wording:
 - STM32F401RCT6-STM32F-Core-Board
 - STM32F407ZGT6-STM32F-Core-Board

All other F4 boards have no such resistor in the schematic or visible in
the images. Other series might also have this problem, but were not
checked.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants