device/usbd_cdc_if.c
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
#if 0
	/* test loopback */
	CDC_Transmit_FS(Buf, *Len);
#else
	uint32_t cnt, sz;
	
	/* process serial */
	cnt = 0;
	while(cnt < *Len)
	{
		/* process buffer */
		switch(ser_state)
		{
			case SER_WAIT:
				/* Wait for start of command */
				if(Buf[cnt++] == 's')
				{
					/* advance to Head state */
					ser_state = SER_HEAD;
					ser_cnt = 4;
					ser_len = 0;
					ser_err = 0;
 				}
				break;
			
			case SER_HEAD:
				/* process header */
				if(ser_cnt-- > 0)
				{
					/* assemble 4 bytes to length */
					ser_len = (ser_len<<8) | Buf[cnt++];
				}
				else
				{
					/* start configuration and send remaining buffer */
					if(spi_config_start())
						ser_err |= 1;
					
					sz = *Len-cnt;
                    if(sz < ser_len)
                    {
                        /* announced data length is more than remaining */
                        spi_send_data(&Buf[cnt], sz);
                        
                        /* advance to Body state */
                        ser_state = SER_BODY;
                        ser_len -= sz;
                        cnt = *Len;
                    }
                    else
                    {
                        /* announced data length is less than remaining */
                        spi_send_data(&Buf[cnt], ser_len);
                        if(spi_config_finish())
							ser_err |= 2;
                        
                        /* return to Wait */
                        cnt += ser_len;
                        ser_len = 0;
						
						/* send status */
						UserTxBufferFS[0] = ser_err;
						CDC_Transmit_FS(UserTxBufferFS, 1);
						
                        ser_state = SER_WAIT;
                    }
				}
				break;
				
			case SER_BODY:
				/* process body */
				if(*Len < ser_len)
				{
					/* continue sending */
					spi_send_data(Buf, *Len);
					ser_len -= *Len;
					cnt = *Len;
				}
				else
				{
					/* finish sending and return to Wait state */
                    /* if *Len != ser_len then tty added some junk! */
					spi_send_data(Buf, ser_len);
					if(spi_config_finish())
						ser_err |= 2;
					if(*Len != ser_len)
						ser_err |= 4;
					cnt += ser_len;
					ser_len = 0;

					/* send status */
					UserTxBufferFS[0] = ser_err;
					CDC_Transmit_FS(UserTxBufferFS, 1);
						
					ser_state = SER_WAIT;
				}
				break;
				
			default:
				/* return to Wait state */
				ser_state = SER_WAIT;
				break;
		}
	}
#endif
	
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  return (USBD_OK);
  /* USER CODE END 6 */
}
/**
  * @brief  Data received over USB OUT endpoint are sent over CDC interface
  *         through this function.
  *
  *         @note
  *         This function will block any OUT packet reception on USB endpoint
  *         untill exiting this function. If you exit this function before transfer
  *         is complete on CDC interface (ie. using DMA controller) it will result
  *         in receiving more data while previous ones are still not sent.
  *
  * @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
  */
@brief  Data received over USB OUT endpoint are sent over CDC interface
through this function.

@note
This function will block any OUT packet reception on USB endpoint
untill exiting this function. If you exit this function before transfer
is complete on CDC interface  it will result
in receiving more data while previous ones are still not sent.

@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
@brief Data received over USB OUT endpoint are sent over CDC interface through this function . @note This function will block any OUT packet reception on USB endpoint untill exiting this function . If you exit this function before transfer is complete on CDC interface it will result in receiving more data while previous ones are still not sent . @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_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
#if 0
	CDC_Transmit_FS(Buf, *Len);
