Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] Microchip AN1249 CAN bus on dsPIC33F: CAN ISR does not get activated

Status
Not open for further replies.

Drugo

Junior Member level 2
Joined
Feb 23, 2011
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,537
Hello community, I'm having an issue implementing View attachment AN1249_dsPIC33F.zipin order to implement CAN bus with DMA and ECAN on dsPIC33F. It's driving me crazy! :bang::bang::bang: I have to deliver my CAN bus driver in 3 days and am really in trouble. :fight: The issue is related to the ISR routine, that never gets activated. Or better, the TX interrupt never gets activated (C1INTFbits.TBIF is always zero). I do not have a CAN simulator to transmit a message in order to debug the RX ISR portion of the code.

I'm using dsPIC33FJ256GP710A (as a transmitter) and dsPIC33FJ128GP706A (as a receiver) devices. These are the devices I'm going to use in my final application. Just for simplicity, I use one device just to transmit and the other one just to receive.

The code I am working on (here attached) is the same of AN1249, except that I used a CAN bit rate of 100 kbps (the final system will work at this speed and won't use terminator resistors) and deleted all parts related to the LCD (I don't have one in my system). Having used a bit rate of 100 kbps, instead of the AN1249 default one (1Mbit), in my opinion all the configuration parameters of the ECAN controller remain the same (like SJW, SEG1PH, SEG2PHTS, SEG2PH, PRSEG, SAM, etc.).

Buffer 1, in the initECAN( ), is initialized as standard CAN to receive message ID = 0x123. Since I use the same code in two devices, one is the transmitter and one is the receiver, I used two #defines in order to distinguish the transmitter of standard ID = 0x123 (buffer 1) and the receiver of standard ID = 0x123 (buffer 1) (the #defines are, respectively, THIS_IS_THE_TRANSMITTER and THIS_IS_THE_RECEIVER). Because of that, in the main( ) before the infinite for(;;), i used 'canTxMessage.frame_type = CAN_FRAME_STD' and NOT 'canTxMessage.frame_type = CAN_FRAME_EXT' as the default code.

Does anyone know the reason why, when I transmit the msg (ID = 0x123), the ISR never gets activated? I tried to read the datasheet of both ECAN and DMA modules but haven't found the reason of that. Any help would be really appreciated. :roll:

Thanks to all for your help! :thumbsup:

Regards
 

Drugo

Junior Member level 2
Joined
Feb 23, 2011
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,537
Sorry, in my post I made a mistake in attaching the code. I attached it to this post

Thanks a lot
 

Attachments

  • AN1249_dsPIC33F.zip
    12.9 KB · Views: 5

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
have you monitored the Canbus with a device such as
https://www.can232.com/?page_id=16

I used the following with a PIC24HJ128GP504 (I seem to remember getting the code from AN1249)
Code:
#if defined(__dsPIC33F__)
#include <p33Fxxxx.h>
#elif defined(__PIC24H__)
#include <p24hxxxx.h>
#endif

#include "ecan.h"
#include "delay.h"
#include <stdio.h>
#include <ctype.h>
#include "serialio.h"
#include "timer.h"

#include "uart2.h"

mID canTxMessage;
mID canRxMessage;

/* Define ECAN Message Buffers */
ECAN1MSGBUF ecan1msgBuf __attribute__((space(dma),aligned(ECAN1_MSG_BUF_LENGTH*16)));


void CANBUSinitialise(void)
{
	printf("\n\nECAN test \n");
	/* initialise other modules */				
	_C1RXR = 24;
	_RP23R = 0x10;
	initECAN();
	initDMAECAN();
	
	/* Enable ECAN1 Interrupt */     	
	IEC2bits.C1IE=1;	
	/* enable Transmit interrupt */
	C1INTEbits.TBIE=1;
	/* Enable Receive interrupt */
	C1INTEbits.RBIE=1;	
}

void putstring(char *string, int length)
{
    int i;
	for(i=0;i<length;i++)
    {
	  UART2PutChar(string[i]);
    }
}

/******************************************************************************
*                                                                             
*    Function:			puts_ecanTx
*    Description:       puts the sent message on the LCD module   
*                                                                             
*    Arguments:			*message: a pointer to the message structure
*						containing all the information about the message 
*	 Author:            Jatinder Gharoo                                                      
*	                                                                 
*                                                                              
******************************************************************************/
void puts_ecanTx(mID *message)
{		
	if(message->frame_type==CAN_FRAME_EXT)
		printf("TX  XTD         %lx\n", message->id);
	else
		printf("TX  STD         %lx\n", message->id);
}	

/******************************************************************************
*                                                                             
*    Function:			puts_ecanRx
*    Description:       puts the received message on the LCD module 
*                                                                             
*    Arguments:			*message: a pointer to the message structure
*						containing all the information about the message 
*	 Author:            Jatinder Gharoo                                                      
*	                                                                 
*                                                                              
******************************************************************************/
void puts_ecanRx(mID *message)
{
	if(message->frame_type==CAN_FRAME_EXT)
		printf("RX  XTD         %lx\n", message->id);
	else
		printf("RX  STD         %lx\n", message->id);
}

int CANBUSreceived(void)
	{
		/* check to see when a message is received and move the message 
		into RAM and parse the message */ 
		if(canRxMessage.buffer_status==CAN_BUF_FULL)
		{
		printf("recived  CAN message\n");
			rxECAN(&canRxMessage);
			/* display the message on LCD */
			puts_ecanRx(&canRxMessage);				
			/* reset the flag when done */
			canRxMessage.buffer_status=CAN_BUF_EMPTY;
		}
	return 1;
}


