cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F105 USB OTG Host Device Mode switching

colin
Associate II
Posted on March 19, 2014 at 11:00

Hi,

I have integrated the Host MSD and Device VCP into a project. I am struggling to find an example of how to switch between the Host/device mode when a �A� USB cable (flash stick ) and a �B� USB cable (connected to PC for VCP serial port ). I am using the project DRD example from the STM32_USB-Host-Device_Lib_V2.1.0 examples. Can anyone point me in the right direction ( to an example ) of mode switching?

Many thanks

#use_otg_mode #stm32f105-usb-otg-host-device #usb_otg_core_device
7 REPLIES 7
chen
Associate II
Posted on March 19, 2014 at 11:22

Hi

''

Device VCP

''

Technically, this should be Device CDC (Communication Device Class).

VCP = Virtual Communications Port

''

I am struggling to find an example of how to switch between the Host/device mode when a ‘A’ USB cable (flash stick ) and a ‘B’ USB cable (connected to PC for VCP serial port )

''

I think the USB OTG library/driver code should do this automatically if the circuit is correct.

OTG = On The Go.

This is the USB extension that defines and allows the dynamic switching og USB from  Host  to device ( and visa versa ).

What dev board are you using (or what is your circuit)?

tsuneo
Senior
Posted on March 19, 2014 at 19:52

> I am using the project DRD example from the STM32_USB-Host-Device_Lib_V2.1.0 examples.

The DRD (Dual Role Device) example apply both of USE_HOST_MODE and USE_DEVICE_MODE, but not USE_OTG_MODE.

\DRD\inc\usb_conf.h
#define USE_HOST_MODE
#define USE_DEVICE_MODE
//#define USE_OTG_MODE

> I am struggling to find an example of how to switch between the Host/device mode when a‘A’ USB cable (flash stick ) Under USE_HOST_MODE and/or USE_DEVICE_MODE, the ID pin interrupt is available to detect 'A' plug cable in/out. When the status of the ID pin alters, CIDSCHG bit in OTG_FS_GINTSTS register rises. Firmware reads CIDSTS bit in OTG_FS_GOTGCTL, to see the level of ID pin (0 = plug in of 'A' plug) > and a‘B’USB cable (connected to PC for VCP serial port ). When VBUS pin voltage rises at PC plug in, SRQINT bit in OTG_FS_GINTSTS is asserted on both of host/device mode, while VBUSASEN/VBUSBSEN bits of OTG_FS_GCCFG are enabled. SEDET bit in OTG_FS_GOTGINT notifies VBUS voltage drop in device mode. As of the modification of the DRD example, 1) ID pin configuration ID pin (PA10) should be configured as input pull-up, explicitly, in USB_OTG_BSP_Init().

usb_bsp.c
void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{
// EXTI_InitTypeDef EXTI_InitStructure;
#ifdef USE_STM3210C_EVAL
GPIO_InitTypeDef GPIO_InitStructure;
USB_OTG_GCCFG_TypeDef gccfg;
// set up ID pin (PA10) as input pull-up
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure); 
// enable VBUS sense
gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG);
gccfg.b.vbussensingA = 1 ;
gccfg.b.vbussensingB = 1 ; 
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
RCC_OTGFSCLKConfig(RCC_OTGFSCLKSource_PLLVCO_Div3);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE) ;
...
...

2) USB peripheral initialization USB_OTG_BSP_Init() is called in Demo_Init(), to set up the USB peripheral in early stage.

dual_func_demo.c
void Demo_Init (void)
{
USB_OTG_BSP_Init(&USB_OTG_Core);
...
...

3) Enable cable interrupts On ''case DEMO_IDLE'' in Demo_Application(), the above interrupts are enabled.

dual_func_demo.c
static void Demo_Application (void)
{
static uint8_t prev_select = 0;
uint16_t bytesWritten, bytesToWrite;
FRESULT res;
switch (demo.state)
{
case DEMO_IDLE:
USB_OTG_EnableCableInt(&USB_OTG_Core);
...
...
static void USB_OTG_EnableCableInt(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTMSK_TypeDef int_mask;
int_mask.d32 = 0;
/* Clear any pending interrupts */
USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xBFFFFFFF);
/* Enable the interrupts in the INTMSK */
int_mask.b.conidstschng = 1; // Connector ID status change
int_mask.b.sessreqintr = 1; // VBUS is in the valid range
USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32);
/* Enable Interrupts */
USB_OTG_BSP_EnableInterrupt(pdev);
}

4) ISR for cable interrupts In OTG_FS_IRQHandler(), above interrupts are handled

stm32fxxx_it.c
#include ''dual_func_demo.h''
extern DEMO_StateMachine demo;
#ifdef USE_USB_OTG_FS
void OTG_FS_IRQHandler(void)
#else
void OTG_HS_IRQHandler(void)
#endif
{
if ( demo.state == DEMO_WAIT ) {
Cable_ISR_Handler(&USB_OTG_Core);
} else {
if (USB_OTG_IsHostMode(&USB_OTG_Core)) /* ensure that we are in device mode */
{
USBH_OTG_ISR_Handler(&USB_OTG_Core);
}
else
{
USBD_OTG_ISR_Handler(&USB_OTG_Core);
}
}
}
void Cable_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_GINTSTS_TypeDef gintsts;
gintsts.d32 = USB_OTG_ReadCoreItr(pdev);
if (gintsts.b.conidstschng) // Connector ID status change
{
USB_OTG_GOTGCTL_TypeDef gotgctl;
gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
if (gotgctl.b.conidsts == 0) // ID pin is low
{
demo.state = DEMO_HOST;
}
}
if (gintsts.b.sessreqintr) // VBUS is in the valid range
{
demo.state = DEMO_DEVICE;
}
/* Set flag and clear interrupt */
USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
}

Tsuneo
colin
Associate II
Posted on March 20, 2014 at 12:05

Thanks Sung it is the STM3210C Eval and our own target PCB they both use PA10 for the detection I think 'A' cable is zero volts.

colin
Associate II
Posted on March 20, 2014 at 12:10

Many Thanks Tsuneo. That is great! Just what I was looking for. I was not sure if the switch was in the stack or we had to do it manualy. We are using STM3210C Eval and our own target PCB they both use PA10 for the detection I think 'A' cable is zero volts.

colin
Associate II
Posted on March 21, 2014 at 15:56

Hi Tsuneo.

Doy you know is the USB_OTG_CORE_HANDLE / usb_otg.c is implemented in the ST code. I tried #define USE_OTG_MODE but get complie errors on USB_OTG_OTGCTL_TypeDef not being defined. Many thanks

tsuneo
Senior
Posted on March 21, 2014 at 17:41

This one?

usb_core.c
USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev)
{
USB_OTG_STS status = USB_OTG_OK;
USB_OTG_FSIZ_TypeDef nptxfifosize;
USB_OTG_FSIZ_TypeDef ptxfifosize; 
USB_OTG_HCFG_TypeDef hcfg;
#ifdef USE_OTG_MODE
USB_OTG_OTGCTL_TypeDef gotgctl; // <-----
#endif

It's typo (bug). USB_OTG_ GOTGCTL_TypeDef As such an essential bug shows, ST should not test the OTG implementation yet. Tsuneo
colin
Associate II
Posted on March 24, 2014 at 11:09

Thanks Tsuneo, You are right I have given up on usb_otg.c there is no way to compile it because USB_OTG_CORE_DEVICE is not in any header I can find. I belive it may be a legacy thing dating back to UM0721.