Haeal
Joined: 04 Mar 2008 Posts: 2 Location: New Zealand
|
PIC18F458 to PIC18F4585 migration issue |
Posted: Tue Mar 04, 2008 9:58 pm |
|
|
Have had this problem for the last couple of weeks, and I have to admit I'm stumped. As well as reading this post, you may want to read the posts on the Microchip forum Migrating from 18f458 to 18f4585.
The whole experience boils down to the code works for the PIC18F458, and doesn't work for the PIC18F4585. I've checked the errata, and nothing is in there for it.
I have had a CAN program working on the old PIC, and decided to upgrade to a new PIC, since it had more versatility (and long story short, I can't change back). Now, with the new PIC I found that it would only pick up the first message, and every time after that, whenever queried the CAN module would return that first packet. Over and over and over. So after a few investigative dramas ,I set up a small loop as shown below to see what was going on. This is the loop...
Code: |
//CAN Definitions.
////////////////////////////////////////////////////////////////////////////////
#IFNDEF CAN_BRG_SYNCH_JUMP_WIDTH
#define CAN_BRG_SYNCH_JUMP_WIDTH 2 //synchronized jump width (def: 1 x Tq)
#ENDIF
#IFNDEF CAN_BRG_PRESCALAR
#define CAN_BRG_PRESCALAR 1 // = PLL-Osc / 4
#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 7 // = 8 Tq for a segment.
#ENDIF
#IFNDEF CAN_BRG_PROPAGATION_TIME
#define CAN_BRG_PROPAGATION_TIME 5 // = 6 Tq for propagation
#ENDIF
#IFNDEF CAN_BRG_PHASE_SEGMENT_2
#define CAN_BRG_PHASE_SEGMENT_2 4 // = 5 Tq for segment 2.
#ENDIF
//With 8 + 6 + 5 = 19, and 1 enforced for edge detection, = Tq * 20 or internal clock / 20 = 500k baud.
#IFNDEF CAN_USE_RX_DOUBLE_BUFFER
#define CAN_USE_RX_DOUBLE_BUFFER FALSE //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#ENDIF
#IFNDEF CAN_USE_EXTENDED_ID
#define CAN_USE_EXTENDED_ID FALSE
#ENDIF
////////////////////////////////////////////////////////////////////////////////
#include <18F4585.H>
#include <can-18xxx8.c>
#fuses NOWDT,H4
#use delay(clock=40000000)
#use rs232(baud=57600, xmit=PIN_C6,rcv=PIN_C7)
#define UINT8 unsigned char
#include "Z:\Include\CCS Compiler\PIC18F4585_SFR.h"
#include "Z:\Include\CCS Compiler\Multex.c"
void Main()
{
int count = 0;
int32 id;
int data[32];
int len;
struct rx_stat rxstat;
unsigned char buffer;
MTXClearAllMappings();
MTXMapX2Pin(5, 6);
MTXMapX2Pin(4, 14);
MTXSetMapping();
//Set CANTX as a driving line.
TRISB2 = 0;
//Drive CANTX high so the transiever isn't transmitting.
RB2 = 1;
//Set CANRX as an input line.
TRISB3 = 1;
RB5 = 0;
TRISB5 = 0;
delay_ms(100);
can_init();
//Turn off RXB1.
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX1MASK, 0xFFFFFFFF, CAN_USE_EXTENDED_ID); //set mask 1
can_set_mode(CAN_OP_LISTEN);
count = 0;
CANCON.win=CAN_WIN_RX0;
while(count < 50)
{
buffer = RXB0CON;
if(BIT_TEST(buffer, 7))
{
count++;
RB5 = 1;
//Set the buffer as clear.
BIT_CLEAR(RXB0CON, 7);
//Set the buffer to no overflow.
BIT_CLEAR(COMSTAT, 7);
//Set no error received on CAN bus.
BIT_CLEAR(PIR3, 7);
//Set buffer 0 as empty interrupt-wise.
BIT_CLEAR(PIR3, 0);
//Set no errors in the CAN module.
BIT_CLEAR(PIR3, 5);
RB5 = 0;
}
}
}
|
RB5 is a line I am using to monitor when RXB0 is full. I can't post any pictures here at the moment, and will look into getting something from photobucket or something, but when I scoped the CANRX line vs the RB5 line, after the first message, when CAN loads the first message into RXB0 and sets RXB0FUL to 1, it goes a little crazy.
Once RXB0FUL is set to 1 by the CAN controller, I can never get it to stay 0 again. I set it 0, and it jumps straight back to 1. Less regularly, but still at weird positions, RXB0OVFL goes to 1 as well, but I think that's my program not clearing RXB0FUL quick enough.
Now, I take this exact same code, no changing of headers or anything, and try it on the exact same hardware, but with a PIC18F458, and it works perfectly. (Sneaky note, I call can_init then set it straight back into config. I've tried it without the mode setting in the library but that didn't change anything, so I've left it in so I don't break other code).
Even more interesting is I change the mode switch from LISTEN to NORMAL, and it works fine (with one tiny exception which makes it not feasible to use of course).
So what I'm looking for is any information at all as to why the CAN controller might be behaving like this. I'm quite happy to give more information if needed, and if asked I'll put the scope snapshot images up as well to show what is happening.
Compiler version: 4.058 (CCSC).
Headers: CCSC headers except for the SFR defines (which have been thrice checked and then again), and the multiplexer code which uses Port E and changes the analog-digital configuration registers for setting Port A pins as analog or digital. I haven't posted these for conciseness but I can do that as well if someone really needs them.
Thank you for your time,
Scott. |
|