cancel
Showing results for 
Search instead for 
Did you mean: 

STm32F USB VCP example

B Zikhali
Associate III
Posted on March 10, 2015 at 16:12

I am building a microcontroller based on the STM32F302K8 chip and I am trying to send data to host PC via USB. My echo code below based on an example in the forums works:

static
int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 7 */
static
uint8_t buff_RX[256];
static
uint8_t buff_TX[256];
int
i = 0;
for
(i = 0; i < *Len; i++)
buff_TX[i] = buff_RX[i];
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &buff_TX[0], *Len);
USBD_CDC_TransmitPacket(&hUsbDeviceFS);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &buff_RX[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return
(USBD_OK);
/* USER CODE END 7 */
}

But when I implement the following code to send from MCU to host, I fall into an Infinite Loop (Default_Handler in startup_stm32f302x8.s)

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 8 */
int
i;
//memcpy(UserTxBufferFS, Buf, Len); //not sure why but memcpy is not working here
for
(i=0;i<Len;i++)
{
UserTxBufferFS[i]=Buf[i];
}
USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS, Len);
result = USBD_CDC_TransmitPacket(hUsbDevice_0);
/* USER CODE END 8 */
return
result;
}

I have looked all over the internet for a solution including the forums on this site, why is this happening? With regards to the recieve code, how is the loop reading from RX_Buff when it is set as the Receiving buffer only after the loop? Does anyone have the USB as VCP examples mentioned in the Software Development Kit PDF? I have been to every nook and cranny of this website and all the links seem to be dead! #stm32f3xx #stm32 #usb #usb #stm32f #stm32f3 #vcp #lmgtfy:-stm32-resources
11 REPLIES 11
Posted on March 10, 2015 at 16:35

Does anyone have the USB as VCP examples mentioned in the Software Development Kit PDF? I have been to every nook and cranny of this website and all the links seem to be dead!

http://www.st.com/web/en/catalog/tools/PF258157

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
B Zikhali
Associate III
Posted on March 10, 2015 at 16:45

Thank you Clive!!!! Will work on it right away, have just spent a full day trying to make this work.

B Zikhali
Associate III
Posted on March 10, 2015 at 17:57

B Zikhali
Associate III
Posted on March 10, 2015 at 18:00

The project file for my STM32 in the downloaded file from ST.com seems to be corrupted. I have looked at the source code and the setup and configuration seems to be completely different from the code I am maintaining eg. I do not have a hw_config.c in my project. Is there anyone who knows why my CDC_Receive_FS is working and yet the CDC_Transmit_FS is sending me into an Infinite Loop?

B Zikhali
Associate III
Posted on March 10, 2015 at 18:29

After further debugging, I have identified that a signal handler is called just after entry into the function USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev, uint8_t  *pbuff, uint16_t length) after which the processor immediately goes into the Infinite Loop.

B Zikhali
Associate III
Posted on March 11, 2015 at 18:22

Thank you again for the link. I am now trying to focus on coding by building on the example instead of my pre-existing code but I am still having problems. I have followed the instructions in the ReadMe to import the project into True Studio, build and load it into my STM32F302K8. The problem is without even touching one line of code the example immediately fails. I have debugged it and True Studio's Debugger reports that a HardFault_Handler was called. I have tried stepping through the program and at the first instruction in main(), the debugger states:

Cannot access memory at address 0x20009ff4

My questions are as follows

 

(i) Am I supposed to load the example as is onto the STM32F302K8, I am not using an evaluation board and I have noticed that all the examples are built for an evaluation board.

 

 

(ii) If the answer to above is yes, why are the programs failing to execute even before I change any part of the code?

 

 

(iii) Failing any of the above, in my first post, why is the echo function in the CDC_Receive_FS() that I found on this forum working, and CDC_Transmit_FS() causing an Infinite Loop.

Really hope someone can help me with this, I am a newbie to STM32 programming.

Posted on March 11, 2015 at 18:53

Most of ST's examples are tailored to specific boards they sell, if your board is different, then you need to accommodate those differences and tailor the code to your board, and the pins, peripherals and memory that it has. You should review the schematic/manual for the EVAL board the example targets, and then compare/contrast that to the board you are attempting to use.

The error seems to be complaining about a RAM access, does the part you are using have adequate resources for the application? Have you changed the target chip to reflect the one you are using and the resources it has?

Not an ATOLLIC user, so can't help you much on that front.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on March 11, 2015 at 18:57

Your part only has 16KB

http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1576/LN1824/PF259029

The address suggest it's using a device with 40KB, perhaps look at the linker script (.LD), or other settings with respect to where it is placing the STACK
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
B Zikhali
Associate III
Posted on March 16, 2015 at 10:22

Thank you Clive for your help. I am learning as I go along. The error was caused by the fact that I was trying to initiate a transmission from a device which was configured as a USB Device. What I have done to go around this is have my CDC_Transmit_FS function only fill the TX buffer and wait till the defined CDC_Receive_FS function recieves something from the host to initiate a transmission by calling USBD_CDC_TransmitPacket(). I am not sure if this is the most efficient way of going about things.

Problem of course is now I have to open a terminal in gtkterm (Ubuntu) and type a character for the PC to recieve something. Is there a way I can tell the PC to poll the USB device every x milliseconds to trigger the transmission of data from the device to host?

#define APP_RX_DATA_SIZE 256
#define APP_TX_DATA_SIZE 256
static uint8_t buff_RX[APP_RX_DATA_SIZE];
static uint8_t buff_TX[APP_TX_DATA_SIZE];
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 8 */
uint32_t i;
for (i = 0; i < Len; i++) {
buff_TX[APP_Rx_ptr_in++] = *(Buf + i);
}
/* To avoid buffer overflow */
if(APP_Rx_ptr_in == APP_TX_DATA_SIZE)
{
APP_Rx_ptr_in = 0;
}
/* USER CODE END 8 */
return result;
}
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 7 */ 
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &buff_TX[0], 128);
USBD_CDC_TransmitPacket(&hUsbDeviceFS);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &buff_RX[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 7 */ 
}