초보의 아웅다웅 설계하기/STM32

STM32H7 USB CDC VCP

로망와니 2021. 1. 11. 21:21

STM32H7

 

 

/**
  ******************************************************************************
  * @file    USB_Device/CDC_Standalone/Src/usbd_cdc_interface.c
  * @author  MCD Application Team
  * @brief   Source file for USBD CDC interface
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------ */
#include <stdarg.h>
#include <stdio.h>
#include "main.h"

tUart stUSB;

/* Private typedef ----------------------------------------------------------- */
/* Private define ------------------------------------------------------------ */
#define APP_RX_DATA_SIZE  2048
#define APP_TX_DATA_SIZE  2048
uint8_t buffer_in[APP_TX_DATA_SIZE];
uint8_t UserRxBuffer[APP_RX_DATA_SIZE]; /* Received Data over USB are stored in
                                         * this buffer */
uint8_t UserTxBuffer[APP_TX_DATA_SIZE]; /* Received Data over UART (CDC
                                         * interface) are stored in this buffer*/
																				 
/* Private macro ------------------------------------------------------------- */
/* Private variables --------------------------------------------------------- */
USBD_CDC_LineCodingTypeDef LineCoding = {
  115200,                       /* baud rate */
  0x00,                         /* stop bits-1 */
  0x00,                         /* parity - none */
  0x08                          /* nb. of bits 8 */
};

uint32_t count_in = 0;

/* USB handler declaration */
extern USBD_HandleTypeDef USBD_Device;

/* Private function prototypes ----------------------------------------------- */
static int8_t CDC_Itf_Init(void);
static int8_t CDC_Itf_DeInit(void);
static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t * pbuf, uint16_t length);
static int8_t CDC_Itf_Receive(uint8_t * pbuf, uint32_t * Len);
static int8_t CDC_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);

USBD_CDC_ItfTypeDef USBD_CDC_fops = {
  CDC_Itf_Init,
  CDC_Itf_DeInit,
  CDC_Itf_Control,
  CDC_Itf_Receive,
  CDC_TransmitCplt
};

/* Private functions --------------------------------------------------------- */

/**
  * @brief  Initializes the CDC media low layer
  * @param  None
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_Itf_Init(void)
{
  /* ##-5- Set Application Buffers ############################################ */
  USBD_CDC_SetTxBuffer(&USBD_Device, UserTxBuffer, 0);
  USBD_CDC_SetRxBuffer(&USBD_Device, UserRxBuffer);

  return (USBD_OK);
}

/**
  * @brief  CDC_Itf_DeInit
  *         DeInitializes the CDC media low layer
  * @param  None
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_Itf_DeInit(void)
{
  return (USBD_OK);
}

/**
  * @brief  CDC_Itf_Control
  *         Manage the CDC class requests
  * @param  Cmd: Command code
  * @param  Buf: Buffer containing command data (request parameters)
  * @param  Len: Number of data to be sent (in bytes)
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t * pbuf, uint16_t length)
{
  switch (cmd)
  {
  case CDC_SEND_ENCAPSULATED_COMMAND:
    /* Add your code here */
    break;

  case CDC_GET_ENCAPSULATED_RESPONSE:
    /* Add your code here */
    break;

  case CDC_SET_COMM_FEATURE:
    /* Add your code here */
    break;

  case CDC_GET_COMM_FEATURE:
    /* Add your code here */
    break;

  case CDC_CLEAR_COMM_FEATURE:
    /* Add your code here */
    break;

  case CDC_SET_LINE_CODING:
    LineCoding.bitrate = (uint32_t) (pbuf[0] | (pbuf[1] << 8) |
                                     (pbuf[2] << 16) | (pbuf[3] << 24));
    LineCoding.format = pbuf[4];
    LineCoding.paritytype = pbuf[5];
    LineCoding.datatype = pbuf[6];

    /* Set the new configuration */
    break;

  case CDC_GET_LINE_CODING:
    pbuf[0] = (uint8_t) (LineCoding.bitrate);
    pbuf[1] = (uint8_t) (LineCoding.bitrate >> 8);
    pbuf[2] = (uint8_t) (LineCoding.bitrate >> 16);
    pbuf[3] = (uint8_t) (LineCoding.bitrate >> 24);
    pbuf[4] = LineCoding.format;
    pbuf[5] = LineCoding.paritytype;
    pbuf[6] = LineCoding.datatype;
    break;

  case CDC_SET_CONTROL_LINE_STATE:
    /* Add your code here */
    break;

  case CDC_SEND_BREAK:
    /* Add your code here */
    break;

  default:
    break;
  }

  return (USBD_OK);
}


#define SEND_TIMEOUT	10000
void USB_Send_Data(uint8_t* data_buffer, uint8_t len)
{
	uint32_t Timeout = SEND_TIMEOUT;
	
	if(len == 0){
    buffer_in[count_in] = *(data_buffer);		
		count_in++;		

    USBD_CDC_SetTxBuffer(&USBD_Device, buffer_in, count_in);
    while(USBD_CDC_TransmitPacket(&USBD_Device) != USBD_OK  && (Timeout != 0x00)){Timeout--;}
	}
	else{
    USBD_CDC_SetTxBuffer(&USBD_Device, data_buffer, len);
    while(USBD_CDC_TransmitPacket(&USBD_Device) != USBD_OK  && (Timeout != 0x00)){Timeout--;}
	}
}


void USB_PutStr(char *string)
{	
	uint8_t len = 0;
	while(*string != '\0'){ string++; len++;}
	string -= len;
	USB_Send_Data((uint8_t *)string, len);
}


void USB_printf(const char *fmt,...)
{
	char string[256];
	va_list ap;

	va_start(ap,fmt);
	vsprintf(string,fmt,ap);
	va_end(ap);

	USB_PutStr(string);
}

/*******************************************************************************
* Function Name  : 
* Description    :
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
uint8_t USB_GetChar(uint8_t *data)
{
    if(stUSB.RxInCnt == stUSB.RxOutCnt) return 0;
    else *data = stUSB.RxBuf[stUSB.RxOutCnt];
    if(stUSB.RxOutCnt<RBUF_SIZE-1) stUSB.RxOutCnt++;
    else stUSB.RxOutCnt = 0;

    return 1;
}

/*******************************************************************************
* Function Name  : 
* Description    :
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
static int8_t CDC_Itf_Receive(uint8_t * Buf, uint32_t * Len)
{
	__IO uint32_t count_out = 0, i;
  SCB_CleanDCache_by_Addr((uint32_t *)Buf, *Len);

	USBD_CDC_SetRxBuffer(&USBD_Device, &Buf[0]);
	USBD_CDC_ReceivePacket(&USBD_Device);	
	
	for(i = 0; i < *Len; i++){
		stUSB.RxBuf[stUSB.RxInCnt] = Buf[i];
		if(stUSB.RxInCnt<RBUF_SIZE-1) stUSB.RxInCnt++;
		else stUSB.RxInCnt = 0;
	}	
	
  return (USBD_OK);
}
	
	
/**
  * @brief  CDC_TransmitCplt
  *         Data transmited callback
  *
  *         @note
  *         This function is IN transfer complete callback used to inform user that
  *         the submitted Data is successfully sent over USB.
  *
  * @param  Buf: Buffer of data to be received
  * @param  Len: Number of data received (in bytes)
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
  UNUSED(Buf);
  UNUSED(Len);
  UNUSED(epnum);
  count_in = 0;
	
  return (0);
}