extern unsigned long int CANBUSfilter, CANBUSmask;
void testCanbus(void)
{
  while(1)
    {
	printf("CANBUS tests\n"
			"  S: send a message \n"
 			"  F: set receive filter\n"
 			"  M: set receive filtermask\n"
            "    enter command  ?");
	fflush(stdout);
    UART2flush();
	while(1)
		{
		CANBUSreceived();
		if(UART2IsPressed())break;
		}
	switch (toupper(UART2GetChar()))
		{
		case 'S': printf("\nenter ID ?");
				/* configure and send a message */
				canTxMessage.message_type=CAN_MSG_DATA;
				//canTxMessage.message_type=CAN_MSG_RTR;
				canTxMessage.frame_type=CAN_FRAME_EXT;
				//canTxMessage.frame_type=CAN_FRAME_STD;
				canTxMessage.buffer=0;
				canTxMessage.id=readLongIntHex();
               	printf("\nenter data (max 16 hex numbers) ? ");
               readHexChars(canTxMessage.data, 16);
				/*canTxMessage.data[0]=0x55;
				canTxMessage.data[1]=0x55;
				canTxMessage.data[2]=0x55;
				canTxMessage.data[3]=0x55;
				canTxMessage.data[4]=0x55;
				canTxMessage.data[5]=0x55;
				canTxMessage.data[6]=0x55;
				canTxMessage.data[7]=0x55;*/
				canTxMessage.data_length=8;
	
				/* Delay for a second */
			//	Delay(Delay_1S_Cnt);
				printf("\nsend CAN message\n");
				/* send a CAN message */
				sendECAN(&canTxMessage);
				break;
		case 'F': printf("\nenter FILTER ?");
				CANBUSfilter=readLongIntHex();
				initECAN();
				break;		
		case 'M': printf("\nenter MASK ?");
				CANBUSmask=readLongIntHex();
				initECAN();
				break;			}
				printf("\n");
    } 

}



/* Interrupt Service Routine 1                      */
/* No fast context save, and no variables stacked   */
void __attribute__((interrupt,no_auto_psv))_C1Interrupt(void)  
{
	/* check to see if the interrupt is caused by receive */     	 
    if(C1INTFbits.RBIF)
    {
	    /* check to see if buffer 1 is full */
	    if(C1RXFUL1bits.RXFUL1)
	    {			
			/* set the buffer full flag and the buffer received flag */
			canRxMessage.buffer_status=CAN_BUF_FULL;
			canRxMessage.buffer=1;	
		}		
		/* check to see if buffer 2 is full */
		else if(C1RXFUL1bits.RXFUL2)
		{
			/* set the buffer full flag and the buffer received flag */
			canRxMessage.buffer_status=CAN_BUF_FULL;
			canRxMessage.buffer=2;					
		}
		/* check to see if buffer 3 is full */
		else if(C1RXFUL1bits.RXFUL3)
		{
			/* set the buffer full flag and the buffer received flag */
			canRxMessage.buffer_status=CAN_BUF_FULL;
			canRxMessage.buffer=3;					
		}
		else;
		/* clear flag */
		C1INTFbits.RBIF = 0;
	}
	else if(C1INTFbits.TBIF)
    {
	    puts_ecanTx(&canTxMessage);
	    /* clear flag */
		C1INTFbits.TBIF = 0;	    
	}
	else;
	
	/* clear interrupt flag */
	IFS2bits.C1IF=0;
}
 

Drugo

Junior Member level 2
Joined
Feb 23, 2011
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,537
Thanks for your reply horace1. Yes, I monitored the CAN bus with a (different) CAN analyzer, but I don't see any message. And I don't see any message, in my opinion, because the CAN TX interrupt request is not triggered. Well, it could not be triggered also for the fact that the receiver is not receiving anything. But, in the receiver, I implemented the same code with enabled the #define THIS_IS_THE_RECEIVER. In other words, maybe the problem is in the receiver configuration code (but I haven't changed anything from the AN1249). But I can't see it...

Thanks again
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
have you tried the CAN loopback mode to check the basic code is working?
have you tried transmitting a CAN test message from the dsPIC33 and see if the monitor shows anything?
also have you tried looking at the signals using an oscilloscope so check that the signal levels etc are correct (put the dsPIC CAN transmit into a loop)

- - - Updated - - -

using my Explorer 16 with a ECAN PictailPlus daughter board

https://www.microchip.com/Developme...4-15&utm_content=CPG&utm_campaign=Explorer+16

https://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=AC164130-2

I ran the CE127_ECAN_Crosswire communication between ECAN1 and ECAN program (downloaded from the ECAN daughter board web page) and it works OK (using a dsPIC33FJ256GP710)

below is a screen dump of the CANUSB monitor program showing the message sent from ECAN1 to ECAN2
Code:
	ecan1WriteTxMsgBufId(0,0x1FFEFFFF,1,0);
	ecan1WriteTxMsgBufData(0,8,0x1111,0x2222,0x3333,0x4444);
and ECAN2 to ECAN1
Code:
ecan2WriteTxMsgBufId(0,0x1FFEFFFF,1,0);
ecan2WriteTxMsgBufData(0,8,0xaaaa,0xbbbb,0xcccc,0xdddd);

ECAN1to2.jpg
 

Drugo

Junior Member level 2
Joined
Feb 23, 2011
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,537
Thanks again horace1, I appreciate your help!

Before answering to your questions, I would like to specify that I already have both hw and fw with CAN implemented and working (not from me), but it's not well implemented so I want to change it because of some limits it has. So that I didn't use my Explorer 16 board for my tests, but the hw the fw will be implemented on. The "old/current" CAN is working and I can see it with my CAN analyzer.

CAN loopback mode
Actually I haven't tried it yet, it is a good way to test my fw.

Oscilloscope
I haven't tried to monitor the CAN line with the scope yet, because I did it with the CAN analyzer which, with the existing CAN, it perfectly works.

But you know what, I'm implementing the code of ce427_can_crosswire code example and, I think, it's going to work. Later today I'm going to update my status with a post. (I find ce427 much better than AN1249 code).

Thanks a lot for your help
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
I have updated the code of CE127_ECAN_Crosswire to display received CAN messages

