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

USBD add core-power and Vbus handle #50

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

alexrayne
Copy link

here provided enhances on usbd-driver for:

  1. Vbus sensing - <usbd_is_vbus> method and callback. This helps to detect cable plug in/out, or it can be USBpowering detection
  2. USBcore power/clock domain control - <usbd_enable> method and <power_control> backend implementation for STM32F4xxx. This intends to power-saving by usb-core and PHY stops.

@@ -75,10 +79,10 @@ static usbd_device *init(const usbd_backend_config *config)
_usbd_dev.config = config;

if (config->feature & USBD_VBUS_SENSE) {
if (OTG_FS_CID >= 0x00002000) { /* 2.0 */
if (OTG_FS_CID >= 0x00002000) { /* 2.0 HS core*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to this comment, CID = 2.0+ and FS core should not exists right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dow understand you. CID indicates an core version. according to RM0090 FS CID=0x0000 1100 and HS CID=0x0200 0600
what you ask about?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see RM0385.
OTG_CID = 0x00002000 for OTG_FS and OTG_HS

Copy link
Author

@alexrayne alexrayne Feb 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh. my version of RM0385 says:
Reset value: 0x0000 3000 for USB OTG FS
Reset value: 0x0000 3100 for USB OTG HS
looks like this code need target MCU specification - it depends on MCU family. And even more - look like this code not aplicatable on stm32f7 family 8/ But for my stm32f4 - works ok 8)

…definition to DWC_OTG_GOTGINT, DWC_OTG_PCGCCTL
…. it intends to handle cable connetion, Vbus powering

+     usbd_register_session_callback
+    :usbd_backend:is_vbus, power_control - add this methods to provide VBus status, and USBcore powering control
+    usbd_is_vbus, usbd_enable - this methods invokes backend power controls
+    usbd_stm32_otg_fs:otgfs_is_powered, otgfs_power_control - implements above controls of stm32f4xx FS core
* false disable PHY and stops usb-core
*/
void usbd_enable(usbd_device *dev, bool onoff);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a function, see "void usbd_disconnect(usbd_device *dev, bool disconnected);".

Copy link
Author

@alexrayne alexrayne Feb 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usbd_disconnect stops session, it is not control power mode of core or phy.

* @param[in] dev USB Device
* @param[in] callback callback to be invoked
*/
void usbd_register_session_callback(usbd_device *dev,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

session callback facility look like a good idea.

* @param[in] dev USB Device
* @return true - cable connected, and Vbus active
*/
bool usbd_is_vbus(usbd_device *dev);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ability to know VBUS state also look like a good idea too.

@kuldeepdhaka
Copy link
Contributor

kuldeepdhaka commented Feb 8, 2017

  • VBUS value reading (your current code look ok)
  • various session callback {connected, suspended, resumed, disconnected}.
    on suspend, disconnected, the USB periph can go into a state that can reduce power consuption of periop and allow detecting SOF. (it should be atleast able to detect activity from host)
    two way of implementation:
    • [breaking] usbd_register_suspend_callback() and usbd_register_resume_callback() already exists. we can remove them and pass an enum as state to session callback.
    • [non-breaking] make two new function usbd_register_connected_callback() and usbd_register_disconnected_callback() for the missing functionality.
  • USB enable/disable. enable or disable the usb periph communication with host. we can drop usbd_disconnect(). [ on _init() the periph is by default enabled for communcation ]
  • not strongly related: we already have a SOF callback (maybe pass frame number value as 2nd argument)

@@ -174,6 +179,11 @@ struct usbd_device {
#endif
};

typedef enum {
usbd_paShutdown
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Enum labels are uppercase. (see coding style for full information)
  • Without compelling reason, please dont use typedef. (see coding style for full information)
    If you really want, you can later do typedef enum usbd_power_action usbd_power_action.

@alexrayne
Copy link
Author

alexrayne commented Feb 8, 2017

various session callback ...

in my version of unicoremx there no callback concected/disconected - what you talk about?
imho control over usbcore power mode should be delegated to user, or must be noted by usbd_conf features.

... we can drop usbd_disconnect(). ...

imho this function made an different thing, vs power control - it initiates session disconnect. but your proposal well - this function can be followed by disable call, that powerdown usbcore after session disconnects.
imho this functionality should be denoted by a feature set in usbd_conf_xx structure, to provide backport compatibility with existing code.

@kuldeepdhaka
Copy link
Contributor

Yes, there are no connected/disconnected callback. (dont exists), they need to be implemented.

I think, we should do things transparently for user till they make sense (ie don't get in their way).
for example: if user has requested to disable communication with host, it is a good thing that the stack should put the periph in power down mode [saves power]. i see no point in providing a function to put periph in powerdown mode manually (instead of automatically doing it for user).

@kuldeepdhaka kuldeepdhaka reopened this Feb 9, 2017
@alexrayne
Copy link
Author

there s possible problem with powerdown - no event generates,no callbacks invokes. Therefore if i powerdown usbcore, suspend callback not affected!

in y board when i plugoff USBcable, session callback invokes and powerdown core. That is all. IMHO here colud be suspend action notified too.

@alexrayne
Copy link
Author

i see no point in providing a function to put periph in powerdown mode manually (instead of automatically doing it for user).

IMHO, user should no bruteforces against library for control over periferia. library should provide API as smart as uer requests. If somebody need manual control - publish this functions not a bad.
Maybe automatic power downing is good for default, and it can be disabled by a feature . but i`m aware about code that alredy writen with old library. maybe should be defined some macro, like USBD_FEATURE_POWERDOWN_DEFAULT, that choose behaviour. can you imagine some good name for this macro?

@kuldeepdhaka
Copy link
Contributor

kuldeepdhaka commented Feb 9, 2017

What are the possible usecases of manually controlling power down of usb periph?

The stack can provide an abstraction over power down mode via session management {connected, disconnected, suspended, resumed}.
For example, after suspend, application code can either either save power (or not save power) but the stack can do [power down] (mundane task) transparently.

@alexrayne
Copy link
Author

Ta present i misunderstand differense between suspend/resume and connect/disconnect operations. can you explain? what happen on invoking suspend and disconnect?

@kuldeepdhaka
Copy link
Contributor

@alexrayne USB 2.0 specs (usb_20.pdf) page 240
screenshot_2017-02-09_21-45-20

@alexrayne
Copy link
Author

Thank you for this picture. There almost see that suspended is surely not an powerdown mode.
but where threr is an mode whre Vbus down - maybe it is "attached" ?

As i remember we discuss about enable vs [dis]connect semantic of usbd api?
i agree about that functionality of this methods are close. but here is aspects. disconnect in current implementation makes an logical bus disconnection, after that we can reconfigure usb OTG (or not) for say - host mode, and reconnect again. But if we make power-down in disconnection, usbcore comes not accesible, until powerup. So for reconfigure, we need power enable without connection?

@kuldeepdhaka
Copy link
Contributor

afaiu, Taking power from VBUS dont not mean that a device is connected [ ie self power device]. (yea, Inrush current could be a hint for "something attached"). the actual detection occur via D+ and D- pull-{up/down}.

USB Host control (master) the suspend and resume process. device only have to make sure that it implement the protocol correctly (reduce power consumption and wait for a SOF to detect resume signal).

usbd_disconnect() -> dont communicate with Host.
usbd_enable() - disable clocking of periph etc.. (ultimately lead to loss of communicate with host)
i would vote for usbd_disconnect() because of (my) intution with function name and its already in api.

I haven't though on reconfiguring api (host mode -> device mode and vice versa - OTG Mode) yet :)

@alexrayne
Copy link
Author

alexrayne commented Feb 9, 2017

because of (my) intution with function name

my intuition - disconnect say nothing about device operational mode, its about connection status. enable(false) says that device should turnoff, and therefore disconnects all connections.

should we fight about names? why this semantics both cant be present?

@kuldeepdhaka
Copy link
Contributor

kuldeepdhaka commented Feb 9, 2017

should we fight about names? why this semantics both cant be present?

But oh boy, bike shedding is fun!

Requirement for the API

  • stop communication with host
  • OTG mode support (switch between Host and device mode)
  • Reduce power consumption.
  • anything else?

@alexrayne
Copy link
Author

alexrayne commented Feb 19, 2017

Kuldeep:

  1. about backend api - one contain method <disconnect (bool )> - but this name confusing me. is it same as <connect(!bool)>?

  2. about handling power on\off on session disconect - in wich sequence should be called on_session callback and backend.power_control(usbd_paActivate)? have you any mention on it?

…ture.USBD_USE_POWERDOWN

*     warns - fixed some compiler warnings about mixing enum as integer
@alexrayne
Copy link
Author

kuldeep, enums was rewrites with your prefered style

@danielinux
Copy link
Contributor

@kuldeepdhaka any input on this?

lib/usbd/usbd.c Outdated
@@ -224,6 +234,8 @@ bool usbd_is_vbus(usbd_device *dev){
}

void usbd_enable(usbd_device *dev, bool onoff){
if (!onoff)
usbd_disconnect(dev, false);
if (dev->backend->power_control)
dev->backend->power_control(dev, (onoff)? usbd_paActivate : usbd_paShutdown );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Application code
= usbd_disconnect(dev, true)
== dev->backend->disconnect(dev, true);
== usbd_enable(dev, false);
=== usbd_disconnect(dev, false);
==== usbd_enable(dev, true);
===== dev->backend->power_control(dev, usbd_paActivate);
==== dev->backend->disconnect(dev, false);
=== dev->backend->power_control(dev, usbd_paShutdown );

Look at the flow of control.
At the end, NOT disconnected with SHUTDOWN power control.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don`t understand you - enable(false) MUST not shutdown?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, i see, thank you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for your new code.

=usbd_disconnect(dev, true)   <----------------\
==dev->backend->disconnect(dev, true);         | RECURSIVE CALL! STACK OVERFLOW!
==usbd_enable(dev, false);                     |
===usbd_disconnect(dev, true)   ---------------/
===dev->backend->power_control(dev, usbd_paShutdown);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, see alredy. more trouble now bother me - cantt understand how to wake up FS from powerdown, cause it want normaly detect online and reset after ungating core clock

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, resolve it. but not preferable way - not like what i write

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When usbd_enable(dev, false) is called, it disconnect and shutdown. but when usbd_enable(dev, true) is called, it only power-up (it remove the disconnect condition).

Copy link
Author

@alexrayne alexrayne May 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this was confused me too. disconnection MUST be provided before powerdown. but fro stm DWC core it is mean that USB enter to non-connectable state. imho, name 'disconnect' - not very suitable for this operation.
i`ll change behaviour to restore disconnection state on powerdown complete.
i not sure, is it good to place disconnection before powerdown into backend->power_control, instead of botherig it on frontend?

USBD_PHY_EXT = (1 << 0),
USBD_VBUS_SENSE = (1 << 1),
USBD_VBUS_EXT = (1 << 2)
//* provide usb-core auto power-up/down on connect/disconnect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"//*" (IMO) Please C style comment only (code consistancy).
@danielinux @brabo what do you think?

USBD_VBUS_SENSE = (1 << 1),
USBD_VBUS_EXT = (1 << 2)
//* provide usb-core auto power-up/down on connect/disconnect
, USBD_USE_POWERDOWN = (1<<3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(IHMO) ", USBD_USE_POWERDOWN" code consistancy. "," not placed there.
(IHMO) "(1<<3)" , "(1 << 2)", "(1 << 0)," space missing in "1" "<<" "3" code consistancy.

@brabo @danielinux Can you please give me a hand at code style / consistancy work.

@@ -279,7 +284,7 @@ enum usbd_transfer_flags {
USBD_FLAG_PACKET_PER_FRAME_MASK = (0x3 << 5)
};

typedef enum usbd_transfer_flags usbd_transfer_flags;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possibly ive got a warning here? enum and typedef - with same name. its confusing me, i newer see such trick.
i`ve saw overriding enum item name with macro definition, but override enum by typedef - is it vlalid practice for C?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

@alexrayne alexrayne May 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, i know about namespaces, and that code was compiled succesfully.
when i ask about "valid practice for C" i mean - is it good? is it helpful? can it lead to some errors?
the name "usbd_transfer_flags" imho nott very suitable for enum. such name also can be imagine for struct of a binary set of flags.
anyway, if you insist - let`s revert this typedef back to code.

Copy link
Author

@alexrayne alexrayne May 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you forgot to denote
+typedef unsigned char usbd_transfer_flags;
ARMCC compiler generates warning when we try to assign to enum variable integer value (with set of flags).
therefore i denote for usbd_transfer_flags as numeric type

!            :otg init:HS detection - now valid detection of HS core stm32F4 and F7
!             - fixed code style
…tatus check

*dwc_otg:poll - poll skips most work ша core powered off
if (config->feature & USBD_VBUS_SENSE) {
if (OTG_FS_CID >= 0x00002000) { /* 2.0 HS core*/
if (OTG_FS_CID >= otg_hs_cid_boundary) { /* 2.0 HS core*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTG_FS_CID >= 0x00003000 leads to running 1.0 HS core init code on 2.0 HS core init

…n. therefore disconnection moved to background.

                        background disconnects before PHY  disabling, and restore disconnection status after.
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 this pull request may close these issues.

3 participants