/* * Copyright (c) 2013 - 2016, Freescale Semiconductor, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * o Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * o Neither the name of Freescale Semiconductor, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * This is template for main module created by New Kinetis SDK 2.x Project Wizard. Enjoy! **/ #include #include "board.h" #include "pin_mux.h" #include "clock_config.h" #include "fsl_debug_console.h" #include "fsl_mpu.h" #include "fsl_flexcan.h" #include "usb_host_config.h" #include "usb.h" #include "usb_host.h" #include "usb_host_hci.h" #include "usb_host_devices.h" /* FreeRTOS kernel includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "timers.h" #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI)) #define CONTROLLER_ID kUSB_ControllerKhci0 #endif #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) #define CONTROLLER_ID kUSB_ControllerEhci0 #endif /* Task priorities. */ #define hello_task_PRIORITY (configMAX_PRIORITIES - 1) #define USB_HOST_INTERRUPT_PRIORITY (5U) /*! * @brief Task responsible for printing of "Hello world." message. */ static void hello_task(void *pvParameters) { for (;;) { PRINTF("Hello world.\r\n"); /* Add your code here */ vTaskDelay(5000); } } usb_host_handle g_HostHandle; static usb_status_t USB_HostEvent(usb_device_handle deviceHandle, usb_host_configuration_handle configurationHandle, uint32_t eventCode) { usb_status_t status = kStatus_USB_Success; uint32_t infoValue; switch (eventCode) { case kUSB_HostEventAttach: usb_echo("device attached.\r\n"); // status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode); break; case kUSB_HostEventNotSupported: usb_echo("device not supported.\r\n"); break; case kUSB_HostEventEnumerationDone: usb_echo("device enumerated.\r\n"); USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &infoValue); usb_echo("PID = 0x%x ", infoValue); USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceVID, &infoValue); usb_echo("VID = 0x%x \r\n", infoValue); // status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode); break; case kUSB_HostEventDetach: usb_echo("device removed.\r\n"); USB_HostCloseDeviceInterface(deviceHandle, NULL); // status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode); break; default: break; } return status; } /*! * @brief USB isr function. */ #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI)) void USB0_IRQHandler(void) { USB_HostKhciIsrFunction(g_HostHandle); } #endif /* USB_HOST_CONFIG_KHCI */ #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) void USBHS_IRQHandler(void) { USB_HostEhciIsrFunction(g_HostHandle); } #endif /* USB_HOST_CONFIG_EHCI */ static void USB_HostApplicationInit(void) { usb_status_t status = kStatus_USB_Success; #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI)) #if (defined(FSL_FEATURE_SOC_SCG_COUNT) && (FSL_FEATURE_SOC_SCG_COUNT > 0U)) CLOCK_EnableUsbfs0Clock(kCLOCK_IpSrcFircAsync, CLOCK_GetFreq(kCLOCK_ScgFircAsyncDiv1Clk)); #else CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); #endif #endif /* USB_HOST_CONFIG_KHCI */ #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) IRQn_Type usbHsIrqs[] = USBHS_IRQS; usbIrq = usbHsIrqs[CONTROLLER_ID - kUSB_ControllerEhci0]; CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ); #endif /* USB_HOST_CONFIG_EHCI */ #if ((defined FSL_FEATURE_SOC_MPU_COUNT) && (FSL_FEATURE_SOC_MPU_COUNT)) MPU_Enable(MPU, 0); #endif /* FSL_FEATURE_SOC_MPU_COUNT */ status = USB_HostInit(CONTROLLER_ID, &g_HostHandle, USB_HostEvent); if (status != kStatus_USB_Success) { usb_echo("host init error\r\n"); return; } NVIC_SetPriority(USB0_IRQn, USB_HOST_INTERRUPT_PRIORITY); NVIC_EnableIRQ(USB0_IRQn); usb_echo("host init done\r\n"); } static void USB_HostTask(void *param) { while (1) { #if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI)) USB_HostKhciTaskFunction(param); #endif /* USB_HOST_CONFIG_KHCI */ #if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) USB_HostEhciTaskFunction(param); #endif /* USB_HOST_CONFIG_EHCI */ } } #define RX_MESSAGE_BUFFER_NUM (9) #define TX_MESSAGE_BUFFER_NUM (8) #define RX_MESSAGE_BUFFER_NUM1 (7) #define TX_MESSAGE_BUFFER_NUM1 (6) flexcan_handle_t flexcanHandle[2]; uint32_t txIdentifier[2]; uint32_t rxIdentifier[2]; volatile bool txComplete[2] = {false, false}; volatile bool rxComplete[2] = {false, false}; static void flexcan_callback0(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData) { switch (status) { case kStatus_FLEXCAN_RxIdle: if (RX_MESSAGE_BUFFER_NUM == result) { rxComplete[0] = true; } break; case kStatus_FLEXCAN_TxIdle: if (TX_MESSAGE_BUFFER_NUM == result) { txComplete[0] = true; } break; default: break; } } static void flexcan_callback1(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData) { switch (status) { case kStatus_FLEXCAN_RxIdle: if (RX_MESSAGE_BUFFER_NUM1 == result) { rxComplete[1] = true; } break; case kStatus_FLEXCAN_TxIdle: if (TX_MESSAGE_BUFFER_NUM1 == result) { txComplete[1] = true; } break; default: break; } } void CAN_Init() { flexcan_config_t flexcanConfig; flexcan_rx_mb_config_t mbConfig; txIdentifier[0] = 0x321; rxIdentifier[0] = 0x123; txIdentifier[1] = 0x123; rxIdentifier[1] = 0x321; /* Get FlexCAN module default Configuration. */ /* * flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc; * flexcanConfig.baudRate = 125000U; * flexcanConfig.maxMbNum = 16; * flexcanConfig.enableLoopBack = false; * flexcanConfig.enableSelfWakeup = false; * flexcanConfig.enableIndividMask = false; * flexcanConfig.enableDoze = false; */ FLEXCAN_GetDefaultConfig(&flexcanConfig); /* Init FlexCAN module. */ flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri; FLEXCAN_Init(CAN0, &flexcanConfig, CLOCK_GetFreq(kCLOCK_BusClk)); /* Create FlexCAN handle structure and set call back function. */ FLEXCAN_TransferCreateHandle(CAN0, &flexcanHandle[0], flexcan_callback0, NULL); /* Set Rx Masking mechanism. */ FLEXCAN_SetRxMbGlobalMask(CAN0, FLEXCAN_RX_MB_STD_MASK(rxIdentifier[0], 0, 0)); /* Setup Rx Message Buffer. */ mbConfig.format = kFLEXCAN_FrameFormatStandard; mbConfig.type = kFLEXCAN_FrameTypeData; mbConfig.id = FLEXCAN_ID_STD(rxIdentifier[0]); FLEXCAN_SetRxMbConfig(CAN0, RX_MESSAGE_BUFFER_NUM, &mbConfig, true); /* Setup Tx Message Buffer. */ FLEXCAN_SetTxMbConfig(CAN0, TX_MESSAGE_BUFFER_NUM, true); /* Get FlexCAN module default Configuration. */ /* * flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc; * flexcanConfig.baudRate = 125000U; * flexcanConfig.maxMbNum = 16; * flexcanConfig.enableLoopBack = false; * flexcanConfig.enableSelfWakeup = false; * flexcanConfig.enableIndividMask = false; * flexcanConfig.enableDoze = false; */ FLEXCAN_GetDefaultConfig(&flexcanConfig); /* Init FlexCAN module. */ flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri; FLEXCAN_Init(CAN1, &flexcanConfig, CLOCK_GetFreq(kCLOCK_BusClk)); /* Create FlexCAN handle structure and set call back function. */ FLEXCAN_TransferCreateHandle(CAN1, &flexcanHandle[1], flexcan_callback1, NULL); /* Set Rx Masking mechanism. */ FLEXCAN_SetRxMbGlobalMask(CAN1, FLEXCAN_RX_MB_STD_MASK(rxIdentifier[1], 0, 0)); /* Setup Rx Message Buffer. */ mbConfig.format = kFLEXCAN_FrameFormatStandard; mbConfig.type = kFLEXCAN_FrameTypeData; mbConfig.id = FLEXCAN_ID_STD(rxIdentifier[1]); FLEXCAN_SetRxMbConfig(CAN1, RX_MESSAGE_BUFFER_NUM1, &mbConfig, true); /* Setup Tx Message Buffer. */ FLEXCAN_SetTxMbConfig(CAN1, TX_MESSAGE_BUFFER_NUM1, true); PRINTF("CAN init done \r\n"); } /*! * @brief Application entry point. */ int main(void) { flexcan_frame_t txFrame, rxFrame; flexcan_mb_transfer_t txXfer, rxXfer; /* Init board hardware. */ BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); PRINTF("Hello!\r\n"); USB_HostApplicationInit(); CAN_Init(); /* Add your code here */ rxXfer.frame = &rxFrame; rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM1; FLEXCAN_TransferReceiveNonBlocking(CAN1, &flexcanHandle[1], &rxXfer); txFrame.format = kFLEXCAN_FrameFormatStandard; txFrame.type = kFLEXCAN_FrameTypeData; txFrame.id = FLEXCAN_ID_STD(0x321); txFrame.length = 8; txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) | CAN_WORD0_DATA_BYTE_3(0x44); txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) | CAN_WORD1_DATA_BYTE_7(0x88); txXfer.frame = &txFrame; txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM; PRINTF("tx word0 = 0x%x\r\n", txFrame.dataWord0); PRINTF("tx word1 = 0x%x\r\n", txFrame.dataWord1); PRINTF("CAN0->CAN1\r\n"); FLEXCAN_TransferSendNonBlocking(CAN0, &flexcanHandle[0], &txXfer); while (!rxComplete[1]) { } PRINTF("rx word0 = 0x%x\r\n", rxFrame.dataWord0); PRINTF("rx word1 = 0x%x\r\n", rxFrame.dataWord1); rxXfer.frame = &rxFrame; rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM; FLEXCAN_TransferReceiveNonBlocking(CAN0, &flexcanHandle[0], &rxXfer); txFrame.format = kFLEXCAN_FrameFormatStandard; txFrame.type = kFLEXCAN_FrameTypeData; txFrame.id = FLEXCAN_ID_STD(0x123); txFrame.length = 8; txFrame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x11) | CAN_WORD0_DATA_BYTE_1(0x22) | CAN_WORD0_DATA_BYTE_2(0x33) | CAN_WORD0_DATA_BYTE_3(0x44); txFrame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x55) | CAN_WORD1_DATA_BYTE_5(0x66) | CAN_WORD1_DATA_BYTE_6(0x77) | CAN_WORD1_DATA_BYTE_7(0x88); txXfer.frame = &txFrame; txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM1; PRINTF("tx word0 = 0x%x\r\n", txFrame.dataWord0); PRINTF("tx word1 = 0x%x\r\n", txFrame.dataWord1); PRINTF("CAN1->CAN0\r\n"); FLEXCAN_TransferSendNonBlocking(CAN1, &flexcanHandle[1], &txXfer); while (!rxComplete[0]) { } PRINTF("rx word0 = 0x%x\r\n", rxFrame.dataWord0); PRINTF("rx word1 = 0x%x\r\n", rxFrame.dataWord1); /* Create RTOS task */ if (xTaskCreate(USB_HostTask, "usb host task", 2000L / sizeof(portSTACK_TYPE), g_HostHandle, 4, NULL) != pdPASS) { usb_echo("create host task error\r\n"); } if(xTaskCreate(hello_task, "Hello_task", configMINIMAL_STACK_SIZE, NULL, hello_task_PRIORITY, NULL) != pdPASS) { usb_echo("create hello task error\r\n"); } vTaskStartScheduler(); for(;;) { /* Infinite loop to avoid leaving the main function */ __asm("NOP"); /* something to use as a breakpoint stop while looping */ } }