Jump to content

    

Использование USB virtual_com примера из Kinetis SDK

Добрый день!

 

Прошу помощи по использованию virtual_com USB стека из FRDM-KL26Z_SC: FRDM-KL26Z Sample Code Package

Данный код создает виртуальный ком порт на USB и отображает на терминале вводимые символы. Код собирается без ошибок и работает на железе.

 

Со своим чайниковским уровнем разобраться в этом коде не могу, хочу использовать как черный ящик.

Виртуальный ком порт хочу использовать для вывода данных и дебага своей программы, вместо традиционного UART. Для начала просто вывести строку символов, но даже с этим у меня проблема.

Использование USB принципиально, ради этого все и затевается.

 

Собственно если развернуть этот SDK то интересующий меня пример KSDK1.1.0_KL26Z_KW01Z_1.0.0\usb\example\device\cdc\virtual_com\virtual _com.c

#include "usb_device_config.h"
#include "usb.h"
#include "usb_device_stack_interface.h"
#include "virtual_com.h"
#include "fsl_device_registers.h"
#include "fsl_clock_manager.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_port_hal.h"
#include <stdio.h>
#include <stdlib.h>
#include "board.h"

/*****************************************************************************
* Constant and Macro's - None
*****************************************************************************/

/*****************************************************************************
* Global Functions Prototypes
*****************************************************************************/
void TestApp_Init(void);

/****************************************************************************
* Global Variables
****************************************************************************/
extern usb_desc_request_notify_struct_t  desc_callback;

cdc_handle_t   g_app_handle;

/*****************************************************************************
* Local Types - None
*****************************************************************************/

/*****************************************************************************
* Local Functions Prototypes
*****************************************************************************/
void USB_App_Device_Callback(uint8_t event_type, void* val,void* arg);
uint8_t USB_App_Class_Callback(uint8_t event, uint16_t value, uint8_t ** data, uint32_t* size, void* arg); 
void Virtual_Com_App(void);
/*****************************************************************************
* Local Variables 
*****************************************************************************/
uint8_t g_line_coding[LINE_CODING_SIZE] = 
{
/*e.g. 0x00,0x10,0x0E,0x00 : 0x000E1000 is 921600 bits per second */
(LINE_CODE_DTERATE_IFACE>> 0) & 0x000000FF,
(LINE_CODE_DTERATE_IFACE>> 8) & 0x000000FF,
(LINE_CODE_DTERATE_IFACE>>16) & 0x000000FF, 		 
(LINE_CODE_DTERATE_IFACE>>24) & 0x000000FF,
 LINE_CODE_CHARFORMAT_IFACE,
 LINE_CODE_PARITYTYPE_IFACE,
 LINE_CODE_DATABITS_IFACE
};

uint8_t g_abstract_state[COMM_FEATURE_DATA_SIZE] = 
{
 (STATUS_ABSTRACT_STATE_IFACE>>0) & 0x00FF,
 (STATUS_ABSTRACT_STATE_IFACE>>8) & 0x00FF																		
};

uint8_t g_country_code[COMM_FEATURE_DATA_SIZE] = 
{
(COUNTRY_SETTING_IFACE>>0) & 0x00FF,
(COUNTRY_SETTING_IFACE>>8) & 0x00FF															  
};
static bool start_app = FALSE;
static bool start_transactions = FALSE;
static uint8_t g_curr_recv_buf[DATA_BUFF_SIZE];
static uint8_t g_curr_send_buf[DATA_BUFF_SIZE];
static uint8_t g_recv_size;
static uint8_t g_send_size;
/*****************************************************************************
* Local Functions
*****************************************************************************/