main.c is now (note that I have an array of receive buffers)
Code:
/**********************************************************************
* © 2005 Microchip Technology Inc.
*
* FileName:        main.c
* Dependencies:    Header (.h) files if applicable, see below
* Processor:       dsPIC33Fxxxx
* Compiler:        MPLAB® C30 v3.00 or higher
*
* SOFTWARE LICENSE AGREEMENT:
* Microchip Technology Incorporated ("Microchip") retains all ownership and 
* intellectual property rights in the code accompanying this message and in all 
* derivatives hereto.  You may use this code, and any derivatives created by 
* any person or entity by or on your behalf, exclusively with Microchip's
* proprietary products.  Your acceptance and/or use of this code constitutes 
* agreement to the terms and conditions of this notice.
*
* CODE ACCOMPANYING THIS MESSAGE IS SUPPLIED BY MICROCHIP "AS IS".  NO 
* WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED 
* TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A 
* PARTICULAR PURPOSE APPLY TO THIS CODE, ITS INTERACTION WITH MICROCHIP'S 
* PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION. 
*
* YOU ACKNOWLEDGE AND AGREE THAT, IN NO EVENT, SHALL MICROCHIP BE LIABLE, WHETHER 
* IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), 
* STRICT LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL, 
* PUNITIVE, EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF 
* ANY KIND WHATSOEVER RELATED TO THE CODE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN 
* ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT 
* ALLOWABLE BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO 
* THIS CODE, SHALL NOT EXCEED THE PRICE YOU PAID DIRECTLY TO MICROCHIP SPECIFICALLY TO 
* HAVE THIS CODE DEVELOPED.
*
* You agree that you are solely responsible for testing the code and 
* determining its suitability.  Microchip has no obligation to modify, test, 
* certify, or support the code.
*
* REVISION HISTORY:
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Author          	Date      Comments on this revision
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Vinaya Skanda 	10/18/06  First release of source file
* Vinaya Skanda		07/25/07  Updates from Joe Supinsky and Jatinder Gharoo incorporated
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* ADDITIONAL NOTES:
* This code is tested on Explorer-16 board with ECAN PICTail Card.
* The device used is dsPIC33FJ256GP710 controller 
*
* The Processor starts with the External Crystal without PLL enabled and then the Clock is switched to PLL Mode.
*************************************************************************************************/

#if defined(__dsPIC33F__)
#include "p33fxxxx.h"
#elif defined(__PIC24H__)
#include "p24hxxxx.h"
#endif

#include <ECAN1Config.h>
#include <ECAN2Config.h>
#include <common.h>

//  Macros for Configuration Fuse Registers 
_FOSCSEL(FNOSC_FRC); 
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT);  
								// Clock Switching is enabled and Fail Safe Clock Monitor is disabled
								// OSC2 Pin Function: OSC2 is Clock Output
								// Primary Oscillator Mode: XT Crystanl


_FWDT(FWDTEN_OFF);              // Watchdog Timer Enabled/disabled by user software
								// (LPRC can be disabled by clearing SWDTEN bit in RCON register


// Define ECAN Message Buffers
ECAN1MSGBUF ecan1msgBuf __attribute__((space(dma),aligned(ECAN1_MSG_BUF_LENGTH*16)));
ECAN2MSGBUF ecan2msgBuf __attribute__((space(dma),aligned(ECAN2_MSG_BUF_LENGTH*16)));

// CAN Messages in RAM
mID rx_ecan1message[10];
mID rx_ecan2message[10];
int ecan1_in=0, ecan1_out=0, ecan2_in=0, ecan2_out=0;	// array indexes

// Prototype Declaration
void oscConfig(void);
void clearIntrflags(void);
void ecan1WriteMessage(void);
void ecan2WriteMessage(void);
void rxECAN1(mID *message);
void rxECAN2(mID *message);

int main(void)
{

/* Configure Oscillator Clock Source 	*/
	oscConfig();
   UART2Init();										// Setup the UART
    printf("\n\ndsPIC33 test program\n");
   // printf("Fosc %ld\n", Fosc);

/* Clear Interrupt Flags 				*/
	clearIntrflags();


/* ECAN1 Initialisation 		
   Configure DMA Channel 0 for ECAN1 Transmit
   Configure DMA Channel 2 for ECAN1 Receive */
	ecan1Init();
	dma0init();	
	dma2init();

/* Enable ECAN1 Interrupt */ 				
    	
	IEC2bits.C1IE = 1;
	C1INTEbits.TBIE = 1;	
	C1INTEbits.RBIE = 1;

/* ECAN2 Initialisation 		
   Configure DMA Channel 1 for ECAN2 Transmit
   Configure DMA Channel 3 for ECAN2 Receive */
	ecan2Init();
	dma1init();	
	dma3init();

/* Enable ECAN2 Interrupt */ 
	
	IEC3bits.C2IE = 1;
	C2INTEbits.TBIE = 1;	
	C2INTEbits.RBIE = 1;

	C2TR01CONbits.TXREQ0=1;
 
/* Write a Message in ECAN1 Transmit Buffer	
   Request Message Transmission			*/
//	ecan1WriteMessage();
//	C1TR01CONbits.TXREQ0=1;	
	


/* Write a Message in ECAN2 Transmit Buffer
   Request Message Transmission			*/
	ecan2WriteMessage();
	C2TR01CONbits.TXREQ0=1;
	
/* Write a Message in ECAN1 Transmit Buffer	
   Request Message Transmission			*/
	ecan1WriteMessage();
	C1TR01CONbits.TXREQ0=1;	
	

/* Loop infinitely */

	while (1)
		{

		if(ecan1_out < ecan1_in)
			{
			int i;
			printf("\nECAN1 received message ecan1_out %d ecan1_in %d - \n   ID %lx  data  ", 
			   ecan1_out, ecan1_in, rx_ecan1message[ecan1_out].id);
			for(i=0;i<8;i++)printf("%x", rx_ecan1message[ecan1_out].data[i]);
			ecan1_out++;
			}
		if(ecan2_out < ecan2_in)

			{
			int i;

			printf("\nECAN2 received message ecan2_out %d ecan2_in %d -  - \n   ID %lx  data  ", 
                 ecan2_out, ecan2_in, rx_ecan1message[ecan2_out].id);
			for(i=0;i<8;i++)printf("%x", rx_ecan2message[ecan2_out].data[i]);
			ecan2_out++;
			}
		}

	
}




/* ECAN1 buffer loaded with Identifiers and Data */
void ecan1WriteMessage(void){

/* Writing the message for Transmission
ecan1WriteTxMsgBufId(unsigned int buf, long txIdentifier, unsigned int ide, unsigned int remoteTransmit);
ecan1WriteTxMsgBufData(unsigned int buf, unsigned int dataLength, unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4);

buf -> Transmit Buffer number

txIdentifier -> SID<10:0> : EID<17:0>

ide = 0 -> Message will transmit standard identifier
ide = 1 -> Message will transmit extended identifier

remoteTransmit = 0 -> Normal message
remoteTransmit = 1 -> Message will request remote transmission

dataLength -> Data length can be from 0 to 8 bytes

data1, data2, data3, data4 -> Data words (2 bytes) each

*/

	ecan1WriteTxMsgBufId(0,0x1FFEFFFF,1,0);
	ecan1WriteTxMsgBufData(0,8,0x1111,0x2222,0x3333,0x4444);

}

