cancel
Showing results for 
Search instead for 
Did you mean: 

Virtual COM and GPIO_Pin_10 from GPIOA

peretuset
Associate II
Posted on May 24, 2012 at 13:07

Dear all,

We have recently developed a board that includes the STM32F103CB microcontroller (36-pin version) and has a USB connection (mini-USB) to power the device and also to communicate with a computer. We are currently using the source code from the STM32 Virtual COM example but we have adapted it to our current board and needs (only send data). Instead of using the default GPIO port and pin we use GPIO_Pin_10 from GPIOA to trigger when the USB cable is connected or disconnected. The settings are as follows:

#define STM32F10X_USB_DISCONNECT_GPIO GPIOA
#define STM32F10X_USB_DISCONNECT_CLK RCC_APB2Periph_GPIOA
#define STM32F10X_USB_DISCONNECT_SPEED GPIO_Speed_50MHz
#define STM32F10X_USB_DISCONNECT_MODE GPIO_Mode_Out_OD
#define STM32F10X_USB_DISCONNECT_PIN GPIO_Pin_10

The Set_System function is as follows:

void Set_System(void) {
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable USB_DISCONNECT GPIO clock */
RCC_APB2PeriphClockCmd(STM32F10X_USB_DISCONNECT_CLK, ENABLE);
/* Configure USB pull-up pin */
GPIO_InitStructure.GPIO_Pin = STM32F10X_USB_DISCONNECT_PIN;
GPIO_InitStructure.GPIO_Speed = STM32F10X_USB_DISCONNECT_SPEED;
GPIO_InitStructure.GPIO_Mode = STM32F10X_USB_DISCONNECT_MODE;
GPIO_Init(STM32F10X_USB_DISCONNECT_GPIO, &GPIO_InitStructure);
}

Finally, the USB_Cable_Function is as follows:

void USB_Cable_Config(FunctionalState NewState) {
if (NewState != DISABLE) {
GPIO_ResetBits(STM32F10X_USB_DISCONNECT_GPIO, STM32F10X_USB_DISCONNECT_PIN);
}
else {
GPIO_SetBits(STM32F10X_USB_DISCONNECT_GPIO, STM32F10X_USB_DISCONNECT_PIN);
}
}

The same code used to work flawlessly in another board using a port from GPIOD (we used a 100-pin microcontroller) and a regular USB connector. As soon as you connected the board through USB the computer detected the device and properly configured the driver. Now the computer does not even detect the device. Using the J-Link debugger we have noticed that the USB_LP_CAN1_RX0_IRQHandler is never called, but I have already spent two days trying to solve it and I do not have any clue. Therefore, my question is: is there any incompatibility in using GPIO_Pin_10 from GPIOA for that purpose? I have noticed (in the reference manual) that GPIO_Pin_10 is used for USART1 (as an alternate function) and that it is also used for the bootloader, but we are using neither of them. Do you have any ideas on where to look? Thanks in advance, Pere #usb #stm32f103cb #vcom #stm32f10x
6 REPLIES 6
Posted on May 24, 2012 at 14:28

I'd look externally, for solder shorts, or at the pull-up. Nothing magic about PA.10 vs PD.10

From a software point of view, I'd make sure there isn't something reconfiguring the pins and enabling USART1, perhaps some debugging code or not immediately visible, that occurs after this configuration. Check the peripheral and GPIO configuration registers when you break into the code.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on May 24, 2012 at 15:44

Check also perhaps that BOOT0 is in fact LOW.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
peretuset
Associate II
Posted on May 24, 2012 at 16:58

Hi,

First of all, thanks for your two replies. Here is how things are right now. I can execute other code (in fact, everything works allright except for the USB peripheral), so I assume that the BOOT0 is in fact low. Otherwise the microcontroller would not execute any code as it would be waiting for the USART1. Am I right? The code does not seem to be the problem either because I have removed all other code that was being executed (configuring other peripherals, etc.). Right now I only have the code that configures the USB peripheral, so it should work fine. The main function is as follows:

int main(void) {
stm32f10x_init();
for (;;) {
asm(''nop'');
}
return 0;
}

Then the stm32f10x_init() function calls another function (named after stm32f10x_usb_config()) that is the one that actually inits the USB peripheral. This last one looks like:

