Trouble with C code - Setting up UART with e2studio - c

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.

Related

CAN Bus with MCC Microchip

I am trying to transmit through CAN using dsPIC33EV256GM106 and MCC to a raspberry Pi.
I am new to CAN Bus and in c. I have configured CAN Bus and DMA via MCC, and I have called the functions in main.c. but nothing arrives in the Raspberry Pi. Here is my main.c, can.c and some pictures of MCC. If anyone has any ideas, how I can change the code to make the CAN bus work, I would appreciate any help.CAN Bus configuration
DMA
System_Module
#include "mcc_generated_files/system.h"
#include "mcc_generated_files/can_types.h"
#include <stdio.h>
/*
Main application
*/
uCAN_MSG msg;
int main(void)
{
// initialize the device
SYSTEM_Initialize();
CAN1_TransmitEnable();
CAN1_ReceiveEnable();
CAN1_OperationModeSet(CAN_CONFIGURATION_MODE);
msg.frame.id = 0x123;
msg.frame.idType = CAN_FRAME_STD;
msg.frame.msgtype = CAN_MSG_DATA;
msg.frame.dlc = 0x08;
msg.frame.data0 = 0x01;
msg.frame.data1 = 0x02;
msg.frame.data2 = 0x03;
msg.frame.data3 = 0x04;
msg.frame.data4 = 0x05;
msg.frame.data5 = 0x06;
msg.frame.data6 = 0x07;
msg.frame.data7 = 0x08;
while (1)
{
CAN1_Transmit(CAN_PRIORITY_HIGH, &msg);
}
return 1;
}
The pictures show the configuration of DMA and timer in MCC.
enter image description here
enter image description here
#include "can1.h"
#include "dma.h"
#define CAN1_TX_DMA_CHANNEL DMA_CHANNEL_0
#define CAN1_RX_DMA_CHANNEL DMA_CHANNEL_2
/* Valid options are 4, 6, 8, 12, 16, 24, or 32. */
#define CAN1_MESSAGE_BUFFERS 32
#define CAN1_FIFO_STARTING_BUFFER 0x1
#define CAN1_TX_BUFFER_COUNT 1
#define CAN1_RX_BUFFER_MSG_DATA_SIZE 8U // CAN RX Buffer Message object data field size
/* Private type definitions */
/******************************************************************************/
typedef struct __attribute__((packed))
{
unsigned priority :2;
unsigned remote_transmit_enable :1;
unsigned send_request :1;
unsigned error :1;
unsigned lost_arbitration :1;
unsigned message_aborted :1;
unsigned transmit_enabled :1;
} CAN1_TX_CONTROLS;
/**
Section: Private Variable Definitions
*/
/* This alignment is required because of the DMA's peripheral indirect
* addressing mode. */
static unsigned int can1msgBuf [CAN1_MESSAGE_BUFFERS][8] __attribute__((aligned(32 * 8 * 2)));
static void CAN1_DMACopy(uint8_t buffer_number, CAN_MSG_OBJ *message);
static void CAN1_MessageToBuffer(uint16_t* buffer, CAN_MSG_OBJ *message);
// CAN1 Default Interrupt Handler
static void (*CAN1_BusErrorHandler)(void) = NULL;
static void (*CAN1_TxErrorPassiveHandler)(void) = NULL;
static void (*CAN1_RxErrorPassiveHandler)(void) = NULL;
static void (*CAN1_BusWakeUpActivityInterruptHandler)(void) = NULL;
static void (*CAN1_RxBufferInterruptHandler)(void) = NULL;
static void (*CAN1_RxBufferOverFlowInterruptHandler)(void) = NULL;
/**
#Summary
Read the message object from Receive buffer and update to the user message object
pointer.
#Description
This routine read the message object from Receive buffer and update to the user
message object pointer.
#Preconditions
CAN1_Initialize function should be called before calling this function.
#Param
bufferNumber - A buffer number is in the Receive buffer where the message would
be stored.
message - pointer to the CAN1 Receive message object.
#Returns
None
#Example
None
*/
static void CAN1_DMACopy(uint8_t buffer_number, CAN_MSG_OBJ *message)
{
uint16_t ide=0;
uint16_t rtr=0;
uint32_t id=0;
/* read word 0 to see the message type */
ide=can1msgBuf[buffer_number][0] & 0x0001U;
/* check to see what type of message it is */
/* message is standard identifier */
if(ide==0U)
{
message->msgId =(can1msgBuf[buffer_number][0] & 0x1FFCU) >> 2U;
message->field.idType = CAN_FRAME_STD;
rtr=can1msgBuf[buffer_number][0] & 0x0002U;
}
/* message is extended identifier */
else
{
id=can1msgBuf[buffer_number][0] & 0x1FFCU;
message->msgId = id << 16U;
message->msgId += ( ((uint32_t) can1msgBuf[buffer_number][1] & (uint32_t)0x0FFF) << 6U );
message->msgId += ( ((uint32_t) can1msgBuf[buffer_number][2] & (uint32_t)0xFC00U) >> 10U );
message->field.idType = CAN_FRAME_EXT;
rtr=can1msgBuf[buffer_number][2] & 0x0200;
}
/* check to see what type of message it is */
/* RTR message */
if(rtr != 0U)
{
/* to be defined ?*/
message->field.frameType = CAN_FRAME_RTR;
}
/* normal message */
else
{
message->field.frameType = CAN_FRAME_DATA;
message->data[0] =(uint8_t) can1msgBuf[buffer_number][3];
message->data[1] =(uint8_t) ((can1msgBuf[buffer_number][3] & 0xFF00U) >> 8U);
message->data[2] =(uint8_t) can1msgBuf[buffer_number][4];
message->data[3] =(uint8_t) ((can1msgBuf[buffer_number][4] & 0xFF00U) >> 8U);
message->data[4] =(uint8_t) can1msgBuf[buffer_number][5];
message->data[5] =(uint8_t) ((can1msgBuf[buffer_number][5] & 0xFF00U) >> 8U);
message->data[6] =(uint8_t) can1msgBuf[buffer_number][6];
message->data[7] =(uint8_t) ((can1msgBuf[buffer_number][6] & 0xFF00U) >> 8U);
message->field.dlc =(uint8_t) (can1msgBuf[buffer_number][2] & 0x000FU);
}
}
/**
#Summary
Read the message object from user input and update to the CAN1 TX buffer.
#Description
This routine Read the message object from user input and update to the CAN1
TX buffer.
#Preconditions
CAN1_Initialize function should be called before calling this function.
#Param
buffer - pointer to the CAN1 Message object.
message - pointer to the CAN1 transmit message object.
#Returns
None
#Example
None
*/
static void CAN1_MessageToBuffer(uint16_t* buffer, CAN_MSG_OBJ* message)
{
if(message->field.idType == CAN_FRAME_STD)
{
buffer[0]= (message->msgId & 0x000007FF) << 2;
buffer[1]= 0;
buffer[2]= message->field.dlc & 0x0F;
}
else
{
buffer[0]= ( ( (uint16_t)(message->msgId >> 16 ) & 0x1FFC ) ) | 0x3;
buffer[1]= (uint16_t)(message->msgId >> 6) & 0x0FFF;
buffer[2]= (message->field.dlc & 0x0F) + ( (uint16_t)(message->msgId << 10) & 0xFC00);
}
if(message->data != NULL)
{
buffer[3]= ((message->data[1])<<8) + message->data[0];
buffer[4]= ((message->data[3])<<8) + message->data[2];
buffer[5]= ((message->data[5])<<8) + message->data[4];
buffer[6]= ((message->data[7])<<8) + message->data[6];
}
}
/**
Section: CAN1 APIs
*/
void CAN1_Initialize(void)
{
// Disable interrupts before the Initialization
IEC2bits.C1IE = 0;
C1INTE = 0;
// set the CAN1_initialize module to the options selected in the User Interface
/* put the module in configuration mode */
C1CTRL1bits.REQOP = CAN_CONFIGURATION_MODE;
while(C1CTRL1bits.OPMODE != CAN_CONFIGURATION_MODE);
/* Set up the baud rate*/
C1CFG1 = 0x03; //BRP TQ = (2 x 4)/FCAN; SJW 1 x TQ;
C1CFG2 = 0x43BE; //WAKFIL enabled; SEG2PHTS Freely programmable; SEG2PH 4 x TQ; SEG1PH 8 x TQ; PRSEG 7 x TQ; SAM Once at the sample point;
C1FCTRL = 0xC001; //FSA Transmit/Receive Buffer TRB1; DMABS 32;
C1FEN1 = 0x01; //FLTEN8 disabled; FLTEN7 disabled; FLTEN9 disabled; FLTEN0 enabled; FLTEN2 disabled; FLTEN10 disabled; FLTEN1 disabled; FLTEN11 disabled; FLTEN4 disabled; FLTEN3 disabled; FLTEN6 disabled; FLTEN5 disabled; FLTEN12 disabled; FLTEN13 disabled; FLTEN14 disabled; FLTEN15 disabled;
C1CTRL1 = 0x00; //CANCKS FOSC/2; CSIDL disabled; ABAT disabled; REQOP Sets Normal Operation Mode; WIN Uses buffer window; CANCAP disabled;
/* Filter configuration */
/* enable window to access the filter configuration registers */
/* use filter window*/
C1CTRL1bits.WIN=1;
/* select acceptance masks for filters */
C1FMSKSEL1bits.F0MSK = 0x0; //Select Mask 0 for Filter 0
/* Configure the masks */
C1RXM0SIDbits.SID = 0x7ff;
C1RXM1SIDbits.SID = 0x0;
C1RXM2SIDbits.SID = 0x0;
C1RXM0SIDbits.EID = 0x0;
C1RXM1SIDbits.EID = 0x0;
C1RXM2SIDbits.EID = 0x0;
C1RXM0EID = 0x00;
C1RXM1EID = 0x00;
C1RXM2EID = 0x00;
C1RXM0SIDbits.MIDE = 0x0;
C1RXM1SIDbits.MIDE = 0x0;
C1RXM2SIDbits.MIDE = 0x0;
/* Configure the filters */
C1RXF0SIDbits.SID = 0x123;
C1RXF0SIDbits.EID = 0x0;
C1RXF0EID = 0x00;
C1RXF0SIDbits.EXIDE = 0x0;
/* FIFO Mode */
C1BUFPNT1bits.F0BP = 0xf; //Filter 0 uses FIFO
/* clear window bit to access CAN1 control registers */
C1CTRL1bits.WIN=0;
/*configure CAN1 Transmit/Receive buffer settings*/
C1TR01CONbits.TXEN0 = 0x1; // Buffer 0 is a Transmit Buffer
C1TR01CONbits.TXEN1 = 0x0; // Buffer 1 is a Receive Buffer
C1TR23CONbits.TXEN2 = 0x0; // Buffer 2 is a Receive Buffer
C1TR23CONbits.TXEN3 = 0x0; // Buffer 3 is a Receive Buffer
C1TR45CONbits.TXEN4 = 0x0; // Buffer 4 is a Receive Buffer
C1TR45CONbits.TXEN5 = 0x0; // Buffer 5 is a Receive Buffer
C1TR67CONbits.TXEN6 = 0x0; // Buffer 6 is a Receive Buffer
C1TR67CONbits.TXEN7 = 0x0; // Buffer 7 is a Receive Buffer
C1TR01CONbits.TX0PRI = 0x0; // Message Buffer 0 Priority Level
C1TR01CONbits.TX1PRI = 0x0; // Message Buffer 1 Priority Level
C1TR23CONbits.TX2PRI = 0x0; // Message Buffer 2 Priority Level
C1TR23CONbits.TX3PRI = 0x0; // Message Buffer 3 Priority Level
C1TR45CONbits.TX4PRI = 0x0; // Message Buffer 4 Priority Level
C1TR45CONbits.TX5PRI = 0x0; // Message Buffer 5 Priority Level
C1TR67CONbits.TX6PRI = 0x0; // Message Buffer 6 Priority Level
C1TR67CONbits.TX7PRI = 0x0; // Message Buffer 7 Priority Level
/* clear the buffer and overflow flags */
C1RXFUL1 = 0x0000;
C1RXFUL2 = 0x0000;
C1RXOVF1 = 0x0000;
C1RXOVF2 = 0x0000;
/* configure the device to interrupt on the receive buffer full flag */
/* clear the buffer full flags */
C1INTFbits.RBIF = 0;
/* put the module in normal mode */
C1CTRL1bits.REQOP = CAN_NORMAL_OPERATION_MODE;
while(C1CTRL1bits.OPMODE != CAN_NORMAL_OPERATION_MODE);
/* Initialize Interrupt Handler*/
CAN1_SetBusErrorHandler(&CAN1_DefaultBusErrorHandler);
CAN1_SetTxErrorPassiveHandler(&CAN1_DefaultTxErrorPassiveHandler);
CAN1_SetRxErrorPassiveHandler(&CAN1_DefaultRxErrorPassiveHandler);
CAN1_SetBusWakeUpActivityInterruptHandler(&CAN1_DefaultBusWakeUpActivityHandler);
CAN1_SetRxBufferInterruptHandler(&CAN1_DefaultReceiveBufferHandler);
CAN1_SetRxBufferOverFlowInterruptHandler(&CAN1_DefaultRxBufferOverFlowHandler);
/* Enable CAN1 Interrupt */
IEC2bits.C1IE = 1;
/* Enable Receive interrupt */
C1INTEbits.RBIE = 1;
/* Enable Error interrupt*/
C1INTEbits.ERRIE = 1;
/* Enable Receive buffer Overflow interrupt */
C1INTEbits.RBOVIE = 1;
}
void CAN1_TransmitEnable()
{
/* setup channel 0 for peripheral indirect addressing mode
normal operation, word operation and select as Tx to peripheral */
/* DMA_PeripheralIrqNumberSet and DMA_TransferCountSet would be done in the
DMA */
/* setup the address of the peripheral CAN1 (C1TXD) */
DMA_PeripheralAddressSet(CAN1_TX_DMA_CHANNEL, (uint16_t) &C1TXD);
/* DPSRAM start address offset value */
DMA_StartAddressASet(CAN1_TX_DMA_CHANNEL, (uint16_t) (&can1msgBuf));
/* enable the channel */
DMA_ChannelEnable(CAN1_TX_DMA_CHANNEL);
}
void CAN1_ReceiveEnable()
{
/* setup DMA channel for peripheral indirect addressing mode
normal operation, word operation and select as Rx to peripheral */
/* setup the address of the peripheral CAN1 (C1RXD) */
/* DMA_TransferCountSet and DMA_PeripheralIrqNumberSet would be set in
the DMA_Initialize function */
DMA_PeripheralAddressSet(CAN1_RX_DMA_CHANNEL, (uint16_t) &C1RXD);
/* DPSRAM start address offset value */
DMA_StartAddressASet(CAN1_RX_DMA_CHANNEL, (uint16_t) (&can1msgBuf) );
/* enable the channel */
DMA_ChannelEnable(CAN1_RX_DMA_CHANNEL);
}
CAN_OP_MODE_STATUS CAN1_OperationModeSet(const CAN_OP_MODES requestMode)
{
CAN_OP_MODE_STATUS status = CAN_OP_MODE_REQUEST_SUCCESS;
if((CAN_CONFIGURATION_MODE == CAN1_OperationModeGet()) || (requestMode == CAN_DISABLE_MODE)
|| (requestMode == CAN_CONFIGURATION_MODE))
{
C1CTRL1bits.REQOP = requestMode;
while(C1CTRL1bits.OPMODE != requestMode);
}
else
{
status = CAN_OP_MODE_REQUEST_FAIL;
}
return status;
}
CAN_OP_MODES CAN1_OperationModeGet(void)
{
return C1CTRL1bits.OPMODE;
}
CAN_TX_MSG_REQUEST_STATUS CAN1_Transmit(CAN_TX_PRIOIRTY priority, CAN_MSG_OBJ *sendCanMsg)
{
CAN_TX_MSG_REQUEST_STATUS txMsgStatus = CAN_TX_MSG_REQUEST_SUCCESS;
CAN1_TX_CONTROLS * pTxControls = (CAN1_TX_CONTROLS*)&C1TR01CON;
uint_fast8_t i;
bool messageSent = false;
// CAN 2.0 mode DLC supports upto 8 byte
if(sendCanMsg->field.dlc > CAN_DLC_8)
{
txMsgStatus |= CAN_TX_MSG_REQUEST_DLC_ERROR;
}
if(CAN1_TX_BUFFER_COUNT > 0)
{
for(i=0; i<CAN1_TX_BUFFER_COUNT; i++)
{
if(pTxControls->transmit_enabled == 1)
{
if (pTxControls->send_request == 0)
{
CAN1_MessageToBuffer(&can1msgBuf[i][0], sendCanMsg);
pTxControls->priority = priority;
/* set the message for transmission */
pTxControls->send_request = 1;
messageSent = true;
break;
}
}
pTxControls++;
}
}
if(messageSent == false)
{
txMsgStatus |= CAN_TX_MSG_REQUEST_BUFFER_FULL;
}
return txMsgStatus;
}
bool CAN1_Receive(CAN_MSG_OBJ *recCanMsg)
{
uint_fast8_t currentBuffer;
uint_fast8_t shiftAmount;
bool messageReceived = false;
uint16_t receptionFlags;
if(C1INTFbits.RBOVIF == 1)
{
C1INTFbits.RBOVIF = 0;
/* Receive buffer overflow occured, call the notification function */
if(CAN1_RxBufferOverFlowInterruptHandler)
{
CAN1_RxBufferOverFlowInterruptHandler();
}
return messageReceived;
}
if(recCanMsg->data == NULL)
{
return messageReceived;
}
currentBuffer = C1FIFObits.FNRB;
if( currentBuffer < 16)
{
receptionFlags = C1RXFUL1;
shiftAmount = currentBuffer;
}
else
{
receptionFlags = C1RXFUL2;
shiftAmount = currentBuffer - 16;
}
if (((receptionFlags >> shiftAmount ) & 0x1) == 0x1)
{
CAN1_DMACopy(currentBuffer, recCanMsg);
if( currentBuffer < 16)
{
C1RXFUL1 &= ~(1 << shiftAmount);
}
else
{
C1RXFUL2 &= ~(1 << shiftAmount);
}
messageReceived = true;
}
return (messageReceived);
}
bool CAN1_IsBusOff()
{
return C1INTFbits.TXBO;
}
bool CAN1_IsRXErrorPassive()
{
return (C1INTFbits.RXBP);
}
bool CAN1_IsRxErrorWarning(void)
{
return (C1INTFbits.RXWAR);
}
bool CAN1_IsRxErrorActive(void)
{
bool errorState = false;
if((0 < C1ECbits.RERRCNT) && (C1ECbits.RERRCNT < 128))
{
errorState = true;
}
return errorState;
}
bool CAN1_IsTXErrorPassive()
{
return (C1INTFbits.TXBP);
}
bool CAN1_IsTxErrorWarning(void)
{
return (C1INTFbits.TXWAR);
}
bool CAN1_IsTxErrorActive(void)
{
bool errorState = false;
if((0 < C1ECbits.TERRCNT) && (C1ECbits.TERRCNT < 128))
{
errorState = true;
}
return errorState;
}
uint8_t CAN1_ReceivedMessageCountGet()
{
uint_fast8_t messageCount;
uint_fast8_t currentBuffer;
uint16_t receptionFlags;
messageCount = 0;
#if (CAN1_FIFO_STARTING_BUFFER<16)
/* Check any message in buffer 0 to buffer 15*/
receptionFlags = C1RXFUL1;
if (receptionFlags != 0)
{
/* check whether a message is received */
for (currentBuffer=0 ; currentBuffer < 16; currentBuffer++)
{
if (((receptionFlags >> currentBuffer ) & 0x1) == 0x1)
{
messageCount++;
}
}
}
#endif
/* Check any message in buffer 16 to buffer 32*/
receptionFlags = C1RXFUL2;
if (receptionFlags != 0)
{
/* check whether a message is received */
for (currentBuffer=0 ; currentBuffer < 16; currentBuffer++)
{
if (((receptionFlags >> currentBuffer ) & 0x1) == 0x1)
{
messageCount++;
}
}
}
return (messageCount);
}
void CAN1_Sleep(void)
{
C1INTFbits.WAKIF = 0;
C1INTEbits.WAKIE = 1;
/* put the module in disable mode */
C1CTRL1bits.REQOP = CAN_DISABLE_MODE;
while(C1CTRL1bits.OPMODE != CAN_DISABLE_MODE);
//Wake up from sleep should set the CAN1 module straight into Normal mode
}
void __attribute__((weak)) CAN1_DefaultBusErrorHandler(void)
{
CAN1_CallbackBusOff();
}
void CAN1_SetBusErrorHandler(void *handler)
{
CAN1_BusErrorHandler = handler;
}
void __attribute__((weak)) CAN1_DefaultTxErrorPassiveHandler(void)
{
CAN1_CallbackTxErrorPassive();
}
void CAN1_SetTxErrorPassiveHandler(void *handler)
{
CAN1_TxErrorPassiveHandler = handler;
}
void __attribute__((weak)) CAN1_DefaultRxErrorPassiveHandler(void)
{
CAN1_CallbackRxErrorPassive();
}
void CAN1_SetRxErrorPassiveHandler(void *handler)
{
CAN1_RxErrorPassiveHandler = handler;
}
void __attribute__((weak)) CAN1_DefaultBusWakeUpActivityHandler(void)
{
}
void CAN1_SetBusWakeUpActivityInterruptHandler(void *handler)
{
CAN1_BusWakeUpActivityInterruptHandler = handler;
}
void __attribute__((weak)) CAN1_DefaultReceiveBufferHandler(void)
{
CAN1_CallbackMessageReceived();
}
void CAN1_SetRxBufferInterruptHandler(void *handler)
{
CAN1_RxBufferInterruptHandler = handler;
}
void __attribute__((weak)) CAN1_DefaultRxBufferOverFlowHandler(void)
{
CAN1_CallbackRxBufferOverflow();
}
void CAN1_SetRxBufferOverFlowInterruptHandler(void *handler)
{
CAN1_RxBufferOverFlowInterruptHandler = handler;
}
void __attribute__((__interrupt__, no_auto_psv)) _C1Interrupt(void)
{
if (C1INTFbits.ERRIF)
{
if (C1INTFbits.TXBO == 1)
{
if(CAN1_BusErrorHandler)
{
CAN1_BusErrorHandler();
}
}
if (C1INTFbits.TXBP == 1)
{
if(CAN1_TxErrorPassiveHandler)
{
CAN1_TxErrorPassiveHandler();
}
}
if (C1INTFbits.RXBP == 1)
{
if(CAN1_RxErrorPassiveHandler)
{
CAN1_RxErrorPassiveHandler();
}
}
/* Call error notification function */
C1INTFbits.ERRIF = 0;
}
if(C1INTFbits.RBIF)
{
if(CAN1_RxBufferInterruptHandler)
{
CAN1_RxBufferInterruptHandler();
}
C1INTFbits.RBIF = 0;
}
if(C1INTFbits.WAKIF)
{
if(CAN1_BusWakeUpActivityInterruptHandler)
{
CAN1_BusWakeUpActivityInterruptHandler();
}
C1INTFbits.WAKIF = 0;
}
IFS2bits.C1IF = 0;
}
/*******************************************************************************
!!! Deprecated Definitions and APIs !!!
!!! These functions will not be supported in future releases !!!
*******************************************************************************/
/******************************************************************************
*
* Function: CAN1_transmit
* Description: Transmits the message from user buffer to CAN1 buffer
* as per the buffer number allocated.
* Allocation of the buffer number is done by user
*
* Arguments: priority : priority of the message to be transmitted
* sendCanMsg: pointer to the message object
*
* Return Value: true - Transmit successful
* false - Transmit failure
******************************************************************************/
bool CAN1_transmit(CAN_TX_PRIOIRTY priority, uCAN_MSG *sendCanMsg)
{
uint8_t msgObjData[8] = {0};
CAN_MSG_OBJ txCanMsg;
txCanMsg.data = msgObjData;
txCanMsg.msgId = sendCanMsg->frame.id;
txCanMsg.field.idType = sendCanMsg->frame.idType;
txCanMsg.field.frameType = sendCanMsg->frame.msgtype;
txCanMsg.field.dlc = sendCanMsg->frame.dlc;
txCanMsg.data[0] = sendCanMsg->frame.data0;
txCanMsg.data[1] = sendCanMsg->frame.data1;
txCanMsg.data[2] = sendCanMsg->frame.data2;
txCanMsg.data[3] = sendCanMsg->frame.data3;
txCanMsg.data[4] = sendCanMsg->frame.data4;
txCanMsg.data[5] = sendCanMsg->frame.data5;
txCanMsg.data[6] = sendCanMsg->frame.data6;
txCanMsg.data[7] = sendCanMsg->frame.data7;
return (CAN1_Transmit(priority, &txCanMsg));
}
/******************************************************************************
*
* Function: CAN1_receive
* Description: Receives the message from CAN1 buffer to user buffer
*
* Arguments: recCanMsg: pointer to the message object
*
* Return Value: true - Receive successful
* false - Receive failure
******************************************************************************/
bool CAN1_receive(uCAN_MSG *recCanMsg)
{
bool messageReceived = false;
uint8_t msgObjData[8] = {0};
CAN_MSG_OBJ rxCanMsg;
rxCanMsg.data = msgObjData;
if(true == CAN1_Receive(&rxCanMsg))
{
recCanMsg->frame.id = rxCanMsg.msgId;
recCanMsg->frame.idType = rxCanMsg.field.idType;
if(rxCanMsg.field.frameType == CAN_FRAME_RTR)
{
recCanMsg->frame.msgtype = CAN_MSG_RTR;
}
else
{
recCanMsg->frame.msgtype = CAN_MSG_DATA;
}
recCanMsg->frame.data0 = rxCanMsg.data[0];
recCanMsg->frame.data1 = rxCanMsg.data[1];
recCanMsg->frame.data2 = rxCanMsg.data[2];
recCanMsg->frame.data3 = rxCanMsg.data[3];
recCanMsg->frame.data4 = rxCanMsg.data[4];
recCanMsg->frame.data5 = rxCanMsg.data[5];
recCanMsg->frame.data6 = rxCanMsg.data[6];
recCanMsg->frame.data7 = rxCanMsg.data[7];
recCanMsg->frame.dlc = rxCanMsg.field.dlc;
messageReceived = true;
}
return (messageReceived);
}
/******************************************************************************
*
* Function: CAN1_isBusOff
* Description: Checks whether the transmitter in Bus off state
*
* Return Value: true - Transmitter in Bus Off state
* false - Transmitter not in Bus Off state
******************************************************************************/
bool CAN1_isBusOff()
{
return C1INTFbits.TXBO;
}
/******************************************************************************
*
* Function: CAN1_isRXErrorPassive
* Description: Checks whether the receive in error passive state
*
* Return Value: true - Receiver in Error Passive state
* false - Receiver not in Error Passive state
******************************************************************************/
bool CAN1_isRXErrorPassive()
{
return C1INTFbits.RXBP;
}
/******************************************************************************
*
* Function: CAN1_isTXErrorPassive
* Description: Checks whether the transmitter in error passive state
*
* Return Value: true - Transmitter in Error Passive state
* false - Transmitter not in Error Passive state
******************************************************************************/
bool CAN1_isTXErrorPassive()
{
return (C1INTFbits.TXBP);
}
/******************************************************************************
*
* Function: CAN1_messagesInBuffer
* Description: returns the number of messages that are received
*
* Return Value: Number of message received
******************************************************************************/
uint8_t CAN1_messagesInBuffer()
{
uint_fast8_t messageCount;
uint_fast8_t currentBuffer;
uint16_t receptionFlags;
messageCount = 0;
#if (CAN1_FIFO_STARTING_BUFFER<16)
/* Check any message in buffer 0 to buffer 15*/
receptionFlags = C1RXFUL1;
if (receptionFlags != 0)
{
/* check whether a message is received */
for (currentBuffer=0 ; currentBuffer < 16; currentBuffer++)
{
if (((receptionFlags >> currentBuffer ) & 0x1) == 0x1)
{
messageCount++;
}
}
}
#endif
/* Check any message in buffer 16 to buffer 32*/
receptionFlags = C1RXFUL2;
if (receptionFlags != 0)
{
/* check whether a message is received */
for (currentBuffer=0 ; currentBuffer < 16; currentBuffer++)
{
if (((receptionFlags >> currentBuffer ) & 0x1) == 0x1)
{
messageCount++;
}
}
}
return (messageCount);
}
/******************************************************************************
*
* Function: CAN1_sleep
* Description: Puts CAN1 module in disable mode.
*
******************************************************************************/
void CAN1_sleep(void)
{
C1INTFbits.WAKIF = 0;
C1INTEbits.WAKIE = 1;
/* put the module in disable mode */
C1CTRL1bits.REQOP = CAN_DISABLE_MODE;
while(C1CTRL1bits.OPMODE != CAN_DISABLE_MODE);
//Wake up from sleep should set the CAN1 module straight into Normal mode
}
/* Null weak implementations of callback functions. */
void __attribute__((weak)) CAN1_CallbackBusOff(void)
{
}
void __attribute__((weak)) CAN1_CallbackTxErrorPassive(void)
{
}
void __attribute__((weak)) CAN1_CallbackRxErrorPassive(void)
{
}
void __attribute__((weak)) CAN1_CallbackMessageReceived(void)
{
}
void __attribute__((weak)) CAN1_CallbackRxBufferOverflow()
{
}
/**
End of File
*/