/* ECAN2 buffer loaded with Identifiers and Data */

void ecan2WriteMessage(void){

/* Writing the message for Transmission

ecan2WriteTxMsgBufId(unsigned int buf, long txIdentifier, unsigned int ide, unsigned int remoteTransmit);
ecan2WriteTxMsgBufData(unsigned int buf, unsigned int dataLength, unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4);

buf -> Transmit Buffer Number

txIdentifier -> SID<10:0> : EID<17:0>

ide = 0 -> Message will transmit standard identifier
ide = 1 -> Message will transmit extended identifier

remoteTransmit = 0 -> Normal message
remoteTransmit = 1 -> Message will request remote transmission


dataLength -> Data length can be from 0 to 8 bytes

data1, data2, data3, data4 -> Data words (2 bytes) each


*/

ecan2WriteTxMsgBufId(0,0x1FFEFFFF,1,0);
ecan2WriteTxMsgBufData(0,8,0xaaaa,0xbbbb,0xcccc,0xdddd);

}



/******************************************************************************
*                                                                             
*    Function:			rxECAN1
*    Description:       moves the message from the DMA memory to RAM
*                                                                             
*    Arguments:			*message: a pointer to the message structure in RAM 
*						that will store the message. 
*	 Author:            Jatinder Gharoo                                                      
*	                                                                 
*                                                                              
******************************************************************************/
void rxECAN1(mID *message)
{
	unsigned int ide=0;
	unsigned int srr=0;
	unsigned long id=0,d;
			
	/*
	Standard Message Format: 
	Word0 : 0bUUUx xxxx xxxx xxxx
			     |____________|||
 					SID10:0   SRR IDE(bit 0)     
	Word1 : 0bUUUU xxxx xxxx xxxx
			   	   |____________|
						EID17:6
	Word2 : 0bxxxx xxx0 UUU0 xxxx
			  |_____||	     |__|
			  EID5:0 RTR   	  DLC
	word3-word6: data bytes
	word7: filter hit code bits
	
	Substitute Remote Request Bit
	SRR->	"0"	 Normal Message 
			"1"  Message will request remote transmission
	
	Extended  Identifier Bit			
	IDE-> 	"0"  Message will transmit standard identifier
	   		"1"  Message will transmit extended identifier
	
	Remote Transmission Request Bit
	RTR-> 	"0"  Message transmitted is a normal message
			"1"  Message transmitted is a remote message
	*/
	/* read word 0 to see the message type */
	ide=ecan1msgBuf[message->buffer][0] & 0x0001;	
	srr=ecan1msgBuf[message->buffer][0] & 0x0002;	
	
	/* check to see what type of message it is */
	/* message is standard identifier */
	if(ide==0)
	{
		message->id=(ecan1msgBuf[message->buffer][0] & 0x1FFC) >> 2;		
		message->frame_type=CAN_FRAME_STD;
	}
	/* mesage is extended identifier */
	else
	{
		id=ecan1msgBuf[message->buffer][0] & 0x1FFC;		
		message->id=id << 16;
		id=ecan1msgBuf[message->buffer][1] & 0x0FFF;
		message->id=message->id+(id << 6);
		id=(ecan1msgBuf[message->buffer][2] & 0xFC00) >> 10;
		message->id=message->id+id;		
		message->frame_type=CAN_FRAME_EXT;
	}
	/* check to see what type of message it is */
	/* RTR message */
	if(srr==1)
	{
		message->message_type=CAN_MSG_RTR;	
	}
	/* normal message */
	else
	{
		message->message_type=CAN_MSG_DATA;
		message->data[0]=(unsigned char)ecan1msgBuf[message->buffer][3];
		message->data[1]=(unsigned char)((ecan1msgBuf[message->buffer][3] & 0xFF00) >> 8);
		message->data[2]=(unsigned char)ecan1msgBuf[message->buffer][4];
		message->data[3]=(unsigned char)((ecan1msgBuf[message->buffer][4] & 0xFF00) >> 8);
		message->data[4]=(unsigned char)ecan1msgBuf[message->buffer][5];
		message->data[5]=(unsigned char)((ecan1msgBuf[message->buffer][5] & 0xFF00) >> 8);
		message->data[6]=(unsigned char)ecan1msgBuf[message->buffer][6];
		message->data[7]=(unsigned char)((ecan1msgBuf[message->buffer][6] & 0xFF00) >> 8);
		message->data_length=(unsigned char)(ecan1msgBuf[message->buffer][2] & 0x000F);
	}	
}


/******************************************************************************
*                                                                             
*    Function:			rxECAN2
*    Description:       moves the message from the DMA memory to RAM
*                                                                             
*    Arguments:			*message: a pointer to the message structure in RAM 
*						that will store the message. 
*	 Author:            Jatinder Gharoo                                                      
*	                                                                 
*                                                                              
******************************************************************************/
void rxECAN2(mID *message)
{
	unsigned int ide=0;
	unsigned int srr=0;
	unsigned long id=0,a1;
			
	/*
	Standard Message Format: 
	Word0 : 0bUUUx xxxx xxxx xxxx
			     |____________|||
 					SID10:0   SRR IDE(bit 0)     
	Word1 : 0bUUUU xxxx xxxx xxxx
			   	   |____________|
						EID17:6
	Word2 : 0bxxxx xxx0 UUU0 xxxx
			  |_____||	     |__|
			  EID5:0 RTR   	  DLC
	word3-word6: data bytes
	word7: filter hit code bits
	
	Substitute Remote Request Bit
	SRR->	"0"	 Normal Message 
			"1"  Message will request remote transmission
	
	Extended  Identifier Bit			
	IDE-> 	"0"  Message will transmit standard identifier
	   		"1"  Message will transmit extended identifier
	
	Remote Transmission Request Bit
	RTR-> 	"0"  Message transmitted is a normal message
			"1"  Message transmitted is a remote message
	*/
	/* read word 0 to see the message type */
	ide=ecan2msgBuf[message->buffer][0] & 0x0001;	
	srr=ecan2msgBuf[message->buffer][0] & 0x0002;	
	
	/* check to see what type of message it is */
	/* message is standard identifier */
	if(ide==0)
	{
		message->id=(ecan2msgBuf[message->buffer][0] & 0x1FFC) >> 2;		
		message->frame_type=CAN_FRAME_STD;
	}
	/* mesage is extended identifier */
	else
	{
		id=ecan2msgBuf[message->buffer][0] & 0x1FFC;		
		message->id=id << 16;
		id=ecan2msgBuf[message->buffer][1] & 0x0FFF;
		message->id=message->id+(id << 6);
		id=(ecan2msgBuf[message->buffer][2] & 0xFC00) >> 10;
		message->id=message->id+id;		
		message->frame_type=CAN_FRAME_EXT;
	}
	/* check to see what type of message it is */
	/* RTR message */
	if(srr==1)
	{
		message->message_type=CAN_MSG_RTR;	
	}
	/* normal message */
	else
	{
		message->message_type=CAN_MSG_DATA;
		message->data[0]=(unsigned char)ecan2msgBuf[message->buffer][3];
		message->data[1]=(unsigned char)((ecan2msgBuf[message->buffer][3] & 0xFF00) >> 8);
		message->data[2]=(unsigned char)ecan2msgBuf[message->buffer][4];
		message->data[3]=(unsigned char)((ecan2msgBuf[message->buffer][4] & 0xFF00) >> 8);
		message->data[4]=(unsigned char)ecan2msgBuf[message->buffer][5];
		message->data[5]=(unsigned char)((ecan2msgBuf[message->buffer][5] & 0xFF00) >> 8);
		message->data[6]=(unsigned char)ecan2msgBuf[message->buffer][6];
		message->data[7]=(unsigned char)((ecan2msgBuf[message->buffer][6] & 0xFF00) >> 8);
		message->data_length=(unsigned char)(ecan2msgBuf[message->buffer][2] & 0x000F);
	}	
}