/**************************************************************************//*!
*
* @name  USB_Get_Line_Coding
*
* @brief The function returns the Line Coding/Configuration
*
* @param handle:        handle     
* @param interface:     interface number     
* @param coding_data:   output line coding data     
*
* @return USB_OK                              When Success
*         USBERR_INVALID_REQ_TYPE             when Error
*****************************************************************************/
uint8_t USB_Get_Line_Coding(uint32_t handle, 
                               uint8_t interface, 
                               uint8_t * *coding_data)
{   
   UNUSED_ARGUMENT(handle)
   /* if interface valid */
   if(interface < USB_MAX_SUPPORTED_INTERFACES)
   {
       /* get line coding data*/
       *coding_data = g_line_coding;
       return USB_OK;  
   }

   return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************//*!
*
* @name  USB_Set_Line_Coding
*
* @brief The function sets the Line Coding/Configuration
*
* @param handle: handle     
* @param interface:     interface number     
* @param coding_data:   output line coding data     
*
* @return USB_OK                              When Success
*         USBERR_INVALID_REQ_TYPE             when Error
*****************************************************************************/
uint8_t USB_Set_Line_Coding(uint32_t handle, 
                               uint8_t interface, 
                               uint8_t * *coding_data)
{   
   uint8_t count;

   UNUSED_ARGUMENT(handle)

   /* if interface valid */
   if(interface < USB_MAX_SUPPORTED_INTERFACES)
   {
       /* set line coding data*/
       for (count = 0; count < LINE_CODING_SIZE; count++) 
       {          
           g_line_coding[count] = *((*coding_data+USB_SETUP_PKT_SIZE) + count);
       }
       return USB_OK;  
   }

   return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************//*!
*
* @name  USB_Get_Abstract_State
*
* @brief The function gets the current setting for communication feature
*                                                  (ABSTRACT_STATE)
* @param handle:        handle
* @param interface:     interface number     
* @param feature_data:   output comm feature data     
*
* @return USB_OK                              When Success
*         USBERR_INVALID_REQ_TYPE             when Error
*****************************************************************************/
uint8_t USB_Get_Abstract_State(uint32_t handle, 
                               uint8_t interface, 
                               uint8_t * *feature_data)
{   
   UNUSED_ARGUMENT(handle)
   /* if interface valid */
   if(interface < USB_MAX_SUPPORTED_INTERFACES)
   {
       /* get line coding data*/
       *feature_data = g_abstract_state;
       return USB_OK;  
   }

   return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************//*!
*
* @name  USB_Get_Country_Setting
*
* @brief The function gets the current setting for communication feature
*                                                  (COUNTRY_CODE)
* @param handle:        handle     
* @param interface:     interface number     
* @param feature_data:   output comm feature data     
*
* @return USB_OK                              When Success
*         USBERR_INVALID_REQ_TYPE             when Error
*****************************************************************************/
uint8_t USB_Get_Country_Setting(uint32_t handle, 
                                   uint8_t interface, 
                                   uint8_t * *feature_data)
{   
   UNUSED_ARGUMENT(handle)
   /* if interface valid */
   if(interface < USB_MAX_SUPPORTED_INTERFACES)
   {
       /* get line coding data*/
       *feature_data = g_country_code;
       return USB_OK;  
   }

   return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************//*!
*
* @name  USB_Set_Abstract_State
*
* @brief The function gets the current setting for communication feature
*                                                  (ABSTRACT_STATE)
* @param handle:        handle     
* @param interface:     interface number     
* @param feature_data:   output comm feature data     
*
* @return USB_OK                              When Success
*         USBERR_INVALID_REQ_TYPE             when Error
*****************************************************************************/
uint8_t USB_Set_Abstract_State(uint32_t handle, 
                               uint8_t interface, 
                               uint8_t * *feature_data)
{   
   uint8_t count;
   UNUSED_ARGUMENT(handle)
   /* if interface valid */
   if(interface < USB_MAX_SUPPORTED_INTERFACES)
   {
       /* set Abstract State Feature*/
       for (count = 0; count < COMM_FEATURE_DATA_SIZE; count++) 
       {          
           g_abstract_state[count] = *(*feature_data + count);
       }
       return USB_OK; 
   }

   return USBERR_INVALID_REQ_TYPE;
}

/**************************************************************************//*!
*
* @name  USB_Set_Country_Setting
*
* @brief The function gets the current setting for communication feature
*                                                  (COUNTRY_CODE)
* @param handle: handle     
* @param interface:     interface number     
* @param feature_data:   output comm feature data     
*
* @return USB_OK                              When Success
*         USBERR_INVALID_REQ_TYPE             when Error
*****************************************************************************/
uint8_t USB_Set_Country_Setting(uint32_t handle, 
                                   uint8_t interface, 
                                   uint8_t * *feature_data)
{   
   uint8_t count;
   UNUSED_ARGUMENT (handle)

   /* if interface valid */
   if(interface < USB_MAX_SUPPORTED_INTERFACES)
   {
       for (count = 0; count < COMM_FEATURE_DATA_SIZE; count++) 
       {          
           g_country_code[count] = *(*feature_data + count);
       }
       return USB_OK; 
   }

   return USBERR_INVALID_REQ_TYPE;
}
/*****************************************************************************
*  
*	@name		 APP_init
* 
*	@brief		 This function do initialization for APP.
* 
*	@param		 None
* 
*	@return 	 None
**				  
*****************************************************************************/
void APP_init()
{
   cdc_config_struct_t cdc_config;
   cdc_config.cdc_application_callback.callback = USB_App_Device_Callback;
   cdc_config.cdc_application_callback.arg = &g_app_handle;
   cdc_config.vendor_req_callback.callback = NULL;
   cdc_config.vendor_req_callback.arg = NULL;
   cdc_config.class_specific_callback.callback = USB_App_Class_Callback;
   cdc_config.class_specific_callback.arg = &g_app_handle;
   cdc_config.desc_callback_ptr =  &desc_callback;
   /* Always happen in control endpoint hence hard coded in Class layer*/

#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX)
g_curr_recv_buf = OS_Mem_alloc_uncached_align(DATA_BUFF_SIZE, 32);
g_curr_send_buf = OS_Mem_alloc_uncached_align(DATA_BUFF_SIZE, 32);
#endif
   /* Initialize the USB interface */
   USB_Class_CDC_Init(CONTROLLER_ID, &cdc_config, &g_app_handle);
   g_recv_size = 0;
   g_send_size= 0;    
}

/*****************************************************************************
*  
*	@name		 APP_task
* 
*	@brief		 This function runs APP task.
*	@param		 None
* 
*	@return 	 None
**				  
*****************************************************************************/
void APP_task()
{
   while (TRUE) 
   {
       /* call the periodic task function */      
       USB_CDC_Periodic_Task();           

      /*check whether enumeration is complete or not */
       if((start_app==TRUE) && (start_transactions==TRUE))
       {        
           Virtual_Com_App(); 
       }            
   }/* Endwhile */   
}

/******************************************************************************
* 
*    @name       Virtual_Com_App
*    
*    @brief      
*                  
*    @param      None
* 
*    @return     None
*    
*****************************************************************************/
void Virtual_Com_App(void)
{
   /* User Code */ 

   if(g_recv_size) 
   {
       int32_t i;

       /* Copy Buffer to Send Buff */
       for (i = 0; i < g_recv_size; i++)
       {
        //   USB_PRINTF("Copied: %c\n", g_curr_recv_buf[i]);
       	g_curr_send_buf[g_send_size++] = g_curr_recv_buf[i];
       }
       g_recv_size = 0;
   }

   if(g_send_size) 
   {
       uint8_t error;
       uint8_t size = g_send_size;
       g_send_size = 0;

       error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,
       	g_curr_send_buf, size);

       if(error != USB_OK) 
       {
           /* Failure to send Data Handling code here */
       } 
   }
   return;
}

/******************************************************************************
* 
*    @name        USB_App_Device_Callback
*    
*    @brief       This function handles the callback  
*                  
*    @param       handle : handle to Identify the controller
*    @param       event_type : value of the event
*    @param       val : gives the configuration value 
* 
*    @return      None
*
*****************************************************************************/
void USB_App_Device_Callback(uint8_t event_type, void* val,void* arg) 
{
   uint32_t handle;
   handle = *((uint32_t *)arg);
   if(event_type == USB_DEV_EVENT_BUS_RESET)
   {
       start_app=FALSE;    
   }
   else if(event_type == USB_DEV_EVENT_CONFIG_CHANGED)
   {
       /* Schedule buffer for receive */
       USB_Class_CDC_Recv_Data(handle, DIC_BULK_OUT_ENDPOINT, g_curr_recv_buf, DIC_BULK_OUT_ENDP_PACKET_SIZE);
       start_app=TRUE;
   }
   else if(event_type == USB_DEV_EVENT_ERROR)
   {
       /* add user code for error handling */
   }
   return;
}

/******************************************************************************
* 
*    @name        USB_App_Class_Callback
*    
*    @brief       This function handles the callback for Get/Set report req  
*                  
*    @param       request  :  request type
*    @param       value    :  give report type and id
*    @param       data     :  pointer to the data 
*    @param       size     :  size of the transfer
*
*    @return      status
*                  USB_OK  :  if successful
*                  else return error
*
*****************************************************************************/

uint8_t USB_App_Class_Callback
(
   uint8_t event, 
   uint16_t value, 
   uint8_t ** data, 
   uint32_t* size,
   void* arg
) 
{
   cdc_handle_t handle;
   uint8_t error = USB_OK;
   handle = *((cdc_handle_t *)arg);
   switch(event)
   {
	case GET_LINE_CODING:
		error = USB_Get_Line_Coding(handle, value, data);
	break;
	case GET_ABSTRACT_STATE:
		error = USB_Get_Abstract_State(handle, value, data);
	break;
	case GET_COUNTRY_SETTING:
		error = USB_Get_Country_Setting(handle, value, data);
	break;
	case SET_LINE_CODING:
		error = USB_Set_Line_Coding(handle, value, data);
	break;
	case SET_ABSTRACT_STATE:
		error = USB_Set_Abstract_State(handle, value, data);
	break;
	case SET_COUNTRY_SETTING:
		error = USB_Set_Country_Setting(handle, value, data);
	break;
	case USB_APP_CDC_DTE_ACTIVATED:
		if(start_app == TRUE)
		{
			start_transactions = TRUE; 
		}
	break;
	case USB_APP_CDC_DTE_DEACTIVATED:
		if(start_app == TRUE)
		{
			start_transactions = FALSE; 
		}
	break;
	case USB_DEV_EVENT_DATA_RECEIVED:
	{
           if((start_app == TRUE) && (start_transactions == TRUE))
           {
			g_recv_size = *size;
			if(!g_recv_size)
			{
				 /* Schedule buffer for next receive event */
				 USB_Class_CDC_Recv_Data(handle, DIC_BULK_OUT_ENDPOINT, g_curr_recv_buf, DIC_BULK_OUT_ENDP_PACKET_SIZE); 
			}

           }
       }
	break;
	case USB_DEV_EVENT_SEND_COMPLETE:
	{
        if ((size != NULL) && (*size != 0) && !(*size % DIC_BULK_IN_ENDP_PACKET_SIZE))
        {
			/* If the last packet is the size of endpoint, then send also zero-ended packet,
			** meaning that we want to inform the host that we do not have any additional
			** data, so it can flush the output.
	             */
            USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT, NULL, 0);
        } else if((start_app == TRUE) && (start_transactions == TRUE))
           {
			 if((*data != NULL) || ((*data == NULL) && (*size == 0)))
			 {
				 /* User: add your own code for send complete event */ 
				 /* Schedule buffer for next receive event */
				 USB_Class_CDC_Recv_Data(handle, DIC_BULK_OUT_ENDPOINT, g_curr_recv_buf, DIC_BULK_OUT_ENDP_PACKET_SIZE); 
			 }
           }
	}
	break;
       default:
       error = USBERR_INVALID_REQ_TYPE;
   }

   return error;
}

static void Task_Start(void *arg)
{
       /* call the periodic task function */      
       USB_CDC_Periodic_Task();           

      /*check whether enumeration is complete or not */
       if((start_app==TRUE) && (start_transactions==TRUE))
{
           Virtual_Com_App(); 
   }
}

int main(void)
{
   OSA_Init();
   hardware_init();
   dbg_uart_init();

   APP_init();

   OS_Task_create(Task_Start, NULL, 9L, 1000L, "task_start", NULL);

   OSA_Start();

	USB_PRINTF("Test:\n");

   return 1;
}

/* EOF */

 

Я хочу использовать что-то типа printf который будет выводить в виртуальный порт. В примере даже есть закомментированная строка

 

// USB_PRINTF("Copied: %c\n", g_curr_recv_buf[i]);

 

как я понимаю это какраз то что мне нужно, но если ее раскомментировать то ничего не меняется, если вставить в тело main такое - тоже.

Хотя собирается без ошибок во всех случаях.

Edited by greenhorn

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this