Porting to a new platform

To port the USB stack to a new platform in the MCUXpresso SDK, the SoC-related files, board-related files, and a linker file for a specified compiler are required.

Assume that the new platform’s name is “xxxk22f120m” based on the MK22F51212 SoC.

System-on-Chip (SoC) files

SoC source/header files are in the following directory, which are available by default from MCUXpresso SDK.

|

|

Note:

Linker files for each toolchain are in the linker directory.

Different toolchains’ SoC startup assembler files are in the Arm, GCC, and IAR directories.

Parent topic:Porting to a new platform

Board files

The files for the board configuration and the clock configuration on a specific platform are needed to enable the USB stack.

The clock configuration files are shown in the following image.

|

|

  1. Create a folder “xxxk22f120m” under the examples directory.

  2. Copy the clock_config.c and clock_config.h file from the similar platform. For example, the TWR-K22F120M Tower System module.

  3. Ensure that BOARD_BootClockxxx is implemented in the clock_config.c file. For example, BOARD_BootClockRUN and BOARD_BootClockHSRUN. The user can change the function name. However, the BOARD_InitHardware must call the function. BOARD_InitHardware is introduced later.

    The board clock initialization is based on the board crystal oscillator. Ensure that the following two MACROs are defined in the clock_config.h file:

    #define BOARD_XTAL0_CLK_HZ    8000000U
    #define BOARD_XTAL32K_CLK_HZ  32768U
    
    

    The user can updatethe MACROs according to the board design. For example, if the XTAL0 crystal oscillator is 16000000U and the XTAL32K is 32768U, change the following MACROs as follows:

    #define BOARD_XTAL0_CLK_HZ    **16000000U**
    #define BOARD_XTAL32K_CLK_HZ  32768U
    
    

    The board configuration files are shown in the following image:

    |

|

  1. Copy board.c and board.h from the similar platform. For example, the TWR-K22F120M platform. Ensure that the BOARD_InitDebugConsole is implemented in board.c file and that the BOARD_InitHardware calls the function. The BOARD_InitHardware function is introduced later.

    The Debug console-related MACROS are needed in the board.h file, as follows:

    #define BOARD_DEBUG_UART_TYPE DEBUG_CONSOLE_DEVICE_TYPE_UART
    #define BOARD_DEBUG_UART_BASEADDR (uint32_t) UART2
    #define BOARD_DEBUG_UART_CLKSRC BUS_CLK
    #define BOARD_DEBUG_UART_BAUDRATE 115200
    
    

    Update the MACROs according to the board design. For example, the default UART instance on the board is LPUART1, the type of default UART instance on one specific platform is LPUART, and the LPUART clock source is the external clock. In this case, change the above MACROs as follows:

    #define BOARD_DEBUG_UART_TYPE **DEBUG\_CONSOLE\_DEVICE\_TYPE\_LPUART**
    #define BOARD_DEBUG_UART_BASEADDR (uint32_t) **LPUART1**
    #define BOARD_DEBUG_UART_CLKSRC **kCLOCK\_Osc0ErClk**
    #define BOARD_DEBUG_UART_BAUDRATE 115200
    
    

    Note that there are three kinds of UART instances provided in MCUXpresso SDK devices, UART, LPUART, and LPSCI. The interfaces of the UART instance are different. To provide a uniform UART interface to a USB Host example in which the UART function is used, a UART instance wrapper is provided. The wrapper is implemented in the usb_uart_drv.c, usb_lpuart_drv.c, or usb_lpsci_drv.c file and has a common header file usb_uart_drv.h. For a different UART instance, use the corresponding UART instance wrapper file in the project.

Parent topic:Porting to a new platform

Porting examples

Copy a new platform example

The platform USB examples directory is shown in the following figure.

|

|

Copy the existed example’s whole directory from the similar platform, which ensures that all example source files and project files are copied.

For example, copy the twrk22f120m/usb/usb_device_audio_generator_lite to the twrkxx/usb location, which ensures that sources files and project files for usb_device_audio_generator_lite example are copied.

Parent topic:Porting examples

Porting the example

For different examples, different pins are used. As a result, the pin_mux.c/h files are needed to assign different pins to a specific functionality. Check the board schematic for correct pin settings.

