View previous topic :: View next topic |
Author |
Message |
jgehret
Joined: 03 Apr 2013 Posts: 5
|
Changing CAN baudrate during operation |
Posted: Wed Apr 03, 2013 7:44 am |
|
|
I'm using the CAN prototyping board to simulate output from a system my production board is monitoring. I want to investigate the effect a bad baudrate has on my production board. I want to boot up with the proper baudrate and force it to an incorrect baudrate when the pushbutton on the board is activated.
Everything works perfectly at bootup, the simulator and the production board communicate perfectly. However, when I activate the pushbutton, the communications continue perfectly.
Can the baudrate be changed on the fly? If so, why won't the following work (a combination of can_init and can_set_baud from can-18xxx8.c)? I also tried a variation where I only changed the prescalar without success.
Code: | // set baud
if (bButton != bBaudBad) {
bBaudBad = bButton;
can_set_mode(CAN_OP_CONFIG); //must be in config mode before params can be set
if (bBaudBad) BRGCON1.brp=CAN_BRG_PRESCALAR_BAD;
else 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;
RXB0CON=0;
RXB0CON.rxm=CAN_RX_VALID;
RXB0CON.rxb0dben=CAN_USE_RX_DOUBLE_BUFFER;
RXB1CON=RXB0CON;
CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;
CIOCON.tx2src=CAN_CANTX2_SOURCE; //added 3/30/09 for PIC18F6585/8585/6680/8680
CIOCON.tx2en=CAN_ENABLE_CANTX2; //added 3/30/09 for PIC18F6585/8585/6680/8680
can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID); //set mask 0
can_set_id(RX0FILTER0, 0, CAN_USE_EXTENDED_ID); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0, CAN_USE_EXTENDED_ID); //set filter 1 of mask 0
can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID); //set mask 1
can_set_id(RX1FILTER2, 0, CAN_USE_EXTENDED_ID); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0, CAN_USE_EXTENDED_ID); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0, CAN_USE_EXTENDED_ID); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0, CAN_USE_EXTENDED_ID); //set filter 3 of mask 1
set_tris_b((*0xF93 & 0xFB ) | 0x08); //b3 is out, b2 is in
can_set_mode(CAN_OP_NORMAL);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 03, 2013 8:28 pm |
|
|
1. What PIC are you using ?
2. Do you know for certain that your pushbutton code works ?
Have you placed an LED or printf statement in the conditional code and
seen the indication that you're in that code when the button is pushed ? |
|
|
jgehret
Joined: 03 Apr 2013 Posts: 5
|
|
Posted: Thu Apr 04, 2013 4:03 am |
|
|
The CCS prototype board has a 18F458.
Yes, I turn on the yellow LED when using the bad baud rate. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Thu Apr 04, 2013 4:51 am |
|
|
Try using abort, before you set config mode. If a transmission is in progress, you will be locked from entering config mode.
Best Wishes |
|
|
jgehret
Joined: 03 Apr 2013 Posts: 5
|
|
Posted: Thu Apr 04, 2013 6:01 am |
|
|
I tried both can_abort() and can_set_mode(CAN_OP_DISABLE) before can_set_mode(CAN_OP_CONFIG). Neither one nor both together had the desired effect. However, when I used can_abort(), CAN comms never restarted, even when I returned the baud rate to the correct value. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Thu Apr 04, 2013 7:08 am |
|
|
OK.
I'd suggest:
Code: |
can_abort();
can_set_mode(CAN_OP_DISABLE);
//set baud code
CANCON.abat=FALSE;
can_set_mode(CAN_OP_NORMAL);
|
The abort on it's own just ensures that transmission is stopped.
you can't set the mode to CAN_OP_DISABLE, unless this is done.
What is odd is that there doesn't seem to be anything in the code to 'de abort'.
You could also try resetting the abat bit immediately after it is set.
Best Wishes |
|
|
jgehret
Joined: 03 Apr 2013 Posts: 5
|
|
Posted: Thu Apr 04, 2013 2:51 pm |
|
|
The problem was in the can-18xxx8.h driver file. I'm on version 4.121, so this may have been fixed
#byte CANSTAT = getenv("CANSTAT") //0xF6E
should be
#byte CANSTAT = getenv("SFR:CANSTAT") //0xF6E
The code is actually very simple now:
// set baud
if (bButton != bBaudBad) {
bBaudBad = bButton;
can_set_mode(CAN_OP_CONFIG); //must be in config mode before params can be set
BRGCON1.brp=(bBaudBad ? CAN_BRG_PRESCALAR_BAD : CAN_BRG_PRESCALAR);
output_bit(Yellow, (BRGCON1.brp == CAN_BRG_PRESCALAR_BAD ? 0 : 1));
can_set_mode(CAN_OP_NORMAL);
} |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Fri Apr 05, 2013 3:50 am |
|
|
Uurgh....
Typical.
Well done in finding it.
Best Wishes |
|
|
jgehret
Joined: 03 Apr 2013 Posts: 5
|
|
Posted: Fri Apr 05, 2013 5:44 am |
|
|
Thanks for your help and thanks to PCM Programmer. |
|
|
|