void clearIntrflags(void){
/* Clear Interrupt Flags */

	IFS0=0;
	IFS1=0;
	IFS2=0;
	IFS3=0;
	IFS4=0;
}


void oscConfig(void){

/*  Configure Oscillator to operate the device at 40Mhz
 	Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
 	Fosc= 8M*40/(2*2)=80Mhz for 8M input clock */

	PLLFBD=38;					/* M=40 */
	CLKDIVbits.PLLPOST=0;		/* N1=2 */
	CLKDIVbits.PLLPRE=0;		/* N2=2 */
	OSCTUN=0;					/* Tune FRC oscillator, if FRC is used */

/* Disable Watch Dog Timer */

	RCONbits.SWDTEN=0;

/* Clock switch to incorporate PLL*/
	__builtin_write_OSCCONH(0x03);		// Initiate Clock Switch to Primary
													// Oscillator with PLL (NOSC=0b011)
	__builtin_write_OSCCONL(0x01);		// Start clock switching
	while (OSCCONbits.COSC != 0b011);	// Wait for Clock switch to occur	


/* Wait for PLL to lock */

	while(OSCCONbits.LOCK!=1) {};
}


void __attribute__((interrupt))_C1Interrupt(void)  
//void __attribute__((interrupt, no_auto_psv))_C1Interrupt(void)  
{    
	IFS2bits.C1IF = 0;        // clear interrupt flag
	if(C1INTFbits.TBIF)
    { 
    	C1INTFbits.TBIF = 0;
    } 
 
    if(C1INTFbits.RBIF)
    {      
		// read the message 
	    if(C1RXFUL1bits.RXFUL1==1)
	    {
	    	rx_ecan1message[ecan1_in].buffer=1;
	    	C1RXFUL1bits.RXFUL1=0;
	    }	    
	    rxECAN1(&rx_ecan1message[ecan1_in]); 
		ecan1_in++;	    	    
		C1INTFbits.RBIF = 0;
	}
}


//void __attribute__((interrupt, no_auto_psv))_C2Interrupt(void)  
void __attribute__((interrupt))_C2Interrupt(void)  
{
	IFS3bits.C2IF = 0;        // clear interrupt flag
	if(C2INTFbits.TBIF)
    { 
		C2INTFbits.TBIF = 0;
    } 
    
    if(C2INTFbits.RBIF)
     {      
		// read the message 
	    if(C2RXFUL1bits.RXFUL1==1)
	    {
	    	rx_ecan2message[ecan2_in].buffer=1;
	    	C2RXFUL1bits.RXFUL1=0;
	    }	    
	    rxECAN2(&rx_ecan2message[ecan2_in]); 
		ecan2_in++;	    	    
		C2INTFbits.RBIF = 0;
     }
}
 

//------------------------------------------------------------------------------
//    DMA interrupt handlers
//------------------------------------------------------------------------------

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
   IFS0bits.DMA0IF = 0;          // Clear the DMA0 Interrupt Flag;
}

void __attribute__((interrupt, no_auto_psv)) _DMA1Interrupt(void)
{
   IFS0bits.DMA1IF = 0;          // Clear the DMA1 Interrupt Flag;
}

void __attribute__((interrupt, no_auto_psv)) _DMA2Interrupt(void)
{
   IFS1bits.DMA2IF = 0;          // Clear the DMA2 Interrupt Flag;
}

void __attribute__((interrupt, no_auto_psv)) _DMA3Interrupt(void)
{
   IFS2bits.DMA3IF = 0;          // Clear the DMA3 Interrupt Flag;
}


when run a teraterm terminal emulator displays
ECAN1to2b.jpg

and the USB-CAN program displays (note that after receiving the two messages from the explorer 16 I have transmitted a couple of messages from this program to the Explorer 16)
ECAN1to2a.jpg
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
I have updated the code to transmit multiple messages from ecan1 and ecan2
Code:
#if defined(__dsPIC33F__)
#include "p33fxxxx.h"
#elif defined(__PIC24H__)
#include "p24hxxxx.h"
#endif

#include <ECAN1Config.h>
#include <ECAN2Config.h>
#include <common.h>

//  Macros for Configuration Fuse Registers 
_FOSCSEL(FNOSC_FRC); 
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF  & POSCMD_XT);  
								// Clock Switching is enabled and Fail Safe Clock Monitor is disabled
								// OSC2 Pin Function: OSC2 is Clock Output
								// Primary Oscillator Mode: XT Crystanl


_FWDT(FWDTEN_OFF);              // Watchdog Timer Enabled/disabled by user software
								// (LPRC can be disabled by clearing SWDTEN bit in RCON register