Example-related port pin configurations are required in the following files:

|

|

Ensure the BOARD_InitPins function is implemented in the pin_mux.c file. In this function, the port clock and pin mux are initialized. Ensure that the BOARD_InitHardware calls the function. The BOARD_InitHardware function will be introduced later.

For example, on the TWR-K65F180M board, the VBUS of the USB Host is controlled by the PORTD_8 as a GPIO. Therefore, the PORTD clock needs to be enabled first and then the PORTD_8 configured to GPIO functionality. The debug console uses UART2. The TX/RX pins are PORTE_16 and PORTE_17. As a result, the clock of PORTE needs to be enabled first and then the PORTE_16 and PORTE_17 configured to alternative 3.

This is example code for TWR-K65F180M:

void BOARD_InitPins(void)
{
/* Initialize UART2 pins below */
CLOCK_EnableClock(kCLOCK_PortE);
    PORT_SetPinMux(PORTE, 16u, kPORT_MuxAlt3);
    PORT_SetPinMux(PORTE, 17u, kPORT_MuxAlt3);
    /* Initialize usb vbus pin */
    CLOCK_EnableClock(kCLOCK_PortD);
    PORT_SetPinMux(PORTD, 8u, kPORT_MuxAsGpio);
}

Check the specific board design to find out which port is used to control the USB VBUS and which port is used for the debug console. For example, in the customer’s board design, the PORTC_15 is used to control the USB VBUS, and PORTD_1 and PORTD_2 is used for debug console. The following shows the example code:

void BOARD_InitPins(void)
{
/* Initialize UART2 pins below */
CLOCK_EnableClock(**kCLOCK\_PortD**);
    PORT_SetPinMux(**PORTD, 1u,** kPORT_MuxAlt3);
    PORT_SetPinMux(**PORTD, 2u,** kPORT_MuxAlt3);
    /* Initialize usb vbus pin */
    CLOCK_EnableClock(**kCLOCK\_PortC**);
    PORT_SetPinMux(**PORTC, 15u,** kPORT_MuxAsGpio);
}

The VBUS must output high. The following is example code for TWR-K65F180M:

void BOARD_InitHardware(void)
{
gpio_pin_config_t pinConfig;
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* vbus gpio output high */
pinConfig.pinDirection = kGPIO_DigitalOutput;
pinConfig.outputLogic = 1U;
GPIO_PinInit(PTD, 8U, &pinConfig);
}

The user can change the function as follows:

void BOARD_InitHardware(void)
{
gpio_pin_config_t pinConfig;
BOARD_InitPins();
**BOARD\_BootClockxxx**();
BOARD_InitDebugConsole();
/* vbus gpio output high */
pinConfig.pinDirection = kGPIO_DigitalOutput;
pinConfig.outputLogic = 1U;
GPIO_PinInit(PTC, 15U, &pinConfig);
}

Parent topic:Porting examples

Modify the example project

USB example project files are kept in the example directory, as shown in the following figure.

|

|

  1. Open the project and change the SoC.

    Note:

    1. Check the project SoC and update to the porting platform SoC.

    2. Update the SoC full name, platform name, and board type name macros if the SoC is updated. For example, for TWR-K22F120M, update the CPU_MK22FN512VDC12, TWR_K22F120M, and TOWER macros.

  2. Check the files in startup group, for example (IAR):

    |

|

Ensure that the system\_MK22F51212.c, system\_MK22F51212.h, and strtup\_MK22F51212.s are the porting SoC files. Also change the include path.
  1. Check the files in the platform/clock group, for example (IAR):

    |

|

Ensure that the fsl\_clock\_MK22F51212.c, and fsl\_clock\_MK22F51212.h are porting SoC files. Additionally, change the include path.
  1. Change the files in board group, for example (IAR):

    |

|

Ensure that board.c, board.h, clock\_config.c, and clock\_config.h are porting platform files. Additionally, change the include path.
  1. Check the files in the sources group, for example (IAR):

    |

|

The example application source files are copied when copying the example directory. Change the include path.
  1. Change the linker file to the new platform. Ensure that the linker file is the porting SoC file.

  2. Debug console may use UART, LPUART, or LPSCI according to the platform. As a result, the example project needs to contain UART, LPUART, or LPSCI driver files according to the platform.

    |

