FlexCan stops receiving data after USB keyboard device is plugged into k22

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FlexCan stops receiving data after USB keyboard device is plugged into k22

1,008 Views
stevenlutz
Contributor II

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();

    }
}

 

 

Labels (2)
Tags (1)
0 Kudos
4 Replies

901 Views
stevenlutz
Contributor II

Attaching a keyboard to the K22 as a USB Host (using the USB stack from the SDK examples), for some reason, Is clearing the CAN0_IMASK1 register and therefore disabling the CAN interrupt. 
For the life of me I can't figure out what in the USB stack is causing this issue. 

I have also migrated my project to use FreeRTOS. the USB Host functions now have their own tasks as does the FlexCAN... I'm having a similar issue. 

Any assistance would be greatly appreciated. 

0 Kudos

948 Views
DanielRuvalcaba
NXP TechSupport
NXP TechSupport

Hi,

Could you please check your email? I just answered you internally.

Best regards, Daniel.

0 Kudos

968 Views
stevenlutz
Contributor II

After looking into this deeper, It seem the MB is being overrun as indicated by 
CAN0_CS9 CODE 0x6 RW [27:24] Reserved
Prior to attaching the usb keyboard it reads:
CAN0_CS9 CODE 0x2 RW [27:24] Reserved

Running:
CAN0_IMASK1 0x00000200 RW 0x40024028 Interrupt Masks 1 register
CAN0_IFLAG1 0x00000000 RW 0x40024030 Interrupt Flags 1 register

After Keyboard Attached:
CAN0_IMASK1 0x00000000 RW 0x40024028 Interrupt Masks 1 register
CAN0_IFLAG1 0x00000200 RW 0x40024030 Interrupt Flags 1 register

... so seems that the interrupt is also being disabled. 

I don't understand why the USB functions are effecting the FlexCan at all. 



 

 

 

 

0 Kudos

994 Views
stevenlutz
Contributor II

Some further information, 

If I call 

            USB_HostTaskFn(g_HostHandle);
            USB_HostHidKeyboardTask(&g_HostHidKeyboard);
            USB_HostHidMouseTask(&g_HostHidMouse);

 

Right before:

FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);



Then, The device boots just fine at power-up with the USB keyboard plugged in. I can unplug the USB keyboard from the K22 and the FlexCan data continues to process. Reconnecting the Keyboard causes the FlexCan data to seize again. 

There seems to be a conflict between the Keyboard task and the SetRxMbConfig function but I'm not sure what the issue is. 

Any information would be helpful. 

0 Kudos