I'm using the K22FX512VLH12 chip on a custom board.
I have built my application based off of 2 SDK examples, flexcan_interrupt_transfer & host_hid_mouse_keyboard_bm.
I have successfully gotten USB keyboard input working as well as receiving CAN frames.
It's currently setup to process the USB data while waiting for the next CAN packet and all seems to work well under one condition. The when starting the board / starting debug session, there can't be any CAN traffic on the bus until after the USB keyboard is attached. Otherwise the CAN bus just stops.
If I start with the canbus detached, so no can data is present, then the USB keyboard input and CAN data are received as expected once the canbus is reattached. removing the USB connection properly shows the USB has been detached and the canbus resumes as expected. when reconnecting the USB keyboard, CAN stops.
I have been chasing this for a few days. Help would be greatly appreciated.
@ErichStyger
Here is the main guts of my application:
/*
* The Clear BSD License
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) 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 the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "usb_host_config.h"
#include "usb_host.h"
#include "fsl_device_registers.h"
#include "usb_host_hid.h"
#include "board.h"
#include "host_keyboard_mouse.h"
#include "host_keyboard.h"
#include "host_mouse.h"
#include "fsl_common.h"
#include "fsl_flexcan.h"
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
#include "fsl_sysmpu.h"
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
#include "app.h"
#if ((!USB_HOST_CONFIG_KHCI) && (!USB_HOST_CONFIG_EHCI) && (!USB_HOST_CONFIG_OHCI) && (!USB_HOST_CONFIG_IP3516HS))
#error Please enable USB_HOST_CONFIG_KHCI, USB_HOST_CONFIG_EHCI, USB_HOST_CONFIG_OHCI, or USB_HOST_CONFIG_IP3516HS in file usb_host_config.
#endif
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_gpio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_CAN CAN0
#define EXAMPLE_CAN_CLKSRC kCLOCK_BusClk
#define EXAMPLE_CAN_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk)
#define RX_MESSAGE_BUFFER_NUM (9)
#define TX_MESSAGE_BUFFER_NUM (8)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief host callback function.
*
* device attach/detach callback function.
*
* deviceHandle device handle.
* configurationHandle attached device's configuration descriptor information.
* eventCode callback event code, please reference to enumeration host_event_t.
*
* @retval kStatus_USB_Success The host is initialized successfully.
* @retval kStatus_USB_NotSupported The application don't support the configuration.
*/
static usb_status_t USB_HostEvent(usb_device_handle deviceHandle,
usb_host_configuration_handle configurationHandle,
uint32_t eventCode);
/*!
* @brief application initialization.
*/
static void USB_HostApplicationInit(void);
extern void USB_HostClockInit(void);
extern void USB_HostIsrEnable(void);
extern void USB_HostTaskFn(void *param);
void BOARD_InitHardware(void);
/*******************************************************************************
* Variables
******************************************************************************/
// ===== USB =====
/*! @brief USB host mouse instance global variable */
extern usb_host_mouse_instance_t g_HostHidMouse;
/*! @brief USB host keyboard instance global variable */
extern usb_host_keyboard_instance_t g_HostHidKeyboard;
usb_host_handle g_HostHandle;
// ======FLEXCAN=====
flexcan_handle_t flexcanHandle;
volatile bool txComplete = false;
volatile bool rxComplete = false;
flexcan_mb_transfer_t txXfer, rxXfer;
#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
flexcan_fd_frame_t frame;
#else
flexcan_frame_t frame;
#endif
uint32_t txIdentifier;
uint32_t rxIdentifier;
/*******************************************************************************
* Code
******************************************************************************/
#if defined(USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI > 0U)
void USB0_IRQHandler(void)
{
USB_HostKhciIsrFunction(g_HostHandle);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
__DSB();
}
#endif /* USB_HOST_CONFIG_KHCI */
void USB_HostClockInit(void)
{
#if defined(USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI > 0U)
SystemCoreClockUpdate();
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
#endif
}
void USB_HostIsrEnable(void)
{
uint8_t irqNumber;
#if defined(USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI > 0U)
uint8_t usbHOSTKhciIrq[] = USB_IRQS;
irqNumber = usbHOSTKhciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];
#endif /* USB_HOST_CONFIG_KHCI */
/* Install isr, set priority, and enable IRQ. */
#if defined(__GIC_PRIO_BITS)
GIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
#else
NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
#endif
EnableIRQ((IRQn_Type)irqNumber);
}
void USB_HostTaskFn(void *param)
{
#if defined(USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI > 0U)
USB_HostKhciTaskFunction(param);
#endif
}
/*!
* @brief USB isr function.
*/
static usb_status_t USB_HostEvent(usb_device_handle deviceHandle,
usb_host_configuration_handle configurationHandle,
uint32_t eventCode)
{
usb_status_t status1;
usb_status_t status2;
usb_status_t status = kStatus_USB_Success;
switch (eventCode)
{
case kUSB_HostEventAttach:
status1 = USB_HostHidKeyboardEvent(deviceHandle, configurationHandle, eventCode);
status2 = USB_HostHidMouseEvent(deviceHandle, configurationHandle, eventCode);
if ((status1 == kStatus_USB_NotSupported) && (status2 == kStatus_USB_NotSupported))
{
status = kStatus_USB_NotSupported;
}
break;
case kUSB_HostEventNotSupported:
usb_echo("device not supported.\r\n");
break;
case kUSB_HostEventEnumerationDone:
status1 = USB_HostHidKeyboardEvent(deviceHandle, configurationHandle, eventCode);
status2 = USB_HostHidMouseEvent(deviceHandle, configurationHandle, eventCode);
if ((status1 != kStatus_USB_Success) && (status2 != kStatus_USB_Success))
{
status = kStatus_USB_Error;
}
break;
case kUSB_HostEventDetach:
status1 = USB_HostHidKeyboardEvent(deviceHandle, configurationHandle, eventCode);
status2 = USB_HostHidMouseEvent(deviceHandle, configurationHandle, eventCode);
if ((status1 != kStatus_USB_Success) && (status2 != kStatus_USB_Success))
{
status = kStatus_USB_Error;
}
break;
default:
break;
}
return status;
}
static void USB_HostApplicationInit(void)
{
usb_status_t status = kStatus_USB_Success;
USB_HostClockInit();
#if ((defined FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT))
SYSMPU_Enable(SYSMPU, 0);
#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
status = USB_HostInit(CONTROLLER_ID, &g_HostHandle, USB_HostEvent);
if (status != kStatus_USB_Success)
{
usb_echo("host init error\r\n");
return;
}
USB_HostIsrEnable();
usb_echo("host init done\r\n");
}
void printBanner()
{
printf("============================================ v0.6 \n \
Live data to follow: \n");
}
/*!
* @brief FlexCAN Call Back function
*/
static void flexcan_callback(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 = true;
}
break;
case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM == result)
{
txComplete = true;
}
break;
default:
break;
}
}
int main(void)
{
flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;
//uint8_t node_type;
gpio_pin_config_t pinConfig;
//BOARD_InitPins();
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
// /* enable usb host vbus */
pinConfig.pinDirection = kGPIO_DigitalOutput;
pinConfig.outputLogic = 1;
GPIO_PinInit(PTC, 9, &pinConfig);
USB_HostApplicationInit();
printBanner();
/* Select mailbox ID. */
txIdentifier = 0x00000321;
rxIdentifier = 0x09F80101;
/* Get FlexCAN module default Configuration. */
/*
* flexcanConfig.clksrc=kFLEXCAN_ClkSrcOsc;
* flexcanConfig.baudRate = 1000000U;
* flexcanConfig.maxMbNum = 16;
* flexcanConfig.enableLoopBack = false;
* flexcanConfig.enableSelfWakeup = false;
* flexcanConfig.enableIndividMask = false;
* flexcanConfig.enableDoze = false;
* flexcanConfig.timingConfig = timingConfig;
*/
FLEXCAN_GetDefaultConfig(&flexcanConfig);
flexcanConfig.baudRate = 250000U;
flexcanConfig.enableIndividMask = true;
/* Init FlexCAN module. */
#if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE
flexcanConfig.clksrc=kFLEXCAN_ClkSrcPeri;
#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
/* If special quantum setting is needed, set the timing parameters. */
#if (defined(SET_CAN_QUANTUM) && SET_CAN_QUANTUM)
flexcanConfig.timingConfig.phaseSeg1 = PSEG1;
flexcanConfig.timingConfig.phaseSeg2 = PSEG2;
flexcanConfig.timingConfig.propSeg = PROPSEG;
#endif
FLEXCAN_Init(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ);
#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
/* Enable CAN FD operation with flexible payload and data rate. */
FLEXCAN_FDEnable(EXAMPLE_CAN, BYTES_IN_MB, false);
#endif
/* Create FlexCAN handle structure and set call back function. */
FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);
/* Set Rx Masking mechanism. */
FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_EXT_MASK(rxIdentifier, 0, 0));
/* Setup Rx Message Buffer. */
mbConfig.format = kFLEXCAN_FrameFormatExtend;
mbConfig.type = kFLEXCAN_FrameTypeData;
mbConfig.id = FLEXCAN_ID_EXT(rxIdentifier);
#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
FLEXCAN_SetFDRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
#else
FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
#endif
while (1)
{
/* Start receive data through Rx Message Buffer. */
rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM;
#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
rxXfer.framefd = &frame;
FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
#else
rxXfer.frame = &frame;
FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
#endif
/* Wait until Rx receive full. */
while (!rxComplete)
{
USB_HostTaskFn(g_HostHandle);
USB_HostHidKeyboardTask(&g_HostHidKeyboard);
USB_HostHidMouseTask(&g_HostHidMouse);
};
rxComplete = false;
//printf("Rx MB ID: 0x%3x, Rx MB data: %d, %d\r\n", frame.id >> CAN_ID_EXT_SHIFT, frame.dataWord0, frame.dataWord1);
GPSLED_GREEN_TOGGLE();
}
}