|

For example, for TWR-K22F120M all UART files are all in the project. In another example, TWR-K80F150M, all LPUART files are in the project.

Parent topic:Porting examples

USB host CDC example

The MCUXpresso SDK debug console can be based on The MCUXpresso SDK UART, LPUART, or LPSCI driver. Because different platforms may use different drivers, the CDC has a wrapper code. The files, which call the corresponding driver API according to the debug console use UART, LPUART, or LPSCI. The utility uses the BOARD_DEBUG_UART_TYPE toidentify the UART type. To use a different UART instance, use the corresponding UART instance wrapper file.

The MCUXpresso SDK debug console only enables send. The Host CDC example needs the receive function. Therefore, configuration MACROs need to be defined in the board.h file. The debug console and the Host CDC share the same configuration. This is an example:

#define BOARD_DEBUG_UART_TYPE       kSerialPort_Uart
#define BOARD_DEBUG_UART_BASEADDR   (uint32_t)UART1
#define BOARD_DEBUG_UART_CLKSRC     kCLOCK_CoreSysClk
#define BOARD_DEBUG_UART_BAUDRATE   115200

Update MACROs according to board design. For example, the default UART instance on the board is LPUART1, the type of default UART instance on one specific platform is LPUART, and the LPUART clock source is the external clock. In this case, change the above MACROs as follows:

#define BOARD_DEBUG_UART_TYPE **kSerialPort\_Uart**
#define BOARD_DEBUG_UART_BASEADDR (uint32_t) **LPUART1**
#define BOARD_DEBUG_UART_CLKSRC **kCLOCK\_Osc0ErClk**
#define BOARD_DEBUG_UART_BAUDRATE 115200

Parent topic:Porting examples

USB device MSC SD card example

USB device MSC SD card example needs SDHC driver support and SD card support. The example works only if the platform supports both SD card and the SDHC. To enable this example using the same code, the following MACROs are defined in the board.h file:

#define BOARD_SDHC_BASEADDR             SDHC
#define BOARD_SDHC_CLKSRC               kCLOCK_CoreSysClk
#define BOARD_SDHC_CD_GPIO_BASE         GPIOB
#define BOARD_SDHC_CD_GPIO_PIN          20U
#define BOARD_SDHC_CD_PORT_BASE         PORTB
#define BOARD_SDHC_CD_PORT_IRQ          PORTB_IRQn
#define BOARD_SDHC_CD_PORT_IRQ_HANDLER  PORTB_IRQHandler

Update the MACROs according to the board design. For example, the SD card detection GPIO on the board is PORTD_1. In this case, change the above MACROs as follows:

#define BOARD_SDHC_BASEADDR             SDHC
#define BOARD_SDHC_CLKSRC               kCLOCK_CoreSysClk
#define BOARD_SDHC_CD_GPIO_BASE         **GPIOD**
#define BOARD_SDHC_CD_GPIO_PIN          **1U**
#define BOARD_SDHC_CD_PORT_BASE         **PORTD**
#define BOARD_SDHC_CD_PORT_IRQ          **PORTD\_IRQn**
#define BOARD_SDHC_CD_PORT_IRQ_HANDLER  **PORTD\_IRQHandler**

Parent topic:Porting examples

USB device audio speaker example

USB device audio speaker example needs the I2C, SAI, and DMA driver support.

The instance of SAI (I2S) and I2C are defined in the app.h file in the example directory as follows:

#define DEMO_SAI I2S0
#define DEMO_I2C I2C0
#define DEMO_SAI_CLKSRC kCLOCK_CoreSysClk

Update the MACROs according to board design. For example, the I2S instance on the board is I2S2. In this case, change the above MACROs as follows:

#define DEMO_SAI I2S2
#define DEMO_I2C I2C2
#define DEMO_SAI_CLKSRC kCLOCK_CoreSysClk

Parent topic:Porting examples

USB device CCID Smart card example

The example is based on the EMVL1 stack, which works on the EMV protocol. As a result, the example can only be ported to the platform that supports both the EMVL1 stack and the EMV protocol.

Parent topic:Porting examples

Parent topic:Porting to a new platform