-
Notifications
You must be signed in to change notification settings - Fork 8
USBD add core-power and Vbus handle #50
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
base: master
Are you sure you want to change the base?
Changes from 3 commits
21d87c3
84012d3
65231b0
5624172
c1cda4f
114158f
d9d1cf9
aff4105
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -135,6 +135,16 @@ enum usbd_speed { | |
|
||
typedef enum usbd_speed usbd_speed; | ||
|
||
/** Optional features */ | ||
enum usbd_backend_features{ | ||
USBD_FEATURE_NONE = 0, | ||
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 | ||
, USBD_USE_POWERDOWN = (1<<3) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (IHMO) ", USBD_USE_POWERDOWN" code consistancy. "," not placed there. @brabo @danielinux Can you please give me a hand at code style / consistancy work. |
||
}; | ||
|
||
struct usbd_backend_config { | ||
/** Number of endpoints. (Including control endpoint) */ | ||
uint8_t ep_count; | ||
|
@@ -145,13 +155,8 @@ struct usbd_backend_config { | |
/** Device speed */ | ||
usbd_speed speed; | ||
|
||
/** Optional features */ | ||
enum { | ||
USBD_FEATURE_NONE = 0, | ||
USBD_PHY_EXT = (1 << 0), | ||
USBD_VBUS_SENSE = (1 << 1), | ||
USBD_VBUS_EXT = (1 << 2) | ||
} feature; | ||
/** Optional features see usbd_backend_features*/ | ||
unsigned int feature; | ||
}; | ||
|
||
typedef struct usbd_backend_config usbd_backend_config; | ||
|
@@ -279,7 +284,7 @@ enum usbd_transfer_flags { | |
USBD_FLAG_PACKET_PER_FRAME_MASK = (0x3 << 5) | ||
}; | ||
|
||
typedef enum usbd_transfer_flags usbd_transfer_flags; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. possibly i There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, i know about namespaces, and that code was compiled succesfully. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you forgot to denote |
||
typedef unsigned char usbd_transfer_flags; | ||
|
||
/** | ||
* USB Transfer status | ||
|
@@ -431,6 +436,8 @@ typedef void (*usbd_set_interface_callback)(usbd_device *dev, | |
typedef void (*usbd_setup_callback)(usbd_device *dev, uint8_t addr, | ||
const struct usb_setup_data *setup_data); | ||
|
||
typedef void (* usbd_session_callback)(usbd_device *dev, bool online); | ||
|
||
typedef void (* usbd_generic_callback)(usbd_device *dev); | ||
|
||
/** | ||
|
@@ -515,6 +522,16 @@ void usbd_register_resume_callback(usbd_device *dev, | |
void usbd_register_sof_callback(usbd_device *dev, | ||
usbd_generic_callback callback); | ||
|
||
/** | ||
* Register session connect/disconnect callback | ||
* with USBD_VBUS_SENSE feature primary need for cable | ||
* plug detection | ||
* @param[in] dev USB Device | ||
* @param[in] callback callback to be invoked | ||
*/ | ||
void usbd_register_session_callback(usbd_device *dev, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. session callback facility look like a good idea. |
||
usbd_session_callback callback); | ||
|
||
/** | ||
* Register SET_CONFIGURATION callback \n | ||
* stack will invoke @a callback when ever SET_CONFIGURATION is received | ||
|
@@ -643,6 +660,22 @@ uint8_t usbd_get_address(usbd_device *dev); | |
*/ | ||
usbd_speed usbd_get_speed(usbd_device *dev); | ||
|
||
|
||
/** | ||
* Get status of connected cable. | ||
* @param[in] dev USB Device | ||
* @return true - cable connected, and Vbus active | ||
*/ | ||
bool usbd_is_vbus(usbd_device *dev); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ability to know VBUS state also look like a good idea too. |
||
|
||
/** | ||
* Controls power state of usb-core and PHY | ||
* @param[in] dev USB Device | ||
* @param[in] onoff - true turn on device in action, and power PHY | ||
* false disable PHY and stops usb-core | ||
*/ | ||
void usbd_enable(usbd_device *dev, bool onoff); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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);". There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
/** | ||
* Perform a transfer | ||
* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,8 @@ | |
#include <unicore-mx/usbd/usbd.h> | ||
|
||
static usbd_device *init(const usbd_backend_config *config); | ||
static bool otgfs_is_powered(usbd_device *dev); | ||
static void otgfs_power_control(usbd_device *dev, usbd_power_action action); | ||
|
||
static struct usbd_device _usbd_dev; | ||
|
||
|
@@ -51,6 +53,8 @@ const struct usbd_backend usbd_stm32_otg_fs = { | |
.get_speed = dwc_otg_get_speed, | ||
.set_address_before_status = true, | ||
.base_address = USB_OTG_FS_BASE, | ||
.is_vbus = otgfs_is_powered | ||
, .power_control = otgfs_power_control | ||
}; | ||
|
||
#define REBASE(REG, ...) REG(usbd_stm32_otg_fs.base_address, ##__VA_ARGS__) | ||
|
@@ -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*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please see RM0385. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. heh. my version of RM0385 says: |
||
/* Enable VBUS detection */ | ||
OTG_FS_GCCFG |= OTG_GCCFG_VBDEN; | ||
} else { /* 1.x */ | ||
} else { /* 1.x FS core*/ | ||
/* Enable VBUS sensing in device mode */ | ||
OTG_FS_GCCFG |= OTG_GCCFG_VBUSBSEN; | ||
} | ||
|
@@ -108,3 +112,29 @@ static usbd_device *init(const usbd_backend_config *config) | |
|
||
return &_usbd_dev; | ||
} | ||
|
||
static | ||
bool otgfs_is_powered(usbd_device *dev){ | ||
uint32_t base = dev->backend->base_address; | ||
return (DWC_OTG_GOTGCTL(base) & DWC_OTG_GOTGCTL_BSVLD) != 0; | ||
} | ||
|
||
static | ||
void otgfs_power_control(usbd_device *dev, usbd_power_action action){ | ||
uint32_t base = dev->backend->base_address; | ||
switch (action){ | ||
case usbd_paActivate:{ | ||
DWC_OTG_PCGCCTL(base) = 0; | ||
OTG_FS_GCCFG |= OTG_GCCFG_PWRDWN; | ||
break; | ||
} | ||
case usbd_paShutdown: { | ||
/* Wait for AHB idle. */ | ||
while (( (DWC_OTG_GRSTCTL(base) & DWC_OTG_GRSTCTL_AHBIDL) == 0) ); | ||
//poser down PHY | ||
OTG_FS_GCCFG &= ~OTG_GCCFG_PWRDWN; | ||
DWC_OTG_PCGCCTL(base) = DWC_OTG_PCGCCTL_STPPCLK; //| DWC_OTG_PCGCCTL_GATEHCLK ; | ||
break; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,6 +128,14 @@ void usbd_register_sof_callback(usbd_device *dev, | |
} | ||
} | ||
|
||
void usbd_register_session_callback(usbd_device *dev, | ||
usbd_session_callback callback) | ||
{ | ||
dev->callback.session = callback; | ||
} | ||
|
||
|
||
|
||
/* Functions to be provided by the hardware abstraction layer */ | ||
void usbd_poll(usbd_device *dev, uint32_t us) | ||
{ | ||
|
@@ -145,9 +153,19 @@ void usbd_poll(usbd_device *dev, uint32_t us) | |
|
||
void usbd_disconnect(usbd_device *dev, bool disconnect) | ||
{ | ||
if (!disconnect) { | ||
// power-up on connect | ||
if ((dev->config->feature & USBD_USE_POWERDOWN) != 0) | ||
usbd_enable(dev, true); | ||
} | ||
if (dev->backend->disconnect) { | ||
dev->backend->disconnect(dev, disconnect); | ||
} | ||
if (disconnect) { | ||
// power-down after disconnect | ||
if ((dev->config->feature & USBD_USE_POWERDOWN) != 0) | ||
usbd_enable(dev, false); | ||
} | ||
} | ||
|
||
void usbd_ep_prepare(usbd_device *dev, uint8_t addr, usbd_ep_type type, | ||
|
@@ -208,5 +226,20 @@ usbd_speed usbd_get_speed(usbd_device *dev) | |
return dev->backend->get_speed(dev); | ||
} | ||
|
||
bool usbd_is_vbus(usbd_device *dev){ | ||
if (dev->backend->is_vbus) | ||
return dev->backend->is_vbus(dev); | ||
else | ||
return true; | ||
} | ||
|
||
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 ); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Look at the flow of control. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don`t understand you - enable(false) MUST not shutdown? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, i see, thank you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for your new code.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, see alredy. more trouble now bother me - cant There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well, resolve it. but not preferable way - not like what i write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
|
||
|
||
/**@}*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ | |
#ifndef UNICOREMX_USBD_PRIVATE_H | ||
#define UNICOREMX_USBD_PRIVATE_H | ||
|
||
#include <stdbool.h> | ||
#include <unicore-mx/usbd/usbd.h> | ||
|
||
/** | ||
|
@@ -109,6 +110,10 @@ struct usbd_device { | |
|
||
/** invoked when sof received */ | ||
usbd_generic_callback sof; | ||
|
||
//* invoked on Session New / End | ||
//* with USBD_VBUS_SENSE feature detects cable plug | ||
usbd_session_callback session; | ||
|
||
/** invoked on SETUP packet */ | ||
usbd_setup_callback setup; | ||
|
@@ -174,6 +179,12 @@ struct usbd_device { | |
#endif | ||
}; | ||
|
||
enum _usbd_power_action{ | ||
usbd_paShutdown | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
, usbd_paActivate | ||
}; | ||
typedef enum _usbd_power_action usbd_power_action; | ||
|
||
/* Functions provided by the hardware abstraction. */ | ||
struct usbd_backend { | ||
usbd_device * (*init)(const usbd_backend_config *config); | ||
|
@@ -197,6 +208,10 @@ struct usbd_backend { | |
/* Frame number */ | ||
uint16_t (*frame_number)(usbd_device *dev); | ||
|
||
//* power control | ||
bool (*is_vbus)(usbd_device *dev); | ||
void (*power_control)(usbd_device *dev, usbd_power_action action); | ||
|
||
/* | ||
* this is to tell usb generic code | ||
* that address need to be set before status-stage. | ||
|
@@ -359,6 +374,14 @@ static inline void usbd_handle_sof(usbd_device *dev) | |
} | ||
} | ||
|
||
static inline | ||
void usbd_handle_session(usbd_device *dev, bool onoff) | ||
{ | ||
if (dev->callback.session != NULL) { | ||
dev->callback.session(dev, onoff); | ||
} | ||
} | ||
|
||
/** | ||
* Called by backend to pass the setup data when a SETUP packet is recevied | ||
* on control endpoint. | ||
|
There was a problem hiding this comment.
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?