KSDK 1.3 USB Descriptor for MSD and CDC

cancel
Showing results for 
Search instead for 
Did you mean: 

KSDK 1.3 USB Descriptor for MSD and CDC

Jump to solution
2,716 Views
philipp
Contributor II

Hello,

 

I am trying to implement the USB classes for MSD and CDC with the TWR-K60D100m. I am using KSDK 1.3 and Processor Expert.

I used the fsl_usb_device_msd_class component of KSDK 1.3 which is working well. Because there is no class for cdc, I used the example for the TWR-K60 from Freescale (composite device msd_cdc) and took the cdc files.

MSD and CDC are both working but only separately.

 

Because the Towerboard is just my testing device, I would like to use Processor Expert, so that it is easier to implement on my custom device (which I currently dont' have). That's why I would like to know, how I can enable the CDC or composite class driver configuration in the fsl_usb_descriptors. The MSD class driver configuration is enabled because I added fsl_usb_device_msd_class. But for the other ones, I can't find the classes...

 

I guess the alternative would be to write the USB descriptor with the different interfaces by myself. But if you know how to do this with Processor Expert (and KSDK 1.3), it would be great, if you can help me.

 

Thank you!

Labels (1)
0 Kudos
1 Solution
685 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

You have to create this CDC component "manually" and do some modifications in generated code in order to get it working. Here, you can find some steps that I followed to create this CDC + MSD project in FRDM-K64F.

  • Add fsl_usb_device_msd_class to your project (4 components will be also added, among them, you can identify the fsl_usb_descriptors component that will be modified later).
  • Configure fsl_usb_device_msd_class component as desired (enable USB RAM DISK if necessary).
  • Configure fsl_usb_descriptors as follows:
    • Class Code:

Class Code.jpg

    • Class list will be 1 by default, so you need to add another class (set to 2). Class 0 will handle MSD configuration and Class 1 will allocate CDC configuration.
    • Modify Class 1 as shown below:

Class 1 Configuration.jpg

    • Set 2 interfaces to this class (One is used for control and other for data), configure them as follows:

     Interface configuration.jpg

  • Generate code. Now we proceed to do some modifications on generated code (For next modifications, you can use CDC_MSD example available in KSDK 1.3), I am adding a preprocessor definition to identify the added code.
  • In usbDsc1 file, include reference for a header file that will be created later (named cdc1.h):

#include "cdc1.h"

  • Modify lenght size for usbDsc1_Full_Speed_Configuration_1:

#if ADD_CDC_SUPPORT

        0x47 + 8 + 5 + 5 + 4 + 5,0x00,       /* Total length of data for this configuration */

#else

        0x47,0x00,                           /* Total length of data for this configuration: 71 bytes */

#endif

  • After MSD's endpoints descriptros, it is necessary to add Interface Association descriptor for CDC control and data:

/***************************************************************************/

        /* msd1: Endpoint FS Bulk EP2 Bulk OUT, up to 1.216 MB/s Descriptor        */

        /***************************************************************************/

        0x07,                                /* Descriptor size: 7 bytes */

        USB_ENDPOINT_DESCRIPTOR,             /* Descriptor type: ENDPOINT descriptor */

        0x02,                                /* Address: 2 OUT */

        0x02,                                /* Transfer type: Bulk */

        0x40,0x00,                           /* Max. packet size: 64 byte(s) */

        0x01,                                /* Maximum NAK rate: 0x01 microframe(s) */

#if ADD_CDC_SUPPORT

        /* Interface Association Descriptor */

        0x08,                                /* Size of this descriptor */

        0x0B,                                /* INTERFACE ASSOCIATION Descriptor */

        0x01,                                /* Interface number of the CDC Control

                                          interface that is associated with this function */

        0x02,                                /* Number of contiguous CDC interfaces

                                          that are associated with this function */

        0x02,                                /* CDC_CC */

        0x03,

        0x00,                                /* Not used */

        0x00,                                /* Index to string descriptor */

#endif

  • Before endpoint descriptors for CDC, add next descriptors needed for CDC:

/***************************************************************************/

        /* cdc: Interface 1 Alternate setting 0 Descriptor                         */

        /***************************************************************************/

        0x09,                                /* Descriptor size: 9 bytes */

        USB_INTERFACE_DESCRIPTOR,            /* Descriptor type: INTERFACE descriptor */

        0x01,                                /* Interface number: 1 */

        0x00,                                /* Alternative setting number: 0 */

        0x01,                                /* Number of EPs(excluding EP0): 1 */

        0x02,                                /* Class code: 0x02 Communication (Communications and CDC Control) */

        0x02,                                /* Subclass code: 0x02 */

        0x00,                                /* Protocol code: 0x00 */

        0x00,                                /* String descriptor index */

#if ADD_CDC_SUPPORT

        /* CDC Class-Specific descriptor */

        0x05,                                 /* size of Functional Desc in bytes */

        USB_CS_INTERFACE_DESCRIPTOR,          /* descriptor type*/

        USB_CDC_HEADER_FUNC_DESCRIPTOR,

        0x10, 0x01,                           /* USB Class Definitions for CDC spec release number in BCD */

        0x05,                                 /* Size of this descriptor */

        USB_CS_INTERFACE_DESCRIPTOR,          /* descriptor type*/

        USB_CDC_CALL_MANAGEMENT_FUNC_DESCRIPTOR,

        0x01,                                 /* device handles call management itself(D0 set)

                                              and will process commands multiplexed over the data interface */

        0x01,                                 /* Indicates multiplexed commands are handled via data interface */

        0x04,                                 /* Size of this descriptor */

        USB_CS_INTERFACE_DESCRIPTOR,          /* descriptor type*/

        USB_CDC_ABSTRACT_CONTROL_FUNC_DESCRIPTOR,

        0x06,                                 /* Device Supports all commands for ACM - CDC

                                              PSTN SubClass bmCapabilities */

        0x05,                                 /* size of Functional Desc in bytes */

        USB_CS_INTERFACE_DESCRIPTOR,          /* descriptor type*/

        USB_CDC_UNION_FUNC_DESCRIPTOR,

        0x01,                                 /* Interface Number of Control */

        0x02,                                 /* Interface Number of Subordinate (Data Class) Interface */

#endif

  • Also, some other modifications are needed:

#if ADD_CDC_SUPPORT static uint8_t g_alternate_interface[3]; #else volatile uint8_t usbDsc1_CurrentConfiguration = 0U; #endif

  • USB_Desc_Get_Entity_Config_Struct_0 function:

static uint8_t USB_Desc_Get_Entity_Config_Struct_0(uint32_t handle,entity_type type, uint32_t * object) {     switch (type)  {     case USB_CLASS_INFO:    #if !ADD_CDC_SUPPORT         if (usbDsc1_CurrentConfiguration == 0U) {                        *object = (uint32_t)FS_Cfg_1_ClassInfoArray;         }           #endif         break;     case USB_COMPOSITE_INFO: #if !ADD_CDC_SUPPORT         if (usbDsc1_CurrentConfiguration == 0U) {                        *object = (uint32_t)&FS_Cfg_1_CompositInfo;         } #else         *object = (uint32_t)&FS_Cfg_1_CompositInfo; #endif         break;     case USB_CLASS_INTERFACE_INDEX_INFO: #if !ADD_CDC_SUPPORT         if (usbDsc1_CurrentConfiguration == 0U) {             *object = FS_Cfg_1_ClassInfoArray[0].interfaces.interface[0].index;         } #else         *object = 0xff;         if (handle == (uint32_t)cdc1_Handle)         {             *object = (uint32_t)FS_Cfg_1_ClassInfoArray[1].interfaces.interface[g_alternate_interface[1]].index; /* Interface index for CDC*/             break;         }         else if (handle == (uint32_t)msd1_MsdHandle)         {             *object = (uint32_t)(uint32_t)FS_Cfg_1_ClassInfoArray[0].interfaces.interface[g_alternate_interface[0]].index; /* Interface index for MSD*/             break;         } #endif         break;     case USB_MSC_LBA_INFO:         /* Call registered callback */         msd1_get_desc_entity(handle, USB_MSC_LBA_INFO, object);         break;     default :         break;     }/* End Switch */     return USB_OK; }

  • USB_Desc_Get_Interface and USB_Desc_Set_Interface functions:

static uint8_t USB_Desc_Get_Interface (         uint32_t      handle,         uint8_t       interface,         uint8_t      *alt_interface ) {     UNUSED_ARGUMENT(handle); #if ADD_CDC_SUPPORT     /* if interface valid */     if(interface < 3)     {         /* get alternate interface*/         *alt_interface = g_alternate_interface[interface];         return USB_OK;     } #endif     return USBERR_INVALID_REQ_TYPE; }

static uint8_t USB_Desc_Set_Interface (         uint32_t  handle,         uint8_t       interface,         uint8_t       alt_interface ) {     UNUSED_ARGUMENT(handle); #if ADD_CDC_SUPPORT     /* if interface valid */     if(interface < 3)     {         /* set alternate interface*/         g_alternate_interface[interface]=alt_interface;         return USB_OK;     } #endif     return USBERR_INVALID_REQ_TYPE; }

  • USB_Set_Configuration function:

static uint8_t USB_Set_Configuration (         uint32_t      handle,         uint8_t       config ) {     UNUSED_ARGUMENT(handle); #if !ADD_CDC_SUPPORT     usbDsc1_CurrentConfiguration = (config - 1U); #else     uint32_t i;     for(i = 0; i < FS_Cfg_1_CompositInfo.count; i++) {         switch(FS_Cfg_1_CompositInfo.class_handle[i].type)         {         case USB_CLASS_COMMUNICATION:             FS_Cfg_1_ClassInfoArray[i].interfaces.interface = &FS_Cfg_1_Class_1_InterfaceInfoArray[config - 1];             break;         case USB_CLASS_MASS_STORAGE:             FS_Cfg_1_ClassInfoArray[i].interfaces.interface = &FS_Cfg_1_Class_0_InterfaceInfoArray[config - 1];             break;         default:             break;         }     } #endif return USB_OK; }

  • Also ClassConfigInfoArray requires to define callbacks for CDC (these callbacks will be defined in cdc1.h and cdc1.c):

static class_config_struct_t ClassConfigInfoArray[] = {         {                 { /* Application callback setting */                         msd1_application_callback,                                     /* Callback address */                         NULL,                                                          /* Callback argument */                 },                 { /* VendorRequest callback setting */                         NULL,                                                          /* Callback address */                         NULL,                                                          /* Callback argument */                 },                 { /* ClassSpecific callback setting */                         msd1_class_specific_callback,                                  /* Callback address */                         NULL,                                                          /* Callback argument */                 },                 &usbDsc1_desc_callback_Config_Struct_0,                           /* Callback function data structure for the specified type of class */                 { /* BoardInit callback setting */                         NULL,                                                          /* Callback address */                         0,                                                             /* Callback argument */                 },                 0U,                                                               /* Class handle */                 USB_CLASS_MASS_STORAGE                                            /* Class name */         }, #if ADD_CDC_SUPPORT         /* CDC callbacks */         {                 { /* Application callback setting */                         cdc1_application_callback,                                     /* Callback address */                         NULL,                                                          /* Callback argument */                 },                 { /* VendorRequest callback setting */                         NULL,                                                          /* Callback address */                         NULL,                                                          /* Callback argument */                 },                 { /* ClassSpecific callback setting */                         cdc1_class_specific_callback,                                  /* Callback address */                         NULL,                                                          /* Callback argument */                 },                 &usbDsc1_desc_callback_Config_Struct_0,                           /* Callback function data structure for the specified type of class */                 { /* BoardInit callback setting */                         NULL,                                                          /* Callback address */                         0,                                                             /* Callback argument */                 },                 0U,                                                               /* Class handle */                 USB_CLASS_COMMUNICATION                                           /* Class name */         } #endif };

  • Last modification on usbDsc1.c is:

composite_config_struct_t usbDsc1_CompositeConfigStructure = { #if !ADD_CDC_SUPPORT         1,                                                                  /* Number of classes */ #else         2,                                                                  /* Number of classes */ #endif         ClassConfigInfoArray                                                /* Class configuration structure array */ };

  • Then, Cpu.c file needs to be modified in order to initialize CDC handling:

View solution in original post

24 Replies
527 Views
philipp
Contributor II

Hi Isaac,

thanks for your help with the Debug Console as well! I made a mistake.. I thought, that I need the Debug Console to get a communication - but I will need it sooner or later so thanks for your help.

I am currently working with the normal CDC MSD (without the debug console). If I debug it step by step, I get an answer on Termite. So if I type something in, it will be looped back.

But it's just working if I change the code like this:

   case USB_DEV_EVENT_DATA_RECEIVED:           /* Write your code here... */             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(cdc1_Handle, CDC_data_PipeOut, g_curr_recv_buf, DATA_BUFF_SIZE);                 //}             }

With the if(!g_recv_size) the code is not working..

But if I use the code like this, I can loop text back a few time and then it's done. Nothing return.... If I don't use the debug mode, Termite is hanging after I send something to the device..

Do you have an idea what the problem is?

Thanks again for your help!

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

You need to analyze the loopback implementation thas is included in VCOM example, this post explains more about it: KSDK VCOM example does not work without loopback , it would help to understand better how the logic is implemented in this example.

I hope this can help you!

Best Regards,

Isaac

0 Kudos
527 Views
philipp
Contributor II

Hi Isaac,

thanks again - sorry I had vacation.

I still have problems with the CDC_MSD.

If I debug the code and plugin the TWR K60D and the TWR SER with USB, then everything is working. Via the TWR-SER the device is recognized as MSD and CDC - the loopback is working. If I send text, it is send back. The K60 is recognized as Debug Port (as usual).

before.PNG

BUT: If I plug the TWR-SER out and then back in, MSD is working but CDC is not. MSD and CDC is recognized but there is also an "unknown" device detected. If I send data to the CDC (same port as before) nothing is returned..

after.PNG

The program just works fine in debug mode... Do you have an idea about that problem?

Thank you!

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

Does it happen every time you disconnect and connect the device again, doesn't it? Have you tried to reset the board every time the board is disconnected?

It seems to me that something in CDC application isn't being closed/finished correctly and when USB  is connected again it cannot initialized correctly, would you be so kind to share your project with me?

Regards,

Isaac

0 Kudos
527 Views
philipp
Contributor II

Hi Isaac,

ok it works now - even without the debug mode.

But after I send 8 to 9 strings the text is not returned. I get the error "usb_device_send_data: DEV_GET_XD failed".

Do you know this issue? I read that the send_complete event should be called, which is called at least for the first few times.

I attached the code again. Would be great if you can help me to fix this.

Thanks again!

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

You can give a look to this thread where similar issue is presented. It is related to how the application was designed: KSDK VCOM example does not work without loopback

Hope this helps!

Regards,

Isaac

0 Kudos
527 Views
philipp
Contributor II

Hi Isaac,

great, thank you. It's working now. It was just one line but now it's running.

I have one last question:

I try to implement SD card support with the fsl_usb_device_msd_class. There are some tutorials but always without PE.. Can you give me some advice about the best way to implement it?

Thank you!

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

You can give a look to this thread where I created an example that uses SD for the MSD part. It was created for KSDK 1.2 nd for HID_AUDIO composite device example but same principle applies.

Unfortunately, there is not a PEx example but I hope that this example could help you to integrate the solution to your current PEx project: usb_dev_msd_cdc example problems

Hope this helps!

Regards,

Isaac

0 Kudos
527 Views
philipp
Contributor II

Hi Isaac,

thanks for your help.

I tried to implement the MSD SD Card example of the TWRK60. My problem right now is, that there are functions missing like "SD_Card_Info", "SDRead_Block". . Here is what I found How to add SD card support in the composite msd_cdc demo[KSDK 1.3]

But it's not that helpful..

I think the include "SD_esdhc_kinetis.h" is missing. Do you know where to find it or how I can implement the methods by myself?

Thanks!

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

Hello Philip,

You can add SDHC and SD Card driver support for your current project with Processor Expert, however, you MUST modify the current MSD application example that uses RAM disk instead of SD Card. For this purpose, you can use the MSD Device example code that is located on <KSDK_1_3_PATH>\examples\<BOARD>\demo_apps\usb\device\msd as reference.

Following you can find the steps needed to add this PEx support, but application must be changed manually by your own:

Before anything else, be sure that you disable code generation for USB components.

  • Add fsl_sdcard component to your current project. On configuration tabs be sure t oselect fsl_sdhc component as your inherited driver (selected by default)
  • In the Inherited components tab, select the > button to configure SDHC according to your needs:

sd card component.jpg

  • Configure Transfer Mode type, card detection mode and pins that will be used by SDHC controller, next configuration was taken from FRDM-K64F's example (Also, you must check pins that are used for SDHC interface in your board):

sd configuration.jpg

sd card pins.jpg

  • In case you want to use interrupt for SDHC module, you can enable them in Initialization tab.
  • If you select the GPIO detection mode, you will need to add this GPIO component by your own: Add a fsl_gpio component.


SD Card detection pin.jpg

  • Configure SD Card detection pin (Input) as desired, In MSD Device example it is configured to generate interrupt on both edges and adds a pull-down resistor on the pin.
  • If you want to use interrupt to detect attachments/detachments for SD Card, go to Events tab and generate the IRQ handler for proper pin PORT:

Generate Interrupt.jpg

  • Now, you can save changes and generate code. At this point you will have added SD Card and SDHC drivers to your current project.

NOTE: Like CPU.c file was overwritten due new components, you will need to add the CDC code part that was removed:

#include "cdc1.h"

(void)USB_Composite_Init(USBFMW1_USB_CONTROLLER_ID, &usbDsc1_CompositeConfigStructure, &usbDsc1_CompositeHandle);

    msd1_MsdHandle = usbDsc1_CompositeConfigStructure.class_app_callback[0].class_handle;

    cdc_preinit();

    cdc1_Handle = usbDsc1_CompositeConfigStructure.class_app_callback[1].class_handle;

After this, you can compile the project and CDC_MSD application should be working (default RAM_DISK_application) but your example is ready t ochange the RAM disk support for SD card. Use the MSD Device example as reference.

Hope this helps!

Regards,

Isaac

0 Kudos
523 Views
philipp
Contributor II

Edit:

Now it is recognized and says it is working properly. But I can't see the SD card..

pastedImage_0.png

I am still not sure where the problem is.. the Pins should be correct..

Would be nice if you can help me one last time!

Thanks!

________________

Hi Isaac,

ok it looks like my program is working properly. If I plug it it, the CDC component is working and MSD in the device manager is recognized but it says "can't start'...

pastedImage_0.png

Do you have an idea about this problem?

Thank you!

0 Kudos
523 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

Be sure that SD initialization is made correctly (SD is being detected and SDHC initialization does get correct response from SD). After that,  you should check if MSC callback is calling read/write procedures to SD or analyze if USB is sending/received data in MSC inteface.

Could you please attach your MSC callback?

Regards,

Isaac

0 Kudos
523 Views
philipp
Contributor II

Hi Isaac,

thanks for your help!

The read/write callback is not called during debugging.. initialisation and detection is working.

Here is the callback:

uint8_t msd1_class_specific_callback(uint8_t event_type, uint16_t value, uint8_t ** data, uint32_t * size, void * arg)
{
#if msd1_RAM_DISK_DEMO              /* USB RAM disk PEx demo project (This code is possible to enable by 'USB RAM disk demo' property). */

#else
     uint8_t * prevent_removal_ptr;
#if(OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
     sdhc_status_t error_code = kStatus_SDHC_NoError;
#endif
     if (g_disk.read_write_error)
     {
          return USBERR_ERROR;
     }
#endif

     device_lba_info_struct_t * device_lba_info_ptr;
     lba_app_struct_t * lba_data_ptr;
     uint8_t error = USB_OK;

     switch (event_type) {

     /* Write the storage device buffer data the storage device */
     case USB_DEV_EVENT_DATA_RECEIVED:
          /* Write your code here... */
#if SD_CARD_APP
          lba_data_ptr = (lba_app_struct_t*) size;
          if (lba_data_ptr->size == 0)
               free_write_buffer((uint32_t*)lba_data_ptr->buff_ptr);
          else
          {
#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
#if MUTILE_BUFFER && (USE_RTOS)
               uint32_t msg[3] = {(uint32_t)lba_data_ptr->buff_ptr, lba_data_ptr->offset, lba_data_ptr->size};
               OS_MsgQ_send(write_msg_handler, (void*)(msg), 0);
#else
               error_code = SDCARD_DRV_WriteBlocks(&card, lba_data_ptr->buff_ptr, lba_data_ptr->offset >> SDCARD_BLOCK_SIZE_POWER,
                         lba_data_ptr->size >> SDCARD_BLOCK_SIZE_POWER);
               free_write_buffer((uint32_t*)lba_data_ptr->buff_ptr);
               if (error_code != kStatus_SDHC_NoError)
               {
                    error = USBERR_ERROR;
                    g_disk.read_write_error=1;
                    USB_PRINTF("Write SD card error, error = 0x%x.\tPlease check recv buff size(must be less than 128 sectors).\r\n", error_code);
               }
#endif

#else
#if MUTILE_BUFFER
               uint32_t msg[3] = {(uint32_t)lba_data_ptr->buff_ptr, lba_data_ptr->offset, lba_data_ptr->size};
               OS_MsgQ_send(write_msg_handler, (void*)(msg), 0);
#else
               error_code = sd_write_device_sectors(g_sdcard_handle, (lba_data_ptr->offset >> SDCARD_BLOCK_SIZE_POWER),
                         (lba_data_ptr->size >> SDCARD_BLOCK_SIZE_POWER) , 3, lba_data_ptr->buff_ptr,NULL);
               free_write_buffer((uint32_t*)lba_data_ptr->buff_ptr);
               if (error_code != MQX_OK)
               {
                    error = USBERR_ERROR;
                    g_disk.read_write_error=1;
                    USB_PRINTF("Write SD card error, error = 0x%x.\tPlease check recv buff size(must be less than 128 sectors).\r\n", error_code);
               }
#endif
#endif
          }
#endif
          break;

          /* Read data from mass storage device to driver buffer */
     case USB_DEV_EVENT_SEND_COMPLETE:
#if msd1_RAM_DISK_DEMO              /* USB RAM disk PEx demo project (This code is possible to enable by 'USB RAM disk demo' property). */
          lba_data_ptr = (lba_app_struct_t *)size;
          if (lba_data_ptr->size != 0) {
               if(data != NULL) {
                    *data = (uint8_t *)&msd1_StorageDisk[lba_data_ptr->offset];
               }
          }
#else 
          /* Write your code here ... */

#endif
          break;

          /* Code to be added by user for starting, stopping or
           ** ejecting the disk drive. e.g. starting/stopping the motor in
           ** case of CD/DVD
           */
     case USB_MSC_START_STOP_EJECT_MEDIA:
          /* Write your code here... */
          break;

          /* Get data from the storage device before sending it to the USB bus.
           ** It reads data from the mass storage device to the driver buffer.
           */
     case USB_MSC_DEVICE_READ_REQUEST:
#if msd1_RAM_DISK_DEMO              /* USB RAM disk PEx demo project (This code is possible to enable by 'USB RAM disk demo' property). */
          lba_data_ptr = (lba_app_struct_t *)size;
          if(data != NULL) {
               *data = (uint8_t *)&msd1_StorageDisk[lba_data_ptr->offset];
          }
#else
          /* Write your code here ... */
          lba_data_ptr = (lba_app_struct_t*) size;

          if(data != NULL)
          {
               *data = g_msc_bulk_in_buff;
          }
          lba_data_ptr->buff_ptr = g_msc_bulk_in_buff;
#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
#if MUTILE_BUFFER && (USE_RTOS)
          OS_Mutex_lock(sdhc_mutex);
#endif
          error_code = SDCARD_DRV_ReadBlocks(&card, lba_data_ptr->buff_ptr, lba_data_ptr->offset >> SDCARD_BLOCK_SIZE_POWER,
                    lba_data_ptr->size >> SDCARD_BLOCK_SIZE_POWER);
#if MUTILE_BUFFER && (USE_RTOS)
          OS_Mutex_unlock(sdhc_mutex);
#endif
          if (error_code != kStatus_SDHC_NoError)
          {
               error = USBERR_ERROR;
               g_disk.read_write_error=1;
               USB_PRINTF("Read SD card error, error = 0x%x.\tPlease check send buff size(must be less than 128 sectors).\r\n", error_code);
          }
#else
#if MUTILE_BUFFER
          OS_Mutex_lock(sdhc_mutex);
#endif
          error_code = sd_read_device_sectors(g_sdcard_handle, (lba_data_ptr->offset >> SDCARD_BLOCK_SIZE_POWER),
                    (lba_data_ptr->size >> SDCARD_BLOCK_SIZE_POWER) , 3, lba_data_ptr->buff_ptr,NULL);
#if MUTILE_BUFFER
          OS_Mutex_unlock(sdhc_mutex);
#endif
          if (error_code != MQX_OK)
          {
               error = USBERR_ERROR;
               g_disk.read_write_error=1;
               USB_PRINTF("Read SD card error, error = 0x%x.\tPlease check send buff size(must be less than 128 sectors).\r\n", error_code);
          }
#endif
#endif
          break;

          /* Prepare the storage device buffer for USB transfer */
     case USB_MSC_DEVICE_WRITE_REQUEST:
#if msd1_RAM_DISK_DEMO              /* USB RAM disk PEx demo project (This code is possible to enable by 'USB RAM disk demo' property). */
          lba_data_ptr = (lba_app_struct_t *)size;
          if(data != NULL) {
               *data = (uint8_t *)&msd1_StorageDisk[lba_data_ptr->offset];
          }
#else
          /* Write your code here ... */
          lba_data_ptr = (lba_app_struct_t*) size;
          if(data != NULL)
          {
               /* get_write_buffer should return NULL when there are no buffers for writing */
               *data = (uint8_t*)get_write_buffer();
          }


#endif
          break;

     case USB_MSC_DEVICE_FORMAT_COMPLETE:
          /* Write your code here ... */
          break;

     case USB_MSC_DEVICE_REMOVAL_REQUEST:
          /* Write your code here ... */

#if SD_CARD_APP
          prevent_removal_ptr = (uint8_t *) size;
          if (SUPPORT_DISK_LOCKING_MECHANISM)
          {
               g_disk.disk_lock = *prevent_removal_ptr;
          }
          else if ((!SUPPORT_DISK_LOCKING_MECHANISM) && (!(*prevent_removal_ptr)))
          {
               /*there is no support for disk locking and removal of medium is enabled*/
               /* code to be added here for this condition, if required */
          }
#endif
          break;

     case USB_MSC_DEVICE_GET_INFO:
#if msd1_RAM_DISK_DEMO              /* USB RAM disk PEx demo project (This code is possible to enable by 'USB RAM disk demo' property). */
          device_lba_info_ptr = (device_lba_info_struct_t *)size;
          device_lba_info_ptr->num_lun_supported = msd1_RAM_DISK_LUN_NUMBER; /* Logical unit supported */
          device_lba_info_ptr->total_lba_device_supports = msd1_RAM_DISK_SECTOR_COUNT; /* Total logical address blocks */
          device_lba_info_ptr->length_of_each_lab_of_device = msd1_RAM_DISK_SECTOR_SIZE; /* Length of each lab */
#else
          /* Write your code here ... */
          device_lba_info_ptr = (device_lba_info_struct_t*) size;

#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
          device_lba_info_ptr->total_lba_device_supports = card.blockCount;
          device_lba_info_ptr->length_of_each_lab_of_device = card.blockSize;
#else
          sd_get_block_size(g_sdcard_handle, &device_lba_info_ptr->length_of_each_lab_of_device);
          sd_get_blocks_num(g_sdcard_handle, &device_lba_info_ptr->total_lba_device_supports);
#endif
          device_lba_info_ptr->num_lun_supported = LOGICAL_UNIT_SUPPORTED;

#endif
          break;

     default :
          break;
          /* End Switch */
     }
     return error;
}

Thank you!

0 Kudos
523 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

You meant that previous callback isn't called at least one time? You would have to be able to set breakpoint on the callback's beginning and program will have to stop, after that, USB enumeration will fail (USB communication is stopped from device's side) but you need to get this callback called at least once. In case this callback isn't being called then, probably, there is a problem on USB initialization or earlier.

I found one HID + MSC (SDC card) example for KSDK 1.2 (without processor expert), I am attaching this example as reference (some APIs changed, but basically, it uses the same principle). I hope you find it helpful.

If problem persists please let me know it!

Regards,

Isaac

0 Kudos
523 Views
philipp
Contributor II

Hi Isaac,

thank you! It was helpful. It looks like everything is working but the SD Card is not shown on the PC. The TWR recognizes that the card is attached and initialized properly. Do you know where the problem might be?

I attached you my project.

Thanks for your help!

Edit: Fixed Handler..

0 Kudos
527 Views
philipp
Contributor II

Hi Isaac,

thank you for your help.

I attached two projects. The first one is the one, where it is just working in the debug mode. The second one I started from the scratch and tried to get it work.. in this case CDC isn't working yet.

Would be great if you find the problem.

Thank you very much.

Philipp

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

(Continuing...)

#include "cdc1.h"

void Components_Init(void)

{

  /*! DbgCs1 Auto initialization start */

  /* Debug console initialization */

  DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, DEBUG_UART_BAUD, DEBUG_UART_TYPE);

  /*! DbgCs1 Auto initialization end */

  /*! usbDsc1 Auto initialization start */

  (void)USB_Composite_Init(USBFMW1_USB_CONTROLLER_ID, &usbDsc1_CompositeConfigStructure, &usbDsc1_CompositeHandle);

  msd1_MsdHandle = usbDsc1_CompositeConfigStructure.class_app_callback[0].class_handle;

#if ADD_CDC_SUPPORT

  cdc_preinit();

  cdc1_Handle = usbDsc1_CompositeConfigStructure.class_app_callback[1].class_handle;

#endif

  /*! usbDsc1 Auto initialization end */

}

These are all modifications that need to be done on Generated code (be sure that CDC configuration allows to support more than 3 endpoints):

cdc configuration.jpg

CDC class support files are missing, you need to include them so, create a new folder (cdc) under SDK > usb > usb_core > device > sources > classes and add cdc files that are located at: C:\Freescale\KSDK_1.3.0\usb\usb_core\device\sources\classes\cdc, also in include folder, add usb_class_cdc.h file that is located at: C:\Freescale\KSDK_1.3.0\usb\usb_core\device\sources\classes\include.

usb cdc files.jpg

In project properties, add next path:

"${ProjDirPath}/SDK/usb/usb_core/device/sources/classes/cdc"

Path.jpg

Now, just add cdc application files (where callbacks and initialization is made).I am attaching my working project, so you can give a look to cdc1.c and cdc1.h files for reference.

Note: Once you compile and run the project and only MSD is recognized, then you will need to update CDC driver and it would work well.

I hope this can really help you!

Regards,

Isaac

527 Views
philipp
Contributor II

Hi Isaac,

thanks for your answer! It really helped me.

But now I have the problem from your note - only MSD is recognized. I tried to update the cdc driver but it didn't work out.

cdc_msd.PNG

That's how it looks. The device is recognized as "USB Device Component" and also as a MSD. I updated the driver for the COM13 Port but when I listen on the Port with Termite nothing happens. If I try to update the COM14 Port, it's not possible because the device can't start.

Do you know how I can fix it? I guess the problem is the driver - where can I get the correct one? I attached the driver I used.

Thank you very much!

Philipp

0 Kudos
527 Views
isaacavila
NXP Employee
NXP Employee

Hello Philipp,

You must go to Device Manager in your PC and will find that Device is not installed correclty (If this is not shown as it, then right click on device and select uninstall, unplug the device and then plug it again):

Device.jpg

  • Right click under Processor Expert USB Device Component and select Update driver software, select theLet me pick from a list of device drivers on my computer, Click Next:

Let me pick.jpg

  • Then, select the Ports (COM & LPT) device type and click on Next button:

Port Type.jpg

  • Select the CDC driver from Freescale semiconductors and click Next as shown below:

Freescale Driver.jpg

  • A warning window will appear, select Yes and wait until installation is finished:

Update Warning.jpg

  • Finally, CDC Device must be shown on COM Ports:

CDC Device.jpg

I hope this can help you!

Regards,

Isaac

527 Views
philipp
Contributor II

Hello Isaac,

thank you very much. The problem was, that PE was overwriting the changes in the code. I set the code generation to "don't write generated component modules" and now it's working. I can update the driver and the MSD and CDC is recognized.

Right know I try to figure out, how I can print something on Termite. The device is recognized and Termite says it is connected, but nothing happens. Even if I use a forever loop, in which I print a text all the time.

I use the USB port of the TWR-SER. In the DbgCs I use UART5.

Do I have to change some jumpers or how can I do this?

Thank you very much!

0 Kudos