// Define ECAN Message Buffers
ECAN1MSGBUF ecan1msgBuf __attribute__((space(dma),aligned(ECAN1_MSG_BUF_LENGTH*16)));
ECAN2MSGBUF ecan2msgBuf __attribute__((space(dma),aligned(ECAN2_MSG_BUF_LENGTH*16)));

// CAN Messages in RAM
mID rx_ecan1message[10];
mID rx_ecan2message[10];
volatile int ecan1_in=0, ecan1_out=0, ecan2_in=0, ecan2_out=0;	// array indexes
volatile int 	ecan1Transmited=1, ecan2Transmited=1;

// Prototype Declaration
void oscConfig(void);
void clearIntrflags(void);
void ecan1WriteMessage(unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4);
void ecan2WriteMessage(unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4);
void rxECAN1(mID *message);
void rxECAN2(mID *message);

int main(void)
{

/* Configure Oscillator Clock Source 	*/
	oscConfig();
   UART2Init();										// Setup the UART
    printf("\n\ndsPIC33 test program\n");
   // printf("Fosc %ld\n", Fosc);

/* Clear Interrupt Flags 				*/
	clearIntrflags();


/* ECAN1 Initialisation 		
   Configure DMA Channel 0 for ECAN1 Transmit
   Configure DMA Channel 2 for ECAN1 Receive */
	ecan1Init();
	dma0init();	
	dma2init();

/* Enable ECAN1 Interrupt */ 				
    	
	IEC2bits.C1IE = 1;
	C1INTEbits.TBIE = 1;	
	C1INTEbits.RBIE = 1;

/* ECAN2 Initialisation 		
   Configure DMA Channel 1 for ECAN2 Transmit
   Configure DMA Channel 3 for ECAN2 Receive */
	ecan2Init();
	dma1init();	
	dma3init();

/* Enable ECAN2 Interrupt */ 
	
	IEC3bits.C2IE = 1;
	C2INTEbits.TBIE = 1;	
	C2INTEbits.RBIE = 1;

	C2TR01CONbits.TXREQ0=1;
 
/* Write a Message in ECAN1 Transmit Buffer	
   Request Message Transmission			*/
//	ecan1WriteMessage();
//	C1TR01CONbits.TXREQ0=1;	
	


/* Write a Message in ECAN2 Transmit Buffer
   Request Message Transmission			*/
	ecan2WriteMessage(0xaaaa,0xbbbb,0xcccc,0xdddd);
//	C2TR01CONbits.TXREQ0=1;
	
/* Write a Message in ECAN1 Transmit Buffer	
   Request Message Transmission			*/
	ecan1WriteMessage(0x1111,0x2222,0x3333,0x4444);
	ecan1WriteMessage(0x5555,0x6666,0x7777,0x8888);
	ecan2WriteMessage(0xaaff,0xbbff,0xccff,0xddff);
	ecan1WriteMessage(0x1234,0x5678,0x9abc,0xdeff);
	

/* Loop infinitely */

	while (1)
		{

		if(ecan1_out < ecan1_in)
			{
			int i;
			printf("\nECAN1 received message ecan1_out %d ecan1_in %d - \n   ID %lx  data  ", 
			   ecan1_out, ecan1_in, rx_ecan1message[ecan1_out].id);
			for(i=0;i<8;i++)printf("%x", rx_ecan1message[ecan1_out].data[i]);
			ecan1_out++;
			}
		if(ecan2_out < ecan2_in)

			{
			int i;

			printf("\nECAN2 received message ecan2_out %d ecan2_in %d -  - \n   ID %lx  data  ", 
                 ecan2_out, ecan2_in, rx_ecan1message[ecan2_out].id);
			for(i=0;i<8;i++)printf("%x", rx_ecan2message[ecan2_out].data[i]);
			ecan2_out++;
			}
		}

	
}




/* ECAN1 buffer loaded with Identifiers and Data */
void ecan1WriteMessage(unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4){

/* Writing the message for Transmission
ecan1WriteTxMsgBufId(unsigned int buf, long txIdentifier, unsigned int ide, unsigned int remoteTransmit);
ecan1WriteTxMsgBufData(unsigned int buf, unsigned int dataLength, unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4);

buf -> Transmit Buffer number

txIdentifier -> SID<10:0> : EID<17:0>

ide = 0 -> Message will transmit standard identifier
ide = 1 -> Message will transmit extended identifier

remoteTransmit = 0 -> Normal message
remoteTransmit = 1 -> Message will request remote transmission

dataLength -> Data length can be from 0 to 8 bytes

data1, data2, data3, data4 -> Data words (2 bytes) each

*/

	while(	!ecan1Transmited) Nop();
	ecan1Transmited=0;
	ecan1WriteTxMsgBufId(0,0x1FFEFFFF,1,0);
	ecan1WriteTxMsgBufData(0,8,data1, data2, data3, data4);
	C1TR01CONbits.TXREQ0=1;	

}

/* ECAN2 buffer loaded with Identifiers and Data */

void ecan2WriteMessage(unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4){

/* Writing the message for Transmission

ecan2WriteTxMsgBufId(unsigned int buf, long txIdentifier, unsigned int ide, unsigned int remoteTransmit);
ecan2WriteTxMsgBufData(unsigned int buf, unsigned int dataLength, unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4);

buf -> Transmit Buffer Number

txIdentifier -> SID<10:0> : EID<17:0>

ide = 0 -> Message will transmit standard identifier
ide = 1 -> Message will transmit extended identifier

remoteTransmit = 0 -> Normal message
remoteTransmit = 1 -> Message will request remote transmission


dataLength -> Data length can be from 0 to 8 bytes

data1, data2, data3, data4 -> Data words (2 bytes) each


*/

	while(	!ecan2Transmited) Nop();
	ecan2Transmited=0;
ecan2WriteTxMsgBufId(0,0x1FFEFFFF,1,0);
ecan2WriteTxMsgBufData(0,8,data1, data2, data3, data4);
	C2TR01CONbits.TXREQ0=1;	

}