EFM32 Gecko Starter Kit USART1 Receive not working (EFM32G890F128)

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

Canbus transmit, but not receiving

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;.

STM32 USB OTG HOST Library hangs trying to create file with FatFs

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.

UART/DMA interrupt not being triggered on dsPIC33

I have a dsPIC33 with an explorer board 16. The entire code base is fairly lengthy but the problem is isolated to the DMA interrupt. It is not being triggered even though I have pretty much copied the Microchip UARTloopback example. I have read the Microchip manual section for both the UART and DMA thoroughly and the loopback example does work, however when it is implemented with my code it does not. I have checked my entire project to make sure that the DMA channels are not being overwritten or used anywhere else in the project. The same applies to the UART section. I will be including the entire file c file and h file. Functions to focus on are the uart_commInit, BEACON_uart_commPuts, and _DMA3Interrupt. The BEACON_uart_commPuts works and prints to the terminal. Everything compiles
uart.c
/**
* This source file contains functions for using the UARTs.
*
* #todo Write uart_monitor() or ISR to check for UART parity, framing error and DMA collisions
*
* #ingroup CSuart
* #defgroup CSuart UART
* #{
* High level functions for UART with DMA. Function names
* beginning with uart_comm... are for communicating with the transceiver. The
* UART peripheral used for the transceiver can be changed by editing the macros
* in CSuart.h.
*/
/* System & Local Includes */
#include <p33Fxxxx.h>
#include <string.h>
#include "CSdefine.h"
#include "types.h"
#include "CSuart.h"
/* Type and Constant Definitions*/
// Handshake control signals for Devboard USB
#define HS0 BIT4 // RC4
#define HS1 BIT3 // RC3
#define HS2 BIT2 // RC2
#define HS3 BIT5 // RD5
#define HS4 BIT2 // RD2
#define HS5 BIT1 // RD1
// Motherboard control signals
#define CS_SD_BAR BIT5 // RE5
#define OE_USB_BAR BIT1 // RC1
#define OE_MHX_BAR BIT2 // RE2
#define ON_SD_BAR BIT4 // RE4
#define ON_MHX_BAR BIT3 // RE3
/* Global & Local Variables */
// DMA TX and RX buffers for comm UART
static uint16 txBuff[RADIO_TX_BUFFER_SIZE] __attribute__((space(dma)));
static uint16 rxBuff[RADIO_RX_BUFFER_SIZE] __attribute__((space(dma)));
static uint16 tx0Buff[BEACON_TX_BUFFER_SIZE] __attribute__((space(dma)));
static uint16 rx0Buff[BEACON_TX_BUFFER_SIZE] __attribute__((space(dma)));
static uint16 *lastRead = (uint16 *) &rxBuff; // Points to next transfer to be read from DMA rxBuff
static uint16 *lastRead0 = (uint16 *) &rx0Buff; // Points to next transfer to be read from DMA rxBuff
/* Functions */
/******************************************************************************
**** ****
** **
csk_usb_open() Enable USB on the Dev/Flight hardware
** **
**** ****
******************************************************************************/
void csk_usb_open(void) {
// Disable all control signals to avoid spurious
// writes when -OE_USB goes active (LOW).
PORTD |= (HS5+HS4+HS3 );
TRISD &= ~(HS5+HS4+HS3 );
//
// // Configure -OE_USB as an output, and make
// // it active (i.e., LOW)
PORTC &= ~OE_USB_BAR;
TRISC &= ~OE_USB_BAR;
} /* csk_usb_open() */
/******************************************************************************
**** ****
** **
csk_usb_close() // Disable USB on the Dev/flight hardware
** **
**** ****
******************************************************************************/
void csk_usb_close(void) {
// Restore -OE_USB to an input.
PORTC |= OE_USB_BAR;
TRISC |= OE_USB_BAR;
} /* csk_usb_close() */
/**
* Initializes the UART port with DMA for use for satellite comm (ie. the transceiver).
* This should be called sometime during startup.
*/
void uart_commInit(){
// Configure UART for 9600 8N1 with interrupts to the DMA module
RADIO_UMODEbits.UEN = 0b10; //UxTX, UxRX, UxCTS and UxRTS pins are enabled and used
RADIO_UMODEbits.PDSEL = 0b00; //8-bit data, no parity
RADIO_UBRG = ((Fcyc/38400)/16)-1; //9600 baud //38400 //((Fcyc/38400)/16)-1
//COMM_UBRG = 259; // 9600 baud # 80MHz
RADIO_USTAbits.UTXISEL0 = 0; // Interrupt when there is room in TX FIFO
RADIO_USTAbits.URXISEL = 0; // Interrupt when a character is received
// Configure DMA channel 1 as Comm Uart transmit
DMA1CONbits.DIR = 1; // DMA reads from SRAM, writes to peripheral
DMA1CONbits.AMODE = 00; // Addr. mode is register indirect w/ post increment
DMA1CONbits.MODE = 0b01;// One-shot, no ping-pong mode.
DMA1CONbits.SIZE = 1; // Transfer 1 byte at a time
DMA1REQbits.IRQSEL = 0b0001100; // DMA1 writes to UART1 TX (the Comm uart port.)
DMA1PAD = (volatile unsigned int) &RADIO_UTXREG; //Tell DMA module address of COMM TX register
DMA1STA = __builtin_dmaoffset(txBuff); // Tell DMA module start address of our dma tx buffer
IFS0bits.DMA1IF = 0; // Clear DMA interrupt flag
//IEC0bits.DMA1IE = 1; // Enable DMA interrupt
//Configure DMA channel 0 as Comm Uart receive
DMA0CONbits.MODE = 0b00; // Continuous no Ping-Pong mode
DMA0CNT = RADIO_RX_BUFFER_SIZE - 1;
DMA0REQbits.IRQSEL = 0b0001011; // DMA0 reads from UART1 RX (the Comm uart port.)
DMA0PAD = (volatile unsigned int) &RADIO_URXREG;
DMA0STA = __builtin_dmaoffset(rxBuff); // Tell DMA start addr. of buffer A
//DMA0STB = __builtin_dmaoffset(rxBuffB); // Tell DMA start addr. of buffer B
IFS0bits.DMA0IF = 0; // Clear DMA interrupt flag
//IEC0bits.DMA0IE = 1; // Enable DMA interrupt
DMA0CONbits.CHEN = 1; // Enable RX DMA channel only. TX channel is one-shot mode.
// UART config for CLI
BEACON_UMODEbits.STSEL = 0; //1-stop bit
BEACON_UMODEbits.PDSEL = 0; //No Parity, 8-data bits
BEACON_UMODEbits.ABAUD = 0; // Autobaud Disabled
BEACON_UBRG = ((Fcyc/9600)/16)-1; // 9600 baud # 80Mhz
BEACON_USTAbits.UTXISEL0 = 0; // interrupt after 1 Tx char is transmited
//BEACON_USTAbits.UTXISEL1 = 0;
BEACON_USTAbits.URXISEL = 0; // interrrupt after 1 Rx char is received
BEACON_UMODEbits.UARTEN = 1; // Enable UART
BEACON_USTAbits.UTXEN = 1; // Enable Uart Tx
IEC4bits.U2EIE = 0; // Enable error interrupt
//Tx config for CLI
DMA4REQ = 0x001F; // Uart2 transmiter
DMA4PAD = (volatile unsigned int) &BEACON_UTXREG;// Tell DMA module address of COMM TX register
DMA4CONbits.AMODE = 0; // Addr. mode is register indirect x/ post increment
DMA4CONbits.MODE = 1; // One-Shot
DMA4CONbits.DIR = 1; // reads from RAM writes to peripheral
DMA4CONbits.SIZE = 1;// Transfers 1 byte at a time
// count needs to be pushed into interrupt and counted there, will avoid weird shit
DMA4CNT = 7; // 11 DMA requests
DMA4STA = __builtin_dmaoffset(tx0Buff); // Tell DMA module start address of our dma tx buffer
IFS2bits.DMA4IF = 0; // Clear DMA interrupt flag
IEC2bits.DMA4IE = 1; // Enable DMA interrupt
// Rx config for CLI
DMA3REQ = 0x001E; // Uart2 Receive
DMA3PAD = (volatile unsigned int) &BEACON_URXREG; // Tell DMA module address of COMM RX register
DMA3CONbits.AMODE = 0; // Addr. mode is register indirect x/ post increment
DMA3CONbits.MODE = 2; // Ping-Pong
DMA3CONbits.DIR = 0; // reads from peripheral writes to RAM
DMA3CONbits.SIZE = 0; // Transfers 1 word at a time
DMA3CNT = 7; // 11 DMA requests
DMA3STA = __builtin_dmaoffset(tx0Buff); // Tell DMA start addr. of receive buffer
DMA3STB = __builtin_dmaoffset(rx0Buff); // Tell DMA start addr. of receive buffer
DMA3CONbits.CHEN = 1; // Enable RX DMA channel only. TX channel is one-shot mode.
IFS2bits.DMA3IF = 0; // Clear DMA interrupt
IEC2bits.DMA3IE = 1; // Enable DMA interrupt
// END of added code
// these bits must be at end of file
RADIO_UMODEbits.UARTEN = 1; //enable uart
RADIO_USTAbits.UTXEN = 1; //transmit enabled
}
/**
* Writes a string to the comm Port. The length must be less than COMM_TX_BUFFER_SIZE
* or this function will have no effect.
* #param str The string to write.
* #param len The number of bytes to write
* #pre uart_commInit() must be called before calling this function.
* #note This function call is blocking. It waits until the last transfer is
* finished to begin current transmission. Once current transmission has been
* started then it will return because the DMA module handles transmission of data.
*/
void BEACON_uart_commPuts(char *str, uint16 len){
#if DEBUG_OUTPUT
uint16 *targetAddr;
if(len == 0 || len > BEACON_TX_BUFFER_SIZE)
return; //TODO Handle error
while(!BEACON_commIsTXReady()); // Blocking!
targetAddr = (uint16 *) (DMA4STA + ((unsigned int) &_DMA_BASE)); // Address of DMA buffer
memcpy((void *) targetAddr, (const void *) str, len); // Copy data into DMA buffer
DMA4CNT = len-1; // Send len # of characters
DMA4CONbits.CHEN = 1; // Turn on the DMA channel
DMA4REQbits.FORCE = 1; // Start DMA transfer to comm UART
#endif
}
/**
* Retrieves a string from the Comm. Port. The caller must ensure that the 'str'
* parameter can handle the number of bytes being requested in parameter 'len'.
* #param str The string to store the received characters in.
* #param len The maximum number of characters to return. The number of chars
* copied to str will be less than or equal to len.
* #return int16 The number of bytes copied to str if non-negative or an error
* code if negative.
* #pre uart_commInit() must be called before calling this function.
* #todo Add overrun detection
* #todo Implement error codes if necessary.
*/
int16 RADIO_uart_commGets(char *str, uint16 len){
/* The DMA transfers 2 bytes of data into the DMA buffer for every byte it
* receives from the UART (see dsPIC33 reference manual DMA chapter). The
* lower byte is the data received by the UART and the upper byte has 2
* status bits. There is one DMA receive buffer (no Ping-Pong mode) which the
* DMA starts to fill 2 bytes at a time until the buffer is full then goes
* back to the beginning and starts to put new characters in the beginning
* of the buffer again. This code reads up to 'len' bytes (not transfers!) from the buffer
* starting from the last location readmup to the last byte available in
* the DMA buffer. If the DMA rolled over to the beginning since the last read,
* this function reads until the end of the buffer, then from the beginning.
* This should be called often enough to prevent overruns.
*
* NOTE: For every 2 bytes this function reads from the DMA buffer it only
* returns one because the upper byte of each transfer are status bits.
*/
uint16 numTransfers, i; // # of DMA transfers (not bytes!) to return to caller.
uint16 *lastArrived = (uint16 *)(DMA0STA + ((unsigned int) &_DMA_BASE)); // Points after most recent transfer received in DMA buffer
//static uint16 *lastRead = (uint16 *) &rxBuff; // Points to next transfer to be read
if(lastArrived < lastRead){ // Rollover occured
// (1) # of transfers till end of buffer.
// (2) # of transfers in the beginning of buffer.
numTransfers = (uint16) ((rxBuff + RADIO_RX_BUFFER_SIZE - 1) - lastRead);
numTransfers += (uint16) (lastArrived - rxBuff);
}else{
numTransfers = (uint16) (lastArrived - lastRead);
}
if(len < numTransfers) // Don't give caller more bytes than they can handle
numTransfers = len;
for(i = 0; i < numTransfers; i++){ // Now copy chars into caller's buffer
/*if(i == 0){
uart_commGetc();
continue;
}*/
if(lastRead >= rxBuff + RADIO_RX_BUFFER_SIZE){ // Handle rollover
lastRead = rxBuff; // Start reading from beginning now
}
// Mask off status byte and only copy the lower char to callers buffer
*str = (char) (*lastRead & 0xFF);
str++; // Increment index into caller's buffer
lastRead++; // Increment read index
}
return i; // # of bytes returned in parameter 1.
}
int16 BEACON_uart_commGets(char *str, uint16 len){
/* The DMA transfers 2 bytes of data into the DMA buffer for every byte it
* receives from the UART (see dsPIC33 reference manual DMA chapter). The
* lower byte is the data received by the UART and the upper byte has 2
* status bits. There is one DMA receive buffer (no Ping-Pong mode) which the
* DMA starts to fill 2 bytes at a time until the buffer is full then goes
* back to the beginning and starts to put new characters in the beginning
* of the buffer again. This code reads up to 'len' bytes (not transfers!) from the buffer
* starting from the last location readmup to the last byte available in
* the DMA buffer. If the DMA rolled over to the beginning since the last read,
* this function reads until the end of the buffer, then from the beginning.
* This should be called often enough to prevent overruns.
*
* NOTE: For every 2 bytes this function reads from the DMA buffer it only
* returns one because the upper byte of each transfer are status bits.
*/
uint16 numTransfers, i; // # of DMA transfers (not bytes!) to return to caller.
uint16 *lastArrived = (uint16 *)(DMA3STA + ((unsigned int) &_DMA_BASE)); // Points after most recent transfer received in DMA buffer
//static uint16 *lastRead = (uint16 *) &rxBuff; // Points to next transfer to be read
if(lastArrived < lastRead){ // Rollover occured
// (1) # of transfers till end of buffer.
// (2) # of transfers in the beginning of buffer.
numTransfers = (uint16) ((rx0Buff + BEACON_RX_BUFFER_SIZE - 1) - lastRead);
numTransfers += (uint16) (lastArrived - rx0Buff);
}else{
numTransfers = (uint16) (lastArrived - lastRead);
}
if(len < numTransfers) // Don't give caller more bytes than they can handle
numTransfers = len;
for(i = 0; i < numTransfers; i++){ // Now copy chars into caller's buffer
/*if(i == 0){
uart_commGetc();
continue;
}*/
if(lastRead >= rx0Buff + BEACON_RX_BUFFER_SIZE){ // Handle rollover
lastRead = rx0Buff; // Start reading from beginning now
}
// Mask off status byte and only copy the lower char to callers buffer
*str = (char) (*lastRead & 0xFF);
str++; // Increment index into caller's buffer
lastRead++; // Increment read index
}
return i; // # of bytes returned in parameter 1.
}
/**
* Retrieves a single character from the comm receive buffer.
* #return (int16) returns a signed integer. If the value is less than zero there
* were no characters in the UART receive buffer to return. Otherwise, the return
* value should be cast to a char and used accordingly.
* #pre uart_commInit() must be called before calling this function.
*/
int16 RADIO_uart_commGetc(){
int16 retValue;
if(RADIO_uart_commNumRXBytes() > 0){
if(lastRead >= rxBuff + RADIO_RX_BUFFER_SIZE){ // Handle rollover
lastRead = rxBuff; // Start reading from beginning now
}
retValue = (int16) *lastRead;
lastRead++;
return retValue;
}
return -1;
}
/**
* Retrieves a single character from the comm receive buffer.
* #return (int16) returns a signed integer. If the value is less than zero there
* were no characters in the UART receive buffer to return. Otherwise, the return
* value should be cast to a char and used accordingly.
* #pre uart_commInit() must be called before calling this function.
*/
int16 BEACON_uart_commGetc(){
int16 retValue;
if(BEACON_uart_commNumRXBytes() > 0){
if(lastRead >= rx0Buff + BEACON_RX_BUFFER_SIZE){ // Handle rollover
lastRead = rx0Buff; // Start reading from beginning now
}
retValue = (int16) *lastRead;
lastRead++;
return retValue;
}
return -1;
}
/**
* Looks for and retrieves a string from the comm port up to and including the
* specified terminating character. If the terminating character does not exist
* in the uart buffer no characters are copied to str and -1 is returned.
* #param str A buffer to stored the received data in
* #param len Maximum number of characters to retrieve
* #param terminator the terminating character
* #return The number of characters copied to str, -1 if no terminator not found or buffer to small for command
*/
int16 uart_commGetToChar(char *str, uint16 len, char terminator){
BOOL foundChar = FALSE;
int16 i, strLen = 0; // strLen is the value we will return
uint16 *tempPtr = lastRead; // Points after the last read DMA transfer (transfer = 2 bytes)
uint16 *lastArrived = (uint16 *)(DMA0STA + ((unsigned int) &_DMA_BASE)); // Points after most recent transfer received in DMA buffer
len = (len < (i = RADIO_uart_commNumRXBytes())) ? len : i; // If numCharsReceived > len then len = numCharsReceived
// Look for null terminating character
while(!foundChar){ // Loop until char is found or 'till end of received chars
if(strLen >= len){
return -1; // Provided buffer not long enough or terminating char not found.
}
if((char) (*tempPtr & 0xFF) == terminator){ // Found terminating char?
foundChar = TRUE;
strLen++; // To count terminating character
}else{
strLen++; // Increment # of transfers we're planning to copy to user's buffer
tempPtr++; // Increment pointer to the receive buffer
if(tempPtr >= rxBuff + RADIO_RX_BUFFER_SIZE){ // Handle rollover in rxBuff
tempPtr = rxBuff; // Start reading from beginning now
}
}
}
for(i = 0; i < strLen; i++){ // Now copy chars into caller's buffer
if(lastRead >= rxBuff + RADIO_RX_BUFFER_SIZE){ // Handle rollover in rxBuff
lastRead = rxBuff; // Start reading from beginning now
}
// Mask off status byte and only copy the lower char to caller's buffer
*str = (char) (*lastRead & 0xFF);
str++; // Increment index into caller's buffer
lastRead++; // Increment read index
}
return strLen; // # of bytes INCLUDING terminating character
}
/**
* Returns the number of unread characters in the comm UART buffer.
* #return (int16) number of unread chars in comm UART buffer
* #pre uart_commInit() must be called before calling this function.
*/
int16 RADIO_uart_commNumRXBytes(){
int16 retValue;
uint16 *lastReceivedChar = (uint16 *)(DMA0STA + ((unsigned int) &_DMA_BASE));
if(lastReceivedChar >= lastRead){
return (int16) (lastReceivedChar - lastRead);
}else{
retValue = (int16) ((uint16 *)(&rxBuff + RADIO_TX_BUFFER_SIZE) - lastRead);
retValue += (uint16) (lastReceivedChar - (uint16 *)&rxBuff);
return retValue;
}
}
int16 BEACON_uart_commNumRXBytes(){
int16 retValue;
uint16 *lastReceivedChar = (uint16 *)(DMA2STA + ((unsigned int) &_DMA_BASE));
if(lastReceivedChar >= lastRead){
return (int16) (lastReceivedChar - lastRead);
}else{
retValue = (int16) ((uint16 *)(&rx0Buff + BEACON_TX_BUFFER_SIZE) - lastRead);
retValue += (uint16) (lastReceivedChar - (uint16 *)&rx0Buff);
return retValue;
}
}
/* Interrupt Handlers */
//void __attribute__((__interrupt__,no_auto_psv)) _U2EInterrupt(void){
// TODO Handle Uart Error
//}
/**
* Comm receive DMA interrupt service routine. Currently not used.
*/
void __attribute__((__interrupt__,no_auto_psv)) _DMA0Interrupt(void){
IFS0bits.DMA0IF = 0; // Clear DMA interrupt flag
}
/**
* Comm transmit DMA interrupt service routine. Currently not used.
*/
void __attribute__((__interrupt__,no_auto_psv)) _DMA1Interrupt(void){
IFS0bits.DMA1IF = 0; // Clear DMA interrupt flag
}
/**
* Comm receive DMA interrupt service routine.
*/
void __attribute__((__interrupt__,no_auto_psv)) _DMA3Interrupt(void){
static unsigned int BufferCount = 0;
if(BufferCount == 0){
DMA4STA = __builtin_dmaoffset(tx0Buff);
}
else{
DMA4STA = __builtin_dmaoffset(rx0Buff);
}
DMA4CONbits.CHEN = 1; // Re-enable DMA3 channel
DMA4REQbits.FORCE = 1; // manual start the transfers, if we doing predetermined transfer size
BufferCount ^= 1;
IFS2bits.DMA3IF = 0; // Clear DMA3 Interrupt flag
}
/**
* Comm transmit DMA interrupt service routine. Currently not used.
*/
void __attribute__((__interrupt__,no_auto_psv)) _DMA4Interrupt(void){
IFS2bits.DMA4IF = 0; // Clear DMA interrupt flag
}
/**
* #}
*/
uart.h
/**
* This header file provides function prototypes and macros for UART ports.
*
* #ingroup CSuart
*/
/**
* #ingroup CSuart
* #{
*/
#ifndef CSUART_H
#define CSUART_H
/* Include Files */
#include <p33Fxxxx.h>
/**
* Register definitions for Comm port uart
* Change these values to use the other uart port.
* WARNING: Must also change values in uart_commInit(). (DMA1REQbits.IRQSEL)
* #cond
*/
/*NOTE:(8/20/14, 3:53pm) these macros have been changed, U2 -> U1 */
#define RADIO_UMODE U1MODE
#define RADIO_UMODEbits U1MODEbits
#define RADIO_USTA U1STA
#define RADIO_USTAbits U1STAbits
#define RADIO_URXREG U1RXREG
#define RADIO_UTXREG U1TXREG
#define RADIO_UBRG U1BRG
#define RADIO_URXIF IFS0bits.U1RXIF // Comm uart receive interrupt flag
#define RADIO_UTXIF IFS0bits.U1TXIF // Comm uart transmite interrupt flag
#define RADIO_RXIntEnable() {IEC0bits.U1RXIE = 1;}
#define RADIO_TXIntEnable() {IEC0bits.U1TXIE = 1;}
#define RADIO_ErrorIntEnable() {IEC4bits.U1EIE = 1;}
#define RADIO_RXIntDisable() {IEC0bits.U1RXIE = 0;}
#define RADIO_TXIntDisable() {IEC0bits.U1TXIE = 0;}
#define RADIO_ErrorIntDisable() {IEC4bits.U1EIE = 0;}
#define BEACON_UMODEbits U2MODEbits
#define BEACON_USTAbits U2STAbits
#define BEACON_URXREG U2RXREG
#define BEACON_UTXREG U2TXREG
#define BEACON_UBRG U2BRG
#define BEACON_IFSbits IFS2bits
#define RADIO_TX_BUFFER_SIZE 283 /// Size of comm port's DMA transmit buffer in bytes
#define RADIO_RX_BUFFER_SIZE 128 /// Size of comm port's DMA receive buffer in bytes
#define BEACON_TX_BUFFER_SIZE 128 /// Size of comm port's DMA transmit buffer in bytes
#define BEACON_RX_BUFFER_SIZE 128 /// Size of comm port's DMA receive buffer in bytes
/**
* Returns 1 when the comm port UART is ready to transmit, and 0 otherwise.
*/
#define RADIO_commIsTXReady() (RADIO_USTAbits.TRMT)
#define BEACON_commIsTXReady() (BEACON_USTAbits.TRMT)
/* Function Prototypes */
void uart_commInit();
void BEACON_uart_commPuts(char *str, uint16 len);
void uart0_commPuts(char *str, uint16 len);
int16 RADIO_uart_commGets(char *str, uint16 len);
//int16 uart0_commGets(char *str, uint16 len);
int16 RADIO_uart_commGetc();
//int16 uart0_commGetc();
int16 uart_commGetToChar(char *str, uint16 len, char terminator);
//int16 uart0_commGetToChar(char *str, uint16 len, char terminator);
int16 RADIO_uart_commNumRXBytes();
//int16 uart0_commNumRXBytes();
/**
* #}
*/
#endif /* CSUART_H */

Resources