|
|
View previous topic :: View next topic |
Author |
Message |
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
CAN on 18F4680 [Solved] |
Posted: Tue Apr 18, 2006 6:46 am |
|
|
Without any luck I am trying to get the CAN-bus up and running on a 18F4680. At this point I think I've tried everything...
I am using the example file EX_CAN.C with some minor modifications (I am using a 10Mhz crystal instead of a 20Mhz) interfacing the bus through a MCP2551 tranceiver.
The problem is that when I measure the activity on the CANTX pin, it remains constantly high. Calling the function can_putd the data gets loaded into the buffers and the Transmit Request Status bit is set. However since no data is ever sent this bit never clears and the buffer remains occupied. Any ideas on what to do?
I have also tried to configure the operation mode into Loopback mode in the same matter as newguy did Here but without any luck. Any tries to change operation mode once a mode previously mode been set causes no effect, the mode never changes.
Help would be greatly appreciated, right now I am going slightly mad.
// Fredrik
Last edited by Fredrik on Thu Apr 20, 2006 8:34 am; edited 1 time in total |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Apr 18, 2006 10:07 am |
|
|
I wish I could be of more help. The code in the post of mine you mentioned is pretty much the same code I'm using now in a product I'm developing. And I'm using a pair of 18F4680's. No issues with them at all. All I had to do was change my header file to include the 18F4680.h, and it worked right away.
How did you calculate the bit timing parameters? |
|
|
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
|
Posted: Tue Apr 18, 2006 12:17 pm |
|
|
I have scaled the timing parameters from the ones given in EX_CAN.C (for the 20Mhz crystal) to make them approx. equal:
-----------------------------------
TQ = 2x(BRP+1)/Fosc. BRP = 1, Fosc = 10M gives TQ = 0.4us
(EX_CAN: BRP = 4, Fosc = 20 gives TQ = 0.5us)
Sync segment = 1xTQ gives 0.4us
(EX_CAN: 1xTQ gives 0.5us)
Propagation Segment = 3xTQ gives 1.2us
(EX_CAN: 3xTQ gives 1.5us)
Phase sync 1 = 8xTQ gives 3.2us
(EX_CAN: 6xTQ gives 3.0us)
Phase sync 2 = 8xTQ gives 3.2us
(EX_CAN: 6xTQ gives 3.0us)
Nominal bit time = 0.4 + 1.2 + 3.2 + 3.2 = 8us (= 125kbit/s)
(EX_CAN: 0.5 + 1.5 + 3.0 + 3.0 = 8us)
-----------------------------------
I've done that because I'm not quite sure on how important the different factors are. Now the main problem is that i can't read out any data at all from CANTX pin.
The chip also refuses to change the operation mode once it has been set after the first init. from config. mode (The chip starts in config. mode, and when a mode is set, the chip don't ever go back to config. mode even if I request it).
If you don't mind I would like to have a look at your source, so i can verify that it is not there the problem lies. Or perhaps you could test mine?
Is there by the way an easy way to fake an ideal bus connected to CANTX/CANRX, so that any possible hardware error can be ignored at this time? Of course the bus wont work if there is no answer, but at least so I can se any data coming out of CANTX. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
|
Posted: Wed Apr 19, 2006 12:29 am |
|
|
Thanks for the link PCM Programmer, that made me understand the bit timing better. Unfortunatley this was not the problem, even thoug it made me change the values a bit.
I will insert one of the many codes I have tried. Maybe someone can figure out the error(s):
Code: | #include <18F4680.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define DEBUG
#define WAIT
#byte CANCON = 0xF6F
#byte CANSTAT = 0xF6E
#byte ECANCON = 0xF77
#byte COMSTAT = 0xF74
#byte TXERRCNT = 0xF76
#byte BRGCON1 = 0xF70
#byte BRGCON2 = 0xF71
#byte BRGCON3 = 0xF72
#byte CIOCON = 0xF73
#byte TXB0CON = 0xF40
#byte TXB1CON = 0xF30
#byte TXB2CON = 0xF20
#byte TXB0SIDH = 0xF41
#byte TXB0SIDL = 0xF42
#byte TXB0EIDH = 0xF43
#byte TXB0EIDL = 0xF44
#byte TXB0DLC = 0xF45
#byte TXB0D0 = 0xF46
#byte TXB0D1 = 0xF47
#byte TXB0D2 = 0xF48
#byte TXB0D3 = 0xF49
#byte TXB0D4 = 0xF4A
#byte TXB0D5 = 0xF4B
#byte TXB0D6 = 0xF4C
#byte TXB0D7 = 0xF4D
void can_init(void);
int1 can_t0_putd(void);
void main() {
int i;
can_init();
printf("Running...\r\n");
while(TRUE)
{
//every second, send new data if transmit buffer is empty
delay_ms(1000);
i = can_t0_putd(); //put data to transmit buffer 0
if (i == TRUE) { //success, a transmit buffer was open
printf("SUCCESS, Buffer 0 loaded\r\n");
}
else { //fail, transmit buffer was occupied
printf("FAIL, Buffer 0 occupied\r\n");
}
#ifdef WAIT
printf("Waiting for message to get transmitted...\r\n");
while(bit_test(TXB0CON,3) == 1);
#endif
#ifdef DEBUG
if(bit_test(COMSTAT,5))
printf("Error: TX_OFF\r\n");
if(bit_test(COMSTAT,4))
printf("Error: TX_PASS\r\n");
if(bit_test(COMSTAT,2))
printf("Error: TX_WARN\r\n");
if(TXERRCNT > 0)
printf("TXERRCNT: %X",TXERRCNT);
#endif
}
}
void can_init(void)
{
#ifdef DEBUG
printf("Can Init\r\n");
#endif
// Request Configuration mode
CANCON = 0x80;
while( (CANSTAT & 0x80) != 0x80 ); // Wait for Configuration mode
/* Removing this comment causes the chip to "hang"
CANCON = CANCON & 0x1F; // Clear previous mode
while( (CANSTAT & 0xE0) != 0x00 ); // Wait for Normal mode
CANCON = 0x80;
while( (CANSTAT & 0x80) != 0x80 ); // Wait for Configuration mode !!** HANGS HERE **!!
*/
// Set baudrate, 125 kbit/s
BRGCON1 = 0x04; // Sync Jmp: 1xTQ, Prescaler: TQ = (2x(4+1))/Fosc (1.0us)
BRGCON2 = 0x98; // Freely prog, One sample, Phase_1 = 4xTQ, Propagation time = 1xTQ
BRGCON3 = 0x01; // Disable wake-up, line filter not used, Phase_2 = 2xTQ
// Set I/O
CIOCON = 0x00; // CANTX = tristate, Disable CAN capture
set_tris_b((*0xF93 & 0xFB ) | 0x08); //b3 is out, b2 is in
// Set mode
ECANCON = 0x30; // CANTX will drive VDD when recessive, Enable CAN capture
// Request Normal mode
CANCON = CANCON & 0x1F; // Clear previous mode
while( (CANSTAT & 0xE0) != 0x00 ); // Wait for Normal mode
}
int1 can_t0_putd(void)
{
if((TXB0CON & 0x08) != 0) // Message pending, abort
return ( FALSE );
// Set ID
TXB0SIDH = 0x02;
TXB0SIDL = 0x04;
TXB0EIDH = 0x00;
TXB0EIDL = 0x00;
// Set Length
TXB0DLC = 8;
// Set RTR
TXB0DLC = TXB0DLC & 0xBF; // Don't set RTR
// Set priority
TXB0CON = TXB0CON | 0x03; // Highest priority
// Set Data
TXB0D0 = 0x00;
TXB0D1 = 0x01;
TXB0D2 = 0x02;
TXB0D3 = 0x03;
TXB0D4 = 0x04;
TXB0D5 = 0x05;
TXB0D6 = 0x06;
TXB0D7 = 0x07;
TXB0CON = TXB0CON | 0x08; // Request transmission
return ( TRUE );
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 19, 2006 1:11 am |
|
|
Unfortunately, you're writing your own low-level driver and that's
undoubtedly the problem. You should use the CCS drivers supplied
with the compiler. Read the posts in the forum archives that tell
how to use loopback mode.
http://www.ccsinfo.com/forum/viewtopic.php?t=23825 |
|
|
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
|
Posted: Wed Apr 19, 2006 1:51 am |
|
|
Actually I started out with the CCS drivers supplied with the compiler. But since that did not work I narrowed it down to have a better view on the functions. My low-level driver does basicaly the same thing as the CCS drivers. It is just smaller so it would be easier to search for the error.
As I mentioned in my first post I began using the CCS drivers in the exact same way as newguy did in the link that you just sent. I start with EX_CAN.C and then change #include to 18f4680.h. Change the #use delay. Alter the bit timing values according to earlier posts. Changes the setup_timer_2 to work propely with a 10Mhz osc. And adding can_set_mode(CAN_OP_LOOPBACK); right after can_init(); The last function causes the chip to hang (apparently because the operation mode never changes). So testing loopback mode with the CCS drivers unchanged does not work for me (I did not work for Sholto either).
Any further suggestions would be greatly appreciated. |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Wed Apr 19, 2006 4:30 am |
|
|
Fredrik,
First, I suggest you reduce the unknowns by using the ccs driver. It works, so that narrows your problem down to either timing or a compiler bug (you don't state your compiler version, but 3.237 onwards has problems with allocating structures which are used in the CAN driver). Try 3.236.
Second, when you tried to use EX_CAN.C, did you change the include from
Code: | #include <can-18xxx8.c>
|
to
Code: | #include <can-18F4580.c>
|
as this is the driver for ALL PICs with the ECAN module not the basic CAN module.
Third, If you use lookback mode, this will rule out any problems with the external hardware (i.e CAN transceiver and other node on the bus).
also have a look at ...
CAN you help (pun intended!)
this thread covers some of the most basic errors and pitfalls when trying to implement CAN. _________________ Regards,
Simon. |
|
|
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
|
Posted: Wed Apr 19, 2006 9:05 am |
|
|
Okay this is getting really annoying. I still can’t get any output from the CANTX pin. Everyone keeps telling me to use the CCS driver supplied. I’ve explained several times that I have tried this approach, but no one seems to believe me. It does not work!
I use version 3.245 of the compiler. I wish I had an older version to test with, but I don't. I only have this version and a really old one not supporting 18f4680. I am starting to beleive that this compiler doesn't support the CAN on 18F4680. Or the CAN on the pic doesn't work?!?
Okay so you still don’t believe me? Here are the changes that I have made to the files EX_CAN.C and can-18F4580.h (yes, it's from the supplied CCS driver).
EX_CAN.C:
Code: |
//#include <18F248.h> // default
#include <18F4680.h>
...
//#use delay(clock=20000000) // default
#use delay(clock=10000000)
...
//#include <can-18xxx8.c> // default
#include <can-18F4580.c>
...
//setup_timer_2(T2_DIV_BY_4,79,16); //setup up timer2 to interrupt every 1ms if using 20Mhz clock // default
setup_timer_2(T2_DIV_BY_4,79,8); //setup up timer2 to interrupt every 1ms if using 10Mhz clock
...
can_init();
can_set_mode(CAN_OP_LOOPBACK); // This line is added
... |
can-18F4580.h:
Code: |
...
// #define CAN_BRG_PHASE_SEGMENT_1 5 //phase segment 1 (def: 6 x Tq) // default
#define CAN_BRG_PHASE_SEGMENT_1 3 //phase segment 1 4 x Tq)
...
// #define CAN_BRG_PROPAGATION_TIME 2 //propagation time select (def: 3 x Tq) // default
#define CAN_BRG_PROPAGATION_TIME 0 //propagation time select 1 x Tq)
...
// #define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time select (def: 6 x Tq) // default
#define CAN_BRG_PHASE_SEGMENT_2 1 //phase segment 2 time select 2 x Tq)
...
// #define CAN_ENABLE_DRIVE_HIGH 0 // default
#define CAN_ENABLE_DRIVE_HIGH 1 // drive to Vdd
...
|
The chip "hangs" when it reaches the function can_set_mode(CAN_OP_LOOPBACK); (as I have mentioned several times before). If i remove that line the chip runs the main loop, but nothing is put out on CANTX pin.
This is not a lot of changes, but it also gives no result. If you still think that i am doing something wrong, or have any idea, please tell me so that i can fix it. |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Wed Apr 19, 2006 9:54 am |
|
|
Fredrik,
If 'everyone' is telling you to use the ccs drivers, thats because we have all been in the same position as you and have learnt how not to do it !! and what you do need to do in order to make it work. Don't introduce more unknowns into an already troubled situation, it just makes the task harder to solve not easier.
You should be able to download 3.236 as is the 'stable' base release for the compiler you currently have. It does support this 18F4680. If you can't get acces to it, mail CCS and they will give you access to the download (as your 3.245 license will be valid for this release).
Have a look at the SYM file and see if any global structs or non-scratch variables are 'overlapping' each other. If they are then this is a 'known' compiler bug introduced around 3.242.
You say that the micro 'hangs'. Put in some breakpoints and step through the program and watch the CAN configuration registers. Step into the can_set_mode and check that the registers are still setup the way can_init has set them (i.e. that they haven't been corrupted). At what point does it hang ? Does it jump into can_set_mode or crash before ?
The reason I suggest you try an earlier version is that I was using 3.242 and everything appeared fine until my call to can_putd, at which point the registers changed as the compiler used a variable scratch location that was one of the global variables used to setup the can (hence the corruption). The earlier version of compiler worked without problems.
You may already know, but in loopback mode you won't see anything on CANTX as the loopback disconnects the output and does the lookback internal to the PIC.
If the example doesn't work ... its one of two things (the compiler or the PIC is no good !!!). _________________ Regards,
Simon. |
|
|
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
|
Posted: Wed Apr 19, 2006 12:21 pm |
|
|
sjbaxter wrote: |
If 'everyone' is telling you to use the ccs drivers, thats because we have all been in the same position as you and have learnt how not to do it !! and what you do need to do in order to make it work. Don't introduce more unknowns into an already troubled situation, it just makes the task harder to solve not easier. |
That was the reason why I decided to write my own driver when the ccs supplied driver did not work. I wanted to minimize data structures, variables etc. to get a straight forward code to overcome any possible compiler bugs. I thougt that CCS driver introduced more unknowns.
Quote: |
You should be able to download 3.236 as is the 'stable' base release for the compiler you currently have. It does support this 18F4680. If you can't get acces to it, mail CCS and they will give you access to the download (as your 3.245 license will be valid for this release).
|
I will try that, thanks for the tip. But I don't really think that the compiler is the issue.
Quote: |
Have a look at the SYM file and see if any global structs or non-scratch variables are 'overlapping' each other. If they are then this is a 'known' compiler bug introduced around 3.242. |
This is something I know very little about. I dont understand what the @scratch means. For instance, what does can_set_mode.@SCRATCH stand for? Many of the @scratch variables appear on different locations. I don't see any overlapping non-scratch variables or global structs.
Quote: |
You say that the micro 'hangs'. Put in some breakpoints and step through the program and watch the CAN configuration registers. Step into the can_set_mode and check that the registers are still setup the way can_init has set them (i.e. that they haven't been corrupted). At what point does it hang ? Does it jump into can_set_mode or crash before ? |
All registers are still setup according to can_init(); settings when stepping into the can_se_mode() function:
Code: | void can_set_mode(CAN_OP_MODE mode) {
CANCON.reqop=mode;
while( (CANSTAT.opmode) != mode );
} |
CANCON register alters to 0x40 as it should requesting to change mode from Normal to Loopback. This request is not met. CANSTAT is never changed to loopback mode causing while( (CANSTAT.opmode) != mode ); to loop forever.
Quote: |
The reason I suggest you try an earlier version is that I was using 3.242 and everything appeared fine until my call to can_putd, at which point the registers changed as the compiler used a variable scratch location that was one of the global variables used to setup the can (hence the corruption). The earlier version of compiler worked without problems. |
Good to know that this problem can occur. However I don't believe that this is the case for me. The global (and main) variables and structures used are:
Code: |
018 curmode
019 curfunmode
01A-01B ms
01C-01F main.rxstat
020-023 main.rx_id
024-02B main.in_data
02C main.rx_len
02D-034 main.out_data
035-038 main.tx_id
039.0 main.tx_rtr
039.1 main.tx_ext
03A main.tx_len
03B main.tx_pri
03C main.i
|
And no other variable uses the same location.
Quote: |
You may already know, but in loopback mode you won't see anything on CANTX as the loopback disconnects the output and does the lookback internal to the PIC.
|
Since I got nothing at all out of the CANTX pin, I wanted to use loopback to se if there were something wrong with the bus. The problem is obviously earlier than that.
Quote: |
If the example doesn't work ... its one of two things (the compiler or the PIC is no good !!!). |
I quess, but I'm not able to narrow down the specific error. My fault, CCS fault or Microchip fault.
Pardon me for my bad manners, and I don't intend to be disrespectful. It is just very frustrating needing to spend so much time with something that should be fairly easy.
Thank you sjbaxter for your suggestions!
Any other ideas? |
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Wed Apr 19, 2006 12:25 pm |
|
|
Why don't you think the compiler is the problem? Several people have said thhis works with 3.236, but not with the version you have. This is the reason I am still using 3.236 even though I have newer versions.
Do what sjbaxter suggested. If it work with the CCS driver and 3.236 then you have a good startiong point. The only change ONE thing at a timer, such as driver or compiler version.
Avery |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Wed Apr 19, 2006 2:01 pm |
|
|
The datasheet states that a mode request will not be actioned until all pending transmissions are complete (Ref 23.3 of the datasheet). So, you need to pause when the app reaches this point and do some watching of the status registers to see if the TXREQ for each of the transmit buffers is set.
If it is, the next problem is why !!
You could try changing the can_set_mode at the bottom of can_init to default to LOOPBACK instead of NORMAL to see if that has any effect. If you are not connected to a live bus and you go into NORMAL mode and for some reason the PIC thinks there are pending TXs, you can't change the operating mode. You could try a can_abort before the set to LOOPBACK call.
Still doesn't explain why you should have messages in the TX buffers, but it gives you something else to work on.
Could be a bad PIC, not resetting properly. _________________ Regards,
Simon. |
|
|
Fredrik
Joined: 18 Apr 2006 Posts: 8
|
|
Posted: Thu Apr 20, 2006 12:37 am |
|
|
amcfall wrote: | Why don't you think the compiler is the problem? Several people have said thhis works with 3.236, but not with the version you have. This is the reason I am still using 3.236 even though I have newer versions. |
I don't think it is the compiler because when I debug the source and look at the registers, the request bits for operation mode change in CANCON are set. But the request is never met and changed into CANSTAT. I don't see this as a compiler issue. But what do I know. So I will try to get an older version and test.
sjbaxter wrote: | The datasheet states that a mode request will not be actioned until all pending transmissions are complete (Ref 23.3 of the datasheet). So, you need to pause when the app reaches this point and do some watching of the status registers to see if the TXREQ for each of the transmit buffers is set.
If it is, the next problem is why !! |
Not any of the TXREQ in any transmit buffer is set (all tx buffers are 0x00).
Quote: |
You could try changing the can_set_mode at the bottom of can_init to default to LOOPBACK instead of NORMAL to see if that has any effect. If you are not connected to a live bus and you go into NORMAL mode and for some reason the PIC thinks there are pending TXs, you can't change the operating mode. You could try a can_abort before the set to LOOPBACK call. |
I have tried to go to any other mode than normal in the can_init() function replacing the last can_set_mode(CAN_OP_NORMAL); to the different modes LISTEN, LOOPBACK and DISABLE. Non of the operating mode change requests are met. The only mode I can switch to is normal. And that doesn't work for me either.
Quote: | Could be a bad PIC, not resetting properly. |
Yes it could be, but then I got three of them.
Maybe it is time to buy and try another PIC... |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Thu Apr 20, 2006 3:52 am |
|
|
Fredrik,
have a look at this thread on the Microchip CAN forum :
Difficulty entering configuration mode
it is similar to your problem and has a few other pointers that may help. _________________ Regards,
Simon. |
|
|
|
|
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
|