|
|
View previous topic :: View next topic |
Author |
Message |
Lengrammer
Joined: 15 Nov 2011 Posts: 4
|
18F258 Can bus issue |
Posted: Tue Nov 15, 2011 12:20 pm |
|
|
Hey,
I'm having a Can bus issue right now which is quite strange. I've created a little board that listens to the CAN bus, it's for switching some lights on and off.
The software I created works, but for some reason it isn't working now.
setup:
18F258
12MHz oscillator
MCP2551 transceiver
I've tried several controllers, 2 transceivers but that doesn't seem the case.
problem 1:
Code: |
can_init();
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)
printf("\r\nRunning...");
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX0MASK, 0x7FF, 0); //set mask 0
can_set_id(RX0FILTER0, 472, 0); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 472, 0); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x7FF, 0); //set mask 1
can_set_id(RX1FILTER2, 472, 0); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 472, 0); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 472, 0); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 472, 0); //set filter 3 of mask 1
can_set_mode(CAN_OP_NORMAL);
|
For some reason the uc is stuck in a loop after the can_set_mode(CAN_OP_CONFIG); After putting manually 5V on the CANRX pin it starts. I 'fixed' this by remove the CAN_OP_CONFIG line and all the can_set_id lines, since the can_init function automatically puts the chip into can_op_normal mode. That works (though not with my filters, any suggestions on this one?)
The second problem is that I see nothing change on the CANTX pin, I want to know for sure the MCP2551 isn't the problem so i removed it and attached my scope on the CANTX pin. Nothing on that pin...
In docklight I see:
CAN_PUTD(): BUFF = 0 ID=000001D8 LEN=1 PRI=1 EXT=0 RTR=0
DATA = 01
CAN_PUTD(): BUFF = 1 ID=000001D8 LEN=1 PRI=1 EXT=0 RTR=0
DATA = 01
CAN_PUTD(): BUFF = 2 ID=000001D8 LEN=1 PRI=1 EXT=0 RTR=0
DATA = 01
So the buffers get full, no errors, and nothing on my scope.
Any help? Here's my code:
Code: |
#include <18F258.h>
#FUSES HS //High speed oscillator
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=12M)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#define CAN_USE_EXTENDED_ID FALSE
#define CAN_DO_DEBUG TRUE
#include <can-18xxx8.c>
#define BOARD2_ID 472
int16 ms;
#int_timer2
void isr_timer2(void) {
ms++;
output_toggle(PIN_A1);
}
//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;
int8 buffer[8];
int8 in_data[8];
int output = 8;
setup_timer_2(T2_DIV_BY_16,250,15); //setup up timer2 to interrupt every 20 ms using 12MHz
can_init();
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)
printf("\r\nRunning...");
//can_set_mode(CAN_OP_CONFIG);
/* can_set_id(RX0MASK, 0x7FF, 0); //set mask 0
can_set_id(RX0FILTER0, 472, 0); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 472, 0); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x7FF, 0); //set mask 1
can_set_id(RX1FILTER2, 472, 0); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 472, 0); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 472, 0); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 472, 0); //set filter 3 of mask 1
*/
can_set_mode(CAN_OP_NORMAL);
buffer[0] = 0x1;
while(1)
{
// output_toggle(PIN_A1);
// Transmit it to board #2.
int i;
if(can_tbe() && ms > 25) {
i = can_putd(BOARD2_ID, &buffer[0], 1, 1, 0, 0);
output_toggle(PIN_A2);
printf("i: %i \n\r", i);
ms=0;
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 15, 2011 12:55 pm |
|
|
Quote: |
The second problem is that I see nothing change on the CANTX pin, I
want to know for sure the MCP2551 isn't the problem so i removed it and
attached my scope on the CANTX pin. Nothing on that pin...
|
That is actually the expected behavior. The CCS CAN Bus drivers
configure the CANTX pin so it doesn't "drive high". It requires an external
pull-up resistor on that pin. The MCP2551 has the pull-up built-in. See
the data sheet.
To make the CCS driver configure CANTX so it will work without an
external pull-up, add the #define statement shown below, and put it
just above the #include for the driver file:
Code: |
#define CAN_ENABLE_DRIVE_HIGH 1
#include <can-18xxx8.c>
|
There are many threads in the forum archives that explain how to
trouble-shoot CAN Bus problems. Here are some of them:
http://www.ccsinfo.com/forum/viewtopic.php?t=39809
http://www.ccsinfo.com/forum/viewtopic.php?t=40076
http://www.ccsinfo.com/forum/viewtopic.php?t=39792 |
|
|
Lengrammer
Joined: 15 Nov 2011 Posts: 4
|
|
Posted: Tue Nov 15, 2011 3:41 pm |
|
|
[quote="PCM programmer"] Quote: |
That is actually the expected behavior. The CCS CAN Bus drivers
configure the CANTX pin so it doesn't "drive high". It requires an external
pull-up resistor on that pin. The MCP2551 has the pull-up built-in. See
the data sheet.
|
so that might mean that my MCP2551's have died? I have 2 here both showing the exact same behaviour. If i measure the Vref pin I measure 0V, on both chips. When properly attached the CANTX pin is certainly not high, so I think it's time to buy new MCP's.
Are those thingys that sensitive?
Anyway cheers for the help so far, I might reply soon when I have my new MCP's. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 15, 2011 4:03 pm |
|
|
I didn't mean that. I assumed you removed the MCP2551 from your
circuit. Then you looked at the CANTX pin on the PIC. Then you saw
no signal. The reason for that is the CANTX pin requires a pull-up. The
MCP2551 has a pull-up on it. |
|
|
Lengrammer
Joined: 15 Nov 2011 Posts: 4
|
|
Posted: Tue Nov 15, 2011 4:24 pm |
|
|
PCM programmer wrote: | I didn't mean that. I assumed you removed the MCP2551 from your
circuit. Then you looked at the CANTX pin on the PIC. Then you saw
no signal. The reason for that is the CANTX pin requires a pull-up. The
MCP2551 has a pull-up on it. |
Yep that's what I did, however when the MCP2551 is in circuit I see two things:
1: the Vref pin stays low (should be Vdd/2 according to datasheet)
2: the CANTX pin isn't high, which it should be if it has an internal Pull-up |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 15, 2011 5:15 pm |
|
|
I plugged an MCP2551 into a socket on my PicDem2-Plus board.
(I already had a socket added for this purpose). I measured +5v
on the Vdd pin and +2.5v on the Vref pin. I have a question.
Do you have anything connected to the Vref pin ? It's supposed
to be un-connected. Do you have +5v on the Vdd pin of the MCP2551 ?
And do you have Vss on the MCP2551 connected to ground ?
You need both of those connections. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Nov 16, 2011 2:35 am |
|
|
When you try to run a PIC CAN node on its own, i.e. without any other CAN nodes running at the same bit rate on the bus, then it doesn't get any acknowledgements when it tries to transmit. That's a transmit error and the the node retries, retries, and retries... forever. The CAN peripheral will buffer three messages then it won't accept any more and can_putd() will block (i.e. won't return) as the CAN subsystem cannot find any free transmit buffers.
If you then try and reset the CAN peripheral will not configure as it waits in can_set_mode(CAN_OP_CONFIG); for the CAN perihperal to become idle, which it can't as its still trying to resend, resend, resend.
What do you see? Three attempts to transmit and it locks up when you attempt to configure. Sounds to me as though you've struck this problem.
I've tried to overcome this behaviour by detecting the retry errors through the error count and then cancelling the send or reseting the peripheral but I've not been able to do that cleanly, something goes wrong somewhere leading to ongoing CAN problems: missed messages and so on. Even a hardware reset doesn't appear to reset the CAN peripheral module in the PIC. I couldn't get my workround to work reliably, and I abandoned the attempt. Instead I now accept that a single CAN node will lock up, end of story.
The moral: One CAN node feels lonely. You must have at least two CAN nodes in a net.
RF Developer |
|
|
Lengrammer
Joined: 15 Nov 2011 Posts: 4
|
|
Posted: Wed Nov 16, 2011 10:26 am |
|
|
PCM programmer wrote: | I plugged an MCP2551 into a socket on my PicDem2-Plus board.
(I already had a socket added for this purpose). I measured +5v
on the Vdd pin and +2.5v on the Vref pin. I have a question.
Do you have anything connected to the Vref pin ? It's supposed
to be un-connected. Do you have +5v on the Vdd pin of the MCP2551 ?
And do you have Vss on the MCP2551 connected to ground ?
You need both of those connections. |
1) the Vref pin is unconnectd
2&3) Both properly connected, ofcourse
RF_Developer wrote: |
When you try to run a PIC CAN node on its own, i.e. without any other CAN nodes running at the same bit rate on the bus, then it doesn't get any acknowledgements when it tries to transmit. That's a transmit error and the the node retries, retries, and retries... forever. The CAN peripheral will buffer three messages then it won't accept any more and can_putd() will block (i.e. won't return) as the CAN subsystem cannot find any free transmit buffers.
If you then try and reset the CAN peripheral will not configure as it waits in can_set_mode(CAN_OP_CONFIG); for the CAN perihperal to become idle, which it can't as its still trying to resend, resend, resend.
What do you see? Three attempts to transmit and it locks up when you attempt to configure. Sounds to me as though you've struck this problem.
I've tried to overcome this behaviour by detecting the retry errors through the error count and then cancelling the send or reseting the peripheral but I've not been able to do that cleanly, something goes wrong somewhere leading to ongoing CAN problems: missed messages and so on. Even a hardware reset doesn't appear to reset the CAN peripheral module in the PIC. I couldn't get my workround to work reliably, and I abandoned the attempt. Instead I now accept that a single CAN node will lock up, end of story. Sad
The moral: One CAN node feels lonely. You must have at least two CAN nodes in a net.
RF Developer
|
I get your point, however. If the transmit buffers are full, it should keep on sending until an acknowledgement is received. That means that if i measure my CANTX pin with my scope I should see some pattern, which is not the case.
And I'm not sure about your remark about the can_op_config part. I call that piece of code before I even try to send something. You say that the can buffer remains even during no power? I doubt that. . .
And also if you look at the can_init function, it goes to can_op_config and can_op_normal without a problem, only the second time (when I try to change the filters) it's giving troubles. . .
Anyway, new uC and MCP's are ordered |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Nov 16, 2011 11:11 am |
|
|
from can-18xxx8.c:
Code: | void can_set_mode(CAN_OP_MODE mode) {
CANCON.reqop=mode;
while( (CANSTAT.opmode) != mode );
} |
can_set_mode() sets the mode blind, then waits for the CAN peripheral to report its got there. When in locked state it doesn't get there, it stays in CAN_OP_NORMAL. The loop hangs.
This state persists over a MCLR or code initialised restart, including if you are using a ICSP debugger. You may think you are resetting the PIC, but you are actually resetting just the processor core. So when, after any reset, the code tries to configure the CAN, it hangs.
Yes in the hung state you should be seeing continuous resends. So maybe this is not your problem. Do you have a second CAN node for this to talk to? A CAN monitor for example?
RF Developer. |
|
|
|
|
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
|