#else
	uint32_t cnt, sz;
	cnt = 0;
	while(cnt < *Len)
	{
		switch(ser_state)
		{
			case SER_WAIT:
				if(Buf[cnt++] == 's')
				{
					ser_state = SER_HEAD;
					ser_cnt = 4;
					ser_len = 0;
					ser_err = 0;
 				}
				break;
			case SER_HEAD:
				if(ser_cnt-- > 0)
				{
					ser_len = (ser_len<<8) | Buf[cnt++];
				}
				else
				{
					if(spi_config_start())
						ser_err |= 1;
					sz = *Len-cnt;
                    if(sz < ser_len)
                    {
                        spi_send_data(&Buf[cnt], sz);
                        ser_state = SER_BODY;
                        ser_len -= sz;
                        cnt = *Len;
                    }
                    else
                    {
                        spi_send_data(&Buf[cnt], ser_len);
                        if(spi_config_finish())
							ser_err |= 2;
                        cnt += ser_len;
                        ser_len = 0;
						UserTxBufferFS[0] = ser_err;
						CDC_Transmit_FS(UserTxBufferFS, 1);
                        ser_state = SER_WAIT;
                    }
				}
				break;
			case SER_BODY:
				if(*Len < ser_len)
				{
					spi_send_data(Buf, *Len);
					ser_len -= *Len;
					cnt = *Len;
				}
				else
				{
					spi_send_data(Buf, ser_len);
					if(spi_config_finish())
						ser_err |= 2;
					if(*Len != ser_len)
						ser_err |= 4;
					cnt += ser_len;
					ser_len = 0;
					UserTxBufferFS[0] = ser_err;
					CDC_Transmit_FS(UserTxBufferFS, 1);
					ser_state = SER_WAIT;
				}
				break;
			default:
				ser_state = SER_WAIT;
				break;
		}
	}
#endif
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  return (USBD_OK);
}
static int8_t CDC_Receive_FS ( uint8_t * Buf , uint32_t * Len ) { #if 0 CDC_Transmit_FS ( Buf , * Len ) ; #else uint32_t cnt , sz ; cnt = 0 ; while ( cnt < * Len ) { switch ( ser_state ) { case SER_WAIT : if ( Buf [ cnt ++ ] == ' ' ) { ser_state = SER_HEAD ; ser_cnt = 4 ; ser_len = 0 ; ser_err = 0 ; } break ; case SER_HEAD : if ( ser_cnt -- > 0 ) { ser_len = ( ser_len << 8 ) | Buf [ cnt ++ ] ; } else { if ( spi_config_start ( ) ) ser_err |= 1 ; sz = * Len - cnt ; if ( sz < ser_len ) { spi_send_data ( & Buf [ cnt ] , sz ) ; ser_state = SER_BODY ; ser_len -= sz ; cnt = * Len ; } else { spi_send_data ( & Buf [ cnt ] , ser_len ) ; if ( spi_config_finish ( ) ) ser_err |= 2 ; cnt += ser_len ; ser_len = 0 ; UserTxBufferFS [ 0 ] = ser_err ; CDC_Transmit_FS ( UserTxBufferFS , 1 ) ; ser_state = SER_WAIT ; } } break ; case SER_BODY : if ( * Len < ser_len ) { spi_send_data ( Buf , * Len ) ; ser_len -= * Len ; cnt = * Len ; } else { spi_send_data ( Buf , ser_len ) ; if ( spi_config_finish ( ) ) ser_err |= 2 ; if ( * Len != ser_len ) ser_err |= 4 ; cnt += ser_len ; ser_len = 0 ; UserTxBufferFS [ 0 ] = ser_err ; CDC_Transmit_FS ( UserTxBufferFS , 1 ) ; ser_state = SER_WAIT ; } break ; default : ser_state = SER_WAIT ; break ; } } #endif USBD_CDC_SetRxBuffer ( & hUsbDeviceFS , & Buf [ 0 ] ) ; USBD_CDC_ReceivePacket ( & hUsbDeviceFS ) ; return ( USBD_OK ) ; }
@brief  Data received over USB OUT endpoint are sent over CDC interface
         through this function.
@brief Data received over USB OUT endpoint are sent over CDC interface through this function .
/* USER CODE BEGIN 6 */ /* test loopback */ /* process serial */ /* process buffer */ /* Wait for start of command */ /* advance to Head state */ /* process header */ /* assemble 4 bytes to length */ /* start configuration and send remaining buffer */ /* announced data length is more than remaining */ /* advance to Body state */ /* announced data length is less than remaining */ /* return to Wait */ /* send status */ /* process body */ /* continue sending */ /* finish sending and return to Wait state */ /* if *Len != ser_len then tty added some junk! */ /* send status */ /* return to Wait state */ /* USER CODE END 6 */