![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
dilandau
Joined: 25 Aug 2010 Posts: 11
|
[SOLVED]CAN BUS communication ECAN and CAN |
Posted: Wed Aug 25, 2010 10:18 am |
|
|
Hi everybody.
I have been reading around looking for a solution in the forum without success.
I am trying to communicate a few pics using CAN BUS and I was lucky until this point as everything seemed to work after a few hours of work. But by now I am not able to fix the problem and I am running out of ideas.
As one image is better than one thousand words this is a schematic of my system.
Uploaded with ImageShack.us
One node connected to a PC communicates with N nodes through the line including the last node which because of complexity needed to be a dsPIC. Every node in the bus use ECAN, but dsPIC doesn't so this is a probable cause of error. I don't know why because in MODE 0 they should be compatible.
DATA:
- PC communicates via serial port with first node. I have test electrical connections for the full system and everything seem to be ok.
- I use 4.108 PICC compiler and MPLAB 8.53. I have tried with older versions as well with same result.
- I am able to communicate with every node, but not with the dsPIC.
- I have check mcp2551 of the dsPIC and apparently is fine. I have acquired reads in CANRX1 pin with an oscilloscope and this picture show the readings:
Uploaded with ImageShack.us
I would say that the signal is fine.
So after checking every hardware I went for software checkings.
- I am using default configurations for CCS drivers for CAN. I am using can-18F4580.c, can-18F4580.h for the PICs with its default configurations and I am using can-dsPIC30.c, can-dsPIC30.h with its default configurations for the dsPIC 30F6010A. => it implies that prescalar, synch, phase, sam, phase segment, propagation, wake and phase segment configuration are exactly the same.
- Every chip is using a 20MHz crystal without any PLL config. So my first thought is that it is not a speed error.
- I init both of the pics with mask = 0x00 in order to take every message in the bus.
Init code for the PICS are:
Code: |
// CODE for NODES 1 and N
void CAN_ConfAndInit()
{
buffer1_can_id_can_1 = 0;
buffer0_can_mask_can_1 = 0x00000000;
buffer1_can_mask_can_1 = 0x00000000;
enable_interrupts(INT_CANRX0);
enable_interrupts(GLOBAL);
// Can Init
can_init();
// Si soy el Centro de control
buffer0_can_id_can_1 = 0x01;
}//
#INT_CANRX0
void CANX0_isr(void)
{
if (can_kbhit())
{
memset(infodata,'\0',sizeof(infodata));
can_getd(IdOrigen, data_rx, rx_length, rx_struct);
strncpy(infodata, data_rx,8);
CAN_RecibeString(infodata);
}
clear_interrupt(int_CANRX0);
}//
|
Code: |
// CAN initialization for dspic 30F6010A
void CAN_ConfAndInit()
{
buffer1_can_id_can_1 = 0;
buffer0_can_mask_can_1 = 0x00000000;
buffer1_can_mask_can_1 = 0x00000000;
// Can Init
can_init();
// Habilito la interrupcion del CAN
enable_interrupts(INT_CAN1);
can_enable_interrupts(RX0 | RX1 | TX0 | TX1 | TX2 | ERR | WAK | IVR);
enable_interrupts(INTR_GLOBAL);
// Si soy el Centro de control
buffer0_can_id_can_1 = 0x01;
}//
#INT_CAN1
void CANX_isr(void)
{
if (can_kbhit())
{
memset(infodata,'\0',sizeof(infodata));
can_getd(IdOrigen, data_rx, rx_length, rx_struct);
strncpy(infodata, data_rx,8);
CAN_RecibeString(infodata);
}
clear_interrupt(INT_CAN1);
}//
|
- I don't mind having two nodes with same id as in my basic system every message will be considered a broadcast.
- I enable every source of interrupt in order to catch something! but nothing fires the interrupt.
I am sorry for such a long post but I hope that plenty of people will find this post interesting if it is finally solved.
I have run out of ideas and I don't know what more to check/test. It seems that ECAN modules and CAN modules are not compatible but MCHP claims to be compatible, so there is something I am missing I don't find it.
Last edited by dilandau on Thu Aug 26, 2010 4:58 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Wed Aug 25, 2010 10:56 am |
|
|
Your hardware layout seems correct to me. Your waveform looks pretty good too.
Wow, the dsPIC30F6010 has garbage documentation on it's canbus functionality. It seems like the canbus hardware in that chip also leaves much to be desired. What a wonderful combination...
Anyway, have you tried periodically checking the error counters for the canbus hardware to see if you are getting a bunch of receive errors? Maybe keep track of C1EC (0x039A) to see if it's incrementing?
It is possible that you will still need to tweak your bit time settings a little on the dsPIC. But, if you are using the exact same crystal speed then the baud rate should be close enough to have worked. |
|
![](templates/subSilver/images/spacer.gif) |
dilandau
Joined: 25 Aug 2010 Posts: 11
|
|
Posted: Wed Aug 25, 2010 3:14 pm |
|
|
Well, thanks for the answer. I will check that register too.
Anyway, it probably won't increase at all as I enable every source of interrupt for the CAN BUS
Code: | can_enable_interrupts(RX0 | RX1 | TX0 | TX1 | TX2 | ERR | WAK | IVR); |
including the ERR which is the Error interrupt, and the interrupt does not fire.
A few more other test I have done:
- If dsPic put a message in the bus, that message appears in the oscilloscope continuosly forever. It seems this is the normal funcionality when nobody hear the message. I deduce it because if I remove every listen node in the line and I try to send a message with the working 18f258 the message is kept repited once and again.
- If I config the dsPIC as LOOPBACK mode, the interrupt fires... so at least dsPIC understand its own messages. What I am not sure is if the message reach the line or the Loopback is just internal (if so, it is just useless). Apparently, documentation says, loopback is internal.
I will keep posting my tests in the hope that someone see the error as I dont have right now any clue of what is wrong. |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Wed Aug 25, 2010 5:36 pm |
|
|
dilandau wrote: |
A few more other test I have done:
- If dsPic put a message in the bus, that message appears in the oscilloscope continuosly forever. It seems this is the normal funcionality when nobody hear the message. I deduce it because if I remove every listen node in the line and I try to send a message with the working 18f258 the message is kept repited once and again.
|
Yes, this is the behavior when nobody acknowledges the frame. It will continuously retry sending it over and over.
Quote: |
- If I config the dsPIC as LOOPBACK mode, the interrupt fires... so at least dsPIC understand its own messages. What I am not sure is if the message reach the line or the Loopback is just internal (if so, it is just useless). Apparently, documentation says, loopback is internal.
|
Yes, loopback tests your software but does nothing to test any hardware external to the PIC chip.
Quote: |
I will keep posting my tests in the hope that someone see the error as I dont have right now any clue of what is wrong. |
I think you need to consider the following possibilities since you cannot send or receive frames for real but you can in loopback :
1. Your transceiver could be either bad or hooked up wrong at the dsPIC. You checked that though so this should not be the case.
2. Your baud rate is actually set wrong for the dsPIC. This will both prevent successful reception and prevent successfully sending. However, you'd get a whole bunch of receive errors which should very quickly increment the error counters and trip the canbus interrupt.
It's odd... receiving can be difficult because there are so many things in the receiver path: masks, filters, etc. But sending should be a lot easier to get going. That nothing acknowledges your frames suggests to me that your baud rate is wrong. Do you happen to have a PC based canbus tool like a quickcan or something? That would help as you could change the baud rate until it (hopefully) works.
Or, maybe there is a compiler bug or something wrong with the canbus driver for your dsPIC chip. I have never used a dsPIC30 so I can't comment on how well they work with the CCS routines and canbus. |
|
![](templates/subSilver/images/spacer.gif) |
dilandau
Joined: 25 Aug 2010 Posts: 11
|
|
Posted: Thu Aug 26, 2010 3:21 am |
|
|
Checking your second advice I came to find something strange.
I have send same message from 18F585 and from de dsPIC and the one of the dsPIC appear to be much faster (about 4 or 5 times faster)
I will keep playing with CAN speed configuration but this is quite strange from the beginning.
Both chips have same 20 MHz crystal.
Both have the same .h configuration
Code: | #IFNDEF CAN_USE_EXTENDED_ID
#define CAN_USE_EXTENDED_ID TRUE
#ENDIF
#IFNDEF CAN_BRG_SYNCH_JUMP_WIDTH
#define CAN_BRG_SYNCH_JUMP_WIDTH 0 //synchronized jump width (def: 1 x Tq)
#ENDIF
#IFNDEF CAN_BRG_PRESCALAR
#define CAN_BRG_PRESCALAR 4 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#ENDIF
#ifndef CAN_BRG_SEG_2_PHASE_TS
#define CAN_BRG_SEG_2_PHASE_TS TRUE //phase segment 2 time select bit (def: freely programmable)
#endif
#ifndef CAN_BRG_SAM
#define CAN_BRG_SAM 0 //sample of the can bus line (def: bus line is sampled 1 times prior to sample point)
#endif
#ifndef CAN_BRG_PHASE_SEGMENT_1
#define CAN_BRG_PHASE_SEGMENT_1 5 //phase segment 1 (def: 6 x Tq)
#endif
#ifndef CAN_BRG_PROPAGATION_TIME
#define CAN_BRG_PROPAGATION_TIME 2 //propagation time select (def: 3 x Tq)
#endif
#ifndef CAN_BRG_WAKE_FILTER
#define CAN_BRG_WAKE_FILTER FALSE //selects can bus line filter for wake up bit
#endif
#ifndef CAN_BRG_PHASE_SEGMENT_2
#define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time select (def: 6 x Tq)
#endif |
And both configures baud speed in the same way:
Code: |
// pic18
void can_set_baud(void) {
BRGCON1.brp=CAN_BRG_PRESCALAR;
BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
BRGCON2.sam=CAN_BRG_SAM;
BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;
BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
}
// dsPic
void can_set_baud(void) {
C1CFG1.brp=CAN_BRG_PRESCALAR;
C1CFG1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
C1CFG2.prseg=CAN_BRG_PROPAGATION_TIME;
C1CFG2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
C1CFG2.sam=CAN_BRG_SAM;
C1CFG2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;
C1CFG2.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
C1CFG2.wakfil=CAN_BRG_WAKE_FILTER;
}
|
So, I dont understand why the resulting baud speed is different, but it is. |
|
![](templates/subSilver/images/spacer.gif) |
dilandau
Joined: 25 Aug 2010 Posts: 11
|
|
Posted: Thu Aug 26, 2010 4:57 am |
|
|
Finally got it.
It seems to be a compiler error.
The next code which is inside the can-dsPIC30.h do not modify the register properly. That's why my baud rate was different, It was not changing BRP (baud prescaler) value.
Code: | C1CFG1.brp=CAN_BRG_PRESCALAR;
C1CFG1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH; |
If I create my own access to that register it works perfectly.
Here I leave you the code if anyone has this problem.
Thanks collink, your tips were of great help.
Code: |
int32 nodo_can_broadcast_Id = 0x00000000;
int32 buffer0_can_id_can_1;
int32 buffer1_can_id_can_1;
int32 buffer0_can_mask_can_1;
int32 buffer1_can_mask_can_1;
#include "can-dsPIC30.c"
struct CiCFG1_struct C1CFG1_dilan;
#word C1CFG1_dilan=0x0392
void MyBaud()
{
can_set_mode(CAN_OP_CONFIG); //must be in config mode before params can be set
C1CFG1_dilan.brp=CAN_BRG_PRESCALAR;
C1CFG1_dilan.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
C1CFG2.prseg=CAN_BRG_PROPAGATION_TIME;
C1CFG2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
C1CFG2.sam=CAN_BRG_SAM;
C1CFG2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;
C1CFG2.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
C1CFG2.wakfil=CAN_BRG_WAKE_FILTER;
can_set_mode(CAN_OP_NORMAL);
}//
void CAN_ConfAndInit()
{
buffer1_can_id_can_1 = 0;
buffer0_can_mask_can_1 = 0x00000000;
buffer1_can_mask_can_1 = 0x00000000;
// Can Init
can_init();
MyBaud();
// Habilito la interrupcion del CAN
enable_interrupts(INT_CAN1);
can_enable_interrupts(RX0 | RX1 | TX0 | TX1 | TX2 | ERR | WAK | IVR);
enable_interrupts(INTR_GLOBAL);
// Si soy el Centro de control
buffer0_can_id_can_1 = 0x01;
}//
|
I still have to do plenty of things with this CAN BUS schema but my main problem by now is SOLVED. |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Thu Aug 26, 2010 5:19 am |
|
|
Awesome! Well... you might want to report that compiler error though. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|