void stm32f10x_usb_config(void) {
Set_System();
Set_USBClock();
USB_Interrupts_Config();
USB_Init();
}

This is the standard procedure and afterwards the USB driver code should automatically be executed according to the events received through the USB port. But, as stated before, the USB_LP_CAN1_RX0_IRQHandler() never gets executed. This is how it looks like.

void USB_LP_CAN1_RX0_IRQHandler(void) {
USB_Istr();
}

Thus, it does not look like being a software matter. By the way we have ten boards, as this is the first batch we produce, and all the board present the same behaviour, so bad soldering seems not to be the case. We also tried soldering pins 4 and 5 from the mini-USB connector with no better results. Any other idea? Pere
peretuset
Associate II
Posted on May 24, 2012 at 17:44

By the way, is there anything within the STM32 USB driver that needs to be changed in order to match it to the specific board configuration, e.g. PORTA or GPIO_Pin4. I assume not, but I am starting to doubt everything.

Right now I am seeing that the USB_LP_CAN1_RX0_IRQHandler fires once during boot, but no Windows machine is able to see the device being connected (even as an unrecognized device). I assume that the interrupt should fire regularly, e.g. each 1ms, to respond to request made by the host but that does not happen. Pere
hfs99
Associate II
Posted on May 25, 2012 at 17:33

You seem to be focusing on PA.10. I don't know anything about your board, but I would think you could power up ''manually'' from bench supply, or battery, etc. and check the status of DP and/or the transistor driving the bias. If DP is near 3.3V and the transistor is on, then that part of the circuit/system is ok, and you can focus on more difficult problems (like whether that first interrupt is a USB Reset event).

muis
Associate
Posted on September 07, 2012 at 10:43

Dear All,

I am not sure if it is the correct place to post. I have problem on implementing Virtual COM port (VCP) in my board Olimex STM32-LCD. The VCP fails to power-on the USB on initialization, as the result my device is not detected when pluged to PC via USB. I used Yagarto toolchain and Eclipse on windows 7 with processor of PC AMD I have installed the VCP driver VCP_V1.3.1_Setup_x64 on my pc. I have ported the project designed for STM3210E-EVAL to my board Olimex STM32-LCD. I check this STM3210E-EVAL uses same processor as my board(STM32F103ZET6). I have made some adjustment to comply with my board as following: at hw_config.c :

in void USB_Interrupts_Config(void):

/* Enable USART Interrupt */
//NVIC_InitStructure.NVIC_IRQChannel = EVAL_COM1_IRQn; //changed
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

in void USART_Config_Default(void):

/* Configure and enable the USART */
//STM_EVAL_COMInit(COM1, &USART_InitStructure); //changed
USART_Init(USART1,&USART_InitStructure); 
/* Enable the USART Receive interrupt */
//USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE); //changed
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

in bool USART_Config(void):

/* Configure and enable the USART */
//STM_EVAL_COMInit(COM1, &USART_InitStructure); //changed
USART_Init(USART1,&USART_InitStructure);

and in some parts of another function in hw_config.c, just changing global variable EVAL_COM1 and COM1 to become USART1.

at platform_config.h :

#if 1 // OLIMEX-STM32-LCD // for the Olimex STM32-LCD using STM32F103ZET6
#define USB_DISCONNECT GPIOD
#define USB_DISCONNECT_PIN GPIO_Pin_3
#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOD

The project is well compiled. But when I flash and debug it step by step, the program stops when it tries to return USB_SUCCESS value at the end of PowerOn() function in usb_pwr.c as following:

RESULT PowerOn(void)
{
#ifndef STM32F10X_CL
uint16_t wRegVal;
/*** cable plugged-in ? ***/
USB_Cable_Config(ENABLE);
/*** CNTR_PWDN = 0 ***/
wRegVal = CNTR_FRES;
_SetCNTR(wRegVal);
/*** CNTR_FRES = 0 ***/
wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);
/*** Clear pending interrupts ***/
_SetISTR(0);
/*** Set interrupt mask ***/
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask);
#endif /* STM32F10X_CL */
return USB_SUCCESS;
}

I do not change the main.c as following:

int main(void)
{
Set_System(); 
Set_USBClock();
USB_Interrupts_Config();
USB_Init();
while (1)
{
}
}

I have done all required to run VCP, havent I? I am newbie on microcontroller. Could anybody help me find out why the power-on fails? Regards, muix