I am implementing a simple canbus communication using the K66F micro controller which has a CAN0 and CAN1 buses. The goal is to send a message from CAN0 to CAN1.
I am using the example code provided by NXP for the from K66F board. The problem is that when using a logic analyzer, I can see that the message is sent and acknowledged but the program gets stuck at !rxcomplete, even though I can clearly see that the message has been acknowledged. Therefore I assume I have some configuration parameter not set properly.
I don't know if the parameters i have are the correct. The electronic wiring i think its fine according to the messages sent.
this is the code I'm using:
#include "fsl_debug_console.h"
#include "fsl_flexcan.h"
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
/****************************************************************************
* Definitions
***************************************************************************/
#define EXAMPLE_CAN CAN0
#define EXAMPLE_CAN1 CAN1
#define EXAMPLE_CAN_CLKSRC1 kCLOCK_BusClk
#define EXAMPLE_CAN_CLKSRC kCLOCK_BusClk
#define RX_MESSAGE_BUFFER_NUM (8)
#define TX_MESSAGE_BUFFER_NUM (9)
/***************************************************************************
* Prototypes
*****************************************************************************/
/***************************************************************************
* Variables
***************************************************************************/
volatile bool txComplete = false;
volatile bool rxComplete = false;
flexcan_handle_t flexcanHandle;
flexcan_mb_transfer_t txXfer, rxXfer;
flexcan_frame_t txFrame, rxFrame;
int status;
/***************************************************************************
* Code
***************************************************************************/
/*!
* #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)
{
/* Process FlexCAN Rx event. */
case kStatus_FLEXCAN_RxIdle:
PRINTF("prueba \n");
if (RX_MESSAGE_BUFFER_NUM == result)
{
rxComplete = true;
}
break;
/* Process FlexCAN Tx event. */
case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM == result)
{
txComplete = true;
}
break;
default:
break;
}
/*!
* #brief Main function
*/
int main(void)
{
flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;
/* Initialize board hardware. */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
PRINTF("\r\n==FlexCAN loopback example -- Start.==\r\n\r\n");
/* Init FlexCAN module. */
/*
* 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);
flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri;
//flexcanConfig.enableLoopBack = true;
flexcanConfig.baudRate = 125000U;
FLEXCAN_Init(EXAMPLE_CAN, &flexcanConfig, CLOCK_GetFreq(EXAMPLE_CAN_CLKSRC));
FLEXCAN_Init(EXAMPLE_CAN1, &flexcanConfig, CLOCK_GetFreq(EXAMPLE_CAN_CLKSRC));
/* Setup Rx Message Buffer. */
mbConfig.format = kFLEXCAN_FrameFormatStandard;
mbConfig.type = kFLEXCAN_FrameTypeData;
mbConfig.id = FLEXCAN_ID_STD(0x223);
FLEXCAN_SetRxMbConfig(EXAMPLE_CAN1, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
/* Setup Tx Message Buffer. */
FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
/* Create FlexCAN handle structure and set call back function. */
FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);
//FLEXCAN_TransferCreateHandle(EXAMPLE_CAN1, &flexcanHandle, flexcan_callback, NULL);
/* Start receive data through Rx Message Buffer. */
rxXfer.frame = &rxFrame;
rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM;
FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN1, &flexcanHandle, &rxXfer);
PRINTF("status=%d \n", status);
/* Prepare Tx Frame for sending. */
txFrame.format = kFLEXCAN_FrameFormatStandard;
txFrame.type = kFLEXCAN_FrameTypeData;
txFrame.id = FLEXCAN_ID_STD(0x223);
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);
PRINTF("Send message from MB%d to MB%d\r\n", TX_MESSAGE_BUFFER_NUM, RX_MESSAGE_BUFFER_NUM);
PRINTF("tx word0 = 0x%x\r\n", txFrame.dataWord0);
PRINTF("tx word1 = 0x%x\r\n", txFrame.dataWord1);
/* Send data through Tx Message Buffer. */
txXfer.frame = &txFrame;
txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM;
FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
while ((!txComplete))
{
};
PRINTF("tx complete \n");
/* Waiting for Rx Message finish. */
while ((!rxComplete))
{
};
PRINTF("\r\nReceved message from MB%d\r\n", RX_MESSAGE_BUFFER_NUM);
PRINTF("rx word0 = 0x%x\r\n", rxFrame.dataWord0);
PRINTF("rx word1 = 0x%x\r\n", rxFrame.dataWord1);
/* Stop FlexCAN Send & Receive. */
FLEXCAN_TransferAbortReceive(EXAMPLE_CAN1, &flexcanHandle, RX_MESSAGE_BUFFER_NUM);
FLEXCAN_TransferAbortSend(EXAMPLE_CAN, &flexcanHandle, TX_MESSAGE_BUFFER_NUM);
PRINTF("\r\n==FlexCAN loopback example -- Finish.==\r\n");
while (1)
{
__WFI();
}
}
this is what i can read with the logic analyzer:
}
Thank you in advance.
Callback should be enabled for CAN1 to set rxComplete = true;.
Related
I have been trying to setup a uart on the EFM32 Starter kind and I am now able to send characters out of the EFM32 Starter kit board to a computer, but when I try to receive from the computer using the example, my interrupt gets called once, but the data I get is 0x0 and then after the first character I dont receive the interrupt again.
I modified the code from the application note software that can be found on silab's website: USART/UART Asynchronous mode Application Note software
I have added the code to this question as well. Has anyone else encountered this? I must be doing something silly.
I checked the RXDATA register in the debugger and it keeps showing 0 even when I press a the "a" character on the keyboard. Also the interrupt only fires once, with the rxdata being 0, then I never get an interrupt after that.
Thanks in advance.
/******************************************************************************
* #file main.c
* #brief USART/UART Asynchronous mode Application Note software example
* #author Silicon Labs
* #version 1.03
******************************************************************************
* #section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdint.h>
#include "em_device.h"
#include "em_chip.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "bsp.h"
/* Function prototypes */
void uartSetup(void);
void cmuSetup(void);
void uartPutData(uint8_t * dataPtr, uint32_t dataLen);
uint32_t uartGetData(uint8_t * dataPtr, uint32_t dataLen);
void uartPutChar(uint8_t charPtr);
uint8_t uartGetChar(void);
/* Declare some strings */
const char welcomeString[] = "EFM32 RS-232 - Please press a key\r\n";
const char overflowString[] = "\n---RX OVERFLOW---\n";
const uint32_t welLen = sizeof(welcomeString) - 1;
const uint32_t ofsLen = sizeof(overflowString) - 1;
/* Define termination character */
#define TERMINATION_CHAR '.'
/* Declare a circular buffer structure to use for Rx and Tx queues */
#define BUFFERSIZE 256
volatile struct circularBuffer
{
uint8_t data[BUFFERSIZE]; /* data buffer */
uint32_t rdI; /* read index */
uint32_t wrI; /* write index */
uint32_t pendingBytes; /* count of how many bytes are not yet handled */
bool overflow; /* buffer overflow indicator */
} rxBuf, txBuf = { {0}, 0, 0, 0, false };
/* Setup UART1 in async mode for RS232*/
static USART_TypeDef * uart = USART1;
static USART_InitAsync_TypeDef uartInit = USART_INITASYNC_DEFAULT;
/******************************************************************************
* #brief Main function
*
*****************************************************************************/
int main(void)
{
/* Initialize chip - handle erratas */
CHIP_Init( );
/* Initialize clocks and oscillators */
cmuSetup( );
/* Initialize UART peripheral */
uartSetup( );
/* Initialize Development Kit in EBI mode */
// BSP_Init(BSP_INIT_DEFAULT);
/* Enable RS-232 transceiver on Development Kit */
//BSP_PeripheralAccess(BSP_RS232_UART, true);
/* When DVK is configured, and no more DVK access is needed, the interface can safely be disabled to save current */
//BSP_Disable();
/* Write welcome message to UART */
uartPutData((uint8_t*) welcomeString, welLen);
/* Eternal while loop
* CPU will sleep during Rx and Tx. When a byte is transmitted, an interrupt
* wakes the CPU which copies the next byte in the txBuf queue to the
* UART TXDATA register.
*
* When the predefined termiation character is received, the all pending
* data in rxBuf is copied to txBuf and echoed back on the UART */
while (1)
{
/* Wait in EM1 while UART transmits */
EMU_EnterEM1();
/* Check if RX buffer has overflowed */
if (rxBuf.overflow)
{
rxBuf.overflow = false;
uartPutData((uint8_t*) overflowString, ofsLen);
}
/* Check if termination character is received */
if (rxBuf.data[(rxBuf.wrI - 1) % BUFFERSIZE] == TERMINATION_CHAR)
{
/* Copy received data to UART transmit queue */
uint8_t tmpBuf[BUFFERSIZE];
int len = uartGetData(tmpBuf, 0);
uartPutData(tmpBuf, len);
}
}
}
/******************************************************************************
* #brief uartSetup function
*
******************************************************************************/
void uartSetup(void)
{
/* Enable clock for GPIO module (required for pin configuration) */
CMU_ClockEnable(cmuClock_GPIO, true);
/* Configure GPIO pins */
GPIO_PinModeSet(gpioPortC, 0, gpioModePushPull, 1);
GPIO_PinModeSet(gpioPortC, 1, gpioModeInput, 0);
/* Prepare struct for initializing UART in asynchronous mode*/
uartInit.enable = usartDisable; /* Don't enable UART upon intialization */
uartInit.refFreq = 0; /* Provide information on reference frequency. When set to 0, the reference frequency is */
uartInit.baudrate = 115200; /* Baud rate */
uartInit.oversampling = usartOVS16; /* Oversampling. Range is 4x, 6x, 8x or 16x */
uartInit.databits = usartDatabits8; /* Number of data bits. Range is 4 to 10 */
uartInit.parity = usartNoParity; /* Parity mode */
uartInit.stopbits = usartStopbits1; /* Number of stop bits. Range is 0 to 2 */
// uartInit.mvdis = false; /* Disable majority voting */
// uartInit.prsRxEnable = false; /* Enable USART Rx via Peripheral Reflex System */
// uartInit.prsRxCh = usartPrsRxCh0; /* Select PRS channel if enabled */
/* Initialize USART with uartInit struct */
USART_InitAsync(uart, &uartInit);
/* Prepare UART Rx and Tx interrupts */
USART_IntClear(uart, _UART_IFC_MASK);
USART_IntEnable(uart, UART_IEN_RXDATAV);
NVIC_ClearPendingIRQ(USART1_RX_IRQn);
NVIC_ClearPendingIRQ(USART1_TX_IRQn);
NVIC_EnableIRQ(USART1_RX_IRQn);
NVIC_EnableIRQ(USART1_TX_IRQn);
/* Enable I/O pins at UART1 location #2 */
uart->ROUTE = UART_ROUTE_RXPEN | UART_ROUTE_TXPEN | UART_ROUTE_LOCATION_LOC0;
/* Enable UART */
USART_Enable(uart, usartEnable);
}
/******************************************************************************
* #brief uartGetChar function
*
* Note that if there are no pending characters in the receive buffer, this
* function will hang until a character is received.
*
*****************************************************************************/
uint8_t uartGetChar( )
{
uint8_t ch;
/* Check if there is a byte that is ready to be fetched. If no byte is ready, wait for incoming data */
if (rxBuf.pendingBytes < 1)
{
while (rxBuf.pendingBytes < 1) ;
}
/* Copy data from buffer */
ch = rxBuf.data[rxBuf.rdI];
rxBuf.rdI = (rxBuf.rdI + 1) % BUFFERSIZE;
/* Decrement pending byte counter */
rxBuf.pendingBytes--;
return ch;
}
/******************************************************************************
* #brief uartPutChar function
*
*****************************************************************************/
void uartPutChar(uint8_t ch)
{
/* Check if Tx queue has room for new data */
if ((txBuf.pendingBytes + 1) > BUFFERSIZE)
{
/* Wait until there is room in queue */
while ((txBuf.pendingBytes + 1) > BUFFERSIZE) ;
}
/* Copy ch into txBuffer */
txBuf.data[txBuf.wrI] = ch;
txBuf.wrI = (txBuf.wrI + 1) % BUFFERSIZE;
/* Increment pending byte counter */
txBuf.pendingBytes++;
/* Enable interrupt on USART TX Buffer*/
USART_IntEnable(uart, UART_IEN_TXBL);
}
/******************************************************************************
* #brief uartPutData function
*
*****************************************************************************/
void uartPutData(uint8_t * dataPtr, uint32_t dataLen)
{
uint32_t i = 0;
/* Check if buffer is large enough for data */
if (dataLen > BUFFERSIZE)
{
/* Buffer can never fit the requested amount of data */
return;
}
/* Check if buffer has room for new data */
if ((txBuf.pendingBytes + dataLen) > BUFFERSIZE)
{
/* Wait until room */
while ((txBuf.pendingBytes + dataLen) > BUFFERSIZE) ;
}
/* Fill dataPtr[0:dataLen-1] into txBuffer */
while (i < dataLen)
{
txBuf.data[txBuf.wrI] = *(dataPtr + i);
txBuf.wrI = (txBuf.wrI + 1) % BUFFERSIZE;
i++;
}
/* Increment pending byte counter */
txBuf.pendingBytes += dataLen;
/* Enable interrupt on USART TX Buffer*/
USART_IntEnable(uart, UART_IEN_TXBL);
}
/******************************************************************************
* #brief uartGetData function
*
*****************************************************************************/
uint32_t uartGetData(uint8_t * dataPtr, uint32_t dataLen)
{
uint32_t i = 0;
/* Wait until the requested number of bytes are available */
if (rxBuf.pendingBytes < dataLen)
{
while (rxBuf.pendingBytes < dataLen) ;
}
if (dataLen == 0)
{
dataLen = rxBuf.pendingBytes;
}
/* Copy data from Rx buffer to dataPtr */
while (i < dataLen)
{
*(dataPtr + i) = rxBuf.data[rxBuf.rdI];
rxBuf.rdI = (rxBuf.rdI + 1) % BUFFERSIZE;
i++;
}
/* Decrement pending byte counter */
rxBuf.pendingBytes -= dataLen;
return i;
}
/***************************************************************************//**
* #brief Set up Clock Management Unit
******************************************************************************/
void cmuSetup(void)
{
/* Start HFXO and wait until it is stable */
/* CMU_OscillatorEnable( cmuOsc_HFXO, true, true); */
/* Select HFXO as clock source for HFCLK */
/* CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO ); */
/* Disable HFRCO */
/* CMU_OscillatorEnable( cmuOsc_HFRCO, false, false ); */
/* Enable clock for HF peripherals */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Enable clock for USART module */
CMU_ClockEnable(cmuClock_USART1, true);
}
/**************************************************************************//**
* #brief UART1 RX IRQ Handler
*
* Set up the interrupt prior to use
*
* Note that this function handles overflows in a very simple way.
*
*****************************************************************************/
void USART1_RX_IRQHandler(void)
{
/* Check for RX data valid interrupt */
if (uart->IF & UART_IF_RXDATAV)
{
/* Copy data into RX Buffer */
uint8_t rxData = USART_Rx(uart);
rxBuf.data[rxBuf.wrI] = rxData;
rxBuf.wrI = (rxBuf.wrI + 1) % BUFFERSIZE;
rxBuf.pendingBytes++;
/* Flag Rx overflow */
if (rxBuf.pendingBytes > BUFFERSIZE)
{
rxBuf.overflow = true;
}
}
}
/**************************************************************************//**
* #brief UART1 TX IRQ Handler
*
* Set up the interrupt prior to use
*
*****************************************************************************/
void USART1_TX_IRQHandler(void)
{
/* Check TX buffer level status */
if (uart->IF & UART_IF_TXBL)
{
if (txBuf.pendingBytes > 0)
{
/* Transmit pending character */
USART_Tx(uart, txBuf.data[txBuf.rdI]);
txBuf.rdI = (txBuf.rdI + 1) % BUFFERSIZE;
txBuf.pendingBytes--;
}
/* Disable Tx interrupt if no more bytes in queue */
if (txBuf.pendingBytes == 0)
{
USART_IntDisable(uart, UART_IEN_TXBL);
}
}
}
I am working on Zynq 702 Evaluation Board where I am trying to send and receive data using UART interface. My code works fine when I generate the bitstream from Vivado after selecting the Zynq 702 board in project settings but the same code doesn't work when I specify the corresponding part number(xc7z020clg484-1) in Vivado and then generate the bitstream. (Need to use part number as I will be using custom boards in the future)
Following is the code snippet for sending data:
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
/* Wait until there is space in TX FIFO */
while (XUartPs_IsTransmitFull(UartBaseAddress));
/* Write the byte into the TX FIFO */
XUartPs_WriteReg(UartBaseAddress, XUARTPS_FIFO_OFFSET,
SendBuffer[Index]);
}
The above code works perfectly fine for both with Zynq Board and when using part number.
However I am unable to receive data from UART using following code. This works perfectly when specifying Zynq Board instead of part number in Vivado:
Running = TRUE;
while (Running) {
/* Wait until there is data */
while (!XUartPs_IsReceiveData(UartBaseAddress));
while(recvCount<4)
{
input.bytes_array[recvCount]=XUartPs_RecvByte(UartBaseAddress);
recvCount++;
}
}
The above code is unable to hit the while(recvCount<4) code (on debugging) after sending data through UART terminal(when using part number in Vivado). What could be the problem here? Everything in Vivado block design is the same except the specification of board in one case and part number in the other.
Edit: adding main function and corresponding code:
#include "xparameters.h"
#include "xstatus.h"
#include "xil_types.h"
#include "xil_assert.h"
#include "xuartps_hw.h"
#include "xil_printf.h"
#include "xtime_l.h"
#include <stdio.h>
#include <math.h>
#include "xuartps.h"
#define UART_BASEADDR XPAR_XUARTPS_0_BASEADDR
#define UART_CLOCK_HZ XPAR_XUARTPS_0_CLOCK_HZ
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define TEST_BUFFER_SIZE 16
int UartPsEchoExample(u32 UartBaseAddress,u16 DeviceId);
/************************** Variable Definitions ***************************/
XUartPs Uart_Ps; /* The instance of the UART Driver */
u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
int main(void)
{
int Status;
/*
* Run the Uart Echo example , specify the Base Address that is
* generated in xparameters.h
*/
Status = UartPsEchoExample(UART_BASEADDR, UART_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/**************************************************************************/
/**
*
* This function does a minimal test on the UART device using the hardware
* interface.
*
* #param UartBaseAddress is the base address of the device
*
* #return XST_SUCCESS if successful, XST_FAILURE if unsuccessful
*
* #note None.
*
**************************************************************************/
int UartPsEchoExample(u32 UartBaseAddress,u16 DeviceId)
{
int Index;
u32 Running;
u32 CntrlRegister;
int Status;
union {
float float_variable;
u8 bytes_array[4];
} input,output;
// Overwrite bytes of union with float variable
int recvCount=0;
XUartPs_Config *Config;
/*
* Initialize the UART driver so that it's ready to use
* Look up the configuration in the config table and then initialize it.
*/
Config = XUartPs_LookupConfig(DeviceId);
if (NULL == Config) {
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(&Uart_Ps, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XUartPs_SetBaudRate(&Uart_Ps, 115200);
CntrlRegister = XUartPs_ReadReg(UartBaseAddress, XUARTPS_CR_OFFSET);
/* Enable TX and RX for the device */
XUartPs_WriteReg(UartBaseAddress, XUARTPS_CR_OFFSET,
((CntrlRegister & ~XUARTPS_CR_EN_DIS_MASK) |
XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN));
/*
* Initialize the send buffer bytes with a pattern to send and the
* the receive buffer bytes to zero
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
SendBuffer[Index] = Index + '0';
}
/* Send the entire transmit buffer. */
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
/* Wait until there is space in TX FIFO */
while (XUartPs_IsTransmitFull(UartBaseAddress));
/* Write the byte into the TX FIFO */
XUartPs_WriteReg(UartBaseAddress, XUARTPS_FIFO_OFFSET,
SendBuffer[Index]);
}
Running = TRUE;
while (Running) {
/* Wait until there is data */
while (!XUartPs_IsReceiveData(UartBaseAddress));
while(recvCount<4)
{
input.bytes_array[recvCount]=XUartPs_RecvByte(UartBaseAddress);
//XUartPs_Recv(&Uart_Ps, &u.temp_array[recvCount], 1);
recvCount++;
}
recvCount=0;
}
return XST_SUCCESS;
}
I am trying to implement a flexcan communication using a k66f micro controller. As an initial step I just want to send a message through the tx pin. I am basing my program on an example from NXP.
I am very new to C and specially to micro controller programming. The code I run gets stuck in the following line:
/* Wait until CAN Message send out. */
while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
{
}
I don't know how exactly the meaning of the code since as I understand, FLEXCAN_GetMbStatusFlags is not a function.
Thanks in advance.
the micro controller is nxp's k66f.
Edit: This is the example
#include "fsl_debug_console.h"
#include "fsl_flexcan.h"
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_CAN CAN0
#define EXAMPLE_CAN_CLKSRC kCLOCK_BusClk
#define EXAMPLE_FLEXCAN_IRQn CAN0_ORed_Message_buffer_IRQn
#define EXAMPLE_FLEXCAN_IRQHandler CAN0_ORed_Message_buffer_IRQHandler
#define RX_MESSAGE_BUFFER_NUM (8)
#define TX_MESSAGE_BUFFER_NUM (9)
int status;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool rxComplete = false;
flexcan_frame_t txFrame, rxFrame;
/*******************************************************************************
* Code
******************************************************************************/
/*!
* #brief Main function
*/
int main(void)
{
flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;
/* Initialize board hardware. */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
PRINTF("\r\n==FlexCAN loopback functional example -- Start.==\r\n\r\n");
/* Init FlexCAN module. */
/*
* 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);
flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri;
//flexcanConfig.enableLoopBack = true;
FLEXCAN_Init(EXAMPLE_CAN, &flexcanConfig, CLOCK_GetFreq(EXAMPLE_CAN_CLKSRC));
/* Setup Rx Message Buffer. */
mbConfig.format = kFLEXCAN_FrameFormatStandard;
mbConfig.type = kFLEXCAN_FrameTypeData;
mbConfig.id = FLEXCAN_ID_STD(0x123);
FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
/* Setup Tx Message Buffer. */
FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
/* Enable Rx Message Buffer interrupt. */
FLEXCAN_EnableMbInterrupts(EXAMPLE_CAN, 1 << RX_MESSAGE_BUFFER_NUM);
EnableIRQ(EXAMPLE_FLEXCAN_IRQn);
/* Prepare Tx Frame for sending. */
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);
/* Send data through Tx Message Buffer using polling function. */
status=FlEXCAN_TransferSendBlocking(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, &txFrame);
PRINTF("status= %d \r\n", status);
PRINTF("Send message from MB%d to MB%d\r\n", TX_MESSAGE_BUFFER_NUM, RX_MESSAGE_BUFFER_NUM);
PRINTF("tx word0 = 0x%x\r\n", txFrame.dataWord0);
PRINTF("tx word1 = 0x%x\r\n", txFrame.dataWord1);
/* Waiting for Message receive finish. */
while (!rxComplete)
{
}
PRINTF("\r\nReceved message from MB%d\r\n", RX_MESSAGE_BUFFER_NUM);
PRINTF("rx word0 = 0x%x\r\n", rxFrame.dataWord0);
PRINTF("rx word1 = 0x%x\r\n", rxFrame.dataWord1);
/* Stop FlexCAN Send & Receive. */
FLEXCAN_DisableMbInterrupts(EXAMPLE_CAN, 1 << RX_MESSAGE_BUFFER_NUM);
PRINTF("\r\n==FlexCAN loopback functional example -- Finish.==\r\n");
while (1)
{
__WFI();
}
}
void EXAMPLE_FLEXCAN_IRQHandler(void)
{
/* If new data arrived. */
if (FLEXCAN_GetMbStatusFlags(EXAMPLE_CAN, 1 << RX_MESSAGE_BUFFER_NUM))
{
FLEXCAN_ClearMbStatusFlags(EXAMPLE_CAN, 1 << RX_MESSAGE_BUFFER_NUM);
FLEXCAN_ReadRxMb(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &rxFrame);
rxComplete = true;
}
}
I'm currently doing a project, using RL78G14 as microcontroller. The project involves making an IR remote and control panel. If been trying to write code to setup a UART. I get an few warning messages of passing an incompatible pointer type when passing TxBuf and RxBuf, and my UART doesn't seem to work. Can anyone help me with the code?
void main(void)
{
R_MAIN_UserInit();
uart1Status = R_UART1_Receive(&RxBuf[0],1); // Prime UART1 Rx
while (1U)
{
//Check if byte received on UART
if (RxFlag)
{
// clear rx flag
RxFlag = 0U;
//Echo back the received character
TxBuf[0] = RxBuf[0];
//Send TX buffer, and specify how many characters to write
uart1Status = R_UART1_Send(TxBuf,1);
// re-Prime UART Rx
uart1Status = R_UART1_Receive(RxBuf,1);
}
//If a character has been transmitted
if (TxFlag)
{
// End of UART2 transmit
TxFlag = 0U; // clear tx flag
}
}
/***********************************************************************************************************************
* Function Name: R_UART1_Receive
* Description : This function receives UART1 data.
* Arguments : rx_buf -
* receive buffer pointer
* rx_num -
* buffer size
* Return Value : status -
* MD_OK or MD_ARGERROR
***********************************************************************************************************************/
MD_STATUS R_UART1_Receive(uint8_t * const rx_buf, uint16_t rx_num)
{
MD_STATUS status = MD_OK;
if (rx_num < 1U)
{
status = MD_ARGERROR;
}
else
{
g_uart1_rx_count = 0U;
g_uart1_rx_length = rx_num;
gp_uart1_rx_address = rx_buf;
}
return (status);
}
/***********************************************************************************************************************
* Function Name: R_UART1_Send
* Description : This function sends UART1 data.
* Arguments : tx_buf -
* transfer buffer pointer
* tx_num -
* buffer size
* Return Value : status -
* MD_OK or MD_ARGERROR
***********************************************************************************************************************/
MD_STATUS R_UART1_Send(uint8_t * const tx_buf, uint16_t tx_num)
{
MD_STATUS status = MD_OK;
if (tx_num < 1U)
{
status = MD_ARGERROR;
}
else
{
gp_uart1_tx_address = tx_buf;
g_uart1_tx_count = tx_num;
STMK1 = 1U; /* disable INTST1 interrupt */
TXD1 = *gp_uart1_tx_address;
gp_uart1_tx_address++;
g_uart1_tx_count--;
STMK1 = 0U; /* enable INTST1 interrupt */
}
return (status);
}
If you are using development board, R11 Pin check. It is connected to CAN RXD chip TJA1050T, and hence not receiving any data. Cut R11 jumper and it will start working.
Did you Started UART1 ? need to start it in Initialization.
I am trying to create a file with FatFs on USB flash, but my f_open call trying to read boot sector for first time file system mount hangs on this function.
DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
BYTE status = USBH_MSC_OK;
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
do
{
status = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512 * count);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(status == USBH_MSC_BUSY ); // Loop which create hanging state
}
if(status == USBH_MSC_OK)
return RES_OK;
return RES_ERROR;
}
The main problem is the loop which creates hanging state
while(status == USBH_MSC_BUSY );
So I do not know what to do to avoid this. Using debugger I discover that state is caused by parameter CmdStateMachine of structure USBH_MSC_BOTXferParam, type USBH_BOTXfer_TypeDef is equal CMD_UNINITIALIZED_STATE which actually cause miss up of switch statement of USBH_MSC_Read10 function.
/**
* #brief USBH_MSC_Read10
* Issue the read command to the device. Once the response received,
* it updates the status to upper layer
* #param dataBuffer : DataBuffer will contain the data to be read
* #param address : Address from which the data will be read
* #param nbOfbytes : NbOfbytes to be read
* #retval Status
*/
uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes)
{
uint8_t index;
static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
uint16_t nbOfPages;
status = USBH_MSC_BUSY;
if(HCD_IsDeviceConnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case CMD_SEND_STATE:
/*Prepare the CBW and relevant field*/
USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
for(index = CBW_CB_LENGTH; index != 0; index--)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10;
/*logical block address*/
USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]);
USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
/*USBH_MSC_PAGE_LENGTH = 512*/
nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
/*Tranfer length */
USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
/* Start the transfer, then let the state machine
manage the other transactions */
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
status = USBH_MSC_BUSY;
break;
case CMD_WAIT_STATUS:
if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \
(HCD_IsDeviceConnected(pdev)))
{
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_OK;
}
else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \
(HCD_IsDeviceConnected(pdev)))
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
}
else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
{
/* Failure Mode */
USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
status = USBH_MSC_PHASE_ERROR;
}
else
{
/* Wait for the Commands to get Completed */
/* NO Change in state Machine */
}
break;
default:
break;
}
}
return status;
}
Here is USBH_BOTXfer_TypeDef type declaration;
typedef struct _BOTXfer
{
uint8_t MSCState;
uint8_t MSCStateBkp;
uint8_t MSCStateCurrent;
uint8_t CmdStateMachine;
uint8_t BOTState;
uint8_t BOTStateBkp;
uint8_t* pRxTxBuff;
uint16_t DataLength;
uint8_t BOTXferErrorCount;
uint8_t BOTXferStatus;
} USBH_BOTXfer_TypeDef;
During the debug I discover that all fields of it is 0x00.
Here are my FatFs calls
int main(void)
{
FATFS Fat;
FIL file;
FRESULT fr;
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
/* Enable SWO output */
DBGMCU->CR = 0x00000020;
GPIOD->MODER=0x55000000;
GPIOD->OTYPER = 0x00000000;
GPIOD->OSPEEDR = 0x00000001;
while(1)
{
if (!USB_MSC_IsInitialized())
{
USB_MSC_Initialize();
}
if (USB_MSC_IsConnected())
{
GPIOD->ODR = (1 << 15);
disk_initialize(0);
fr = f_mount(0, &Fat);
if(fr == FR_OK)
{
fr = f_open(&file,"0:DP_lab8.pdf",(FA_CREATE_ALWAYS | FA_WRITE));
if (fr == FR_OK)
{
f_close(&file);
}
f_mount(0, NULL);
}
}
else
{
GPIOD->ODR = (1 << 14);
}
USB_MSC_Main();
}
}
USB_MSC_IsConnected function is:
int USB_MSC_IsConnected(void)
{
if (g_USB_MSC_HostStatus == USB_DEV_NOT_SUPPORTED)
{
USB_MSC_Uninitialize();
}
return !(g_USB_MSC_HostStatus == USB_DEV_DETACHED ||
g_USB_MSC_HostStatus == USB_HOST_NO_INIT ||
g_USB_MSC_HostStatus == USB_DEV_NOT_SUPPORTED);
}
And device states are:
typedef enum
{
USB_HOST_NO_INIT = 0, /* USB interface not initialized */
USB_DEV_DETACHED, /* no device connected */
USB_SPEED_ERROR, /* unsupported USB speed */
USB_DEV_NOT_SUPPORTED, /* unsupported device */
USB_DEV_WRITE_PROTECT, /* device is write protected */
USB_OVER_CURRENT, /* overcurrent detected */
USB_DEV_CONNECTED /* device connected and ready */
} USB_HostStatus;
The value of g_USB_MSC_HostStatus is received by standard USB HOST user callbacks.
I think it is a bug in ST host library. I've hunted it down, as my usb host was unable to pass enumeration stage. After a fix the stack is Ok.
There is union _USB_Setup in usbh_def.h file in "STM32Cube/Repository/STM32Cube_FW_F7_V1.13.0/Middlewares/ST/STM32_USB_Host_Library/Core/Inc" (any chip, not only F7, any version, not only V1.13.0). It has uint16_t bmRequestType and uint16_t bRequest. These two fileds must be uint8_t as of USB specs. Fixing this issue made usb host go as needed. Enumeration stage passes ok, and all other stages as well.