/******************************************************************************
*                                                                             
*    Function:			rxECAN1
*    Description:       moves the message from the DMA memory to RAM
*                                                                             
*    Arguments:			*message: a pointer to the message structure in RAM 
*						that will store the message. 
*	 Author:            Jatinder Gharoo                                                      
*	                                                                 
*                                                                              
******************************************************************************/
void rxECAN1(mID *message)
{
	unsigned int ide=0;
	unsigned int srr=0;
	unsigned long id=0,d;
			
	/*
	Standard Message Format: 
	Word0 : 0bUUUx xxxx xxxx xxxx
			     |____________|||
 					SID10:0   SRR IDE(bit 0)     
	Word1 : 0bUUUU xxxx xxxx xxxx
			   	   |____________|
						EID17:6
	Word2 : 0bxxxx xxx0 UUU0 xxxx
			  |_____||	     |__|
			  EID5:0 RTR   	  DLC
	word3-word6: data bytes
	word7: filter hit code bits
	
	Substitute Remote Request Bit
	SRR->	"0"	 Normal Message 
			"1"  Message will request remote transmission
	
	Extended  Identifier Bit			
	IDE-> 	"0"  Message will transmit standard identifier
	   		"1"  Message will transmit extended identifier
	
	Remote Transmission Request Bit
	RTR-> 	"0"  Message transmitted is a normal message
			"1"  Message transmitted is a remote message
	*/
	/* read word 0 to see the message type */
	ide=ecan1msgBuf[message->buffer][0] & 0x0001;	
	srr=ecan1msgBuf[message->buffer][0] & 0x0002;	
	
	/* check to see what type of message it is */
	/* message is standard identifier */
	if(ide==0)
	{
		message->id=(ecan1msgBuf[message->buffer][0] & 0x1FFC) >> 2;		
		message->frame_type=CAN_FRAME_STD;
	}
	/* mesage is extended identifier */
	else
	{
		id=ecan1msgBuf[message->buffer][0] & 0x1FFC;		
		message->id=id << 16;
		id=ecan1msgBuf[message->buffer][1] & 0x0FFF;
		message->id=message->id+(id << 6);
		id=(ecan1msgBuf[message->buffer][2] & 0xFC00) >> 10;
		message->id=message->id+id;		
		message->frame_type=CAN_FRAME_EXT;
	}
	/* check to see what type of message it is */
	/* RTR message */
	if(srr==1)
	{
		message->message_type=CAN_MSG_RTR;	
	}
	/* normal message */
	else
	{
		message->message_type=CAN_MSG_DATA;
		message->data[0]=(unsigned char)ecan1msgBuf[message->buffer][3];
		message->data[1]=(unsigned char)((ecan1msgBuf[message->buffer][3] & 0xFF00) >> 8);
		message->data[2]=(unsigned char)ecan1msgBuf[message->buffer][4];
		message->data[3]=(unsigned char)((ecan1msgBuf[message->buffer][4] & 0xFF00) >> 8);
		message->data[4]=(unsigned char)ecan1msgBuf[message->buffer][5];
		message->data[5]=(unsigned char)((ecan1msgBuf[message->buffer][5] & 0xFF00) >> 8);
		message->data[6]=(unsigned char)ecan1msgBuf[message->buffer][6];
		message->data[7]=(unsigned char)((ecan1msgBuf[message->buffer][6] & 0xFF00) >> 8);
		message->data_length=(unsigned char)(ecan1msgBuf[message->buffer][2] & 0x000F);
	}	
}


/******************************************************************************
*                                                                             
*    Function:			rxECAN2
*    Description:       moves the message from the DMA memory to RAM
*                                                                             
*    Arguments:			*message: a pointer to the message structure in RAM 
*						that will store the message. 
*	 Author:            Jatinder Gharoo                                                      
*	                                                                 
*                                                                              
******************************************************************************/
void rxECAN2(mID *message)
{
	unsigned int ide=0;
	unsigned int srr=0;
	unsigned long id=0,a1;
			
	/*
	Standard Message Format: 
	Word0 : 0bUUUx xxxx xxxx xxxx
			     |____________|||
 					SID10:0   SRR IDE(bit 0)     
	Word1 : 0bUUUU xxxx xxxx xxxx
			   	   |____________|
						EID17:6
	Word2 : 0bxxxx xxx0 UUU0 xxxx
			  |_____||	     |__|
			  EID5:0 RTR   	  DLC
	word3-word6: data bytes
	word7: filter hit code bits
	
	Substitute Remote Request Bit
	SRR->	"0"	 Normal Message 
			"1"  Message will request remote transmission
	
	Extended  Identifier Bit			
	IDE-> 	"0"  Message will transmit standard identifier
	   		"1"  Message will transmit extended identifier
	
	Remote Transmission Request Bit
	RTR-> 	"0"  Message transmitted is a normal message
			"1"  Message transmitted is a remote message
	*/
	/* read word 0 to see the message type */
	ide=ecan2msgBuf[message->buffer][0] & 0x0001;	
	srr=ecan2msgBuf[message->buffer][0] & 0x0002;	
	
	/* check to see what type of message it is */
	/* message is standard identifier */
	if(ide==0)
	{
		message->id=(ecan2msgBuf[message->buffer][0] & 0x1FFC) >> 2;		
		message->frame_type=CAN_FRAME_STD;
	}
	/* mesage is extended identifier */
	else
	{
		id=ecan2msgBuf[message->buffer][0] & 0x1FFC;		
		message->id=id << 16;
		id=ecan2msgBuf[message->buffer][1] & 0x0FFF;
		message->id=message->id+(id << 6);
		id=(ecan2msgBuf[message->buffer][2] & 0xFC00) >> 10;
		message->id=message->id+id;		
		message->frame_type=CAN_FRAME_EXT;
	}
	/* check to see what type of message it is */
	/* RTR message */
	if(srr==1)
	{
		message->message_type=CAN_MSG_RTR;	
	}
	/* normal message */
	else
	{
		message->message_type=CAN_MSG_DATA;
		message->data[0]=(unsigned char)ecan2msgBuf[message->buffer][3];
		message->data[1]=(unsigned char)((ecan2msgBuf[message->buffer][3] & 0xFF00) >> 8);
		message->data[2]=(unsigned char)ecan2msgBuf[message->buffer][4];
		message->data[3]=(unsigned char)((ecan2msgBuf[message->buffer][4] & 0xFF00) >> 8);
		message->data[4]=(unsigned char)ecan2msgBuf[message->buffer][5];
		message->data[5]=(unsigned char)((ecan2msgBuf[message->buffer][5] & 0xFF00) >> 8);
		message->data[6]=(unsigned char)ecan2msgBuf[message->buffer][6];
		message->data[7]=(unsigned char)((ecan2msgBuf[message->buffer][6] & 0xFF00) >> 8);
		message->data_length=(unsigned char)(ecan2msgBuf[message->buffer][2] & 0x000F);
	}	
}





