Yes you are right.
But I am already using a setup with LPCXpresso54628 with CAN-Dual extension Board and a PEAK-USB connected to both CAN ports, as well as a CAN monitoring program PCAN-Explorer. As I already mentioned, sending from the PCAN-explorer to the development board is functioning, so I can read incoming CAN messages. But if I want to transmit a message it won't send it from the board to the PCAN-explorer and is halted in the function MCAN_TransferSendBlocking (more specific at function MCAN_IsTransmitOccurred).
But when I transmit a message using the example program "mcan_interrupt_transfer", I see incoming messages in the PCAN-explorer.
That's why I dont understand why transmission won't function with my own program.
Best regards.
Here, my test code:
/*
* Copyright 2016-2022 NXP
* 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 NXP 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.
*/
/**
* @file test.c
* @brief Application entry point.
*/
#include "board.h"
#include "peripherals.h"
#include "stdlib.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "fsl_mcan.h"
#include "fsl_gpio.h"
#include "fsl_pint.h"
#include "fsl_inputmux.h"
#include <stdio.h>
#include <stdbool.h>
/*******************************************************************************
* Defines
******************************************************************************/
#define LED2_PORT 3U
#define LED2_PIN 3U
#define LED3_PORT 2U
#define LED3_PIN 2U
#define LED_PIN_ON 0U
#define LED_PIN_OFF 1U
#define SW5_PORT_PIN kINPUTMUX_GpioPort1Pin1ToPintsel
#define SW5_ALT_FUNC kPINT_PinInt0
#define CAN_INPUT CAN0
#define CAN_OUTPUT CAN1
#define CAN_DATASIZE (8U)
#define CAN_BITRATE (500000U)
#define MCAN_CLK_FREQ CLOCK_GetMCanClkFreq(0U)
#define STD_FILTER_OFS 0x0
#define STDID_OFFSET (18U)
#define RX_FIFO0_OFS 0x10U
#define TX_BUFFER_OFS 0x20U
#define MSG_RAM_SIZE (TX_BUFFER_OFS + 8 + CAN_DATASIZE)
#define RX_IDENTIFIER 0x123U
#define TX_IDENTIFIER 0x124U
/*******************************************************************************
* Variables
******************************************************************************/
static mcan_config_t mcanConfig;
static mcan_std_filter_element_config_t stdFilter;
//static mcan_fifo_transfer_t rxXfer;
static mcan_rx_buffer_frame_t rxFrame;
static uint8_t rx_data[CAN_DATASIZE];
static mcan_frame_filter_config_t rxFilter;
static mcan_rx_fifo_config_t rxFifo0;
static mcan_tx_buffer_frame_t txFrame;
static mcan_buffer_transfer_t txXfer;
static mcan_tx_buffer_config_t txBuffer;
static uint8_t tx_data[CAN_DATASIZE];
static uint8_t numMessage = 0;
#ifndef MSG_RAM_BASE
SDK_ALIGN(uint8_t msgRam[MSG_RAM_SIZE], 1U << CAN_MRBA_BA_SHIFT);
#else
#define msgRam MSG_RAM_BASE
#endif
static volatile bool rxComplete = false;
static volatile bool txComplete = false;
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief CAN0 IRQ handler (Receiver)
*/
void CAN0_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(CAN_INPUT, CAN_IR_RF0N_MASK);
MCAN_ReadRxFifo(CAN_INPUT, 0, &rxFrame);
rxComplete = true;
SDK_ISR_EXIT_BARRIER;
}
/*!
* @brief Initialize routine for CAN0 (receiver) and CAN1 (transeiver)
*/
static void CAN_Init(void)
{
PRINTF("Initializing CAN ports.\r\n");
/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/* Set MCAN clock 220Mhz/11=20MHz. */
CLOCK_SetClkDiv(kCLOCK_DivCan0Clk, 11U, true);
CLOCK_SetClkDiv(kCLOCK_DivCan1Clk, 11U, true);
/* Initialize CAN structure */
MCAN_GetDefaultConfig(&mcanConfig);
mcanConfig.baudRateA = CAN_BITRATE;
mcanConfig.enableCanfdNormal = false;
/* Improve timing config */
mcan_timing_config_t timing_config;
memset(&timing_config, 0, sizeof(timing_config));
if (MCAN_CalculateImprovedTimingValues(mcanConfig.baudRateA, MCAN_CLK_FREQ, &timing_config))
{
/* Update the improved timing configuration*/
memcpy(&(mcanConfig.timingConfig), &timing_config, sizeof(mcan_timing_config_t));
}
else
{
PRINTF("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
}
PRINTF("MCAN Clk-Frequency: %d Hz\r\n", MCAN_CLK_FREQ);
PRINTF("Bitrate: %d Hz\r\n", mcanConfig.baudRateA);
/* Initialize CAN with modified CAN structure */
MCAN_Init(CAN_INPUT, &mcanConfig, MCAN_CLK_FREQ);
MCAN_Init(CAN_OUTPUT, &mcanConfig, MCAN_CLK_FREQ);
/* Create MCAN handle structure and set call back function. */
// MCAN_TransferCreateHandle(CAN_INPUT, &mcanHandle_0, CAN0_IRQHandler, NULL);
// MCAN_TransferCreateHandle(CAN_OUTPUT, &mcanHandle_1, CAN1_IRQHandler, NULL);
/* Set Message RAM base address and clear to avoid BEU/BEC error. */
MCAN_SetMsgRAMBase(CAN_INPUT, (uint32_t)msgRam);
memset((void *)msgRam, 0, MSG_RAM_SIZE * sizeof(uint8_t));
MCAN_SetMsgRAMBase(CAN_OUTPUT, (uint32_t)msgRam);
memset((void *)msgRam, 0, MSG_RAM_SIZE * sizeof(uint8_t));
/* STD filter config for rxCAN. */
rxFilter.address = STD_FILTER_OFS;
rxFilter.idFormat = kMCAN_FrameIDStandard;
rxFilter.listSize = 1U;
rxFilter.nmFrame = kMCAN_reject0;
rxFilter.remFrame = kMCAN_rejectFrame;
MCAN_SetFilterConfig(CAN_INPUT, &rxFilter);
stdFilter.sfec = kMCAN_storeinFifo0;
/* Classic filter mode, only filter matching ID. */
stdFilter.sft = kMCAN_classic;
stdFilter.sfid1 = RX_IDENTIFIER;
stdFilter.sfid2 = 0x7FFU;
MCAN_SetSTDFilterElement(CAN_INPUT, &rxFilter, &stdFilter, 0);
/* Enable RX fifo0 new message interrupt using interrupt line 0. */
MCAN_EnableInterrupts(CAN_INPUT, 0, CAN_IE_RF0NE_MASK);
EnableIRQ(CAN0_IRQ0_IRQn);
/* RX fifo0 config. */
rxFifo0.address = RX_FIFO0_OFS;
rxFifo0.elementSize = 1U;
rxFifo0.watermark = 0;
rxFifo0.opmode = kMCAN_FifoBlocking;
rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
MCAN_SetRxFifo0Config(CAN_INPUT, &rxFifo0);
/* Enable RX fifo0 new message interrupt using interrupt line 0. */
MCAN_EnableInterrupts(CAN_INPUT, 0, CAN_IE_RF0NE_MASK);
EnableIRQ(CAN0_IRQ0_IRQn);
/* TX buffer config. */
memset(&txBuffer, 0, sizeof(txBuffer));
txBuffer.address = TX_BUFFER_OFS;
txBuffer.dedicatedSize = 1U;
txBuffer.fqSize = 0;
txBuffer.datafieldSize = kMCAN_8ByteDatafield;
MCAN_SetTxBufferConfig(CAN_OUTPUT, &txBuffer);
/* Finish software initialization and enter normal mode, synchronizes to
* CAN bus, ready for communication */
MCAN_EnterNormalMode(CAN_INPUT);
MCAN_EnterNormalMode(CAN_OUTPUT);
PRINTF("Available for CAN communication.\r\n");
}
/*!
* @brief Interrupt handler for Switch 5 => transfer CAN message
*/
static void SW_Interrupt_Handler(pint_pin_int_t pintr, uint32_t pmatch_status)
{
GPIO_PortToggle(GPIO, LED3_PORT, 1u << LED3_PIN);
PRINTF("Press any key to trigger one-shot transmission\r\n\r\n");
GETCHAR();
PRINTF("Transmitting CAN message...\r\n");
/* Config TX frame data. */
uint8_t cnt = 0;
for (cnt = 0; cnt < CAN_DATASIZE; cnt++)
{
tx_data[cnt] = cnt;
}
tx_data[0] += numMessage++;
txFrame.xtd = kMCAN_FrameIDStandard;
txFrame.rtr = kMCAN_FrameTypeData;
txFrame.fdf = 0;
txFrame.brs = 0;
txFrame.dlc = 8U;
txFrame.id = TX_IDENTIFIER << STDID_OFFSET;
txFrame.data = tx_data;
txFrame.size = CAN_DATASIZE;
txXfer.frame = &txFrame;
txXfer.bufferIdx = 0;
//status_t status = MCAN_WriteTxBuffer(CAN_OUTPUT, 0, &txFrame);
//status_t status = MCAN_TransferSendNonBlocking(CAN_OUTPUT, &mcanHandle_1, &txXfer);
status_t status = MCAN_TransferSendBlocking(CAN_OUTPUT, 0, &txFrame);
if(status == kStatus_Success)
{
PRINTF("Transmited CAN message!\r\n");
}
else
{
PRINTF("*Error: Failed to transmit CAN message*\r\n");
}
txComplete = false;
}
/*!
* @brief Initialize routine for LED2 and SW5
*/
void GPIO_Init(void)
{
PRINTF("Initializing LED2 and SW5.\r\n");
/* Define the init structure for the LED and SW pin*/
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
/* Init output LED2 and 3 GPIO. */
GPIO_PortInit(GPIO, LED2_PORT);
GPIO_PinInit(GPIO, LED2_PORT, LED2_PIN, &led_config);
GPIO_PinWrite(GPIO, LED2_PORT, LED2_PIN, LED_PIN_OFF);
GPIO_PortInit(GPIO, LED3_PORT);
GPIO_PinInit(GPIO, LED3_PORT, LED3_PIN, &led_config);
GPIO_PinWrite(GPIO, LED3_PORT, LED3_PIN, LED_PIN_OFF);
/* Init input switch 5 GPIO. */
INPUTMUX_Init(INPUTMUX);
INPUTMUX_AttachSignal(INPUTMUX, SW5_ALT_FUNC, SW5_PORT_PIN);
/* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
INPUTMUX_Deinit(INPUTMUX);
/* Initialize the PINT module */
PINT_Init(PINT);
/* Make PINT channel 0 react to falling edges */
PINT_PinInterruptConfig(PINT, SW5_ALT_FUNC, kPINT_PinIntEnableFallEdge, SW_Interrupt_Handler);
/* Enable callbacks for PINT0 by Index */
PINT_EnableCallbackByIndex(PINT, SW5_ALT_FUNC);
}
/*
* @brief Application entry point.
*/
int main(void)
{
/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
/* Init FSL debug console */
BOARD_InitDebugConsole();
/* Init LED and SW */
GPIO_Init();
/* Init CAN TX and RX */
CAN_Init();
uint8_t cnt = 0;
rxFrame.size = CAN_DATASIZE;
/* Enter an infinite loop, print received CAN messages. */
while(1)
{
if(rxComplete)
{
/* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
* only get a point (rxFrame.data) to the fifo reading entrance.
* Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
memcpy(rx_data, rxFrame.data, rxFrame.size);
PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
PRINTF("Received Frame DATA: ");
cnt = 0;
while (cnt < rxFrame.size)
{
PRINTF("0x%x ", rx_data[cnt++]);
}
PRINTF("\r\n");
rxComplete = false;
}
}
return 0;
}