void clearIntrflags(void){
/* Clear Interrupt Flags */

	IFS0=0;
	IFS1=0;
	IFS2=0;
	IFS3=0;
	IFS4=0;
}


void oscConfig(void){

/*  Configure Oscillator to operate the device at 40Mhz
 	Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
 	Fosc= 8M*40/(2*2)=80Mhz for 8M input clock */

	PLLFBD=38;					/* M=40 */
	CLKDIVbits.PLLPOST=0;		/* N1=2 */
	CLKDIVbits.PLLPRE=0;		/* N2=2 */
	OSCTUN=0;					/* Tune FRC oscillator, if FRC is used */

/* Disable Watch Dog Timer */

	RCONbits.SWDTEN=0;

/* Clock switch to incorporate PLL*/
	__builtin_write_OSCCONH(0x03);		// Initiate Clock Switch to Primary
													// Oscillator with PLL (NOSC=0b011)
	__builtin_write_OSCCONL(0x01);		// Start clock switching
	while (OSCCONbits.COSC != 0b011);	// Wait for Clock switch to occur	


/* Wait for PLL to lock */

	while(OSCCONbits.LOCK!=1) {};
}


void __attribute__((interrupt))_C1Interrupt(void)  
//void __attribute__((interrupt, no_auto_psv))_C1Interrupt(void)  
{    
	IFS2bits.C1IF = 0;        // clear interrupt flag
	if(C1INTFbits.TBIF)
    { 
    	C1INTFbits.TBIF = 0;
		ecan1Transmited=1;
    } 
 
    if(C1INTFbits.RBIF)
    {      
		// read the message 
	    if(C1RXFUL1bits.RXFUL1==1)
	    {
			// if array indexes are the same reset then add new data to array
			if(ecan1_out == ecan1_in)ecan1_out = ecan1_in=0;
	    	rx_ecan1message[ecan1_in].buffer=1;
	    	C1RXFUL1bits.RXFUL1=0;
	    }	    
	    rxECAN1(&rx_ecan1message[ecan1_in]); 
		ecan1_in++;	    	    
		C1INTFbits.RBIF = 0;
	}
}


//void __attribute__((interrupt, no_auto_psv))_C2Interrupt(void)  
void __attribute__((interrupt))_C2Interrupt(void)  
{
	IFS3bits.C2IF = 0;        // clear interrupt flag
	if(C2INTFbits.TBIF)
    { 
		C2INTFbits.TBIF = 0;
		ecan2Transmited=1;
    } 
    
    if(C2INTFbits.RBIF)
     {      
		// read the message 
	    if(C2RXFUL1bits.RXFUL1==1)
	    {
			// if array indexes are the same reset then add new data to array
			if(ecan2_out == ecan2_in)ecan2_out = ecan2_in=0;
	    	rx_ecan2message[ecan2_in].buffer=1;
	    	C2RXFUL1bits.RXFUL1=0;
	    }	    
	    rxECAN2(&rx_ecan2message[ecan2_in]); 
		ecan2_in++;	    	    
		C2INTFbits.RBIF = 0;
     }
}
 

//------------------------------------------------------------------------------
//    DMA interrupt handlers
//------------------------------------------------------------------------------

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
   IFS0bits.DMA0IF = 0;          // Clear the DMA0 Interrupt Flag;
}

void __attribute__((interrupt, no_auto_psv)) _DMA1Interrupt(void)
{
   IFS0bits.DMA1IF = 0;          // Clear the DMA1 Interrupt Flag;
}

void __attribute__((interrupt, no_auto_psv)) _DMA2Interrupt(void)
{
   IFS1bits.DMA2IF = 0;          // Clear the DMA2 Interrupt Flag;
}

void __attribute__((interrupt, no_auto_psv)) _DMA3Interrupt(void)
{
   IFS2bits.DMA3IF = 0;          // Clear the DMA3 Interrupt Flag;
}
teraterm displays
teraterm2.jpg
and the USB-CAN displays
USBCAN2.jpg

note there is a problem with the order of transmission of bytes, e.g. when I transmit
Code:
	ecan1WriteMessage(0x1234,0x5678,0x9abc,0xdeff);
I receive
Code:
   ID 0  data  34127856bc9affde
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
the problem with data being transmited in the wrong order is no doubt due to the dsPIC being little endian when multiple byte data is stored in memory least significant byte first - we are passing the ecan1WriteMessage() function unsigned int parameters where a value such as 0x1234 is stored as two bytes 0x34 then 0x12
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
the problem with data being transmited in the wrong order is no doubt due to the dsPIC being little endian when multiple byte data is stored in memory least significant byte first - we are passing the ecan1WriteMessage() function unsigned int parameters where a value such as 0x1234 is stored as two bytes 0x34 then 0x12
there are various ways to fix this
probably the simplest is to swop the bytes in a word before transmission, e.g. in ECAN1Drv.c (and ECAN2Drv.c) define a macro to swop the bytes in a 16 bit word
Code:
// fix so bytes are transmitted in correct order
#define swopBytes(x) ((x << 8)| ((x >> 8) & 0xFF))


void ecan1WriteTxMsgBufData(unsigned int buf, unsigned int dataLength, unsigned int data1, unsigned int data2, unsigned int data3, unsigned int data4){
	ecan1msgBuf[buf][2] = ((ecan1msgBuf[buf][2] & 0xFFF0) + dataLength) ;
	ecan1msgBuf[buf][3] = swopBytes(data1);
	ecan1msgBuf[buf][4] = swopBytes(data2);
	ecan1msgBuf[buf][5] = swopBytes(data3);
	ecan1msgBuf[buf][6] = swopBytes(data4);
}
when run tera term now displays
teraterm3.jpg

- - - Updated - - -

the above shows the importance of selecting suitable test data - in the statement
Code:
	ecan1WriteMessage(0x1111,0x2222,0x3333,0x4444);
the bytes of each data word are identical so the problem of the bytes being transmited in the incorrect order is not shown

the following showed the problem
Code:
	ecan1WriteMessage(0x1234,0x5678,0x9abc,0xdeff);
when the result was
Code:
 ID 0  data  34127856bc9affde
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top